package com.gildedgames.the_aether.entities.bosses.sun_spirit; import java.util.List; import com.gildedgames.the_aether.Aether; import com.gildedgames.the_aether.AetherConfig; import com.gildedgames.the_aether.api.AetherAPI; import com.gildedgames.the_aether.api.player.util.IAetherBoss; import com.gildedgames.the_aether.entities.bosses.EntityFireMinion; import com.gildedgames.the_aether.entities.projectile.crystals.EntityCrystal; import com.gildedgames.the_aether.entities.projectile.crystals.EnumCrystalType; import com.gildedgames.the_aether.entities.util.AetherNameGen; import com.gildedgames.the_aether.entities.util.EntityAetherItem; import com.gildedgames.the_aether.items.ItemsAether; import com.gildedgames.the_aether.player.PlayerAether; import com.gildedgames.the_aether.registry.achievements.AchievementsAether; import com.gildedgames.the_aether.world.AetherData; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.relauncher.Side; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.entity.*; import net.minecraft.entity.boss.EntityDragonPart; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.monster.IMob; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.potion.PotionEffect; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; import net.minecraft.util.EntityDamageSource; import net.minecraft.util.MathHelper; import net.minecraft.world.World; import com.gildedgames.the_aether.blocks.BlocksAether; import com.gildedgames.the_aether.blocks.dungeon.BlockDungeonBase; import net.minecraft.world.WorldProvider; public class EntitySunSpirit extends EntityFlying implements IMob, IAetherBoss, IEntityMultiPart { public int originPointX, originPointY, originPointZ; public int motionTimer; public int flameCount; public int ballCount; public int chatLog; public int chatCount; public int direction; public double rotary; public double velocity; public EntityDragonPart[] sunSpiritParts; public EntityDragonPart SpiritPartHead = new EntityDragonPart(this, "head", 1.375F, 1.375F); public EntityDragonPart SpiritPartShoulder1 = new EntityDragonPart(this, "shoulder1", 1.375F, 2.0F); public EntityDragonPart SpiritPartShoulder2 = new EntityDragonPart(this, "shoulder2", 1.375F, 2.0F); public EntitySunSpirit(World worldIn) { super(worldIn); this.sunSpiritParts = new EntityDragonPart[] {this.SpiritPartHead, this.SpiritPartShoulder1, this.SpiritPartShoulder2}; this.setSize(2.5F, 2.8F); this.dataWatcher.updateObject(20, AetherNameGen.gen()); } public EntitySunSpirit(World worldIn, int posX, int posY, int posZ, int var6) { this(worldIn); this.noClip = true; this.direction = var6; this.rotary = (double) this.rand.nextFloat() * 360.0D; ; this.rotationYaw = this.rotationYawHead = var6 == 3 ? 0 : var6 == 0 ? 90 : var6 == 2 ? 180 : 270; this.setPosition((double) posX + 0.5D, (double) posY, (double) posZ + 0.5D); this.setOriginPosition((int) posX, (int) posY, (int) posZ); } @Override public void entityInit() { super.entityInit(); this.dataWatcher.addObject(18, new Byte((byte) 0)); this.dataWatcher.addObject(19, new Byte((byte) 0)); this.dataWatcher.addObject(20, AetherNameGen.gen()); } @Override protected void applyEntityAttributes() { super.applyEntityAttributes(); this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(1.0D); this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(50.0D); } public boolean isPotionApplicable(PotionEffect par1PotionEffect) { return false; } public boolean canDespawn() { return false; } @Override protected String getHurtSound() { return null; } @Override protected String getDeathSound() { return null; } public boolean isDead() { return this.getHealth() <= 0.0F || this.isDead; } public void writeEntityToNBT(NBTTagCompound tag) { super.writeEntityToNBT(tag); tag.setInteger("originPointX", this.originPointX); tag.setInteger("originPointY", this.originPointY); tag.setInteger("originPointZ", this.originPointZ); tag.setInteger("dungeonDirection", this.direction); tag.setInteger("chatLog", this.getChatLine()); tag.setString("bossName", this.getName()); tag.setBoolean("isFreezing", this.isFreezing()); } public void readEntityFromNBT(NBTTagCompound tag) { super.readEntityFromNBT(tag); this.originPointX = tag.getInteger("originPointX"); this.originPointY = tag.getInteger("originPointY"); this.originPointZ = tag.getInteger("originPointZ"); this.direction = tag.getInteger("dungeonDirection"); this.setChatLine(tag.getInteger("chatLog")); this.setBossName(tag.getString("bossName")); this.setFreezing(tag.getBoolean("isFreezing")); } @Override public void onLivingUpdate() { super.onLivingUpdate(); this.setMultiPartLocations(); } private void setMultiPartLocations() { if (this.sunSpiritParts == null) { this.sunSpiritParts = new EntityDragonPart[] {this.SpiritPartHead, this.SpiritPartShoulder1, this.SpiritPartShoulder2}; } float f = this.rotationYaw * 0.017453292F; float f1 = MathHelper.sin(f); float f2 = MathHelper.cos(f); this.SpiritPartHead.onUpdate(); this.SpiritPartHead.setLocationAndAngles(this.posX, this.posY + 1.5f, this.posZ, 0F, 0F); this.SpiritPartShoulder1.onUpdate(); this.SpiritPartShoulder1.setLocationAndAngles(this.posX - f2 * 1.0F, this.posY - 0.25F, this.posZ - f1 * 1.0F, 0F, 0F); this.SpiritPartShoulder2.onUpdate(); this.SpiritPartShoulder2.setLocationAndAngles(this.posX + f2 * 1.0F, this.posY - 0.25F, this.posZ + f1 * 1.0F, 0F, 0F); } public Entity[] getParts() { return this.sunSpiritParts; } public void onUpdate() { super.onUpdate(); this.velocity = 0.5D - (double) this.getHealth() / 70.0D * 0.2D; this.width = this.height = 2.0F; if (this.getAttackTarget() instanceof EntityPlayer) { List dungeonPlayers = this.getPlayersInDungeon(); EntityPlayer dungeonTarget = (EntityPlayer) this.getAttackTarget(); PlayerAether playerAether = PlayerAether.get(dungeonTarget); for (int i = 0; i < dungeonPlayers.size(); ++i) { Entity entity = (Entity) dungeonPlayers.get(i); if (entity instanceof EntityPlayer) { PlayerAether dungeonPA = PlayerAether.get((EntityPlayer) entity); if (dungeonPA.getFocusedBoss() != this) { dungeonPA.setFocusedBoss(this); } } } if (dungeonTarget.isDead) { for (int i = 0; i < dungeonPlayers.size(); ++i) { Entity entity = (Entity) dungeonPlayers.get(i); if (entity instanceof EntityPlayer) { PlayerAether dungeonPA = PlayerAether.get((EntityPlayer) entity); dungeonPA.setFocusedBoss(null); } } this.setPosition((double) this.originPointX + 0.5D, (double) this.originPointY, (double) this.originPointZ + 0.5D); this.chatLog = 10; this.motionX = this.motionY = this.motionZ = 0.0D; this.chatLine(dungeonTarget, "\u00a7cSuch is the fate of a being who opposes the might of the sun."); this.chatCount = 100; this.setPosition((double) this.originPointX + 0.5D, (double) this.originPointY, (double) this.originPointZ + 0.5D); this.setDoor(Blocks.air); this.setFreezing(false); this.setAttackTarget(null); this.setHealth(this.getMaxHealth()); } else { playerAether.setFocusedBoss(this); } if (this.isDead()) { this.setFreezing(true); this.chatLine(dungeonTarget, "\u00a7bSuch bitter cold... is this the feeling... of pain?"); this.chatCount = 100; for (int i = 0; i < dungeonPlayers.size(); ++i) { Entity entity = (Entity) dungeonPlayers.get(i); if (entity instanceof EntityPlayer) { ((EntityPlayer) entity).triggerAchievement(AchievementsAether.defeat_gold); } } dungeonTarget.triggerAchievement(AchievementsAether.defeat_gold); if (!AetherConfig.eternalDayDisabled()) { if (!this.worldObj.isRemote) { if (!AetherData.getInstance(this.worldObj).isEternalDay()) { AetherData.getInstance(this.worldObj).setEternalDay(true); } } } this.setDoor(Blocks.air); this.unlockTreasure(); } } this.setFreezing(this.hurtTime > 0); if (this.getHealth() > 0) { double xCoord = this.posX + (this.rand.nextFloat() - 0.5F) * this.rand.nextFloat(); double yCoord = this.boundingBox.minY + this.rand.nextFloat() - 0.5D; double zCoord = this.posZ + (this.rand.nextFloat() - 0.5F) * this.rand.nextFloat(); this.worldObj.spawnParticle("flame", xCoord, yCoord, zCoord, 0.0D, -0.07500000298023224D, 0.0D); this.burnEntities(); this.evapWater(); } if (this.chatCount > 0) { --this.chatCount; } } @Override protected void updateEntityActionState() { super.updateEntityActionState(); if (this.getAttackTarget() != null) { this.motionY = 0.0D; this.renderYawOffset = this.rotationYaw; this.setPosition(this.posX, (double) this.originPointY, this.posZ); boolean changedCourse = false; if (this.motionX >= 0.0D && this.posX > (double) this.originPointX + 8.5D) { this.rotary = 360.0D - this.rotary; changedCourse = true; } else if (this.motionX <= 0.0D && this.posX < (double) this.originPointX - 10D) { this.rotary = 360.0D - this.rotary; changedCourse = true; } if (this.motionZ >= 0.0D && this.posZ > (double) this.originPointZ + 10.0D) { this.rotary = 180.0D - this.rotary; changedCourse = true; } else if (this.motionZ <= 0.0D && this.posZ < (double) this.originPointZ - 9.0D) { this.rotary = 180.0D - this.rotary; changedCourse = true; } if (this.rotary > 360.0D) { this.rotary -= 360.0D; } else if (this.rotary < 0.0D) { this.rotary += 360.0D; } this.faceEntity(this.getAttackTarget(), 20.0F, 20.0F); double angle = this.rotary / (180D / Math.PI); this.motionX = Math.sin(angle) * this.velocity; this.motionZ = Math.cos(angle) * this.velocity; ++this.motionTimer; if (this.motionTimer >= 20 || changedCourse) { if (this.rand.nextInt(3) == 0) { this.rotary += (double) (this.rand.nextFloat() - this.rand.nextFloat()) * 60.0D; } this.motionTimer = 0; } ++this.flameCount; if (this.flameCount == 40) { this.summonFire(); } else if (this.flameCount >= 55 + this.getHealth() / 2) { this.makeFireBall(1); this.flameCount = 0; } } } @Override public void updateAITasks() { super.updateAITasks(); } public void burnEntities() { List entityList = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(0.0D, 4.0D, 0.0D)); for (int ammount = 0; ammount < entityList.size(); ++ammount) { Entity entity = (Entity) entityList.get(ammount); if (entity instanceof EntityLivingBase && !entity.isImmuneToFire()) { entity.attackEntityFrom(new EntityDamageSource("incineration", this), 10); entity.setFire(15); } } } public void evapWater() { int var1 = MathHelper.floor_double(this.boundingBox.minX + (this.boundingBox.maxX - this.boundingBox.minX) / 2.0D); int var2 = MathHelper.floor_double(this.boundingBox.minZ + (this.boundingBox.maxZ - this.boundingBox.minZ) / 2.0D); byte radius = 10; for (int var4 = var1 - radius; var4 <= var1 + radius; ++var4) { for (int var5 = var2 - radius; var5 <= var2 + radius; ++var5) { for (int var6 = 0; var6 < 8; ++var6) { int var7 = this.originPointY - 2 + var6; if (this.worldObj.getBlock(var4, var7, var5).getMaterial() == Material.water) { this.worldObj.setBlock(var4, var7, var5, Blocks.air); this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ, "random.fizz", 2.0F, this.rand.nextFloat() - this.rand.nextFloat() * 0.2F + 1.2F); for (int var8 = 0; var8 < 8; ++var8) { this.worldObj.spawnParticle("largesmoke", (double) var4 + Math.random(), (double) var7 + 0.75D, (double) var5 + Math.random(), 0.0D, 0.0D, 0.0D); } } } } } } public void makeFireBall(int var1) { this.worldObj.playSoundAtEntity(this, "mob.ghast.fireball", this.rand.nextFloat() - this.rand.nextFloat() * 0.2F + 1.2F, 1.0F); boolean shootIceyBall = false; ++this.ballCount; if (this.ballCount >= 2 + this.rand.nextInt(3)) { shootIceyBall = true; this.ballCount = 0; } for (int var3 = 0; var3 < var1; ++var3) { EntityCrystal crystal = new EntityCrystal(this.worldObj, this.posX - this.motionX / 2.0D, this.posY, this.posZ - this.motionZ / 2.0D, shootIceyBall ? EnumCrystalType.ICE : EnumCrystalType.FIRE); if (!this.worldObj.isRemote) { this.worldObj.spawnEntityInWorld(crystal); } } } public void summonFire() { int x = MathHelper.floor_double(this.posX); int z = MathHelper.floor_double(this.posZ); int y = this.originPointY - 2; if (this.worldObj.isAirBlock(x, y, z)) { this.worldObj.setBlock(x, y, z, Blocks.fire); } } private void chatLine(EntityPlayer player, String s) { Side side = FMLCommonHandler.instance().getEffectiveSide(); if (this.chatCount <= 0 || (!AetherConfig.repeatSunSpiritDialogue() && ((PlayerAether) AetherAPI.get(player)).seenSpiritDialog)) { if (side == Side.CLIENT) { Aether.proxy.sendMessage(player, s); } } } public boolean chatWithMe(EntityPlayer entityPlayer) { if (this.chatCount <= 0) { if (AetherConfig.repeatSunSpiritDialogue() || !((PlayerAether) AetherAPI.get(entityPlayer)).seenSpiritDialog) { if (this.getChatLine() == 0) { this.chatLine(entityPlayer, "\u00a7cYou are certainly a brave soul to have entered this chamber."); this.setChatLine(1); } else if (this.getChatLine() == 1) { this.chatLine(entityPlayer, "\u00a7cBegone human, you serve no purpose here."); this.setChatLine(2); } else if (this.getChatLine() == 2) { this.chatLine(entityPlayer, "\u00a7cYour presence annoys me. Do you not fear my burning aura?"); this.setChatLine(3); } else if (this.getChatLine() == 3) { this.chatLine(entityPlayer, "\u00a7cI have nothing to offer you, fool. Leave me at peace."); this.setChatLine(4); } else if (this.getChatLine() == 4) { this.chatLine(entityPlayer, "\u00a7cPerhaps you are ignorant. Do you wish to know who I am?"); this.setChatLine(5); } else if (this.getChatLine() == 5) { this.chatLine(entityPlayer, "\u00a7cI am a sun spirit, embodiment of Aether's eternal daylight. As "); this.chatLine(entityPlayer, "\u00a7clong as I am alive, the sun will never set on this world."); this.setChatLine(6); } else if (this.getChatLine() == 6) { this.chatLine(entityPlayer, "\u00a7cMy body burns with the anger of a thousand beasts. No man, "); this.chatLine(entityPlayer, "\u00a7chero, or villain can harm me. You are no exception."); this.setChatLine(7); } else if (this.getChatLine() == 7) { this.chatLine(entityPlayer, "\u00a7cYou wish to challenge the might of the sun? You are mad. "); this.chatLine(entityPlayer, "\u00a7cDo not further insult me or you will feel my wrath."); this.setChatLine(8); } else if (this.getChatLine() == 8) { this.chatLine(entityPlayer, "\u00a7cThis is your final warning. Leave now, or prepare to burn."); this.setChatLine(9); } else { if (this.getChatLine() == 9) { this.chatLine(entityPlayer, "\u00a76As you wish, your death will be slow and agonizing."); this.setChatLine(10); return true; } if (this.getChatLine() == 10 && this.getAttackTarget() == null) { this.chatLine(entityPlayer, "\u00a7cDid your previous death not satisfy your curiosity, human?"); this.setChatLine(9); } } } else if (((PlayerAether) AetherAPI.get(entityPlayer)).seenSpiritDialog) { this.setChatLine(9); if (this.getChatLine() == 9) { this.chatLine(entityPlayer, "\u00a76As you wish, your death will be slow and agonizing."); this.setChatLine(10); return true; } if (this.getChatLine() == 10 && this.getAttackTarget() == null) { this.chatLine(entityPlayer, "\u00a7cDid your previous death not satisfy your curiosity, human?"); this.setChatLine(9); } } } return false; } @Override public boolean interact(EntityPlayer player) { if (this.chatWithMe(player)) { this.rotary = (180D / Math.PI) * Math.atan2(this.posX - player.posX, this.posZ - player.posZ); this.setAttackTarget(player); this.setDoor(BlocksAether.locked_hellfire_stone); return true; } return false; } @Override public void addVelocity(double x, double y, double z) { } @Override public void knockBack(Entity entity, float strength, double xRatio, double zRatio) { } @Override public boolean attackEntityFrom(DamageSource source, float amount) { System.out.println(true); if (source.getSourceOfDamage() instanceof EntityCrystal) { if (((EntityCrystal) source.getSourceOfDamage()).getCrystalType() == EnumCrystalType.ICE) { this.velocity = 0.5D - (double) this.getHealth() / 70.0D * 0.2D; boolean flag = super.attackEntityFrom(source, amount); if (flag) { EntityFireMinion minion = new EntityFireMinion(this.worldObj); minion.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F); minion.setAttackTarget(this.getAttackTarget()); if (!this.worldObj.isRemote) { this.worldObj.spawnEntityInWorld(minion); } } return flag; } else { return false; } } else { return false; } } @Override public boolean attackEntityFromPart(EntityDragonPart part, DamageSource source, float damage) { return this.attackEntityFrom(source, damage); } @Override protected void dropFewItems(boolean var1, int var2) { this.entityDropItem(new ItemStack(ItemsAether.dungeon_key, 1, 2), 0.5F); } @Override public EntityItem entityDropItem(ItemStack stack, float offsetY) { if (stack.stackSize != 0 && stack.getItem() != null) { EntityAetherItem entityitem = new EntityAetherItem(this.worldObj, this.posX, this.posY + (double) offsetY, this.posZ, stack); if (this.captureDrops) this.capturedDrops.add(entityitem); else this.worldObj.spawnEntityInWorld(entityitem); return entityitem; } else { return null; } } private void setDoor(Block block) { int x, y, z; if (this.direction / 2 == 0) { for (y = this.originPointY - 1; y < this.originPointY + 2; ++y) { for (z = this.originPointZ - 1; z < this.originPointZ + 2; ++z) { if (this.worldObj.getBlock(this.originPointX + (this.direction == 0 ? -13 : 13), y, z) != block) { this.worldObj.setBlock(this.originPointX + (this.direction == 0 ? -13 : 13), y, z, block); } } } } else { for (y = this.originPointY - 1; y < this.originPointY + 2; ++y) { for (x = this.originPointX - 1; x < this.originPointX + 2; ++x) { if (this.worldObj.getBlock(x, y, this.originPointZ + (this.direction == 3 ? 13 : -13)) != block) { this.worldObj.setBlock(x, y, this.originPointZ + (this.direction == 3 ? 13 : -13), block); } } } } } private void unlockTreasure() { int x, y, z; if (this.direction / 2 == 0) { for (y = this.originPointY - 1; y < this.originPointY + 2; ++y) { for (z = this.originPointZ - 1; z < this.originPointZ + 2; ++z) { this.worldObj.setBlock(this.originPointX + (this.direction == 0 ? 13 : -13), y, z, Blocks.air); } } } else { for (y = this.originPointY - 1; y < this.originPointY + 2; ++y) { for (x = this.originPointX - 1; x < this.originPointX + 2; ++x) { this.worldObj.setBlock(x, y, this.originPointZ + (this.direction == 3 ? -13 : 13), Blocks.air); } } } for (x = this.originPointX - 20; x < this.originPointX + 20; ++x) { for (y = this.originPointY - 3; y < this.originPointY + 6; ++y) { for (z = this.originPointZ - 20; z < this.originPointZ + 20; ++z) { Block unlock_block = this.worldObj.getBlock(x, y, z); if (unlock_block == BlocksAether.locked_hellfire_stone || unlock_block == BlocksAether.locked_light_hellfire_stone) { this.worldObj.setBlock(x, y, z, ((BlockDungeonBase) unlock_block).getUnlockedBlock()); } } } } } public List getPlayersInDungeon() { return this.worldObj.getEntitiesWithinAABBExcludingEntity(this.getAttackTarget(), AxisAlignedBB.getBoundingBox(this.originPointX, this.originPointY, this.originPointZ, this.originPointX, this.originPointY, this.originPointZ).expand(20, 3, 20)); } public void setOriginPosition(int x, int y, int z) { this.originPointX = x; this.originPointY = y; this.originPointZ = z; } public int getChatLine() { return (int) this.dataWatcher.getWatchableObjectByte(18); } public void setChatLine(int lineNumber) { this.chatCount = 100; this.dataWatcher.updateObject(18, new Byte((byte) lineNumber)); } public boolean isFreezing() { return this.dataWatcher.getWatchableObjectByte(19) == (byte) 1; } public void setFreezing(boolean isFreezing) { this.dataWatcher.updateObject(19, new Byte(isFreezing ? (byte) 1 : (byte) 0)); } public void setBossName(String name) { this.dataWatcher.updateObject(20, name); } public String getName() { return this.dataWatcher.getWatchableObjectString(20); } @Override public String getBossName() { return this.dataWatcher.getWatchableObjectString(20) + ", the Sun Spirit"; } @Override public float getBossHealth() { return this.getHealth(); } @Override public float getMaxBossHealth() { return this.getMaxHealth(); } @Override public World func_82194_d() { return this.worldObj; } }