001package net.minecraft.client.entity; 002 003import cpw.mods.fml.relauncher.Side; 004import cpw.mods.fml.relauncher.SideOnly; 005import net.minecraft.client.Minecraft; 006import net.minecraft.client.multiplayer.NetClientHandler; 007import net.minecraft.entity.item.EntityItem; 008import net.minecraft.item.ItemStack; 009import net.minecraft.network.packet.Packet101CloseWindow; 010import net.minecraft.network.packet.Packet10Flying; 011import net.minecraft.network.packet.Packet11PlayerPosition; 012import net.minecraft.network.packet.Packet12PlayerLook; 013import net.minecraft.network.packet.Packet13PlayerLookMove; 014import net.minecraft.network.packet.Packet14BlockDig; 015import net.minecraft.network.packet.Packet18Animation; 016import net.minecraft.network.packet.Packet19EntityAction; 017import net.minecraft.network.packet.Packet202PlayerAbilities; 018import net.minecraft.network.packet.Packet205ClientCommand; 019import net.minecraft.network.packet.Packet3Chat; 020import net.minecraft.stats.StatBase; 021import net.minecraft.util.DamageSource; 022import net.minecraft.util.MathHelper; 023import net.minecraft.util.Session; 024import net.minecraft.world.World; 025 026@SideOnly(Side.CLIENT) 027public class EntityClientPlayerMP extends EntityPlayerSP 028{ 029 public NetClientHandler sendQueue; 030 private double oldPosX; 031 032 /** Old Minimum Y of the bounding box */ 033 private double oldMinY; 034 private double oldPosY; 035 private double oldPosZ; 036 private float oldRotationYaw; 037 private float oldRotationPitch; 038 039 /** Check if was on ground last update */ 040 private boolean wasOnGround = false; 041 042 /** should the player stop sneaking? */ 043 private boolean shouldStopSneaking = false; 044 private boolean wasSneaking = false; 045 private int field_71168_co = 0; 046 047 /** has the client player's health been set? */ 048 private boolean hasSetHealth = false; 049 050 public EntityClientPlayerMP(Minecraft par1Minecraft, World par2World, Session par3Session, NetClientHandler par4NetClientHandler) 051 { 052 super(par1Minecraft, par2World, par3Session, 0); 053 this.sendQueue = par4NetClientHandler; 054 } 055 056 /** 057 * Called when the entity is attacked. 058 */ 059 public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) 060 { 061 return false; 062 } 063 064 /** 065 * Heal living entity (param: amount of half-hearts) 066 */ 067 public void heal(int par1) {} 068 069 /** 070 * Called to update the entity's position/logic. 071 */ 072 public void onUpdate() 073 { 074 if (this.worldObj.blockExists(MathHelper.floor_double(this.posX), 0, MathHelper.floor_double(this.posZ))) 075 { 076 super.onUpdate(); 077 this.sendMotionUpdates(); 078 } 079 } 080 081 /** 082 * Send updated motion and position information to the server 083 */ 084 public void sendMotionUpdates() 085 { 086 boolean flag = this.isSprinting(); 087 088 if (flag != this.wasSneaking) 089 { 090 if (flag) 091 { 092 this.sendQueue.addToSendQueue(new Packet19EntityAction(this, 4)); 093 } 094 else 095 { 096 this.sendQueue.addToSendQueue(new Packet19EntityAction(this, 5)); 097 } 098 099 this.wasSneaking = flag; 100 } 101 102 boolean flag1 = this.isSneaking(); 103 104 if (flag1 != this.shouldStopSneaking) 105 { 106 if (flag1) 107 { 108 this.sendQueue.addToSendQueue(new Packet19EntityAction(this, 1)); 109 } 110 else 111 { 112 this.sendQueue.addToSendQueue(new Packet19EntityAction(this, 2)); 113 } 114 115 this.shouldStopSneaking = flag1; 116 } 117 118 double d0 = this.posX - this.oldPosX; 119 double d1 = this.boundingBox.minY - this.oldMinY; 120 double d2 = this.posZ - this.oldPosZ; 121 double d3 = (double)(this.rotationYaw - this.oldRotationYaw); 122 double d4 = (double)(this.rotationPitch - this.oldRotationPitch); 123 boolean flag2 = d0 * d0 + d1 * d1 + d2 * d2 > 9.0E-4D || this.field_71168_co >= 20; 124 boolean flag3 = d3 != 0.0D || d4 != 0.0D; 125 126 if (this.ridingEntity != null) 127 { 128 this.sendQueue.addToSendQueue(new Packet13PlayerLookMove(this.motionX, -999.0D, -999.0D, this.motionZ, this.rotationYaw, this.rotationPitch, this.onGround)); 129 flag2 = false; 130 } 131 else if (flag2 && flag3) 132 { 133 this.sendQueue.addToSendQueue(new Packet13PlayerLookMove(this.posX, this.boundingBox.minY, this.posY, this.posZ, this.rotationYaw, this.rotationPitch, this.onGround)); 134 } 135 else if (flag2) 136 { 137 this.sendQueue.addToSendQueue(new Packet11PlayerPosition(this.posX, this.boundingBox.minY, this.posY, this.posZ, this.onGround)); 138 } 139 else if (flag3) 140 { 141 this.sendQueue.addToSendQueue(new Packet12PlayerLook(this.rotationYaw, this.rotationPitch, this.onGround)); 142 } 143 else 144 { 145 this.sendQueue.addToSendQueue(new Packet10Flying(this.onGround)); 146 } 147 148 ++this.field_71168_co; 149 this.wasOnGround = this.onGround; 150 151 if (flag2) 152 { 153 this.oldPosX = this.posX; 154 this.oldMinY = this.boundingBox.minY; 155 this.oldPosY = this.posY; 156 this.oldPosZ = this.posZ; 157 this.field_71168_co = 0; 158 } 159 160 if (flag3) 161 { 162 this.oldRotationYaw = this.rotationYaw; 163 this.oldRotationPitch = this.rotationPitch; 164 } 165 } 166 167 /** 168 * Called when player presses the drop item key 169 */ 170 public EntityItem dropOneItem(boolean par1) 171 { 172 int i = par1 ? 3 : 4; 173 this.sendQueue.addToSendQueue(new Packet14BlockDig(i, 0, 0, 0, 0)); 174 return null; 175 } 176 177 /** 178 * Joins the passed in entity item with the world. Args: entityItem 179 */ 180 public void joinEntityItemWithWorld(EntityItem par1EntityItem) {} 181 182 /** 183 * Sends a chat message from the player. Args: chatMessage 184 */ 185 public void sendChatMessage(String par1Str) 186 { 187 this.sendQueue.addToSendQueue(new Packet3Chat(par1Str)); 188 } 189 190 /** 191 * Swings the item the player is holding. 192 */ 193 public void swingItem() 194 { 195 super.swingItem(); 196 this.sendQueue.addToSendQueue(new Packet18Animation(this, 1)); 197 } 198 199 public void respawnPlayer() 200 { 201 this.sendQueue.addToSendQueue(new Packet205ClientCommand(1)); 202 } 203 204 /** 205 * Deals damage to the entity. If its a EntityPlayer then will take damage from the armor first and then health 206 * second with the reduced value. Args: damageAmount 207 */ 208 protected void damageEntity(DamageSource par1DamageSource, int par2) 209 { 210 if (!this.isEntityInvulnerable()) 211 { 212 this.setEntityHealth(this.getHealth() - par2); 213 } 214 } 215 216 /** 217 * sets current screen to null (used on escape buttons of GUIs) 218 */ 219 public void closeScreen() 220 { 221 this.sendQueue.addToSendQueue(new Packet101CloseWindow(this.openContainer.windowId)); 222 this.func_92015_f(); 223 } 224 225 public void func_92015_f() 226 { 227 this.inventory.setItemStack((ItemStack)null); 228 super.closeScreen(); 229 } 230 231 /** 232 * Updates health locally. 233 */ 234 public void setHealth(int par1) 235 { 236 if (this.hasSetHealth) 237 { 238 super.setHealth(par1); 239 } 240 else 241 { 242 this.setEntityHealth(par1); 243 this.hasSetHealth = true; 244 } 245 } 246 247 /** 248 * Adds a value to a statistic field. 249 */ 250 public void addStat(StatBase par1StatBase, int par2) 251 { 252 if (par1StatBase != null) 253 { 254 if (par1StatBase.isIndependent) 255 { 256 super.addStat(par1StatBase, par2); 257 } 258 } 259 } 260 261 /** 262 * Used by NetClientHandler.handleStatistic 263 */ 264 public void incrementStat(StatBase par1StatBase, int par2) 265 { 266 if (par1StatBase != null) 267 { 268 if (!par1StatBase.isIndependent) 269 { 270 super.addStat(par1StatBase, par2); 271 } 272 } 273 } 274 275 /** 276 * Sends the player's abilities to the server (if there is one). 277 */ 278 public void sendPlayerAbilities() 279 { 280 this.sendQueue.addToSendQueue(new Packet202PlayerAbilities(this.capabilities)); 281 } 282 283 public boolean func_71066_bF() 284 { 285 return true; 286 } 287}