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