Jump to content

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


Recommended Posts

Posted

(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/

Posted

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/

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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Hi,  I'm using Forge 47.3.0 for Minecraft 1.20.1 I apologise if this is obvious I am very new to modding for Minecraft. I sucessfully made a mod that launched without errors or crashes (without it doing anything) but in order to add the features I need, I need to add "Custom Portal API [Forge]" as a dependency. However no matter the way I've tried to acheive this, it crashes. I am pretty sure it's not the way I'm putting it in the repositories, the dependencies or the way I'm refrencing it, as I've a hundred diffrent combinations and multiple Maven methods. And on all those diffrent variations I still get this crash: pastebin.com/UhumzZCZ Any tips would be invaluable as I've been loosing my mind over this!
    • Hi, i'm really having problems trying to set the texture to my custom item. I thought i'm doing everything correctly, but all i see is the missing texture block for my item. I am trying this for over a week now and getting really frustrated. The only time i could make the texture work, was when i used an older Forge version (52.0.1) for Minecraft (1.21.4). Was there a fundamental change for textures and models somewhere between versions that i'm missing? I started with Forge 54.1.0 and had this problem, so in my frustration i tried many things: Upgrading to Forge 54.1.1, created multiple new projects, workspaces, redownloaded everything and setting things up multiple times, as it was suggested in an older thread. Therea are no errors in the console logs, but maybe i'm blind, so i pasted the console logs to pastebin anyway: https://pastebin.com/zAM8RiUN The only time i see an error is when i change the models JSON file to an incorrect JSON which makes sense and that suggests to me it is actually reading the JSON file.   I set the github repository to public, i would be so thankful if anyone could take a look and tell me what i did wrong: https://github.com/xLorkin/teleport_pug_forge   As a note: i'm pretty new to modding, this is my first mod ever. But i'm used to programming. I had some up and downs, but through reading the documentation, using google and experimenting, i could solve all other problems. I only started modding for Minecraft because my son is such a big fan and wanted this mod.
    • Please read the FAQ (link in orange bar at top of page), and post logs as described there.
    • Hello fellow Minecrafters! I recently returned to Minecraft and realized I needed a wiki that displays basic information easily and had great user navigation. That’s why I decided to build: MinecraftSearch — a site by a Minecraft fan, for Minecraft fans. Key Features So Far Straight-to-the-Point Info: No extra fluff; just the essentials on items, mobs, recipes, loot and more. Clean & Intuitive Layout: Easy navigation so you spend less time scrolling and more time playing. Optimized Search: Search for anything—items, mobs, blocks—and get results instantly. What I’m Thinking of Adding More data/information: Catch chances for fishing rod, traveling villager trades, biomes info and a lot more. The website is still under development and need a lot more data added. Community Contributions: Potential for user-uploaded tips for items/mobs/blocks in the future. Feature Requests Welcome: Your ideas could shape how the wiki evolves! You can see my roadmap at the About page https://minecraftsearch.com/about I’d love for you to check out MinecraftSearch and see if it helps you find the info you need faster. Feedback is crucial—I want to develop this further based on what the community needs most, so please let me know what you think. Thanks, and happy crafting!
  • Topics

  • Who's Online (See full list)

    • There are no registered users currently online
×
×
  • Create New...

Important Information

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