diff --git a/client/src/main/java/client/renderer/entity/RenderChicken.java b/client/src/main/java/client/renderer/entity/RenderChicken.java index 9afeff9..d9f885c 100755 --- a/client/src/main/java/client/renderer/entity/RenderChicken.java +++ b/client/src/main/java/client/renderer/entity/RenderChicken.java @@ -27,8 +27,8 @@ public class RenderChicken extends RenderLiving */ protected float handleRotationFloat(EntityChicken livingBase, float partialTicks) { - float f = livingBase.field_70888_h + (livingBase.wingRotation - livingBase.field_70888_h) * partialTicks; - float f1 = livingBase.field_70884_g + (livingBase.destPos - livingBase.field_70884_g) * partialTicks; + float f = livingBase.lastWingRotation + (livingBase.wingRotation - livingBase.lastWingRotation) * partialTicks; + float f1 = livingBase.lastDestPos + (livingBase.destPos - livingBase.lastDestPos) * partialTicks; return (ExtMath.sin(f) + 1.0F) * f1; } } diff --git a/common/src/main/java/common/entity/animal/EntityChicken.java b/common/src/main/java/common/entity/animal/EntityChicken.java index d285f9a..98ff744 100755 --- a/common/src/main/java/common/entity/animal/EntityChicken.java +++ b/common/src/main/java/common/entity/animal/EntityChicken.java @@ -1,14 +1,19 @@ package common.entity.animal; +import common.ai.EntityAIAttackOnCollide; import common.ai.EntityAIFollowParent; import common.ai.EntityAILookIdle; import common.ai.EntityAIMate; +import common.ai.EntityAINearestAttackableTarget; import common.ai.EntityAIPanic; import common.ai.EntityAISwimming; import common.ai.EntityAITempt; import common.ai.EntityAIWander; import common.ai.EntityAIWatchClosest; import common.attributes.Attribute; +import common.entity.DamageSource; +import common.entity.Entity; +import common.entity.npc.Alignment; import common.entity.npc.EntityNPC; import common.entity.types.EntityAnimal; import common.entity.types.EntityLiving; @@ -21,225 +26,185 @@ import common.util.ExtMath; import common.vars.Vars; import common.world.World; -public class EntityChicken extends EntityAnimal -{ - public float wingRotation; - public float destPos; - public float field_70884_g; - public float field_70888_h; - public float wingRotDelta = 1.0F; +public class EntityChicken extends EntityAnimal { + private final EntityAIAttackOnCollide attack = new EntityAIAttackOnCollide(this, EntityNPC.class, 1.4, false); + private final EntityAINearestAttackableTarget targetter = new EntityAINearestAttackableTarget(this, EntityNPC.class, true); + + public float wingRotation; + public float lastWingRotation; + public float destPos; + public float lastDestPos; + private float wingRotDelta = 1.0F; + private int eggTimer; + private boolean noEggs; + private boolean attackSet; - /** The time until the next egg is spawned. */ - public int timeUntilNextEgg; - public boolean chickenJockey; + public EntityChicken(World world) { + super(world); + this.setSize(0.4F, 0.7F); + this.eggTimer = world.client || Vars.eggTimer <= 0 ? 1000 : this.rand.excl(Vars.eggTimer, Vars.eggTimer * 2); + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAIPanic(this, 1.4D)); + this.tasks.addTask(2, new EntityAIMate(this, 1.0D)); + this.tasks.addTask(3, new EntityAITempt(this, 1.0D, Items.wheat, false)); + this.tasks.addTask(4, new EntityAIFollowParent(this, 1.1D)); + this.tasks.addTask(5, new EntityAIWander(this, 1.0D)); + this.tasks.addTask(6, new EntityAIWatchClosest(this, null, 6.0F)); + this.tasks.addTask(7, new EntityAILookIdle(this)); + } - public EntityChicken(World worldIn) - { - super(worldIn); - this.setSize(0.4F, 0.7F); - this.timeUntilNextEgg = worldIn.client || Vars.eggTimer <= 0 ? 1000 : this.rand.excl(Vars.eggTimer, Vars.eggTimer * 2); - this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(1, new EntityAIPanic(this, 1.4D)); - this.tasks.addTask(2, new EntityAIMate(this, 1.0D)); - this.tasks.addTask(3, new EntityAITempt(this, 1.0D, Items.wheat, false)); - this.tasks.addTask(4, new EntityAIFollowParent(this, 1.1D)); - this.tasks.addTask(5, new EntityAIWander(this, 1.0D)); - this.tasks.addTask(6, new EntityAIWatchClosest(this, null, 6.0F)); - this.tasks.addTask(7, new EntityAILookIdle(this)); - } + public float getEyeHeight() { + return this.height; + } - public float getEyeHeight() - { - return this.height; - } + protected void entityInit() { + super.entityInit(); + this.dataWatcher.addObject(18, Byte.valueOf((byte)0)); + } - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.setMaxHealth(4); - this.getEntityAttribute(Attribute.MOVEMENT_SPEED).setBaseValue(0.25D); - } + protected void applyEntityAttributes() { + super.applyEntityAttributes(); + this.setMaxHealth(4); + this.getEntityAttribute(Attribute.MOVEMENT_SPEED).setBaseValue(0.25D); + } - /** - * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons - * use this to react to sunlight and start to burn. - */ - public void onLivingUpdate() - { - super.onLivingUpdate(); - this.field_70888_h = this.wingRotation; - this.field_70884_g = this.destPos; - this.destPos = (float)((double)this.destPos + (double)(this.onGround ? -1 : 4) * 0.3D); - this.destPos = ExtMath.clampf(this.destPos, 0.0F, 1.0F); + public void onLivingUpdate() { + super.onLivingUpdate(); + this.lastWingRotation = this.wingRotation; + this.lastDestPos = this.destPos; + this.destPos = (float)((double)this.destPos + (double)(this.onGround ? -1 : 4) * 0.3D); + this.destPos = ExtMath.clampf(this.destPos, 0.0F, 1.0F); + if(!this.onGround && this.wingRotDelta < 1.0F) + this.wingRotDelta = 1.0F; + this.wingRotDelta = (float)((double)this.wingRotDelta * 0.9D); + if(!this.onGround && this.motionY < 0.0D) + this.motionY *= 0.6D; + this.wingRotation += this.wingRotDelta * 2.0F; + if(!this.worldObj.client) { + if(Vars.eggTimer > 0 && !this.isChild() && !this.noEggs && --this.eggTimer <= 0) { + this.playSound(SoundEvent.PLOP, 1.0F); + this.dropItem(Items.egg, 1); + this.eggTimer = this.rand.excl(Vars.eggTimer, Vars.eggTimer * 2); + } + boolean evil = this.canBeEvil(); + if(evil != this.attackSet) { + if(evil) { + this.tasks.addTask(1, this.attack); + this.targets.addTask(1, this.targetter); + } + else { + this.tasks.removeTask(this.attack); + this.targets.removeTask(this.targetter); + } + this.attackSet = evil; + } + } + } - if (!this.onGround && this.wingRotDelta < 1.0F) - { - this.wingRotDelta = 1.0F; - } + public void fall(float distance, float damage) { + } - this.wingRotDelta = (float)((double)this.wingRotDelta * 0.9D); + protected SoundEvent getLivingSound() { + return SoundEvent.CHICKEN_IDLE; + } - if (!this.onGround && this.motionY < 0.0D) - { - this.motionY *= 0.6D; - } + protected SoundEvent getHurtSound() { + return SoundEvent.CHICKEN_HIT; + } - this.wingRotation += this.wingRotDelta * 2.0F; + protected SoundEvent getDeathSound() { + return SoundEvent.CHICKEN_HIT; + } - if (!this.worldObj.client && Vars.eggTimer > 0 && !this.isChild() && !this.isChickenJockey() && --this.timeUntilNextEgg <= 0) - { - this.playSound(SoundEvent.PLOP, 1.0F); - this.dropItem(Items.egg, 1); - this.timeUntilNextEgg = this.rand.excl(Vars.eggTimer, Vars.eggTimer * 2); - } - } + protected Item getDropItem() { + return Items.feather; + } - public void fall(float distance, float damageMultiplier) - { - } + protected void dropFewItems(boolean hit, int looting) { + int amt = this.rand.zrange(3) + this.rand.zrange(1 + looting); + for(int z = 0; z < amt; z++) { + this.dropItem(Items.feather, 1); + } + this.dropItem(this.isBurning() ? Items.cooked_chicken : Items.chicken, 1); + } - /** - * Returns the sound this mob makes while it's alive. - */ - protected SoundEvent getLivingSound() - { - return SoundEvent.CHICKEN_IDLE; - } + public EntityChicken createChild(EntityLiving entity) { + EntityChicken chick = new EntityChicken(this.worldObj); + chick.setEvil(this.isEvil()); + chick.setNotLaying(this.isNotLaying()); + return chick; + } - /** - * Returns the sound this mob makes when it is hurt. - */ - protected SoundEvent getHurtSound() - { - return SoundEvent.CHICKEN_HIT; - } + public boolean isBreedingItem(ItemStack stack) { + return stack != null && stack.getItem() == Items.wheat; + } - /** - * Returns the sound this mob makes on death. - */ - protected SoundEvent getDeathSound() - { - return SoundEvent.CHICKEN_HIT; - } + public void readEntity(TagObject tag) { + super.readEntity(tag); + this.setEvil(tag.getBool("evil")); + this.noEggs = tag.getBool("noEggs"); + this.eggTimer = tag.getInt("eggTime"); + } -// protected void playStepSound(BlockPos pos, Block blockIn) -// { -// this.playSound("mob.chicken.step", 0.15F, 1.0F); -// } + public void writeEntity(TagObject tag) { + super.writeEntity(tag); + tag.setBool("evil", this.isEvil()); + tag.setBool("noEggs", this.noEggs); + tag.setInt("eggTime", this.eggTimer); + } - protected Item getDropItem() - { - return Items.feather; - } + public void updateRiderPosition() { + super.updateRiderPosition(); + float x = ExtMath.sin(this.yawOffset * (float)Math.PI / 180.0F); + float z = ExtMath.cos(this.yawOffset * (float)Math.PI / 180.0F); + float mult = 0.1F; + float off = 0.0F; + this.passenger.setPosition(this.posX + (double)(mult * x), + this.posY + (double)(this.height * 0.5F) + this.passenger.getYOffset() + (double)off, this.posZ - (double)(mult * z)); + if(this.passenger instanceof EntityLiving) + ((EntityLiving)this.passenger).yawOffset = this.yawOffset; + } - /** - * Drop 0-2 items of this living's type - * - * @param wasRecentlyHit true if this this entity was recently hit by appropriate entity (generally only if player - * or tameable) - * @param lootingModifier level of enchanment to be applied to this drop - */ - protected void dropFewItems(boolean wasRecentlyHit, int lootingModifier) - { - int i = this.rand.zrange(3) + this.rand.zrange(1 + lootingModifier); + public boolean attackEntityAsMob(Entity entityIn) { + if(!this.worldObj.client && !Vars.damageMobs) + return false; + return entityIn.attackEntityFrom(DamageSource.causeMobDamage(this), this.isChild() ? 1 : 2); + } + + public Object onInitialSpawn(Object livingdata) { + livingdata = super.onInitialSpawn(livingdata); + if(Vars.evilChickenChance > 0 && this.rand.chance(Vars.evilChickenChance)) + this.setEvil(true); + if(this.rand.chance(15)) + this.setGrowingAge(-24000); + return livingdata; + } + + protected boolean canBeEvil() { + return this.isEvil() || Vars.aggressiveChickens; + } - for (int j = 0; j < i; ++j) - { - this.dropItem(Items.feather, 1); - } + public boolean isEvil() { + return this.dataWatcher.getWatchableObjectByte(18) != 0; + } - if (this.isBurning()) - { - this.dropItem(Items.cooked_chicken, 1); - } - else - { - this.dropItem(Items.chicken, 1); - } - } + public void setEvil(boolean evil) { + this.dataWatcher.updateObject(18, (byte)(evil ? 1 : 0)); + } - public EntityChicken createChild(EntityLiving ageable) - { - return new EntityChicken(this.worldObj); - } + public boolean isNotLaying() { + return this.noEggs; + } - /** - * Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on - * the animal type) - */ - public boolean isBreedingItem(ItemStack stack) - { - return stack != null && stack.getItem() == Items.wheat; - } + public void setNotLaying(boolean noEggs) { + this.noEggs = noEggs; + } - /** - * (abstract) Protected helper method to read subclass entity data from NBT. - */ - public void readEntity(TagObject tagCompund) - { - super.readEntity(tagCompund); - this.chickenJockey = tagCompund.getBool("IsChickenJockey"); - this.timeUntilNextEgg = tagCompund.getInt("EggLayTime"); - } - - /** - * Get the experience points the entity currently has. - */ - protected int getExperiencePoints(EntityNPC player) - { - return this.isChickenJockey() ? 10 : super.getExperiencePoints(player); - } - - /** - * (abstract) Protected helper method to write subclass entity data to NBT. - */ - public void writeEntity(TagObject tagCompound) - { - super.writeEntity(tagCompound); - tagCompound.setBool("IsChickenJockey", this.chickenJockey); - tagCompound.setInt("EggLayTime", this.timeUntilNextEgg); - } - -// /** -// * Determines if an entity can be despawned, used on idle far away entities -// */ -// protected boolean canDespawn() -// { -// return this.isChickenJockey() && this.passenger == null; -// } - - public void updateRiderPosition() - { - super.updateRiderPosition(); - float f = ExtMath.sin(this.yawOffset * (float)Math.PI / 180.0F); - float f1 = ExtMath.cos(this.yawOffset * (float)Math.PI / 180.0F); - float f2 = 0.1F; - float f3 = 0.0F; - this.passenger.setPosition(this.posX + (double)(f2 * f), this.posY + (double)(this.height * 0.5F) + this.passenger.getYOffset() + (double)f3, this.posZ - (double)(f2 * f1)); - - if (this.passenger instanceof EntityLiving) - { - ((EntityLiving)this.passenger).yawOffset = this.yawOffset; - } - } - - /** - * Determines if this chicken is a jokey with a zombie riding it. - */ - public boolean isChickenJockey() - { - return this.chickenJockey; - } - - /** - * Sets whether this chicken is a jockey or not. - */ - public void setChickenJockey(boolean jockey) - { - this.chickenJockey = jockey; - } - public int getColor() { return 0xdb5152; } + + public Alignment getAlignment() { + return this.isEvil() ? Alignment.CHAOTIC_EVIL : Alignment.CHAOTIC; + } } diff --git a/common/src/main/java/common/entity/npc/EntityNPC.java b/common/src/main/java/common/entity/npc/EntityNPC.java index d906a6f..30de48f 100755 --- a/common/src/main/java/common/entity/npc/EntityNPC.java +++ b/common/src/main/java/common/entity/npc/EntityNPC.java @@ -440,8 +440,8 @@ public abstract class EntityNPC extends EntityLiving public boolean shouldFlee(EntityLiving entity) { return (this.getHealth() <= (this.getMaxHealth() / 4) || !this.canCounter(entity)) && - ((entity instanceof EntityNPC && (((EntityNPC)entity).canAttack(this)) || - (entity == this.getAttackedBy() && ((EntityNPC)entity).canCounter(this)))); + ((entity instanceof EntityNPC && ((((EntityNPC)entity).canAttack(this)) || + (entity == this.getAttackedBy() && ((EntityNPC)entity).canCounter(this))))); } // public void setCombatTask() @@ -893,7 +893,7 @@ public abstract class EntityNPC extends EntityLiving public void setAttackedBy(EntityLiving livingBase) { if(livingBase != null && /* livingBase.isPlayer() && */ this.isEntityAlive() && /* !this.isPeaceful() && */ this.getAttackedBy() != livingBase && - Vars.mobAttacks) { + Vars.mobAttacks && !this.isPlayer()) { this.worldObj.setEntityState(this, (byte)13); } super.setAttackedBy(livingBase); diff --git a/common/src/main/java/common/entity/npc/EntityZombie.java b/common/src/main/java/common/entity/npc/EntityZombie.java index 1aaf728..a816488 100755 --- a/common/src/main/java/common/entity/npc/EntityZombie.java +++ b/common/src/main/java/common/entity/npc/EntityZombie.java @@ -219,7 +219,7 @@ public class EntityZombie extends EntityNPC if (!list.isEmpty()) { EntityChicken entitychicken = (EntityChicken)list.get(0); - entitychicken.setChickenJockey(true); + entitychicken.setNotLaying(true); this.mountEntity(entitychicken); } } @@ -228,7 +228,7 @@ public class EntityZombie extends EntityNPC EntityChicken entitychicken1 = new EntityChicken(this.worldObj); entitychicken1.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotYaw, 0.0F); entitychicken1.onInitialSpawn(null); - entitychicken1.setChickenJockey(true); + entitychicken1.setNotLaying(true); this.worldObj.spawnEntityInWorld(entitychicken1); this.mountEntity(entitychicken1); } diff --git a/common/src/main/java/common/vars/Vars.java b/common/src/main/java/common/vars/Vars.java index d8327bb..a3b25ad 100755 --- a/common/src/main/java/common/vars/Vars.java +++ b/common/src/main/java/common/vars/Vars.java @@ -200,6 +200,8 @@ public abstract class Vars { public static boolean mergeFinite = false; @Var(name = "veryHungryRabbits") public static boolean rabidRabbits = false; + @Var(name = "evilFowl") + public static boolean aggressiveChickens = false; @Var(name = "hurtCooldown") public static int hurtDelay = 20; @@ -213,6 +215,8 @@ public abstract class Vars { public static int rabbitMateChance = 10; @Var(name = "killerBunnyChance") public static int killerBunnyChance = 1000; + @Var(name = "evilChickenChance") + public static int evilChickenChance = 700; @Var(name = "fallPortalHeight") public static int portalHeight = 256; @Var(name = "damageOrb")