package micdoodle8.mods.galacticraft.core.tile; import micdoodle8.mods.galacticraft.api.vector.Vector3; import micdoodle8.mods.galacticraft.core.entities.*; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.server.MinecraftServer; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.BlockPos; import net.minecraft.world.World; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.List; public class TileEntityDungeonSpawner<E extends Entity> extends TileEntityAdvanced { public Class<E> bossClass; public IBoss boss; public boolean spawned; public boolean isBossDefeated; public boolean playerInRange; public boolean lastPlayerInRange; private Vector3 roomCoords; private Vector3 roomSize; public long lastKillTime; private BlockPos chestPos; private AxisAlignedBB range15 = null; private AxisAlignedBB rangeBounds = null; private AxisAlignedBB rangeBoundsPlus3 = null; private AxisAlignedBB rangeBoundsPlus11 = null; public TileEntityDungeonSpawner() { } public TileEntityDungeonSpawner(Class<E> bossClass) { this.bossClass = bossClass; } @SuppressWarnings("unchecked") @Override public void update() { super.update(); if (this.roomCoords == null) { return; } if (!this.worldObj.isRemote) { if (this.range15 == null) { final Vector3 thisVec = new Vector3(this); this.range15 = AxisAlignedBB.fromBounds(thisVec.x - 15, thisVec.y - 15, thisVec.z - 15, thisVec.x + 15, thisVec.y + 15, thisVec.z + 15); this.rangeBounds = AxisAlignedBB.fromBounds(this.roomCoords.intX(), this.roomCoords.intY(), this.roomCoords.intZ(), this.roomCoords.intX() + this.roomSize.intX(), this.roomCoords.intY() + this.roomSize.intY(), this.roomCoords.intZ() + this.roomSize.intZ()); this.rangeBoundsPlus3 = this.rangeBounds.expand(3, 3, 3); } if (this.lastKillTime > 0 && MinecraftServer.getCurrentTimeMillis() - lastKillTime > 900000) // 15 minutes { this.lastKillTime = 0; this.isBossDefeated = false; //After 15 minutes a new boss is able to be spawned } final List<E> l = this.worldObj.getEntitiesWithinAABB(bossClass, this.range15); for (final Entity e : l) { if (!e.isDead) { this.boss = (IBoss) e; this.spawned = true; this.isBossDefeated = false; this.boss.onBossSpawned(this); } } List<EntityMob> entitiesWithin = this.worldObj.getEntitiesWithinAABB(EntityMob.class, this.rangeBoundsPlus3); for (Entity mob : entitiesWithin) { if (this.getDisabledCreatures().contains(mob.getClass())) { mob.setDead(); } } List<EntityPlayer> playersWithin = this.worldObj.getEntitiesWithinAABB(EntityPlayer.class, this.rangeBounds); this.playerInRange = !playersWithin.isEmpty(); if (this.playerInRange) { if (!this.lastPlayerInRange && !this.spawned) { //Try to create a boss entity if (this.boss == null && !this.isBossDefeated) { try { Constructor<?> c = this.bossClass.getConstructor(new Class[] { World.class }); this.boss = (IBoss) c.newInstance(new Object[] { this.worldObj }); ((Entity) this.boss).setPosition(this.getPos().getX() + 0.5, this.getPos().getY() + 1.0, this.getPos().getZ() + 0.5); } catch (Exception e) { e.printStackTrace(); } } //Now spawn the boss if (this.boss != null) { if (this.boss instanceof EntityLiving) { EntityLiving bossLiving = (EntityLiving) this.boss; bossLiving.onInitialSpawn(this.worldObj.getDifficultyForLocation(new BlockPos(bossLiving)), null); this.worldObj.spawnEntityInWorld(bossLiving); this.playSpawnSound(bossLiving); this.spawned = true; } } } } this.lastPlayerInRange = this.playerInRange; } } public void playSpawnSound(Entity entity) { } public List<Class<? extends EntityLiving>> getDisabledCreatures() { List<Class<? extends EntityLiving>> list = new ArrayList<Class<? extends EntityLiving>>(); list.add(EntityEvolvedSkeleton.class); list.add(EntityEvolvedCreeper.class); list.add(EntityEvolvedZombie.class); list.add(EntityEvolvedSpider.class); return list; } public void setRoom(Vector3 coords, Vector3 size) { this.roomCoords = coords; this.roomSize = size; } @SuppressWarnings("unchecked") @Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); this.playerInRange = this.lastPlayerInRange = nbt.getBoolean("playerInRange"); this.isBossDefeated = nbt.getBoolean("defeated"); try { this.bossClass = (Class<E>) Class.forName(nbt.getString("bossClass")); } catch (Exception e) { e.printStackTrace(); } this.roomCoords = new Vector3(); this.roomCoords.x = nbt.getDouble("roomCoordsX"); this.roomCoords.y = nbt.getDouble("roomCoordsY"); this.roomCoords.z = nbt.getDouble("roomCoordsZ"); this.roomSize = new Vector3(); this.roomSize.x = nbt.getDouble("roomSizeX"); this.roomSize.y = nbt.getDouble("roomSizeY"); this.roomSize.z = nbt.getDouble("roomSizeZ"); if (nbt.hasKey("lastKillTime")) { this.lastKillTime = nbt.getLong("lastKillTime"); } else if (nbt.hasKey("lastKillTimeNew")) { long savedTime = nbt.getLong("lastKillTimeNew"); this.lastKillTime = savedTime == 0 ? 0 : savedTime + MinecraftServer.getCurrentTimeMillis(); } if (nbt.hasKey("chestPosNull") && !nbt.getBoolean("chestPosNull")) { this.chestPos = new BlockPos(nbt.getInteger("chestX"), nbt.getInteger("chestY"), nbt.getInteger("chestZ")); } } @Override public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); nbt.setBoolean("playerInRange", this.playerInRange); nbt.setBoolean("defeated", this.isBossDefeated); nbt.setString("bossClass", this.bossClass.getCanonicalName()); if (this.roomCoords != null) { nbt.setDouble("roomCoordsX", this.roomCoords.x); nbt.setDouble("roomCoordsY", this.roomCoords.y); nbt.setDouble("roomCoordsZ", this.roomCoords.z); nbt.setDouble("roomSizeX", this.roomSize.x); nbt.setDouble("roomSizeY", this.roomSize.y); nbt.setDouble("roomSizeZ", this.roomSize.z); } nbt.setLong("lastKillTimeNew", this.lastKillTime == 0 ? 0 : this.lastKillTime - MinecraftServer.getCurrentTimeMillis()); nbt.setBoolean("chestPosNull", this.chestPos == null); if (this.chestPos != null) { nbt.setInteger("chestX", this.chestPos.getX()); nbt.setInteger("chestY", this.chestPos.getY()); nbt.setInteger("chestZ", this.chestPos.getZ()); } } @Override public double getPacketRange() { return 0; } @Override public int getPacketCooldown() { return 0; } @Override public boolean isNetworkedTile() { return false; } public BlockPos getChestPos() { return chestPos; } public void setChestPos(BlockPos chestPos) { this.chestPos = chestPos; } public AxisAlignedBB getRangeBounds() { if (this.rangeBounds == null) this.rangeBounds = AxisAlignedBB.fromBounds(this.roomCoords.intX(), this.roomCoords.intY(), this.roomCoords.intZ(), this.roomCoords.intX() + this.roomSize.intX(), this.roomCoords.intY() + this.roomSize.intY(), this.roomCoords.intZ() + this.roomSize.intZ()); return this.rangeBounds; } public AxisAlignedBB getRangeBoundsPlus11() { if (this.rangeBoundsPlus11 == null) this.rangeBoundsPlus11 = this.getRangeBounds().expand(11, 11, 11); return this.rangeBoundsPlus11; } }