Jump to content

[SOLVED][1.7.2]My tiger targets player but its "attack" does no damage


jabelar

Recommended Posts

(Forge version = 1047)

 

[updated subject to be more specific]

 

Okay, so I have created an EntityTiger that is essentially a re-textured vanilla wolf, and it works perfectly (basically behaves like a wolf in that it is passive unless attacked, can be tamed, hunts sheep on its own, etc.)

 

I want to make a sub-class EntityManEatingTiger which extends EntityTiger but basically is always hostile and will attack a player on sight.  I thought I could do this by setAngry(true) and setting target to the player (I realize this isn't really good practice for multiplayer, but will fix that later).  I also have setTamed(false). 

 

So I have an untamed, angry tiger with player as the target.  It does in fact look angry (red eyes texture), and it follows my player and leaps at it just like it is attacking me.  However, it doesn't actually do any damage (not a real attack).  If I hit it though, then it will attack me for real.

 

So I'm missing something -- how do you make it actually attack rather than follow me with red eyes?

 

Here are the two classes.

 

EntityTiger

 

package wildanimals.entities;

 

import net.minecraft.block.Block;

import net.minecraft.block.BlockColored;

import net.minecraft.entity.Entity;

import net.minecraft.entity.EntityAgeable;

import net.minecraft.entity.EntityLivingBase;

import net.minecraft.entity.SharedMonsterAttributes;

import net.minecraft.entity.ai.EntityAIAttackOnCollide;

import net.minecraft.entity.ai.EntityAIBase;

import net.minecraft.entity.ai.EntityAIFollowOwner;

import net.minecraft.entity.ai.EntityAIHurtByTarget;

import net.minecraft.entity.ai.EntityAILeapAtTarget;

import net.minecraft.entity.ai.EntityAILookIdle;

import net.minecraft.entity.ai.EntityAIMate;

import net.minecraft.entity.ai.EntityAIOwnerHurtByTarget;

import net.minecraft.entity.ai.EntityAIOwnerHurtTarget;

import net.minecraft.entity.ai.EntityAISwimming;

import net.minecraft.entity.ai.EntityAITargetNonTamed;

import net.minecraft.entity.ai.EntityAIWander;

import net.minecraft.entity.ai.EntityAIWatchClosest;

import net.minecraft.entity.monster.EntityCreeper;

import net.minecraft.entity.monster.EntityGhast;

import net.minecraft.entity.passive.EntityAnimal;

import net.minecraft.entity.passive.EntityHorse;

import net.minecraft.entity.passive.EntitySheep;

import net.minecraft.entity.passive.EntityTameable;

import net.minecraft.entity.player.EntityPlayer;

import net.minecraft.entity.projectile.EntityArrow;

import net.minecraft.init.Items;

import net.minecraft.item.Item;

import net.minecraft.item.ItemFood;

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.world.World;

import wildanimals.entities.ai.EntityAIBegTiger;

import cpw.mods.fml.relauncher.Side;

import cpw.mods.fml.relauncher.SideOnly;

 

public class EntityTiger extends EntityTameable

{

    protected float field_70926_e;

    protected float field_70924_f;

    /**

    * true is the tiger is wet else false

    */

    protected boolean isShaking;

    protected boolean field_70928_h;

    /**

    * This time increases while tiger is shaking and emitting water particles.

    */

    protected float timeTigerIsShaking;

    protected float prevTimeTigerIsShaking;

    protected static final String __OBFID = "CL_00001654";

   

    // good to have instances of AI so task list can be modified, including in sub-classes

    protected EntityAIBase aiSwimming = new EntityAISwimming(this);

    protected EntityAIBase aiLeapAtTarget = new EntityAILeapAtTarget(this, 0.4F);

    protected EntityAIBase aiAttackOnCollide = new EntityAIAttackOnCollide(this, 1.0D, true);

    protected EntityAIBase aiFollowOwner = new EntityAIFollowOwner(this, 1.0D, 10.0F, 2.0F);

    protected EntityAIBase aiMate = new EntityAIMate(this, 1.0D);

    protected EntityAIBase aiWander = new EntityAIWander(this, 1.0D);

    protected EntityAIBase aiBeg = new EntityAIBegTiger(this, 8.0F); // in vanilla begging is only for wolf

    protected EntityAIBase aiWatchClosest = new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F);

    protected EntityAIBase aiLookIdle = new EntityAILookIdle(this);

    protected EntityAIBase aiOwnerHurtByTarget = new EntityAIOwnerHurtByTarget(this);

    protected EntityAIBase aiOwnerHurtTarget = new EntityAIOwnerHurtTarget(this);

    protected EntityAIBase aiHurtByTarget = new EntityAIHurtByTarget(this, true);

    protected EntityAIBase aiTargetNonTamed = new EntityAITargetNonTamed(this, EntitySheep.class, 200, false);

 

    public EntityTiger(World par1World)

    {

        super(par1World);

       

        // DEBUG

        System.out.println("EntityTiger constructor()");

 

        this.setSize(0.6F, 0.8F);

        this.getNavigator().setAvoidsWater(true);

        this.tasks.addTask(1, this.aiSwimming);

        this.tasks.addTask(2, this.aiSit);

        this.tasks.addTask(3, this.aiLeapAtTarget);

        this.tasks.addTask(4, this.aiAttackOnCollide);

        this.tasks.addTask(5, this.aiFollowOwner);

        this.tasks.addTask(6, this.aiMate);

        this.tasks.addTask(7, this.aiWander);

        this.tasks.addTask(8, this.aiBeg); // in vanilla begging is only for wolf

        this.tasks.addTask(9, this.aiWatchClosest);

        this.tasks.addTask(10, this.aiLookIdle);

        this.targetTasks.addTask(1, this.aiOwnerHurtByTarget);

        this.targetTasks.addTask(2, this.aiOwnerHurtTarget);

        this.targetTasks.addTask(3, this.aiHurtByTarget);

        this.targetTasks.addTask(4, this.aiTargetNonTamed);

        this.setTamed(false);

    }

   

    // use clear tasks for subclasses then build up their ai task list specifically

    protected void clearAITasks()

    {

        this.tasks.removeTask(this.aiSwimming);

        this.tasks.removeTask(this.aiSit);

        this.tasks.removeTask(this.aiLeapAtTarget);

        this.tasks.removeTask(this.aiAttackOnCollide);

        this.tasks.removeTask(this.aiFollowOwner);

        this.tasks.removeTask(this.aiMate);

        this.tasks.removeTask(this.aiWander);

        this.tasks.removeTask(this.aiBeg); // in vanilla begging is only for wolf

        this.tasks.removeTask(this.aiWatchClosest);

        this.tasks.removeTask(this.aiLookIdle);

        this.targetTasks.removeTask(this.aiOwnerHurtByTarget);

        this.targetTasks.removeTask(this.aiOwnerHurtTarget);

        this.targetTasks.removeTask(this.aiHurtByTarget);

        this.targetTasks.removeTask(this.aiTargetNonTamed);

 

    }

 

    @Override

protected void applyEntityAttributes()

    {

        super.applyEntityAttributes();

        this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.30000001192092896D);

 

        if (this.isTamed())

        {

            this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(20.0D);

        }

        else

        {

            this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(8.0D);

        }

    }

 

    /**

    * Returns true if the newer Entity AI code should be run

    */

    @Override

