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