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