Code/net/minecraft/world/level/pathfinder/AmphibiousNodeEvaluator.java

117 lines
4.5 KiB
Java
Raw Normal View History

2025-07-01 06:20:03 +00:00
package net.minecraft.world.level.pathfinder;
import javax.annotation.Nullable;
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;
public class AmphibiousNodeEvaluator extends WalkNodeEvaluator {
private final boolean prefersShallowSwimming;
private float oldWalkableCost;
private float oldWaterBorderCost;
public AmphibiousNodeEvaluator(boolean p_164659_) {
this.prefersShallowSwimming = p_164659_;
}
@Override
public void prepare(PathNavigationRegion p_164671_, Mob p_164672_) {
super.prepare(p_164671_, p_164672_);
p_164672_.setPathfindingMalus(PathType.WATER, 0.0F);
this.oldWalkableCost = p_164672_.getPathfindingMalus(PathType.WALKABLE);
p_164672_.setPathfindingMalus(PathType.WALKABLE, 6.0F);
this.oldWaterBorderCost = p_164672_.getPathfindingMalus(PathType.WATER_BORDER);
p_164672_.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 p_330100_, double p_334194_, double p_330998_) {
return this.getTargetNodeAt(p_330100_, p_334194_ + 0.5, p_330998_);
}
@Override
public int getNeighbors(Node[] p_164676_, Node p_164677_) {
int i = super.getNeighbors(p_164676_, p_164677_);
PathType pathtype = this.getCachedPathType(p_164677_.x, p_164677_.y + 1, p_164677_.z);
PathType pathtype1 = this.getCachedPathType(p_164677_.x, p_164677_.y, p_164677_.z);
int j;
if (this.mob.getPathfindingMalus(pathtype) >= 0.0F && pathtype1 != PathType.STICKY_HONEY) {
j = Mth.floor(Math.max(1.0F, this.mob.maxUpStep()));
} else {
j = 0;
}
double d0 = this.getFloorLevel(new BlockPos(p_164677_.x, p_164677_.y, p_164677_.z));
Node node = this.findAcceptedNode(p_164677_.x, p_164677_.y + 1, p_164677_.z, Math.max(0, j - 1), d0, Direction.UP, pathtype1);
Node node1 = this.findAcceptedNode(p_164677_.x, p_164677_.y - 1, p_164677_.z, j, d0, Direction.DOWN, pathtype1);
if (this.isVerticalNeighborValid(node, p_164677_)) {
p_164676_[i++] = node;
}
if (this.isVerticalNeighborValid(node1, p_164677_) && pathtype1 != PathType.TRAPDOOR) {
p_164676_[i++] = node1;
}
for (int k = 0; k < i; k++) {
Node node2 = p_164676_[k];
if (node2.type == PathType.WATER && this.prefersShallowSwimming && node2.y < this.mob.level().getSeaLevel() - 10) {
node2.costMalus++;
}
}
return i;
}
private boolean isVerticalNeighborValid(@Nullable Node p_230611_, Node p_230612_) {
return this.isNeighborValid(p_230611_, p_230612_) && p_230611_.type == PathType.WATER;
}
@Override
protected boolean isAmphibious() {
return true;
}
@Override
public PathType getPathType(PathfindingContext p_336213_, int p_329171_, int p_336028_, int p_327966_) {
PathType pathtype = p_336213_.getPathTypeFromState(p_329171_, p_336028_, p_327966_);
if (pathtype == PathType.WATER) {
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
for (Direction direction : Direction.values()) {
blockpos$mutableblockpos.set(p_329171_, p_336028_, p_327966_).move(direction);
PathType pathtype1 = p_336213_.getPathTypeFromState(
blockpos$mutableblockpos.getX(), blockpos$mutableblockpos.getY(), blockpos$mutableblockpos.getZ()
);
if (pathtype1 == PathType.BLOCKED) {
return PathType.WATER_BORDER;
}
}
return PathType.WATER;
} else {
return super.getPathType(p_336213_, p_329171_, p_336028_, p_327966_);
}
}
}