public boolean isAIEnabled()

    {

        return true;

    }

 

    /**

    * Sets the active target the Task system uses for tracking

    */

    @Override

public void setAttackTarget(EntityLivingBase par1EntityLivingBase)

    {

        super.setAttackTarget(par1EntityLivingBase);

 

        if (par1EntityLivingBase == null)

        {

            this.setAngry(false);

        }

        else if (!this.isTamed())

        {

            this.setAngry(true);

        }

    }

 

    /**

    * main AI tick function, replaces updateEntityActionState

    */

    @Override

protected void updateAITick()

    {

        this.dataWatcher.updateObject(18, Float.valueOf(this.getHealth()));

    }

 

    @Override

protected void entityInit()

    {

        super.entityInit();

        this.dataWatcher.addObject(18, new Float(this.getHealth()));

        this.dataWatcher.addObject(19, new Byte((byte)0));

        this.dataWatcher.addObject(20, new Byte((byte)BlockColored.func_150032_b(1)));

    }

 

    @Override

protected void func_145780_a(int p_145780_1_, int p_145780_2_, int p_145780_3_, Block p_145780_4_)

    {

        this.playSound("wildanimals:mob.tiger.step", 0.15F, 1.0F); // this is randomized from 1 to 5

    }

 

    /**

    * (abstract) Protected helper method to write subclass entity data to NBT.

    */

    @Override

