001package net.minecraft.entity.ai;
002
003import net.minecraft.block.Block;
004import net.minecraft.block.BlockDoor;
005import net.minecraft.entity.EntityLiving;
006import net.minecraft.pathfinding.PathEntity;
007import net.minecraft.pathfinding.PathNavigate;
008import net.minecraft.pathfinding.PathPoint;
009import net.minecraft.util.MathHelper;
010
011public 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 pathnavigate = this.theEntity.getNavigator();
043            PathEntity pathentity = pathnavigate.getPath();
044
045            if (pathentity != null && !pathentity.isFinished() && pathnavigate.getCanBreakDoors())
046            {
047                for (int i = 0; i < Math.min(pathentity.getCurrentPathIndex() + 2, pathentity.getCurrentPathLength()); ++i)
048                {
049                    PathPoint pathpoint = pathentity.getPathPointFromIndex(i);
050                    this.entityPosX = pathpoint.xCoord;
051                    this.entityPosY = pathpoint.yCoord + 1;
052                    this.entityPosZ = pathpoint.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 f = (float)((double)((float)this.entityPosX + 0.5F) - this.theEntity.posX);
102        float f1 = (float)((double)((float)this.entityPosZ + 0.5F) - this.theEntity.posZ);
103        float f2 = this.entityPositionX * f + this.entityPositionZ * f1;
104
105        if (f2 < 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 l = this.theEntity.worldObj.getBlockId(par1, par2, par3);
117        return l != Block.doorWood.blockID ? null : (BlockDoor)Block.blocksList[l];
118    }
119}