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 var1 = this.isSprinting();
087
088        if (var1 != this.wasSneaking)
089        {
090            if (var1)
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 = var1;
100        }
101
102        boolean var2 = this.isSneaking();
103
104        if (var2 != this.shouldStopSneaking)
105        {
106            if (var2)
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 = var2;
116        }
117
118        double var3 = this.posX - this.oldPosX;
119        double var5 = this.boundingBox.minY - this.oldMinY;
120        double var7 = this.posZ - this.oldPosZ;
121        double var9 = (double)(this.rotationYaw - this.oldRotationYaw);
122        double var11 = (double)(this.rotationPitch - this.oldRotationPitch);
123        boolean var13 = var3 * var3 + var5 * var5 + var7 * var7 > 9.0E-4D || this.field_71168_co >= 20;
124        boolean var14 = var9 != 0.0D || var11 != 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            var13 = false;
130        }
131        else if (var13 && var14)
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 (var13)
136        {
137            this.sendQueue.addToSendQueue(new Packet11PlayerPosition(this.posX, this.boundingBox.minY, this.posY, this.posZ, this.onGround));
138        }
139        else if (var14)
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 (var13)
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 (var14)
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 var2 = par1 ? 3 : 4;
173        this.sendQueue.addToSendQueue(new Packet14BlockDig(var2, 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}