public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)

    {

        super.writeEntityToNBT(par1NBTTagCompound);

        par1NBTTagCompound.setBoolean("Angry", this.isAngry());

        par1NBTTagCompound.setByte("CollarColor", (byte)this.getCollarColor());

    }

 

    /**

    * (abstract) Protected helper method to read subclass entity data from NBT.

    */

    @Override

public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)

    {

        super.readEntityFromNBT(par1NBTTagCompound);

        this.setAngry(par1NBTTagCompound.getBoolean("Angry"));

 

        if (par1NBTTagCompound.hasKey("CollarColor", 99))

        {

            this.setCollarColor(par1NBTTagCompound.getByte("CollarColor"));

        }

    }

 

    /**

    * Returns the sound this mob makes while it's alive.

    */

    @Override

protected String getLivingSound()

    {

        return this.isAngry() ? "wildanimals:mob.tiger.growl" : (this.rand.nextInt(3) == 0 ? (this.isTamed() && this.dataWatcher.getWatchableObjectFloat(18) < 10.0F ? "wildanimals:mob.tiger.whine" : "wildanimals:mob.tiger.panting") : "wildanimals:mob.tiger.bark");

    }

 

    /**

    * Returns the sound this mob makes when it is hurt.

    */

    @Override

protected String getHurtSound()

    {

        return "wildanimals:mob.tiger.hurt"; // It uses sounds.json file to randomize and adds 1, 2 or 3 and .ogg

    }

 

    /**

    * Returns the sound this mob makes on death.

    */

    @Override

protected String getDeathSound()

    {

        return "wildanimals:mob.tiger.death";

    }

 

    /**

    * Returns the volume for the sounds this mob makes.

    */

    @Override

protected float getSoundVolume()

    {

        return 0.4F;

    }

 

    @Override

protected Item getDropItem()

    {

        return Item.getItemById(-1);

    }

 

    /**

    * 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.

    */

    @Override

public void onLivingUpdate()

    {

        super.onLivingUpdate();

 

        if (!this.worldObj.isRemote && this.isShaking && !this.field_70928_h && !this.hasPath() && this.onGround)

        {

            this.field_70928_h = true;

            this.timeTigerIsShaking = 0.0F;

            this.prevTimeTigerIsShaking = 0.0F;

            this.worldObj.setEntityState(this, (byte)8);

        }

    }

 

    /**

    * Called to update the entity's position/logic.

    */

    @Override

