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