001 package net.minecraft.src; 002 003 import java.io.ByteArrayOutputStream; 004 import java.io.DataOutputStream; 005 import java.io.IOException; 006 import java.util.ArrayList; 007 import java.util.Iterator; 008 import java.util.LinkedList; 009 import java.util.List; 010 import net.minecraft.server.MinecraftServer; 011 import net.minecraftforge.common.ForgeHooks; 012 import net.minecraftforge.common.MinecraftForge; 013 import net.minecraftforge.event.entity.player.PlayerDropsEvent; 014 015 public class EntityPlayerMP extends EntityPlayer implements ICrafting 016 { 017 private StringTranslate translator = new StringTranslate("en_US"); 018 019 /** set by the NetServerHandler or the ServerConfigurationManager */ 020 public NetServerHandler serverForThisPlayer; 021 022 /** Reference to the MinecraftServer object. */ 023 public MinecraftServer mcServer; 024 025 /** The ItemInWorldManager belonging to this player */ 026 public ItemInWorldManager theItemInWorldManager; 027 028 /** player X position as seen by PlayerManager */ 029 public double managedPosX; 030 031 /** player Z position as seen by PlayerManager */ 032 public double managedPosZ; 033 public final List chunksToLoad = new LinkedList(); 034 035 /** entities added to this list will be packet29'd to the player */ 036 public final List destroyedItemsNetCache = new LinkedList(); 037 038 /** set to getHealth */ 039 private int lastHealth = -99999999; 040 041 /** set to foodStats.GetFoodLevel */ 042 private int lastFoodLevel = -99999999; 043 044 /** set to foodStats.getSaturationLevel() == 0.0F each tick */ 045 private boolean wasHungry = true; 046 047 /** Amount of experience the client was last set to */ 048 private int lastExperience = -99999999; 049 050 /** de-increments onUpdate, attackEntityFrom is ignored if this >0 */ 051 private int initialInvulnerability = 60; 052 053 /** must be between 3>x>15 (strictly between) */ 054 private int renderDistance = 0; 055 private int chatVisibility = 0; 056 private boolean chatColours = true; 057 058 /** 059 * 0 is the held item, 1-4 is armor ; used to detect changes in getCurrentItemOrArmor 060 */ 061 private ItemStack[] lastActiveItems = new ItemStack[] {null, null, null, null, null}; 062 063 /** 064 * The currently in use window ID. Incremented every time a window is opened. 065 */ 066 public int currentWindowId = 0; 067 068 /** 069 * poor mans concurency flag, lets hope the jvm doesn't re-order the setting of this flag wrt the inventory change 070 * on the next line 071 */ 072 public boolean playerInventoryBeingManipulated; 073 public int ping; 074 075 /** set to true when the player is leaving the End after success. */ 076 public boolean playerHasConqueredTheEnd = false; 077 078 public EntityPlayerMP(MinecraftServer par1MinecraftServer, World par2World, String par3Str, ItemInWorldManager par4ItemInWorldManager) 079 { 080 super(par2World); 081 par4ItemInWorldManager.thisPlayerMP = this; 082 this.theItemInWorldManager = par4ItemInWorldManager; 083 this.renderDistance = par1MinecraftServer.getConfigurationManager().getViewDistance(); 084 ChunkCoordinates var5 = par2World.provider.getRandomizedSpawnPoint(); 085 int var6 = var5.posX; 086 int var7 = var5.posZ; 087 int var8 = var5.posY; 088 089 this.setLocationAndAngles((double)var6 + 0.5D, (double)var8, (double)var7 + 0.5D, 0.0F, 0.0F); 090 this.mcServer = par1MinecraftServer; 091 this.stepHeight = 0.0F; 092 this.username = par3Str; 093 this.yOffset = 0.0F; 094 } 095 096 /** 097 * (abstract) Protected helper method to read subclass entity data from NBT. 098 */ 099 public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) 100 { 101 super.readEntityFromNBT(par1NBTTagCompound); 102 103 if (par1NBTTagCompound.hasKey("playerGameType")) 104 { 105 this.theItemInWorldManager.setGameType(EnumGameType.getByID(par1NBTTagCompound.getInteger("playerGameType"))); 106 } 107 } 108 109 /** 110 * (abstract) Protected helper method to write subclass entity data to NBT. 111 */ 112 public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) 113 { 114 super.writeEntityToNBT(par1NBTTagCompound); 115 par1NBTTagCompound.setInteger("playerGameType", this.theItemInWorldManager.getGameType().getID()); 116 } 117 118 /** 119 * Decrease the player level, used to pay levels for enchantments on items at enchanted table. 120 */ 121 public void removeExperience(int par1) 122 { 123 super.removeExperience(par1); 124 this.lastExperience = -1; 125 } 126 127 public void addSelfToInternalCraftingInventory() 128 { 129 this.craftingInventory.addCraftingToCrafters(this); 130 } 131 132 public ItemStack[] getLastActiveItems() 133 { 134 return this.lastActiveItems; 135 } 136 137 /** 138 * sets the players height back to normal after doing things like sleeping and dieing 139 */ 140 protected void resetHeight() 141 { 142 this.yOffset = 0.0F; 143 } 144 145 public float getEyeHeight() 146 { 147 return 1.62F; 148 } 149 150 /** 151 * Called to update the entity's position/logic. 152 */ 153 public void onUpdate() 154 { 155 this.theItemInWorldManager.updateBlockRemoving(); 156 --this.initialInvulnerability; 157 this.craftingInventory.updateCraftingResults(); 158 int var1; 159 160 for (var1 = 0; var1 < 5; ++var1) 161 { 162 ItemStack var2 = this.getCurrentItemOrArmor(var1); 163 164 if (var2 != this.lastActiveItems[var1]) 165 { 166 this.getServerForPlayer().getEntityTracker().sendPacketToAllPlayersTrackingEntity(this, new Packet5PlayerInventory(this.entityId, var1, var2)); 167 this.lastActiveItems[var1] = var2; 168 } 169 } 170 171 if (!this.chunksToLoad.isEmpty()) 172 { 173 ArrayList var6 = new ArrayList(); 174 Iterator var7 = this.chunksToLoad.iterator(); 175 ArrayList var3 = new ArrayList(); 176 177 while (var7.hasNext() && var6.size() < 5) 178 { 179 ChunkCoordIntPair var4 = (ChunkCoordIntPair)var7.next(); 180 var7.remove(); 181 182 if (var4 != null && this.worldObj.blockExists(var4.chunkXPos << 4, 0, var4.chunkZPos << 4)) 183 { 184 var6.add(this.worldObj.getChunkFromChunkCoords(var4.chunkXPos, var4.chunkZPos)); 185 var3.addAll(((WorldServer)this.worldObj).getAllTileEntityInBox(var4.chunkXPos * 16, 0, var4.chunkZPos * 16, var4.chunkXPos * 16 + 16, 256, var4.chunkZPos * 16 + 16)); 186 } 187 } 188 189 if (!var6.isEmpty()) 190 { 191 this.serverForThisPlayer.sendPacketToPlayer(new Packet56MapChunks(var6)); 192 Iterator var10 = var3.iterator(); 193 194 while (var10.hasNext()) 195 { 196 TileEntity var5 = (TileEntity)var10.next(); 197 this.sendTileEntityToPlayer(var5); 198 } 199 } 200 } 201 202 if (!this.destroyedItemsNetCache.isEmpty()) 203 { 204 var1 = Math.min(this.destroyedItemsNetCache.size(), 127); 205 int[] var8 = new int[var1]; 206 Iterator var9 = this.destroyedItemsNetCache.iterator(); 207 int var11 = 0; 208 209 while (var9.hasNext() && var11 < var1) 210 { 211 var8[var11++] = ((Integer)var9.next()).intValue(); 212 var9.remove(); 213 } 214 215 this.serverForThisPlayer.sendPacketToPlayer(new Packet29DestroyEntity(var8)); 216 } 217 } 218 219 public void onUpdateEntity() 220 { 221 super.onUpdate(); 222 223 for (int var1 = 0; var1 < this.inventory.getSizeInventory(); ++var1) 224 { 225 ItemStack var2 = this.inventory.getStackInSlot(var1); 226 227 if (var2 != null && Item.itemsList[var2.itemID].isMap() && this.serverForThisPlayer.packetSize() <= 2) 228 { 229 Packet var3 = ((ItemMapBase)Item.itemsList[var2.itemID]).createMapDataPacket(var2, this.worldObj, this); 230 231 if (var3 != null) 232 { 233 this.serverForThisPlayer.sendPacketToPlayer(var3); 234 } 235 } 236 } 237 238 if (this.inPortal) 239 { 240 if (this.mcServer.getAllowNether()) 241 { 242 if (this.craftingInventory != this.inventorySlots) 243 { 244 this.closeScreen(); 245 } 246 247 if (this.ridingEntity != null) 248 { 249 this.mountEntity(this.ridingEntity); 250 } 251 else 252 { 253 this.timeInPortal += 0.0125F; 254 255 if (this.timeInPortal >= 1.0F) 256 { 257 this.timeInPortal = 1.0F; 258 this.timeUntilPortal = 10; 259 boolean var4 = false; 260 byte var5; 261 262 if (this.dimension == -1) 263 { 264 var5 = 0; 265 } 266 else 267 { 268 var5 = -1; 269 } 270 271 this.mcServer.getConfigurationManager().transferPlayerToDimension(this, var5); 272 this.lastExperience = -1; 273 this.lastHealth = -1; 274 this.lastFoodLevel = -1; 275 this.triggerAchievement(AchievementList.portal); 276 } 277 } 278 279 this.inPortal = false; 280 } 281 } 282 else 283 { 284 if (this.timeInPortal > 0.0F) 285 { 286 this.timeInPortal -= 0.05F; 287 } 288 289 if (this.timeInPortal < 0.0F) 290 { 291 this.timeInPortal = 0.0F; 292 } 293 } 294 295 if (this.timeUntilPortal > 0) 296 { 297 --this.timeUntilPortal; 298 } 299 300 if (this.getHealth() != this.lastHealth || this.lastFoodLevel != this.foodStats.getFoodLevel() || this.foodStats.getSaturationLevel() == 0.0F != this.wasHungry) 301 { 302 this.serverForThisPlayer.sendPacketToPlayer(new Packet8UpdateHealth(this.getHealth(), this.foodStats.getFoodLevel(), this.foodStats.getSaturationLevel())); 303 this.lastHealth = this.getHealth(); 304 this.lastFoodLevel = this.foodStats.getFoodLevel(); 305 this.wasHungry = this.foodStats.getSaturationLevel() == 0.0F; 306 } 307 308 if (this.experienceTotal != this.lastExperience) 309 { 310 this.lastExperience = this.experienceTotal; 311 this.serverForThisPlayer.sendPacketToPlayer(new Packet43Experience(this.experience, this.experienceTotal, this.experienceLevel)); 312 } 313 } 314 315 /** 316 * 0 = item, 1-n is armor 317 */ 318 public ItemStack getCurrentItemOrArmor(int par1) 319 { 320 return par1 == 0 ? this.inventory.getCurrentItem() : this.inventory.armorInventory[par1 - 1]; 321 } 322 323 /** 324 * Called when the mob's health reaches 0. 325 */ 326 public void onDeath(DamageSource par1DamageSource) 327 { 328 if (ForgeHooks.onLivingDeath(this, par1DamageSource)) 329 { 330 return; 331 } 332 333 this.mcServer.getConfigurationManager().sendPacketToAllPlayers(new Packet3Chat(par1DamageSource.getDeathMessage(this))); 334 335 captureDrops = true; 336 capturedDrops.clear(); 337 338 this.inventory.dropAllItems(); 339 340 captureDrops = false; 341 PlayerDropsEvent event = new PlayerDropsEvent(this, par1DamageSource, capturedDrops, recentlyHit > 0); 342 if (!MinecraftForge.EVENT_BUS.post(event)) 343 { 344 for (EntityItem item : capturedDrops) 345 { 346 joinEntityItemWithWorld(item); 347 } 348 } 349 } 350 351 /** 352 * Called when the entity is attacked. 353 */ 354 public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) 355 { 356 if (this.initialInvulnerability > 0) 357 { 358 return false; 359 } 360 else 361 { 362 if (!this.mcServer.isPVPEnabled() && par1DamageSource instanceof EntityDamageSource) 363 { 364 Entity var3 = par1DamageSource.getEntity(); 365 366 if (var3 instanceof EntityPlayer) 367 { 368 return false; 369 } 370 371 if (var3 instanceof EntityArrow) 372 { 373 EntityArrow var4 = (EntityArrow)var3; 374 375 if (var4.shootingEntity instanceof EntityPlayer) 376 { 377 return false; 378 } 379 } 380 } 381 382 return super.attackEntityFrom(par1DamageSource, par2); 383 } 384 } 385 386 /** 387 * returns if pvp is enabled or not 388 */ 389 protected boolean isPVPEnabled() 390 { 391 return this.mcServer.isPVPEnabled(); 392 } 393 394 public void travelToTheEnd(int par1) 395 { 396 if (this.dimension == 1 && par1 == 1) 397 { 398 this.triggerAchievement(AchievementList.theEnd2); 399 this.worldObj.setEntityDead(this); 400 this.playerHasConqueredTheEnd = true; 401 this.serverForThisPlayer.sendPacketToPlayer(new Packet70GameEvent(4, 0)); 402 } 403 else 404 { 405 this.triggerAchievement(AchievementList.theEnd); 406 ChunkCoordinates var2 = this.mcServer.worldServerForDimension(par1).getEntrancePortalLocation(); 407 408 if (var2 != null) 409 { 410 this.serverForThisPlayer.setPlayerLocation((double)var2.posX, (double)var2.posY, (double)var2.posZ, 0.0F, 0.0F); 411 } 412 413 this.mcServer.getConfigurationManager().transferPlayerToDimension(this, 1); 414 this.lastExperience = -1; 415 this.lastHealth = -1; 416 this.lastFoodLevel = -1; 417 } 418 } 419 420 /** 421 * called from onUpdate for all tileEntity in specific chunks 422 */ 423 private void sendTileEntityToPlayer(TileEntity par1TileEntity) 424 { 425 if (par1TileEntity != null) 426 { 427 Packet var2 = par1TileEntity.getAuxillaryInfoPacket(); 428 429 if (var2 != null) 430 { 431 this.serverForThisPlayer.sendPacketToPlayer(var2); 432 } 433 } 434 } 435 436 /** 437 * Called whenever an item is picked up from walking over it. Args: pickedUpEntity, stackSize 438 */ 439 public void onItemPickup(Entity par1Entity, int par2) 440 { 441 if (!par1Entity.isDead) 442 { 443 EntityTracker var3 = this.getServerForPlayer().getEntityTracker(); 444 445 if (par1Entity instanceof EntityItem) 446 { 447 var3.sendPacketToAllPlayersTrackingEntity(par1Entity, new Packet22Collect(par1Entity.entityId, this.entityId)); 448 } 449 450 if (par1Entity instanceof EntityArrow) 451 { 452 var3.sendPacketToAllPlayersTrackingEntity(par1Entity, new Packet22Collect(par1Entity.entityId, this.entityId)); 453 } 454 455 if (par1Entity instanceof EntityXPOrb) 456 { 457 var3.sendPacketToAllPlayersTrackingEntity(par1Entity, new Packet22Collect(par1Entity.entityId, this.entityId)); 458 } 459 } 460 461 super.onItemPickup(par1Entity, par2); 462 this.craftingInventory.updateCraftingResults(); 463 } 464 465 /** 466 * Swings the item the player is holding. 467 */ 468 public void swingItem() 469 { 470 if (!this.isSwinging) 471 { 472 this.swingProgressInt = -1; 473 this.isSwinging = true; 474 this.getServerForPlayer().getEntityTracker().sendPacketToAllPlayersTrackingEntity(this, new Packet18Animation(this, 1)); 475 } 476 } 477 478 /** 479 * Attempts to have the player sleep in a bed at the specified location. 480 */ 481 public EnumStatus sleepInBedAt(int par1, int par2, int par3) 482 { 483 EnumStatus var4 = super.sleepInBedAt(par1, par2, par3); 484 485 if (var4 == EnumStatus.OK) 486 { 487 Packet17Sleep var5 = new Packet17Sleep(this, 0, par1, par2, par3); 488 this.getServerForPlayer().getEntityTracker().sendPacketToAllPlayersTrackingEntity(this, var5); 489 this.serverForThisPlayer.setPlayerLocation(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch); 490 this.serverForThisPlayer.sendPacketToPlayer(var5); 491 } 492 493 return var4; 494 } 495 496 /** 497 * Wake up the player if they're sleeping. 498 */ 499 public void wakeUpPlayer(boolean par1, boolean par2, boolean par3) 500 { 501 if (this.isPlayerSleeping()) 502 { 503 this.getServerForPlayer().getEntityTracker().sendPacketToAllAssociatedPlayers(this, new Packet18Animation(this, 3)); 504 } 505 506 super.wakeUpPlayer(par1, par2, par3); 507 508 if (this.serverForThisPlayer != null) 509 { 510 this.serverForThisPlayer.setPlayerLocation(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch); 511 } 512 } 513 514 /** 515 * Called when a player mounts an entity. e.g. mounts a pig, mounts a boat. 516 */ 517 public void mountEntity(Entity par1Entity) 518 { 519 super.mountEntity(par1Entity); 520 this.serverForThisPlayer.sendPacketToPlayer(new Packet39AttachEntity(this, this.ridingEntity)); 521 this.serverForThisPlayer.setPlayerLocation(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch); 522 } 523 524 /** 525 * Takes in the distance the entity has fallen this tick and whether its on the ground to update the fall distance 526 * and deal fall damage if landing on the ground. Args: distanceFallenThisTick, onGround 527 */ 528 protected void updateFallState(double par1, boolean par3) {} 529 530 /** 531 * likeUpdateFallState, but called from updateFlyingState, rather than moveEntity 532 */ 533 public void updateFlyingState(double par1, boolean par3) 534 { 535 super.updateFallState(par1, par3); 536 } 537 538 public void incrementWindowID() 539 { 540 this.currentWindowId = this.currentWindowId % 100 + 1; 541 } 542 543 /** 544 * Displays the crafting GUI for a workbench. 545 */ 546 public void displayGUIWorkbench(int par1, int par2, int par3) 547 { 548 this.incrementWindowID(); 549 this.serverForThisPlayer.sendPacketToPlayer(new Packet100OpenWindow(this.currentWindowId, 1, "Crafting", 9)); 550 this.craftingInventory = new ContainerWorkbench(this.inventory, this.worldObj, par1, par2, par3); 551 this.craftingInventory.windowId = this.currentWindowId; 552 this.craftingInventory.addCraftingToCrafters(this); 553 } 554 555 public void displayGUIEnchantment(int par1, int par2, int par3) 556 { 557 this.incrementWindowID(); 558 this.serverForThisPlayer.sendPacketToPlayer(new Packet100OpenWindow(this.currentWindowId, 4, "Enchanting", 9)); 559 this.craftingInventory = new ContainerEnchantment(this.inventory, this.worldObj, par1, par2, par3); 560 this.craftingInventory.windowId = this.currentWindowId; 561 this.craftingInventory.addCraftingToCrafters(this); 562 } 563 564 /** 565 * Displays the GUI for interacting with a chest inventory. Args: chestInventory 566 */ 567 public void displayGUIChest(IInventory par1IInventory) 568 { 569 if (this.craftingInventory != this.inventorySlots) 570 { 571 this.closeScreen(); 572 } 573 574 this.incrementWindowID(); 575 this.serverForThisPlayer.sendPacketToPlayer(new Packet100OpenWindow(this.currentWindowId, 0, par1IInventory.getInvName(), par1IInventory.getSizeInventory())); 576 this.craftingInventory = new ContainerChest(this.inventory, par1IInventory); 577 this.craftingInventory.windowId = this.currentWindowId; 578 this.craftingInventory.addCraftingToCrafters(this); 579 } 580 581 /** 582 * Displays the furnace GUI for the passed in furnace entity. Args: tileEntityFurnace 583 */ 584 public void displayGUIFurnace(TileEntityFurnace par1TileEntityFurnace) 585 { 586 this.incrementWindowID(); 587 this.serverForThisPlayer.sendPacketToPlayer(new Packet100OpenWindow(this.currentWindowId, 2, par1TileEntityFurnace.getInvName(), par1TileEntityFurnace.getSizeInventory())); 588 this.craftingInventory = new ContainerFurnace(this.inventory, par1TileEntityFurnace); 589 this.craftingInventory.windowId = this.currentWindowId; 590 this.craftingInventory.addCraftingToCrafters(this); 591 } 592 593 /** 594 * Displays the dipsenser GUI for the passed in dispenser entity. Args: TileEntityDispenser 595 */ 596 public void displayGUIDispenser(TileEntityDispenser par1TileEntityDispenser) 597 { 598 this.incrementWindowID(); 599 this.serverForThisPlayer.sendPacketToPlayer(new Packet100OpenWindow(this.currentWindowId, 3, par1TileEntityDispenser.getInvName(), par1TileEntityDispenser.getSizeInventory())); 600 this.craftingInventory = new ContainerDispenser(this.inventory, par1TileEntityDispenser); 601 this.craftingInventory.windowId = this.currentWindowId; 602 this.craftingInventory.addCraftingToCrafters(this); 603 } 604 605 /** 606 * Displays the GUI for interacting with a brewing stand. 607 */ 608 public void displayGUIBrewingStand(TileEntityBrewingStand par1TileEntityBrewingStand) 609 { 610 this.incrementWindowID(); 611 this.serverForThisPlayer.sendPacketToPlayer(new Packet100OpenWindow(this.currentWindowId, 5, par1TileEntityBrewingStand.getInvName(), par1TileEntityBrewingStand.getSizeInventory())); 612 this.craftingInventory = new ContainerBrewingStand(this.inventory, par1TileEntityBrewingStand); 613 this.craftingInventory.windowId = this.currentWindowId; 614 this.craftingInventory.addCraftingToCrafters(this); 615 } 616 617 public void displayGUIMerchant(IMerchant par1IMerchant) 618 { 619 this.incrementWindowID(); 620 this.craftingInventory = new ContainerMerchant(this.inventory, par1IMerchant, this.worldObj); 621 this.craftingInventory.windowId = this.currentWindowId; 622 this.craftingInventory.addCraftingToCrafters(this); 623 InventoryMerchant var2 = ((ContainerMerchant)this.craftingInventory).getMerchantInventory(); 624 this.serverForThisPlayer.sendPacketToPlayer(new Packet100OpenWindow(this.currentWindowId, 6, var2.getInvName(), var2.getSizeInventory())); 625 MerchantRecipeList var3 = par1IMerchant.getRecipes(this); 626 627 if (var3 != null) 628 { 629 try 630 { 631 ByteArrayOutputStream var4 = new ByteArrayOutputStream(); 632 DataOutputStream var5 = new DataOutputStream(var4); 633 var5.writeInt(this.currentWindowId); 634 var3.writeRecipiesToStream(var5); 635 this.serverForThisPlayer.sendPacketToPlayer(new Packet250CustomPayload("MC|TrList", var4.toByteArray())); 636 } 637 catch (IOException var6) 638 { 639 var6.printStackTrace(); 640 } 641 } 642 } 643 644 /** 645 * inform the player of a change in a single slot 646 */ 647 public void updateCraftingInventorySlot(Container par1Container, int par2, ItemStack par3ItemStack) 648 { 649 if (!(par1Container.getSlot(par2) instanceof SlotCrafting)) 650 { 651 if (!this.playerInventoryBeingManipulated) 652 { 653 this.serverForThisPlayer.sendPacketToPlayer(new Packet103SetSlot(par1Container.windowId, par2, par3ItemStack)); 654 } 655 } 656 } 657 658 public void sendContainerToPlayer(Container par1Container) 659 { 660 this.sendContainerAndContentsToPlayer(par1Container, par1Container.getInventory()); 661 } 662 663 public void sendContainerAndContentsToPlayer(Container par1Container, List par2List) 664 { 665 this.serverForThisPlayer.sendPacketToPlayer(new Packet104WindowItems(par1Container.windowId, par2List)); 666 this.serverForThisPlayer.sendPacketToPlayer(new Packet103SetSlot(-1, -1, this.inventory.getItemStack())); 667 } 668 669 /** 670 * send information about the crafting inventory to the client(currently only for furnace times) 671 */ 672 public void updateCraftingInventoryInfo(Container par1Container, int par2, int par3) 673 { 674 this.serverForThisPlayer.sendPacketToPlayer(new Packet105UpdateProgressbar(par1Container.windowId, par2, par3)); 675 } 676 677 /** 678 * sets current screen to null (used on escape buttons of GUIs) 679 */ 680 public void closeScreen() 681 { 682 this.serverForThisPlayer.sendPacketToPlayer(new Packet101CloseWindow(this.craftingInventory.windowId)); 683 this.closeInventory(); 684 } 685 686 public void sendInventoryToPlayer() 687 { 688 if (!this.playerInventoryBeingManipulated) 689 { 690 this.serverForThisPlayer.sendPacketToPlayer(new Packet103SetSlot(-1, -1, this.inventory.getItemStack())); 691 } 692 } 693 694 public void closeInventory() 695 { 696 this.craftingInventory.onCraftGuiClosed(this); 697 this.craftingInventory = this.inventorySlots; 698 } 699 700 /** 701 * Adds a value to a statistic field. 702 */ 703 public void addStat(StatBase par1StatBase, int par2) 704 { 705 if (par1StatBase != null) 706 { 707 if (!par1StatBase.isIndependent) 708 { 709 while (par2 > 100) 710 { 711 this.serverForThisPlayer.sendPacketToPlayer(new Packet200Statistic(par1StatBase.statId, 100)); 712 par2 -= 100; 713 } 714 715 this.serverForThisPlayer.sendPacketToPlayer(new Packet200Statistic(par1StatBase.statId, par2)); 716 } 717 } 718 } 719 720 public void mountEntityAndWakeUp() 721 { 722 if (this.ridingEntity != null) 723 { 724 this.mountEntity(this.ridingEntity); 725 } 726 727 if (this.riddenByEntity != null) 728 { 729 this.riddenByEntity.mountEntity(this); 730 } 731 732 if (this.sleeping) 733 { 734 this.wakeUpPlayer(true, false, false); 735 } 736 } 737 738 /** 739 * this function is called when a players inventory is sent to him, lastHealth is updated on any dimension 740 * transitions, then reset. 741 */ 742 public void setPlayerHealthUpdated() 743 { 744 this.lastHealth = -99999999; 745 } 746 747 /** 748 * Add a chat message to the player 749 */ 750 public void addChatMessage(String par1Str) 751 { 752 StringTranslate var2 = StringTranslate.getInstance(); 753 String var3 = var2.translateKey(par1Str); 754 this.serverForThisPlayer.sendPacketToPlayer(new Packet3Chat(var3)); 755 } 756 757 /** 758 * Used for when item use count runs out, ie: eating completed 759 */ 760 protected void onItemUseFinish() 761 { 762 this.serverForThisPlayer.sendPacketToPlayer(new Packet38EntityStatus(this.entityId, (byte)9)); 763 super.onItemUseFinish(); 764 } 765 766 /** 767 * sets the itemInUse when the use item button is clicked. Args: itemstack, int maxItemUseDuration 768 */ 769 public void setItemInUse(ItemStack par1ItemStack, int par2) 770 { 771 super.setItemInUse(par1ItemStack, par2); 772 773 if (par1ItemStack != null && par1ItemStack.getItem() != null && par1ItemStack.getItem().getItemUseAction(par1ItemStack) == EnumAction.eat) 774 { 775 this.getServerForPlayer().getEntityTracker().sendPacketToAllAssociatedPlayers(this, new Packet18Animation(this, 5)); 776 } 777 } 778 779 protected void onNewPotionEffect(PotionEffect par1PotionEffect) 780 { 781 super.onNewPotionEffect(par1PotionEffect); 782 this.serverForThisPlayer.sendPacketToPlayer(new Packet41EntityEffect(this.entityId, par1PotionEffect)); 783 } 784 785 protected void onChangedPotionEffect(PotionEffect par1PotionEffect) 786 { 787 super.onChangedPotionEffect(par1PotionEffect); 788 this.serverForThisPlayer.sendPacketToPlayer(new Packet41EntityEffect(this.entityId, par1PotionEffect)); 789 } 790 791 protected void onFinishedPotionEffect(PotionEffect par1PotionEffect) 792 { 793 super.onFinishedPotionEffect(par1PotionEffect); 794 this.serverForThisPlayer.sendPacketToPlayer(new Packet42RemoveEntityEffect(this.entityId, par1PotionEffect)); 795 } 796 797 /** 798 * Move the entity to the coordinates informed, but keep yaw/pitch values. 799 */ 800 public void setPositionAndUpdate(double par1, double par3, double par5) 801 { 802 this.serverForThisPlayer.setPlayerLocation(par1, par3, par5, this.rotationYaw, this.rotationPitch); 803 } 804 805 /** 806 * Called when the player performs a critical hit on the Entity. Args: entity that was hit critically 807 */ 808 public void onCriticalHit(Entity par1Entity) 809 { 810 this.getServerForPlayer().getEntityTracker().sendPacketToAllAssociatedPlayers(this, new Packet18Animation(par1Entity, 6)); 811 } 812 813 public void onEnchantmentCritical(Entity par1Entity) 814 { 815 this.getServerForPlayer().getEntityTracker().sendPacketToAllAssociatedPlayers(this, new Packet18Animation(par1Entity, 7)); 816 } 817 818 /** 819 * Sends the player's abilities to the server (if there is one). 820 */ 821 public void sendPlayerAbilities() 822 { 823 if (this.serverForThisPlayer != null) 824 { 825 this.serverForThisPlayer.sendPacketToPlayer(new Packet202PlayerAbilities(this.capabilities)); 826 } 827 } 828 829 public WorldServer getServerForPlayer() 830 { 831 return (WorldServer)this.worldObj; 832 } 833 834 public void sendGameTypeToPlayer(EnumGameType par1EnumGameType) 835 { 836 this.theItemInWorldManager.setGameType(par1EnumGameType); 837 this.serverForThisPlayer.sendPacketToPlayer(new Packet70GameEvent(3, par1EnumGameType.getID())); 838 } 839 840 public void sendChatToPlayer(String par1Str) 841 { 842 this.serverForThisPlayer.sendPacketToPlayer(new Packet3Chat(par1Str)); 843 } 844 845 /** 846 * Returns true if the command sender is allowed to use the given command. 847 */ 848 public boolean canCommandSenderUseCommand(String par1Str) 849 { 850 return "seed".equals(par1Str) && !this.mcServer.isDedicatedServer() ? true : (!"tell".equals(par1Str) && !"help".equals(par1Str) && !"me".equals(par1Str) ? this.mcServer.getConfigurationManager().areCommandsAllowed(this.username) : true); 851 } 852 853 public String func_71114_r() 854 { 855 String var1 = this.serverForThisPlayer.theNetworkManager.getSocketAddress().toString(); 856 var1 = var1.substring(var1.indexOf("/") + 1); 857 var1 = var1.substring(0, var1.indexOf(":")); 858 return var1; 859 } 860 861 public void updateClientInfo(Packet204ClientInfo par1Packet204ClientInfo) 862 { 863 if (this.translator.getLanguageList().containsKey(par1Packet204ClientInfo.getLanguage())) 864 { 865 this.translator.setLanguage(par1Packet204ClientInfo.getLanguage()); 866 } 867 868 int var2 = 256 >> par1Packet204ClientInfo.getRenderDistance(); 869 870 if (var2 > 3 && var2 < 15) 871 { 872 this.renderDistance = var2; 873 } 874 875 this.chatVisibility = par1Packet204ClientInfo.getChatVisibility(); 876 this.chatColours = par1Packet204ClientInfo.getChatColours(); 877 878 if (this.mcServer.isSinglePlayer() && this.mcServer.getServerOwner().equals(this.username)) 879 { 880 this.mcServer.setDifficultyForAllDimensions(par1Packet204ClientInfo.getDifficulty()); 881 } 882 } 883 884 public StringTranslate getTranslator() 885 { 886 return this.translator; 887 } 888 889 public int getChatVisibility() 890 { 891 return this.chatVisibility; 892 } 893 894 /** 895 * on recieving this message the client (if permission is given) will download the requested textures 896 */ 897 public void requestTexturePackLoad(String par1Str, int par2) 898 { 899 String var3 = par1Str + "\u0000" + par2; 900 this.serverForThisPlayer.sendPacketToPlayer(new Packet250CustomPayload("MC|TPack", var3.getBytes())); 901 } 902 }