public void onUpdate()

    {

        super.onUpdate();

        this.field_70924_f = this.field_70926_e;

 

        if (this.func_70922_bv())

        {

            this.field_70926_e += (1.0F - this.field_70926_e) * 0.4F;

        }

        else

        {

            this.field_70926_e += (0.0F - this.field_70926_e) * 0.4F;

        }

 

        if (this.func_70922_bv())

        {

            this.numTicksToChaseTarget = 10;

        }

 

        if (this.isWet())

        {

            this.isShaking = true;

            this.field_70928_h = false;

            this.timeTigerIsShaking = 0.0F;

            this.prevTimeTigerIsShaking = 0.0F;

        }

        else if ((this.isShaking || this.field_70928_h) && this.field_70928_h)

        {

            if (this.timeTigerIsShaking == 0.0F)

            {

                this.playSound("wildanimals:mob.tiger.shake", this.getSoundVolume(), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F);

            }

 

            this.prevTimeTigerIsShaking = this.timeTigerIsShaking;

            this.timeTigerIsShaking += 0.05F;

 

            if (this.prevTimeTigerIsShaking >= 2.0F)

            {

                this.isShaking = false;

                this.field_70928_h = false;

                this.prevTimeTigerIsShaking = 0.0F;

                this.timeTigerIsShaking = 0.0F;

            }

 

            if (this.timeTigerIsShaking > 0.4F)

            {

                float f = (float)this.boundingBox.minY;

                int i = (int)(MathHelper.sin((this.timeTigerIsShaking - 0.4F) * (float)Math.PI) * 7.0F);

 

                for (int j = 0; j < i; ++j)

                {

                    float f1 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width * 0.5F;

                    float f2 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width * 0.5F;

                    this.worldObj.spawnParticle("splash", this.posX + f1, f + 0.8F, this.posZ + f2, this.motionX, this.motionY, this.motionZ);

                }

            }

        }

    }

 

    @SideOnly(Side.CLIENT)

    public boolean getTigerShaking()

    {

        return this.isShaking;

    }

 

    /**

    * Used when calculating the amount of shading to apply while the tiger is shaking.

    */

    @SideOnly(Side.CLIENT)

    public float getShadingWhileShaking(float par1)

    {

        return 0.75F + (this.prevTimeTigerIsShaking + (this.timeTigerIsShaking - this.prevTimeTigerIsShaking) * par1) / 2.0F * 0.25F;

    }

 

    @SideOnly(Side.CLIENT)

    public float getShakeAngle(float par1, float par2)

    {

        float f2 = (this.prevTimeTigerIsShaking + (this.timeTigerIsShaking - this.prevTimeTigerIsShaking) * par1 + par2) / 1.8F;

 

        if (f2 < 0.0F)

        {

            f2 = 0.0F;

        }

        else if (f2 > 1.0F)

        {

            f2 = 1.0F;

        }

 

        return MathHelper.sin(f2 * (float)Math.PI) * MathHelper.sin(f2 * (float)Math.PI * 11.0F) * 0.15F * (float)Math.PI;

    }

 

    @Override

public float getEyeHeight()

    {

        return this.height * 0.8F;

    }

 

    @SideOnly(Side.CLIENT)

    public float getInterestedAngle(float par1)

    {

        return (this.field_70924_f + (this.field_70926_e - this.field_70924_f) * par1) * 0.15F * (float)Math.PI;

    }

 

    /**

    * The speed it takes to move the entityliving's rotationPitch through the faceEntity method. This is only currently

    * use in wolves.

    */

    @Override

public int getVerticalFaceSpeed()

    {

        return this.isSitting() ? 20 : super.getVerticalFaceSpeed();

    }

 

    /**

    * Called when the entity is attacked.

    */

    @Override

public boolean attackEntityFrom(DamageSource par1DamageSource, float par2)

    {

        if (this.isEntityInvulnerable())

        {

            return false;

        }

        else

        {

            Entity entity = par1DamageSource.getEntity();

            this.aiSit.setSitting(false);

 

            if (entity != null && !(entity instanceof EntityPlayer) && !(entity instanceof EntityArrow))

            {

                par2 = (par2 + 1.0F) / 2.0F;

            }

 

            return super.attackEntityFrom(par1DamageSource, par2);

        }

    }

 

    @Override

public boolean attackEntityAsMob(Entity par1Entity)

    {

        int i = this.isTamed() ? 4 : 2;

        return par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), i);

    }

 

    @Override

public void setTamed(boolean par1)

    {

        super.setTamed(par1);

 

        if (par1)

        {

            this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(20.0D);

        }

        else

        {

            this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(8.0D);

        }

    }

 

    /**

    * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.

    */

    @Override

