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