    001    package net.minecraft.entity.ai;
    002
    003    import net.minecraft.block.Block;
    004    import net.minecraft.block.BlockDoor;
    005    import net.minecraft.entity.EntityLiving;
    006    import net.minecraft.pathfinding.PathEntity;
    007    import net.minecraft.pathfinding.PathNavigate;
    008    import net.minecraft.pathfinding.PathPoint;
    009    import net.minecraft.util.MathHelper;
    010
    011    public abstract class EntityAIDoorInteract extends EntityAIBase
    012    {
    013        protected EntityLiving theEntity;
    014        protected int entityPosX;
    015        protected int entityPosY;
    016        protected int entityPosZ;
    017        protected BlockDoor targetDoor;
    018
    019        /**
    020         * If is true then the Entity has stopped Door Interaction and compoleted the task.
    021         */
    022        boolean hasStoppedDoorInteraction;
    023        float entityPositionX;
    024        float entityPositionZ;
    025
    026        public EntityAIDoorInteract(EntityLiving par1EntityLiving)
    027        {
    028            this.theEntity = par1EntityLiving;
    029        }
    030
    031        /**
    032         * Returns whether the EntityAIBase should begin execution.
    033         */
    034        public boolean shouldExecute()
    035        {
    036            if (!this.theEntity.isCollidedHorizontally)
    037            {
    038                return false;
    039            }
    040            else
    041            {
    042                PathNavigate var1 = this.theEntity.getNavigator();
    043                PathEntity var2 = var1.getPath();
    044
    045                if (var2 != null && !var2.isFinished() && var1.getCanBreakDoors())
    046                {
    047                    for (int var3 = 0; var3 < Math.min(var2.getCurrentPathIndex() + 2, var2.getCurrentPathLength()); ++var3)
    048                    {
    049                        PathPoint var4 = var2.getPathPointFromIndex(var3);
    050                        this.entityPosX = var4.xCoord;
    051                        this.entityPosY = var4.yCoord + 1;
    052                        this.entityPosZ = var4.zCoord;
    053
    054                        if (this.theEntity.getDistanceSq((double)this.entityPosX, this.theEntity.posY, (double)this.entityPosZ) <= 2.25D)
    055                        {
    056                            this.targetDoor = this.findUsableDoor(this.entityPosX, this.entityPosY, this.entityPosZ);
    057
    058                            if (this.targetDoor != null)
    059                            {
    060                                return true;
    061                            }
    062                        }
    063                    }
    064
    065                    this.entityPosX = MathHelper.floor_double(this.theEntity.posX);
    066                    this.entityPosY = MathHelper.floor_double(this.theEntity.posY + 1.0D);
    067                    this.entityPosZ = MathHelper.floor_double(this.theEntity.posZ);
    068                    this.targetDoor = this.findUsableDoor(this.entityPosX, this.entityPosY, this.entityPosZ);
    069                    return this.targetDoor != null;
    070                }
    071                else
    072                {
    073                    return false;
    074                }
    075            }
    076        }
    077
    078        /**
    079         * Returns whether an in-progress EntityAIBase should continue executing
    080         */
    081        public boolean continueExecuting()
    082        {
    083            return !this.hasStoppedDoorInteraction;
    084        }
    085
    086        /**
    087         * Execute a one shot task or start executing a continuous task
    088         */
    089        public void startExecuting()
    090        {
    091            this.hasStoppedDoorInteraction = false;
    092            this.entityPositionX = (float)((double)((float)this.entityPosX + 0.5F) - this.theEntity.posX);
    093            this.entityPositionZ = (float)((double)((float)this.entityPosZ + 0.5F) - this.theEntity.posZ);
    094        }
    095
    096        /**
    097         * Updates the task
    098         */
    099        public void updateTask()
    100        {
    101            float var1 = (float)((double)((float)this.entityPosX + 0.5F) - this.theEntity.posX);
    102            float var2 = (float)((double)((float)this.entityPosZ + 0.5F) - this.theEntity.posZ);
    103            float var3 = this.entityPositionX * var1 + this.entityPositionZ * var2;
    104
    105            if (var3 < 0.0F)
    106            {
    107                this.hasStoppedDoorInteraction = true;
    108            }
    109        }
    110
    111        /**
    112         * Determines if a door can be broken with AI.
    113         */
    114        private BlockDoor findUsableDoor(int par1, int par2, int par3)
    115        {
    116            int var4 = this.theEntity.worldObj.getBlockId(par1, par2, par3);
    117            return var4 != Block.doorWood.blockID ? null : (BlockDoor)Block.blocksList[var4];
    118        }
    119    }