    001    package net.minecraft.src;
    002
    003    import cpw.mods.fml.common.Side;
    004    import cpw.mods.fml.common.asm.SideOnly;
    005    import cpw.mods.fml.common.registry.VillagerRegistry;
    006
    007    import java.util.Collections;
    008    import java.util.HashMap;
    009    import java.util.Iterator;
    010    import java.util.Map;
    011    import java.util.Random;
    012
    013    public class EntityVillager extends EntityAgeable implements INpc, IMerchant
    014    {
    015        private int randomTickDivider;
    016        private boolean isMating;
    017        private boolean isPlaying;
    018        Village villageObj;
    019
    020        /** This villager's current customer. */
    021        private EntityPlayer buyingPlayer;
    022
    023        /** Initialises the MerchantRecipeList.java */
    024        private MerchantRecipeList buyingList;
    025        private int timeUntilReset;
    026
    027        /** addDefaultEquipmentAndRecipies is called if this is true */
    028        private boolean needsInitilization;
    029        private int wealth;
    030
    031        /** Last player to trade with this villager, used for aggressivity. */
    032        private String lastBuyingPlayer;
    033        private boolean field_82190_bM;
    034        private float field_82191_bN;
    035
    036        /**
    037         * a villagers recipe list is intialized off this list ; the 2 params are min/max amount they will trade for 1
    038         * emerald
    039         */
    040        public static final Map villagerStockList = new HashMap();
    041
    042        /**
    043         * Selling list of Blacksmith items. negative numbers mean 1 emerald for n items, positive numbers are n emeralds
    044         * for 1 item
    045         */
    046        public static final Map blacksmithSellingList = new HashMap();
    047
    048        public EntityVillager(World par1World)
    049        {
    050            this(par1World, 0);
    051        }
    052
    053        public EntityVillager(World par1World, int par2)
    054        {
    055            super(par1World);
    056            this.randomTickDivider = 0;
    057            this.isMating = false;
    058            this.isPlaying = false;
    059            this.villageObj = null;
    060            this.setProfession(par2);
    061            this.texture = "/mob/villager/villager.png";
    062            this.moveSpeed = 0.5F;
    063            this.getNavigator().setBreakDoors(true);
    064            this.getNavigator().setAvoidsWater(true);
    065            this.tasks.addTask(0, new EntityAISwimming(this));
    066            this.tasks.addTask(1, new EntityAIAvoidEntity(this, EntityZombie.class, 8.0F, 0.3F, 0.35F));
    067            this.tasks.addTask(1, new EntityAITradePlayer(this));
    068            this.tasks.addTask(1, new EntityAILookAtTradePlayer(this));
    069            this.tasks.addTask(2, new EntityAIMoveIndoors(this));
    070            this.tasks.addTask(3, new EntityAIRestrictOpenDoor(this));
    071            this.tasks.addTask(4, new EntityAIOpenDoor(this, true));
    072            this.tasks.addTask(5, new EntityAIMoveTwardsRestriction(this, 0.3F));
    073            this.tasks.addTask(6, new EntityAIVillagerMate(this));
    074            this.tasks.addTask(7, new EntityAIFollowGolem(this));
    075            this.tasks.addTask(8, new EntityAIPlay(this, 0.32F));
    076            this.tasks.addTask(9, new EntityAIWatchClosest2(this, EntityPlayer.class, 3.0F, 1.0F));
    077            this.tasks.addTask(9, new EntityAIWatchClosest2(this, EntityVillager.class, 5.0F, 0.02F));
    078            this.tasks.addTask(9, new EntityAIWander(this, 0.3F));
    079            this.tasks.addTask(10, new EntityAIWatchClosest(this, EntityLiving.class, 8.0F));
    080        }
    081
    082        /**
    083         * Returns true if the newer Entity AI code should be run
    084         */
    085        public boolean isAIEnabled()
    086        {
    087            return true;
    088        }
    089
    090        /**
    091         * main AI tick function, replaces updateEntityActionState
    092         */
    093        protected void updateAITick()
    094        {
    095            if (--this.randomTickDivider <= 0)
    096            {
    097                this.worldObj.villageCollectionObj.addVillagerPosition(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ));
    098                this.randomTickDivider = 70 + this.rand.nextInt(50);
    099                this.villageObj = this.worldObj.villageCollectionObj.findNearestVillage(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ), 32);
    100
    101                if (this.villageObj == null)
    102                {
    103                    this.detachHome();
    104                }
    105                else
    106                {
    107                    ChunkCoordinates var1 = this.villageObj.getCenter();
    108                    this.setHomeArea(var1.posX, var1.posY, var1.posZ, (int)((float)this.villageObj.getVillageRadius() * 0.6F));
    109
    110                    if (this.field_82190_bM)
    111                    {
    112                        this.field_82190_bM = false;
    113                        this.villageObj.func_82683_b(5);
    114                    }
    115                }
    116            }
    117
    118            if (!this.isTrading() && this.timeUntilReset > 0)
    119            {
    120                --this.timeUntilReset;
    121
    122                if (this.timeUntilReset <= 0)
    123                {
    124                    if (this.needsInitilization)
    125                    {
    126                        if (this.buyingList.size() > 1)
    127                        {
    128                            Iterator var3 = this.buyingList.iterator();
    129
    130                            while (var3.hasNext())
    131                            {
    132                                MerchantRecipe var2 = (MerchantRecipe)var3.next();
    133
    134                                if (var2.func_82784_g())
    135                                {
    136                                    var2.func_82783_a(this.rand.nextInt(6) + this.rand.nextInt(6) + 2);
    137                                }
    138                            }
    139                        }
    140
    141                        this.addDefaultEquipmentAndRecipies(1);
    142                        this.needsInitilization = false;
    143
    144                        if (this.villageObj != null && this.lastBuyingPlayer != null)
    145                        {
    146                            this.worldObj.setEntityState(this, (byte)14);
    147                            this.villageObj.setReputationForPlayer(this.lastBuyingPlayer, 1);
    148                        }
    149                    }
    150
    151                    this.addPotionEffect(new PotionEffect(Potion.regeneration.id, 200, 0));
    152                }
    153            }
    154
    155            super.updateAITick();
    156        }
    157
    158        /**
    159         * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig.
    160         */
    161        public boolean interact(EntityPlayer par1EntityPlayer)
    162        {
    163            ItemStack var2 = par1EntityPlayer.inventory.getCurrentItem();
    164            boolean var3 = var2 != null && var2.itemID == Item.monsterPlacer.shiftedIndex;
    165
    166            if (!var3 && this.isEntityAlive() && !this.isTrading() && !this.isChild())
    167            {
    168                if (!this.worldObj.isRemote)
    169                {
    170                    this.setCustomer(par1EntityPlayer);
    171                    par1EntityPlayer.displayGUIMerchant(this);
    172                }
    173
    174                return true;
    175            }
    176            else
    177            {
    178                return super.interact(par1EntityPlayer);
    179            }
    180        }
    181
    182        protected void entityInit()
    183        {
    184            super.entityInit();
    185            this.dataWatcher.addObject(16, Integer.valueOf(0));
    186        }
    187
    188        public int getMaxHealth()
    189        {
    190            return 20;
    191        }
    192
    193        /**
    194         * (abstract) Protected helper method to write subclass entity data to NBT.
    195         */
    196        public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
    197        {
    198            super.writeEntityToNBT(par1NBTTagCompound);
    199            par1NBTTagCompound.setInteger("Profession", this.getProfession());
    200            par1NBTTagCompound.setInteger("Riches", this.wealth);
    201
    202            if (this.buyingList != null)
    203            {
    204                par1NBTTagCompound.setCompoundTag("Offers", this.buyingList.getRecipiesAsTags());
    205            }
    206        }
    207
    208        /**
    209         * (abstract) Protected helper method to read subclass entity data from NBT.
    210         */
    211        public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
    212        {
    213            super.readEntityFromNBT(par1NBTTagCompound);
    214            this.setProfession(par1NBTTagCompound.getInteger("Profession"));
    215            this.wealth = par1NBTTagCompound.getInteger("Riches");
    216
    217            if (par1NBTTagCompound.hasKey("Offers"))
    218            {
    219                NBTTagCompound var2 = par1NBTTagCompound.getCompoundTag("Offers");
    220                this.buyingList = new MerchantRecipeList(var2);
    221            }
    222        }
    223
    224        @SideOnly(Side.CLIENT)
    225
    226        /**
    227         * Returns the texture's file path as a String.
    228         */
    229        public String getTexture()
    230        {
    231            switch (this.getProfession())
    232            {
    233                case 0:
    234                    return "/mob/villager/farmer.png";
    235                case 1:
    236                    return "/mob/villager/librarian.png";
    237                case 2:
    238                    return "/mob/villager/priest.png";
    239                case 3:
    240                    return "/mob/villager/smith.png";
    241                case 4:
    242                    return "/mob/villager/butcher.png";
    243                default:
    244                    return VillagerRegistry.getVillagerSkin(this.getProfession(), super.getTexture());
    245            }
    246        }
    247
    248        /**
    249         * Determines if an entity can be despawned, used on idle far away entities
    250         */
    251        protected boolean canDespawn()
    252        {
    253            return false;
    254        }
    255
    256        /**
    257         * Returns the sound this mob makes while it's alive.
    258         */
    259        protected String getLivingSound()
    260        {
    261            return "mob.villager.default";
    262        }
    263
    264        /**
    265         * Returns the sound this mob makes when it is hurt.
    266         */
    267        protected String getHurtSound()
    268        {
    269            return "mob.villager.defaulthurt";
    270        }
    271
    272        /**
    273         * Returns the sound this mob makes on death.
    274         */
    275        protected String getDeathSound()
    276        {
    277            return "mob.villager.defaultdeath";
    278        }
    279
    280        public void setProfession(int par1)
    281        {
    282            this.dataWatcher.updateObject(16, Integer.valueOf(par1));
    283        }
    284
    285        public int getProfession()
    286        {
    287            return this.dataWatcher.getWatchableObjectInt(16);
    288        }
    289
    290        public boolean isMating()
    291        {
    292            return this.isMating;
    293        }
    294
    295        public void setMating(boolean par1)
    296        {
    297            this.isMating = par1;
    298        }
    299
    300        public void setPlaying(boolean par1)
    301        {
    302            this.isPlaying = par1;
    303        }
    304
    305        public boolean isPlaying()
    306        {
    307            return this.isPlaying;
    308        }
    309
    310        public void setRevengeTarget(EntityLiving par1EntityLiving)
    311        {
    312            super.setRevengeTarget(par1EntityLiving);
    313
    314            if (this.villageObj != null && par1EntityLiving != null)
    315            {
    316                this.villageObj.addOrRenewAgressor(par1EntityLiving);
    317
    318                if (par1EntityLiving instanceof EntityPlayer)
    319                {
    320                    byte var2 = -1;
    321
    322                    if (this.isChild())
    323                    {
    324                        var2 = -3;
    325                    }
    326
    327                    this.villageObj.setReputationForPlayer(((EntityPlayer)par1EntityLiving).getCommandSenderName(), var2);
    328
    329                    if (this.isEntityAlive())
    330                    {
    331                        this.worldObj.setEntityState(this, (byte)13);
    332                    }
    333                }
    334            }
    335        }
    336
    337        /**
    338         * Called when the mob's health reaches 0.
    339         */
    340        public void onDeath(DamageSource par1DamageSource)
    341        {
    342            if (this.villageObj != null)
    343            {
    344                Entity var2 = par1DamageSource.getEntity();
    345
    346                if (var2 != null)
    347                {
    348                    if (var2 instanceof EntityPlayer)
    349                    {
    350                        this.villageObj.setReputationForPlayer(((EntityPlayer)var2).getCommandSenderName(), -2);
    351                    }
    352                    else if (var2 instanceof IMob)
    353                    {
    354                        this.villageObj.func_82692_h();
    355                    }
    356                }
    357                else if (var2 == null)
    358                {
    359                    EntityPlayer var3 = this.worldObj.getClosestPlayerToEntity(this, 16.0D);
    360
    361                    if (var3 != null)
    362                    {
    363                        this.villageObj.func_82692_h();
    364                    }
    365                }
    366            }
    367
    368            super.onDeath(par1DamageSource);
    369        }
    370
    371        public void setCustomer(EntityPlayer par1EntityPlayer)
    372        {
    373            this.buyingPlayer = par1EntityPlayer;
    374        }
    375
    376        public EntityPlayer getCustomer()
    377        {
    378            return this.buyingPlayer;
    379        }
    380
    381        public boolean isTrading()
    382        {
    383            return this.buyingPlayer != null;
    384        }
    385
    386        public void useRecipe(MerchantRecipe par1MerchantRecipe)
    387        {
    388            par1MerchantRecipe.incrementToolUses();
    389
    390            if (par1MerchantRecipe.hasSameIDsAs((MerchantRecipe)this.buyingList.get(this.buyingList.size() - 1)))
    391            {
    392                this.timeUntilReset = 40;
    393                this.needsInitilization = true;
    394
    395                if (this.buyingPlayer != null)
    396                {
    397                    this.lastBuyingPlayer = this.buyingPlayer.getCommandSenderName();
    398                }
    399                else
    400                {
    401                    this.lastBuyingPlayer = null;
    402                }
    403            }
    404
    405            if (par1MerchantRecipe.getItemToBuy().itemID == Item.emerald.shiftedIndex)
    406            {
    407                this.wealth += par1MerchantRecipe.getItemToBuy().stackSize;
    408            }
    409        }
    410
    411        public MerchantRecipeList getRecipes(EntityPlayer par1EntityPlayer)
    412        {
    413            if (this.buyingList == null)
    414            {
    415                this.addDefaultEquipmentAndRecipies(1);
    416            }
    417
    418            return this.buyingList;
    419        }
    420
    421        private float func_82188_j(float par1)
    422        {
    423            float var2 = par1 + this.field_82191_bN;
    424            return var2 > 0.9F ? 0.9F - (var2 - 0.9F) : var2;
    425        }
    426
    427        /**
    428         * based on the villagers profession add items, equipment, and recipies adds par1 random items to the list of things
    429         * that the villager wants to buy. (at most 1 of each wanted type is added)
    430         */
    431        private void addDefaultEquipmentAndRecipies(int par1)
    432        {
    433            if (this.buyingList != null)
    434            {
    435                this.field_82191_bN = MathHelper.sqrt_float((float)this.buyingList.size()) * 0.2F;
    436            }
    437            else
    438            {
    439                this.field_82191_bN = 0.0F;
    440            }
    441
    442            MerchantRecipeList var2;
    443            var2 = new MerchantRecipeList();
    444            VillagerRegistry.manageVillagerTrades(var2, this, this.getProfession(), this.rand);
    445            label48:
    446
    447            switch (this.getProfession())
    448            {
    449                case 0:
    450                    addMerchantItem(var2, Item.wheat.shiftedIndex, this.rand, this.func_82188_j(0.9F));
    451                    addMerchantItem(var2, Block.cloth.blockID, this.rand, this.func_82188_j(0.5F));
    452                    addMerchantItem(var2, Item.chickenRaw.shiftedIndex, this.rand, this.func_82188_j(0.5F));
    453                    addMerchantItem(var2, Item.fishCooked.shiftedIndex, this.rand, this.func_82188_j(0.4F));
    454                    addBlacksmithItem(var2, Item.bread.shiftedIndex, this.rand, this.func_82188_j(0.9F));
    455                    addBlacksmithItem(var2, Item.melon.shiftedIndex, this.rand, this.func_82188_j(0.3F));
    456                    addBlacksmithItem(var2, Item.appleRed.shiftedIndex, this.rand, this.func_82188_j(0.3F));
    457                    addBlacksmithItem(var2, Item.cookie.shiftedIndex, this.rand, this.func_82188_j(0.3F));
    458                    addBlacksmithItem(var2, Item.shears.shiftedIndex, this.rand, this.func_82188_j(0.3F));
    459                    addBlacksmithItem(var2, Item.flintAndSteel.shiftedIndex, this.rand, this.func_82188_j(0.3F));
    460                    addBlacksmithItem(var2, Item.chickenCooked.shiftedIndex, this.rand, this.func_82188_j(0.3F));
    461                    addBlacksmithItem(var2, Item.arrow.shiftedIndex, this.rand, this.func_82188_j(0.5F));
    462
    463                    if (this.rand.nextFloat() < this.func_82188_j(0.5F))
    464                    {
    465                        var2.add(new MerchantRecipe(new ItemStack(Block.gravel, 10), new ItemStack(Item.emerald), new ItemStack(Item.flint.shiftedIndex, 4 + this.rand.nextInt(2), 0)));
    466                    }
    467
    468                    break;
    469                case 1:
    470                    addMerchantItem(var2, Item.paper.shiftedIndex, this.rand, this.func_82188_j(0.8F));
    471                    addMerchantItem(var2, Item.book.shiftedIndex, this.rand, this.func_82188_j(0.8F));
    472                    addMerchantItem(var2, Item.writtenBook.shiftedIndex, this.rand, this.func_82188_j(0.3F));
    473                    addBlacksmithItem(var2, Block.bookShelf.blockID, this.rand, this.func_82188_j(0.8F));
    474                    addBlacksmithItem(var2, Block.glass.blockID, this.rand, this.func_82188_j(0.2F));
    475                    addBlacksmithItem(var2, Item.compass.shiftedIndex, this.rand, this.func_82188_j(0.2F));
    476                    addBlacksmithItem(var2, Item.pocketSundial.shiftedIndex, this.rand, this.func_82188_j(0.2F));
    477                    break;
    478                case 2:
    479                    addBlacksmithItem(var2, Item.eyeOfEnder.shiftedIndex, this.rand, this.func_82188_j(0.3F));
    480                    addBlacksmithItem(var2, Item.expBottle.shiftedIndex, this.rand, this.func_82188_j(0.2F));
    481                    addBlacksmithItem(var2, Item.redstone.shiftedIndex, this.rand, this.func_82188_j(0.4F));
    482                    addBlacksmithItem(var2, Block.glowStone.blockID, this.rand, this.func_82188_j(0.3F));
    483                    int[] var3 = new int[] {Item.swordSteel.shiftedIndex, Item.swordDiamond.shiftedIndex, Item.plateSteel.shiftedIndex, Item.plateDiamond.shiftedIndex, Item.axeSteel.shiftedIndex, Item.axeDiamond.shiftedIndex, Item.pickaxeSteel.shiftedIndex, Item.pickaxeDiamond.shiftedIndex};
    484                    int[] var4 = var3;
    485                    int var5 = var3.length;
    486                    int var6 = 0;
    487
    488                    while (true)
    489                    {
    490                        if (var6 >= var5)
    491                        {
    492                            break label48;
    493                        }
    494
    495                        int var7 = var4[var6];
    496
    497                        if (this.rand.nextFloat() < this.func_82188_j(0.05F))
    498                        {
    499                            var2.add(new MerchantRecipe(new ItemStack(var7, 1, 0), new ItemStack(Item.emerald, 2 + this.rand.nextInt(3), 0), EnchantmentHelper.addRandomEnchantment(this.rand, new ItemStack(var7, 1, 0), 5 + this.rand.nextInt(15))));
    500                        }
    501
    502                        ++var6;
    503                    }
    504                case 3:
    505                    addMerchantItem(var2, Item.coal.shiftedIndex, this.rand, this.func_82188_j(0.7F));
    506                    addMerchantItem(var2, Item.ingotIron.shiftedIndex, this.rand, this.func_82188_j(0.5F));
    507                    addMerchantItem(var2, Item.ingotGold.shiftedIndex, this.rand, this.func_82188_j(0.5F));
    508                    addMerchantItem(var2, Item.diamond.shiftedIndex, this.rand, this.func_82188_j(0.5F));
    509                    addBlacksmithItem(var2, Item.swordSteel.shiftedIndex, this.rand, this.func_82188_j(0.5F));
    510                    addBlacksmithItem(var2, Item.swordDiamond.shiftedIndex, this.rand, this.func_82188_j(0.5F));
    511                    addBlacksmithItem(var2, Item.axeSteel.shiftedIndex, this.rand, this.func_82188_j(0.3F));
    512                    addBlacksmithItem(var2, Item.axeDiamond.shiftedIndex, this.rand, this.func_82188_j(0.3F));
    513                    addBlacksmithItem(var2, Item.pickaxeSteel.shiftedIndex, this.rand, this.func_82188_j(0.5F));
    514                    addBlacksmithItem(var2, Item.pickaxeDiamond.shiftedIndex, this.rand, this.func_82188_j(0.5F));
    515                    addBlacksmithItem(var2, Item.shovelSteel.shiftedIndex, this.rand, this.func_82188_j(0.2F));
    516                    addBlacksmithItem(var2, Item.shovelDiamond.shiftedIndex, this.rand, this.func_82188_j(0.2F));
    517                    addBlacksmithItem(var2, Item.hoeSteel.shiftedIndex, this.rand, this.func_82188_j(0.2F));
    518                    addBlacksmithItem(var2, Item.hoeDiamond.shiftedIndex, this.rand, this.func_82188_j(0.2F));
    519                    addBlacksmithItem(var2, Item.bootsSteel.shiftedIndex, this.rand, this.func_82188_j(0.2F));
    520                    addBlacksmithItem(var2, Item.bootsDiamond.shiftedIndex, this.rand, this.func_82188_j(0.2F));
    521                    addBlacksmithItem(var2, Item.helmetSteel.shiftedIndex, this.rand, this.func_82188_j(0.2F));
    522                    addBlacksmithItem(var2, Item.helmetDiamond.shiftedIndex, this.rand, this.func_82188_j(0.2F));
    523                    addBlacksmithItem(var2, Item.plateSteel.shiftedIndex, this.rand, this.func_82188_j(0.2F));
    524                    addBlacksmithItem(var2, Item.plateDiamond.shiftedIndex, this.rand, this.func_82188_j(0.2F));
    525                    addBlacksmithItem(var2, Item.legsSteel.shiftedIndex, this.rand, this.func_82188_j(0.2F));
    526                    addBlacksmithItem(var2, Item.legsDiamond.shiftedIndex, this.rand, this.func_82188_j(0.2F));
    527                    addBlacksmithItem(var2, Item.bootsChain.shiftedIndex, this.rand, this.func_82188_j(0.1F));
    528                    addBlacksmithItem(var2, Item.helmetChain.shiftedIndex, this.rand, this.func_82188_j(0.1F));
    529                    addBlacksmithItem(var2, Item.plateChain.shiftedIndex, this.rand, this.func_82188_j(0.1F));
    530                    addBlacksmithItem(var2, Item.legsChain.shiftedIndex, this.rand, this.func_82188_j(0.1F));
    531                    break;
    532                case 4:
    533                    addMerchantItem(var2, Item.coal.shiftedIndex, this.rand, this.func_82188_j(0.7F));
    534                    addMerchantItem(var2, Item.porkRaw.shiftedIndex, this.rand, this.func_82188_j(0.5F));
    535                    addMerchantItem(var2, Item.beefRaw.shiftedIndex, this.rand, this.func_82188_j(0.5F));
    536                    addBlacksmithItem(var2, Item.saddle.shiftedIndex, this.rand, this.func_82188_j(0.1F));
    537                    addBlacksmithItem(var2, Item.plateLeather.shiftedIndex, this.rand, this.func_82188_j(0.3F));
    538                    addBlacksmithItem(var2, Item.bootsLeather.shiftedIndex, this.rand, this.func_82188_j(0.3F));
    539                    addBlacksmithItem(var2, Item.helmetLeather.shiftedIndex, this.rand, this.func_82188_j(0.3F));
    540                    addBlacksmithItem(var2, Item.legsLeather.shiftedIndex, this.rand, this.func_82188_j(0.3F));
    541                    addBlacksmithItem(var2, Item.porkCooked.shiftedIndex, this.rand, this.func_82188_j(0.3F));
    542                    addBlacksmithItem(var2, Item.beefCooked.shiftedIndex, this.rand, this.func_82188_j(0.3F));
    543            }
    544
    545            if (var2.isEmpty())
    546            {
    547                addMerchantItem(var2, Item.ingotGold.shiftedIndex, this.rand, 1.0F);
    548            }
    549
    550            Collections.shuffle(var2);
    551
    552            if (this.buyingList == null)
    553            {
    554                this.buyingList = new MerchantRecipeList();
    555            }
    556
    557            for (int var8 = 0; var8 < par1 && var8 < var2.size(); ++var8)
    558            {
    559                this.buyingList.addToListWithCheck((MerchantRecipe)var2.get(var8));
    560            }
    561        }
    562
    563        @SideOnly(Side.CLIENT)
    564        public void setRecipes(MerchantRecipeList par1MerchantRecipeList) {}
    565
    566        /**
    567         * each recipie takes a random stack from villagerStockList and offers it for 1 emerald
    568         */
    569        public static void addMerchantItem(MerchantRecipeList par0MerchantRecipeList, int par1, Random par2Random, float par3)
    570        {
    571            if (par2Random.nextFloat() < par3)
    572            {
    573                par0MerchantRecipeList.add(new MerchantRecipe(getRandomSizedStack(par1, par2Random), Item.emerald));
    574            }
    575        }
    576
    577        private static ItemStack getRandomSizedStack(int par0, Random par1Random)
    578        {
    579            return new ItemStack(par0, getRandomCountForItem(par0, par1Random), 0);
    580        }
    581
    582        /**
    583         * default to 1, and villagerStockList contains a min/max amount for each index
    584         */
    585        private static int getRandomCountForItem(int par0, Random par1Random)
    586        {
    587            Tuple var2 = (Tuple)villagerStockList.get(Integer.valueOf(par0));
    588            return var2 == null ? 1 : (((Integer)var2.getFirst()).intValue() >= ((Integer)var2.getSecond()).intValue() ? ((Integer)var2.getFirst()).intValue() : ((Integer)var2.getFirst()).intValue() + par1Random.nextInt(((Integer)var2.getSecond()).intValue() - ((Integer)var2.getFirst()).intValue()));
    589        }
    590
    591        public static void addBlacksmithItem(MerchantRecipeList par0MerchantRecipeList, int par1, Random par2Random, float par3)
    592        {
    593            if (par2Random.nextFloat() < par3)
    594            {
    595                int var4 = getRandomCountForBlacksmithItem(par1, par2Random);
    596                ItemStack var5;
    597                ItemStack var6;
    598
    599                if (var4 < 0)
    600                {
    601                    var5 = new ItemStack(Item.emerald.shiftedIndex, 1, 0);
    602                    var6 = new ItemStack(par1, -var4, 0);
    603                }
    604                else
    605                {
    606                    var5 = new ItemStack(Item.emerald.shiftedIndex, var4, 0);
    607                    var6 = new ItemStack(par1, 1, 0);
    608                }
    609
    610                par0MerchantRecipeList.add(new MerchantRecipe(var5, var6));
    611            }
    612        }
    613
    614        private static int getRandomCountForBlacksmithItem(int par0, Random par1Random)
    615        {
    616            Tuple var2 = (Tuple)blacksmithSellingList.get(Integer.valueOf(par0));
    617            return var2 == null ? 1 : (((Integer)var2.getFirst()).intValue() >= ((Integer)var2.getSecond()).intValue() ? ((Integer)var2.getFirst()).intValue() : ((Integer)var2.getFirst()).intValue() + par1Random.nextInt(((Integer)var2.getSecond()).intValue() - ((Integer)var2.getFirst()).intValue()));
    618        }
    619
    620        @SideOnly(Side.CLIENT)
    621        public void handleHealthUpdate(byte par1)
    622        {
    623            if (par1 == 12)
    624            {
    625                this.generateRandomParticles("heart");
    626            }
    627            else if (par1 == 13)
    628            {
    629                this.generateRandomParticles("angryVillager");
    630            }
    631            else if (par1 == 14)
    632            {
    633                this.generateRandomParticles("happyVillager");
    634            }
    635            else
    636            {
    637                super.handleHealthUpdate(par1);
    638            }
    639        }
    640
    641        @SideOnly(Side.CLIENT)
    642
    643        /**
    644         * par1 is the particleName
    645         */
    646        private void generateRandomParticles(String par1Str)
    647        {
    648            for (int var2 = 0; var2 < 5; ++var2)
    649            {
    650                double var3 = this.rand.nextGaussian() * 0.02D;
    651                double var5 = this.rand.nextGaussian() * 0.02D;
    652                double var7 = this.rand.nextGaussian() * 0.02D;
    653                this.worldObj.spawnParticle(par1Str, this.posX + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, this.posY + 1.0D + (double)(this.rand.nextFloat() * this.height), this.posZ + (double)(this.rand.nextFloat() * this.width * 2.0F) - (double)this.width, var3, var5, var7);
    654            }
    655        }
    656
    657        /**
    658         * Initialize this creature.
    659         */
    660        public void initCreature()
    661        {
    662            VillagerRegistry.applyRandomTrade(this, worldObj.rand);
    663        }
    664
    665        public void func_82187_q()
    666        {
    667            this.field_82190_bM = true;
    668        }
    669
    670        public EntityVillager func_90012_b(EntityAgeable par1EntityAgeable)
    671        {
    672            return new EntityVillager(this.worldObj);
    673        }
    674
    675        public EntityAgeable func_90011_a(EntityAgeable par1EntityAgeable)
    676        {
    677            return this.func_90012_b(par1EntityAgeable);
    678        }
    679
    680        static
    681        {
    682            villagerStockList.put(Integer.valueOf(Item.coal.shiftedIndex), new Tuple(Integer.valueOf(16), Integer.valueOf(24)));
    683            villagerStockList.put(Integer.valueOf(Item.ingotIron.shiftedIndex), new Tuple(Integer.valueOf(8), Integer.valueOf(10)));
    684            villagerStockList.put(Integer.valueOf(Item.ingotGold.shiftedIndex), new Tuple(Integer.valueOf(8), Integer.valueOf(10)));
    685            villagerStockList.put(Integer.valueOf(Item.diamond.shiftedIndex), new Tuple(Integer.valueOf(4), Integer.valueOf(6)));
    686            villagerStockList.put(Integer.valueOf(Item.paper.shiftedIndex), new Tuple(Integer.valueOf(24), Integer.valueOf(36)));
    687            villagerStockList.put(Integer.valueOf(Item.book.shiftedIndex), new Tuple(Integer.valueOf(11), Integer.valueOf(13)));
    688            villagerStockList.put(Integer.valueOf(Item.writtenBook.shiftedIndex), new Tuple(Integer.valueOf(1), Integer.valueOf(1)));
    689            villagerStockList.put(Integer.valueOf(Item.enderPearl.shiftedIndex), new Tuple(Integer.valueOf(3), Integer.valueOf(4)));
    690            villagerStockList.put(Integer.valueOf(Item.eyeOfEnder.shiftedIndex), new Tuple(Integer.valueOf(2), Integer.valueOf(3)));
    691            villagerStockList.put(Integer.valueOf(Item.porkRaw.shiftedIndex), new Tuple(Integer.valueOf(14), Integer.valueOf(18)));
    692            villagerStockList.put(Integer.valueOf(Item.beefRaw.shiftedIndex), new Tuple(Integer.valueOf(14), Integer.valueOf(18)));
    693            villagerStockList.put(Integer.valueOf(Item.chickenRaw.shiftedIndex), new Tuple(Integer.valueOf(14), Integer.valueOf(18)));
    694            villagerStockList.put(Integer.valueOf(Item.fishCooked.shiftedIndex), new Tuple(Integer.valueOf(9), Integer.valueOf(13)));
    695            villagerStockList.put(Integer.valueOf(Item.seeds.shiftedIndex), new Tuple(Integer.valueOf(34), Integer.valueOf(48)));
    696            villagerStockList.put(Integer.valueOf(Item.melonSeeds.shiftedIndex), new Tuple(Integer.valueOf(30), Integer.valueOf(38)));
    697            villagerStockList.put(Integer.valueOf(Item.pumpkinSeeds.shiftedIndex), new Tuple(Integer.valueOf(30), Integer.valueOf(38)));
    698            villagerStockList.put(Integer.valueOf(Item.wheat.shiftedIndex), new Tuple(Integer.valueOf(18), Integer.valueOf(22)));
    699            villagerStockList.put(Integer.valueOf(Block.cloth.blockID), new Tuple(Integer.valueOf(14), Integer.valueOf(22)));
    700            villagerStockList.put(Integer.valueOf(Item.rottenFlesh.shiftedIndex), new Tuple(Integer.valueOf(36), Integer.valueOf(64)));
    701            blacksmithSellingList.put(Integer.valueOf(Item.flintAndSteel.shiftedIndex), new Tuple(Integer.valueOf(3), Integer.valueOf(4)));
    702            blacksmithSellingList.put(Integer.valueOf(Item.shears.shiftedIndex), new Tuple(Integer.valueOf(3), Integer.valueOf(4)));
    703            blacksmithSellingList.put(Integer.valueOf(Item.swordSteel.shiftedIndex), new Tuple(Integer.valueOf(7), Integer.valueOf(11)));
    704            blacksmithSellingList.put(Integer.valueOf(Item.swordDiamond.shiftedIndex), new Tuple(Integer.valueOf(12), Integer.valueOf(14)));
    705            blacksmithSellingList.put(Integer.valueOf(Item.axeSteel.shiftedIndex), new Tuple(Integer.valueOf(6), Integer.valueOf(8)));
    706            blacksmithSellingList.put(Integer.valueOf(Item.axeDiamond.shiftedIndex), new Tuple(Integer.valueOf(9), Integer.valueOf(12)));
    707            blacksmithSellingList.put(Integer.valueOf(Item.pickaxeSteel.shiftedIndex), new Tuple(Integer.valueOf(7), Integer.valueOf(9)));
    708            blacksmithSellingList.put(Integer.valueOf(Item.pickaxeDiamond.shiftedIndex), new Tuple(Integer.valueOf(10), Integer.valueOf(12)));
    709            blacksmithSellingList.put(Integer.valueOf(Item.shovelSteel.shiftedIndex), new Tuple(Integer.valueOf(4), Integer.valueOf(6)));
    710            blacksmithSellingList.put(Integer.valueOf(Item.shovelDiamond.shiftedIndex), new Tuple(Integer.valueOf(7), Integer.valueOf(8)));
    711            blacksmithSellingList.put(Integer.valueOf(Item.hoeSteel.shiftedIndex), new Tuple(Integer.valueOf(4), Integer.valueOf(6)));
    712            blacksmithSellingList.put(Integer.valueOf(Item.hoeDiamond.shiftedIndex), new Tuple(Integer.valueOf(7), Integer.valueOf(8)));
    713            blacksmithSellingList.put(Integer.valueOf(Item.bootsSteel.shiftedIndex), new Tuple(Integer.valueOf(4), Integer.valueOf(6)));
    714            blacksmithSellingList.put(Integer.valueOf(Item.bootsDiamond.shiftedIndex), new Tuple(Integer.valueOf(7), Integer.valueOf(8)));
    715            blacksmithSellingList.put(Integer.valueOf(Item.helmetSteel.shiftedIndex), new Tuple(Integer.valueOf(4), Integer.valueOf(6)));
    716            blacksmithSellingList.put(Integer.valueOf(Item.helmetDiamond.shiftedIndex), new Tuple(Integer.valueOf(7), Integer.valueOf(8)));
    717            blacksmithSellingList.put(Integer.valueOf(Item.plateSteel.shiftedIndex), new Tuple(Integer.valueOf(10), Integer.valueOf(14)));
    718            blacksmithSellingList.put(Integer.valueOf(Item.plateDiamond.shiftedIndex), new Tuple(Integer.valueOf(16), Integer.valueOf(19)));
    719            blacksmithSellingList.put(Integer.valueOf(Item.legsSteel.shiftedIndex), new Tuple(Integer.valueOf(8), Integer.valueOf(10)));
    720            blacksmithSellingList.put(Integer.valueOf(Item.legsDiamond.shiftedIndex), new Tuple(Integer.valueOf(11), Integer.valueOf(14)));
    721            blacksmithSellingList.put(Integer.valueOf(Item.bootsChain.shiftedIndex), new Tuple(Integer.valueOf(5), Integer.valueOf(7)));
    722            blacksmithSellingList.put(Integer.valueOf(Item.helmetChain.shiftedIndex), new Tuple(Integer.valueOf(5), Integer.valueOf(7)));
    723            blacksmithSellingList.put(Integer.valueOf(Item.plateChain.shiftedIndex), new Tuple(Integer.valueOf(11), Integer.valueOf(15)));
    724            blacksmithSellingList.put(Integer.valueOf(Item.legsChain.shiftedIndex), new Tuple(Integer.valueOf(9), Integer.valueOf(11)));
    725            blacksmithSellingList.put(Integer.valueOf(Item.bread.shiftedIndex), new Tuple(Integer.valueOf(-4), Integer.valueOf(-2)));
    726            blacksmithSellingList.put(Integer.valueOf(Item.melon.shiftedIndex), new Tuple(Integer.valueOf(-8), Integer.valueOf(-4)));
    727            blacksmithSellingList.put(Integer.valueOf(Item.appleRed.shiftedIndex), new Tuple(Integer.valueOf(-8), Integer.valueOf(-4)));
    728            blacksmithSellingList.put(Integer.valueOf(Item.cookie.shiftedIndex), new Tuple(Integer.valueOf(-10), Integer.valueOf(-7)));
    729            blacksmithSellingList.put(Integer.valueOf(Block.glass.blockID), new Tuple(Integer.valueOf(-5), Integer.valueOf(-3)));
    730            blacksmithSellingList.put(Integer.valueOf(Block.bookShelf.blockID), new Tuple(Integer.valueOf(3), Integer.valueOf(4)));
    731            blacksmithSellingList.put(Integer.valueOf(Item.plateLeather.shiftedIndex), new Tuple(Integer.valueOf(4), Integer.valueOf(5)));
    732            blacksmithSellingList.put(Integer.valueOf(Item.bootsLeather.shiftedIndex), new Tuple(Integer.valueOf(2), Integer.valueOf(4)));
    733            blacksmithSellingList.put(Integer.valueOf(Item.helmetLeather.shiftedIndex), new Tuple(Integer.valueOf(2), Integer.valueOf(4)));
    734            blacksmithSellingList.put(Integer.valueOf(Item.legsLeather.shiftedIndex), new Tuple(Integer.valueOf(2), Integer.valueOf(4)));
    735            blacksmithSellingList.put(Integer.valueOf(Item.saddle.shiftedIndex), new Tuple(Integer.valueOf(6), Integer.valueOf(8)));
    736            blacksmithSellingList.put(Integer.valueOf(Item.expBottle.shiftedIndex), new Tuple(Integer.valueOf(-4), Integer.valueOf(-1)));
    737            blacksmithSellingList.put(Integer.valueOf(Item.redstone.shiftedIndex), new Tuple(Integer.valueOf(-4), Integer.valueOf(-1)));
    738            blacksmithSellingList.put(Integer.valueOf(Item.compass.shiftedIndex), new Tuple(Integer.valueOf(10), Integer.valueOf(12)));
    739            blacksmithSellingList.put(Integer.valueOf(Item.pocketSundial.shiftedIndex), new Tuple(Integer.valueOf(10), Integer.valueOf(12)));
    740            blacksmithSellingList.put(Integer.valueOf(Block.glowStone.blockID), new Tuple(Integer.valueOf(-3), Integer.valueOf(-1)));
    741            blacksmithSellingList.put(Integer.valueOf(Item.porkCooked.shiftedIndex), new Tuple(Integer.valueOf(-7), Integer.valueOf(-5)));
    742            blacksmithSellingList.put(Integer.valueOf(Item.beefCooked.shiftedIndex), new Tuple(Integer.valueOf(-7), Integer.valueOf(-5)));
    743            blacksmithSellingList.put(Integer.valueOf(Item.chickenCooked.shiftedIndex), new Tuple(Integer.valueOf(-8), Integer.valueOf(-6)));
    744            blacksmithSellingList.put(Integer.valueOf(Item.eyeOfEnder.shiftedIndex), new Tuple(Integer.valueOf(7), Integer.valueOf(11)));
    745            blacksmithSellingList.put(Integer.valueOf(Item.arrow.shiftedIndex), new Tuple(Integer.valueOf(-12), Integer.valueOf(-8)));
    746        }
    747    }