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 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}