    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}