-the A.I. of some mobs has been improved, to name a few:
--zombies will now shoot arrows if holding a bow, and snowballs and eggs if holding said items
--withers and ender dragons have a better targeting system (withers now go after the player on sight as intended, and ender dragons don't target creative mode players as often)
--vanilla hostile mobs are now part of a peace system, and can no long cause infighting among themselves. They will attack anything that isn't an ally as a team. (vanilla withers are the only exception to this. There is, however, now an "Evil" and a "Good" wither.)
--endermen now act like zombie pigmen. Hit one, and all of them are on you. So do spiders and ghasts
--skeletons, creepers, endermen and withers all have baby versions
--mobs will look back at you if you look them in the eye
--certain mobs have special attacks. all these have a charge that needs to replenish once the ability is used
---spiders can leap super far
---zombies no longer summon allies when hurt, but instead summon allies as a special attack
---zombie pigmen summon as well, but can also switch their gold swords for diamond ones briefly
---creepers throw TNT at their enemies
---dispenser creepers will shoot faster and become invulnerable briefly when low on health. They will explode if the attacker comes to close
---skeletons spawn silverfish at their enemies feet, along with shooting the occasional critical arrow
---silverfish spawn more silverfish
---endermen can scream to give all non-allied mobs around them negative buffs
---slimes and magma cubes suck life out of non-allied entities to heal themselves, and magma cubes also light it on fire
---ghasts can shoot an inescapable explosion at their target
---ender creepers can make illusions of themselves that blow up upon being touched by anything
---blazes can light enemies on fire that are near them, along with applying slowness
---spiders can trap their enemies in webs to prevent escape. If mobGriefing is turned to false, they put slowness on you instead
---witches can toss 3 random potions at their targets
---cave spiders can spit poison
---iron golems can "stomp to create a seismic wave that knocks back attackers
---snow golems can create an aura that heals nearby mobs, give them random good buffs, and even give other snow golems damage to their snowballs
---ender ghasts shoot multiple fireballs, and occasionally shoot fireballs that teleport hit targets
---fights with Withers and The Ender Dragon are MUCH HARDER!
---creepers can shoot LIGHTNING BOLTS at you when charged. Their explosions also cause lightning
---creepers are immune to fire when charged
---blazes set you on fire when they are on fire and they hit you
---slimes and magma cubes heal when they kill something
---most mobs heal when they kill animals
---zombie pigmen turn pigs into zombie pigmen when they kill them
---all mobs have a boost in their stats
---spiders seek out skeletons so they can be ridden, becoming spider jockeys
---mobs now attack in hordes if single ones aren't dealt with
---did I forget to mention that zombies have 3 lives, and can only be killed immediately with fire?!
The Meaning of Life, the Universe, and Everything.
Join Date:
6/17/2015
Posts:
394
Discord:
PsychedeliCon#5929
Member Details
Mod looks great, but why 1.7.10? 1.8 has been out in over a year,and 1.9 is going to be released within the next 2 months most likely... I suggest you update the code to 1.8 and then have somebody compile it for you.
The Meaning of Life, the Universe, and Everything.
Location:
The End, in the largest End City
Join Date:
10/16/2015
Posts:
868
Minecraft:
Umbrella_Ghast
Member Details
I've updated my eclipse to 1.8. The only trouble is that I now have to update all the files so they will work in 1.8, cause all of them were written in 1.7.10.
The Meaning of Life, the Universe, and Everything.
Location:
The End, in the largest End City
Join Date:
10/16/2015
Posts:
868
Minecraft:
Umbrella_Ghast
Member Details
Can't pm. I am right now developing it from the start, and for the moment I'm working on the inter-dimensional mob peace treaty code. If you want, you can see it, cause I do have some code, and I'm relearning the Minecraft code line placement to do so.
public class EntityZombie extends EntityMob implements IRangedAttackMob
{
/** The attribute which determines the chance that this mob will spawn reinforcements */
protected static final IAttribute reinforcementChance = (new RangedAttribute((IAttribute)null, "zombie.spawnReinforcements", 0.0D, 0.0D, 1.0D)).setDescription("Spawn Reinforcements Chance");
private static final UUID babySpeedBoostUUID = UUID.fromString("B9766B59-9566-4402-BC1F-2EE2A276D836");
private static final AttributeModifier babySpeedBoostModifier = new AttributeModifier(babySpeedBoostUUID, "Baby speed boost", 0.5D, 1);
private final EntityAIBreakDoor breakDoor = new EntityAIBreakDoor(this);
/** Ticker used to determine the time remaining for this zombie to convert into a villager when cured. */
private int conversionTime;
private boolean field_146076_bu = false;
/** The width of the entity */
private float zombieWidth = -1.0F;
/** The height of the the entity. */
private float zombieHeight;
private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 1.0D, 20, 60, 15.0F);
private EntityAIAttackOnCollide aiAttackOnCollide = new EntityAIAttackOnCollide(this, EntityLivingBase.class, 1.0D, false);
private static final String __OBFID = "CL_00001702";
private static final Predicate attackEntitySelector = new Predicate()
{
private static final String __OBFID = "CL_00001662";
/**
* Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue
*/
public int getTotalArmorValue()
{
int i = super.getTotalArmorValue() + 2;
if (i > 20)
{
i = 20;
}
return i;
}
public boolean func_146072_bX()
{
return this.field_146076_bu;
}
public void func_146070_a(boolean p_146070_1_)
{
if (this.field_146076_bu != p_146070_1_)
{
this.field_146076_bu = p_146070_1_;
/**
* If Animal, checks if the age timer is negative
*/
public boolean isChild()
{
return this.getDataWatcher().getWatchableObjectByte(12) == 1;
}
/**
* Get the experience points the entity currently has.
*/
protected int getExperiencePoints(EntityPlayer player)
{
if (this.isChild())
{
this.experienceValue = (int)((float)this.experienceValue * 2.5F);
}
return super.getExperiencePoints(player);
}
/**
* Set whether this zombie is a child.
*/
public void setChild(boolean childZombie)
{
this.getDataWatcher().updateObject(12, Byte.valueOf((byte)(childZombie ? 1 : 0)));
if (childZombie)
{
iattributeinstance.applyModifier(babySpeedBoostModifier);
}
}
this.setChildSize(childZombie);
}
/**
* Return whether this zombie is a villager.
*/
public boolean isVillager()
{
return this.getDataWatcher().getWatchableObjectByte(13) == 1;
}
/**
* Set whether this zombie is a villager.
*/
public void setVillager(boolean villager)
{
this.getDataWatcher().updateObject(13, Byte.valueOf((byte)(villager ? 1 : 0)));
}
/**
* 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()
{
if (this.worldObj.isDaytime() && !this.worldObj.isRemote && !this.isChild())
{
float f = this.getBrightness(1.0F);
BlockPos blockpos = new BlockPos(this.posX, (double)Math.round(this.posY), this.posZ);
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
if (!this.worldObj.isRemote && this.isConverting())
{
int i = this.getConversionTimeBoost();
this.conversionTime -= i;
if (this.conversionTime <= 0)
{
this.convertToVillager();
}
}
super.onUpdate();
}
public boolean attackEntityAsMob(Entity p_70652_1_)
{
boolean flag = super.attackEntityAsMob(p_70652_1_);
if (flag)
{
int i = this.worldObj.getDifficulty().getDifficultyId();
/**
* Get this Entity's EnumCreatureAttribute
*/
public EnumCreatureAttribute getCreatureAttribute()
{
return EnumCreatureAttribute.UNDEAD;
}
/**
* Makes entity wear random armor based on difficulty
*/
protected void addRandomArmor()
{
switch (this.rand.nextInt(3))
{
case 0:
this.dropItem(Items.iron_ingot, 1);
break;
case 1:
this.dropItem(Items.carrot, 1);
break;
case 2:
this.dropItem(Items.potato, 1);
}
}
if (this.rand.nextFloat() < (this.worldObj.getDifficulty() == EnumDifficulty.HARD ? 0.05F : 0.01F))
{
int i = this.rand.nextInt(3);
if (i == 0)
{
this.setCurrentItemOrArmor(0, new ItemStack(Items.iron_sword));
}
else
{
this.setCurrentItemOrArmor(0, new ItemStack(Items.iron_shovel));
}
}
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
public void writeEntityToNBT(NBTTagCompound tagCompound)
{
super.writeEntityToNBT(tagCompound);
if (this.isChild())
{
tagCompound.setBoolean("IsBaby", true);
}
if (this.isVillager())
{
tagCompound.setBoolean("IsVillager", true);
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
public void readEntityFromNBT(NBTTagCompound tagCompund)
{
super.readEntityFromNBT(tagCompund);
if (tagCompund.getBoolean("IsBaby"))
{
this.setChild(true);
}
if (tagCompund.getBoolean("IsVillager"))
{
this.setVillager(true);
}
if (tagCompund.hasKey("ConversionTime", 99) && tagCompund.getInteger("ConversionTime") > -1)
{
this.startConversion(tagCompund.getInteger("ConversionTime"));
}
/**
* Sets the held item, or an armor slot. Slot 0 is held item. Slot 1-4 is armor. Params: Item, slot
*/
public void setCurrentItemOrArmor(int slotIn, ItemStack stack)
{
super.setCurrentItemOrArmor(slotIn, stack);
if (!this.worldObj.isRemote && slotIn == 0)
{
this.setCombatTask();
}
}
/**
* This method gets called when the entity kills another one.
*/
public void onKillEntity(EntityLivingBase entityLivingIn)
{
super.onKillEntity(entityLivingIn);
public IEntityLivingData func_180482_a(DifficultyInstance p_180482_1_, IEntityLivingData p_180482_2_)
{
Object p_180482_2_1 = super.func_180482_a(p_180482_1_, p_180482_2_);
float f = p_180482_1_.getClampedAdditionalDifficulty();
this.setCanPickUpLoot(true);
if (p_180482_2_1 == null)
{
p_180482_2_1 = new EntityZombie.GroupData(this.worldObj.rand.nextFloat() < net.minecraftforge.common.ForgeModContainer.zombieBabyChance, this.worldObj.rand.nextFloat() < 0.05F, null);
}
if (p_180482_2_1 instanceof EntityZombie.GroupData)
{
EntityZombie.GroupData groupdata = (EntityZombie.GroupData)p_180482_2_1;
if (groupdata.field_142046_b)
{
this.setVillager(true);
}
if (groupdata.field_142048_a)
{
this.setChild(true);
if ((double)this.worldObj.rand.nextFloat() < 0.05D)
{
List list = this.worldObj.getEntitiesWithinAABB(EntityChicken.class, this.getEntityBoundingBox().expand(5.0D, 3.0D, 5.0D), IEntitySelector.IS_STANDALONE);
/**
* Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
*/
public boolean interact(EntityPlayer player)
{
ItemStack itemstack = player.getCurrentEquippedItem();
if (itemstack.stackSize <= 0)
{
player.inventory.setInventorySlotContents(player.inventory.currentItem, (ItemStack)null);
}
if (!this.worldObj.isRemote)
{
this.startConversion(this.rand.nextInt(2401) + 3600);
}
return true;
}
else
{
return false;
}
}
/**
* Starts converting this zombie into a villager. The zombie converts into a villager after the specified time in
* ticks.
*/
protected void startConversion(int p_82228_1_)
{
this.conversionTime = p_82228_1_;
this.getDataWatcher().updateObject(14, Byte.valueOf((byte)1));
this.removePotionEffect(Potion.weakness.id);
this.addPotionEffect(new PotionEffect(Potion.damageBoost.id, p_82228_1_, Math.min(this.worldObj.getDifficulty().getDifficultyId() - 1, 0)));
this.worldObj.setEntityState(this, (byte)16);
}
/**
* Determines if an entity can be despawned, used on idle far away entities
*/
protected boolean canDespawn()
{
return !this.isConverting();
}
/**
* Returns whether this zombie is in the process of converting to a villager
*/
public boolean isConverting()
{
return this.getDataWatcher().getWatchableObjectByte(14) == 1;
}
/**
* Convert this zombie into a villager.
*/
protected void convertToVillager()
{
EntityVillager entityvillager = new EntityVillager(this.worldObj);
entityvillager.copyLocationAndAnglesFrom(this);
entityvillager.func_180482_a(this.worldObj.getDifficultyForLocation(new BlockPos(entityvillager)), (IEntityLivingData)null);
entityvillager.setLookingForHome();
if (this.isChild())
{
entityvillager.setGrowingAge(-24000);
}
/**
* Return the amount of time decremented from conversionTime every tick.
*/
protected int getConversionTimeBoost()
{
int i = 1;
if (this.rand.nextFloat() < 0.01F)
{
int j = 0;
for (int k = (int)this.posX - 4; k < (int)this.posX + 4 && j < 14; ++k)
{
for (int l = (int)this.posY - 4; l < (int)this.posY + 4 && j < 14; ++l)
{
for (int i1 = (int)this.posZ - 4; i1 < (int)this.posZ + 4 && j < 14; ++i1)
{
Block block = this.worldObj.getBlockState(new BlockPos(k, l, i1)).getBlock();
if (block == Blocks.iron_bars || block == Blocks.bed)
{
if (this.rand.nextFloat() < 0.3F)
{
++i;
}
++j;
}
}
}
}
}
return i;
}
/**
* sets the size of the entity to be half of its current size if true.
*
* @param isChild If the mob is a child it's height and width will be halved. Otherwise the size will remain the
* same.
*/
public void setChildSize(boolean isChild)
{
this.multiplySize(isChild ? 0.5F : 1.0F);
}
/**
* Sets the width and height of the entity. Args: width, height
*/
protected final void setSize(float width, float height)
{
boolean flag = this.zombieWidth > 0.0F && this.zombieHeight > 0.0F;
this.zombieWidth = width;
this.zombieHeight = height;
if (!flag)
{
this.multiplySize(1.0F);
}
}
/**
* Multiplies the height and width by the provided float.
*
* @param size The size to multiply the height and width of the entity by.
*/
protected final void multiplySize(float size)
{
super.setSize(this.zombieWidth * size, this.zombieHeight * size);
}
/**
* Returns the Y Offset of this entity.
*/
public double getYOffset()
{
return super.getYOffset() - 0.5D;
}
/**
* Called when the mob's health reaches 0.
*/
public void onDeath(DamageSource cause)
{
super.onDeath(cause);
class GroupData implements IEntityLivingData
{
public boolean field_142048_a;
public boolean field_142046_b;
private static final String __OBFID = "CL_00001704";
If you read it, you might notice that the zombie implements the IRangedAttackMob interface, in the same way skeletons do. But the zombie also has the attackEntitySelector, just like a wither. It's set to only target mobs that don't use the new isInAlliedSystem boolean.
Can't pm. I am right now developing it from the start, and for the moment I'm working on the inter-dimensional mob peace treaty code. If you want, you can see it, cause I do have some code, and I'm relearning the Minecraft code line placement to do so.
public class EntityZombie extends EntityMob implements IRangedAttackMob
{
/** The attribute which determines the chance that this mob will spawn reinforcements */
protected static final IAttribute reinforcementChance = (new RangedAttribute((IAttribute)null, "zombie.spawnReinforcements", 0.0D, 0.0D, 1.0D)).setDescription("Spawn Reinforcements Chance");
private static final UUID babySpeedBoostUUID = UUID.fromString("B9766B59-9566-4402-BC1F-2EE2A276D836");
private static final AttributeModifier babySpeedBoostModifier = new AttributeModifier(babySpeedBoostUUID, "Baby speed boost", 0.5D, 1);
private final EntityAIBreakDoor breakDoor = new EntityAIBreakDoor(this);
/** Ticker used to determine the time remaining for this zombie to convert into a villager when cured. */
private int conversionTime;
private boolean field_146076_bu = false;
/** The width of the entity */
private float zombieWidth = -1.0F;
/** The height of the the entity. */
private float zombieHeight;
private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 1.0D, 20, 60, 15.0F);
private EntityAIAttackOnCollide aiAttackOnCollide = new EntityAIAttackOnCollide(this, EntityLivingBase.class, 1.0D, false);
private static final String __OBFID = "CL_00001702";
private static final Predicate attackEntitySelector = new Predicate()
{
private static final String __OBFID = "CL_00001662";
/**
* Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue
*/
public int getTotalArmorValue()
{
int i = super.getTotalArmorValue() + 2;
if (i > 20)
{
i = 20;
}
return i;
}
public boolean func_146072_bX()
{
return this.field_146076_bu;
}
public void func_146070_a(boolean p_146070_1_)
{
if (this.field_146076_bu != p_146070_1_)
{
this.field_146076_bu = p_146070_1_;
/**
* If Animal, checks if the age timer is negative
*/
public boolean isChild()
{
return this.getDataWatcher().getWatchableObjectByte(12) == 1;
}
/**
* Get the experience points the entity currently has.
*/
protected int getExperiencePoints(EntityPlayer player)
{
if (this.isChild())
{
this.experienceValue = (int)((float)this.experienceValue * 2.5F);
}
return super.getExperiencePoints(player);
}
/**
* Set whether this zombie is a child.
*/
public void setChild(boolean childZombie)
{
this.getDataWatcher().updateObject(12, Byte.valueOf((byte)(childZombie ? 1 : 0)));
if (childZombie)
{
iattributeinstance.applyModifier(babySpeedBoostModifier);
}
}
this.setChildSize(childZombie);
}
/**
* Return whether this zombie is a villager.
*/
public boolean isVillager()
{
return this.getDataWatcher().getWatchableObjectByte(13) == 1;
}
/**
* Set whether this zombie is a villager.
*/
public void setVillager(boolean villager)
{
this.getDataWatcher().updateObject(13, Byte.valueOf((byte)(villager ? 1 : 0)));
}
/**
* 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()
{
if (this.worldObj.isDaytime() && !this.worldObj.isRemote && !this.isChild())
{
float f = this.getBrightness(1.0F);
BlockPos blockpos = new BlockPos(this.posX, (double)Math.round(this.posY), this.posZ);
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
if (!this.worldObj.isRemote && this.isConverting())
{
int i = this.getConversionTimeBoost();
this.conversionTime -= i;
if (this.conversionTime <= 0)
{
this.convertToVillager();
}
}
super.onUpdate();
}
public boolean attackEntityAsMob(Entity p_70652_1_)
{
boolean flag = super.attackEntityAsMob(p_70652_1_);
if (flag)
{
int i = this.worldObj.getDifficulty().getDifficultyId();
/**
* Get this Entity's EnumCreatureAttribute
*/
public EnumCreatureAttribute getCreatureAttribute()
{
return EnumCreatureAttribute.UNDEAD;
}
/**
* Makes entity wear random armor based on difficulty
*/
protected void addRandomArmor()
{
switch (this.rand.nextInt(3))
{
case 0:
this.dropItem(Items.iron_ingot, 1);
break;
case 1:
this.dropItem(Items.carrot, 1);
break;
case 2:
this.dropItem(Items.potato, 1);
}
}
if (this.rand.nextFloat() < (this.worldObj.getDifficulty() == EnumDifficulty.HARD ? 0.05F : 0.01F))
{
int i = this.rand.nextInt(3);
if (i == 0)
{
this.setCurrentItemOrArmor(0, new ItemStack(Items.iron_sword));
}
else
{
this.setCurrentItemOrArmor(0, new ItemStack(Items.iron_shovel));
}
}
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
public void writeEntityToNBT(NBTTagCompound tagCompound)
{
super.writeEntityToNBT(tagCompound);
if (this.isChild())
{
tagCompound.setBoolean("IsBaby", true);
}
if (this.isVillager())
{
tagCompound.setBoolean("IsVillager", true);
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
public void readEntityFromNBT(NBTTagCompound tagCompund)
{
super.readEntityFromNBT(tagCompund);
if (tagCompund.getBoolean("IsBaby"))
{
this.setChild(true);
}
if (tagCompund.getBoolean("IsVillager"))
{
this.setVillager(true);
}
if (tagCompund.hasKey("ConversionTime", 99) && tagCompund.getInteger("ConversionTime") > -1)
{
this.startConversion(tagCompund.getInteger("ConversionTime"));
}
/**
* Sets the held item, or an armor slot. Slot 0 is held item. Slot 1-4 is armor. Params: Item, slot
*/
public void setCurrentItemOrArmor(int slotIn, ItemStack stack)
{
super.setCurrentItemOrArmor(slotIn, stack);
if (!this.worldObj.isRemote && slotIn == 0)
{
this.setCombatTask();
}
}
/**
* This method gets called when the entity kills another one.
*/
public void onKillEntity(EntityLivingBase entityLivingIn)
{
super.onKillEntity(entityLivingIn);
public IEntityLivingData func_180482_a(DifficultyInstance p_180482_1_, IEntityLivingData p_180482_2_)
{
Object p_180482_2_1 = super.func_180482_a(p_180482_1_, p_180482_2_);
float f = p_180482_1_.getClampedAdditionalDifficulty();
this.setCanPickUpLoot(true);
if (p_180482_2_1 == null)
{
p_180482_2_1 = new EntityZombie.GroupData(this.worldObj.rand.nextFloat() < net.minecraftforge.common.ForgeModContainer.zombieBabyChance, this.worldObj.rand.nextFloat() < 0.05F, null);
}
if (p_180482_2_1 instanceof EntityZombie.GroupData)
{
EntityZombie.GroupData groupdata = (EntityZombie.GroupData)p_180482_2_1;
if (groupdata.field_142046_b)
{
this.setVillager(true);
}
if (groupdata.field_142048_a)
{
this.setChild(true);
if ((double)this.worldObj.rand.nextFloat() < 0.05D)
{
List list = this.worldObj.getEntitiesWithinAABB(EntityChicken.class, this.getEntityBoundingBox().expand(5.0D, 3.0D, 5.0D), IEntitySelector.IS_STANDALONE);
/**
* Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
*/
public boolean interact(EntityPlayer player)
{
ItemStack itemstack = player.getCurrentEquippedItem();
if (itemstack.stackSize <= 0)
{
player.inventory.setInventorySlotContents(player.inventory.currentItem, (ItemStack)null);
}
if (!this.worldObj.isRemote)
{
this.startConversion(this.rand.nextInt(2401) + 3600);
}
return true;
}
else
{
return false;
}
}
/**
* Starts converting this zombie into a villager. The zombie converts into a villager after the specified time in
* ticks.
*/
protected void startConversion(int p_82228_1_)
{
this.conversionTime = p_82228_1_;
this.getDataWatcher().updateObject(14, Byte.valueOf((byte)1));
this.removePotionEffect(Potion.weakness.id);
this.addPotionEffect(new PotionEffect(Potion.damageBoost.id, p_82228_1_, Math.min(this.worldObj.getDifficulty().getDifficultyId() - 1, 0)));
this.worldObj.setEntityState(this, (byte)16);
}
/**
* Determines if an entity can be despawned, used on idle far away entities
*/
protected boolean canDespawn()
{
return !this.isConverting();
}
/**
* Returns whether this zombie is in the process of converting to a villager
*/
public boolean isConverting()
{
return this.getDataWatcher().getWatchableObjectByte(14) == 1;
}
/**
* Convert this zombie into a villager.
*/
protected void convertToVillager()
{
EntityVillager entityvillager = new EntityVillager(this.worldObj);
entityvillager.copyLocationAndAnglesFrom(this);
entityvillager.func_180482_a(this.worldObj.getDifficultyForLocation(new BlockPos(entityvillager)), (IEntityLivingData)null);
entityvillager.setLookingForHome();
if (this.isChild())
{
entityvillager.setGrowingAge(-24000);
}
/**
* Return the amount of time decremented from conversionTime every tick.
*/
protected int getConversionTimeBoost()
{
int i = 1;
if (this.rand.nextFloat() < 0.01F)
{
int j = 0;
for (int k = (int)this.posX - 4; k < (int)this.posX + 4 && j < 14; ++k)
{
for (int l = (int)this.posY - 4; l < (int)this.posY + 4 && j < 14; ++l)
{
for (int i1 = (int)this.posZ - 4; i1 < (int)this.posZ + 4 && j < 14; ++i1)
{
Block block = this.worldObj.getBlockState(new BlockPos(k, l, i1)).getBlock();
if (block == Blocks.iron_bars || block == Blocks.bed)
{
if (this.rand.nextFloat() < 0.3F)
{
++i;
}
++j;
}
}
}
}
}
return i;
}
/**
* sets the size of the entity to be half of its current size if true.
*
* @param isChild If the mob is a child it's height and width will be halved. Otherwise the size will remain the
* same.
*/
public void setChildSize(boolean isChild)
{
this.multiplySize(isChild ? 0.5F : 1.0F);
}
/**
* Sets the width and height of the entity. Args: width, height
*/
protected final void setSize(float width, float height)
{
boolean flag = this.zombieWidth > 0.0F && this.zombieHeight > 0.0F;
this.zombieWidth = width;
this.zombieHeight = height;
if (!flag)
{
this.multiplySize(1.0F);
}
}
/**
* Multiplies the height and width by the provided float.
*
* @param size The size to multiply the height and width of the entity by.
*/
protected final void multiplySize(float size)
{
super.setSize(this.zombieWidth * size, this.zombieHeight * size);
}
/**
* Returns the Y Offset of this entity.
*/
public double getYOffset()
{
return super.getYOffset() - 0.5D;
}
/**
* Called when the mob's health reaches 0.
*/
public void onDeath(DamageSource cause)
{
super.onDeath(cause);
class GroupData implements IEntityLivingData
{
public boolean field_142048_a;
public boolean field_142046_b;
private static final String __OBFID = "CL_00001704";
If you read it, you might notice that the zombie implements the IRangedAttackMob interface, in the same way skeletons do. But the zombie also has the attackEntitySelector, just like a wither. It's set to only target mobs that don't use the new isInAlliedSystem boolean.
Can't pm. I am right now developing it from the start, and for the moment I'm working on the inter-dimensional mob peace treaty code. If you want, you can see it, cause I do have some code, and I'm relearning the Minecraft code line placement to do so.
public class EntityZombie extends EntityMob implements IRangedAttackMob
{
/** The attribute which determines the chance that this mob will spawn reinforcements */
protected static final IAttribute reinforcementChance = (new RangedAttribute((IAttribute)null, "zombie.spawnReinforcements", 0.0D, 0.0D, 1.0D)).setDescription("Spawn Reinforcements Chance");
private static final UUID babySpeedBoostUUID = UUID.fromString("B9766B59-9566-4402-BC1F-2EE2A276D836");
private static final AttributeModifier babySpeedBoostModifier = new AttributeModifier(babySpeedBoostUUID, "Baby speed boost", 0.5D, 1);
private final EntityAIBreakDoor breakDoor = new EntityAIBreakDoor(this);
/** Ticker used to determine the time remaining for this zombie to convert into a villager when cured. */
private int conversionTime;
private boolean field_146076_bu = false;
/** The width of the entity */
private float zombieWidth = -1.0F;
/** The height of the the entity. */
private float zombieHeight;
private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 1.0D, 20, 60, 15.0F);
private EntityAIAttackOnCollide aiAttackOnCollide = new EntityAIAttackOnCollide(this, EntityLivingBase.class, 1.0D, false);
private static final String __OBFID = "CL_00001702";
private static final Predicate attackEntitySelector = new Predicate()
{
private static final String __OBFID = "CL_00001662";
/**
* Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue
*/
public int getTotalArmorValue()
{
int i = super.getTotalArmorValue() + 2;
if (i > 20)
{
i = 20;
}
return i;
}
public boolean func_146072_bX()
{
return this.field_146076_bu;
}
public void func_146070_a(boolean p_146070_1_)
{
if (this.field_146076_bu != p_146070_1_)
{
this.field_146076_bu = p_146070_1_;
/**
* If Animal, checks if the age timer is negative
*/
public boolean isChild()
{
return this.getDataWatcher().getWatchableObjectByte(12) == 1;
}
/**
* Get the experience points the entity currently has.
*/
protected int getExperiencePoints(EntityPlayer player)
{
if (this.isChild())
{
this.experienceValue = (int)((float)this.experienceValue * 2.5F);
}
return super.getExperiencePoints(player);
}
/**
* Set whether this zombie is a child.
*/
public void setChild(boolean childZombie)
{
this.getDataWatcher().updateObject(12, Byte.valueOf((byte)(childZombie ? 1 : 0)));
if (childZombie)
{
iattributeinstance.applyModifier(babySpeedBoostModifier);
}
}
this.setChildSize(childZombie);
}
/**
* Return whether this zombie is a villager.
*/
public boolean isVillager()
{
return this.getDataWatcher().getWatchableObjectByte(13) == 1;
}
/**
* Set whether this zombie is a villager.
*/
public void setVillager(boolean villager)
{
this.getDataWatcher().updateObject(13, Byte.valueOf((byte)(villager ? 1 : 0)));
}
/**
* 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()
{
if (this.worldObj.isDaytime() && !this.worldObj.isRemote && !this.isChild())
{
float f = this.getBrightness(1.0F);
BlockPos blockpos = new BlockPos(this.posX, (double)Math.round(this.posY), this.posZ);
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
if (!this.worldObj.isRemote && this.isConverting())
{
int i = this.getConversionTimeBoost();
this.conversionTime -= i;
if (this.conversionTime <= 0)
{
this.convertToVillager();
}
}
super.onUpdate();
}
public boolean attackEntityAsMob(Entity p_70652_1_)
{
boolean flag = super.attackEntityAsMob(p_70652_1_);
if (flag)
{
int i = this.worldObj.getDifficulty().getDifficultyId();
/**
* Get this Entity's EnumCreatureAttribute
*/
public EnumCreatureAttribute getCreatureAttribute()
{
return EnumCreatureAttribute.UNDEAD;
}
/**
* Makes entity wear random armor based on difficulty
*/
protected void addRandomArmor()
{
switch (this.rand.nextInt(3))
{
case 0:
this.dropItem(Items.iron_ingot, 1);
break;
case 1:
this.dropItem(Items.carrot, 1);
break;
case 2:
this.dropItem(Items.potato, 1);
}
}
if (this.rand.nextFloat() < (this.worldObj.getDifficulty() == EnumDifficulty.HARD ? 0.05F : 0.01F))
{
int i = this.rand.nextInt(3);
if (i == 0)
{
this.setCurrentItemOrArmor(0, new ItemStack(Items.iron_sword));
}
else
{
this.setCurrentItemOrArmor(0, new ItemStack(Items.iron_shovel));
}
}
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
public void writeEntityToNBT(NBTTagCompound tagCompound)
{
super.writeEntityToNBT(tagCompound);
if (this.isChild())
{
tagCompound.setBoolean("IsBaby", true);
}
if (this.isVillager())
{
tagCompound.setBoolean("IsVillager", true);
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
public void readEntityFromNBT(NBTTagCompound tagCompund)
{
super.readEntityFromNBT(tagCompund);
if (tagCompund.getBoolean("IsBaby"))
{
this.setChild(true);
}
if (tagCompund.getBoolean("IsVillager"))
{
this.setVillager(true);
}
if (tagCompund.hasKey("ConversionTime", 99) && tagCompund.getInteger("ConversionTime") > -1)
{
this.startConversion(tagCompund.getInteger("ConversionTime"));
}
/**
* Sets the held item, or an armor slot. Slot 0 is held item. Slot 1-4 is armor. Params: Item, slot
*/
public void setCurrentItemOrArmor(int slotIn, ItemStack stack)
{
super.setCurrentItemOrArmor(slotIn, stack);
if (!this.worldObj.isRemote && slotIn == 0)
{
this.setCombatTask();
}
}
/**
* This method gets called when the entity kills another one.
*/
public void onKillEntity(EntityLivingBase entityLivingIn)
{
super.onKillEntity(entityLivingIn);
public IEntityLivingData func_180482_a(DifficultyInstance p_180482_1_, IEntityLivingData p_180482_2_)
{
Object p_180482_2_1 = super.func_180482_a(p_180482_1_, p_180482_2_);
float f = p_180482_1_.getClampedAdditionalDifficulty();
this.setCanPickUpLoot(true);
if (p_180482_2_1 == null)
{
p_180482_2_1 = new EntityZombie.GroupData(this.worldObj.rand.nextFloat() < net.minecraftforge.common.ForgeModContainer.zombieBabyChance, this.worldObj.rand.nextFloat() < 0.05F, null);
}
if (p_180482_2_1 instanceof EntityZombie.GroupData)
{
EntityZombie.GroupData groupdata = (EntityZombie.GroupData)p_180482_2_1;
if (groupdata.field_142046_b)
{
this.setVillager(true);
}
if (groupdata.field_142048_a)
{
this.setChild(true);
if ((double)this.worldObj.rand.nextFloat() < 0.05D)
{
List list = this.worldObj.getEntitiesWithinAABB(EntityChicken.class, this.getEntityBoundingBox().expand(5.0D, 3.0D, 5.0D), IEntitySelector.IS_STANDALONE);
/**
* Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
*/
public boolean interact(EntityPlayer player)
{
ItemStack itemstack = player.getCurrentEquippedItem();
if (itemstack.stackSize <= 0)
{
player.inventory.setInventorySlotContents(player.inventory.currentItem, (ItemStack)null);
}
if (!this.worldObj.isRemote)
{
this.startConversion(this.rand.nextInt(2401) + 3600);
}
return true;
}
else
{
return false;
}
}
/**
* Starts converting this zombie into a villager. The zombie converts into a villager after the specified time in
* ticks.
*/
protected void startConversion(int p_82228_1_)
{
this.conversionTime = p_82228_1_;
this.getDataWatcher().updateObject(14, Byte.valueOf((byte)1));
this.removePotionEffect(Potion.weakness.id);
this.addPotionEffect(new PotionEffect(Potion.damageBoost.id, p_82228_1_, Math.min(this.worldObj.getDifficulty().getDifficultyId() - 1, 0)));
this.worldObj.setEntityState(this, (byte)16);
}
/**
* Determines if an entity can be despawned, used on idle far away entities
*/
protected boolean canDespawn()
{
return !this.isConverting();
}
/**
* Returns whether this zombie is in the process of converting to a villager
*/
public boolean isConverting()
{
return this.getDataWatcher().getWatchableObjectByte(14) == 1;
}
/**
* Convert this zombie into a villager.
*/
protected void convertToVillager()
{
EntityVillager entityvillager = new EntityVillager(this.worldObj);
entityvillager.copyLocationAndAnglesFrom(this);
entityvillager.func_180482_a(this.worldObj.getDifficultyForLocation(new BlockPos(entityvillager)), (IEntityLivingData)null);
entityvillager.setLookingForHome();
if (this.isChild())
{
entityvillager.setGrowingAge(-24000);
}
/**
* Return the amount of time decremented from conversionTime every tick.
*/
protected int getConversionTimeBoost()
{
int i = 1;
if (this.rand.nextFloat() < 0.01F)
{
int j = 0;
for (int k = (int)this.posX - 4; k < (int)this.posX + 4 && j < 14; ++k)
{
for (int l = (int)this.posY - 4; l < (int)this.posY + 4 && j < 14; ++l)
{
for (int i1 = (int)this.posZ - 4; i1 < (int)this.posZ + 4 && j < 14; ++i1)
{
Block block = this.worldObj.getBlockState(new BlockPos(k, l, i1)).getBlock();
if (block == Blocks.iron_bars || block == Blocks.bed)
{
if (this.rand.nextFloat() < 0.3F)
{
++i;
}
++j;
}
}
}
}
}
return i;
}
/**
* sets the size of the entity to be half of its current size if true.
*
* @param isChild If the mob is a child it's height and width will be halved. Otherwise the size will remain the
* same.
*/
public void setChildSize(boolean isChild)
{
this.multiplySize(isChild ? 0.5F : 1.0F);
}
/**
* Sets the width and height of the entity. Args: width, height
*/
protected final void setSize(float width, float height)
{
boolean flag = this.zombieWidth > 0.0F && this.zombieHeight > 0.0F;
this.zombieWidth = width;
this.zombieHeight = height;
if (!flag)
{
this.multiplySize(1.0F);
}
}
/**
* Multiplies the height and width by the provided float.
*
* @param size The size to multiply the height and width of the entity by.
*/
protected final void multiplySize(float size)
{
super.setSize(this.zombieWidth * size, this.zombieHeight * size);
}
/**
* Returns the Y Offset of this entity.
*/
public double getYOffset()
{
return super.getYOffset() - 0.5D;
}
/**
* Called when the mob's health reaches 0.
*/
public void onDeath(DamageSource cause)
{
super.onDeath(cause);
class GroupData implements IEntityLivingData
{
public boolean field_142048_a;
public boolean field_142046_b;
private static final String __OBFID = "CL_00001704";
If you read it, you might notice that the zombie implements the IRangedAttackMob interface, in the same way skeletons do. But the zombie also has the attackEntitySelector, just like a wither. It's set to only target mobs that don't use the new isInAlliedSystem boolean.
I hope you got that.
What percentage are you at right now finishing the program?
The Meaning of Life, the Universe, and Everything.
Location:
The End, in the largest End City
Join Date:
10/16/2015
Posts:
868
Minecraft:
Umbrella_Ghast
Member Details
Lets just say I'm working on making the Titans more "titan-like". You'll be able to summon them in using the same T structure as you do with Iron golems and withers. I can show the basic layout of a titan totem:
_B_
DDD
_D_
_D_
_D_
The D represent diamond blocks, _ represents air, and the B represents the block used to complete the totem. Just like other totems, you can spawn them in sideways or even upside-down. Here is the list of blocks that can summon the specific titans:
Zombie Titan -> Zombie Head
Skeletons Titan -> Skeleton Skull
Wither Skeleton Titan -> Wither Skeleton Skull
Creeper Titan -> Creeper Head
Spider Titan -> Cobweb (placeholder until I make a Spider Head)
Cave Spider Titan -> Monster Spawner (again, placeholder until I make a Cave Spider Head)
Ender Colossus -> Obsidian
Witherzilla -> replace the diamond blocks with emerald blocks, and B is Bedrock
When spawned in, they start normal sized and, like a wither, grow until they are at maximum size.
Also working on their A.I. and what they do when you fight them. Already have the idea layed out, but I just need to implement it.
Lets just say I'm working on making the Titans more "titan-like". You'll be able to summon them in using the same T structure as you do with Iron golems and withers. I can show the basic layout of a titan totem:
_B_
DDD
_D_
_D_
_D_
The D represent diamond blocks, _ represents air, and the B represents the block used to complete the totem. Just like other totems, you can spawn them in sideways or even upside-down. Here is the list of blocks that can summon the specific titans:
Zombie Titan -> Zombie Head
Skeletons Titan -> Skeleton Skull
Wither Skeleton Titan -> Wither Skeleton Skull
Creeper Titan -> Creeper Head
Spider Titan -> Cobweb (placeholder until I make a Spider Head)
Cave Spider Titan -> Monster Spawner (again, placeholder until I make a Cave Spider Head)
Ender Colossus -> Obsidian
Witherzilla -> replace the diamond blocks with emerald blocks, and B is Bedrock
When spawned in, they start normal sized and, like a wither, grow until they are at maximum size.
Also working on their A.I. and what they do when you fight them. Already have the idea layed out, but I just need to implement it.
Do the titans have special skills like the wither shoots out giant wither skulls...etc? Nice to see this project growing.
The Meaning of Life, the Universe, and Everything.
Location:
The End, in the largest End City
Join Date:
10/16/2015
Posts:
868
Minecraft:
Umbrella_Ghast
Member Details
One things for sure. They all have the ability to summon minions. Since I've discovered the RenderManager file (that's the one that renders every entity in Minecraft), I might be able to do that.
Also, since all Titans have to be built to spawn in, they will be the least of your worries...
One things for sure. They all have the ability to summon minions. Since I've discovered the RenderManager file (that's the one that renders every entity in Minecraft), I might be able to do that.
Also, since all Titans have to be built to spawn in, they will be the least of your worries...
Noice. I'm expecting the titan skeleton to shoot a giant arrow.
Sorry, but this mod is being put on hold until I learn how to make a core mod. Go to this thread instead!
http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/2583152-minecraft-1-8-the-titans-mod-your-world-has-just
If you want just look at the list roll in and give you all the features of this mod. You might have to zoom in on some pictures to get a better look
Your health is now determined by how many levels you have
-better game-play mechanics, and variable health.
-the A.I. of some mobs has been improved, to name a few:
--zombies will now shoot arrows if holding a bow, and snowballs and eggs if holding said items
--withers and ender dragons have a better targeting system (withers now go after the player on sight as intended, and ender dragons don't target creative mode players as often)
--vanilla hostile mobs are now part of a peace system, and can no long cause infighting among themselves. They will attack anything that isn't an ally as a team. (vanilla withers are the only exception to this. There is, however, now an "Evil" and a "Good" wither.)
--endermen now act like zombie pigmen. Hit one, and all of them are on you. So do spiders and ghasts
--skeletons, creepers, endermen and withers all have baby versions
--mobs will look back at you if you look them in the eye
--certain mobs have special attacks. all these have a charge that needs to replenish once the ability is used
---spiders can leap super far
---zombies no longer summon allies when hurt, but instead summon allies as a special attack
---zombie pigmen summon as well, but can also switch their gold swords for diamond ones briefly
---creepers throw TNT at their enemies
---dispenser creepers will shoot faster and become invulnerable briefly when low on health. They will explode if the attacker comes to close
---skeletons spawn silverfish at their enemies feet, along with shooting the occasional critical arrow
---silverfish spawn more silverfish
---endermen can scream to give all non-allied mobs around them negative buffs
---slimes and magma cubes suck life out of non-allied entities to heal themselves, and magma cubes also light it on fire
---ghasts can shoot an inescapable explosion at their target
---ender creepers can make illusions of themselves that blow up upon being touched by anything
---blazes can light enemies on fire that are near them, along with applying slowness
---spiders can trap their enemies in webs to prevent escape. If mobGriefing is turned to false, they put slowness on you instead
---witches can toss 3 random potions at their targets
---cave spiders can spit poison
---iron golems can "stomp to create a seismic wave that knocks back attackers
---snow golems can create an aura that heals nearby mobs, give them random good buffs, and even give other snow golems damage to their snowballs
---ender ghasts shoot multiple fireballs, and occasionally shoot fireballs that teleport hit targets
---fights with Withers and The Ender Dragon are MUCH HARDER!
---creepers can shoot LIGHTNING BOLTS at you when charged. Their explosions also cause lightning
---creepers are immune to fire when charged
---blazes set you on fire when they are on fire and they hit you
---slimes and magma cubes heal when they kill something
---most mobs heal when they kill animals
---zombie pigmen turn pigs into zombie pigmen when they kill them
---all mobs have a boost in their stats
---spiders seek out skeletons so they can be ridden, becoming spider jockeys
---mobs now attack in hordes if single ones aren't dealt with
---did I forget to mention that zombies have 3 lives, and can only be killed immediately with fire?!
humans are back...
This enderman is fighting one of the new mobs: a bugbear!
-old mobs have been re-added, as well as unused ones being given a better purpose.
IT'S THE ZOMBIE TITAN!
ALL HAIL WITHERZILLA!
-new TITANS!
--Skeleton Titan
--Zombie Titan
--Wither Skeleton Titan
--Creeper Titan
--Spider Titan
--Cave Spider Titan
--Ender Colossus
--Witherzilla
New black bear
A lion attacking animals
Bug bears
Zombies reviving (hard to tell, but smoke is what gives it away)
zombie horde vs two hill giants
Yes, that blaze is moving towards the pig so it can torch it by attacking with melee
Leaping spider in action!
A spider trapping two giant rats with it's webbing
Defend this village at all costs!
Creeper lobbing TNT at a human. The explosion did kill the human, but the game lag a bit there
Dispenser Creepers! What dumb-ass thought this was a good idea? (notice the ender creeper to the right?)
A Benderman compared to an Enderman
This wither got hit by an iron golem. Notice anything peculiar about it?
Normal and Baby Creeper
Normal and Baby Skeleton
Normal and Baby Enderman
That zombie ram is about to bring a world of pain to those poor animals
-new mobs
--bears
--lions
--tigers
--dispenser creepers
--new guards to aid in the village defense. Even small villages may have them
--ender creepers
--ender ghasts (they're enormous!)
--siege witches
--crawler zombies and crawler zombie pigmen
--hopping zombie heads
--ghouls
--wights
--mummies and mummy lords
--wraiths
--zombie rams
--large creepers
--rats, both normal and giant
--mice
--foxes to tame
--kobolds
--goblins
--hobgoblins
--bugbears
--ogres, normal, purple and golden
--hill giants
--mountain giants
--shriekers that scream if your too close
--Ur-Eye boss
--beta endermen
--BENDERMEN! (what endermen might turn into if given 5 millions years to evolve. They have telekinesis.)
-new Bosses
--The Zombie King
---able to summon minions at night time
---taunts you
---can grant nearby zombie diamond helmets and swords for a brief period
----if they originally had a bow, they'll be reequipped with it
---uses a totem to spawn:
_H_ = zombie head
_D_ = diamond block
_D_ = diamond block
SSS = stone
--The Skeleton Prince
---able to summon minions at night time
---taunts you
---can grant nearby skeletons fire arrows for a brief period
---uses a totem to spawn:
_H_ = skeleton skull
_D_ = diamond block
_D_ = diamond block
SSS = stone
--The Obsidian Ghast
---fires extremely explosive fireballs
---immune to fire, wither, explosions, arrows, fireballs (mostly), and thorns damage
---has the ability to destroy your ear drums
--"Good" Withers, and their "Evil" counterparts
---automatically fire blue skulls on hard
---evils skulls can corrupt mobs, causing them to attack anything near them
---goods skulls can undo corruption, and do bonus damage against evil withers
---evils summon wither minions: weird monsters with obsidian heads
---goods summon most of the nether and/or undead mobs
--new and improved Ender Dragon, twice the size and speed of the original
---can hover at a minimum of 12 blocks above you. He will try to gain altitude if you go after him
---spits fireballs
---summons endermen that auto attack you
---heals slowly if no non spectator players are close to him
---follows the nearest player
---can knock you a million blocks away if his velocity is high enough.
-wither's flying speed and skull damage are now changeable
-ender dragon's flight speed and attack damage are now changeable
-new structures
--dungeons EVERYWHERE!
--elite dungeons that spawn stronger mobs
--nether dungeons
--end dungeons
--overworld fortresses (like nether ones, but spawns endermen at the spawners instead, and is made of stonebrick)
Wheres the download ??? Looks interesting !
It's not available yet. If someone could convert the .java files into .class files, I'll release it.
Mod looks great, but why 1.7.10? 1.8 has been out in over a year,and 1.9 is going to be released within the next 2 months most likely... I suggest you update the code to 1.8 and then have somebody compile it for you.
Most the links for the mobs don't work (404 file directory not found). Looks great anyway!
my minecraft forge isn't up to date on eclipse. I'll change the title once it is.
I've updated my eclipse to 1.8. The only trouble is that I now have to update all the files so they will work in 1.8, cause all of them were written in 1.7.10.
Hey I can help you with your problem, pm me for more info
I hope you can.
Can't pm. I am right now developing it from the start, and for the moment I'm working on the inter-dimensional mob peace treaty code. If you want, you can see it, cause I do have some code, and I'm relearning the Minecraft code line placement to do so.
I'll use the zombie as an example:
package net.minecraft.entity.monster;
import java.util.Calendar;
import java.util.List;
import java.util.UUID;
import com.google.common.base.Predicate;
import net.minecraft.block.Block;
import net.minecraft.command.IEntitySelector;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.EnumCreatureAttribute;
import net.minecraft.entity.IEntityLivingData;
import net.minecraft.entity.IRangedAttackMob;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.EntityAIArrowAttack;
import net.minecraft.entity.ai.EntityAIAttackOnCollide;
import net.minecraft.entity.ai.EntityAIBreakDoor;
import net.minecraft.entity.ai.EntityAIHurtByTarget;
import net.minecraft.entity.ai.EntityAILookIdle;
import net.minecraft.entity.ai.EntityAIMoveThroughVillage;
import net.minecraft.entity.ai.EntityAIMoveTowardsRestriction;
import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
import net.minecraft.entity.ai.EntityAISwimming;
import net.minecraft.entity.ai.EntityAIWander;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.ai.attributes.AttributeModifier;
import net.minecraft.entity.ai.attributes.IAttribute;
import net.minecraft.entity.ai.attributes.IAttributeInstance;
import net.minecraft.entity.ai.attributes.RangedAttribute;
import net.minecraft.entity.passive.EntityChicken;
import net.minecraft.entity.passive.EntityVillager;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityArrow;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.pathfinding.PathNavigateGround;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.BlockPos;
import net.minecraft.util.DamageSource;
import net.minecraft.util.MathHelper;
import net.minecraft.world.DifficultyInstance;
import net.minecraft.world.EnumDifficulty;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class EntityZombie extends EntityMob implements IRangedAttackMob
{
/** The attribute which determines the chance that this mob will spawn reinforcements */
protected static final IAttribute reinforcementChance = (new RangedAttribute((IAttribute)null, "zombie.spawnReinforcements", 0.0D, 0.0D, 1.0D)).setDescription("Spawn Reinforcements Chance");
private static final UUID babySpeedBoostUUID = UUID.fromString("B9766B59-9566-4402-BC1F-2EE2A276D836");
private static final AttributeModifier babySpeedBoostModifier = new AttributeModifier(babySpeedBoostUUID, "Baby speed boost", 0.5D, 1);
private final EntityAIBreakDoor breakDoor = new EntityAIBreakDoor(this);
/** Ticker used to determine the time remaining for this zombie to convert into a villager when cured. */
private int conversionTime;
private boolean field_146076_bu = false;
/** The width of the entity */
private float zombieWidth = -1.0F;
/** The height of the the entity. */
private float zombieHeight;
private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 1.0D, 20, 60, 15.0F);
private EntityAIAttackOnCollide aiAttackOnCollide = new EntityAIAttackOnCollide(this, EntityLivingBase.class, 1.0D, false);
private static final String __OBFID = "CL_00001702";
private static final Predicate attackEntitySelector = new Predicate()
{
private static final String __OBFID = "CL_00001662";
public boolean func_180027_a(Entity p_180027_1_)
{
return p_180027_1_ instanceof EntityLivingBase && !p_180027_1_.isInAlliedSystem;
}
public boolean apply(Object p_apply_1_)
{
return this.func_180027_a((Entity)p_apply_1_);
}
};
public EntityZombie(World worldIn)
{
super(worldIn);
this.isInAlliedSystem = true;
((PathNavigateGround)this.getNavigator()).func_179688_b(true);
this.tasks.addTask(0, new EntityAISwimming(this));
this.tasks.addTask(1, new EntityAIBreakDoor(this));
this.tasks.addTask(2, this.field_175455_a);
this.tasks.addTask(5, new EntityAIMoveTowardsRestriction(this, 1.0D));
this.tasks.addTask(7, new EntityAIWander(this, 1.0D));
this.tasks.addTask(8, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));
this.tasks.addTask(8, new EntityAILookIdle(this));
this.applyEntityAI();
this.setSize(0.5F, 2.0F);
if (worldIn != null && !worldIn.isRemote)
{
this.setCombatTask();
}
}
protected void applyEntityAI()
{
this.tasks.addTask(6, new EntityAIMoveThroughVillage(this, 1.0D, false));
this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true, new Class[] {EntityPigZombie.class}));
this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityLivingBase.class, 0, false, false, attackEntitySelector));
}
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(32.0D);
this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.25D);
this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(4.0D);
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(30.0D);
this.getAttributeMap().registerAttribute(reinforcementChance).setBaseValue(this.rand.nextDouble() * net.minecraftforge.common.ForgeModContainer.zombieSummonBaseChance);
}
protected void entityInit()
{
super.entityInit();
this.getDataWatcher().addObject(12, Byte.valueOf((byte)0));
this.getDataWatcher().addObject(13, Byte.valueOf((byte)0));
this.getDataWatcher().addObject(14, Byte.valueOf((byte)0));
}
/**
* Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue
*/
public int getTotalArmorValue()
{
int i = super.getTotalArmorValue() + 2;
if (i > 20)
{
i = 20;
}
return i;
}
public boolean func_146072_bX()
{
return this.field_146076_bu;
}
public void func_146070_a(boolean p_146070_1_)
{
if (this.field_146076_bu != p_146070_1_)
{
this.field_146076_bu = p_146070_1_;
if (p_146070_1_)
{
this.tasks.addTask(1, this.breakDoor);
}
else
{
this.tasks.removeTask(this.breakDoor);
}
}
}
/**
* If Animal, checks if the age timer is negative
*/
public boolean isChild()
{
return this.getDataWatcher().getWatchableObjectByte(12) == 1;
}
/**
* Get the experience points the entity currently has.
*/
protected int getExperiencePoints(EntityPlayer player)
{
if (this.isChild())
{
this.experienceValue = (int)((float)this.experienceValue * 2.5F);
}
return super.getExperiencePoints(player);
}
/**
* Set whether this zombie is a child.
*/
public void setChild(boolean childZombie)
{
this.getDataWatcher().updateObject(12, Byte.valueOf((byte)(childZombie ? 1 : 0)));
if (this.worldObj != null && !this.worldObj.isRemote)
{
IAttributeInstance iattributeinstance = this.getEntityAttribute(SharedMonsterAttributes.movementSpeed);
iattributeinstance.removeModifier(babySpeedBoostModifier);
if (childZombie)
{
iattributeinstance.applyModifier(babySpeedBoostModifier);
}
}
this.setChildSize(childZombie);
}
/**
* Return whether this zombie is a villager.
*/
public boolean isVillager()
{
return this.getDataWatcher().getWatchableObjectByte(13) == 1;
}
/**
* Set whether this zombie is a villager.
*/
public void setVillager(boolean villager)
{
this.getDataWatcher().updateObject(13, Byte.valueOf((byte)(villager ? 1 : 0)));
}
/**
* 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()
{
if (this.worldObj.isDaytime() && !this.worldObj.isRemote && !this.isChild())
{
float f = this.getBrightness(1.0F);
BlockPos blockpos = new BlockPos(this.posX, (double)Math.round(this.posY), this.posZ);
if (f > 0.5F && this.rand.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.worldObj.canSeeSky(blockpos))
{
boolean flag = true;
ItemStack itemstack = this.getEquipmentInSlot(4);
if (itemstack != null)
{
if (itemstack.isItemStackDamageable())
{
itemstack.setItemDamage(itemstack.getItemDamage() + this.rand.nextInt(2));
if (itemstack.getItemDamage() >= itemstack.getMaxDamage())
{
this.renderBrokenItemStack(itemstack);
this.setCurrentItemOrArmor(4, (ItemStack)null);
}
}
flag = false;
}
if (flag)
{
this.setFire(8);
}
}
}
if (this.isRiding() && this.getAttackTarget() != null && this.ridingEntity instanceof EntityChicken)
{
((EntityLiving)this.ridingEntity).getNavigator().setPath(this.getNavigator().getPath(), 1.5D);
}
super.onLivingUpdate();
}
/**
* Called when the entity is attacked.
*/
public boolean attackEntityFrom(DamageSource source, float amount)
{
Entity entity0;
entity0 = source.getEntity();
if (entity0 != null && entity0.isInAlliedSystem)
{
return false;
}
if (super.attackEntityFrom(source, amount))
{
EntityLivingBase entitylivingbase = this.getAttackTarget();
if (entitylivingbase == null && source.getEntity() instanceof EntityLivingBase)
{
entitylivingbase = (EntityLivingBase)source.getEntity();
}
int i = MathHelper.floor_double(this.posX);
int j = MathHelper.floor_double(this.posY);
int k = MathHelper.floor_double(this.posZ);
net.minecraftforge.event.entity.living.ZombieEvent.SummonAidEvent summonAid = net.minecraftforge.event.ForgeEventFactory.fireZombieSummonAid(this, worldObj, i, j, k, entitylivingbase, this.getEntityAttribute(reinforcementChance).getAttributeValue());
if (summonAid.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.DENY) return true;
if (summonAid.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW ||
entitylivingbase != null && this.worldObj.getDifficulty() == EnumDifficulty.HARD && (double)this.rand.nextFloat() < this.getEntityAttribute(reinforcementChance).getAttributeValue())
{
EntityZombie entityzombie;
if (summonAid.customSummonedAid != null && summonAid.getResult() == net.minecraftforge.fml.common.eventhandler.Event.Result.ALLOW)
{
entityzombie = summonAid.customSummonedAid;
}
else
{
entityzombie = new EntityZombie(this.worldObj);
}
for (int l = 0; l < 50; ++l)
{
int i1 = i + MathHelper.getRandomIntegerInRange(this.rand, 7, 40) * MathHelper.getRandomIntegerInRange(this.rand, -1, 1);
int j1 = j + MathHelper.getRandomIntegerInRange(this.rand, 7, 40) * MathHelper.getRandomIntegerInRange(this.rand, -1, 1);
int k1 = k + MathHelper.getRandomIntegerInRange(this.rand, 7, 40) * MathHelper.getRandomIntegerInRange(this.rand, -1, 1);
if (World.doesBlockHaveSolidTopSurface(this.worldObj, new BlockPos(i1, j1 - 1, k1)) && this.worldObj.getLightFromNeighbors(new BlockPos(i1, j1, k1)) < 10)
{
entityzombie.setPosition((double)i1, (double)j1, (double)k1);
if (!this.worldObj.func_175636_b((double)i1, (double)j1, (double)k1, 7.0D) && this.worldObj.checkNoEntityCollision(entityzombie.getEntityBoundingBox(), entityzombie) && this.worldObj.getCollidingBoundingBoxes(entityzombie, entityzombie.getEntityBoundingBox()).isEmpty() && !this.worldObj.isAnyLiquid(entityzombie.getEntityBoundingBox()))
{
this.worldObj.spawnEntityInWorld(entityzombie);
if (entitylivingbase != null) entityzombie.setAttackTarget(entitylivingbase);
entityzombie.func_180482_a(this.worldObj.getDifficultyForLocation(new BlockPos(entityzombie)), (IEntityLivingData)null);
this.getEntityAttribute(reinforcementChance).applyModifier(new AttributeModifier("Zombie reinforcement caller charge", -0.05000000074505806D, 0));
entityzombie.getEntityAttribute(reinforcementChance).applyModifier(new AttributeModifier("Zombie reinforcement callee charge", -0.05000000074505806D, 0));
break;
}
}
}
}
return true;
}
else
{
return false;
}
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
if (!this.worldObj.isRemote && this.isConverting())
{
int i = this.getConversionTimeBoost();
this.conversionTime -= i;
if (this.conversionTime <= 0)
{
this.convertToVillager();
}
}
super.onUpdate();
}
public boolean attackEntityAsMob(Entity p_70652_1_)
{
boolean flag = super.attackEntityAsMob(p_70652_1_);
if (flag)
{
int i = this.worldObj.getDifficulty().getDifficultyId();
if (this.getHeldItem() == null && this.isBurning() && this.rand.nextFloat() < (float)i * 0.3F)
{
p_70652_1_.setFire(2 * i);
}
}
return flag;
}
/**
* Returns the sound this mob makes while it's alive.
*/
protected String getLivingSound()
{
return "mob.zombie.say";
}
/**
* Returns the sound this mob makes when it is hurt.
*/
protected String getHurtSound()
{
return "mob.zombie.hurt";
}
/**
* Returns the sound this mob makes on death.
*/
protected String getDeathSound()
{
return "mob.zombie.death";
}
protected void playStepSound(BlockPos p_180429_1_, Block p_180429_2_)
{
this.playSound("mob.zombie.step", 0.15F, 1.0F);
}
protected Item getDropItem()
{
return Items.rotten_flesh;
}
/**
* Get this Entity's EnumCreatureAttribute
*/
public EnumCreatureAttribute getCreatureAttribute()
{
return EnumCreatureAttribute.UNDEAD;
}
/**
* Makes entity wear random armor based on difficulty
*/
protected void addRandomArmor()
{
switch (this.rand.nextInt(3))
{
case 0:
this.dropItem(Items.iron_ingot, 1);
break;
case 1:
this.dropItem(Items.carrot, 1);
break;
case 2:
this.dropItem(Items.potato, 1);
}
}
protected void func_180481_a(DifficultyInstance p_180481_1_)
{
super.func_180481_a(p_180481_1_);
if (this.rand.nextFloat() < (this.worldObj.getDifficulty() == EnumDifficulty.HARD ? 0.05F : 0.01F))
{
int i = this.rand.nextInt(3);
if (i == 0)
{
this.setCurrentItemOrArmor(0, new ItemStack(Items.iron_sword));
}
else
{
this.setCurrentItemOrArmor(0, new ItemStack(Items.iron_shovel));
}
}
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
public void writeEntityToNBT(NBTTagCompound tagCompound)
{
super.writeEntityToNBT(tagCompound);
if (this.isChild())
{
tagCompound.setBoolean("IsBaby", true);
}
if (this.isVillager())
{
tagCompound.setBoolean("IsVillager", true);
}
tagCompound.setInteger("ConversionTime", this.isConverting() ? this.conversionTime : -1);
tagCompound.setBoolean("CanBreakDoors", this.func_146072_bX());
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
public void readEntityFromNBT(NBTTagCompound tagCompund)
{
super.readEntityFromNBT(tagCompund);
if (tagCompund.getBoolean("IsBaby"))
{
this.setChild(true);
}
if (tagCompund.getBoolean("IsVillager"))
{
this.setVillager(true);
}
if (tagCompund.hasKey("ConversionTime", 99) && tagCompund.getInteger("ConversionTime") > -1)
{
this.startConversion(tagCompund.getInteger("ConversionTime"));
}
this.func_146070_a(tagCompund.getBoolean("CanBreakDoors"));
this.setCombatTask();
}
/**
* Sets the held item, or an armor slot. Slot 0 is held item. Slot 1-4 is armor. Params: Item, slot
*/
public void setCurrentItemOrArmor(int slotIn, ItemStack stack)
{
super.setCurrentItemOrArmor(slotIn, stack);
if (!this.worldObj.isRemote && slotIn == 0)
{
this.setCombatTask();
}
}
/**
* This method gets called when the entity kills another one.
*/
public void onKillEntity(EntityLivingBase entityLivingIn)
{
super.onKillEntity(entityLivingIn);
if ((this.worldObj.getDifficulty() == EnumDifficulty.NORMAL || this.worldObj.getDifficulty() == EnumDifficulty.HARD) && entityLivingIn instanceof EntityVillager)
{
if (this.worldObj.getDifficulty() != EnumDifficulty.HARD && this.rand.nextBoolean())
{
return;
}
EntityZombie entityzombie = new EntityZombie(this.worldObj);
entityzombie.copyLocationAndAnglesFrom(entityLivingIn);
this.worldObj.removeEntity(entityLivingIn);
entityzombie.func_180482_a(this.worldObj.getDifficultyForLocation(new BlockPos(entityzombie)), (IEntityLivingData)null);
entityzombie.setVillager(true);
if (entityLivingIn.isChild())
{
entityzombie.setChild(true);
}
this.worldObj.spawnEntityInWorld(entityzombie);
this.worldObj.playAuxSFXAtEntity((EntityPlayer)null, 1016, new BlockPos((int)this.posX, (int)this.posY, (int)this.posZ), 0);
}
}
public float getEyeHeight()
{
float f = 1.74F;
if (this.isChild())
{
f = (float)((double)f - 0.81D);
}
return f;
}
protected boolean func_175448_a(ItemStack p_175448_1_)
{
return p_175448_1_.getItem() == Items.egg && this.isChild() && this.isRiding() ? false : super.func_175448_a(p_175448_1_);
}
public IEntityLivingData func_180482_a(DifficultyInstance p_180482_1_, IEntityLivingData p_180482_2_)
{
Object p_180482_2_1 = super.func_180482_a(p_180482_1_, p_180482_2_);
float f = p_180482_1_.getClampedAdditionalDifficulty();
this.setCanPickUpLoot(true);
if (p_180482_2_1 == null)
{
p_180482_2_1 = new EntityZombie.GroupData(this.worldObj.rand.nextFloat() < net.minecraftforge.common.ForgeModContainer.zombieBabyChance, this.worldObj.rand.nextFloat() < 0.05F, null);
}
if (p_180482_2_1 instanceof EntityZombie.GroupData)
{
EntityZombie.GroupData groupdata = (EntityZombie.GroupData)p_180482_2_1;
if (groupdata.field_142046_b)
{
this.setVillager(true);
}
if (groupdata.field_142048_a)
{
this.setChild(true);
if ((double)this.worldObj.rand.nextFloat() < 0.05D)
{
List list = this.worldObj.getEntitiesWithinAABB(EntityChicken.class, this.getEntityBoundingBox().expand(5.0D, 3.0D, 5.0D), IEntitySelector.IS_STANDALONE);
if (!list.isEmpty())
{
EntityChicken entitychicken = (EntityChicken)list.get(0);
entitychicken.setChickenJockey(true);
this.mountEntity(entitychicken);
}
}
else if ((double)this.worldObj.rand.nextFloat() < 0.05D)
{
EntityChicken entitychicken1 = new EntityChicken(this.worldObj);
entitychicken1.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F);
entitychicken1.func_180482_a(p_180482_1_, (IEntityLivingData)null);
entitychicken1.setChickenJockey(true);
this.worldObj.spawnEntityInWorld(entitychicken1);
this.mountEntity(entitychicken1);
}
}
}
if (this.rand.nextFloat() < 0.25F)
{
this.setCurrentItemOrArmor(0, new ItemStack(Items.bow));
this.tasks.addTask(4, this.aiArrowAttack);
}
else
{
this.tasks.addTask(4, this.aiAttackOnCollide);
}
this.func_146070_a(this.rand.nextFloat() < f * 0.1F);
this.func_180481_a(p_180482_1_);
this.func_180483_b(p_180482_1_);
if (this.getEquipmentInSlot(4) == null)
{
Calendar calendar = this.worldObj.getCurrentDate();
if (calendar.get(2) + 1 == 10 && calendar.get(5) == 31 && this.rand.nextFloat() < 0.25F)
{
this.setCurrentItemOrArmor(4, new ItemStack(this.rand.nextFloat() < 0.1F ? Blocks.lit_pumpkin : Blocks.pumpkin));
this.equipmentDropChances[4] = 0.0F;
}
}
this.getEntityAttribute(SharedMonsterAttributes.knockbackResistance).applyModifier(new AttributeModifier("Random spawn bonus", this.rand.nextDouble() * 0.05000000074505806D, 0));
double d0 = this.rand.nextDouble() * 1.5D * (double)f;
if (d0 > 1.0D)
{
this.getEntityAttribute(SharedMonsterAttributes.followRange).applyModifier(new AttributeModifier("Random zombie-spawn bonus", d0, 2));
}
if (this.rand.nextFloat() < f * 0.05F)
{
this.getEntityAttribute(reinforcementChance).applyModifier(new AttributeModifier("Leader zombie bonus", this.rand.nextDouble() * 0.25D + 0.5D, 0));
this.getEntityAttribute(SharedMonsterAttributes.maxHealth).applyModifier(new AttributeModifier("Leader zombie bonus", this.rand.nextDouble() * 3.0D + 1.0D, 2));
this.func_146070_a(true);
}
return (IEntityLivingData)p_180482_2_1;
}
/**
* Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
*/
public boolean interact(EntityPlayer player)
{
ItemStack itemstack = player.getCurrentEquippedItem();
if (itemstack != null && itemstack.getItem() == Items.golden_apple && itemstack.getMetadata() == 0 && this.isVillager() && this.isPotionActive(Potion.weakness))
{
if (!player.capabilities.isCreativeMode)
{
--itemstack.stackSize;
}
if (itemstack.stackSize <= 0)
{
player.inventory.setInventorySlotContents(player.inventory.currentItem, (ItemStack)null);
}
if (!this.worldObj.isRemote)
{
this.startConversion(this.rand.nextInt(2401) + 3600);
}
return true;
}
else
{
return false;
}
}
/**
* Starts converting this zombie into a villager. The zombie converts into a villager after the specified time in
* ticks.
*/
protected void startConversion(int p_82228_1_)
{
this.conversionTime = p_82228_1_;
this.getDataWatcher().updateObject(14, Byte.valueOf((byte)1));
this.removePotionEffect(Potion.weakness.id);
this.addPotionEffect(new PotionEffect(Potion.damageBoost.id, p_82228_1_, Math.min(this.worldObj.getDifficulty().getDifficultyId() - 1, 0)));
this.worldObj.setEntityState(this, (byte)16);
}
@SideOnly(Side.CLIENT)
public void handleHealthUpdate(byte p_70103_1_)
{
if (p_70103_1_ == 16)
{
if (!this.isSilent())
{
this.worldObj.playSound(this.posX + 0.5D, this.posY + 0.5D, this.posZ + 0.5D, "mob.zombie.remedy", 1.0F + this.rand.nextFloat(), this.rand.nextFloat() * 0.7F + 0.3F, false);
}
}
else
{
super.handleHealthUpdate(p_70103_1_);
}
}
/**
* Determines if an entity can be despawned, used on idle far away entities
*/
protected boolean canDespawn()
{
return !this.isConverting();
}
/**
* Returns whether this zombie is in the process of converting to a villager
*/
public boolean isConverting()
{
return this.getDataWatcher().getWatchableObjectByte(14) == 1;
}
/**
* Convert this zombie into a villager.
*/
protected void convertToVillager()
{
EntityVillager entityvillager = new EntityVillager(this.worldObj);
entityvillager.copyLocationAndAnglesFrom(this);
entityvillager.func_180482_a(this.worldObj.getDifficultyForLocation(new BlockPos(entityvillager)), (IEntityLivingData)null);
entityvillager.setLookingForHome();
if (this.isChild())
{
entityvillager.setGrowingAge(-24000);
}
this.worldObj.removeEntity(this);
this.worldObj.spawnEntityInWorld(entityvillager);
entityvillager.addPotionEffect(new PotionEffect(Potion.confusion.id, 200, 0));
this.worldObj.playAuxSFXAtEntity((EntityPlayer)null, 1017, new BlockPos((int)this.posX, (int)this.posY, (int)this.posZ), 0);
}
/**
* Return the amount of time decremented from conversionTime every tick.
*/
protected int getConversionTimeBoost()
{
int i = 1;
if (this.rand.nextFloat() < 0.01F)
{
int j = 0;
for (int k = (int)this.posX - 4; k < (int)this.posX + 4 && j < 14; ++k)
{
for (int l = (int)this.posY - 4; l < (int)this.posY + 4 && j < 14; ++l)
{
for (int i1 = (int)this.posZ - 4; i1 < (int)this.posZ + 4 && j < 14; ++i1)
{
Block block = this.worldObj.getBlockState(new BlockPos(k, l, i1)).getBlock();
if (block == Blocks.iron_bars || block == Blocks.bed)
{
if (this.rand.nextFloat() < 0.3F)
{
++i;
}
++j;
}
}
}
}
}
return i;
}
/**
* sets the size of the entity to be half of its current size if true.
*
* @param isChild If the mob is a child it's height and width will be halved. Otherwise the size will remain the
* same.
*/
public void setChildSize(boolean isChild)
{
this.multiplySize(isChild ? 0.5F : 1.0F);
}
/**
* Sets the width and height of the entity. Args: width, height
*/
protected final void setSize(float width, float height)
{
boolean flag = this.zombieWidth > 0.0F && this.zombieHeight > 0.0F;
this.zombieWidth = width;
this.zombieHeight = height;
if (!flag)
{
this.multiplySize(1.0F);
}
}
/**
* Multiplies the height and width by the provided float.
*
* @param size The size to multiply the height and width of the entity by.
*/
protected final void multiplySize(float size)
{
super.setSize(this.zombieWidth * size, this.zombieHeight * size);
}
/**
* Returns the Y Offset of this entity.
*/
public double getYOffset()
{
return super.getYOffset() - 0.5D;
}
/**
* Called when the mob's health reaches 0.
*/
public void onDeath(DamageSource cause)
{
super.onDeath(cause);
if (cause.getEntity() instanceof EntityCreeper && !(this instanceof EntityPigZombie) && ((EntityCreeper)cause.getEntity()).getPowered() && ((EntityCreeper)cause.getEntity()).isAIEnabled())
{
((EntityCreeper)cause.getEntity()).func_175493_co();
this.entityDropItem(new ItemStack(Items.skull, 1, 2), 0.0F);
}
}
/**
* sets this entity's combat AI.
*/
public void setCombatTask()
{
this.tasks.removeTask(this.aiAttackOnCollide);
this.tasks.removeTask(this.aiArrowAttack);
ItemStack itemstack = this.getHeldItem();
if (itemstack != null && itemstack.getItem() == Items.bow)
{
this.tasks.addTask(4, this.aiArrowAttack);
}
else
{
this.tasks.addTask(4, this.aiAttackOnCollide);
}
}
/**
* Attack the specified entity using a ranged attack.
*/
public void attackEntityWithRangedAttack(EntityLivingBase p_82196_1_, float p_82196_2_)
{
EntityArrow entityarrow = new EntityArrow(this.worldObj, this, p_82196_1_, 1.6F, (float)(14 - this.worldObj.getDifficulty().getDifficultyId() * 4));
int i = EnchantmentHelper.getEnchantmentLevel(Enchantment.power.effectId, this.getHeldItem());
int j = EnchantmentHelper.getEnchantmentLevel(Enchantment.punch.effectId, this.getHeldItem());
entityarrow.setDamage((double)(p_82196_2_ * 2.0F) + this.rand.nextGaussian() * 0.25D + (double)((float)this.worldObj.getDifficulty().getDifficultyId() * 0.11F));
if (i > 0)
{
entityarrow.setDamage(entityarrow.getDamage() + (double)i * 0.5D + 0.5D);
}
if (j > 0)
{
entityarrow.setKnockbackStrength(j);
}
if (EnchantmentHelper.getEnchantmentLevel(Enchantment.flame.effectId, this.getHeldItem()) > 0)
{
entityarrow.setFire(100);
}
this.playSound("random.bow", 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F));
this.worldObj.spawnEntityInWorld(entityarrow);
}
class GroupData implements IEntityLivingData
{
public boolean field_142048_a;
public boolean field_142046_b;
private static final String __OBFID = "CL_00001704";
private GroupData(boolean p_i2348_2_, boolean p_i2348_3_)
{
this.field_142048_a = false;
this.field_142046_b = false;
this.field_142048_a = p_i2348_2_;
this.field_142046_b = p_i2348_3_;
}
GroupData(boolean p_i2349_2_, boolean p_i2349_3_, Object p_i2349_4_)
{
this(p_i2349_2_, p_i2349_3_);
}
}
}
If you read it, you might notice that the zombie implements the IRangedAttackMob interface, in the same way skeletons do. But the zombie also has the attackEntitySelector, just like a wither. It's set to only target mobs that don't use the new isInAlliedSystem boolean.
I hope you got that.
Nice coding there. It's very fine work indeed...
What percentage are you at right now finishing the program?
Lets just say I'm working on making the Titans more "titan-like". You'll be able to summon them in using the same T structure as you do with Iron golems and withers. I can show the basic layout of a titan totem:
_B_
DDD
_D_
_D_
_D_
The D represent diamond blocks, _ represents air, and the B represents the block used to complete the totem. Just like other totems, you can spawn them in sideways or even upside-down. Here is the list of blocks that can summon the specific titans:
Zombie Titan -> Zombie Head
Skeletons Titan -> Skeleton Skull
Wither Skeleton Titan -> Wither Skeleton Skull
Creeper Titan -> Creeper Head
Spider Titan -> Cobweb (placeholder until I make a Spider Head)
Cave Spider Titan -> Monster Spawner (again, placeholder until I make a Cave Spider Head)
Ender Colossus -> Obsidian
Witherzilla -> replace the diamond blocks with emerald blocks, and B is Bedrock
When spawned in, they start normal sized and, like a wither, grow until they are at maximum size.
Also working on their A.I. and what they do when you fight them. Already have the idea layed out, but I just need to implement it.
Do the titans have special skills like the wither shoots out giant wither skulls...etc? Nice to see this project growing.
One things for sure. They all have the ability to summon minions. Since I've discovered the RenderManager file (that's the one that renders every entity in Minecraft), I might be able to do that.
Also, since all Titans have to be built to spawn in, they will be the least of your worries...
Noice. I'm expecting the titan skeleton to shoot a giant arrow.
Well, I can give an image of my progress. These are the Titans that are so far active and summonable:
Excellent mobs! I can see the spawn next to them. btw, what's your next thing on the update list?
The next thing comes once I'm done and the download is avaliable. It'll be mob abilities.
Sounds and looks nice, but I really hope there is a good config!