package mcjty.rftools.dimension;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.TickEvent;
import mcjty.rftools.PlayerBuff;
import mcjty.rftools.RFTools;
import mcjty.rftools.blocks.dimlets.DimletConfiguration;
import mcjty.rftools.blocks.teleporter.TeleportationTools;
import mcjty.rftools.dimension.description.DimensionDescriptor;
import mcjty.rftools.dimension.world.types.EffectType;
import mcjty.rftools.items.dimlets.types.Patreons;
import mcjty.rftools.playerprops.BuffProperties;
import net.minecraft.entity.item.EntityFireworkRocket;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.DimensionManager;
import java.util.*;
public class DimensionTickEvent {
public static final int MAXTICKS = 10;
private int counter = MAXTICKS;
private static final int EFFECTS_MAX = 18;
private int counterEffects = EFFECTS_MAX;
private static Random random = new Random();
@SubscribeEvent
public void onServerTick(TickEvent.ServerTickEvent evt) {
if (evt.phase == TickEvent.Phase.START) {
return;
}
counter--;
if (counter <= 0) {
counter = MAXTICKS;
counterEffects--;
boolean doEffects = false;
if (counterEffects <= 0) {
counterEffects = EFFECTS_MAX;
doEffects = true;
}
serverTick(doEffects);
}
}
private void serverTick(boolean doEffects) {
World entityWorld = MinecraftServer.getServer().getEntityWorld();
RfToolsDimensionManager dimensionManager = RfToolsDimensionManager.getDimensionManager(entityWorld);
if (!dimensionManager.getDimensions().isEmpty()) {
DimensionStorage dimensionStorage = DimensionStorage.getDimensionStorage(entityWorld);
for (Map.Entry<Integer, DimensionDescriptor> entry : dimensionManager.getDimensions().entrySet()) {
Integer id = entry.getKey();
// If there is an activity probe we only drain power if the dimension is loaded (a player is there or a chunkloader)
DimensionInformation information = dimensionManager.getDimensionInformation(id);
WorldServer world = DimensionManager.getWorld(id);
// Power handling.
if (world != null || information.getProbeCounter() == 0) {
handlePower(doEffects, dimensionStorage, entry, id, information);
}
// Special effect handling.
if (world != null && !world.playerEntities.isEmpty()) {
handleRandomEffects(world, information);
}
}
dimensionStorage.save(entityWorld);
}
}
private void handlePower(boolean doEffects, DimensionStorage dimensionStorage, Map.Entry<Integer, DimensionDescriptor> entry, Integer id, DimensionInformation information) {
int cost = 0;
if (DimletConfiguration.dimensionDifficulty != -1) {
cost = information.getActualRfCost();
if (cost == 0) {
cost = entry.getValue().getRfMaintainCost();
}
}
int power = dimensionStorage.getEnergyLevel(id);
power -= cost * MAXTICKS;
if (power < 0) {
power = 0;
}
handleLowPower(id, power, doEffects, cost);
if (doEffects && power > 0) {
handleEffectsForDimension(power, id, information);
}
dimensionStorage.setEnergyLevel(id, power);
}
private void handleRandomEffects(WorldServer world, DimensionInformation information) {
// The world is loaded and there are players there.
if (information.isPatreonBitSet(Patreons.PATREON_FIREWORKS)) {
handleFireworks(world);
}
if (information.isPatreonBitSet(Patreons.PATREON_TOMWOLF)) {
handleHowlingWolf(world, information);
}
}
private static int t = 0;
private void handleHowlingWolf(WorldServer world, DimensionInformation information) {
if (information.getCelestialAngle() == null) {
// We don't have fixed time.
float a = world.getCelestialAngle(1.0f);
t--;
if (t <= 0) {
t = 0;
}
if (Math.abs(a-0.5f) < 0.05f) {
if (t <= 0) {
playHowl(world);
t = 40;
}
}
} else {
// We have fixed time so just play the sound at random moments
if (random.nextFloat() < 0.001) {
playHowl(world);
}
}
}
private void playHowl(WorldServer world) {
for (Object playerEntity : world.playerEntities) {
EntityPlayer player = (EntityPlayer) playerEntity;
world.playSoundEffect(player.posX, player.posY, player.posZ, RFTools.MODID+":wolfhowl", 1.0f, 1.0f);
}
}
private void handleFireworks(WorldServer world) {
if (random.nextFloat() < 0.05) {
// Calculate a bounding box for all players in the world.
double minPosX = 1000000000.0f;
double minPosZ = 1000000000.0f;
double maxPosX = -1000000000.0f;
double maxPosZ = -1000000000.0f;
for (Object playerEntity : world.playerEntities) {
EntityPlayer player = (EntityPlayer) playerEntity;
if (player.posX > maxPosX) {
maxPosX = player.posX;
}
if (player.posX < minPosX) {
minPosX = player.posX;
}
if (player.posZ > maxPosZ) {
maxPosZ = player.posZ;
}
if (player.posZ < minPosZ) {
minPosZ = player.posZ;
}
}
double posX = random.nextFloat() * (maxPosX - minPosX + 60.0f) + minPosX - 30.0f;
double posZ = random.nextFloat() * (maxPosZ - minPosZ + 60.0f) + minPosZ - 30.0f;
ItemStack fireworkStack = new ItemStack(Items.fireworks);
NBTTagCompound tag = new NBTTagCompound();
NBTTagCompound fireworks = new NBTTagCompound();
fireworks.setByte("Flight", (byte) 2);
NBTTagList explosions = new NBTTagList();
explosions.appendTag(makeExplosion(tag));
fireworks.setTag("Explosions", explosions);
tag.setTag("Fireworks", fireworks);
fireworkStack.setTagCompound(tag);
int y = world.getTopSolidOrLiquidBlock((int) posX, (int) posZ);
if (y == -1) {
y = 64;
} else {
y += 3;
}
EntityFireworkRocket entityfireworkrocket = new EntityFireworkRocket(world, posX, y, posZ, fireworkStack);
world.spawnEntityInWorld(entityfireworkrocket);
}
}
private static int[] colors = new int[] {
0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff, 0x00ffff, 0xffffff,
0xff5555, 0x55ff55, 0x5555ff, 0xffff55, 0xff55ff, 0x55ffff, 0x555555
};
private NBTTagCompound makeExplosion(NBTTagCompound tag) {
NBTTagCompound explosion = new NBTTagCompound();
explosion.setBoolean("Flicker", true);
explosion.setBoolean("Tail", true);
explosion.setByte("Type", (byte) (random.nextInt(4)+1));
explosion.setIntArray("Colors", new int[]{colors[random.nextInt(colors.length)], colors[random.nextInt(colors.length)], colors[random.nextInt(colors.length)]});
tag.setTag("Explosion", explosion);
return explosion;
}
static final Map<EffectType,Integer> effectsMap = new HashMap<EffectType, Integer>();
static final Map<EffectType,Integer> effectAmplifierMap = new HashMap<EffectType, Integer>();
static {
effectsMap.put(EffectType.EFFECT_POISON, Potion.poison.getId());
effectsMap.put(EffectType.EFFECT_POISON2, Potion.poison.getId());
effectAmplifierMap.put(EffectType.EFFECT_POISON2, 1);
effectsMap.put(EffectType.EFFECT_POISON3, Potion.poison.getId());
effectAmplifierMap.put(EffectType.EFFECT_POISON3, 2);
effectsMap.put(EffectType.EFFECT_REGENERATION, Potion.regeneration.getId());
effectsMap.put(EffectType.EFFECT_REGENERATION2, Potion.regeneration.getId());
effectAmplifierMap.put(EffectType.EFFECT_REGENERATION2, 1);
effectsMap.put(EffectType.EFFECT_REGENERATION3, Potion.regeneration.getId());
effectAmplifierMap.put(EffectType.EFFECT_REGENERATION3, 2);
effectsMap.put(EffectType.EFFECT_MOVESLOWDOWN, Potion.moveSlowdown.getId());
effectsMap.put(EffectType.EFFECT_MOVESLOWDOWN2, Potion.moveSlowdown.getId());
effectAmplifierMap.put(EffectType.EFFECT_MOVESLOWDOWN2, 1);
effectsMap.put(EffectType.EFFECT_MOVESLOWDOWN3, Potion.moveSlowdown.getId());
effectAmplifierMap.put(EffectType.EFFECT_MOVESLOWDOWN3, 2);
effectsMap.put(EffectType.EFFECT_MOVESLOWDOWN4, Potion.moveSlowdown.getId());
effectAmplifierMap.put(EffectType.EFFECT_MOVESLOWDOWN4, 3);
effectsMap.put(EffectType.EFFECT_MOVESPEED, Potion.moveSpeed.getId());
effectsMap.put(EffectType.EFFECT_MOVESPEED2, Potion.moveSpeed.getId());
effectAmplifierMap.put(EffectType.EFFECT_MOVESPEED2, 1);
effectsMap.put(EffectType.EFFECT_MOVESPEED3, Potion.moveSpeed.getId());
effectAmplifierMap.put(EffectType.EFFECT_MOVESPEED3, 2);
effectsMap.put(EffectType.EFFECT_DIGSLOWDOWN, Potion.digSlowdown.getId());
effectsMap.put(EffectType.EFFECT_DIGSLOWDOWN2, Potion.digSlowdown.getId());
effectAmplifierMap.put(EffectType.EFFECT_DIGSLOWDOWN2, 1);
effectsMap.put(EffectType.EFFECT_DIGSLOWDOWN3, Potion.digSlowdown.getId());
effectAmplifierMap.put(EffectType.EFFECT_DIGSLOWDOWN3, 2);
effectsMap.put(EffectType.EFFECT_DIGSLOWDOWN4, Potion.digSlowdown.getId());
effectAmplifierMap.put(EffectType.EFFECT_DIGSLOWDOWN4, 3);
effectsMap.put(EffectType.EFFECT_DIGSPEED, Potion.digSpeed.getId());
effectsMap.put(EffectType.EFFECT_DIGSPEED2, Potion.digSpeed.getId());
effectAmplifierMap.put(EffectType.EFFECT_DIGSPEED2, 1);
effectsMap.put(EffectType.EFFECT_DIGSPEED3, Potion.digSpeed.getId());
effectAmplifierMap.put(EffectType.EFFECT_DIGSPEED3, 2);
effectsMap.put(EffectType.EFFECT_DAMAGEBOOST, Potion.damageBoost.getId());
effectsMap.put(EffectType.EFFECT_DAMAGEBOOST2, Potion.damageBoost.getId());
effectAmplifierMap.put(EffectType.EFFECT_DAMAGEBOOST2, 1);
effectsMap.put(EffectType.EFFECT_DAMAGEBOOST3, Potion.damageBoost.getId());
effectAmplifierMap.put(EffectType.EFFECT_DAMAGEBOOST3, 2);
effectsMap.put(EffectType.EFFECT_INSTANTHEALTH, Potion.heal.getId());
effectsMap.put(EffectType.EFFECT_HARM, Potion.harm.getId());
effectsMap.put(EffectType.EFFECT_JUMP, Potion.jump.getId());
effectsMap.put(EffectType.EFFECT_JUMP2, Potion.jump.getId());
effectAmplifierMap.put(EffectType.EFFECT_JUMP2, 1);
effectsMap.put(EffectType.EFFECT_JUMP3, Potion.jump.getId());
effectAmplifierMap.put(EffectType.EFFECT_JUMP3, 2);
effectsMap.put(EffectType.EFFECT_CONFUSION, Potion.confusion.getId());
effectsMap.put(EffectType.EFFECT_RESISTANCE, Potion.resistance.getId());
effectsMap.put(EffectType.EFFECT_RESISTANCE2, Potion.resistance.getId());
effectAmplifierMap.put(EffectType.EFFECT_RESISTANCE2, 1);
effectsMap.put(EffectType.EFFECT_RESISTANCE3, Potion.resistance.getId());
effectAmplifierMap.put(EffectType.EFFECT_RESISTANCE3, 2);
effectsMap.put(EffectType.EFFECT_FIRERESISTANCE, Potion.fireResistance.getId());
effectsMap.put(EffectType.EFFECT_WATERBREATHING, Potion.waterBreathing.getId());
effectsMap.put(EffectType.EFFECT_INVISIBILITY, Potion.invisibility.getId());
effectsMap.put(EffectType.EFFECT_BLINDNESS, Potion.blindness.getId());
effectsMap.put(EffectType.EFFECT_NIGHTVISION, Potion.nightVision.getId());
effectsMap.put(EffectType.EFFECT_HUNGER, Potion.hunger.getId());
effectsMap.put(EffectType.EFFECT_HUNGER2, Potion.hunger.getId());
effectAmplifierMap.put(EffectType.EFFECT_HUNGER2, 1);
effectsMap.put(EffectType.EFFECT_HUNGER3, Potion.hunger.getId());
effectAmplifierMap.put(EffectType.EFFECT_HUNGER3, 2);
effectsMap.put(EffectType.EFFECT_WEAKNESS, Potion.weakness.getId());
effectsMap.put(EffectType.EFFECT_WEAKNESS2, Potion.weakness.getId());
effectAmplifierMap.put(EffectType.EFFECT_WEAKNESS2, 1);
effectsMap.put(EffectType.EFFECT_WEAKNESS3, Potion.weakness.getId());
effectAmplifierMap.put(EffectType.EFFECT_WEAKNESS3, 2);
effectsMap.put(EffectType.EFFECT_WITHER, Potion.wither.getId());
effectsMap.put(EffectType.EFFECT_WITHER2, Potion.wither.getId());
effectAmplifierMap.put(EffectType.EFFECT_WITHER2, 1);
effectsMap.put(EffectType.EFFECT_WITHER3, Potion.wither.getId());
effectAmplifierMap.put(EffectType.EFFECT_WITHER3, 2);
effectsMap.put(EffectType.EFFECT_HEALTHBOOST, Potion.field_76434_w.getId());
effectsMap.put(EffectType.EFFECT_HEALTHBOOST2, Potion.field_76434_w.getId());
effectAmplifierMap.put(EffectType.EFFECT_HEALTHBOOST2, 1);
effectsMap.put(EffectType.EFFECT_HEALTHBOOST3, Potion.field_76434_w.getId());
effectAmplifierMap.put(EffectType.EFFECT_HEALTHBOOST3, 2);
effectsMap.put(EffectType.EFFECT_ABSORPTION, Potion.field_76444_x.getId());
effectsMap.put(EffectType.EFFECT_ABSORPTION2, Potion.field_76444_x.getId());
effectAmplifierMap.put(EffectType.EFFECT_ABSORPTION2, 1);
effectsMap.put(EffectType.EFFECT_ABSORPTION3, Potion.field_76444_x.getId());
effectAmplifierMap.put(EffectType.EFFECT_ABSORPTION3, 2);
effectsMap.put(EffectType.EFFECT_SATURATION, Potion.field_76443_y.getId());
effectsMap.put(EffectType.EFFECT_SATURATION2, Potion.field_76443_y.getId());
effectAmplifierMap.put(EffectType.EFFECT_SATURATION2, 1);
effectsMap.put(EffectType.EFFECT_SATURATION3, Potion.field_76443_y.getId());
effectAmplifierMap.put(EffectType.EFFECT_SATURATION3, 2);
}
private void handleEffectsForDimension(int power, int id, DimensionInformation information) {
WorldServer world = DimensionManager.getWorld(id);
if (world != null) {
Set<EffectType> effects = information.getEffectTypes();
List<EntityPlayer> players = new ArrayList<EntityPlayer>(world.playerEntities);
for (EntityPlayer player : players) {
for (EffectType effect : effects) {
Integer potionEffect = effectsMap.get(effect);
if (potionEffect != null) {
Integer amplifier = effectAmplifierMap.get(effect);
if (amplifier == null) {
amplifier = 0;
}
player.addPotionEffect(new PotionEffect(potionEffect, EFFECTS_MAX*MAXTICKS*3, amplifier, true));
} else if (effect == EffectType.EFFECT_FLIGHT) {
BuffProperties.addBuff(player, PlayerBuff.BUFF_FLIGHT, EFFECTS_MAX * MAXTICKS * 2);
}
}
if (power < DimletConfiguration.DIMPOWER_WARN3) {
// We are VERY low on power. Start bad effects.
player.addPotionEffect(new PotionEffect(Potion.moveSlowdown.getId(), EFFECTS_MAX*MAXTICKS, 4, true));
player.addPotionEffect(new PotionEffect(Potion.digSlowdown.getId(), EFFECTS_MAX*MAXTICKS, 4, true));
player.addPotionEffect(new PotionEffect(Potion.poison.getId(), EFFECTS_MAX*MAXTICKS, 2, true));
player.addPotionEffect(new PotionEffect(Potion.hunger.getId(), EFFECTS_MAX*MAXTICKS, 2, true));
} else if (power < DimletConfiguration.DIMPOWER_WARN2) {
player.addPotionEffect(new PotionEffect(Potion.moveSlowdown.getId(), EFFECTS_MAX*MAXTICKS, 2, true));
player.addPotionEffect(new PotionEffect(Potion.digSlowdown.getId(), EFFECTS_MAX*MAXTICKS, 2, true));
player.addPotionEffect(new PotionEffect(Potion.hunger.getId(), EFFECTS_MAX*MAXTICKS, 1, true));
} else if (power < DimletConfiguration.DIMPOWER_WARN1) {
player.addPotionEffect(new PotionEffect(Potion.moveSlowdown.getId(), EFFECTS_MAX*MAXTICKS, 0, true));
player.addPotionEffect(new PotionEffect(Potion.digSlowdown.getId(), EFFECTS_MAX*MAXTICKS, 0, true));
}
}
}
}
private void handleLowPower(Integer id, int power, boolean doEffects, int phasedCost) {
if (power <= 0) {
// We ran out of power!
WorldServer world = DimensionManager.getWorld(id);
if (world != null) {
List<EntityPlayer> players = new ArrayList<EntityPlayer>(world.playerEntities);
if (DimletConfiguration.dimensionDifficulty >= 1) {
for (EntityPlayer player : players) {
if (!RfToolsDimensionManager.checkValidPhasedFieldGenerator(player, true, phasedCost)) {
player.attackEntityFrom(new DamageSourcePowerLow("powerLow"), 1000000.0f);
} else {
if (doEffects && DimletConfiguration.phasedFieldGeneratorDebuf) {
player.addPotionEffect(new PotionEffect(Potion.moveSlowdown.getId(), EFFECTS_MAX * MAXTICKS, 4, true));
player.addPotionEffect(new PotionEffect(Potion.digSlowdown.getId(), EFFECTS_MAX * MAXTICKS, 2, true));
player.addPotionEffect(new PotionEffect(Potion.hunger.getId(), EFFECTS_MAX * MAXTICKS, 2, true));
}
}
}
} else {
Random random = new Random();
for (EntityPlayer player : players) {
if (!RfToolsDimensionManager.checkValidPhasedFieldGenerator(player, true, phasedCost)) {
WorldServer worldServerForDimension = MinecraftServer.getServer().worldServerForDimension(DimletConfiguration.spawnDimension);
int x = random.nextInt(2000) - 1000;
int z = random.nextInt(2000) - 1000;
int y = worldServerForDimension.getTopSolidOrLiquidBlock(x, z);
if (y == -1) {
y = 63;
}
TeleportationTools.teleportToDimension(player, DimletConfiguration.spawnDimension, x, y, z);
} else {
if (doEffects) {
player.addPotionEffect(new PotionEffect(Potion.moveSlowdown.getId(), EFFECTS_MAX * MAXTICKS, 4, true));
player.addPotionEffect(new PotionEffect(Potion.digSlowdown.getId(), EFFECTS_MAX * MAXTICKS, 4, true));
player.addPotionEffect(new PotionEffect(Potion.hunger.getId(), EFFECTS_MAX * MAXTICKS, 2, true));
}
}
}
}
}
}
}
}