001package net.minecraft.entity.player; 002 003import cpw.mods.fml.common.FMLCommonHandler; 004import cpw.mods.fml.common.network.FMLNetworkHandler; 005import cpw.mods.fml.relauncher.Side; 006import cpw.mods.fml.relauncher.SideOnly; 007import java.util.Iterator; 008import java.util.List; 009import net.minecraft.block.Block; 010import net.minecraft.block.BlockBed; 011import net.minecraft.block.material.Material; 012import net.minecraft.command.ICommandSender; 013import net.minecraft.enchantment.EnchantmentHelper; 014import net.minecraft.enchantment.EnchantmentThorns; 015import net.minecraft.entity.Entity; 016import net.minecraft.entity.EntityLiving; 017import net.minecraft.entity.IMerchant; 018import net.minecraft.entity.item.EntityBoat; 019import net.minecraft.entity.item.EntityItem; 020import net.minecraft.entity.item.EntityMinecart; 021import net.minecraft.entity.monster.EntityCreeper; 022import net.minecraft.entity.monster.EntityGhast; 023import net.minecraft.entity.monster.EntityMob; 024import net.minecraft.entity.monster.IMob; 025import net.minecraft.entity.passive.EntityPig; 026import net.minecraft.entity.passive.EntityWolf; 027import net.minecraft.entity.projectile.EntityArrow; 028import net.minecraft.entity.projectile.EntityFishHook; 029import net.minecraft.inventory.Container; 030import net.minecraft.inventory.ContainerPlayer; 031import net.minecraft.inventory.IInventory; 032import net.minecraft.inventory.InventoryEnderChest; 033import net.minecraft.item.EnumAction; 034import net.minecraft.item.Item; 035import net.minecraft.item.ItemStack; 036import net.minecraft.nbt.NBTTagCompound; 037import net.minecraft.nbt.NBTTagList; 038import net.minecraft.potion.Potion; 039import net.minecraft.stats.AchievementList; 040import net.minecraft.stats.StatBase; 041import net.minecraft.stats.StatList; 042import net.minecraft.tileentity.TileEntity; 043import net.minecraft.tileentity.TileEntityBeacon; 044import net.minecraft.tileentity.TileEntityBrewingStand; 045import net.minecraft.tileentity.TileEntityDispenser; 046import net.minecraft.tileentity.TileEntityFurnace; 047import net.minecraft.util.AxisAlignedBB; 048import net.minecraft.util.ChunkCoordinates; 049import net.minecraft.util.DamageSource; 050import net.minecraft.util.FoodStats; 051import net.minecraft.util.MathHelper; 052import net.minecraft.util.StringTranslate; 053import net.minecraft.util.Vec3; 054import net.minecraft.world.EnumGameType; 055import net.minecraft.world.World; 056import net.minecraft.world.chunk.IChunkProvider; 057 058import net.minecraftforge.common.ForgeHooks; 059import net.minecraftforge.common.ISpecialArmor.ArmorProperties; 060import net.minecraftforge.common.MinecraftForge; 061import net.minecraftforge.event.ForgeEventFactory; 062import net.minecraftforge.event.entity.living.LivingHurtEvent; 063import net.minecraftforge.event.entity.player.AttackEntityEvent; 064import net.minecraftforge.event.entity.player.EntityInteractEvent; 065import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent; 066import net.minecraftforge.event.entity.player.PlayerDropsEvent; 067import net.minecraftforge.event.entity.player.PlayerSleepInBedEvent; 068 069public 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 public void playSound(String par1Str, float par2, float par3) 413 { 414 this.worldObj.playSoundToNearExcept(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.playSound("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().itemID, var5.xCoord, var5.yCoord, var5.zCoord, var4.xCoord, var4.yCoord + 0.05D, var4.zCoord); 439 } 440 441 this.playSound("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 /** 621 * Set player's score 622 */ 623 public void setScore(int par1) 624 { 625 this.dataWatcher.updateObject(18, Integer.valueOf(par1)); 626 } 627 628 /** 629 * Add to player's score 630 */ 631 public void addScore(int par1) 632 { 633 int var2 = this.getScore(); 634 this.dataWatcher.updateObject(18, Integer.valueOf(var2 + par1)); 635 } 636 637 /** 638 * Called when the mob's health reaches 0. 639 */ 640 public void onDeath(DamageSource par1DamageSource) 641 { 642 super.onDeath(par1DamageSource); 643 this.setSize(0.2F, 0.2F); 644 this.setPosition(this.posX, this.posY, this.posZ); 645 this.motionY = 0.10000000149011612D; 646 647 captureDrops = true; 648 capturedDrops.clear(); 649 650 if (this.username.equals("Notch")) 651 { 652 this.dropPlayerItemWithRandomChoice(new ItemStack(Item.appleRed, 1), true); 653 } 654 655 if (!this.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory")) 656 { 657 this.inventory.dropAllItems(); 658 } 659 660 captureDrops = false; 661 662 if (!worldObj.isRemote) 663 { 664 PlayerDropsEvent event = new PlayerDropsEvent(this, par1DamageSource, capturedDrops, recentlyHit > 0); 665 if (!MinecraftForge.EVENT_BUS.post(event)) 666 { 667 for (EntityItem item : capturedDrops) 668 { 669 joinEntityItemWithWorld(item); 670 } 671 } 672 } 673 674 if (par1DamageSource != null) 675 { 676 this.motionX = (double)(-MathHelper.cos((this.attackedAtYaw + this.rotationYaw) * (float)Math.PI / 180.0F) * 0.1F); 677 this.motionZ = (double)(-MathHelper.sin((this.attackedAtYaw + this.rotationYaw) * (float)Math.PI / 180.0F) * 0.1F); 678 } 679 else 680 { 681 this.motionX = this.motionZ = 0.0D; 682 } 683 684 this.yOffset = 0.1F; 685 this.addStat(StatList.deathsStat, 1); 686 } 687 688 /** 689 * Adds a value to the player score. Currently not actually used and the entity passed in does nothing. Args: 690 * entity, scoreToAdd 691 */ 692 public void addToPlayerScore(Entity par1Entity, int par2) 693 { 694 this.addScore(par2); 695 696 if (par1Entity instanceof EntityPlayer) 697 { 698 this.addStat(StatList.playerKillsStat, 1); 699 } 700 else 701 { 702 this.addStat(StatList.mobKillsStat, 1); 703 } 704 } 705 706 /** 707 * Called when player presses the drop item key 708 */ 709 public EntityItem dropOneItem(boolean par1) 710 { 711 ItemStack stack = inventory.getCurrentItem(); 712 713 if (stack == null) 714 { 715 return null; 716 } 717 718 if (stack.getItem().onDroppedByPlayer(stack, this)) 719 { 720 int count = par1 && this.inventory.getCurrentItem() != null ? this.inventory.getCurrentItem().stackSize : 1; 721 return ForgeHooks.onPlayerTossEvent(this, inventory.decrStackSize(inventory.currentItem, count)); 722 } 723 724 return null; 725 } 726 727 /** 728 * Args: itemstack - called when player drops an item stack that's not in his inventory (like items still placed in 729 * a workbench while the workbench'es GUI gets closed) 730 */ 731 public EntityItem dropPlayerItem(ItemStack par1ItemStack) 732 { 733 return ForgeHooks.onPlayerTossEvent(this, par1ItemStack); 734 } 735 736 /** 737 * Args: itemstack, flag 738 */ 739 public EntityItem dropPlayerItemWithRandomChoice(ItemStack par1ItemStack, boolean par2) 740 { 741 if (par1ItemStack == null) 742 { 743 return null; 744 } 745 else 746 { 747 EntityItem var3 = new EntityItem(this.worldObj, this.posX, this.posY - 0.30000001192092896D + (double)this.getEyeHeight(), this.posZ, par1ItemStack); 748 var3.delayBeforeCanPickup = 40; 749 float var4 = 0.1F; 750 float var5; 751 752 if (par2) 753 { 754 var5 = this.rand.nextFloat() * 0.5F; 755 float var6 = this.rand.nextFloat() * (float)Math.PI * 2.0F; 756 var3.motionX = (double)(-MathHelper.sin(var6) * var5); 757 var3.motionZ = (double)(MathHelper.cos(var6) * var5); 758 var3.motionY = 0.20000000298023224D; 759 } 760 else 761 { 762 var4 = 0.3F; 763 var3.motionX = (double)(-MathHelper.sin(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float)Math.PI) * var4); 764 var3.motionZ = (double)(MathHelper.cos(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float)Math.PI) * var4); 765 var3.motionY = (double)(-MathHelper.sin(this.rotationPitch / 180.0F * (float)Math.PI) * var4 + 0.1F); 766 var4 = 0.02F; 767 var5 = this.rand.nextFloat() * (float)Math.PI * 2.0F; 768 var4 *= this.rand.nextFloat(); 769 var3.motionX += Math.cos((double)var5) * (double)var4; 770 var3.motionY += (double)((this.rand.nextFloat() - this.rand.nextFloat()) * 0.1F); 771 var3.motionZ += Math.sin((double)var5) * (double)var4; 772 } 773 774 this.joinEntityItemWithWorld(var3); 775 this.addStat(StatList.dropStat, 1); 776 return var3; 777 } 778 } 779 780 /** 781 * Joins the passed in entity item with the world. Args: entityItem 782 */ 783 public void joinEntityItemWithWorld(EntityItem par1EntityItem) 784 { 785 if (captureDrops) 786 { 787 capturedDrops.add(par1EntityItem); 788 } 789 else 790 { 791 this.worldObj.spawnEntityInWorld(par1EntityItem); 792 } 793 } 794 795 /** 796 * Returns how strong the player is against the specified block at this moment 797 * Deprecated in favor of the more sensitive version 798 */ 799 @Deprecated 800 public float getCurrentPlayerStrVsBlock(Block par1Block) 801 { 802 return getCurrentPlayerStrVsBlock(par1Block, 0); 803 } 804 805 public float getCurrentPlayerStrVsBlock(Block par1Block, int meta) 806 { 807 ItemStack stack = inventory.getCurrentItem(); 808 float var2 = (stack == null ? 1.0F : stack.getItem().getStrVsBlock(stack, par1Block, meta)); 809 int var3 = EnchantmentHelper.getEfficiencyModifier(this); 810 ItemStack var4 = this.inventory.getCurrentItem(); 811 812 if (var3 > 0 && var4 != null) 813 { 814 float var5 = (float)(var3 * var3 + 1); 815 boolean canHarvest = ForgeHooks.canToolHarvestBlock(par1Block, meta, var4); 816 817 if (!canHarvest && var2 <= 1.0F) 818 { 819 var2 += var5 * 0.08F; 820 } 821 else 822 { 823 var2 += var5; 824 } 825 } 826 827 if (this.isPotionActive(Potion.digSpeed)) 828 { 829 var2 *= 1.0F + (float)(this.getActivePotionEffect(Potion.digSpeed).getAmplifier() + 1) * 0.2F; 830 } 831 832 if (this.isPotionActive(Potion.digSlowdown)) 833 { 834 var2 *= 1.0F - (float)(this.getActivePotionEffect(Potion.digSlowdown).getAmplifier() + 1) * 0.2F; 835 } 836 837 if (this.isInsideOfMaterial(Material.water) && !EnchantmentHelper.getAquaAffinityModifier(this)) 838 { 839 var2 /= 5.0F; 840 } 841 842 if (!this.onGround) 843 { 844 var2 /= 5.0F; 845 } 846 847 var2 = ForgeEventFactory.getBreakSpeed(this, par1Block, meta, var2); 848 return (var2 < 0 ? 0 : var2); 849 } 850 851 /** 852 * Checks if the player has the ability to harvest a block (checks current inventory item for a tool if necessary) 853 */ 854 public boolean canHarvestBlock(Block par1Block) 855 { 856 return ForgeEventFactory.doPlayerHarvestCheck(this, par1Block, inventory.canHarvestBlock(par1Block)); 857 } 858 859 /** 860 * (abstract) Protected helper method to read subclass entity data from NBT. 861 */ 862 public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) 863 { 864 super.readEntityFromNBT(par1NBTTagCompound); 865 NBTTagList var2 = par1NBTTagCompound.getTagList("Inventory"); 866 this.inventory.readFromNBT(var2); 867 this.inventory.currentItem = par1NBTTagCompound.getInteger("SelectedItemSlot"); 868 this.sleeping = par1NBTTagCompound.getBoolean("Sleeping"); 869 this.sleepTimer = par1NBTTagCompound.getShort("SleepTimer"); 870 this.experience = par1NBTTagCompound.getFloat("XpP"); 871 this.experienceLevel = par1NBTTagCompound.getInteger("XpLevel"); 872 this.experienceTotal = par1NBTTagCompound.getInteger("XpTotal"); 873 this.setScore(par1NBTTagCompound.getInteger("Score")); 874 875 if (this.sleeping) 876 { 877 this.playerLocation = new ChunkCoordinates(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)); 878 this.wakeUpPlayer(true, true, false); 879 } 880 881 if (par1NBTTagCompound.hasKey("SpawnX") && par1NBTTagCompound.hasKey("SpawnY") && par1NBTTagCompound.hasKey("SpawnZ")) 882 { 883 this.spawnChunk = new ChunkCoordinates(par1NBTTagCompound.getInteger("SpawnX"), par1NBTTagCompound.getInteger("SpawnY"), par1NBTTagCompound.getInteger("SpawnZ")); 884 this.spawnForced = par1NBTTagCompound.getBoolean("SpawnForced"); 885 } 886 887 this.foodStats.readNBT(par1NBTTagCompound); 888 this.capabilities.readCapabilitiesFromNBT(par1NBTTagCompound); 889 890 if (par1NBTTagCompound.hasKey("EnderItems")) 891 { 892 NBTTagList var3 = par1NBTTagCompound.getTagList("EnderItems"); 893 this.theInventoryEnderChest.loadInventoryFromNBT(var3); 894 } 895 896 //Disable vanilla mob armor/item pickup, players can already pickup items 897 //and it causes issues with overwriting items, dropping items, etc.. 898 this.canPickUpLoot = false; 899 } 900 901 /** 902 * (abstract) Protected helper method to write subclass entity data to NBT. 903 */ 904 public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) 905 { 906 super.writeEntityToNBT(par1NBTTagCompound); 907 par1NBTTagCompound.setTag("Inventory", this.inventory.writeToNBT(new NBTTagList())); 908 par1NBTTagCompound.setInteger("SelectedItemSlot", this.inventory.currentItem); 909 par1NBTTagCompound.setBoolean("Sleeping", this.sleeping); 910 par1NBTTagCompound.setShort("SleepTimer", (short)this.sleepTimer); 911 par1NBTTagCompound.setFloat("XpP", this.experience); 912 par1NBTTagCompound.setInteger("XpLevel", this.experienceLevel); 913 par1NBTTagCompound.setInteger("XpTotal", this.experienceTotal); 914 par1NBTTagCompound.setInteger("Score", this.getScore()); 915 916 if (this.spawnChunk != null) 917 { 918 par1NBTTagCompound.setInteger("SpawnX", this.spawnChunk.posX); 919 par1NBTTagCompound.setInteger("SpawnY", this.spawnChunk.posY); 920 par1NBTTagCompound.setInteger("SpawnZ", this.spawnChunk.posZ); 921 par1NBTTagCompound.setBoolean("SpawnForced", this.spawnForced); 922 } 923 924 this.foodStats.writeNBT(par1NBTTagCompound); 925 this.capabilities.writeCapabilitiesToNBT(par1NBTTagCompound); 926 par1NBTTagCompound.setTag("EnderItems", this.theInventoryEnderChest.saveInventoryToNBT()); 927 } 928 929 /** 930 * Displays the GUI for interacting with a chest inventory. Args: chestInventory 931 */ 932 public void displayGUIChest(IInventory par1IInventory) {} 933 934 public void displayGUIEnchantment(int par1, int par2, int par3) {} 935 936 /** 937 * Displays the GUI for interacting with an anvil. 938 */ 939 public void displayGUIAnvil(int par1, int par2, int par3) {} 940 941 /** 942 * Displays the crafting GUI for a workbench. 943 */ 944 public void displayGUIWorkbench(int par1, int par2, int par3) {} 945 946 public float getEyeHeight() 947 { 948 return 0.12F; 949 } 950 951 /** 952 * sets the players height back to normal after doing things like sleeping and dieing 953 */ 954 protected void resetHeight() 955 { 956 this.yOffset = 1.62F; 957 } 958 959 /** 960 * Called when the entity is attacked. 961 */ 962 public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) 963 { 964 if (this.isEntityInvulnerable()) 965 { 966 return false; 967 } 968 else if (this.capabilities.disableDamage && !par1DamageSource.canHarmInCreative()) 969 { 970 return false; 971 } 972 else 973 { 974 this.entityAge = 0; 975 976 if (this.getHealth() <= 0) 977 { 978 return false; 979 } 980 else 981 { 982 if (this.isPlayerSleeping() && !this.worldObj.isRemote) 983 { 984 this.wakeUpPlayer(true, true, false); 985 } 986 987 if (par1DamageSource.isDifficultyScaled()) 988 { 989 if (this.worldObj.difficultySetting == 0) 990 { 991 par2 = 0; 992 } 993 994 if (this.worldObj.difficultySetting == 1) 995 { 996 par2 = par2 / 2 + 1; 997 } 998 999 if (this.worldObj.difficultySetting == 3) 1000 { 1001 par2 = par2 * 3 / 2; 1002 } 1003 } 1004 1005 if (par2 == 0) 1006 { 1007 return false; 1008 } 1009 else 1010 { 1011 Entity var3 = par1DamageSource.getEntity(); 1012 1013 if (var3 instanceof EntityArrow && ((EntityArrow)var3).shootingEntity != null) 1014 { 1015 var3 = ((EntityArrow)var3).shootingEntity; 1016 } 1017 1018 if (var3 instanceof EntityLiving) 1019 { 1020 this.alertWolves((EntityLiving)var3, false); 1021 } 1022 1023 this.addStat(StatList.damageTakenStat, par2); 1024 return super.attackEntityFrom(par1DamageSource, par2); 1025 } 1026 } 1027 } 1028 } 1029 1030 /** 1031 * Reduces damage, depending on potions 1032 */ 1033 protected int applyPotionDamageCalculations(DamageSource par1DamageSource, int par2) 1034 { 1035 int var3 = super.applyPotionDamageCalculations(par1DamageSource, par2); 1036 1037 if (var3 <= 0) 1038 { 1039 return 0; 1040 } 1041 else 1042 { 1043 int var4 = EnchantmentHelper.getEnchantmentModifierDamage(this.inventory.armorInventory, par1DamageSource); 1044 1045 if (var4 > 20) 1046 { 1047 var4 = 20; 1048 } 1049 1050 if (var4 > 0 && var4 <= 20) 1051 { 1052 int var5 = 25 - var4; 1053 int var6 = var3 * var5 + this.carryoverDamage; 1054 var3 = var6 / 25; 1055 this.carryoverDamage = var6 % 25; 1056 } 1057 1058 return var3; 1059 } 1060 } 1061 1062 /** 1063 * returns if pvp is enabled or not 1064 */ 1065 protected boolean isPVPEnabled() 1066 { 1067 return false; 1068 } 1069 1070 /** 1071 * Called when the player attack or gets attacked, it's alert all wolves in the area that are owned by the player to 1072 * join the attack or defend the player. 1073 */ 1074 protected void alertWolves(EntityLiving par1EntityLiving, boolean par2) 1075 { 1076 if (!(par1EntityLiving instanceof EntityCreeper) && !(par1EntityLiving instanceof EntityGhast)) 1077 { 1078 if (par1EntityLiving instanceof EntityWolf) 1079 { 1080 EntityWolf var3 = (EntityWolf)par1EntityLiving; 1081 1082 if (var3.isTamed() && this.username.equals(var3.getOwnerName())) 1083 { 1084 return; 1085 } 1086 } 1087 1088 if (!(par1EntityLiving instanceof EntityPlayer) || this.isPVPEnabled()) 1089 { 1090 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)); 1091 Iterator var4 = var6.iterator(); 1092 1093 while (var4.hasNext()) 1094 { 1095 EntityWolf var5 = (EntityWolf)var4.next(); 1096 1097 if (var5.isTamed() && var5.getEntityToAttack() == null && this.username.equals(var5.getOwnerName()) && (!par2 || !var5.isSitting())) 1098 { 1099 var5.setSitting(false); 1100 var5.setTarget(par1EntityLiving); 1101 } 1102 } 1103 } 1104 } 1105 } 1106 1107 protected void damageArmor(int par1) 1108 { 1109 this.inventory.damageArmor(par1); 1110 } 1111 1112 /** 1113 * Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue 1114 */ 1115 public int getTotalArmorValue() 1116 { 1117 return this.inventory.getTotalArmorValue(); 1118 } 1119 1120 public float func_82243_bO() 1121 { 1122 int var1 = 0; 1123 ItemStack[] var2 = this.inventory.armorInventory; 1124 int var3 = var2.length; 1125 1126 for (int var4 = 0; var4 < var3; ++var4) 1127 { 1128 ItemStack var5 = var2[var4]; 1129 1130 if (var5 != null) 1131 { 1132 ++var1; 1133 } 1134 } 1135 1136 return (float)var1 / (float)this.inventory.armorInventory.length; 1137 } 1138 1139 /** 1140 * Deals damage to the entity. If its a EntityPlayer then will take damage from the armor first and then health 1141 * second with the reduced value. Args: damageAmount 1142 */ 1143 protected void damageEntity(DamageSource par1DamageSource, int par2) 1144 { 1145 if (!this.isEntityInvulnerable()) 1146 { 1147 par2 = ForgeHooks.onLivingHurt(this, par1DamageSource, par2); 1148 if (par2 <= 0) 1149 { 1150 return; 1151 } 1152 1153 if (!par1DamageSource.isUnblockable() && this.isBlocking()) 1154 { 1155 par2 = 1 + par2 >> 1; 1156 } 1157 1158 par2 = ArmorProperties.ApplyArmor(this, inventory.armorInventory, par1DamageSource, par2); 1159 if (par2 <= 0) 1160 { 1161 return; 1162 } 1163 par2 = this.applyPotionDamageCalculations(par1DamageSource, par2); 1164 this.addExhaustion(par1DamageSource.getHungerDamage()); 1165 this.health -= par2; 1166 } 1167 } 1168 1169 /** 1170 * Displays the furnace GUI for the passed in furnace entity. Args: tileEntityFurnace 1171 */ 1172 public void displayGUIFurnace(TileEntityFurnace par1TileEntityFurnace) {} 1173 1174 /** 1175 * Displays the dipsenser GUI for the passed in dispenser entity. Args: TileEntityDispenser 1176 */ 1177 public void displayGUIDispenser(TileEntityDispenser par1TileEntityDispenser) {} 1178 1179 /** 1180 * Displays the GUI for editing a sign. Args: tileEntitySign 1181 */ 1182 public void displayGUIEditSign(TileEntity par1TileEntity) {} 1183 1184 /** 1185 * Displays the GUI for interacting with a brewing stand. 1186 */ 1187 public void displayGUIBrewingStand(TileEntityBrewingStand par1TileEntityBrewingStand) {} 1188 1189 /** 1190 * Displays the GUI for interacting with a beacon. 1191 */ 1192 public void displayGUIBeacon(TileEntityBeacon par1TileEntityBeacon) {} 1193 1194 public void displayGUIMerchant(IMerchant par1IMerchant) {} 1195 1196 /** 1197 * Displays the GUI for interacting with a book. 1198 */ 1199 public void displayGUIBook(ItemStack par1ItemStack) {} 1200 1201 public boolean interactWith(Entity par1Entity) 1202 { 1203 if (MinecraftForge.EVENT_BUS.post(new EntityInteractEvent(this, par1Entity))) 1204 { 1205 return false; 1206 } 1207 if (par1Entity.interact(this)) 1208 { 1209 return true; 1210 } 1211 else 1212 { 1213 ItemStack var2 = this.getCurrentEquippedItem(); 1214 1215 if (var2 != null && par1Entity instanceof EntityLiving) 1216 { 1217 if (this.capabilities.isCreativeMode) 1218 { 1219 var2 = var2.copy(); 1220 } 1221 1222 if (var2.interactWith((EntityLiving)par1Entity)) 1223 { 1224 if (var2.stackSize <= 0 && !this.capabilities.isCreativeMode) 1225 { 1226 this.destroyCurrentEquippedItem(); 1227 } 1228 1229 return true; 1230 } 1231 } 1232 1233 return false; 1234 } 1235 } 1236 1237 /** 1238 * Returns the currently being used item by the player. 1239 */ 1240 public ItemStack getCurrentEquippedItem() 1241 { 1242 return this.inventory.getCurrentItem(); 1243 } 1244 1245 /** 1246 * Destroys the currently equipped item from the player's inventory. 1247 */ 1248 public void destroyCurrentEquippedItem() 1249 { 1250 ItemStack orig = getCurrentEquippedItem(); 1251 this.inventory.setInventorySlotContents(this.inventory.currentItem, (ItemStack)null); 1252 MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(this, orig)); 1253 } 1254 1255 /** 1256 * Returns the Y Offset of this entity. 1257 */ 1258 public double getYOffset() 1259 { 1260 return (double)(this.yOffset - 0.5F); 1261 } 1262 1263 /** 1264 * Attacks for the player the targeted entity with the currently equipped item. The equipped item has hitEntity 1265 * called on it. Args: targetEntity 1266 */ 1267 public void attackTargetEntityWithCurrentItem(Entity par1Entity) 1268 { 1269 if (MinecraftForge.EVENT_BUS.post(new AttackEntityEvent(this, par1Entity))) 1270 { 1271 return; 1272 } 1273 ItemStack stack = getCurrentEquippedItem(); 1274 if (stack != null && stack.getItem().onLeftClickEntity(stack, this, par1Entity)) 1275 { 1276 return; 1277 } 1278 if (par1Entity.canAttackWithItem()) 1279 { 1280 if (!par1Entity.func_85031_j(this)) 1281 { 1282 int var2 = this.inventory.getDamageVsEntity(par1Entity); 1283 1284 if (this.isPotionActive(Potion.damageBoost)) 1285 { 1286 var2 += 3 << this.getActivePotionEffect(Potion.damageBoost).getAmplifier(); 1287 } 1288 1289 if (this.isPotionActive(Potion.weakness)) 1290 { 1291 var2 -= 2 << this.getActivePotionEffect(Potion.weakness).getAmplifier(); 1292 } 1293 1294 int var3 = 0; 1295 int var4 = 0; 1296 1297 if (par1Entity instanceof EntityLiving) 1298 { 1299 var4 = EnchantmentHelper.getEnchantmentModifierLiving(this, (EntityLiving)par1Entity); 1300 var3 += EnchantmentHelper.getKnockbackModifier(this, (EntityLiving)par1Entity); 1301 } 1302 1303 if (this.isSprinting()) 1304 { 1305 ++var3; 1306 } 1307 1308 if (var2 > 0 || var4 > 0) 1309 { 1310 boolean var5 = this.fallDistance > 0.0F && !this.onGround && !this.isOnLadder() && !this.isInWater() && !this.isPotionActive(Potion.blindness) && this.ridingEntity == null && par1Entity instanceof EntityLiving; 1311 1312 if (var5) 1313 { 1314 var2 += this.rand.nextInt(var2 / 2 + 2); 1315 } 1316 1317 var2 += var4; 1318 boolean var6 = false; 1319 int var7 = EnchantmentHelper.getFireAspectModifier(this); 1320 1321 if (par1Entity instanceof EntityLiving && var7 > 0 && !par1Entity.isBurning()) 1322 { 1323 var6 = true; 1324 par1Entity.setFire(1); 1325 } 1326 1327 boolean var8 = par1Entity.attackEntityFrom(DamageSource.causePlayerDamage(this), var2); 1328 1329 if (var8) 1330 { 1331 if (var3 > 0) 1332 { 1333 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)); 1334 this.motionX *= 0.6D; 1335 this.motionZ *= 0.6D; 1336 this.setSprinting(false); 1337 } 1338 1339 if (var5) 1340 { 1341 this.onCriticalHit(par1Entity); 1342 } 1343 1344 if (var4 > 0) 1345 { 1346 this.onEnchantmentCritical(par1Entity); 1347 } 1348 1349 if (var2 >= 18) 1350 { 1351 this.triggerAchievement(AchievementList.overkill); 1352 } 1353 1354 this.setLastAttackingEntity(par1Entity); 1355 1356 if (par1Entity instanceof EntityLiving) 1357 { 1358 EnchantmentThorns.func_92096_a(this, (EntityLiving)par1Entity, this.rand); 1359 } 1360 } 1361 1362 ItemStack var9 = this.getCurrentEquippedItem(); 1363 1364 if (var9 != null && par1Entity instanceof EntityLiving) 1365 { 1366 var9.hitEntity((EntityLiving)par1Entity, this); 1367 1368 if (var9.stackSize <= 0) 1369 { 1370 this.destroyCurrentEquippedItem(); 1371 } 1372 } 1373 1374 if (par1Entity instanceof EntityLiving) 1375 { 1376 if (par1Entity.isEntityAlive()) 1377 { 1378 this.alertWolves((EntityLiving)par1Entity, true); 1379 } 1380 1381 this.addStat(StatList.damageDealtStat, var2); 1382 1383 if (var7 > 0 && var8) 1384 { 1385 par1Entity.setFire(var7 * 4); 1386 } 1387 else if (var6) 1388 { 1389 par1Entity.extinguish(); 1390 } 1391 } 1392 1393 this.addExhaustion(0.3F); 1394 } 1395 } 1396 } 1397 } 1398 1399 /** 1400 * Called when the player performs a critical hit on the Entity. Args: entity that was hit critically 1401 */ 1402 public void onCriticalHit(Entity par1Entity) {} 1403 1404 public void onEnchantmentCritical(Entity par1Entity) {} 1405 1406 @SideOnly(Side.CLIENT) 1407 public void respawnPlayer() {} 1408 1409 /** 1410 * Will get destroyed next tick. 1411 */ 1412 public void setDead() 1413 { 1414 super.setDead(); 1415 this.inventoryContainer.onCraftGuiClosed(this); 1416 1417 if (this.openContainer != null) 1418 { 1419 this.openContainer.onCraftGuiClosed(this); 1420 } 1421 } 1422 1423 /** 1424 * Checks if this entity is inside of an opaque block 1425 */ 1426 public boolean isEntityInsideOpaqueBlock() 1427 { 1428 return !this.sleeping && super.isEntityInsideOpaqueBlock(); 1429 } 1430 1431 public boolean func_71066_bF() 1432 { 1433 return false; 1434 } 1435 1436 /** 1437 * Attempts to have the player sleep in a bed at the specified location. 1438 */ 1439 public EnumStatus sleepInBedAt(int par1, int par2, int par3) 1440 { 1441 PlayerSleepInBedEvent event = new PlayerSleepInBedEvent(this, par1, par2, par3); 1442 MinecraftForge.EVENT_BUS.post(event); 1443 if (event.result != null) 1444 { 1445 return event.result; 1446 } 1447 if (!this.worldObj.isRemote) 1448 { 1449 if (this.isPlayerSleeping() || !this.isEntityAlive()) 1450 { 1451 return EnumStatus.OTHER_PROBLEM; 1452 } 1453 1454 if (!this.worldObj.provider.isSurfaceWorld()) 1455 { 1456 return EnumStatus.NOT_POSSIBLE_HERE; 1457 } 1458 1459 if (this.worldObj.isDaytime()) 1460 { 1461 return EnumStatus.NOT_POSSIBLE_NOW; 1462 } 1463 1464 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) 1465 { 1466 return EnumStatus.TOO_FAR_AWAY; 1467 } 1468 1469 double var4 = 8.0D; 1470 double var6 = 5.0D; 1471 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)); 1472 1473 if (!var8.isEmpty()) 1474 { 1475 return EnumStatus.NOT_SAFE; 1476 } 1477 } 1478 1479 this.setSize(0.2F, 0.2F); 1480 this.yOffset = 0.2F; 1481 1482 if (this.worldObj.blockExists(par1, par2, par3)) 1483 { 1484 int var9 = this.worldObj.getBlockMetadata(par1, par2, par3); 1485 int var5 = BlockBed.getDirection(var9); 1486 Block block = Block.blocksList[worldObj.getBlockId(par1, par2, par3)]; 1487 if (block != null) 1488 { 1489 var5 = block.getBedDirection(worldObj, par1, par2, par3); 1490 } 1491 float var10 = 0.5F; 1492 float var7 = 0.5F; 1493 1494 switch (var5) 1495 { 1496 case 0: 1497 var7 = 0.9F; 1498 break; 1499 case 1: 1500 var10 = 0.1F; 1501 break; 1502 case 2: 1503 var7 = 0.1F; 1504 break; 1505 case 3: 1506 var10 = 0.9F; 1507 } 1508 1509 this.func_71013_b(var5); 1510 this.setPosition((double)((float)par1 + var10), (double)((float)par2 + 0.9375F), (double)((float)par3 + var7)); 1511 } 1512 else 1513 { 1514 this.setPosition((double)((float)par1 + 0.5F), (double)((float)par2 + 0.9375F), (double)((float)par3 + 0.5F)); 1515 } 1516 1517 this.sleeping = true; 1518 this.sleepTimer = 0; 1519 this.playerLocation = new ChunkCoordinates(par1, par2, par3); 1520 this.motionX = this.motionZ = this.motionY = 0.0D; 1521 1522 if (!this.worldObj.isRemote) 1523 { 1524 this.worldObj.updateAllPlayersSleepingFlag(); 1525 } 1526 1527 return EnumStatus.OK; 1528 } 1529 1530 private void func_71013_b(int par1) 1531 { 1532 this.field_71079_bU = 0.0F; 1533 this.field_71089_bV = 0.0F; 1534 1535 switch (par1) 1536 { 1537 case 0: 1538 this.field_71089_bV = -1.8F; 1539 break; 1540 case 1: 1541 this.field_71079_bU = 1.8F; 1542 break; 1543 case 2: 1544 this.field_71089_bV = 1.8F; 1545 break; 1546 case 3: 1547 this.field_71079_bU = -1.8F; 1548 } 1549 } 1550 1551 /** 1552 * Wake up the player if they're sleeping. 1553 */ 1554 public void wakeUpPlayer(boolean par1, boolean par2, boolean par3) 1555 { 1556 this.setSize(0.6F, 1.8F); 1557 this.resetHeight(); 1558 ChunkCoordinates var4 = this.playerLocation; 1559 ChunkCoordinates var5 = this.playerLocation; 1560 1561 Block block = (var4 == null ? null : Block.blocksList[worldObj.getBlockId(var4.posX, var4.posY, var4.posZ)]); 1562 1563 if (var4 != null && block != null && block.isBed(worldObj, var4.posX, var4.posY, var4.posZ, this)) 1564 { 1565 block.setBedOccupied(this.worldObj, var4.posX, var4.posY, var4.posZ, this, false); 1566 var5 = block.getBedSpawnPosition(worldObj, var4.posX, var4.posY, var4.posZ, this); 1567 1568 if (var5 == null) 1569 { 1570 var5 = new ChunkCoordinates(var4.posX, var4.posY + 1, var4.posZ); 1571 } 1572 1573 this.setPosition((double)((float)var5.posX + 0.5F), (double)((float)var5.posY + this.yOffset + 0.1F), (double)((float)var5.posZ + 0.5F)); 1574 } 1575 1576 this.sleeping = false; 1577 1578 if (!this.worldObj.isRemote && par2) 1579 { 1580 this.worldObj.updateAllPlayersSleepingFlag(); 1581 } 1582 1583 if (par1) 1584 { 1585 this.sleepTimer = 0; 1586 } 1587 else 1588 { 1589 this.sleepTimer = 100; 1590 } 1591 1592 if (par3) 1593 { 1594 this.setSpawnChunk(this.playerLocation, false); 1595 } 1596 } 1597 1598 /** 1599 * Checks if the player is currently in a bed 1600 */ 1601 private boolean isInBed() 1602 { 1603 ChunkCoordinates c = playerLocation; 1604 int blockID = worldObj.getBlockId(c.posX, c.posY, c.posZ); 1605 return Block.blocksList[blockID] != null && Block.blocksList[blockID].isBed(worldObj, c.posX, c.posY, c.posZ, this); 1606 } 1607 1608 /** 1609 * Ensure that a block enabling respawning exists at the specified coordinates and find an empty space nearby to 1610 * spawn. 1611 */ 1612 public static ChunkCoordinates verifyRespawnCoordinates(World par0World, ChunkCoordinates par1ChunkCoordinates, boolean par2) 1613 { 1614 IChunkProvider var3 = par0World.getChunkProvider(); 1615 var3.loadChunk(par1ChunkCoordinates.posX - 3 >> 4, par1ChunkCoordinates.posZ - 3 >> 4); 1616 var3.loadChunk(par1ChunkCoordinates.posX + 3 >> 4, par1ChunkCoordinates.posZ - 3 >> 4); 1617 var3.loadChunk(par1ChunkCoordinates.posX - 3 >> 4, par1ChunkCoordinates.posZ + 3 >> 4); 1618 var3.loadChunk(par1ChunkCoordinates.posX + 3 >> 4, par1ChunkCoordinates.posZ + 3 >> 4); 1619 1620 ChunkCoordinates c = par1ChunkCoordinates; 1621 Block block = Block.blocksList[par0World.getBlockId(c.posX, c.posY, c.posZ)]; 1622 1623 if (block != null && block.isBed(par0World, c.posX, c.posY, c.posZ, null)) 1624 { 1625 ChunkCoordinates var8 = block.getBedSpawnPosition(par0World, c.posX, c.posY, c.posZ, null); 1626 return var8; 1627 } 1628 else 1629 { 1630 Material var4 = par0World.getBlockMaterial(par1ChunkCoordinates.posX, par1ChunkCoordinates.posY, par1ChunkCoordinates.posZ); 1631 Material var5 = par0World.getBlockMaterial(par1ChunkCoordinates.posX, par1ChunkCoordinates.posY + 1, par1ChunkCoordinates.posZ); 1632 boolean var6 = !var4.isSolid() && !var4.isLiquid(); 1633 boolean var7 = !var5.isSolid() && !var5.isLiquid(); 1634 return par2 && var6 && var7 ? par1ChunkCoordinates : null; 1635 } 1636 } 1637 1638 @SideOnly(Side.CLIENT) 1639 1640 /** 1641 * Returns the orientation of the bed in degrees. 1642 */ 1643 public float getBedOrientationInDegrees() 1644 { 1645 if (this.playerLocation != null) 1646 { 1647 int x = playerLocation.posX; 1648 int y = playerLocation.posY; 1649 int z = playerLocation.posZ; 1650 Block block = Block.blocksList[worldObj.getBlockId(x, y, z)]; 1651 int var2 = (block == null ? 0 : block.getBedDirection(worldObj, x, y, z)); 1652 1653 switch (var2) 1654 { 1655 case 0: 1656 return 90.0F; 1657 case 1: 1658 return 0.0F; 1659 case 2: 1660 return 270.0F; 1661 case 3: 1662 return 180.0F; 1663 } 1664 } 1665 1666 return 0.0F; 1667 } 1668 1669 /** 1670 * Returns whether player is sleeping or not 1671 */ 1672 public boolean isPlayerSleeping() 1673 { 1674 return this.sleeping; 1675 } 1676 1677 /** 1678 * Returns whether or not the player is asleep and the screen has fully faded. 1679 */ 1680 public boolean isPlayerFullyAsleep() 1681 { 1682 return this.sleeping && this.sleepTimer >= 100; 1683 } 1684 1685 public int getSleepTimer() 1686 { 1687 return this.sleepTimer; 1688 } 1689 1690 @SideOnly(Side.CLIENT) 1691 protected boolean getHideCape(int par1) 1692 { 1693 return (this.dataWatcher.getWatchableObjectByte(16) & 1 << par1) != 0; 1694 } 1695 1696 protected void setHideCape(int par1, boolean par2) 1697 { 1698 byte var3 = this.dataWatcher.getWatchableObjectByte(16); 1699 1700 if (par2) 1701 { 1702 this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var3 | 1 << par1))); 1703 } 1704 else 1705 { 1706 this.dataWatcher.updateObject(16, Byte.valueOf((byte)(var3 & ~(1 << par1)))); 1707 } 1708 } 1709 1710 /** 1711 * Add a chat message to the player 1712 */ 1713 public void addChatMessage(String par1Str) {} 1714 1715 /** 1716 * Returns the location of the bed the player will respawn at, or null if the player has not slept in a bed. 1717 */ 1718 public ChunkCoordinates getBedLocation() 1719 { 1720 return this.spawnChunk; 1721 } 1722 1723 public boolean isSpawnForced() 1724 { 1725 return this.spawnForced; 1726 } 1727 1728 /** 1729 * Defines a spawn coordinate to player spawn. Used by bed after the player sleep on it. 1730 */ 1731 public void setSpawnChunk(ChunkCoordinates par1ChunkCoordinates, boolean par2) 1732 { 1733 if (par1ChunkCoordinates != null) 1734 { 1735 this.spawnChunk = new ChunkCoordinates(par1ChunkCoordinates); 1736 this.spawnForced = par2; 1737 } 1738 else 1739 { 1740 this.spawnChunk = null; 1741 this.spawnForced = false; 1742 } 1743 } 1744 1745 /** 1746 * Will trigger the specified trigger. 1747 */ 1748 public void triggerAchievement(StatBase par1StatBase) 1749 { 1750 this.addStat(par1StatBase, 1); 1751 } 1752 1753 /** 1754 * Adds a value to a statistic field. 1755 */ 1756 public void addStat(StatBase par1StatBase, int par2) {} 1757 1758 /** 1759 * Causes this entity to do an upwards motion (jumping). 1760 */ 1761 protected void jump() 1762 { 1763 super.jump(); 1764 this.addStat(StatList.jumpStat, 1); 1765 1766 if (this.isSprinting()) 1767 { 1768 this.addExhaustion(0.8F); 1769 } 1770 else 1771 { 1772 this.addExhaustion(0.2F); 1773 } 1774 } 1775 1776 /** 1777 * Moves the entity based on the specified heading. Args: strafe, forward 1778 */ 1779 public void moveEntityWithHeading(float par1, float par2) 1780 { 1781 double var3 = this.posX; 1782 double var5 = this.posY; 1783 double var7 = this.posZ; 1784 1785 if (this.capabilities.isFlying && this.ridingEntity == null) 1786 { 1787 double var9 = this.motionY; 1788 float var11 = this.jumpMovementFactor; 1789 this.jumpMovementFactor = this.capabilities.getFlySpeed(); 1790 super.moveEntityWithHeading(par1, par2); 1791 this.motionY = var9 * 0.6D; 1792 this.jumpMovementFactor = var11; 1793 } 1794 else 1795 { 1796 super.moveEntityWithHeading(par1, par2); 1797 } 1798 1799 this.addMovementStat(this.posX - var3, this.posY - var5, this.posZ - var7); 1800 } 1801 1802 /** 1803 * Adds a value to a movement statistic field - like run, walk, swin or climb. 1804 */ 1805 public void addMovementStat(double par1, double par3, double par5) 1806 { 1807 if (this.ridingEntity == null) 1808 { 1809 int var7; 1810 1811 if (this.isInsideOfMaterial(Material.water)) 1812 { 1813 var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par3 * par3 + par5 * par5) * 100.0F); 1814 1815 if (var7 > 0) 1816 { 1817 this.addStat(StatList.distanceDoveStat, var7); 1818 this.addExhaustion(0.015F * (float)var7 * 0.01F); 1819 } 1820 } 1821 else if (this.isInWater()) 1822 { 1823 var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par5 * par5) * 100.0F); 1824 1825 if (var7 > 0) 1826 { 1827 this.addStat(StatList.distanceSwumStat, var7); 1828 this.addExhaustion(0.015F * (float)var7 * 0.01F); 1829 } 1830 } 1831 else if (this.isOnLadder()) 1832 { 1833 if (par3 > 0.0D) 1834 { 1835 this.addStat(StatList.distanceClimbedStat, (int)Math.round(par3 * 100.0D)); 1836 } 1837 } 1838 else if (this.onGround) 1839 { 1840 var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par5 * par5) * 100.0F); 1841 1842 if (var7 > 0) 1843 { 1844 this.addStat(StatList.distanceWalkedStat, var7); 1845 1846 if (this.isSprinting()) 1847 { 1848 this.addExhaustion(0.099999994F * (float)var7 * 0.01F); 1849 } 1850 else 1851 { 1852 this.addExhaustion(0.01F * (float)var7 * 0.01F); 1853 } 1854 } 1855 } 1856 else 1857 { 1858 var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par5 * par5) * 100.0F); 1859 1860 if (var7 > 25) 1861 { 1862 this.addStat(StatList.distanceFlownStat, var7); 1863 } 1864 } 1865 } 1866 } 1867 1868 /** 1869 * Adds a value to a mounted movement statistic field - by minecart, boat, or pig. 1870 */ 1871 private void addMountedMovementStat(double par1, double par3, double par5) 1872 { 1873 if (this.ridingEntity != null) 1874 { 1875 int var7 = Math.round(MathHelper.sqrt_double(par1 * par1 + par3 * par3 + par5 * par5) * 100.0F); 1876 1877 if (var7 > 0) 1878 { 1879 if (this.ridingEntity instanceof EntityMinecart) 1880 { 1881 this.addStat(StatList.distanceByMinecartStat, var7); 1882 1883 if (this.startMinecartRidingCoordinate == null) 1884 { 1885 this.startMinecartRidingCoordinate = new ChunkCoordinates(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)); 1886 } 1887 else if ((double)this.startMinecartRidingCoordinate.getDistanceSquared(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)) >= 1000000.0D) 1888 { 1889 this.addStat(AchievementList.onARail, 1); 1890 } 1891 } 1892 else if (this.ridingEntity instanceof EntityBoat) 1893 { 1894 this.addStat(StatList.distanceByBoatStat, var7); 1895 } 1896 else if (this.ridingEntity instanceof EntityPig) 1897 { 1898 this.addStat(StatList.distanceByPigStat, var7); 1899 } 1900 } 1901 } 1902 } 1903 1904 /** 1905 * Called when the mob is falling. Calculates and applies fall damage. 1906 */ 1907 protected void fall(float par1) 1908 { 1909 if (!this.capabilities.allowFlying) 1910 { 1911 if (par1 >= 2.0F) 1912 { 1913 this.addStat(StatList.distanceFallenStat, (int)Math.round((double)par1 * 100.0D)); 1914 } 1915 1916 super.fall(par1); 1917 } 1918 } 1919 1920 /** 1921 * This method gets called when the entity kills another one. 1922 */ 1923 public void onKillEntity(EntityLiving par1EntityLiving) 1924 { 1925 if (par1EntityLiving instanceof IMob) 1926 { 1927 this.triggerAchievement(AchievementList.killEnemy); 1928 } 1929 } 1930 1931 /** 1932 * Sets the Entity inside a web block. 1933 */ 1934 public void setInWeb() 1935 { 1936 if (!this.capabilities.isFlying) 1937 { 1938 super.setInWeb(); 1939 } 1940 } 1941 1942 @SideOnly(Side.CLIENT) 1943 1944 /** 1945 * Gets the Icon Index of the item currently held 1946 */ 1947 public int getItemIcon(ItemStack par1ItemStack, int par2) 1948 { 1949 int var3 = super.getItemIcon(par1ItemStack, par2); 1950 1951 if (par1ItemStack.itemID == Item.fishingRod.itemID && this.fishEntity != null) 1952 { 1953 var3 = par1ItemStack.getIconIndex() + 16; 1954 } 1955 else 1956 { 1957 if (par1ItemStack.getItem().requiresMultipleRenderPasses()) 1958 { 1959 return par1ItemStack.getItem().getIconIndex(par1ItemStack, par2); 1960 } 1961 1962 if (this.itemInUse != null && par1ItemStack.itemID == Item.bow.itemID) 1963 { 1964 int var4 = par1ItemStack.getMaxItemUseDuration() - this.itemInUseCount; 1965 1966 if (var4 >= 18) 1967 { 1968 return 133; 1969 } 1970 1971 if (var4 > 13) 1972 { 1973 return 117; 1974 } 1975 1976 if (var4 > 0) 1977 { 1978 return 101; 1979 } 1980 } 1981 var3 = par1ItemStack.getItem().getIconIndex(par1ItemStack, par2, this, itemInUse, itemInUseCount); 1982 } 1983 1984 return var3; 1985 } 1986 1987 public ItemStack getCurrentArmor(int par1) 1988 { 1989 return this.inventory.armorItemInSlot(par1); 1990 } 1991 1992 protected void func_82164_bB() {} 1993 1994 protected void func_82162_bC() {} 1995 1996 /** 1997 * This method increases the player's current amount of experience. 1998 */ 1999 public void addExperience(int par1) 2000 { 2001 this.addScore(par1); 2002 int var2 = Integer.MAX_VALUE - this.experienceTotal; 2003 2004 if (par1 > var2) 2005 { 2006 par1 = var2; 2007 } 2008 2009 this.experience += (float)par1 / (float)this.xpBarCap(); 2010 2011 for (this.experienceTotal += par1; this.experience >= 1.0F; this.experience /= (float)this.xpBarCap()) 2012 { 2013 this.experience = (this.experience - 1.0F) * (float)this.xpBarCap(); 2014 this.addExperienceLevel(1); 2015 } 2016 } 2017 2018 /** 2019 * Add experience levels to this player. 2020 */ 2021 public void addExperienceLevel(int par1) 2022 { 2023 this.experienceLevel += par1; 2024 2025 if (this.experienceLevel < 0) 2026 { 2027 this.experienceLevel = 0; 2028 this.experience = 0.0F; 2029 this.experienceTotal = 0; 2030 } 2031 2032 if (par1 > 0 && this.experienceLevel % 5 == 0 && (float)this.field_82249_h < (float)this.ticksExisted - 100.0F) 2033 { 2034 float var2 = this.experienceLevel > 30 ? 1.0F : (float)this.experienceLevel / 30.0F; 2035 this.worldObj.playSoundAtEntity(this, "random.levelup", var2 * 0.75F, 1.0F); 2036 this.field_82249_h = this.ticksExisted; 2037 } 2038 } 2039 2040 /** 2041 * This method returns the cap amount of experience that the experience bar can hold. With each level, the 2042 * experience cap on the player's experience bar is raised by 10. 2043 */ 2044 public int xpBarCap() 2045 { 2046 return this.experienceLevel >= 30 ? 62 + (this.experienceLevel - 30) * 7 : (this.experienceLevel >= 15 ? 17 + (this.experienceLevel - 15) * 3 : 17); 2047 } 2048 2049 /** 2050 * increases exhaustion level by supplied amount 2051 */ 2052 public void addExhaustion(float par1) 2053 { 2054 if (!this.capabilities.disableDamage) 2055 { 2056 if (!this.worldObj.isRemote) 2057 { 2058 this.foodStats.addExhaustion(par1); 2059 } 2060 } 2061 } 2062 2063 /** 2064 * Returns the player's FoodStats object. 2065 */ 2066 public FoodStats getFoodStats() 2067 { 2068 return this.foodStats; 2069 } 2070 2071 public boolean canEat(boolean par1) 2072 { 2073 return (par1 || this.foodStats.needFood()) && !this.capabilities.disableDamage; 2074 } 2075 2076 /** 2077 * Checks if the player's health is not full and not zero. 2078 */ 2079 public boolean shouldHeal() 2080 { 2081 return this.getHealth() > 0 && this.getHealth() < this.getMaxHealth(); 2082 } 2083 2084 /** 2085 * sets the itemInUse when the use item button is clicked. Args: itemstack, int maxItemUseDuration 2086 */ 2087 public void setItemInUse(ItemStack par1ItemStack, int par2) 2088 { 2089 if (par1ItemStack != this.itemInUse) 2090 { 2091 this.itemInUse = par1ItemStack; 2092 this.itemInUseCount = par2; 2093 2094 if (!this.worldObj.isRemote) 2095 { 2096 this.setEating(true); 2097 } 2098 } 2099 } 2100 2101 /** 2102 * Returns true if the item the player is holding can harvest the block at the given coords. Args: x, y, z. 2103 */ 2104 public boolean canCurrentToolHarvestBlock(int par1, int par2, int par3) 2105 { 2106 if (this.capabilities.allowEdit) 2107 { 2108 return true; 2109 } 2110 else 2111 { 2112 int var4 = this.worldObj.getBlockId(par1, par2, par3); 2113 2114 if (var4 > 0) 2115 { 2116 Block var5 = Block.blocksList[var4]; 2117 2118 if (var5.blockMaterial.func_85157_q()) 2119 { 2120 return true; 2121 } 2122 2123 if (this.getCurrentEquippedItem() != null) 2124 { 2125 ItemStack var6 = this.getCurrentEquippedItem(); 2126 2127 if (var6.canHarvestBlock(var5) || var6.getStrVsBlock(var5) > 1.0F) 2128 { 2129 return true; 2130 } 2131 } 2132 } 2133 2134 return false; 2135 } 2136 } 2137 2138 public boolean canPlayerEdit(int par1, int par2, int par3, int par4, ItemStack par5ItemStack) 2139 { 2140 return this.capabilities.allowEdit ? true : (par5ItemStack != null ? par5ItemStack.func_82835_x() : false); 2141 } 2142 2143 /** 2144 * Get the experience points the entity currently has. 2145 */ 2146 protected int getExperiencePoints(EntityPlayer par1EntityPlayer) 2147 { 2148 if (this.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory")) 2149 { 2150 return 0; 2151 } 2152 else 2153 { 2154 int var2 = this.experienceLevel * 7; 2155 return var2 > 100 ? 100 : var2; 2156 } 2157 } 2158 2159 /** 2160 * Only use is to identify if class is an instance of player for experience dropping 2161 */ 2162 protected boolean isPlayer() 2163 { 2164 return true; 2165 } 2166 2167 /** 2168 * Gets the username of the entity. 2169 */ 2170 public String getEntityName() 2171 { 2172 return this.username; 2173 } 2174 2175 /** 2176 * Copies the values from the given player into this player if boolean par2 is true. Always clones Ender Chest 2177 * Inventory. 2178 */ 2179 public void clonePlayer(EntityPlayer par1EntityPlayer, boolean par2) 2180 { 2181 if (par2) 2182 { 2183 this.inventory.copyInventory(par1EntityPlayer.inventory); 2184 this.health = par1EntityPlayer.health; 2185 this.foodStats = par1EntityPlayer.foodStats; 2186 this.experienceLevel = par1EntityPlayer.experienceLevel; 2187 this.experienceTotal = par1EntityPlayer.experienceTotal; 2188 this.experience = par1EntityPlayer.experience; 2189 this.setScore(par1EntityPlayer.getScore()); 2190 this.field_82152_aq = par1EntityPlayer.field_82152_aq; 2191 } 2192 else if (this.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory")) 2193 { 2194 this.inventory.copyInventory(par1EntityPlayer.inventory); 2195 this.experienceLevel = par1EntityPlayer.experienceLevel; 2196 this.experienceTotal = par1EntityPlayer.experienceTotal; 2197 this.experience = par1EntityPlayer.experience; 2198 this.setScore(par1EntityPlayer.getScore()); 2199 } 2200 2201 this.theInventoryEnderChest = par1EntityPlayer.theInventoryEnderChest; 2202 2203 //Copy over a section of the Entity Data from the old player. 2204 //Allows mods to specify data that persists after players respawn. 2205 NBTTagCompound old = par1EntityPlayer.getEntityData(); 2206 if (old.hasKey(PERSISTED_NBT_TAG)) 2207 { 2208 getEntityData().setCompoundTag(PERSISTED_NBT_TAG, old.getCompoundTag(PERSISTED_NBT_TAG)); 2209 } 2210 } 2211 2212 /** 2213 * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to 2214 * prevent them from trampling crops 2215 */ 2216 protected boolean canTriggerWalking() 2217 { 2218 return !this.capabilities.isFlying; 2219 } 2220 2221 /** 2222 * Sends the player's abilities to the server (if there is one). 2223 */ 2224 public void sendPlayerAbilities() {} 2225 2226 /** 2227 * Sets the player's game mode and sends it to them. 2228 */ 2229 public void setGameType(EnumGameType par1EnumGameType) {} 2230 2231 /** 2232 * Gets the name of this command sender (usually username, but possibly "Rcon") 2233 */ 2234 public String getCommandSenderName() 2235 { 2236 return this.username; 2237 } 2238 2239 public StringTranslate getTranslator() 2240 { 2241 return StringTranslate.getInstance(); 2242 } 2243 2244 /** 2245 * Translates and formats the given string key with the given arguments. 2246 */ 2247 public String translateString(String par1Str, Object ... par2ArrayOfObj) 2248 { 2249 return this.getTranslator().translateKeyFormat(par1Str, par2ArrayOfObj); 2250 } 2251 2252 /** 2253 * Returns the InventoryEnderChest of this player. 2254 */ 2255 public InventoryEnderChest getInventoryEnderChest() 2256 { 2257 return this.theInventoryEnderChest; 2258 } 2259 2260 /** 2261 * 0 = item, 1-n is armor 2262 */ 2263 public ItemStack getCurrentItemOrArmor(int par1) 2264 { 2265 return par1 == 0 ? this.inventory.getCurrentItem() : this.inventory.armorInventory[par1 - 1]; 2266 } 2267 2268 /** 2269 * Returns the item that this EntityLiving is holding, if any. 2270 */ 2271 public ItemStack getHeldItem() 2272 { 2273 return this.inventory.getCurrentItem(); 2274 } 2275 2276 /** 2277 * Sets the held item, or an armor slot. Slot 0 is held item. Slot 1-4 is armor. Params: Item, slot 2278 */ 2279 public void setCurrentItemOrArmor(int par1, ItemStack par2ItemStack) 2280 { 2281 if (par1 == 0) 2282 { 2283 this.inventory.mainInventory[this.inventory.currentItem] = par2ItemStack; 2284 } 2285 else 2286 { 2287 this.inventory.armorInventory[par1 - 1] = par2ItemStack; 2288 } 2289 } 2290 2291 public ItemStack[] getLastActiveItems() 2292 { 2293 return this.inventory.armorInventory; 2294 } 2295 2296 @SideOnly(Side.CLIENT) 2297 public boolean getHideCape() 2298 { 2299 return this.getHideCape(1); 2300 } 2301 2302 public void openGui(Object mod, int modGuiId, World world, int x, int y, int z) 2303 { 2304 FMLNetworkHandler.openGui(this, mod, modGuiId, world, x, y, z); 2305 } 2306}