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