package drzhark.mocreatures.entity; import java.util.List; import drzhark.mocreatures.MoCTools; import drzhark.mocreatures.MoCreatures; import drzhark.mocreatures.entity.item.MoCEntityEgg; import drzhark.mocreatures.entity.item.MoCEntityKittyBed; import drzhark.mocreatures.entity.item.MoCEntityLitterBox; import drzhark.mocreatures.entity.passive.MoCEntityHorse; import drzhark.mocreatures.network.MoCServerPacketHandler; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityAgeable; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.passive.EntityAnimal; import net.minecraft.entity.passive.EntityWolf; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.Item; import net.minecraft.item.ItemFood; import net.minecraft.item.ItemSeeds; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.pathfinding.PathEntity; import net.minecraft.util.DamageSource; import net.minecraft.util.MathHelper; import net.minecraft.util.Vec3; import net.minecraft.world.World; public abstract class MoCEntityAnimal extends EntityAnimal implements MoCIMoCreature { protected boolean divePending; protected boolean jumpPending; protected int temper; protected boolean isEntityJumping; public EntityLiving roper; private PathEntity entitypath; private int mountCount; public MoCEntityAnimal(World world) { super(world); setTamed(false); setAdult(true); //selectType(); } /** * Put your code to choose a texture / the mob type in here. Will be called * by default MocEntity constructors. */ @Override public void selectType() { setType(1); } @Override public void initCreature() { selectType(); super.initCreature(); } @Override public EntityAgeable createChild(EntityAgeable var1) { return null; } @Override protected void entityInit() { super.entityInit(); dataWatcher.addObject(15, Byte.valueOf((byte) 0)); // isAdult - 0 false 1 true dataWatcher.addObject(16, Byte.valueOf((byte) 0)); // isTamed - 0 false 1 true dataWatcher.addObject(17, String.valueOf("")); // displayName empty string by default dataWatcher.addObject(18, Integer.valueOf(0)); // int ageTicks / "edad" dataWatcher.addObject(19, Integer.valueOf(0)); // int type dataWatcher.addObject(20, String.valueOf("")); //owners name } public void setType(int i) { //if (!MoCreatures.isServer()) return; dataWatcher.updateObject(19, Integer.valueOf(i)); } @Override public int getType() { return dataWatcher.getWatchableObjectInt(19); } public void setDisplayName(boolean flag) { } public boolean getDisplayName() { return (getName() != null && !getName().equals("")); } @Override public boolean getIsAdult() { return (dataWatcher.getWatchableObjectByte(15) == 1); } @Override public boolean getIsTamed() { return (dataWatcher.getWatchableObjectByte(16) == 1); } @Override public String getName() { return this.dataWatcher.getWatchableObjectString(17); } /** * @return networked Entity "Age" in integer value, typical values are * 0-100. Old float eDad was typically 0F-1.0F */ public int getEdad() { return dataWatcher.getWatchableObjectInt(18); } public boolean getIsJumping() { return isEntityJumping; } public void setEdad(int i) { dataWatcher.updateObject(18, Integer.valueOf(i)); } @Override public void setAdult(boolean flag) { byte input = (byte) (flag ? 1 : 0); dataWatcher.updateObject(15, Byte.valueOf(input)); } @Override public void setName(String name) { //if (!MoCreatures.isServer()) return; dataWatcher.updateObject(17, String.valueOf(name)); } @Override public void setTamed(boolean flag) { byte input = (byte) (flag ? 1 : 0); dataWatcher.updateObject(16, Byte.valueOf(input)); } public void setIsJumping(boolean flag) { isEntityJumping = flag; } @Override protected boolean canDespawn() { return !getIsTamed(); } /** * called in getCanSpawnHere to make sure the right type of creature spawns * in the right biome i.e. snakes, rays, bears, BigCats and later wolves, * etc. */ @Override public boolean checkSpawningBiome() { return true; } protected EntityLiving getClosestEntityLiving(Entity entity, double d) { double d1 = -1D; EntityLiving entityliving = null; List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.expand(d, d, d)); for (int i = 0; i < list.size(); i++) { Entity entity1 = (Entity) list.get(i); if (entitiesToIgnore(entity1)) { continue; } double d2 = entity1.getDistanceSq(entity.posX, entity.posY, entity.posZ); if (((d < 0.0D) || (d2 < (d * d))) && ((d1 == -1D) || (d2 < d1)) && ((EntityLiving) entity1).canEntityBeSeen(entity)) { d1 = d2; entityliving = (EntityLiving) entity1; } } return entityliving; } protected EntityLiving getClosestSpecificEntity(Entity entity, Class myClass, double d) { double d1 = -1D; EntityLiving entityliving = null; List list = worldObj.getEntitiesWithinAABBExcludingEntity(entity, entity.boundingBox.expand(d, d, d)); for (int i = 0; i < list.size(); i++) { Entity entity1 = (Entity) list.get(i); if (!myClass.isAssignableFrom(entity1.getClass())) { continue; } double d2 = entity1.getDistanceSq(entity.posX, entity.posY, entity.posZ); if (((d < 0.0D) || (d2 < (d * d))) && ((d1 == -1D) || (d2 < d1)))// && ((EntityLiving) entity1).canEntityBeSeen(entity)) { d1 = d2; entityliving = (EntityLiving) entity1; } } return entityliving; } public boolean entitiesToIgnore(Entity entity) { return ((!(entity instanceof EntityLiving)) || (entity instanceof EntityMob) || (entity instanceof EntityPlayer && this.getIsTamed()) || (entity instanceof MoCEntityKittyBed) || (entity instanceof MoCEntityLitterBox) || (this.getIsTamed() && (entity instanceof MoCIMoCreature && ((MoCIMoCreature) entity).getIsTamed())) || ((entity instanceof EntityWolf) && !(MoCreatures.proxy.attackWolves)) || ((entity instanceof MoCEntityHorse) && !(MoCreatures.proxy.attackHorses)) || (entity.width >= this.width || entity.height >= this.height) || (entity instanceof MoCEntityEgg) ); } public void runLikeHell(Entity entity) { double d = posX - entity.posX; double d1 = posZ - entity.posZ; double d2 = Math.atan2(d, d1); d2 += (rand.nextFloat() - rand.nextFloat()) * 0.75D; double d3 = posX + (Math.sin(d2) * 8D); double d4 = posZ + (Math.cos(d2) * 8D); int i = MathHelper.floor_double(d3); int j = MathHelper.floor_double(boundingBox.minY); int k = MathHelper.floor_double(d4); int l = 0; do { if (l >= 16) { break; } int i1 = (i + rand.nextInt(4)) - rand.nextInt(4); int j1 = (j + rand.nextInt(3)) - rand.nextInt(3); int k1 = (k + rand.nextInt(4)) - rand.nextInt(4); if ((j1 > 4) && ((worldObj.getBlockId(i1, j1, k1) == 0) || (worldObj.getBlockId(i1, j1, k1) == Block.snow.blockID)) && (worldObj.getBlockId(i1, j1 - 1, k1) != 0)) { PathEntity pathentity = worldObj.getEntityPathToXYZ(this, i1, j1, k1, 16F, true, false, false, true); setPathToEntity(pathentity); break; } l++; } while (true); } /** * Finds and entity described in entitiesToInclude at d distance * * @param d * @return */ protected EntityLiving getBoogey(double d) { double d1 = -1D; EntityLiving entityliving = null; List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.expand(d, 4D, d)); for (int i = 0; i < list.size(); i++) { Entity entity = (Entity) list.get(i); if (entitiesToInclude(entity)) { entityliving = (EntityLiving) entity; } } return entityliving; } /** * Used in getBoogey to specify what kind of entity to look for * * @param entity * @return */ public boolean entitiesToInclude(Entity entity) { return ( (entity.getClass() != this.getClass()) && (entity instanceof EntityLiving) && ((entity.width >= 0.5D) || (entity.height >= 0.5D)) ); } @Override public void onLivingUpdate() { if (MoCreatures.isServer()) { if (rideableEntity() && this.riddenByEntity != null) { Riding(); mountCount = 1; } if (mountCount > 0) { if (++mountCount > 50) { mountCount = 0; } } if (forceUpdates() && rand.nextInt(500) == 0) { MoCTools.forceDataSync(this); } if (getIsTamed() && rand.nextInt(100) == 0) { MoCServerPacketHandler.sendHealth(this.entityId, this.worldObj.provider.dimensionId, this.getHealth()); } } if (isNotScared() && fleeingTick > 0) { fleeingTick = 0; } if (isSwimming() && swimmerEntity()) { floating(); } if (!isMovementCeased() && entityToAttack == null) { followPlayer(); } moveSpeed = getMoveSpeed(); super.onLivingUpdate(); } public boolean isNotScared() { return false; } public boolean swimmerEntity() { return false; } public boolean isSwimming() { return ((isInsideOfMaterial(Material.water))); } /*public void setMaxHealth(int i) { maxHealth = i; }*/ public void floating() { if (motionY < 0) { motionY = 0; } motionY += 0.001D;// 0.001 int distY = (int) MoCTools.distanceToSurface(this); if (distY > 1) { motionY += (distY * 0.07); } if (hasPath() && isCollidedHorizontally) { jump(); } } /* * public boolean stuckInWater() { return * ((isInsideOfMaterial(Material.water)) && !inWater && !hasPath()); } */ /** * List of edible foods * * @param item1 * @return */ public boolean isItemEdible(Item item1) { return (item1 instanceof ItemFood) || (item1 instanceof ItemSeeds) || item1.itemID == Item.wheat.itemID || item1.itemID == Item.sugar.itemID || item1.itemID == Item.cake.itemID || item1.itemID == Item.egg.itemID; } /** * Used to breed * * @param item1 * @return */ public boolean isMyAphrodisiac(Item item1) { return false;//(item1 instanceof ItemFood); } @Override public boolean interact(EntityPlayer entityplayer) { ItemStack itemstack = entityplayer.inventory.getCurrentItem(); //before ownership check if ((itemstack != null) && getIsTamed() && ((itemstack.itemID == MoCreatures.scrollOfOwner.itemID)) && MoCreatures.proxy.enableResetOwnership && MoCTools.isThisPlayerAnOP(entityplayer)) { if (--itemstack.stackSize == 0) { entityplayer.inventory.setInventorySlotContents(entityplayer.inventory.currentItem, null); } if (MoCreatures.isServer()) { if (MoCreatures.proxy.enableOwnership) { EntityPlayer epOwner = this.worldObj.getPlayerEntityByName(this.getOwnerName()); if (epOwner != null) { MoCTools.reduceTamedByPlayer(epOwner); } else { MoCTools.reduceTamedByOfflinePlayer(this.getOwnerName()); } } this.setOwner(""); } return true; } //if the player interacting is not the owner, do nothing! if (MoCreatures.proxy.enableOwnership && getOwnerName() != null && !getOwnerName().equals("") && !entityplayer.username.equals(getOwnerName())) { //System.out.println("Player " + entityplayer + " attempted interaction. Denies as " + getOwnerName() + " is the owner"); return true; } //changes name if ((itemstack != null) && getIsTamed() //&& MoCreatures.isServer() && ((itemstack.itemID == MoCreatures.medallion.itemID) || (itemstack.itemID == Item.book.itemID))) { if (MoCreatures.isServer()) { MoCTools.tameWithName((EntityPlayerMP) entityplayer, this); } //TODO NAMER /*if (!MoCreatures.isServer()) { MoCreatures.proxy.setName(entityplayer, this); }*/ return true; } //sets it free, untamed if ((itemstack != null) && getIsTamed() && ((itemstack.itemID == MoCreatures.scrollFreedom.itemID))) { if (--itemstack.stackSize == 0) { entityplayer.inventory.setInventorySlotContents(entityplayer.inventory.currentItem, null); } if (MoCreatures.isServer()) { if (MoCreatures.proxy.enableOwnership) MoCTools.reduceTamedByPlayer(entityplayer); this.setOwner(""); this.setName(""); this.dropMyStuff(); this.setTamed(false); } return true; } //removes owner, any other player can claim it by renaming it if ((itemstack != null) && getIsTamed() && ((itemstack.itemID == MoCreatures.scrollOfSale.itemID))) { if (--itemstack.stackSize == 0) { entityplayer.inventory.setInventorySlotContents(entityplayer.inventory.currentItem, null); } if (MoCreatures.isServer()) { if (MoCreatures.proxy.enableOwnership) MoCTools.reduceTamedByPlayer(entityplayer); this.setOwner(""); } return true; } //heals if ((itemstack != null) && getIsTamed() && isMyHealFood(itemstack)) { if (--itemstack.stackSize == 0) { entityplayer.inventory.setInventorySlotContents(entityplayer.inventory.currentItem, null); } worldObj.playSoundAtEntity(this, "eating", 1.0F, 1.0F + ((rand.nextFloat() - rand.nextFloat()) * 0.2F)); if (MoCreatures.isServer()) { health = getMaxHealth(); } return true; } //attaches rope if ((itemstack != null) && (riddenByEntity == null) && (roper == null) && getIsTamed() && (itemstack.itemID == MoCreatures.rope.itemID)) { if (--itemstack.stackSize == 0) { entityplayer.inventory.setInventorySlotContents(entityplayer.inventory.currentItem, null); } worldObj.playSoundAtEntity(this, "roping", 1.0F, 1.0F + ((rand.nextFloat() - rand.nextFloat()) * 0.2F)); roper = entityplayer; setEating(false); return true; } //removes rope if ((roper != null) && getIsTamed()) { entityplayer.inventory.addItemStackToInventory(new ItemStack(MoCreatures.rope)); worldObj.playSoundAtEntity(this, "roping", 1.0F, 1.0F + ((rand.nextFloat() - rand.nextFloat()) * 0.2F)); roper = null; return true; } if ((itemstack != null) && getIsTamed() && (itemstack.itemID == Item.shears.itemID)) { if (MoCreatures.isServer()) { dropMyStuff(); } return true; } return false; } //used to drop armor, inventory, saddles, etc. public void dropMyStuff() {} /** * Used to heal the animal * * @param itemstack * @return */ protected boolean isMyHealFood(ItemStack itemstack) { return false; } @Override public boolean isInWater() { if (swimmerEntity()) { return false; } return super.isInWater(); } @Override public boolean canBreatheUnderwater() { return swimmerEntity(); } public EntityItem getClosestItem(Entity entity, double d, int i, int j) { double d1 = -1D; EntityItem entityitem = null; List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.expand(d, d, d)); for (int k = 0; k < list.size(); k++) { Entity entity1 = (Entity) list.get(k); if (!(entity1 instanceof EntityItem)) { continue; } EntityItem entityitem1 = (EntityItem) entity1; if ((entityitem1.getEntityItem().itemID != i) && (entityitem1.getEntityItem().itemID != j)) { continue; } double d2 = entityitem1.getDistanceSq(entity.posX, entity.posY, entity.posZ); if (((d < 0.0D) || (d2 < (d * d))) && ((d1 == -1D) || (d2 < d1))) { d1 = d2; entityitem = entityitem1; } } return entityitem; } public EntityItem getClosestEntityItem(Entity entity, double d) { double d1 = -1D; EntityItem entityitem = null; List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.expand(d, d, d)); for (int k = 0; k < list.size(); k++) { Entity entity1 = (Entity) list.get(k); if (!(entity1 instanceof EntityItem)) { continue; } EntityItem entityitem1 = (EntityItem) entity1; double d2 = entityitem1.getDistanceSq(entity.posX, entity.posY, entity.posZ); if (((d < 0.0D) || (d2 < (d * d))) && ((d1 == -1D) || (d2 < d1))) { d1 = d2; entityitem = entityitem1; } } return entityitem; } public EntityItem getClosestFood(Entity entity, double d) { double d1 = -1D; EntityItem entityitem = null; List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.expand(d, d, d)); for (int k = 0; k < list.size(); k++) { Entity entity1 = (Entity) list.get(k); if (!(entity1 instanceof EntityItem)) { continue; } EntityItem entityitem1 = (EntityItem) entity1; if (!isItemEdible(entityitem1.getEntityItem().getItem())) { continue; } double d2 = entityitem1.getDistanceSq(entity.posX, entity.posY, entity.posZ); if (((d < 0.0D) || (d2 < (d * d))) && ((d1 == -1D) || (d2 < d1))) { d1 = d2; entityitem = entityitem1; } } return entityitem; } public void faceLocation(int i, int j, int k, float f) { double var4 = i + 0.5D - posX; double var8 = k + 0.5D - posZ; double var6 = j + 0.5D - posY; double var14 = (double) MathHelper.sqrt_double(var4 * var4 + var8 * var8); float var12 = (float) (Math.atan2(var8, var4) * 180.0D / Math.PI) - 90.0F; float var13 = (float) (-(Math.atan2(var6, var14) * 180.0D / Math.PI)); this.rotationPitch = -this.updateRotation(this.rotationPitch, var13, f); this.rotationYaw = this.updateRotation(this.rotationYaw, var12, f); } /** * Arguments: current rotation, intended rotation, max increment. */ private float updateRotation(float par1, float par2, float par3) { float var4; for (var4 = par2 - par1; var4 < -180.0F; var4 += 360.0F) { ; } while (var4 >= 180.0F) { var4 -= 360.0F; } if (var4 > par3) { var4 = par3; } if (var4 < -par3) { var4 = -par3; } return par1 + var4; } public void getMyOwnPath(Entity entity, float f) { PathEntity pathentity = worldObj.getPathEntityToEntity(this, entity, 16F, true, false, false, true); if (pathentity != null) { setPathToEntity(pathentity); } } /** * Called to make ridden entities pass on collision to rider */ public void Riding() { if ((riddenByEntity != null) && (riddenByEntity instanceof EntityPlayer)) { EntityPlayer entityplayer = (EntityPlayer) riddenByEntity; List list = worldObj.getEntitiesWithinAABBExcludingEntity(this, boundingBox.expand(1.0D, 0.0D, 1.0D)); if (list != null) { for (int i = 0; i < list.size(); i++) { Entity entity = (Entity) list.get(i); if (entity.isDead) { continue; } entity.onCollideWithPlayer(entityplayer); if (!(entity instanceof EntityMob)) { continue; } float f = getDistanceToEntity(entity); if ((f < 2.0F) && entity instanceof EntityMob && (rand.nextInt(10) == 0)) { attackEntityFrom(DamageSource.causeMobDamage((EntityLiving) entity), ((EntityMob)entity).getAttackStrength(this)); } } } if (entityplayer.isSneaking()) { //if (!worldObj.isRemote) //{ this.makeEntityDive(); //entityplayer.mountEntity(null); //} } } } protected void getPathOrWalkableBlock(Entity entity, float f) { PathEntity pathentity = worldObj.getPathEntityToEntity(this, entity, 16F, true, false, false, true); if ((pathentity == null) && (f > 8F)) { int i = MathHelper.floor_double(entity.posX) - 2; int j = MathHelper.floor_double(entity.posZ) - 2; int k = MathHelper.floor_double(entity.boundingBox.minY); for (int l = 0; l <= 4; l++) { for (int i1 = 0; i1 <= 4; i1++) { if (((l < 1) || (i1 < 1) || (l > 3) || (i1 > 3)) && worldObj.isBlockNormalCube(i + l, k - 1, j + i1) && !worldObj.isBlockNormalCube(i + l, k, j + i1) && !worldObj.isBlockNormalCube(i + l, k + 1, j + i1)) { setLocationAndAngles((i + l) + 0.5F, k, (j + i1) + 0.5F, rotationYaw, rotationPitch); return; } } } } else { setPathToEntity(pathentity); } } @Override public int getMaxHealth() { return 20; } public MoCEntityAnimal spawnBabyAnimal(EntityAgeable par1EntityAgeable) { return null; } public boolean getCanSpawnHereAnimal() { int i = MathHelper.floor_double(posX); int j = MathHelper.floor_double(boundingBox.minY); int k = MathHelper.floor_double(posZ); return worldObj.getBlockId(i, j - 1, k) == Block.grass.blockID && worldObj.getFullBlockLightValue(i, j, k) > 8; } public boolean getCanSpawnHereCreature() { int i = MathHelper.floor_double(posX); int j = MathHelper.floor_double(boundingBox.minY); int k = MathHelper.floor_double(posZ); return getBlockPathWeight(i, j, k) >= 0.0F; } public boolean getCanSpawnHereLiving() { return worldObj.checkNoEntityCollision(boundingBox) && worldObj.getCollidingBoundingBoxes(this, boundingBox).size() == 0 && !worldObj.isAnyLiquid(boundingBox); } public boolean getCanSpawnHereAquatic() { return worldObj.checkNoEntityCollision(boundingBox); } public boolean getCanSpawnHere2() { return getCanSpawnHereCreature() && getCanSpawnHereLiving(); } @Override public boolean getCanSpawnHere() { if (worldObj.provider.dimensionId != 0) { return getCanSpawnHereCreature() && getCanSpawnHereLiving(); } int i = MathHelper.floor_double(posX); int j = MathHelper.floor_double(boundingBox.minY); int k = MathHelper.floor_double(posZ); String s = MoCTools.BiomeName(worldObj, i, j, k); //System.out.println("checkin animal getcanspawnhere and biome = " + s); if (s.equals("Jungle") || s.equals("JungleHills")) { return getCanSpawnHereJungle(); } if (s.equals("WyvernBiome")) { return getCanSpawnHereMoCBiome(); } return super.getCanSpawnHere(); } private boolean getCanSpawnHereMoCBiome() { //System.out.println("checking MoC biome spawn settings"); if (this.worldObj.checkNoEntityCollision(this.boundingBox) && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() && !this.worldObj.isAnyLiquid(this.boundingBox)) { int var1 = MathHelper.floor_double(this.posX); int var2 = MathHelper.floor_double(this.boundingBox.minY); int var3 = MathHelper.floor_double(this.posZ); if (var2 < 50) { return false; } int var4 = this.worldObj.getBlockId(var1, var2 - 1, var3); Block block = Block.blocksList[var4]; if (var4 == MoCreatures.mocDirt.blockID || var4 == MoCreatures.mocGrass.blockID || (block != null && block.isLeaves(worldObj, var1, var2 - 1, var3))) { return true; } } return false; } public boolean getCanSpawnHereJungle() { //System.out.println("checking jungle!"); if (this.worldObj.checkNoEntityCollision(this.boundingBox) && this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() && !this.worldObj.isAnyLiquid(this.boundingBox)) { int var1 = MathHelper.floor_double(this.posX); int var2 = MathHelper.floor_double(this.boundingBox.minY); int var3 = MathHelper.floor_double(this.posZ); if (var2 < 63) { return false; } int var4 = this.worldObj.getBlockId(var1, var2 - 1, var3); Block block = Block.blocksList[var4]; if (var4 == Block.grass.blockID || var4 == Block.leaves.blockID || (block != null && block.isLeaves(worldObj, var1, var2 - 1, var3))) { return true; } } return false; } @Override public void writeEntityToNBT(NBTTagCompound nbttagcompound) { super.writeEntityToNBT(nbttagcompound); nbttagcompound.setBoolean("Tamed", getIsTamed()); nbttagcompound.setBoolean("Adult", getIsAdult()); nbttagcompound.setInteger("Edad", getEdad()); nbttagcompound.setString("Name", getName()); nbttagcompound.setInteger("TypeInt", getType()); nbttagcompound.setString("Owner", getOwnerName()); } @Override public void readEntityFromNBT(NBTTagCompound nbttagcompound) { super.readEntityFromNBT(nbttagcompound); setTamed(nbttagcompound.getBoolean("Tamed")); setAdult(nbttagcompound.getBoolean("Adult")); setEdad(nbttagcompound.getInteger("Edad")); setName(nbttagcompound.getString("Name")); setType(nbttagcompound.getInteger("TypeInt")); setOwner(nbttagcompound.getString("Owner")); //type = (nbttagcompound.getInteger("TypeInt")); //selectType(); } @Override public void moveEntityWithHeading(float f, float f1) { //If the entity is not ridden by entityplayer, then execute the normal Entityliving code if (!isFlyer() && (!rideableEntity() || this.riddenByEntity == null))// || (this.ridingEntity != null && !(this.ridingEntity instanceof EntityPlayer))) { super.moveEntityWithHeading(f, f1); return; } if (handleWaterMovement()) { if (riddenByEntity != null) { motionX += riddenByEntity.motionX * (getCustomSpeed() / 2.0D); motionZ += riddenByEntity.motionZ * (getCustomSpeed() / 2.0D); if (jumpPending && !getIsJumping()) { motionY = getCustomJump(); setIsJumping(true); jumpPending = false; } if (!worldObj.isRemote) { moveEntity(motionX, motionY, motionZ); } //moveEntity(motionX, motionY, motionZ); rotationPitch = riddenByEntity.rotationPitch * 0.5F; if (rand.nextInt(20) == 0) { rotationYaw = riddenByEntity.rotationYaw; } setRotation(rotationYaw, rotationPitch); if (MoCreatures.isServer() && !getIsTamed()) { worldObj.playSoundAtEntity(this, getMadSound(), 1.0F, 1.0F + ((rand.nextFloat() - rand.nextFloat()) * 0.2F)); riddenByEntity.motionY += 0.3D; riddenByEntity.motionZ -= 0.3D; riddenByEntity.mountEntity(null); this.riddenByEntity = null; } if (rand.nextInt(25) == 0) { setIsJumping(false); } } double d = posY; if (!worldObj.isRemote) { moveFlying(f, f1, 0.02F); moveEntity(motionX, motionY, motionZ); } motionX *= 0.800000011920929D; motionY *= 0.800000011920929D; motionZ *= 0.800000011920929D; motionY -= 0.02D; if (isCollidedHorizontally && isOffsetPositionInLiquid(motionX, ((motionY + 0.60000002384185791D) - posY) + d, motionZ)) { motionY = 0.30000001192092901D; } } else if (handleLavaMovement()) { if (riddenByEntity != null) { motionX += riddenByEntity.motionX * (getCustomSpeed() / 2.0D); motionZ += riddenByEntity.motionZ * (getCustomSpeed() / 2.0D); if (jumpPending && !getIsJumping()) { motionY = getCustomJump(); //setEntityJumping(true); jumpPending = false; } moveEntity(motionX, motionY, motionZ); //moveEntity(motionX, motionY, motionZ); rotationPitch = riddenByEntity.rotationPitch * 0.5F; if (rand.nextInt(20) == 0) { rotationYaw = riddenByEntity.rotationYaw; } setRotation(rotationYaw, rotationPitch); if (MoCreatures.isServer() && !getIsTamed()) { worldObj.playSoundAtEntity(this, getMadSound(), 1.0F, 1.0F + ((rand.nextFloat() - rand.nextFloat()) * 0.2F)); riddenByEntity.motionY += 0.3D; riddenByEntity.motionZ -= 0.3D; riddenByEntity.mountEntity(null); this.riddenByEntity = null; } } double d1 = posY; moveFlying(f, f1, 0.02F); moveEntity(motionX, motionY, motionZ); motionX *= 0.5D; motionY *= 0.5D; motionZ *= 0.5D; motionY -= 0.02D; if (isCollidedHorizontally && isOffsetPositionInLiquid(motionX, ((motionY + 0.60000002384185791D) - posY) + d1, motionZ)) { motionY = 0.30000001192092901D; } } else { float f2 = 0.91F; if (onGround) { //this.isAirBorne = false; f2 = 0.5460001F; int i = worldObj.getBlockId(MathHelper.floor_double(posX), MathHelper.floor_double(boundingBox.minY) - 1, MathHelper.floor_double(posZ)); if (i > 0) { f2 = Block.blocksList[i].slipperiness * 0.91F; } } float f3 = 0.162771F / (f2 * f2 * f2); moveFlying(f, f1, onGround ? 0.1F * f3 : 0.02F); if (isOnLadder()) { fallDistance = 0.0F; if (motionY < -0.15D) { motionY = -0.15D; } } if ((riddenByEntity != null) && !getIsTamed()) { if ((rand.nextInt(5) == 0) && !getIsJumping() && motionY < 0 && motionY > -0.2D) { motionY = this.getCustomJump(); setIsJumping(true); } if (rand.nextInt(10) == 0) { motionX += rand.nextDouble() / 30D; motionZ += rand.nextDouble() / 10D; } // blood - This must be run on server side only since it causes glitch/twitch if run on both sides. if (!worldObj.isRemote) { moveEntity(motionX, motionY, motionZ); } if (MoCreatures.isServer() && rand.nextInt(50) == 0) { worldObj.playSoundAtEntity(this, getMadSound(), 1.0F, 1.0F + ((rand.nextFloat() - rand.nextFloat()) * 0.2F)); riddenByEntity.motionY += 0.9D; riddenByEntity.motionZ -= 0.3D; riddenByEntity.mountEntity(null); this.riddenByEntity = null; } if (onGround) { setIsJumping(false); } //TODO check!, also check nullpointerEx on the (Entityplayer) cast if (MoCreatures.isServer()) { int chance = (getMaxTemper() - getTemper()); if (chance <= 0) { chance = 5; } if (rand.nextInt(chance * 8) == 0) { MoCTools.tameWithName((EntityPlayerMP) riddenByEntity, this); //TODO NAMER //setTamed(true); //MoCServerPacketHandler.sendNameGUI((EntityPlayerMP) riddenByEntity, this.entityId); } } } if ((riddenByEntity != null) && getIsTamed()) { boundingBox.maxY = riddenByEntity.boundingBox.maxY; if (!selfPropelledFlyer() || (selfPropelledFlyer() && !isOnAir())) { motionX += riddenByEntity.motionX * getCustomSpeed(); motionZ += riddenByEntity.motionZ * getCustomSpeed(); } if (jumpPending && (isFlyer())) { motionY += flyerThrust();//0.3D; jumpPending = false; if (selfPropelledFlyer() && isOnAir()) { double velX = 0.25F * Math.cos((MoCTools.realAngle(this.rotationYaw - 90F)) / 57.29578F); double velZ = 0.25F * Math.sin((MoCTools.realAngle(this.rotationYaw - 90F)) / 57.29578F); this.motionX -= velX; this.motionZ -= velZ; } } else if (jumpPending && !getIsJumping()) { motionY = getCustomJump(); setIsJumping(true); jumpPending = false; } if (divePending) { divePending = false; motionY -= 0.3D; } // blood - This must be run on server side only since it causes glitch/twitch if run on both sides. if (MoCreatures.isServer()) { moveEntity(motionX, motionY, motionZ); } if (onGround) { // blood - fixes jump bug jumpPending = false; setIsJumping(false); divePending = false; } prevRotationYaw = rotationYaw = riddenByEntity.rotationYaw; rotationPitch = riddenByEntity.rotationPitch * 0.5F; setRotation(rotationYaw, rotationPitch); } // blood - This must be run on server side only since it causes glitch/twitch if run on both sides. if (!worldObj.isRemote) { //needs to be left in so flying mounts can be controlled moveEntity(motionX, motionY, motionZ); } if (isFlyingAlone())// && entityToAttack == null) { int distY = MoCTools.distanceToFloor(this); if (distY <= flyingHeight()) { motionY *= f2; } if (distY <= flyingHeight() && (isCollidedHorizontally || rand.nextInt(100) == 0)) { motionY += 0.1D; } if (distY > flyingHeight() || rand.nextInt(150) == 0) { motionY -= 0.10D; } if (isOnAir()) { double velX = 0.05F * Math.cos((MoCTools.realAngle(this.rotationYaw - 90F)) / 57.29578F); double velZ = 0.05F * Math.sin((MoCTools.realAngle(this.rotationYaw - 90F)) / 57.29578F); this.motionX -= velX; this.motionZ -= velZ; } } if (isFlyer() && riddenByEntity == null && entityToAttack != null && entityToAttack.posY < this.posY && rand.nextInt(30) == 0) { motionY = -0.25D; } if (isFlyer() && (riddenByEntity != null) && getIsTamed()) { motionY -= 0.08D; motionY *= myFallSpeed();//0.6D; } else if (!isFlyingAlone()) { motionY -= 0.08D; motionY *= 0.98000001907348633D; } if (this.riddenByEntity != null && isOnAir()) { f2 = flyerFriction(); } //f2 = 0.95F; motionX *= f2; motionZ *= f2; } this.prevLimbYaw = this.limbYaw; double d2 = posX - prevPosX; double d3 = posZ - prevPosZ; float f4 = MathHelper.sqrt_double((d2 * d2) + (d3 * d3)) * 4.0F; if (f4 > 1.0F) { f4 = 1.0F; } this.limbYaw += (f4 - this.limbYaw) * 0.4F; this.limbSwing += this.limbYaw; } /** * Maximum flyer height when moving autonomously * @return */ public int flyingHeight() { return 5; } /** * Used for flyer mounts, to calculate fall speed * @return */ protected double myFallSpeed() { return 0.6D; } /** * flyer mounts Y thrust * @return */ protected double flyerThrust() { return 0.3D; } /** * flyer deceleration on Z and X axis * @return */ protected float flyerFriction() { return 0.91F; } /** * Alternative flyer mount movement, when true, the player only controls frequency of wing flaps * @return */ protected boolean selfPropelledFlyer() { return false; } /** * Sets a flag that will make the Entity "jump" in the next onGround * moveEntity update */ @Override public void makeEntityJump() { /*if (FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER) { //System.out.println("Server jumping entity = " + this.entityId); }else { //System.out.println("Client jumping entity = " + this.entityId); }*/ this.jumpPending = true; } /** * Boolean used for flying mounts */ public boolean isFlyer() { return false; } public int getTemper() { return temper; } public void setTemper(int i) { temper = i; } /** * How difficult is the creature to be tamed? the Higher the number, the * more difficult */ public int getMaxTemper() { return 100; } /** * mount speed */ public double getCustomSpeed() { return 0.8D; } /** * mount jumping power */ public double getCustomJump() { return 0.4D; } /** * sound played when an untamed mount buckles rider */ protected String getMadSound() { return null; } /** * to avoid double jumps */ /*public boolean isEntityJumping() { return isEntityJumping; } public void setEntityJumping(boolean flag) { isEntityJumping = flag; }*/ /** * Is this a rideable entity? */ public boolean rideableEntity() { return false; } @Override public boolean renderName() { return getDisplayName() && (riddenByEntity == null); } @Override public int nameYOffset() { return -80; } @Override public double roperYOffset() { return 0D; } /** * adds a following behavior to animals with a rope */ @Override protected void updateEntityActionState() { if (getIsTamed() && (riddenByEntity == null) && (roper != null)) { float f = roper.getDistanceToEntity(this); if (f > 3F) { getPathOrWalkableBlock(roper, f); } } if (!isFlyingAlone()) { super.updateEntityActionState(); return; } hasAttacked = false; float f = 16F; if (entityToAttack == null) { entityToAttack = findPlayerToAttack(); if (entityToAttack != null) { entitypath = worldObj.getPathEntityToEntity(this, entityToAttack, f, true, false, false, true); } } else if (!entityToAttack.isEntityAlive()) { entityToAttack = null; } else { float f1 = entityToAttack.getDistanceToEntity(this); if (canEntityBeSeen(entityToAttack)) { attackEntity(entityToAttack, f1); } } if (!hasAttacked && (entityToAttack != null) && ((entitypath == null) || (rand.nextInt(10) == 0))) { // entitypath = worldObj.getPathToEntity(this, entityToAttack, f); entitypath = worldObj.getPathEntityToEntity(this, entityToAttack, f, true, false, false, true); } else if (((entitypath == null) && (rand.nextInt(80) == 0)) || (rand.nextInt(80) == 0)) { boolean flag = false; int j = -1; int k = -1; int l = -1; float f2 = -99999F; for (int i1 = 0; i1 < 10; i1++) { int j1 = MathHelper.floor_double((posX + rand.nextInt(13)) - 6D); int k1 = MathHelper.floor_double((posY + rand.nextInt(7)) - 3D); int l1 = MathHelper.floor_double((posZ + rand.nextInt(13)) - 6D); float f3 = getBlockPathWeight(j1, k1, l1); if (f3 > f2) { f2 = f3; j = j1; k = k1; l = l1; flag = true; } } if (flag) { entitypath = worldObj.getEntityPathToXYZ(this, j, k, l, 10F, true, false, false, true); } } int i = MathHelper.floor_double(boundingBox.minY); boolean flag1 = handleWaterMovement(); boolean flag2 = handleLavaMovement(); rotationPitch = 0.0F; if ((entitypath == null) || (rand.nextInt(100) == 0)) { super.updateEntityActionState(); entitypath = null; return; } //TODO 4FIX test! Vec3 vec3d = entitypath.getPosition(this); //client //Vec3D vec3d = entitypath.getPosition(this); //server for (double d = width * 2.0F; (vec3d != null) && (vec3d.squareDistanceTo(posX, vec3d.yCoord, posZ) < (d * d));) { entitypath.incrementPathIndex(); if (entitypath.isFinished()) { vec3d = null; entitypath = null; } else { //vec3d = entitypath.getPosition(this); //server //TODO 4FIX test! vec3d = entitypath.getPosition(this); } } isJumping = false; if (vec3d != null) { double d1 = vec3d.xCoord - posX; double d2 = vec3d.zCoord - posZ; double d3 = vec3d.yCoord - i; float f4 = (float) ((Math.atan2(d2, d1) * 180D) / 3.1415927410125728D) - 90F; float f5 = f4 - rotationYaw; moveForward = moveSpeed; for (; f5 < -180F; f5 += 360F) { } for (; f5 >= 180F; f5 -= 360F) { } if (f5 > 30F) { f5 = 30F; } if (f5 < -30F) { f5 = -30F; } rotationYaw += f5; if (hasAttacked && (entityToAttack != null)) { double d4 = entityToAttack.posX - posX; double d5 = entityToAttack.posZ - posZ; float f6 = rotationYaw; rotationYaw = (float) ((Math.atan2(d5, d4) * 180D) / 3.1415927410125728D) - 90F; float f7 = (((f6 - rotationYaw) + 90F) * 3.141593F) / 180F; moveStrafing = -MathHelper.sin(f7) * moveForward * 1.0F; moveForward = MathHelper.cos(f7) * moveForward * 1.0F; } if (d3 > 0.0D) { isJumping = true; } } if (entityToAttack != null) { faceEntity(entityToAttack, 30F, 30F); } if (isCollidedHorizontally) { isJumping = true; } if ((rand.nextFloat() < 0.8F) && (flag1 || flag2)) { isJumping = true; } } /** * fixes dewspawning tamed creatures */ @Override public boolean isEntityInsideOpaqueBlock() { //if (getIsTamed()) return false; return super.isEntityInsideOpaqueBlock(); } /** * fixes bug with entities following a player carrying wheat */ @Override protected Entity findPlayerToAttack() { return null; } public void repelMobs(Entity entity1, Double dist, World worldObj) { List list = worldObj.getEntitiesWithinAABBExcludingEntity(entity1, entity1.boundingBox.expand(dist, 4D, dist)); for (int i = 0; i < list.size(); i++) { Entity entity = (Entity) list.get(i); if (!(entity instanceof EntityMob)) { continue; } EntityMob entitymob = (EntityMob) entity; entitymob.setAttackTarget(null); entitymob.setPathToEntity(null); } } public void faceItem(int i, int j, int k, float f) { double d = i - posX; double d1 = k - posZ; double d2 = j - posY; double d3 = MathHelper.sqrt_double((d * d) + (d1 * d1)); float f1 = (float) ((Math.atan2(d1, d) * 180D) / 3.1415927410125728D) - 90F; float f2 = (float) ((Math.atan2(d2, d3) * 180D) / 3.1415927410125728D); rotationPitch = -adjustRotation(rotationPitch, f2, f); rotationYaw = adjustRotation(rotationYaw, f1, f); } public float adjustRotation(float f, float f1, float f2) { float f3 = f1; for (f3 = f1 - f; f3 < -180F; f3 += 360F) { } for (; f3 >= 180F; f3 -= 360F) { } if (f3 > f2) { f3 = f2; } if (f3 < -f2) { f3 = -f2; } return f + f3; } public boolean isFlyingAlone() { return false; } public float getMoveSpeed() { return 0.7F; } /** * Used to spawn hearts at this location */ public void SpawnHeart() { double var2 = this.rand.nextGaussian() * 0.02D; double var4 = this.rand.nextGaussian() * 0.02D; double var6 = this.rand.nextGaussian() * 0.02D; this.worldObj.spawnParticle("heart", this.posX + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, this.posY + 0.5D + (double) (this.rand.nextFloat() * this.height), this.posZ + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, var2, var4, var6); } /** * Used to synchronize animations between server and client * * @param attackType */ @Override public void performAnimation(int attackType) { } /** * Makes the entity despawn if requirements are reached changed to the * entities now last longer */ /*@Override protected void despawnEntity() { EntityPlayer var1 = this.worldObj.getClosestPlayerToEntity(this, -1.0D); if (var1 != null) { double var2 = var1.posX - this.posX; double var4 = var1.posY - this.posY; double var6 = var1.posZ - this.posZ; double var8 = var2 * var2 + var4 * var4 + var6 * var6; if (this.canDespawn() && var8 > 16384.0D) { this.setDead(); } //changed from 600 if (this.entityAge > 1800 && this.rand.nextInt(800) == 0 && var8 > 1024.0D && this.canDespawn()) { this.setDead(); } else if (var8 < 1024.0D) { this.entityAge = 0; } } }*/ /** * Used to follow the player carrying the item * * @param par1ItemStack * @return */ public boolean isMyFavoriteFood(ItemStack par1ItemStack) { return false; //return par1ItemStack.itemID == Item.wheat.itemID; } private void followPlayer() { EntityPlayer entityplayer1 = worldObj.getClosestPlayerToEntity(this, 24D); if (entityplayer1 == null) { return; } ItemStack itemstack1 = entityplayer1.inventory.getCurrentItem(); if (itemstack1 != null && isMyFavoriteFood(itemstack1)) { PathEntity pathentity = worldObj.getPathEntityToEntity(this, entityplayer1, 16F, true, false, false, true); setPathToEntity(pathentity); } } /** * This method must be overrided to work in conjunction with our * onLivingUpdate update packets. It is currently used to fix mount bug when * players reconnect. */ @Override public void mountEntity(Entity par1Entity) { if (updateMount()) { if (par1Entity == null) { if (this.ridingEntity != null) { this.setLocationAndAngles(this.ridingEntity.posX, this.ridingEntity.boundingBox.minY + (double) this.ridingEntity.height, this.ridingEntity.posZ, this.rotationYaw, this.rotationPitch); this.ridingEntity.riddenByEntity = null; } this.ridingEntity = null; } else { this.ridingEntity = par1Entity; par1Entity.riddenByEntity = this; } } else { super.mountEntity(par1Entity); } } @Override public Entity getRoper() { return roper; } @Override public boolean updateMount() { return false; } @Override public boolean forceUpdates() { return false; } @Override public void makeEntityDive() { //System.out.println("server = " + MoCreatures.isServer()); this.divePending = true; } public boolean isOnAir() { int j = worldObj.getBlockId(MathHelper.floor_double(posX), MathHelper.floor_double(posY - 0.2D), MathHelper.floor_double(posZ)); int k = worldObj.getBlockId(MathHelper.floor_double(posX), MathHelper.floor_double(posY - 1.2D), MathHelper.floor_double(posZ)); return (j == 0) && (k == 0); } @Override public float getSizeFactor() { return 1.0F; } @Override public float getAdjustedYOffset() { return 0F; } @Override public String getOwnerName() { return this.dataWatcher.getWatchableObjectString(20); } @Override public void setOwner(String par1Str) { this.dataWatcher.updateObject(20, par1Str); } /*public EntityLiving getOwner() { return this.worldObj.getPlayerEntityByName(this.getOwnerName()); }*/ @Override public void onDeath(DamageSource damagesource) { if (MoCreatures.isServer()) { dropMyStuff(); } if (MoCreatures.proxy.enableOwnership && this.getIsTamed() && (this.getOwnerName() != null) && MoCreatures.isServer()) { EntityPlayer ep = worldObj.getPlayerEntityByName(this.getOwnerName()); if (ep != null) { MoCTools.reduceTamedByPlayer(ep); } else { MoCTools.reduceTamedByOfflinePlayer(getOwnerName()); } } super.onDeath(damagesource); } @Override public boolean attackEntityFrom(DamageSource damagesource, int i) { Entity entity = damagesource.getEntity(); //this avoids damage done by Players to a tamed creature that is not theirs if (MoCreatures.proxy.enableOwnership && getOwnerName() != null && !getOwnerName().equals("") && entity != null && entity instanceof EntityPlayer && !((EntityPlayer) entity).username.equals(getOwnerName())) { return false; } if (MoCreatures.isServer() && getIsTamed()) { MoCServerPacketHandler.sendHealth(this.entityId, this.worldObj.provider.dimensionId, this.getHealth()); } if (isNotScared()) { Entity tempEntity = entityToAttack; boolean flag = super.attackEntityFrom(damagesource, i); fleeingTick = 0; entityToAttack = tempEntity; return flag; } else { return super.attackEntityFrom(damagesource, i); } } public boolean getIsRideable() { return false; } public void setRideable(boolean b) {} // Fixes despawn issue when chunks unload and duplicated mounts when disconnecting on servers @Override public void setDead() { if (MoCreatures.isServer() && getIsTamed() && this.health > 0 && mountCount == 0)//&& (this.riddenByEntity == null)) { return; } super.setDead(); } @Override public void setArmorType(byte i) {} public byte getArmorType() { return 0; } @Override public void dismountEntity() { if (MoCreatures.isServer() && this.riddenByEntity != null) { this.riddenByEntity.mountEntity(null); this.riddenByEntity = null; } } /** * Drops armor if the animal has one */ public void dropArmor() {} }