All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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