Jump to content

Entity Tameable


ninjapancakes87

Recommended Posts

Hi I am making a mod and using some wolf code for a "tameable soldier."  I am using the exact same code the wolf uses to save and load it's "isAngry" data.  However, for me it throws an error saying cannot convert from an Integer to a Byte.  Help?

EntitySoldier_Union code:

package ninjapancakes87.civilwar.common.campUnion.soldier;

import cpw.mods.fml.common.registry.VillagerRegistry;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.BlockCloth;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentData;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityAgeable;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.IMerchant;
import net.minecraft.entity.INpc;
import net.minecraft.entity.IRangedAttackMob;
import net.minecraft.entity.ai.EntityAIArrowAttack;
import net.minecraft.entity.ai.EntityAIAvoidEntity;
import net.minecraft.entity.ai.EntityAIFollowGolem;
import net.minecraft.entity.ai.EntityAILookAtTradePlayer;
import net.minecraft.entity.ai.EntityAIMoveIndoors;
import net.minecraft.entity.ai.EntityAIMoveTwardsRestriction;
import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
import net.minecraft.entity.ai.EntityAIOpenDoor;
import net.minecraft.entity.ai.EntityAIPlay;
import net.minecraft.entity.ai.EntityAIRestrictOpenDoor;
import net.minecraft.entity.ai.EntityAISwimming;
import net.minecraft.entity.ai.EntityAITradePlayer;
import net.minecraft.entity.ai.EntityAIVillagerMate;
import net.minecraft.entity.ai.EntityAIWander;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.ai.EntityAIWatchClosest2;
import net.minecraft.entity.monster.EntityZombie;
import net.minecraft.entity.monster.IMob;
import net.minecraft.entity.passive.EntityAnimal;
import net.minecraft.entity.passive.EntityTameable;
import net.minecraft.entity.passive.EntityWolf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityArrow;
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.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.util.DamageSource;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Tuple;
import net.minecraft.village.MerchantRecipe;
import net.minecraft.village.MerchantRecipeList;
import net.minecraft.village.Village;
import net.minecraft.world.World;
import ninjapancakes87.civilwar.common.CivilWar;
import ninjapancakes87.civilwar.common.campConfederate.soldierConF.EntitySoldier_Rebel;
import ninjapancakes87.civilwar.common.item.EntityMusketBall;

public class EntitySoldier_Union extends EntityTameable implements INpc, IRangedAttackMob
{
    private int randomTickDivider;

    /** addDefaultEquipmentAndRecipies is called if this is true */
    private boolean needsInitilization;

    /** Last player to trade with this villager, used for aggressivity. */
    private String lastBuyingPlayer;
    private boolean field_82190_bM;
    private float field_82191_bN;
    
    public Class EntitySoldier_Rebel;

    public EntitySoldier_Union(World par1World)
    {
        this(par1World, 0);
    }

    public EntitySoldier_Union(World par1World, int par2)
    {
        super(par1World);
        this.randomTickDivider = 0;
        this.setProfession(par2);
        this.texture = "/mods/Civil War/textures/mob/UnionSoldier.png";
        this.moveSpeed = 0.5F;
        this.addDefaultEquipment();
        this.setSize(0.6F, 1.8F);
        this.getNavigator().setBreakDoors(true);
        this.getNavigator().setAvoidsWater(true);
        this.tasks.addTask(0, new EntityAISwimming(this));
        this.tasks.addTask(2, new EntityAIMoveIndoors(this));
        this.tasks.addTask(3, new EntityAIRestrictOpenDoor(this));
        this.tasks.addTask(4, new EntityAIOpenDoor(this, true));
        this.tasks.addTask(9, new EntityAIWatchClosest2(this, EntityPlayer.class, 3.0F, 1.0F));
        this.tasks.addTask(9, new EntityAIWatchClosest2(this, EntitySoldier_Union.class, 5.0F, 0.02F));
        this.tasks.addTask(9, new EntityAIWander(this, 0.3F));
        this.tasks.addTask(10, new EntityAIWatchClosest(this, EntityLiving.class, 8.0F));
        //this.targetTasks.addTask(1, new EntityAINearestAttackableTarget(this, EntitySoldier_Rebel, 50, 100, true));
        //this.targetTasks.addTask(2, new EntityAIArrowAttack(this, field_82191_bN, par2, field_82191_bN));
    }
    public boolean isAIEnabled()
    {
        return true;
    }