public boolean interact(EntityPlayer par1EntityPlayer)

    {

        ItemStack itemstack = par1EntityPlayer.inventory.getCurrentItem();

 

        if (this.isTamed())

        {

            if (itemstack != null)

            {

                if (itemstack.getItem() instanceof ItemFood)

                {

                    ItemFood itemfood = (ItemFood)itemstack.getItem();

 

                    if (itemfood.isWolfsFavoriteMeat() && this.dataWatcher.getWatchableObjectFloat(18) < 20.0F)

                    {

                        if (!par1EntityPlayer.capabilities.isCreativeMode)

                        {

                            --itemstack.stackSize;

                        }

 

                        this.heal(itemfood.func_150905_g(itemstack));

 

                        if (itemstack.stackSize <= 0)

                        {

                            par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack)null);

                        }

 

                        return true;

                    }

                }

                else if (itemstack.getItem() == Items.dye)

                {

                    int i = BlockColored.func_150032_b(itemstack.getItemDamage());

 

                    if (i != this.getCollarColor())

                    {

                        this.setCollarColor(i);

 

                        if (!par1EntityPlayer.capabilities.isCreativeMode && --itemstack.stackSize <= 0)

                        {

                            par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack)null);

                        }

 

                        return true;

                    }

                }

            }

 

            if (par1EntityPlayer.getCommandSenderName().equalsIgnoreCase(this.getOwnerName()) && !this.worldObj.isRemote && !this.isBreedingItem(itemstack))

            {

                this.aiSit.setSitting(!this.isSitting());

                this.isJumping = false;

                this.setPathToEntity((PathEntity)null);

                this.setTarget((Entity)null);

                this.setAttackTarget((EntityLivingBase)null);

            }

        }

        else if (itemstack != null && itemstack.getItem() == Items.bone && !this.isAngry())

        {

            if (!par1EntityPlayer.capabilities.isCreativeMode)

            {

                --itemstack.stackSize;

            }

 

            if (itemstack.stackSize <= 0)

            {

                par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack)null);

            }

 

            if (!this.worldObj.isRemote)

            {

                if (this.rand.nextInt(3) == 0)

                {

                    this.setTamed(true);

                    this.setPathToEntity((PathEntity)null);

                    this.setAttackTarget((EntityLivingBase)null);

                    this.aiSit.setSitting(true);

                    this.setHealth(20.0F);

                    this.setOwner(par1EntityPlayer.getCommandSenderName());

                    this.playTameEffect(true);

                    this.worldObj.setEntityState(this, (byte)7);

                }

                else

                {

                    this.playTameEffect(false);

                    this.worldObj.setEntityState(this, (byte)6);

                }

            }

 

            return true;

        }

 

        return super.interact(par1EntityPlayer);

    }

 

    @Override

@SideOnly(Side.CLIENT)

    public void handleHealthUpdate(byte par1)

    {

        if (par1 == 8)

        {

            this.field_70928_h = true;

            this.timeTigerIsShaking = 0.0F;

            this.prevTimeTigerIsShaking = 0.0F;

        }

        else

        {

            super.handleHealthUpdate(par1);

        }

    }

 

    @SideOnly(Side.CLIENT)

    public float getTailRotation()

    {

        return this.isAngry() ? 1.5393804F : (this.isTamed() ? (0.55F - (20.0F - this.dataWatcher.getWatchableObjectFloat(18)) * 0.02F) * (float)Math.PI : ((float)Math.PI / 5F));

    }

 

    /**

    * Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on

    * the animal type)

    */

    @Override

public boolean isBreedingItem(ItemStack par1ItemStack)

    {

        return par1ItemStack == null ? false : (!(par1ItemStack.getItem() instanceof ItemFood) ? false : ((ItemFood)par1ItemStack.getItem()).isWolfsFavoriteMeat());

    }

 

    /**

    * Will return how many at most can spawn in a chunk at once.

    */

    @Override

