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