111 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			111 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.world.level.pathfinder;
 | |
| 
 | |
| import net.minecraft.core.BlockPos;
 | |
| import net.minecraft.core.Direction;
 | |
| import net.minecraft.util.Mth;
 | |
| import net.minecraft.world.entity.Mob;
 | |
| import net.minecraft.world.level.PathNavigationRegion;
 | |
| import org.jetbrains.annotations.Nullable;
 | |
| 
 | |
| public class AmphibiousNodeEvaluator extends WalkNodeEvaluator {
 | |
| 	private final boolean prefersShallowSwimming;
 | |
| 	private float oldWalkableCost;
 | |
| 	private float oldWaterBorderCost;
 | |
| 
 | |
| 	public AmphibiousNodeEvaluator(boolean prefersShallowSwimming) {
 | |
| 		this.prefersShallowSwimming = prefersShallowSwimming;
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public void prepare(PathNavigationRegion level, Mob mob) {
 | |
| 		super.prepare(level, mob);
 | |
| 		mob.setPathfindingMalus(PathType.WATER, 0.0F);
 | |
| 		this.oldWalkableCost = mob.getPathfindingMalus(PathType.WALKABLE);
 | |
| 		mob.setPathfindingMalus(PathType.WALKABLE, 6.0F);
 | |
| 		this.oldWaterBorderCost = mob.getPathfindingMalus(PathType.WATER_BORDER);
 | |
| 		mob.setPathfindingMalus(PathType.WATER_BORDER, 4.0F);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public void done() {
 | |
| 		this.mob.setPathfindingMalus(PathType.WALKABLE, this.oldWalkableCost);
 | |
| 		this.mob.setPathfindingMalus(PathType.WATER_BORDER, this.oldWaterBorderCost);
 | |
| 		super.done();
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public Node getStart() {
 | |
| 		return !this.mob.isInWater()
 | |
| 			? super.getStart()
 | |
| 			: this.getStartNode(
 | |
| 				new BlockPos(Mth.floor(this.mob.getBoundingBox().minX), Mth.floor(this.mob.getBoundingBox().minY + 0.5), Mth.floor(this.mob.getBoundingBox().minZ))
 | |
| 			);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public Target getTarget(double x, double y, double z) {
 | |
| 		return this.getTargetNodeAt(x, y + 0.5, z);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public int getNeighbors(Node[] outputArray, Node node) {
 | |
| 		int i = super.getNeighbors(outputArray, node);
 | |
| 		PathType pathType = this.getCachedPathType(node.x, node.y + 1, node.z);
 | |
| 		PathType pathType2 = this.getCachedPathType(node.x, node.y, node.z);
 | |
| 		int j;
 | |
| 		if (this.mob.getPathfindingMalus(pathType) >= 0.0F && pathType2 != PathType.STICKY_HONEY) {
 | |
| 			j = Mth.floor(Math.max(1.0F, this.mob.maxUpStep()));
 | |
| 		} else {
 | |
| 			j = 0;
 | |
| 		}
 | |
| 
 | |
| 		double d = this.getFloorLevel(new BlockPos(node.x, node.y, node.z));
 | |
| 		Node node2 = this.findAcceptedNode(node.x, node.y + 1, node.z, Math.max(0, j - 1), d, Direction.UP, pathType2);
 | |
| 		Node node3 = this.findAcceptedNode(node.x, node.y - 1, node.z, j, d, Direction.DOWN, pathType2);
 | |
| 		if (this.isVerticalNeighborValid(node2, node)) {
 | |
| 			outputArray[i++] = node2;
 | |
| 		}
 | |
| 
 | |
| 		if (this.isVerticalNeighborValid(node3, node) && pathType2 != PathType.TRAPDOOR) {
 | |
| 			outputArray[i++] = node3;
 | |
| 		}
 | |
| 
 | |
| 		for (int k = 0; k < i; k++) {
 | |
| 			Node node4 = outputArray[k];
 | |
| 			if (node4.type == PathType.WATER && this.prefersShallowSwimming && node4.y < this.mob.level().getSeaLevel() - 10) {
 | |
| 				node4.costMalus++;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		return i;
 | |
| 	}
 | |
| 
 | |
| 	private boolean isVerticalNeighborValid(@Nullable Node neighbor, Node node) {
 | |
| 		return this.isNeighborValid(neighbor, node) && neighbor.type == PathType.WATER;
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected boolean isAmphibious() {
 | |
| 		return true;
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public PathType getPathType(PathfindingContext context, int x, int y, int z) {
 | |
| 		PathType pathType = context.getPathTypeFromState(x, y, z);
 | |
| 		if (pathType == PathType.WATER) {
 | |
| 			BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
 | |
| 
 | |
| 			for (Direction direction : Direction.values()) {
 | |
| 				mutableBlockPos.set(x, y, z).move(direction);
 | |
| 				PathType pathType2 = context.getPathTypeFromState(mutableBlockPos.getX(), mutableBlockPos.getY(), mutableBlockPos.getZ());
 | |
| 				if (pathType2 == PathType.BLOCKED) {
 | |
| 					return PathType.WATER_BORDER;
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			return PathType.WATER;
 | |
| 		} else {
 | |
| 			return super.getPathType(context, x, y, z);
 | |
| 		}
 | |
| 	}
 | |
| }
 |