    /**
     * Sets the active target the Task system uses for tracking
     */
    public void setAttackTarget(EntityLiving par1EntityLiving)
    {
        super.setAttackTarget(par1EntityLiving);

        if (par1EntityLiving instanceof EntityPlayer)
        {
            this.setAngry(true);
        }
    }

    /**
     * main AI tick function, replaces updateEntityActionState
     */
    protected void updateAITick()
    {
        this.dataWatcher.updateObject(18, Integer.valueOf(this.getHealth()));
    }

    public int getMaxHealth()
    {
        return this.isTamed() ? 20 : 8;
    }

    protected void entityInit()
    {
        super.entityInit();
        this.dataWatcher.addObject(18, new Integer(this.getHealth()));
        this.dataWatcher.addObject(19, new Byte((byte)0));
    }

    /**
     * (abstract) Protected helper method to write subclass entity data to NBT.
     */
    public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
    {
        super.writeEntityToNBT(par1NBTTagCompound);
        par1NBTTagCompound.setBoolean("Angry", this.isAngry());
        par1NBTTagCompound.setInteger("Profession", this.getProfession());
    }

    /**
     * (abstract) Protected helper method to read subclass entity data from NBT.
     */
    public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
    {
        super.readEntityFromNBT(par1NBTTagCompound);
        this.setAngry(par1NBTTagCompound.getBoolean("Angry"));
        this.setProfession(par1NBTTagCompound.getInteger("Profession"));
    }

    /**
     * Determines if an entity can be despawned, used on idle far away entities
     */
    protected boolean canDespawn()
    {
        return this.isAngry() && !this.isTamed();
    }

    /**
     * Returns the volume for the sounds this mob makes.
     */
    protected float getSoundVolume()
    {
        return 0.4F;
    }

    /**
     * Returns the item ID for the item the mob drops on death.
     */
    protected int getDropItemId()
    {
        return -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.
     */
    public void onLivingUpdate()
    {
        super.onLivingUpdate();
    }

    /**
     * Called to update the entity's position/logic.
     */
    public void onUpdate()
    {
        super.onUpdate();
    }

    /**
     * Called when the entity is attacked.
     */
    public boolean attackEntityFrom(DamageSource par1DamageSource, int par2)
    {
        if (this.isEntityInvulnerable())
        {
            return false;
        }
        else
        {
            Entity entity = par1DamageSource.getEntity();

            if (entity != null && !(entity instanceof EntityPlayer) && !(entity instanceof EntityArrow))
            {
                par2 = (par2 + 1) / 2;
            }

            return super.attackEntityFrom(par1DamageSource, par2);
        }
    }

    public boolean attackEntityAsMob(Entity par1Entity)
    {
        int i = this.isTamed() ? 4 : 2;
        return par1Entity.attackEntityFrom(DamageSource.causeMobDamage(this), i);
    }

    @SideOnly(Side.CLIENT)
    public void handleHealthUpdate(byte par1)
    {
        super.handleHealthUpdate(par1);
    }

    /**
     * Determines whether this wolf is angry or not.
     */
    public boolean isAngry()
    {
        return (this.dataWatcher.getWatchableObjectByte(16) & 2) != 0;
    }

    /**
     * Sets whether this wolf 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)));
        }
    }

    public void func_70918_i(boolean par1)
    {
        byte b0 = this.dataWatcher.getWatchableObjectByte(19);

        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.
     */
    public boolean canMateWith(EntityAnimal par1EntityAnimal)
    {
        return false;
    }

    public boolean func_70922_bv()
    {
        return this.dataWatcher.getWatchableObjectByte(19) == 1;
    }

    @Override
    public void attackEntityWithRangedAttack(EntityLiving par1EntityLiving, float par2)
    {
        EntityMusketBall entityarrow = new EntityMusketBall(this.worldObj, this, par1EntityLiving, 1.6F, (float)(14 - this.worldObj.difficultySetting * 4));

        this.playSound("Civil War.gunshot", 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F));
        this.worldObj.spawnEntityInWorld(entityarrow);
    }

@Override
public EntityAgeable createChild(EntityAgeable entityageable) {
	return null;
}
 public int getMaxSpawnedInChunk()
    {
        return 16;
    }
 public boolean isBreedingItem(ItemStack par1ItemStack)
    {
        return par1ItemStack == null ? false : (!(Item.itemsList[par1ItemStack.itemID] instanceof ItemFood) ? false : ((ItemFood)Item.itemsList[par1ItemStack.itemID]).isWolfsFavoriteMeat());
    }
 public String getProfessionName(int par1){
	 switch(par1){
	 case 0: return "Commander";
	 case 1: return "Captain";
	 case 2: return "Doctor";
	 case 3: return "Barracks Master";
	 case 4: return "Soldier";
	 default: return "Soldier";
	 }
 }
 private void addDefaultEquipment()
    {
        switch (this.getProfession())
        {
        case 0: this.setCurrentItemOrArmor(1,new ItemStack(setArmor(1))); this.setCurrentItemOrArmor(2,new ItemStack(setArmor(2))); this.setCurrentItemOrArmor(3,new ItemStack(setArmor(3))); this.setCurrentItemOrArmor(4,new ItemStack(setArmor(4)));
        case 1:	this.setCurrentItemOrArmor(1,new ItemStack(setArmor(1))); this.setCurrentItemOrArmor(2,new ItemStack(setArmor(2))); this.setCurrentItemOrArmor(3,new ItemStack(setArmor(3))); this.setCurrentItemOrArmor(4,new ItemStack(setArmor(4)));
        case 2: this.setCurrentItemOrArmor(0, new ItemStack(Item.appleRed));
        case 3: this.setCurrentItemOrArmor(1,new ItemStack(setArmor(1))); this.setCurrentItemOrArmor(2,new ItemStack(setArmor(2))); this.setCurrentItemOrArmor(3,new ItemStack(setArmor(3))); this.setCurrentItemOrArmor(4,new ItemStack(setArmor(4)));
        case 4: this.setCurrentItemOrArmor(1,new ItemStack(setArmor(1))); this.setCurrentItemOrArmor(2,new ItemStack(setArmor(2))); this.setCurrentItemOrArmor(3,new ItemStack(setArmor(3))); this.setCurrentItemOrArmor(4,new ItemStack(setArmor(4)));
        }
       }
    protected Item setArmor(int par1){
    	Item i = null;
    	if(par1 == 1){
    		i = CivilWar.clothhelmet;
    	}
    	else if(par1 == 2){
    		i = CivilWar.clothchestplate;
    	}
    	else if(par1 == 3){
    		i = CivilWar.clothlegs;
    	}
    	else if(par1 == 4){
    		i = CivilWar.clothboots;
    	}
    	return i;
    }
    public void setProfession(int par1)
    {
        this.dataWatcher.updateObject(16, Integer.valueOf(par1));
    }

    public int getProfession()
    {
        return this.dataWatcher.getWatchableObjectInt(16);
    }
    protected String getLivingSound()
    {
        return "mob.villager.default";
    }

    /**
     * Returns the sound this mob makes when it is hurt.
     */
    protected String getHurtSound()
    {
        return "Civil War.hurt";
    }