public int getMaxSpawnedInChunk()

    {

        return 8;

    }

 

    /**

    * Determines whether this tiger is angry or not.

    */

    public boolean isAngry()

    {

        return (this.dataWatcher.getWatchableObjectByte(16) & 2) != 0;

    }

 

    /**

    * Sets whether this tiger is angry or not.

    */

    public void setAngry(boolean par1)

    {

        byte b0 = this.dataWatcher.getWatchableObjectByte(16);

 

        if (par1)

        {

            this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 | 2)));

        }

        else

        {

            this.dataWatcher.updateObject(16, Byte.valueOf((byte)(b0 & -3)));

        }

    }

 

    /**

    * Return this tiger's collar color.

    */

    public int getCollarColor()

    {

        return this.dataWatcher.getWatchableObjectByte(20) & 15;

    }

 

    /**

    * Set this tiger's collar color.

    */

    public void setCollarColor(int par1)

    {

        this.dataWatcher.updateObject(20, Byte.valueOf((byte)(par1 & 15)));

    }

 

    @Override

public EntityTiger createChild(EntityAgeable par1EntityAgeable)

    {

        EntityTiger entitytiger = new EntityTiger(this.worldObj);

        String s = this.getOwnerName();

 

        if (s != null && s.trim().length() > 0)

        {

            entitytiger.setOwner(s);

            entitytiger.setTamed(true);

        }

 

        return entitytiger;

    }

 

    public void func_70918_i(boolean par1)

    {

        if (par1)

        {

            this.dataWatcher.updateObject(19, Byte.valueOf((byte)1));

        }

        else

        {

            this.dataWatcher.updateObject(19, Byte.valueOf((byte)0));

        }

    }

 

    /**

    * Returns true if the mob is currently able to mate with the specified mob.

    */

    @Override

public boolean canMateWith(EntityAnimal par1EntityAnimal)

    {

        if (par1EntityAnimal == this)

        {

            return false;

        }

        else if (!this.isTamed())

        {

            return false;

        }

        else if (!(par1EntityAnimal instanceof EntityTiger))

        {

            return false;

        }

        else

        {

            EntityTiger entitytiger = (EntityTiger)par1EntityAnimal;

            return !entitytiger.isTamed() ? false : (entitytiger.isSitting() ? false : this.isInLove() && entitytiger.isInLove());

        }

    }

 

    public boolean func_70922_bv()

    {

        return this.dataWatcher.getWatchableObjectByte(19) == 1;

    }

 

    /**

    * Determines if an entity can be despawned, used on idle far away entities

    */

    @Override

protected boolean canDespawn()

    {

        return !this.isTamed() && this.ticksExisted > 2400;

    }

 

    @Override

public boolean func_142018_a(EntityLivingBase par1EntityLivingBase, EntityLivingBase par2EntityLivingBase)

    {

        if (!(par1EntityLivingBase instanceof EntityCreeper) && !(par1EntityLivingBase instanceof EntityGhast))

        {

            if (par1EntityLivingBase instanceof EntityTiger)

            {

                EntityTiger entitytiger = (EntityTiger)par1EntityLivingBase;

 

                if (entitytiger.isTamed() && entitytiger.getOwner() == par2EntityLivingBase)

                {

                    return false;

                }

            }

 

            return par1EntityLivingBase instanceof EntityPlayer && par2EntityLivingBase instanceof EntityPlayer && !((EntityPlayer)par2EntityLivingBase).canAttackPlayer((EntityPlayer)par1EntityLivingBase) ? false : !(par1EntityLivingBase instanceof EntityHorse) || !((EntityHorse)par1EntityLivingBase).isTame();

        }

        else

        {

            return false;

        }

    }

}

 

 

EntityManEatingTiger

 

package wildanimals.entities;

 

import net.minecraft.client.Minecraft;

import net.minecraft.entity.EntityLivingBase;

import net.minecraft.entity.SharedMonsterAttributes;

import net.minecraft.entity.player.EntityPlayer;

import net.minecraft.item.ItemStack;

import net.minecraft.world.World;

 

public class EntityManEatingTiger extends EntityTiger

