package micdoodle8.mods.galacticraft.planets.venus.entities.ai;
import micdoodle8.mods.galacticraft.planets.venus.entities.EntityJuicer;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.entity.monster.EntityZombie;
import net.minecraft.entity.passive.EntityChicken;
import net.minecraft.pathfinding.PathFinder;
import net.minecraft.pathfinding.PathNavigate;
import net.minecraft.util.BlockPos;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
public class PathNavigateCeiling extends PathNavigate
{
protected WalkNodeProcessorCeiling nodeProcessor;
public PathNavigateCeiling(EntityJuicer entity, World worldIn)
{
super(entity, worldIn);
}
@Override
protected PathFinder getPathFinder()
{
this.nodeProcessor = new WalkNodeProcessorCeiling();
return new PathFinder(this.nodeProcessor);
}
@Override
protected boolean canNavigate()
{
return this.theEntity.onGround || this.theEntity.isRiding() && this.theEntity instanceof EntityZombie && this.theEntity.ridingEntity instanceof EntityChicken;
}
@Override
protected Vec3 getEntityPosition()
{
return new Vec3(this.theEntity.posX, (double)this.getPathablePosY(), this.theEntity.posZ);
}
private int getPathablePosY()
{
return (int)(this.theEntity.getEntityBoundingBox().minY + 0.5D);
}
@Override
protected boolean isDirectPathBetweenPoints(Vec3 current, Vec3 target, int sizeX, int sizeY, int sizeZ)
{
int i = MathHelper.floor_double(current.xCoord);
int j = MathHelper.floor_double(current.zCoord);
double d0 = target.xCoord - current.xCoord;
double d1 = target.zCoord - current.zCoord;
double d2 = d0 * d0 + d1 * d1;
if (d2 < 1.0E-8D)
{
return false;
}
else
{
double d3 = 1.0D / Math.sqrt(d2);
d0 = d0 * d3;
d1 = d1 * d3;
sizeX = sizeX + 2;
sizeZ = sizeZ + 2;
if (!this.isSafeToStandAt(i, (int)current.yCoord, j, sizeX, sizeY, sizeZ, current, d0, d1))
{
return false;
}
else
{
sizeX = sizeX - 2;
sizeZ = sizeZ - 2;
double d4 = 1.0D / Math.abs(d0);
double d5 = 1.0D / Math.abs(d1);
double d6 = (double)(i) - current.xCoord;
double d7 = (double)(j) - current.zCoord;
if (d0 >= 0.0D)
{
++d6;
}
if (d1 >= 0.0D)
{
++d7;
}
d6 = d6 / d0;
d7 = d7 / d1;
int k = d0 < 0.0D ? -1 : 1;
int l = d1 < 0.0D ? -1 : 1;
int i1 = MathHelper.floor_double(target.xCoord);
int j1 = MathHelper.floor_double(target.zCoord);
int k1 = i1 - i;
int l1 = j1 - j;
while (k1 * k > 0 || l1 * l > 0)
{
if (d6 < d7)
{
d6 += d4;
i += k;
k1 = i1 - i;
}
else
{
d7 += d5;
j += l;
l1 = j1 - j;
}
if (!this.isSafeToStandAt(i, (int)current.yCoord, j, sizeX, sizeY, sizeZ, current, d0, d1))
{
return false;
}
}
return true;
}
}
}
private boolean isSafeToStandAt(int x, int y, int z, int sizeX, int sizeY, int sizeZ, Vec3 currentPos, double distanceX, double distanceZ)
{
int i = x - sizeX / 2;
int j = z - sizeZ / 2;
if (!this.isPositionClear(i, y, j, sizeX, sizeY, sizeZ, currentPos, distanceX, distanceZ))
{
return false;
}
else
{
for (int k = i; k < i + sizeX; ++k)
{
for (int l = j; l < j + sizeZ; ++l)
{
double d0 = (double)k + 0.5D - currentPos.xCoord;
double d1 = (double)l + 0.5D - currentPos.zCoord;
if (d0 * distanceX + d1 * distanceZ >= 0.0D)
{
Block block = this.worldObj.getBlockState(new BlockPos(k, y + 1, l)).getBlock();
Material material = block.getMaterial();
if (material == Material.air)
{
return false;
}
if (material == Material.water && !this.theEntity.isInWater())
{
return false;
}
if (material == Material.lava)
{
return false;
}
}
}
}
return true;
}
}
private boolean isPositionClear(int minX, int minY, int minZ, int sizeX, int sizeY, int sizeZ, Vec3 currentPos, double distanceX, double distanceZ)
{
for (BlockPos blockpos : BlockPos.getAllInBox(new BlockPos(minX, minY, minZ), new BlockPos(minX + sizeX - 1, minY + sizeY - 1, minZ + sizeZ - 1)))
{
double d0 = (double)blockpos.getX() + 0.5D - currentPos.xCoord;
double d1 = (double)blockpos.getZ() + 0.5D - currentPos.zCoord;
if (d0 * distanceX + d1 * distanceZ >= 0.0D)
{
Block block = this.worldObj.getBlockState(blockpos).getBlock();
if (!block.isPassable(this.worldObj, blockpos))
{
return false;
}
}
}
return true;
}
}