    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}