
net.minecraft.server.NavigationAbstract Maven / Gradle / Ivy
package net.minecraft.server;
import java.util.Iterator;
import java.util.List;
public abstract class NavigationAbstract {
public EntityInsentient entity; // from -> b
public World world; // from -> c
/**
* The PathEntity being followed.
*/
public PathEntity currentPath; // from -> d
public double speed; // from -> e
/**
* The number of blocks (extra) +/- in each axis that get pulled out as cache for the pathfinder's search space
*/
public final AttributeInstance pathSearchRange; // from -> a
/**
* Time, in number of ticks, following the current path
*/
public int totalTicks; // from -> f
/**
* The time when the last position check was done (to detect successful movement)
*/
public int ticksAtLastPos; // from -> g
/**
* Coordinates of the entity's position last time a check was done (part of monitoring getting 'stuck')
*/
public Vec3D lastPosCheck = new Vec3D(0.0D, 0.0D, 0.0D); // from -> h
public float heightRequirement = 1.0F; // from -> i
public final Pathfinder pathFinder; // from -> j
public NavigationAbstract(EntityInsentient entity, World world) {
this.entity = entity;
this.world = world;
this.pathSearchRange = entity.getAttributeInstance(GenericAttributes.FOLLOW_RANGE);
this.pathFinder = this.a();
}
// from -> a()
protected abstract Pathfinder a();
/**
* Sets the speed
*/
// from -> a()
public void setSpeed(double speed) {
this.speed = speed;
}
/**
* Gets the maximum distance that the path finding will search in.
*/
// from -> i()
public float getPathSearchRange() {
return (float) this.pathSearchRange.getValue();
}
/**
* Returns the path to the given coordinates. Args : x, y, z
*/
// from -> a()
public final PathEntity getPathToXYZ(double x, double y, double z) {
return this.getPathToPos(new BlockPosition(MathHelper.floor(x), (int) y, MathHelper.floor(z)));
}
/**
* Returns path to given BlockPos
*/
// from -> a()
public PathEntity getPathToPos(BlockPosition blockposition) {
if (!this.canNavigate()) {
return null;
} else {
float f = this.getPathSearchRange();
BlockPosition blockposition1 = new BlockPosition(this.entity);
int i = (int) (f + 8.0F);
ChunkCache chunkcache = new ChunkCache(this.world, blockposition1.a(-i, -i, -i), blockposition1.a(i, i, i), 0);
return this.pathFinder.a(chunkcache, this.entity, blockposition, f);
}
}
/**
* Try to find and set a path to XYZ. Returns true if successful. Args : x, y, z, speed
*/
// from -> a()
public boolean tryMoveToXYZ(double x, double y, double z, double speed) {
PathEntity pathentity = this.getPathToXYZ(MathHelper.floor(x), (int) y, MathHelper.floor(z));
return this.setPath(pathentity, speed);
}
/**
* Sets vertical space requirement for path
*/
// from -> a()
public void setHeightRequirement(float height) {
this.heightRequirement = height;
}
/**
* Returns the path to the given EntityLiving. Args : entity
*/
// from -> a()
public PathEntity getPathToEntityLiving(Entity entity) {
if (!this.canNavigate()) {
return null;
} else {
float f = this.getPathSearchRange();
BlockPosition blockposition = (new BlockPosition(this.entity)).up();
int i = (int) (f + 16.0F);
ChunkCache chunkcache = new ChunkCache(this.world, blockposition.a(-i, -i, -i), blockposition.a(i, i, i), 0);
return this.pathFinder.a(chunkcache, this.entity, entity, f);
}
}
/**
* Try to find and set a path to EntityLiving. Returns true if successful. Args : entity, speed
*/
// from -> a()
public boolean tryMoveToEntity(Entity entity, double speed) {
PathEntity pathentity = this.getPathToEntityLiving(entity);
return pathentity != null && this.setPath(pathentity, speed);
}
/**
* Sets a new path. If it's diferent from the old path. Checks to adjust path for sun avoiding, and stores start
* coords. Args : path, speed
*/
// from -> a()
public boolean setPath(PathEntity pathentity, double speed) {
if (pathentity == null) {
this.currentPath = null;
return false;
} else {
if (!pathentity.a(this.currentPath)) {
this.currentPath = pathentity;
}
this.removeSunnyPath();
if (this.currentPath.d() == 0) {
return false;
} else {
this.speed = speed;
Vec3D vec3d = this.getEntityPosition();
this.ticksAtLastPos = this.totalTicks;
this.lastPosCheck = vec3d;
return true;
}
}
}
/**
* gets the actively used PathEntity
*/
// from -> j()
public PathEntity getPath() {
return this.currentPath;
}
// from -> k()
public void onUpdateNavigation() {
++this.totalTicks;
if (!this.noPath()) {
Vec3D vec3d;
if (this.canNavigate()) {
this.pathFollow();
} else if (this.currentPath != null && this.currentPath.e() < this.currentPath.d()) {
vec3d = this.getEntityPosition();
Vec3D vec3d1 = this.currentPath.a(this.entity, this.currentPath.e());
if (vec3d.b > vec3d1.b && !this.entity.onGround && MathHelper.floor(vec3d.a) == MathHelper.floor(vec3d1.a) && MathHelper.floor(vec3d.c) == MathHelper.floor(vec3d1.c)) {
this.currentPath.c(this.currentPath.e() + 1);
}
}
if (!this.noPath()) {
vec3d = this.currentPath.a(this.entity);
if (vec3d != null) {
AxisAlignedBB axisalignedbb = (new AxisAlignedBB(vec3d.a, vec3d.b, vec3d.c, vec3d.a, vec3d.b, vec3d.c)).grow(0.5D, 0.5D, 0.5D);
List list = this.world.getCubes(this.entity, axisalignedbb.a(0.0D, -1.0D, 0.0D));
double d0 = -1.0D;
axisalignedbb = axisalignedbb.c(0.0D, 1.0D, 0.0D);
AxisAlignedBB axisalignedbb1;
for (Iterator iterator = list.iterator(); iterator.hasNext(); d0 = axisalignedbb1.b(axisalignedbb, d0)) {
axisalignedbb1 = iterator.next();
}
this.entity.getControllerMove().a(vec3d.a, vec3d.b + d0, vec3d.c, this.speed);
}
}
}
}
// from -> l()
protected void pathFollow() {
Vec3D vec3d = this.getEntityPosition();
int i = this.currentPath.d();
for (int j = this.currentPath.e(); j < this.currentPath.d(); ++j) {
if (this.currentPath.a(j).b != (int) vec3d.b) {
i = j;
break;
}
}
float f = this.entity.width * this.entity.width * this.heightRequirement;
int k;
for (k = this.currentPath.e(); k < i; ++k) {
Vec3D vec3d1 = this.currentPath.a(this.entity, k);
if (vec3d.distanceSquared(vec3d1) < (double) f) {
this.currentPath.c(k + 1);
}
}
k = MathHelper.f(this.entity.width);
int l = (int) this.entity.length + 1;
int i1 = k;
for (int j1 = i - 1; j1 >= this.currentPath.e(); --j1) {
if (this.isDirectPathBetweenPoints(vec3d, this.currentPath.a(this.entity, j1), k, l, i1)) {
this.currentPath.c(j1);
break;
}
}
this.checkForStuck(vec3d);
}
/**
* Checks if entity haven't been moved when last checked and if so, clears current
*/
// from -> a()
protected void checkForStuck(Vec3D vec3d) {
if (this.totalTicks - this.ticksAtLastPos > 100) {
if (vec3d.distanceSquared(this.lastPosCheck) < 2.25D) {
this.clearPathEntity();
}
this.ticksAtLastPos = this.totalTicks;
this.lastPosCheck = vec3d;
}
}
/**
* If null path or reached the end
*/
// from -> m()
public boolean noPath() {
return this.currentPath == null || this.currentPath.b();
}
/**
* sets active PathEntity to null
*/
// from -> n()
public void clearPathEntity() {
this.currentPath = null;
}
// from -> c()
protected abstract Vec3D getEntityPosition();
/**
* If on ground or swimming and can swim
*/
// from -> b()
protected abstract boolean canNavigate();
/**
* Returns true if the entity is in water or lava, false otherwise
*/
// from -> o()
protected boolean isInLiquid() {
return this.entity.isInWater() || this.entity.isInLava();
}
/**
* Trims path data from the end to the first sun covered block
*/
// from -> d()
protected void removeSunnyPath() {
}
/**
* Returns true when an entity of specified size could safely walk in a straight line between the two points. Args:
* pos1, pos2, entityXSize, entityYSize, entityZSize
*/
// from -> a()
protected abstract boolean isDirectPathBetweenPoints(Vec3D vec3d, Vec3D vec3d1, int sizeX, int sizeY, int sizeZ);
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy