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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Slot deposit 3000 adalah situs slot deposit 3000 via dana yang super gacor dimana para pemain dijamin garansi wd hari ini juga hanya dengan modal receh berupa deposit sebesar 3000 baik via dana, ovo, gopay maupun linkaja untuk para pemain pengguna e-wallet di seluruh Indonesia.   DAFTAR & LOGIN AKUN PRO SLOT DEPOSIT 3000 ⭐⭐⭐ KLIK DISINI ⭐⭐⭐  
    • OLXTOTO: Menikmati Sensasi Bermain Togel dan Slot dengan Aman dan Mengasyikkan Dunia perjudian daring terus berkembang dengan cepat, dan salah satu situs yang telah menonjol dalam pasar adalah OLXTOTO. Sebagai platform resmi untuk permainan togel dan slot, OLXTOTO telah memenangkan kepercayaan banyak pemain dengan menyediakan pengalaman bermain yang aman, adil, dan mengasyikkan. DAFTAR OLXTOTO DISINI <a href="https://imgbb.com/"><img src="https://i.ibb.co/GnjSVpx/daftar1-480x480.webp" alt="daftar1-480x480" border="0" /></a> Keamanan Sebagai Prioritas Utama Salah satu aspek utama yang membuat OLXTOTO begitu menonjol adalah komitmennya terhadap keamanan pemain. Dengan menggunakan teknologi enkripsi terkini, situs ini memastikan bahwa semua informasi pribadi dan keuangan para pemain tetap aman dan terlindungi dari akses yang tidak sah. Beragam Permainan yang Menarik Di OLXTOTO, pemain dapat menemukan beragam permainan yang menarik untuk dinikmati. Mulai dari permainan klasik seperti togel hingga slot modern dengan fitur-fitur inovatif, ada sesuatu untuk setiap selera dan preferensi. Grafik yang memukau dan efek suara yang mengagumkan menambah keseruan setiap putaran. Peluang Menang yang Tinggi Salah satu hal yang paling menarik bagi para pemain adalah peluang menang yang tinggi yang ditawarkan oleh OLXTOTO. Dengan pembayaran yang adil dan peluang yang setara bagi semua pemain, setiap taruhan memberikan kesempatan nyata untuk memenangkan hadiah besar. Layanan Pelanggan yang Responsif Tim layanan pelanggan OLXTOTO siap membantu para pemain dengan setiap pertanyaan atau masalah yang mereka hadapi. Dengan layanan yang ramah dan responsif, pemain dapat yakin bahwa mereka akan mendapatkan bantuan yang mereka butuhkan dengan cepat dan efisien. Kesimpulan OLXTOTO telah membuktikan dirinya sebagai salah satu situs terbaik untuk penggemar togel dan slot online. Dengan fokus pada keamanan, beragam permainan yang menarik, peluang menang yang tinggi, dan layanan pelanggan yang luar biasa, tidak mengherankan bahwa situs ini telah menjadi pilihan utama bagi banyak pemain. Jadi, jika Anda mencari pengalaman bermain yang aman, adil, dan mengasyikkan, jangan ragu untuk bergabung dengan OLXTOTO hari ini dan rasakan sensasi kemenangan!
    • Slot deposit dana adalah situs slot deposit dana yang juga menerima dari e-wallet lain seperti deposit via dana, ovo, gopay & linkaja terlengkap saat ini, sehingga para pemain yang tidak memiliki rekening bank lokal bisa tetap bermain slot dan terbantu dengan adanya fitur tersebut.   DAFTAR & LOGIN AKUN PRO SLOT DEPOSIT DANA ⭐⭐⭐ KLIK DISINI ⭐⭐⭐  
    • Slot deposit dana adalah situs slot deposit dana minimal 5000 yang dijamin garansi super gacor dan gampang menang, dimana para pemain yang tidak memiliki rekening bank lokal tetap dalam bermain slot dengan melakukan deposit dana serta e-wallet lainnya seperti ovo, gopay maupun linkaja lengkap. Agar para pecinta slot di seluruh Indonesia tetap dapat menikmati permainan tanpa halangan apapun khususnya metode deposit, dimana ketersediaan cara deposit saat ini yang lebih beragam tentunya sangat membantu para pecinta slot.   DAFTAR & LOGIN AKUN PRO SLOT DEPOSIT DANA ⭐⭐⭐ KLIK DISINI ⭐⭐⭐  
    • Slot deposit pulsa adalah situs slot deposit pulsa tanpa potongan apapun yang dijamin garansi terpercaya, dimana kamu bisa bermain slot dengan melakukan deposit pulsa dan tanpa dikenakan potongan apapun sehingga dana yang masuk ke dalam akun akan 100% utuh. Proses penarikan dana juga dijamin gampang dan tidak sulit sehingga kamu tidak perlu khawatir akan kemenangan yang akan kamu peroleh dengan sangat mudah jika bermain disini.   DAFTAR & LOGIN AKUN PRO SLOT DEPOSIT PULSA TANPA POTONGAN ⭐⭐⭐ KLIK DISINI ⭐⭐⭐  
  • Topics

×
×
  • Create New...

Important Information

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