{

 

    public EntityManEatingTiger(World par1World)

    {

        super(par1World);

       

        // DEBUG

        System.out.println("EntityManEatingTiger constructor()");

   

        this.setSize(0.6F, 0.8F);

       

        // rebuild AI task list specific to this sub-class

        clearAITasks();

        this.tasks.addTask(1, this.aiSwimming);

        this.tasks.addTask(2, this.aiLeapAtTarget);

        this.tasks.addTask(3, this.aiAttackOnCollide);

        this.tasks.addTask(4, this.aiWander);

        this.tasks.addTask(5, this.aiWatchClosest);

        this.tasks.addTask(6, this.aiLookIdle);

        this.targetTasks.addTask(1, this.aiHurtByTarget);

        this.targetTasks.addTask(2, this.aiTargetNonTamed);

       

        this.setTamed(false);

        // make him a man-eater by starting angry

        this.setAngry(true);

        // make him hunt the player

    super.setAttackTarget(Minecraft.getMinecraft().thePlayer);

    }

 

    @Override

protected void applyEntityAttributes()

    {

        super.applyEntityAttributes();

        this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.30000001192092896D);

        this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(8.0D);

    }

 

    /**

    * Sets the active target the Task system uses for tracking

    */

    @Override

public void setAttackTarget(EntityLivingBase par1EntityLivingBase)

    {

    if (par1EntityLivingBase!=null) // already has target

    {

            super.setAttackTarget(par1EntityLivingBase);

    }

    else // make player target

    {

    super.setAttackTarget(Minecraft.getMinecraft().thePlayer);

    }

        // always angry makes him a man-eater

        this.setAngry(true);

    }

 

    @Override

protected void entityInit()

    {

        super.entityInit();

        // note that custom datawatcher objects are created in EntityTiger superclass

        this.setAngry(true); // starting angry makes it a man-eater

    }

 

    /**

    * 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.

    */

    @Override

public void onLivingUpdate()

    {

        super.onLivingUpdate();

        this.setAngry(true); // keep the man-eater angry

        if (!this.worldObj.isRemote && this.isShaking && !this.field_70928_h && !this.hasPath() && this.onGround)

        {

            this.field_70928_h = true;

            this.timeTigerIsShaking = 0.0F;

            this.prevTimeTigerIsShaking = 0.0F;

            this.worldObj.setEntityState(this, (byte)8);

        }

    }

 

 

    @Override

public void setTamed(boolean par1)

    {

    // man-eating tiger can't be tamed

    }

 

    /**

    * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.

    */

    @Override

public boolean interact(EntityPlayer par1EntityPlayer)

    {

    // no special interaction for a man-eater!

        return super.interact(par1EntityPlayer);

    }

 

    /**

    * Checks if the parameter is an item which this animal can be fed to breed it (wheat, carrots or seeds depending on

    * the animal type)

    */

    @Override

public boolean isBreedingItem(ItemStack par1ItemStack)

    {

        return false; // can't breed man-eating tiger

    }

 

    /**

    * Will return how many at most can spawn in a chunk at once.

    */

    @Override

public int getMaxSpawnedInChunk()

    {

        return 8;

    }

}

 

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

Okay, I had some success by changing the way I reference the player.

 

Originally I had:

 

super.setAttackTarget(Minecraft.getMinecraft().thePlayer);

 

Which I replaced with:

 

hunted_player = this.worldObj.getClosestVulnerablePlayerToEntity(this, 32.0D);

super.setAttackTarget(hunted_player != null && this.canEntityBeSeen(hunted_player) ? hunted_player : null);

 

 

 

I guess I'm okay now that it works, but I like to understand code that doesn't behave how I expect.  Why would the original code make the entity look like it attacked (but with no damage) whereas the second version works?

 

I'm guessing it has to do with server side versus client side?  Maybe the first one wasn't properly updating the server version of the player object so what looked like an attack on the client side didn't really cause damage?

 

client - server stuff is still something I mess up a lot ...

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.