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 }