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    }