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