    /**
     * Returns the sound this mob makes on death.
     */
    protected String getDeathSound()
    {
        return "Civil War.hurt";
    }
    public boolean interact(EntityPlayer par1EntityPlayer)
    {
        ItemStack itemstack = par1EntityPlayer.inventory.getCurrentItem();

        if (this.isTamed())
        {
            if (itemstack != null)
            {
                if (Item.itemsList[itemstack.itemID] instanceof ItemFood)
                {
                    ItemFood itemfood = (ItemFood)Item.itemsList[itemstack.itemID];

                    if (itemfood.isWolfsFavoriteMeat() && this.dataWatcher.getWatchableObjectInt(18) < 20)
                    {
                        if (!par1EntityPlayer.capabilities.isCreativeMode)
                        {
                            --itemstack.stackSize;
                        }

                        this.heal(itemfood.getHealAmount());

                        if (itemstack.stackSize <= 0)
                        {
                            par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, (ItemStack)null);
                        }

                        return true;
                    }
                }
            }

            if (par1EntityPlayer.username.equalsIgnoreCase(this.getOwnerName()) && !this.worldObj.isRemote && !this.isBreedingItem(itemstack))
            {
                this.isJumping = false;
                this.setPathToEntity((PathEntity)null);
            }
        }
        else if (itemstack != null && itemstack.itemID == CivilWar.coin.itemID && !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);
                    par1EntityPlayer.addChatMessage("You have recruited a soldier with the profession" + this.getProfessionName(this.getProfession()));
                    this.setPathToEntity((PathEntity)null);
                    this.setAttackTarget((EntityLiving)null);
                    this.setEntityHealth(20);
                    this.setOwner(par1EntityPlayer.username);
                    this.playTameEffect(true);
                }
                else
                {
                    this.playTameEffect(false);
                }
            }

            return true;
        }

        return super.interact(par1EntityPlayer);
    }

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

    @SideOnly(Side.CLIENT)

    /**
     * Returns the texture's file path as a String.
     */
    public String getTexture()
    {
        switch (this.getProfession())
        {
            case 0:
                return "/mods/Civil War/textures/mob/UnionCommander.png";
            case 1:
                return "/mods/Civil War/textures/mob/UnionCaptain.png";
            case 2:
                return "/mods/Civil War/textures/mob/UnionDoctor.png";
            case 3:
                return "/mods/Civil War/textures/mob/UnionWeaponsMaster.png";
            case 4:
                return "/mods/Civil War/textures/mob/UnionSoldier.png";
            default:
                return this.texture;
        }
    }
}

Link to comment
Share on other sites

  • 2 years later...

Just posting an answer for others to find when searching the same issue. Yes, I know it's two and a half years old, but still....

 

One problem in the code might be that your get/set Profession code uses dataWatcher watchable object index number 16. That's already defined in EntityTameable as a byte.

 

For anyone using the dataWatcher instance, please be aware of the many possible combinations of watchable objects in the super classes. For example, my own investigation might have produced data such as the following table:

Entity

0

flags (bit-based?)

1

air (entity breathable amount)

2

custom name tag text

3

using custom name tag

4

isSilent/setSilent: whether to play sound

EntityLivingBase

6

health: a float value representing the current HP

7-8

potion effects mapping

9

arrow count in entity

EntityLiving

15

is AI enabled/disabled; may not necessarily be used, AI seems to be always-on

EntityAgeable

12

growing age, negative values for child entities, positive for adult entities

EntityTameable

16

byte-flags for dual-use, maybe? 4bits for tamed state, 1bit for sitting state, .. remaining bits unused?

17

String for owner-entity "name"

and so on, and so forth, et cetera, et cetera...

 

In any case, using watchable object index 16 may be one problem, easily fixable; I assume any index not used by a superclass of the Entity subclass you extend, may be used as necessary.

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.