2025-11-24 22:52:51 +03:00

213 lines
6.7 KiB
Java

/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* org.jspecify.annotations.Nullable
*/
package net.minecraft.world.level.pathfinder;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.minecraft.core.BlockPos;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.util.VisibleForDebug;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.pathfinder.Node;
import net.minecraft.world.level.pathfinder.Target;
import net.minecraft.world.phys.Vec3;
import org.jspecify.annotations.Nullable;
public final class Path {
public static final StreamCodec<FriendlyByteBuf, Path> STREAM_CODEC = StreamCodec.of((output, value) -> value.writeToStream((FriendlyByteBuf)((Object)output)), Path::createFromStream);
private final List<Node> nodes;
private @Nullable DebugData debugData;
private int nextNodeIndex;
private final BlockPos target;
private final float distToTarget;
private final boolean reached;
public Path(List<Node> nodes, BlockPos target, boolean reached) {
this.nodes = nodes;
this.target = target;
this.distToTarget = nodes.isEmpty() ? Float.MAX_VALUE : this.nodes.get(this.nodes.size() - 1).distanceManhattan(this.target);
this.reached = reached;
}
public void advance() {
++this.nextNodeIndex;
}
public boolean notStarted() {
return this.nextNodeIndex <= 0;
}
public boolean isDone() {
return this.nextNodeIndex >= this.nodes.size();
}
public @Nullable Node getEndNode() {
if (!this.nodes.isEmpty()) {
return this.nodes.get(this.nodes.size() - 1);
}
return null;
}
public Node getNode(int i) {
return this.nodes.get(i);
}
public void truncateNodes(int index) {
if (this.nodes.size() > index) {
this.nodes.subList(index, this.nodes.size()).clear();
}
}
public void replaceNode(int index, Node replaceWith) {
this.nodes.set(index, replaceWith);
}
public int getNodeCount() {
return this.nodes.size();
}
public int getNextNodeIndex() {
return this.nextNodeIndex;
}
public void setNextNodeIndex(int nextNodeIndex) {
this.nextNodeIndex = nextNodeIndex;
}
public Vec3 getEntityPosAtNode(Entity entity, int index) {
Node node = this.nodes.get(index);
double x = (double)node.x + (double)((int)(entity.getBbWidth() + 1.0f)) * 0.5;
double y = node.y;
double z = (double)node.z + (double)((int)(entity.getBbWidth() + 1.0f)) * 0.5;
return new Vec3(x, y, z);
}
public BlockPos getNodePos(int index) {
return this.nodes.get(index).asBlockPos();
}
public Vec3 getNextEntityPos(Entity entity) {
return this.getEntityPosAtNode(entity, this.nextNodeIndex);
}
public BlockPos getNextNodePos() {
return this.nodes.get(this.nextNodeIndex).asBlockPos();
}
public Node getNextNode() {
return this.nodes.get(this.nextNodeIndex);
}
public @Nullable Node getPreviousNode() {
return this.nextNodeIndex > 0 ? this.nodes.get(this.nextNodeIndex - 1) : null;
}
public boolean sameAs(@Nullable Path path) {
return path != null && this.nodes.equals(path.nodes);
}
public boolean equals(Object obj) {
if (!(obj instanceof Path)) {
return false;
}
Path path = (Path)obj;
return this.nextNodeIndex == path.nextNodeIndex && this.debugData == path.debugData && this.reached == path.reached && this.target.equals(path.target) && this.nodes.equals(path.nodes);
}
public int hashCode() {
return this.nextNodeIndex + this.nodes.hashCode() * 31;
}
public boolean canReach() {
return this.reached;
}
@VisibleForDebug
void setDebug(Node[] openSet, Node[] closedSet, Set<Target> targets) {
this.debugData = new DebugData(openSet, closedSet, targets);
}
public @Nullable DebugData debugData() {
return this.debugData;
}
public void writeToStream(FriendlyByteBuf buffer) {
if (this.debugData == null || this.debugData.targetNodes.isEmpty()) {
throw new IllegalStateException("Missing debug data");
}
buffer.writeBoolean(this.reached);
buffer.writeInt(this.nextNodeIndex);
buffer.writeBlockPos(this.target);
buffer.writeCollection(this.nodes, (out, node) -> node.writeToStream((FriendlyByteBuf)((Object)out)));
this.debugData.write(buffer);
}
public static Path createFromStream(FriendlyByteBuf buffer) {
boolean reached = buffer.readBoolean();
int indexStream = buffer.readInt();
BlockPos target = buffer.readBlockPos();
List<Node> nodes = buffer.readList(Node::createFromStream);
DebugData debugData = DebugData.read(buffer);
Path path = new Path(nodes, target, reached);
path.debugData = debugData;
path.nextNodeIndex = indexStream;
return path;
}
public String toString() {
return "Path(length=" + this.nodes.size() + ")";
}
public BlockPos getTarget() {
return this.target;
}
public float getDistToTarget() {
return this.distToTarget;
}
private static Node[] readNodeArray(FriendlyByteBuf input) {
Node[] nodes = new Node[input.readVarInt()];
for (int i = 0; i < nodes.length; ++i) {
nodes[i] = Node.createFromStream(input);
}
return nodes;
}
private static void writeNodeArray(FriendlyByteBuf output, Node[] nodes) {
output.writeVarInt(nodes.length);
for (Node node : nodes) {
node.writeToStream(output);
}
}
public Path copy() {
Path result = new Path(this.nodes, this.target, this.reached);
result.debugData = this.debugData;
result.nextNodeIndex = this.nextNodeIndex;
return result;
}
public record DebugData(Node[] openSet, Node[] closedSet, Set<Target> targetNodes) {
public void write(FriendlyByteBuf output) {
output.writeCollection(this.targetNodes, (out, target) -> target.writeToStream((FriendlyByteBuf)((Object)out)));
Path.writeNodeArray(output, this.openSet);
Path.writeNodeArray(output, this.closedSet);
}
public static DebugData read(FriendlyByteBuf input) {
HashSet targets = input.readCollection(HashSet::new, Target::createFromStream);
Node[] openSet = Path.readNodeArray(input);
Node[] closedSet = Path.readNodeArray(input);
return new DebugData(openSet, closedSet, targets);
}
}
}