package micdoodle8.mods.galacticraft.core.entities;
import micdoodle8.mods.galacticraft.core.GalacticraftCore;
import micdoodle8.mods.galacticraft.core.network.PacketSimple;
import micdoodle8.mods.galacticraft.core.tile.TileEntityDungeonSpawner;
import micdoodle8.mods.galacticraft.core.tile.TileEntityTreasureChest;
import micdoodle8.mods.galacticraft.core.util.GCCoreUtil;
import net.minecraft.entity.boss.IBossDisplayData;
import net.minecraft.entity.item.EntityXPOrb;
import net.minecraft.entity.monster.EntityMob;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.server.MinecraftServer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.WeightedRandomChestContent;
import net.minecraft.world.World;
import net.minecraftforge.common.ChestGenHooks;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import java.util.List;
import java.util.Random;
public abstract class EntityBossBase extends EntityMob implements IBossDisplayData, IBoss
{
protected TileEntityDungeonSpawner spawner;
public int deathTicks = 0;
public int entitiesWithin;
public int entitiesWithinLast;
public EntityBossBase(World world)
{
super(world);
}
public abstract int getChestTier();
public abstract ItemStack getGuaranteedLoot(Random rand);
public abstract void dropKey();
@Override
protected void onDeathUpdate()
{
++this.deathTicks;
if (this.deathTicks >= 180 && this.deathTicks <= 200)
{
final float x = (this.rand.nextFloat() - 0.5F) * this.width;
final float y = (this.rand.nextFloat() - 0.5F) * (this.height / 2.0F);
final float z = (this.rand.nextFloat() - 0.5F) * this.width;
this.worldObj.spawnParticle(EnumParticleTypes.EXPLOSION_HUGE, this.posX + x, this.posY + 2.0D + y, this.posZ + z, 0.0D, 0.0D, 0.0D);
}
int i;
int j;
if (!this.worldObj.isRemote)
{
if (this.deathTicks >= 180 && this.deathTicks % 5 == 0)
{
GalacticraftCore.packetPipeline.sendToAllAround(new PacketSimple(PacketSimple.EnumSimplePacket.C_PLAY_SOUND_EXPLODE, GCCoreUtil.getDimensionID(this.worldObj), new Object[] {}), new NetworkRegistry.TargetPoint(GCCoreUtil.getDimensionID(this.worldObj), this.posX, this.posY, this.posZ, 40.0D));
}
if (this.deathTicks > 150 && this.deathTicks % 5 == 0)
{
i = 30;
while (i > 0)
{
j = EntityXPOrb.getXPSplit(i);
i -= j;
this.worldObj.spawnEntityInWorld(new EntityXPOrb(this.worldObj, this.posX, this.posY, this.posZ, j));
}
}
}
if (this.deathTicks == 200 && !this.worldObj.isRemote)
{
i = 20;
while (i > 0)
{
j = EntityXPOrb.getXPSplit(i);
i -= j;
this.worldObj.spawnEntityInWorld(new EntityXPOrb(this.worldObj, this.posX, this.posY, this.posZ, j));
}
TileEntityTreasureChest chest = null;
if (this.spawner != null && this.spawner.getChestPos() != null)
{
TileEntity chestTest = this.worldObj.getTileEntity(this.spawner.getChestPos());
if (chestTest != null && chestTest instanceof TileEntityTreasureChest)
{
chest = (TileEntityTreasureChest) chestTest;
}
}
if (chest == null)
{
// Fallback to finding closest chest
chest = TileEntityTreasureChest.findClosest(this, this.getChestTier());
}
if (chest != null)
{
double dist = this.getDistanceSq(chest.getPos().getX() + 0.5, chest.getPos().getY() + 0.5, chest.getPos().getZ() + 0.5);
if (dist < 1000 * 1000)
{
if (!chest.locked)
{
chest.locked = true;
}
for (int k = 0; k < chest.getSizeInventory(); k++)
{
chest.setInventorySlotContents(k, null);
}
ChestGenHooks info = ChestGenHooks.getInfo(ChestGenHooks.DUNGEON_CHEST);
// Generate twice, since it's an extra special chest
WeightedRandomChestContent.generateChestContents(this.rand, info.getItems(this.rand), chest, info.getCount(this.rand));
WeightedRandomChestContent.generateChestContents(this.rand, info.getItems(this.rand), chest, info.getCount(this.rand));
ItemStack schematic = this.getGuaranteedLoot(this.rand);
int slot = this.rand.nextInt(chest.getSizeInventory());
chest.setInventorySlotContents(slot, schematic);
}
}
this.dropKey();
super.setDead();
if (this.spawner != null)
{
//Note: spawner.isBossDefeated is true, so it's properly dead
this.spawner.isBossDefeated = true;
this.spawner.boss = null;
this.spawner.spawned = false;
if (!this.worldObj.isRemote)
{
this.spawner.lastKillTime = MinecraftServer.getCurrentTimeMillis();
}
}
}
}
@Override
public void onLivingUpdate()
{
if (this.spawner != null)
{
List<EntityPlayer> playersWithin = this.worldObj.getEntitiesWithinAABB(EntityPlayer.class, this.spawner.getRangeBounds());
this.entitiesWithin = playersWithin.size();
if (this.entitiesWithin == 0 && this.entitiesWithinLast != 0)
{
List<EntityPlayer> entitiesWithin2 = this.worldObj.getEntitiesWithinAABB(EntityPlayer.class, this.spawner.getRangeBoundsPlus11());
for (EntityPlayer p : entitiesWithin2)
{
p.addChatMessage(new ChatComponentText(GCCoreUtil.translate("gui.skeleton_boss.message")));
}
this.setDead();
//Note: spawner.isBossDefeated is false, so the boss will respawn if any player comes back inside the room
return;
}
this.entitiesWithinLast = this.entitiesWithin;
}
super.onLivingUpdate();
}
@Override
public void setDead()
{
if (this.spawner != null)
{
this.spawner.isBossDefeated = false;
this.spawner.boss = null;
this.spawner.spawned = false;
}
super.setDead();
}
@Override
public void onBossSpawned(TileEntityDungeonSpawner spawner)
{
this.spawner = spawner;
}
}