001 package net.minecraft.entity.player; 002 003 import cpw.mods.fml.common.FMLCommonHandler; 004 import cpw.mods.fml.common.Side; 005 import cpw.mods.fml.common.asm.SideOnly; 006 import cpw.mods.fml.common.network.FMLNetworkHandler; 007 008 import java.util.Iterator; 009 import java.util.List; 010 import net.minecraft.block.Block; 011 import net.minecraft.block.BlockBed; 012 import net.minecraft.block.material.Material; 013 import net.minecraft.command.ICommandSender; 014 import net.minecraft.enchantment.EnchantmentHelper; 015 import net.minecraft.entity.Entity; 016 import net.minecraft.entity.EntityLiving; 017 import net.minecraft.entity.IMerchant; 018 import net.minecraft.entity.item.EntityBoat; 019 import net.minecraft.entity.item.EntityItem; 020 import net.minecraft.entity.item.EntityMinecart; 021 import net.minecraft.entity.monster.EntityCreeper; 022 import net.minecraft.entity.monster.EntityGhast; 023 import net.minecraft.entity.monster.EntityMob; 024 import net.minecraft.entity.monster.IMob; 025 import net.minecraft.entity.passive.EntityPig; 026 import net.minecraft.entity.passive.EntityWolf; 027 import net.minecraft.entity.projectile.EntityArrow; 028 import net.minecraft.entity.projectile.EntityFishHook; 029 import net.minecraft.inventory.Container; 030 import net.minecraft.inventory.ContainerPlayer; 031 import net.minecraft.inventory.IInventory; 032 import net.minecraft.inventory.InventoryEnderChest; 033 import net.minecraft.item.EnumAction; 034 import net.minecraft.item.Item; 035 import net.minecraft.item.ItemStack; 036 import net.minecraft.nbt.NBTTagCompound; 037 import net.minecraft.nbt.NBTTagList; 038 import net.minecraft.potion.Potion; 039 import net.minecraft.stats.AchievementList; 040 import net.minecraft.stats.StatBase; 041 import net.minecraft.stats.StatList; 042 import net.minecraft.tileentity.TileEntity; 043 import net.minecraft.tileentity.TileEntityBeacon; 044 import net.minecraft.tileentity.TileEntityBrewingStand; 045 import net.minecraft.tileentity.TileEntityDispenser; 046 import net.minecraft.tileentity.TileEntityFurnace; 047 import net.minecraft.util.AxisAlignedBB; 048 import net.minecraft.util.ChunkCoordinates; 049 import net.minecraft.util.DamageSource; 050 import net.minecraft.util.FoodStats; 051 import net.minecraft.util.MathHelper; 052 import net.minecraft.util.StringTranslate; 053 import net.minecraft.util.Vec3; 054 import net.minecraft.world.EnumGameType; 055 import net.minecraft.world.World; 056 import net.minecraft.world.chunk.IChunkProvider; 057 058 import net.minecraftforge.common.ForgeHooks; 059 import net.minecraftforge.common.ISpecialArmor.ArmorProperties; 060 import net.minecraftforge.common.MinecraftForge; 061 import net.minecraftforge.event.ForgeEventFactory; 062 import net.minecraftforge.event.entity.living.LivingHurtEvent; 063 import net.minecraftforge.event.entity.player.AttackEntityEvent; 064 import net.minecraftforge.event.entity.player.EntityInteractEvent; 065 import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent; 066 import net.minecraftforge.event.entity.player.PlayerDropsEvent; 067 import net.minecraftforge.event.entity.player.PlayerSleepInBedEvent; 068 069 public abstract class EntityPlayer extends EntityLiving implements ICommandSender 070 { 071 public static final String PERSISTED_NBT_TAG = "PlayerPersisted"; 072 073 /** Inventory of the player */ 074 public InventoryPlayer inventory = new InventoryPlayer(this); 075 private InventoryEnderChest theInventoryEnderChest = new InventoryEnderChest(); 076 077 /** 078 * The Container for the player's inventory (which opens when they press E) 079 */ 080 public Container inventoryContainer; 081 082 /** The Container the player has open. */ 083 public Container openContainer; 084 085 /** The player's food stats. (See class FoodStats) */ 086 protected FoodStats foodStats = new FoodStats(); 087 088 /** 089 * Used to tell if the player pressed jump twice. If this is at 0 and it's pressed (And they are allowed to fly, as 090 * defined in the player's movementInput) it sets this to 7. If it's pressed and it's greater than 0 enable fly. 091 */ 092 protected int flyToggleTimer = 0; 093 public byte field_71098_bD = 0; 094 public float prevCameraYaw; 095 public float cameraYaw; 096 public String username; 097 @SideOnly(Side.CLIENT) 098 public String playerCloakUrl; 099 100 /** 101 * Used by EntityPlayer to prevent too many xp orbs from getting absorbed at once. 102 */ 103 public int xpCooldown = 0; 104 public double field_71091_bM; 105 public double field_71096_bN; 106 public double field_71097_bO; 107 public double field_71094_bP; 108 public double field_71095_bQ; 109 public double field_71085_bR; 110 111 /** Boolean value indicating weather a player is sleeping or not */ 112 protected boolean sleeping; 113 114 /** 115 * The chunk coordinates of the bed the player is in (null if player isn't in a bed). 116 */ 117 public ChunkCoordinates playerLocation; 118 private int sleepTimer; 119 public float field_71079_bU; 120 @SideOnly(Side.CLIENT) 121 public float field_71082_cx; 122 public float field_71089_bV; 123 124 /** 125 * Holds the last coordinate to spawn based on last bed that the player sleep. 126 */ 127 private ChunkCoordinates spawnChunk; 128 129 /** 130 * Whether this player's spawn point is forced, preventing execution of bed checks. 131 */ 132 private boolean spawnForced; 133 134 /** Holds the coordinate of the player when enter a minecraft to ride. */ 135 private ChunkCoordinates startMinecartRidingCoordinate; 136 137 /** The player's capabilities. (See class PlayerCapabilities) */ 138 public PlayerCapabilities capabilities = new PlayerCapabilities(); 139 140 /** The current experience level the player is on. */ 141 public int experienceLevel; 142 143 /** 144 * The total amount of experience the player has. This also includes the amount of experience within their 145 * Experience Bar. 146 */ 147 public int experienceTotal; 148 149 /** 150 * The current amount of experience the player has within their Experience Bar. 151 */ 152 public float experience; 153 154 /** 155 * This is the item that is in use when the player is holding down the useItemButton (e.g., bow, food, sword) 156 */ 157 private ItemStack itemInUse; 158 159 /** 160 * This field starts off equal to getMaxItemUseDuration and is decremented on each tick 161 */ 162 private int itemInUseCount; 163 protected float speedOnGround = 0.1F; 164 protected float speedInAir = 0.02F; 165 private int field_82249_h = 0; 166 167 /** 168 * An instance of a fishing rod's hook. If this isn't null, the icon image of the fishing rod is slightly different 169 */ 170 public EntityFishHook fishEntity = null; 171 172 public EntityPlayer(World par1World) 173 { 174 super(par1World); 175 this.inventoryContainer = new ContainerPlayer(this.inventory, !par1World.isRemote, this); 176 this.openContainer = this.inventoryContainer; 177 this.yOffset = 1.62F; 178 ChunkCoordinates var2 = par1World.getSpawnPoint(); 179 this.setLocationAndAngles((double)var2.posX + 0.5D, (double)(var2.posY + 1), (double)var2.posZ + 0.5D, 0.0F, 0.0F); 180 this.entityType = "humanoid"; 181 this.field_70741_aB = 180.0F; 182 this.fireResistance = 20; 183 this.texture = "/mob/char.png"; 184 } 185 186 public int getMaxHealth() 187 { 188 return 20; 189 } 190 191 protected void entityInit() 192 { 193 super.entityInit(); 194 this.dataWatcher.addObject(16, Byte.valueOf((byte)0)); 195 this.dataWatcher.addObject(17, Byte.valueOf((byte)0)); 196 this.dataWatcher.addObject(18, Integer.valueOf(0)); 197 } 198 199 @SideOnly(Side.CLIENT) 200 201 /** 202 * returns the ItemStack containing the itemInUse 203 */ 204 public ItemStack getItemInUse() 205 { 206 return this.itemInUse; 207 } 208 209 @SideOnly(Side.CLIENT) 210 211 /** 212 * Returns the item in use count 213 */ 214 public int getItemInUseCount() 215 { 216 return this.itemInUseCount; 217 } 218 219 /** 220 * Checks if the entity is currently using an item (e.g., bow, food, sword) by holding down the useItemButton 221 */ 222 public boolean isUsingItem() 223 { 224 return this.itemInUse != null; 225 } 226 227 @SideOnly(Side.CLIENT) 228 229 /** 230 * gets the duration for how long the current itemInUse has been in use 231 */ 232 public int getItemInUseDuration() 233 { 234 return this.isUsingItem() ? this.itemInUse.getMaxItemUseDuration() - this.itemInUseCount : 0; 235 } 236 237 public void stopUsingItem() 238 { 239 if (this.itemInUse != null) 240 { 241 this.itemInUse.onPlayerStoppedUsing(this.worldObj, this, this.itemInUseCount); 242 } 243 244 this.clearItemInUse(); 245 } 246 247 public void clearItemInUse() 248 { 249 this.itemInUse = null; 250 this.itemInUseCount = 0; 251 252 if (!this.worldObj.isRemote) 253 { 254 this.setEating(false); 255 } 256 } 257 258 public boolean isBlocking() 259 { 260 return this.isUsingItem() && Item.itemsList[this.itemInUse.itemID].getItemUseAction(this.itemInUse) == EnumAction.block; 261 } 262 263 /** 264 * Called to update the entity's position/logic. 265 */ 266 public void onUpdate() 267 { 268 FMLCommonHandler.instance().onPlayerPreTick(this); 269 if (this.itemInUse != null) 270 { 271 ItemStack var1 = this.inventory.getCurrentItem(); 272 273 if (var1 == this.itemInUse) 274 { 275 itemInUse.getItem().onUsingItemTick(itemInUse, this, itemInUseCount); 276 if (this.itemInUseCount <= 25 && this.itemInUseCount % 4 == 0) 277 { 278 this.updateItemUse(var1, 5); 279 } 280 281 if (--this.itemInUseCount == 0 && !this.worldObj.isRemote) 282 { 283 this.onItemUseFinish(); 284 } 285 } 286 else 287 { 288 this.clearItemInUse(); 289 } 290 } 291 292 if (this.xpCooldown > 0) 293 { 294 --this.xpCooldown; 295 } 296 297 if (this.isPlayerSleeping()) 298 { 299 ++this.sleepTimer; 300 301 if (this.sleepTimer > 100) 302 { 303 this.sleepTimer = 100; 304 } 305 306 if (!this.worldObj.isRemote) 307 { 308 if (!this.isInBed()) 309 { 310 this.wakeUpPlayer(true, true, false); 311 } 312 else if (this.worldObj.isDaytime()) 313 { 314 this.wakeUpPlayer(false, true, true); 315 } 316 } 317 } 318 else if (this.sleepTimer > 0) 319 { 320 ++this.sleepTimer; 321 322 if (this.sleepTimer >= 110) 323 { 324 this.sleepTimer = 0; 325 } 326 } 327 328 super.onUpdate(); 329 330 if (!this.worldObj.isRemote && this.openContainer != null && !this.openContainer.canInteractWith(this)) 331 { 332 this.closeScreen(); 333 this.openContainer = this.inventoryContainer; 334 } 335 336 if (this.isBurning() && this.capabilities.disableDamage) 337 { 338 this.extinguish(); 339 } 340 341 this.field_71091_bM = this.field_71094_bP; 342 this.field_71096_bN = this.field_71095_bQ; 343 this.field_71097_bO = this.field_71085_bR; 344 double var9 = this.posX - this.field_71094_bP; 345 double var3 = this.posY - this.field_71095_bQ; 346 double var5 = this.posZ - this.field_71085_bR; 347 double var7 = 10.0D; 348 349 if (var9 > var7) 350 { 351 this.field_71091_bM = this.field_71094_bP = this.posX; 352 } 353 354 if (var5 > var7) 355 { 356 this.field_71097_bO = this.field_71085_bR = this.posZ; 357 } 358 359 if (var3 > var7) 360 { 361 this.field_71096_bN = this.field_71095_bQ = this.posY; 362 } 363 364 if (var9 < -var7) 365 { 366 this.field_71091_bM = this.field_71094_bP = this.posX; 367 } 368 369 if (var5 < -var7) 370 { 371 this.field_71097_bO = this.field_71085_bR = this.posZ; 372 } 373 374 if (var3 < -var7) 375 { 376 this.field_71096_bN = this.field_71095_bQ = this.posY; 377 } 378 379 this.field_71094_bP += var9 * 0.25D; 380 this.field_71085_bR += var5 * 0.25D; 381 this.field_71095_bQ += var3 * 0.25D; 382 this.addStat(StatList.minutesPlayedStat, 1); 383 384 if (this.ridingEntity == null) 385 { 386 this.startMinecartRidingCoordinate = null; 387 } 388 389 if (!this.worldObj.isRemote) 390 { 391 this.foodStats.onUpdate(this); 392 } 393 FMLCommonHandler.instance().onPlayerPostTick(this); 394 } 395 396 /** 397 * Return the amount of time this entity should stay in a portal before being transported. 398 */ 399 public int getMaxInPortalTime() 400 { 401 return this.capabilities.disableDamage ? 0 : 80; 402 } 403 404 /** 405 * Return the amount of cooldown before this entity can use a portal again. 406 */ 407 public int getPortalCooldown() 408 { 409 return 10; 410 } 411 412 protected void func_85030_a(String par1Str, float par2, float par3) 413 { 414 this.worldObj.func_85173_a(this, par1Str, par2, par3); 415 } 416 417 /** 418 * Plays sounds and makes particles for item in use state 419 */ 420 protected void updateItemUse(ItemStack par1ItemStack, int par2) 421 { 422 if (par1ItemStack.getItemUseAction() == EnumAction.drink) 423 { 424 this.func_85030_a("random.drink", 0.5F, this.worldObj.rand.nextFloat() * 0.1F + 0.9F); 425 } 426 427 if (par1ItemStack.getItemUseAction() == EnumAction.eat) 428 { 429 for (int var3 = 0; var3 < par2; ++var3) 430 { 431 Vec3 var4 = this.worldObj.getWorldVec3Pool().getVecFromPool(((double)this.rand.nextFloat() - 0.5D) * 0.1D, Math.random() * 0.1D + 0.1D, 0.0D); 432 var4.rotateAroundX(-this.rotationPitch * (float)Math.PI / 180.0F); 433 var4.rotateAroundY(-this.rotationYaw * (float)Math.PI / 180.0F); 434 Vec3 var5 = this.worldObj.getWorldVec3Pool().getVecFromPool(((double)this.rand.nextFloat() - 0.5D) * 0.3D, (double)(-this.rand.nextFloat()) * 0.6D - 0.3D, 0.6D); 435 var5.rotateAroundX(-this.rotationPitch * (float)Math.PI / 180.0F); 436 var5.rotateAroundY(-this.rotationYaw * (float)Math.PI / 180.0F); 437 var5 = var5.addVector(this.posX, this.posY + (double)this.getEyeHeight(), this.posZ); 438 this.worldObj.spawnParticle("iconcrack_" + par1ItemStack.getItem().shiftedIndex, var5.xCoord, var5.yCoord, var5.zCoord, var4.xCoord, var4.yCoord + 0.05D, var4.zCoord); 439 } 440 441 this.func_85030_a("random.eat", 0.5F + 0.5F * (float)this.rand.nextInt(2), (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F); 442 } 443 } 444 445 /** 446 * Used for when item use count runs out, ie: eating completed 447 */ 448 protected void onItemUseFinish() 449 { 450 if (this.itemInUse != null) 451 { 452 this.updateItemUse(this.itemInUse, 16); 453 int var1 = this.itemInUse.stackSize; 454 ItemStack var2 = this.itemInUse.onFoodEaten(this.worldObj, this); 455 456 if (var2 != this.itemInUse || var2 != null && var2.stackSize != var1) 457 { 458 this.inventory.mainInventory[this.inventory.currentItem] = var2; 459 460 if (var2.stackSize == 0) 461 { 462 this.inventory.mainInventory[this.inventory.currentItem] = null; 463 } 464 } 465 466 this.clearItemInUse(); 467 } 468 } 469 470 @SideOnly(Side.CLIENT) 471 public void handleHealthUpdate(byte par1) 472 { 473 if (par1 == 9) 474 { 475 this.onItemUseFinish(); 476 } 477 else 478 { 479 super.handleHealthUpdate(par1); 480 } 481 } 482 483 /** 484 * Dead and sleeping entities cannot move 485 */ 486 protected boolean isMovementBlocked() 487 { 488 return this.getHealth() <= 0 || this.isPlayerSleeping(); 489 } 490 491 /** 492 * sets current screen to null (used on escape buttons of GUIs) 493 */ 494 public void closeScreen() 495 { 496 this.openContainer = this.inventoryContainer; 497 } 498 499 /** 500 * Handles updating while being ridden by an entity 501 */ 502 public void updateRidden() 503 { 504 double var1 = this.posX; 505 double var3 = this.posY; 506 double var5 = this.posZ; 507 float var7 = this.rotationYaw; 508 float var8 = this.rotationPitch; 509 super.updateRidden(); 510 this.prevCameraYaw = this.cameraYaw; 511 this.cameraYaw = 0.0F; 512 this.addMountedMovementStat(this.posX - var1, this.posY - var3, this.posZ - var5); 513 514 if (this.ridingEntity instanceof EntityLiving && ((EntityLiving)ridingEntity).shouldRiderFaceForward(this)) 515 { 516 this.rotationPitch = var8; 517 this.rotationYaw = var7; 518 this.renderYawOffset = ((EntityLiving)this.ridingEntity).renderYawOffset; 519 } 520 } 521 522 @SideOnly(Side.CLIENT) 523 524 /** 525 * Keeps moving the entity up so it isn't colliding with blocks and other requirements for this entity to be spawned 526 * (only actually used on players though its also on Entity) 527 */ 528 public void preparePlayerToSpawn() 529 { 530 this.yOffset = 1.62F; 531 this.setSize(0.6F, 1.8F); 532 super.preparePlayerToSpawn(); 533 this.setEntityHealth(this.getMaxHealth()); 534 this.deathTime = 0; 535 } 536 537 protected void updateEntityActionState() 538 { 539 this.updateArmSwingProgress(); 540 } 541 542 /** 543 * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons 544 * use this to react to sunlight and start to burn. 545 */ 546 public void onLivingUpdate() 547 { 548 if (this.flyToggleTimer > 0) 549 { 550 --this.flyToggleTimer; 551 } 552 553 if (this.worldObj.difficultySetting == 0 && this.getHealth() < this.getMaxHealth() && this.ticksExisted % 20 * 12 == 0) 554 { 555 this.heal(1); 556 } 557 558 this.inventory.decrementAnimations(); 559 this.prevCameraYaw = this.cameraYaw; 560 super.onLivingUpdate(); 561 this.landMovementFactor = this.capabilities.getWalkSpeed(); 562 this.jumpMovementFactor = this.speedInAir; 563 564 if (this.isSprinting()) 565 { 566 this.landMovementFactor = (float)((double)this.landMovementFactor + (double)this.capabilities.getWalkSpeed() * 0.3D); 567 this.jumpMovementFactor = (float)((double)this.jumpMovementFactor + (double)this.speedInAir * 0.3D); 568 } 569 570 float var1 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); 571 float var2 = (float)Math.atan(-this.motionY * 0.20000000298023224D) * 15.0F; 572 573 if (var1 > 0.1F) 574 { 575 var1 = 0.1F; 576 } 577 578 if (!this.onGround || this.getHealth() <= 0) 579 { 580 var1 = 0.0F; 581 } 582 583 if (this.onGround || this.getHealth() <= 0) 584 { 585 var2 = 0.0F; 586 } 587 588 this.cameraYaw += (var1 - this.cameraYaw) * 0.4F; 589 this.cameraPitch += (var2 - this.cameraPitch) * 0.8F; 590 591 if (this.getHealth() > 0) 592 { 593 List var3 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(1.0D, 0.5D, 1.0D)); 594 595 if (var3 != null) 596 { 597 for (int var4 = 0; var4 < var3.size(); ++var4) 598 { 599 Entity var5 = (Entity)var3.get(var4); 600 601 if (!var5.isDead) 602 { 603 this.collideWithPlayer(var5); 604 } 605 } 606 } 607 } 608 } 609 610 private void collideWithPlayer(Entity par1Entity) 611 { 612 par1Entity.onCollideWithPlayer(this); 613 } 614 615 public int getScore() 616 { 617 return this.dataWatcher.getWatchableObjectInt(18); 618 } 619 620 public void func_85040_s(int par1) 621 { 622 this.dataWatcher.updateObject(18, Integer.valueOf(par1)); 623 } 624 625 public void func_85039_t(int par1) 626 { 627 int var2 = this.getScore(); 628 this.dataWatcher.updateObject(18, Integer.valueOf(var2 + par1)); 629 } 630 631 /** 632 * Called when the mob's health reaches 0. 633 */ 634 public void onDeath(DamageSource par1DamageSource) 635 { 636 super.onDeath(par1DamageSource); 637 this.setSize(0.2F, 0.2F); 638 this.setPosition(this.posX, this.posY, this.posZ); 639 this.motionY = 0.10000000149011612D; 640 641 captureDrops = true; 642 capturedDrops.clear(); 643 644 if (this.username.equals("Notch")) 645 { 646 this.dropPlayerItemWithRandomChoice(new ItemStack(Item.appleRed, 1), true); 647 } 648 649 if (!this.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory")) 650 { 651 this.inventory.dropAllItems(); 652 } 653 654 captureDrops = false; 655 656 if (!worldObj.isRemote) 657 { 658 PlayerDropsEvent event = new PlayerDropsEvent(this, par1DamageSource, capturedDrops, recentlyHit > 0); 659 if (!MinecraftForge.EVENT_BUS.post(event)) 660 { 661 for (EntityItem item : capturedDrops) 662 { 663 joinEntityItemWithWorld(item); 664 } 665 } 666 } 667 668 if (par1DamageSource != null) 669 { 670 this.motionX = (double)(-MathHelper.cos((this.attackedAtYaw + this.rotationYaw) * (float)Math.PI / 180.0F) * 0.1F); 671 this.motionZ = (double)(-MathHelper.sin((this.attackedAtYaw + this.rotationYaw) * (float)Math.PI / 180.0F) * 0.1F); 672 } 673 else 674 { 675 this.motionX = this.motionZ = 0.0D; 676 } 677 678 this.yOffset = 0.1F; 679 this.addStat(StatList.deathsStat, 1); 680 } 681 682 /** 683 * Adds a value to the player score. Currently not actually used and the entity passed in does nothing. Args: 684 * entity, scoreToAdd 685 */ 686 public void addToPlayerScore(Entity par1Entity, int par2) 687 { 688 this.func_85039_t(par2); 689 690 if (par1Entity instanceof EntityPlayer) 691 { 692 this.addStat(StatList.playerKillsStat, 1); 693 } 694 else 695 { 696 this.addStat(StatList.mobKillsStat, 1); 697 } 698 } 699 700 /** 701 * Called when player presses the drop item key 702 */ 703 public EntityItem dropOneItem() 704 { 705 ItemStack stack = inventory.getCurrentItem(); 706 if (stack == null) 707 { 708 return null; 709 } 710 if (stack.getItem().onDroppedByPlayer(stack, this)) 711 { 712 return ForgeHooks.onPlayerTossEvent(this, inventory.decrStackSize(inventory.currentItem, 1)); 713 } 714 return null; 715 } 716 717 /** 718 * Args: itemstack - called when player drops an item stack that's not in his inventory (like items still placed in 719 * a workbench while the workbench'es GUI gets closed) 720 */ 721 public EntityItem dropPlayerItem(ItemStack par1ItemStack) 722 { 723 return ForgeHooks.onPlayerTossEvent(this, par1ItemStack); 724 } 725 726 /** 727 * Args: itemstack, flag 728 */ 729 public EntityItem dropPlayerItemWithRandomChoice(ItemStack par1ItemStack, boolean par2) 730 { 731 if (par1ItemStack == null) 732 { 733 return null; 734 } 735 else 736 { 737 EntityItem var3 = new EntityItem(this.worldObj, this.posX, this.posY - 0.30000001192092896D + (double)this.getEyeHeight(), this.posZ, par1ItemStack); 738 var3.delayBeforeCanPickup = 40; 739 float var4 = 0.1F; 740 float var5; 741 742 if (par2) 743 { 744 var5 = this.rand.nextFloat() * 0.5F; 745 float var6 = this.rand.nextFloat() * (float)Math.PI * 2.0F; 746 var3.motionX = (double)(-MathHelper.sin(var6) * var5); 747 var3.motionZ = (double)(MathHelper.cos(var6) * var5); 748 var3.motionY = 0.20000000298023224D; 749 } 750 else 751 { 752 var4 = 0.3F; 753 var3.motionX = (double)(-MathHelper.sin(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float)Math.PI) * var4); 754 var3.motionZ = (double)(MathHelper.cos(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float)Math.PI) * var4); 755 var3.motionY = (double)(-MathHelper.sin(this.rotationPitch / 180.0F * (float)Math.PI) * var4 + 0.1F); 756 var4 = 0.02F; 757 var5 = this.rand.nextFloat() * (float)Math.PI * 2.0F; 758 var4 *= this.rand.nextFloat(); 759 var3.motionX += Math.cos((double)var5) * (double)var4; 760 var3.motionY += (double)((this.rand.nextFloat() - this.rand.nextFloat()) * 0.1F); 761 var3.motionZ += Math.sin((double)var5) * (double)var4; 762 } 763 764 this.joinEntityItemWithWorld(var3); 765 this.addStat(StatList.dropStat, 1); 766 return var3; 767 } 768 } 769 770 /** 771 * Joins the passed in entity item with the world. Args: entityItem 772 */ 773 public void joinEntityItemWithWorld(EntityItem par1EntityItem) 774 { 775 if (captureDrops) 776 { 777 capturedDrops.add(par1EntityItem); 778 } 779 else 780 { 781 this.worldObj.spawnEntityInWorld(par1EntityItem); 782 } 783 } 784 785 /** 786 * Returns how strong the player is against the specified block at this moment 787 * Deprecated in favor of the more sensitive version 788 */ 789 @Deprecated 790 public float getCurrentPlayerStrVsBlock(Block par1Block) 791 { 792 return getCurrentPlayerStrVsBlock(par1Block, 0); 793 } 794 795 public float getCurrentPlayerStrVsBlock(Block par1Block, int meta) 796 { 797 ItemStack stack = inventory.getCurrentItem(); 798 float var2 = (stack == null ? 1.0F : stack.getItem().getStrVsBlock(stack, par1Block, meta)); 799 int var3 = EnchantmentHelper.getEfficiencyModifier(this); 800 801 if (var3 > 0 && ForgeHooks.canHarvestBlock(par1Block, this, meta)) 802 { 803 var2 += (float)(var3 * var3 + 1); 804 } 805 806 if (this.isPotionActive(Potion.digSpeed)) 807 { 808 var2 *= 1.0F + (float)(this.getActivePotionEffect(Potion.digSpeed).getAmplifier() + 1) * 0.2F; 809 } 810 811 if (this.isPotionActive(Potion.digSlowdown)) 812 { 813 var2 *= 1.0F - (float)(this.getActivePotionEffect(Potion.digSlowdown).getAmplifier() + 1) * 0.2F; 814 } 815 816 if (this.isInsideOfMaterial(Material.water) && !EnchantmentHelper.getAquaAffinityModifier(this)) 817 { 818 var2 /= 5.0F; 819 } 820 821 if (!this.onGround) 822 { 823 var2 /= 5.0F; 824 } 825 826 var2 = ForgeEventFactory.getBreakSpeed(this, par1Block, meta, var2); 827 return (var2 < 0 ? 0 : var2); 828 } 829 830 /** 831 * Checks if the player has the ability to harvest a block (checks current inventory item for a tool if necessary) 832 */ 833 public boolean canHarvestBlock(Block par1Block) 834 { 835 return ForgeEventFactory.doPlayerHarvestCheck(this, par1Block, inventory.canHarvestBlock(par1Block)); 836 } 837 838 /** 839 * (abstract) Protected helper method to read subclass entity data from NBT. 840 */ 841 public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) 842 { 843 super.readEntityFromNBT(par1NBTTagCompound); 844 NBTTagList var2 = par1NBTTagCompound.getTagList("Inventory"); 845 this.inventory.readFromNBT(var2); 846 this.sleeping = par1NBTTagCompound.getBoolean("Sleeping"); 847 this.sleepTimer = par1NBTTagCompound.getShort("SleepTimer"); 848 this.experience = par1NBTTagCompound.getFloat("XpP"); 849 this.experienceLevel = par1NBTTagCompound.getInteger("XpLevel"); 850 this.experienceTotal = par1NBTTagCompound.getInteger("XpTotal"); 851 this.func_85040_s(par1NBTTagCompound.getInteger("Score")); 852 853 if (this.sleeping) 854 { 855 this.playerLocation = new ChunkCoordinates(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)); 856 this.wakeUpPlayer(true, true, false); 857 } 858 859 if (par1NBTTagCompound.hasKey("SpawnX") && par1NBTTagCompound.hasKey("SpawnY") && par1NBTTagCompound.hasKey("SpawnZ")) 860 { 861 this.spawnChunk = new ChunkCoordinates(par1NBTTagCompound.getInteger("SpawnX"), par1NBTTagCompound.getInteger("SpawnY"), par1NBTTagCompound.getInteger("SpawnZ")); 862 this.spawnForced = par1NBTTagCompound.getBoolean("SpawnForced"); 863 } 864 865 this.foodStats.readNBT(par1NBTTagCompound); 866 this.capabilities.readCapabilitiesFromNBT(par1NBTTagCompound); 867 868 if (par1NBTTagCompound.hasKey("EnderItems")) 869 { 870 NBTTagList var3 = par1NBTTagCompound.getTagList("EnderItems"); 871 this.theInventoryEnderChest.loadInventoryFromNBT(var3); 872 } 873 } 874 875 /** 876 * (abstract) Protected helper method to write subclass entity data to NBT. 877 */ 878 public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) 879 { 880 super.writeEntityToNBT(par1NBTTagCompound); 881 par1NBTTagCompound.setTag("Inventory", this.inventory.writeToNBT(new NBTTagList())); 882 par1NBTTagCompound.setBoolean("Sleeping", this.sleeping); 883 par1NBTTagCompound.setShort("SleepTimer", (short)this.sleepTimer); 884 par1NBTTagCompound.setFloat("XpP", this.experience); 885 par1NBTTagCompound.setInteger("XpLevel", this.experienceLevel); 886 par1NBTTagCompound.setInteger("XpTotal", this.experienceTotal); 887 par1NBTTagCompound.setInteger("Score", this.getScore()); 888 889 if (this.spawnChunk != null) 890 { 891 par1NBTTagCompound.setInteger("SpawnX", this.spawnChunk.posX); 892 par1NBTTagCompound.setInteger("SpawnY", this.spawnChunk.posY); 893 par1NBTTagCompound.setInteger("SpawnZ", this.spawnChunk.posZ); 894 par1NBTTagCompound.setBoolean("SpawnForced", this.spawnForced); 895 } 896 897 this.foodStats.writeNBT(par1NBTTagCompound); 898 this.capabilities.writeCapabilitiesToNBT(par1NBTTagCompound); 899 par1NBTTagCompound.setTag("EnderItems", this.theInventoryEnderChest.saveInventoryToNBT()); 900 } 901 902 /** 903 * Displays the GUI for interacting with a chest inventory. Args: chestInventory 904 */ 905 public void displayGUIChest(IInventory par1IInventory) {} 906 907 public void displayGUIEnchantment(int par1, int par2, int par3) {} 908 909 /** 910 * Displays the GUI for interacting with an anvil. 911 */ 912 public void displayGUIAnvil(int par1, int par2, int par3) {} 913 914 /** 915 * Displays the crafting GUI for a workbench. 916 */ 917 public void displayGUIWorkbench(int par1, int par2, int par3) {} 918 919 public float getEyeHeight() 920 { 921 return 0.12F; 922 } 923 924 /** 925 * sets the players height back to normal after doing things like sleeping and dieing 926 */ 927 protected void resetHeight() 928 { 929 this.yOffset = 1.62F; 930 } 931 932 /** 933 * Called when the entity is attacked. 934 */ 935 public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) 936 { 937 if (this.func_85032_ar()) 938 { 939 return false; 940 } 941 else if (this.capabilities.disableDamage && !par1DamageSource.canHarmInCreative()) 942 { 943 return false; 944 } 945 else 946 { 947 this.entityAge = 0; 948 949 if (this.getHealth() <= 0) 950 { 951 return false; 952 } 953 else 954 { 955 if (this.isPlayerSleeping() && !this.worldObj.isRemote) 956 { 957 this.wakeUpPlayer(true, true, false); 958 } 959 960 if (par1DamageSource.func_76350_n()) 961 { 962 if (this.worldObj.difficultySetting == 0) 963 { 964 par2 = 0; 965 } 966 967 if (this.worldObj.difficultySetting == 1) 968 { 969 par2 = par2 / 2 + 1; 970 } 971 972 if (this.worldObj.difficultySetting == 3) 973 { 974 par2 = par2 * 3 / 2; 975 } 976 } 977 978 if (par2 == 0) 979 { 980 return false; 981 } 982 else 983 { 984 Entity var3 = par1DamageSource.getEntity(); 985 986 if (var3 instanceof EntityArrow && ((EntityArrow)var3).shootingEntity != null) 987 { 988 var3 = ((EntityArrow)var3).shootingEntity; 989 } 990 991 if (var3 instanceof EntityLiving) 992 { 993 this.alertWolves((EntityLiving)var3, false); 994 } 995 996 this.addStat(StatList.damageTakenStat, par2); 997 return super.attackEntityFrom(par1DamageSource, par2); 998 } 999 } 1000 } 1001 } 1002 1003 /** 1004 * Reduces damage, depending on potions 1005 */ 1006 protected int applyPotionDamageCalculations(DamageSource par1DamageSource, int par2) 1007 { 1008 int var3 = super.applyPotionDamageCalculations(par1DamageSource, par2); 1009 1010 if (var3 <= 0) 1011 { 1012 return 0; 1013 } 1014 else 1015 { 1016 int var4 = EnchantmentHelper.getEnchantmentModifierDamage(this.inventory.armorInventory, par1DamageSource); 1017 1018 if (var4 > 20) 1019 { 1020 var4 = 20; 1021 } 1022 1023 if (var4 > 0 && var4 <= 20) 1024 { 1025 int var5 = 25 - var4; 1026 int var6 = var3 * var5 + this.carryoverDamage; 1027 var3 = var6 / 25; 1028 this.carryoverDamage = var6 % 25; 1029 } 1030 1031 return var3; 1032 } 1033 } 1034 1035 /** 1036 * returns if pvp is enabled or not 1037 */ 1038 protected boolean isPVPEnabled() 1039 { 1040 return false; 1041 } 1042 1043 /** 1044 * Called when the player attack or gets attacked, it's alert all wolves in the area that are owned by the player to 1045 * join the attack or defend the player. 1046 */ 1047 protected void alertWolves(EntityLiving par1EntityLiving, boolean par2) 1048 { 1049 if (!(par1EntityLiving instanceof EntityCreeper) && !(par1EntityLiving instanceof EntityGhast)) 1050 { 1051 if (par1EntityLiving instanceof EntityWolf) 1052 { 1053 EntityWolf var3 = (EntityWolf)par1EntityLiving; 1054 1055 if (var3.isTamed() && this.username.equals(var3.getOwnerName())) 1056 { 1057 return; 1058 } 1059 } 1060 1061 if (!(par1EntityLiving instanceof EntityPlayer) || this.isPVPEnabled()) 1062 { 1063 List var6 = this.worldObj.getEntitiesWithinAABB(EntityWolf.class, AxisAlignedBB.getAABBPool().addOrModifyAABBInPool(this.posX, this.posY, this.posZ, this.posX + 1.0D, this.posY + 1.0D, this.posZ + 1.0D).expand(16.0D, 4.0D, 16.0D)); 1064 Iterator var4 = var6.iterator(); 1065 1066 while (var4.hasNext()) 1067 { 1068 EntityWolf var5 = (EntityWolf)var4.next(); 1069 1070 if (var5.isTamed() && var5.getEntityToAttack() == null && this.username.equals(var5.getOwnerName()) && (!par2 || !var5.isSitting())) 1071 { 1072 var5.setSitting(false); 1073 var5.setTarget(par1EntityLiving); 1074 } 1075 } 1076 } 1077 } 1078 } 1079 1080 protected void damageArmor(int par1) 1081 { 1082 this.inventory.damageArmor(par1); 1083 } 1084 1085 /** 1086 * Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue 1087 */ 1088 public int getTotalArmorValue() 1089 { 1090 return this.inventory.getTotalArmorValue(); 1091 } 1092 1093 public float func_82243_bO() 1094 { 1095 int var1 = 0; 1096 ItemStack[] var2 = this.inventory.armorInventory; 1097 int var3 = var2.length; 1098 1099 for (int var4 = 0; var4 < var3; ++var4) 1100 { 1101 ItemStack var5 = var2[var4]; 1102 1103 if (var5 != null) 1104 { 1105 ++var1; 1106 } 1107 } 1108 1109 return (float)var1 / (float)this.inventory.armorInventory.length; 1110 } 1111 1112 /** 1113 * Deals damage to the entity. If its a EntityPlayer then will take damage from the armor first and then health 1114 * second with the reduced value. Args: damageAmount 1115 */ 1116 protected void damageEntity(DamageSource par1DamageSource, int par2) 1117 { 1118 if (!this.func_85032_ar()) 1119 { 1120 par2 = ForgeHooks.onLivingHurt(this, par1DamageSource, par2); 1121 if (par2 <= 0) 1122 { 1123 return; 1124 } 1125 1126 if (!par1DamageSource.isUnblockable() && this.isBlocking()) 1127 { 1128 par2 = 1 + par2 >> 1; 1129 } 1130 1131 par2 = ArmorProperties.ApplyArmor(this, inventory.armorInventory, par1DamageSource, par2); 1132 if (par2 <= 0) 1133 { 1134 return; 1135 } 1136 par2 = this.applyPotionDamageCalculations(par1DamageSource, par2); 1137 this.addExhaustion(par1DamageSource.getHungerDamage()); 1138 this.health -= par2; 1139 } 1140 } 1141 1142 /** 1143 * Displays the furnace GUI for the passed in furnace entity. Args: tileEntityFurnace 1144 */ 1145 public void displayGUIFurnace(TileEntityFurnace par1TileEntityFurnace) {} 1146 1147 /** 1148 * Displays the dipsenser GUI for the passed in dispenser entity. Args: TileEntityDispenser 1149 */ 1150 public void displayGUIDispenser(TileEntityDispenser par1TileEntityDispenser) {} 1151 1152 /** 1153 * Displays the GUI for editing a sign. Args: tileEntitySign 1154 */ 1155 public void displayGUIEditSign(TileEntity par1TileEntity) {} 1156 1157 /** 1158 * Displays the GUI for interacting with a brewing stand. 1159 */ 1160 public void displayGUIBrewingStand(TileEntityBrewingStand par1TileEntityBrewingStand) {} 1161 1162 /** 1163 * Displays the GUI for interacting with a beacon. 1164 */ 1165 public void displayGUIBeacon(TileEntityBeacon par1TileEntityBeacon) {} 1166 1167 public void displayGUIMerchant(IMerchant par1IMerchant) {} 1168 1169 /** 1170 * Displays the GUI for interacting with a book. 1171 */ 1172 public void displayGUIBook(ItemStack par1ItemStack) {} 1173 1174 public boolean interactWith(Entity par1Entity) 1175 { 1176 if (MinecraftForge.EVENT_BUS.post(new EntityInteractEvent(this, par1Entity))) 1177 { 1178 return false; 1179 } 1180 if (par1Entity.interact(this)) 1181 { 1182 return true; 1183 } 1184 else 1185 { 1186 ItemStack var2 = this.getCurrentEquippedItem(); 1187 1188 if (var2 != null && par1Entity instanceof EntityLiving) 1189 { 1190 if (this.capabilities.isCreativeMode) 1191 { 1192 var2 = var2.copy(); 1193 } 1194 1195 if (var2.interactWith((EntityLiving)par1Entity)) 1196 { 1197 if (var2.stackSize <= 0 && !this.capabilities.isCreativeMode) 1198 { 1199 this.destroyCurrentEquippedItem(); 1200 } 1201 1202 return true; 1203 } 1204 } 1205 1206 return false; 1207 } 1208 } 1209 1210 /** 1211 * Returns the currently being used item by the player. 1212 */ 1213 public ItemStack getCurrentEquippedItem() 1214 { 1215 return this.inventory.getCurrentItem(); 1216 } 1217 1218 /** 1219 * Destroys the currently equipped item from the player's inventory. 1220 */ 1221 public void destroyCurrentEquippedItem() 1222 { 1223 ItemStack orig = getCurrentEquippedItem(); 1224 this.inventory.setInventorySlotContents(this.inventory.currentItem, (ItemStack)null); 1225 MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(this, orig)); 1226 } 1227 1228 /** 1229 * Returns the Y Offset of this entity. 1230 */ 1231 public double getYOffset() 1232 { 1233 return (double)(this.yOffset - 0.5F); 1234 } 1235 1236 /** 1237 * Attacks for the player the targeted entity with the currently equipped item. The equipped item has hitEntity 1238 * called on it. Args: targetEntity 1239 */ 1240 public void attackTargetEntityWithCurrentItem(Entity par1Entity) 1241 { 1242 if (MinecraftForge.EVENT_BUS.post(new AttackEntityEvent(this, par1Entity))) 1243 { 1244 return; 1245 } 1246 ItemStack stack = getCurrentEquippedItem(); 1247 if (stack != null && stack.getItem().onLeftClickEntity(stack, this, par1Entity)) 1248 { 1249 return; 1250 } 1251 if (par1Entity.canAttackWithItem()) 1252 { 1253 if (!par1Entity.func_85031_j(this)) 1254 { 1255 int var2 = this.inventory.getDamageVsEntity(par1Entity); 1256 1257 if (this.isPotionActive(Potion.damageBoost)) 1258 { 1259 var2 += 3 << this.getActivePotionEffect(Potion.damageBoost).getAmplifier(); 1260 } 1261 1262 if (this.isPotionActive(Potion.weakness)) 1263 { 1264 var2 -= 2 << this.getActivePotionEffect(Potion.weakness).getAmplifier(); 1265 } 1266 1267 int var3 = 0; 1268 int var4 = 0; 1269 1270 if (par1Entity instanceof EntityLiving) 1271 { 1272 var4 = EnchantmentHelper.getEnchantmentModifierLiving(this, (EntityLiving)par1Entity); 1273 var3 += EnchantmentHelper.getKnockbackModifier(this, (EntityLiving)par1Entity); 1274 } 1275 1276 if (this.isSprinting()) 1277 { 1278 ++var3; 1279 } 1280 1281 if (var2 > 0 || var4 > 0) 1282 { 1283 boolean var5 = this.fallDistance > 0.0F && !this.onGround && !this.isOnLadder() && !this.isInWater() && !this.isPotionActive(Potion.blindness) && this.ridingEntity == null && par1Entity instanceof EntityLiving; 1284 1285 if (var5) 1286 { 1287 var2 += this.rand.nextInt(var2 / 2 + 2); 1288 } 1289 1290 var2 += var4; 1291 boolean var6 = false; 1292 int var7 = EnchantmentHelper.func_90036_a(this); 1293 1294 if (par1Entity instanceof EntityLiving && var7 > 0 && !par1Entity.isBurning()) 1295 { 1296 var6 = true; 1297 par1Entity.setFire(1); 1298 } 1299 1300 boolean var8 = par1Entity.attackEntityFrom(DamageSource.causePlayerDamage(this), var2); 1301 1302 if (var8) 1303 { 1304 if (var3 > 0) 1305 { 1306 par1Entity.addVelocity((double)(-MathHelper.sin(this.rotationYaw * (float)Math.PI / 180.0F) * (float)var3 * 0.5F), 0.1D, (double)(MathHelper.cos(this.rotationYaw * (float)Math.PI / 180.0F) * (float)var3 * 0.5F)); 1307 this.motionX *= 0.6D; 1308 this.motionZ *= 0.6D; 1309 this.setSprinting(false); 1310 } 1311 1312 if (var5) 1313 { 1314 this.onCriticalHit(par1Entity); 1315 } 1316 1317 if (var4 > 0) 1318 { 1319 this.onEnchantmentCritical(par1Entity); 1320 } 1321 1322 if (var2 >= 18) 1323 { 1324 this.triggerAchievement(AchievementList.overkill); 1325 } 1326 1327 this.setLastAttackingEntity(par1Entity); 1328 } 1329 1330 ItemStack var9 = this.getCurrentEquippedItem(); 1331 1332 if (var9 != null && par1Entity instanceof EntityLiving) 1333 { 1334 var9.hitEntity((EntityLiving)par1Entity, this); 1335 1336 if (var9.stackSize <= 0) 1337 { 1338 this.destroyCurrentEquippedItem(); 1339 } 1340 } 1341 1342 if (par1Entity instanceof EntityLiving) 1343 { 1344 if (par1Entity.isEntityAlive()) 1345 { 1346 this.alertWolves((EntityLiving)par1Entity, true); 1347 } 1348 1349 this.addStat(StatList.damageDealtStat, var2); 1350 1351 if (var7 > 0 && var8) 1352 { 1353 par1Entity.setFire(var7 * 4); 1354 } 1355 else if (var6) 1356 { 1357 par1Entity.extinguish(); 1358 } 1359 } 1360 1361 this.addExhaustion(0.3F); 1362 } 1363 } 1364 } 1365 } 1366 1367 /** 1368 * Called when the player performs a critical hit on the Entity. Args: entity that was hit critically 1369 */ 1370 public void onCriticalHit(Entity par1Entity) {} 1371 1372 public void onEnchantmentCritical(Entity par1Entity) {} 1373 1374 @SideOnly(Side.CLIENT) 1375 public void respawnPlayer() {} 1376 1377 /** 1378 * Will get destroyed next tick. 1379 */ 1380 public void setDead() 1381 { 1382 super.setDead(); 1383 this.inventoryContainer.onCraftGuiClosed(this); 1384 1385 if (this.openContainer != null) 1386 { 1387 this.openContainer.onCraftGuiClosed(this); 1388 } 1389 } 1390 1391 /** 1392 * Checks if this entity is inside of an opaque block 1393 */ 1394 public boolean isEntityInsideOpaqueBlock() 1395 { 1396 return !this.sleeping && super.isEntityInsideOpaqueBlock(); 1397 } 1398 1399 public boolean func_71066_bF() 1400 { 1401 return false; 1402 } 1403 1404 /** 1405 * Attempts to have the player sleep in a bed at the specified location. 1406 */ 1407 public EnumStatus sleepInBedAt(int par1, int par2, int par3) 1408 { 1409 PlayerSleepInBedEvent event = new PlayerSleepInBedEvent(this, par1, par2, par3); 1410 MinecraftForge.EVENT_BUS.post(event); 1411 if (event.result != null) 1412 { 1413 return event.result; 1414 } 1415 if (!this.worldObj.isRemote) 1416 { 1417 if (this.isPlayerSleeping() || !this.isEntityAlive()) 1418 { 1419 return EnumStatus.OTHER_PROBLEM; 1420 } 1421 1422 if (!this.worldObj.provider.isSurfaceWorld()) 1423 { 1424 return EnumStatus.NOT_POSSIBLE_HERE; 1425 } 1426 1427 if (this.worldObj.isDaytime()) 1428 { 1429 return EnumStatus.NOT_POSSIBLE_NOW; 1430 } 1431 1432 if (Math.abs(this.posX - (double)par1) > 3.0D || Math.abs(this.posY - (double)par2) > 2.0D || Math.abs(this.posZ - (double)par3) > 3.0D) 1433 { 1434 return EnumStatus.TOO_FAR_AWAY; 1435 } 1436 1437 double var4 = 8.0D; 1438 double var6 = 5.0D; 1439 List var8 = this.worldObj.getEntitiesWithinAABB(EntityMob.class, AxisAlignedBB.getAABBPool().addOrModifyAABBInPool((double)par1 - var4, (double)par2 - var6, (double)par3 - var4, (double)par1 + var4, (double)par2 + var6, (double)par3 + var4)); 1440 1441 if (!var8.isEmpty()) 1442 { 1443 return EnumStatus.NOT_SAFE; 1444 } 1445 } 1446 1447 this.setSize(0.2F, 0.2F); 1448 this.yOffset = 0.2F; 1449 1450 if (this.worldObj.blockExists(par1, par2, par3)) 1451 { 1452 int var9 = this.worldObj.getBlockMetadata(par1, par2, par3); 1453 int var5 = BlockBed.getDirection(var9); 1454 Block block = Block.blocksList[worldObj.getBlockId(par1, par2, par3)]; 1455 if (block != null) 1456 { 1457 var5 = block.getBedDirection(worldObj, par1, par2, par3); 1458 } 1459 float var10 = 0.5F; 1460 float var7 = 0.5F; 1461 1462 switch (var5) 1463 { 1464 case 0: 1465 var7 = 0.9F; 1466 break; 1467 case 1: 1468 var10 = 0.1F; 1469 break; 1470 case 2: 1471 var7 = 0.1F; 1472 break; 1473 case 3: 1474 var10 = 0.9F; 1475 } 1476 1477 this.func_71013_b(var5); 1478 this.setPosition((double)((float)par1 + var10), (double)((float)par2 + 0.9375F), (double)((float)par3 + var7)); 1479 } 1480 else 1481 { 1482 this.setPosition((double)((float)par1 + 0.5F), (double)((float)par2 + 0.9375F), (double)((float)par3 + 0.5F)); 1483 } 1484 1485 this.sleeping = true; 1486 this.sleepTimer = 0; 1487 this.playerLocation = new ChunkCoordinates(par1, par2, par3); 1488 this.motionX = this.motionZ = this.motionY = 0.0D; 1489 1490 if (!this.worldObj.isRemote) 1491 { 1492 this.worldObj.updateAllPlayersSleepingFlag(); 1493 } 1494 1495 return EnumStatus.OK; 1496 } 1497 1498 private void func_71013_b(int par1) 1499 { 1500 this.field_71079_bU = 0.0F; 1501 this.field_71089_bV = 0.0F; 1502 1503 switch (par1) 1504 { 1505 case 0: 1506 this.field_71089_bV = -1.8F; 1507 break; 1508 case 1: 1509 this.field_71079_bU = 1.8F; 1510 break; 1511 case 2: 1512 this.field_71089_bV = 1.8F; 1513 break; 1514 case 3: 1515 this.field_71079_bU = -1.8F; 1516 } 1517 } 1518 1519 /** 1520 * Wake up the player if they're sleeping. 1521 */ 1522 public void wakeUpPlayer(boolean par1, boolean par2, boolean par3) 1523 { 1524 this.setSize(0.6F, 1.8F); 1525 this.resetHeight(); 1526 ChunkCoordinates var4 = this.playerLocation; 1527 ChunkCoordinates var5 = this.playerLocation; 1528 1529 Block block = (var4 == null ? null : Block.blocksList[worldObj.getBlockId(var4.posX, var4.posY, var4.posZ)]); 1530 1531 if (var4 != null && block != null && block.isBed(worldObj, var4.posX, var4.posY, var4.posZ, this)) 1532 { 1533 block.setBedOccupied(this.worldObj, var4.posX, var4.posY, var4.posZ, this, false); 1534 var5 = block.getBedSpawnPosition(worldObj, var4.posX, var4.posY, var4.posZ, this); 1535 1536 if (var5 == null) 1537 { 1538 var5 = new ChunkCoordinates(var4.posX, var4.posY + 1, var4.posZ); 1539 } 1540 1541 this.setPosition((double)((float)var5.posX + 0.5F), (double)((float)var5.posY + this.yOffset + 0.1F), (double)((float)var5.posZ + 0.5F)); 1542 } 1543 1544 this.sleeping = false; 1545 1546 if (!this.worldObj.isRemote && par2) 1547 { 1548 this.worldObj.updateAllPlayersSleepingFlag(); 1549 } 1550 1551 if (par1) 1552 { 1553 this.sleepTimer = 0; 1554 } 1555 else 1556 { 1557 this.sleepTimer = 100; 1558 } 1559 1560 if (par3) 1561 { 1562 this.setSpawnChunk(this.playerLocation, false); 1563 } 1564 } 1565 1566 /** 1567 * Checks if the player is currently in a bed 1568 */ 1569 private boolean isInBed() 1570 { 1571 ChunkCoordinates c = playerLocation; 1572 int blockID = worldObj.getBlockId(c.posX, c.posY, c.posZ); 1573 return Block.blocksList[blockID] != null && Block.blocksList[blockID].isBed(worldObj, c.posX, c.posY, c.posZ, this); 1574 } 1575 1576 /** 1577 * Ensure that a block enabling respawning exists at the specified coordinates and find an empty space nearby to 1578 * spawn. 1579 */ 1580 public static ChunkCoordinates verifyRespawnCoordinates(World par0World, ChunkCoordinates par1ChunkCoordinates, boolean par2) 1581 { 1582 IChunkProvider var3 = par0World.getChunkProvider(); 1583 var3.loadChunk(par1ChunkCoordinates.posX - 3 >> 4, par1ChunkCoordinates.posZ - 3 >> 4); 1584 var3.loadChunk(par1ChunkCoordinates.posX + 3 >> 4, par1ChunkCoordinates.posZ - 3 >> 4); 1585 var3.loadChunk(par1ChunkCoordinates.posX - 3 >> 4, par1ChunkCoordinates.posZ + 3 >> 4); 1586 var3.loadChunk(par1ChunkCoordinates.posX + 3 >> 4, par1ChunkCoordinates.posZ + 3 >> 4); 1587 1588 ChunkCoordinates c = par1ChunkCoordinates; 1589 Block block = Block.blocksList[par0World.getBlockId(c.posX, c.posY, c.posZ)]; 1590 1591 if (block != null && block.isBed(par0World, c.posX, c.posY, c.posZ, null)) 1592 { 1593 ChunkCoordinates var8 = block.getBedSpawnPosition(par0World, c.posX, c.posY, c.posZ, null); 1594 return var8; 1595 } 1596 else 1597 { 1598 Material var4 = par0World.getBlockMaterial(par1ChunkCoordinates.posX, par1ChunkCoordinates.posY, par1ChunkCoordinates.posZ); 1599 Material var5 = par0World.getBlockMaterial(par1ChunkCoordinates.posX, par1ChunkCoordinates.posY + 1, par1ChunkCoordinates.posZ); 1600 boolean var6 = !var4.isSolid() && !var4.isLiquid(); 1601 boolean var7 = !var5.isSolid() && !var5.isLiquid(); 1602 return par2 && var6 && var7 ? par1ChunkCoordinates : null; 1603 } 1604 } 1605 1606 @SideOnly(Side.CLIENT) 1607 1608 /** 1609 * Returns the orientation of the bed in degrees. 1610 */ 1611 public float getBedOrientationInDegrees() 1612 { 1613 if (this.playerLocation != null) 1614 { 1615 int x = playerLocation.posX; 1616 int y = playerLocation.posY; 1617 int z = playerLocation.posZ; 1618 Block block = Block.blocksList[worldObj.getBlockId(x, y, z)]; 1619 int var2 = (block == null ? 0 : block.getBedDirection(worldObj, x, y, z)); 1620 1621 switch (var2) 1622 { 1623 case 0: 1624 return 90.0F; 1625 case 1: 1626 return 0.0F; 1627 case 2: 1628 return 270.0F; 1629 case 3: 1630 return 180.0F; 1631 } 1632 } 1633 1634 return 0.0F; 1635 } 1636 1637 /** 1638 * Returns whether player is sleeping or not 1639 */ 1640 public boolean isPlayerSleeping() 1641 { 1642 return this.sleeping; 1643 } 1644 1645 /** 1646 * Returns whether or not the player is asleep and the screen has fully faded. 1647 */ 1648 public boolean isPlayerFullyAsleep() 1649 { 1650 return this.sleeping && this.sleepTimer >= 100; 1651 } 1652 1653 @SideOnly(Side.CLIENT) 1654 public int getSleepTimer() 1655 { 1656 return this.sleepTimer; 1657 } 1658 1659 @SideOnly(Side.CLIENT) 1660 protected boolean getHideCape(int par1) 1661 { 1662 return (this.dataWatcher.getWatchableObjectByte(16) & 1 << par1) != 0; 1663 } 1664 1665 protected void setHideCape(int par1, boolean par2) 1666 { 1667 byte var3 = this.dataWatcher.getWatchableObjectByte(16); 1668 1669 if (par2) 1670 { 1671 this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var3 | 1 << par1))); 1672 } 1673 else 1674 { 1675 this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var3 & ~(1 << par1)))); 1676 } 1677 } 1678 1679 /** 1680 * Add a chat message to the player 1681 */ 1682 public void addChatMessage(String par1Str) {} 1683 1684 /** 1685 * Returns the location of the bed the player will respawn at, or null if the player has not slept in a bed. 1686 */ 1687 public ChunkCoordinates getBedLocation() 1688 { 1689 return this.spawnChunk; 1690 } 1691 1692 public boolean isSpawnForced() 1693 { 1694 return this.spawnForced; 1695 } 1696 1697 /** 1698 * Defines a spawn coordinate to player spawn. Used by bed after the player sleep on it. 1699 */ 1700 public void setSpawnChunk(ChunkCoordinates par1ChunkCoordinates, boolean par2) 1701 { 1702 if (par1ChunkCoordinates != null) 1703 { 1704 this.spawnChunk = new ChunkCoordinates(par1ChunkCoordinates); 1705 this.spawnForced = par2; 1706 } 1707 else 1708 { 1709 this.spawnChunk = null; 1710 this.spawnForced = false; 1711 } 1712 } 1713 1714 /** 1715 * Will trigger the specified trigger. 1716 */ 1717 public void triggerAchievement(StatBase par1StatBase) 1718 { 1719 this.addStat(par1StatBase, 1); 1720 } 1721 1722 /** 1723 * Adds a value to a statistic field. 1724 */ 1725 public void addStat(StatBase par1StatBase, int par2) {} 1726 1727 /** 1728 * Causes this entity to do an upwards motion (jumping). 1729 */ 1730 protected void jump() 1731 { 1732 super.jump(); 1733 this.addStat(StatList.jumpStat, 1); 1734 1735 if (this.isSprinting()) 1736 { 1737 this.addExhaustion(0.8F); 1738 } 1739 else 1740 { 1741 this.addExhaustion(0.2F); 1742 } 1743 } 1744 1745 /** 1746 * Moves the entity based on the specified heading. Args: strafe, forward 1747 */ 1748 public void moveEntityWithHeading(float par1, float par2) 1749 { 1750 double var3 = this.posX; 1751 double var5 = this.posY; 1752 double var7 = this.posZ; 1753 1754 if (this.capabilities.isFlying && this.ridingEntity == null) 1755 { 1756 double var9 = this.motionY; 1757 float var11 = this.jumpMovementFactor; 1758 this.jumpMovementFactor = this.capabilities.getFlySpeed(); 1759 super.moveEntityWithHeading(par1, par2); 1760 this.motionY = var9 * 0.6D; 1761 this.jumpMovementFactor = var11; 1762 } 1763 else 1764 { 1765 super.moveEntityWithHeading(par1, par2); 1766 } 1767 1768 this.addMovementStat(this.posX - var3, this.posY - var5, this.posZ - var7); 1769 } 1770 1771 /** 1772 * Adds a value to a movement statistic field - like run, walk, swin or climb. 1773 */ 1774 public void addMovementStat(double par1, double par3, double par5) 1775 { 1776 if (this.ridingEntity == null) 1777 { 1778 int var7; 1779 1780 if (this.isInsideOfMaterial(Material.water)) 1781 { 1782 var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par3 * par3 + par5 * par5) * 100.0F); 1783 1784 if (var7 > 0) 1785 { 1786 this.addStat(StatList.distanceDoveStat, var7); 1787 this.addExhaustion(0.015F * (float)var7 * 0.01F); 1788 } 1789 } 1790 else if (this.isInWater()) 1791 { 1792 var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par5 * par5) * 100.0F); 1793 1794 if (var7 > 0) 1795 { 1796 this.addStat(StatList.distanceSwumStat, var7); 1797 this.addExhaustion(0.015F * (float)var7 * 0.01F); 1798 } 1799 } 1800 else if (this.isOnLadder()) 1801 { 1802 if (par3 > 0.0D) 1803 { 1804 this.addStat(StatList.distanceClimbedStat, (int)Math.round(par3 * 100.0D)); 1805 } 1806 } 1807 else if (this.onGround) 1808 { 1809 var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par5 * par5) * 100.0F); 1810 1811 if (var7 > 0) 1812 { 1813 this.addStat(StatList.distanceWalkedStat, var7); 1814 1815 if (this.isSprinting()) 1816 { 1817 this.addExhaustion(0.099999994F * (float)var7 * 0.01F); 1818 } 1819 else 1820 { 1821 this.addExhaustion(0.01F * (float)var7 * 0.01F); 1822 } 1823 } 1824 } 1825 else 1826 { 1827 var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par5 * par5) * 100.0F); 1828 1829 if (var7 > 25) 1830 { 1831 this.addStat(StatList.distanceFlownStat, var7); 1832 } 1833 } 1834 } 1835 } 1836 1837 /** 1838 * Adds a value to a mounted movement statistic field - by minecart, boat, or pig. 1839 */ 1840 private void addMountedMovementStat(double par1, double par3, double par5) 1841 { 1842 if (this.ridingEntity != null) 1843 { 1844 int var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par3 * par3 + par5 * par5) * 100.0F); 1845 1846 if (var7 > 0) 1847 { 1848 if (this.ridingEntity instanceof EntityMinecart) 1849 { 1850 this.addStat(StatList.distanceByMinecartStat, var7); 1851 1852 if (this.startMinecartRidingCoordinate == null) 1853 { 1854 this.startMinecartRidingCoordinate = new ChunkCoordinates(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)); 1855 } 1856 else if ((double)this.startMinecartRidingCoordinate.getDistanceSquared(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)) >= 1000000.0D) 1857 { 1858 this.addStat(AchievementList.onARail, 1); 1859 } 1860 } 1861 else if (this.ridingEntity instanceof EntityBoat) 1862 { 1863 this.addStat(StatList.distanceByBoatStat, var7); 1864 } 1865 else if (this.ridingEntity instanceof EntityPig) 1866 { 1867 this.addStat(StatList.distanceByPigStat, var7); 1868 } 1869 } 1870 } 1871 } 1872 1873 /** 1874 * Called when the mob is falling. Calculates and applies fall damage. 1875 */ 1876 protected void fall(float par1) 1877 { 1878 if (!this.capabilities.allowFlying) 1879 { 1880 if (par1 >= 2.0F) 1881 { 1882 this.addStat(StatList.distanceFallenStat, (int)Math.round((double)par1 * 100.0D)); 1883 } 1884 1885 super.fall(par1); 1886 } 1887 } 1888 1889 /** 1890 * This method gets called when the entity kills another one. 1891 */ 1892 public void onKillEntity(EntityLiving par1EntityLiving) 1893 { 1894 if (par1EntityLiving instanceof IMob) 1895 { 1896 this.triggerAchievement(AchievementList.killEnemy); 1897 } 1898 } 1899 1900 /** 1901 * Sets the Entity inside a web block. 1902 */ 1903 public void setInWeb() 1904 { 1905 if (!this.capabilities.isFlying) 1906 { 1907 super.setInWeb(); 1908 } 1909 } 1910 1911 @SideOnly(Side.CLIENT) 1912 1913 /** 1914 * Gets the Icon Index of the item currently held 1915 */ 1916 public int getItemIcon(ItemStack par1ItemStack, int par2) 1917 { 1918 int var3 = super.getItemIcon(par1ItemStack, par2); 1919 1920 if (par1ItemStack.itemID == Item.fishingRod.shiftedIndex && this.fishEntity != null) 1921 { 1922 var3 = par1ItemStack.getIconIndex() + 16; 1923 } 1924 else 1925 { 1926 if (par1ItemStack.getItem().requiresMultipleRenderPasses()) 1927 { 1928 return par1ItemStack.getItem().getIconFromItemStackForMultiplePasses(par1ItemStack, par2); 1929 } 1930 1931 if (this.itemInUse != null && par1ItemStack.itemID == Item.bow.shiftedIndex) 1932 { 1933 int var4 = par1ItemStack.getMaxItemUseDuration() - this.itemInUseCount; 1934 1935 if (var4 >= 18) 1936 { 1937 return 133; 1938 } 1939 1940 if (var4 > 13) 1941 { 1942 return 117; 1943 } 1944 1945 if (var4 > 0) 1946 { 1947 return 101; 1948 } 1949 } 1950 var3 = par1ItemStack.getItem().getIconIndex(par1ItemStack, par2, this, itemInUse, itemInUseCount); 1951 } 1952 1953 return var3; 1954 } 1955 1956 public ItemStack getCurrentArmor(int par1) 1957 { 1958 return this.inventory.armorItemInSlot(par1); 1959 } 1960 1961 protected void func_82164_bB() {} 1962 1963 protected void func_82162_bC() {} 1964 1965 /** 1966 * This method increases the player's current amount of experience. 1967 */ 1968 public void addExperience(int par1) 1969 { 1970 this.func_85039_t(par1); 1971 int var2 = Integer.MAX_VALUE - this.experienceTotal; 1972 1973 if (par1 > var2) 1974 { 1975 par1 = var2; 1976 } 1977 1978 this.experience += (float)par1 / (float)this.xpBarCap(); 1979 1980 for (this.experienceTotal += par1; this.experience >= 1.0F; this.experience /= (float)this.xpBarCap()) 1981 { 1982 this.experience = (this.experience - 1.0F) * (float)this.xpBarCap(); 1983 this.addExperienceLevel(1); 1984 } 1985 } 1986 1987 /** 1988 * Add experience levels to this player. 1989 */ 1990 public void addExperienceLevel(int par1) 1991 { 1992 this.experienceLevel += par1; 1993 1994 if (this.experienceLevel < 0) 1995 { 1996 this.experienceLevel = 0; 1997 } 1998 1999 if (par1 > 0 && this.experienceLevel % 5 == 0 && (float)this.field_82249_h < (float)this.ticksExisted - 100.0F) 2000 { 2001 float var2 = this.experienceLevel > 30 ? 1.0F : (float)this.experienceLevel / 30.0F; 2002 this.func_85030_a("random.levelup", var2 * 0.75F, 1.0F); 2003 this.field_82249_h = this.ticksExisted; 2004 } 2005 } 2006 2007 /** 2008 * This method returns the cap amount of experience that the experience bar can hold. With each level, the 2009 * experience cap on the player's experience bar is raised by 10. 2010 */ 2011 public int xpBarCap() 2012 { 2013 return this.experienceLevel >= 30 ? 62 + (this.experienceLevel - 30) * 7 : (this.experienceLevel >= 15 ? 17 + (this.experienceLevel - 15) * 3 : 17); 2014 } 2015 2016 /** 2017 * increases exhaustion level by supplied amount 2018 */ 2019 public void addExhaustion(float par1) 2020 { 2021 if (!this.capabilities.disableDamage) 2022 { 2023 if (!this.worldObj.isRemote) 2024 { 2025 this.foodStats.addExhaustion(par1); 2026 } 2027 } 2028 } 2029 2030 /** 2031 * Returns the player's FoodStats object. 2032 */ 2033 public FoodStats getFoodStats() 2034 { 2035 return this.foodStats; 2036 } 2037 2038 public boolean canEat(boolean par1) 2039 { 2040 return (par1 || this.foodStats.needFood()) && !this.capabilities.disableDamage; 2041 } 2042 2043 /** 2044 * Checks if the player's health is not full and not zero. 2045 */ 2046 public boolean shouldHeal() 2047 { 2048 return this.getHealth() > 0 && this.getHealth() < this.getMaxHealth(); 2049 } 2050 2051 /** 2052 * sets the itemInUse when the use item button is clicked. Args: itemstack, int maxItemUseDuration 2053 */ 2054 public void setItemInUse(ItemStack par1ItemStack, int par2) 2055 { 2056 if (par1ItemStack != this.itemInUse) 2057 { 2058 this.itemInUse = par1ItemStack; 2059 this.itemInUseCount = par2; 2060 2061 if (!this.worldObj.isRemote) 2062 { 2063 this.setEating(true); 2064 } 2065 } 2066 } 2067 2068 /** 2069 * Returns true if the item the player is holding can harvest the block at the given coords. Args: x, y, z. 2070 */ 2071 public boolean canCurrentToolHarvestBlock(int par1, int par2, int par3) 2072 { 2073 if (this.capabilities.allowEdit) 2074 { 2075 return true; 2076 } 2077 else 2078 { 2079 int var4 = this.worldObj.getBlockId(par1, par2, par3); 2080 2081 if (var4 > 0) 2082 { 2083 Block var5 = Block.blocksList[var4]; 2084 2085 if (var5.blockMaterial.func_85157_q()) 2086 { 2087 return true; 2088 } 2089 2090 if (this.getCurrentEquippedItem() != null) 2091 { 2092 ItemStack var6 = this.getCurrentEquippedItem(); 2093 2094 if (var6.canHarvestBlock(var5) || var6.getStrVsBlock(var5) > 1.0F) 2095 { 2096 return true; 2097 } 2098 } 2099 } 2100 2101 return false; 2102 } 2103 } 2104 2105 public boolean canPlayerEdit(int par1, int par2, int par3, int par4, ItemStack par5ItemStack) 2106 { 2107 return this.capabilities.allowEdit ? true : (par5ItemStack != null ? par5ItemStack.func_82835_x() : false); 2108 } 2109 2110 /** 2111 * Get the experience points the entity currently has. 2112 */ 2113 protected int getExperiencePoints(EntityPlayer par1EntityPlayer) 2114 { 2115 if (this.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory")) 2116 { 2117 return 0; 2118 } 2119 else 2120 { 2121 int var2 = this.experienceLevel * 7; 2122 return var2 > 100 ? 100 : var2; 2123 } 2124 } 2125 2126 /** 2127 * Only use is to identify if class is an instance of player for experience dropping 2128 */ 2129 protected boolean isPlayer() 2130 { 2131 return true; 2132 } 2133 2134 /** 2135 * Gets the username of the entity. 2136 */ 2137 public String getEntityName() 2138 { 2139 return this.username; 2140 } 2141 2142 /** 2143 * Copies the values from the given player into this player if boolean par2 is true. Always clones Ender Chest 2144 * Inventory. 2145 */ 2146 public void clonePlayer(EntityPlayer par1EntityPlayer, boolean par2) 2147 { 2148 if (par2) 2149 { 2150 this.inventory.copyInventory(par1EntityPlayer.inventory); 2151 this.health = par1EntityPlayer.health; 2152 this.foodStats = par1EntityPlayer.foodStats; 2153 this.experienceLevel = par1EntityPlayer.experienceLevel; 2154 this.experienceTotal = par1EntityPlayer.experienceTotal; 2155 this.experience = par1EntityPlayer.experience; 2156 this.func_85040_s(par1EntityPlayer.getScore()); 2157 this.field_82152_aq = par1EntityPlayer.field_82152_aq; 2158 } 2159 else if (this.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory")) 2160 { 2161 this.inventory.copyInventory(par1EntityPlayer.inventory); 2162 this.experienceLevel = par1EntityPlayer.experienceLevel; 2163 this.experienceTotal = par1EntityPlayer.experienceTotal; 2164 this.experience = par1EntityPlayer.experience; 2165 this.func_85040_s(par1EntityPlayer.getScore()); 2166 } 2167 2168 this.theInventoryEnderChest = par1EntityPlayer.theInventoryEnderChest; 2169 2170 //Copy over a section of the Entity Data from the old player. 2171 //Allows mods to specify data that persists after players respawn. 2172 NBTTagCompound old = par1EntityPlayer.getEntityData(); 2173 if (old.hasKey(PERSISTED_NBT_TAG)) 2174 { 2175 getEntityData().setCompoundTag(PERSISTED_NBT_TAG, old.getCompoundTag(PERSISTED_NBT_TAG)); 2176 } 2177 } 2178 2179 /** 2180 * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to 2181 * prevent them from trampling crops 2182 */ 2183 protected boolean canTriggerWalking() 2184 { 2185 return !this.capabilities.isFlying; 2186 } 2187 2188 /** 2189 * Sends the player's abilities to the server (if there is one). 2190 */ 2191 public void sendPlayerAbilities() {} 2192 2193 public void sendGameTypeToPlayer(EnumGameType par1EnumGameType) {} 2194 2195 /** 2196 * Gets the name of this command sender (usually username, but possibly "Rcon") 2197 */ 2198 public String getCommandSenderName() 2199 { 2200 return this.username; 2201 } 2202 2203 public StringTranslate getTranslator() 2204 { 2205 return StringTranslate.getInstance(); 2206 } 2207 2208 /** 2209 * Translates and formats the given string key with the given arguments. 2210 */ 2211 public String translateString(String par1Str, Object ... par2ArrayOfObj) 2212 { 2213 return this.getTranslator().translateKeyFormat(par1Str, par2ArrayOfObj); 2214 } 2215 2216 /** 2217 * Returns the InventoryEnderChest of this player. 2218 */ 2219 public InventoryEnderChest getInventoryEnderChest() 2220 { 2221 return this.theInventoryEnderChest; 2222 } 2223 2224 /** 2225 * 0 = item, 1-n is armor 2226 */ 2227 public ItemStack getCurrentItemOrArmor(int par1) 2228 { 2229 return par1 == 0 ? this.inventory.getCurrentItem() : this.inventory.armorInventory[par1 - 1]; 2230 } 2231 2232 /** 2233 * Returns the item that this EntityLiving is holding, if any. 2234 */ 2235 public ItemStack getHeldItem() 2236 { 2237 return this.inventory.getCurrentItem(); 2238 } 2239 2240 /** 2241 * Sets the held item, or an armor slot. Slot 0 is held item. Slot 1-4 is armor. Params: Item, slot 2242 */ 2243 public void setCurrentItemOrArmor(int par1, ItemStack par2ItemStack) 2244 { 2245 this.inventory.armorInventory[par1] = par2ItemStack; 2246 } 2247 2248 public ItemStack[] getLastActiveItems() 2249 { 2250 return this.inventory.armorInventory; 2251 } 2252 2253 @SideOnly(Side.CLIENT) 2254 public boolean getHideCape() 2255 { 2256 return this.getHideCape(1); 2257 } 2258 2259 public void openGui(Object mod, int modGuiId, World world, int x, int y, int z) 2260 { 2261 FMLNetworkHandler.openGui(this, mod, modGuiId, world, x, y, z); 2262 } 2263 }