hytale-server/com/hypixel/hytale/server/npc/navigation/AStarDebugBase.java

229 lines
7.3 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.hypixel.hytale.server.npc.navigation;
import com.hypixel.hytale.logger.HytaleLogger;
import com.hypixel.hytale.server.npc.movement.controllers.MotionController;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectMaps;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap.Entry;
import it.unimi.dsi.fastutil.objects.ObjectIterator;
import java.util.List;
import java.util.logging.Level;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class AStarDebugBase {
public static final char CENTER = ' ';
public static final char CROSS = '┼';
public static final char HLINE = '─';
public static final char VLINE = '│';
public static final char OPEN_NODE = '◆';
public static final char CLOSED_NODE = '◇';
public static final char CLOSED_PATH_NODE = '◯';
public static final char OPEN_PATH_NODE = '◉';
public static final char BLOCKED_NODE = '×';
public static final char START_POSITION = '@';
public static final char END_POSITION = 'Ω';
public static final String BORDER_PATTERN = "─┼".repeat(1025);
public static final String CENTER_PATTERN = "".repeat(1025);
protected AStarBase aStarBase;
protected HytaleLogger logger;
protected HytaleLogger.Api loggerInfo;
public AStarDebugBase(AStarBase base, @Nonnull HytaleLogger logger) {
this.aStarBase = base;
this.logger = logger;
this.loggerInfo = logger.at(Level.INFO);
}
public void dumpOpens(MotionController controller) {
int openCount = this.aStarBase.getOpenCount();
List<AStarNode> openNodes = this.aStarBase.getOpenNodes();
int maxLength = -1;
for (int i = 0; i < openCount; i++) {
int length = openNodes.get(i).getLength();
if (length > maxLength) {
maxLength = length;
}
}
this.loggerInfo
.log(
"== A* iter=%s opens=%s total=%s maxLength=%s %s",
this.aStarBase.getIterations(),
openCount,
this.aStarBase.getVisitedBlocks().size(),
maxLength,
this.getExtraLogString(controller)
);
for (int ix = 0; ix < openCount; ix++) {
this.loggerInfo.log("%2d %s", ix, openNodes.get(ix).toString());
}
}
public void dumpPath() {
AStarNode node = this.aStarBase.getPath();
this.loggerInfo
.log("== A* Path iter=%s opens=%s total=%s", this.aStarBase.getIterations(), this.aStarBase.getOpenCount(), this.aStarBase.getVisitedBlocks().size());
while (node != null) {
this.loggerInfo.log("%s", node.toString());
node = node.getNextPathNode();
}
}
public void dumpMap(boolean drawPath, MotionController controller) {
int openCount = this.aStarBase.getOpenCount();
List<AStarNode> openNodes = this.aStarBase.getOpenNodes();
AStarNode start = null;
boolean finalPath = false;
if (drawPath) {
AStarNode path = this.aStarBase.getPath();
if (path != null) {
start = path;
finalPath = true;
} else if (openCount > 0) {
start = openNodes.get(openCount - 1);
}
}
this.dumpMap(start, finalPath, controller);
}
public void dumpMap(@Nullable AStarNode pathNode, boolean isFinalPath, MotionController controller) {
long startPositionIndex = this.aStarBase.getStartPositionIndex();
Long2ObjectMap<AStarNode> visitedBlocks = this.aStarBase.getVisitedBlocks();
int s = AStarBase.xFromIndex(startPositionIndex);
int e = this.getDumpMapRegionX(s);
int minX;
int maxX;
if (s < e) {
minX = s;
maxX = e;
} else {
minX = e;
maxX = s;
}
s = AStarBase.zFromIndex(startPositionIndex);
e = this.getDumpMapRegionZ(s);
int minZ;
int maxZ;
if (s < e) {
minZ = s;
maxZ = e;
} else {
minZ = e;
maxZ = s;
}
ObjectIterator<Entry<AStarNode>> fastIterator = Long2ObjectMaps.fastIterator(visitedBlocks);
while (fastIterator.hasNext()) {
AStarNode node = (AStarNode)((Entry)fastIterator.next()).getValue();
int x = AStarBase.xFromIndex(node.getPositionIndex());
int z = AStarBase.zFromIndex(node.getPositionIndex());
if (x < minX) {
minX = x;
}
if (x > maxX) {
maxX = x;
}
if (z < minZ) {
minZ = z;
}
if (z > maxZ) {
maxZ = z;
}
}
int rows = maxZ - minZ + 1;
int columns = maxX - minX + 1;
int offset = minX & 1;
boolean evenStart = (minZ & 1) == 0;
String first = "'" + (evenStart ? CENTER_PATTERN : BORDER_PATTERN).substring(offset, offset + columns) + "'";
String second = "'" + (evenStart ? BORDER_PATTERN : CENTER_PATTERN).substring(offset, offset + columns) + "'";
StringBuilder[] map = new StringBuilder[rows];
for (int i = 0; i < rows; i += 2) {
map[i] = new StringBuilder(first);
if (i + 1 < rows) {
map[i + 1] = new StringBuilder(second);
}
}
fastIterator = Long2ObjectMaps.fastIterator(visitedBlocks);
while (fastIterator.hasNext()) {
AStarNode nodex = (AStarNode)((Entry)fastIterator.next()).getValue();
this.plot(nodex.getPositionIndex(), (char)(nodex.isInvalid() ? '×' : (nodex.isOpen() ? '◆' : '◇')), map, minX, minZ);
}
int openCount = this.aStarBase.getOpenCount();
int maxLength;
if (pathNode != null) {
maxLength = pathNode.getLength();
while (pathNode != null) {
this.plot(pathNode.getPositionIndex(), (char)(pathNode.isOpen() ? '◉' : '◯'), map, minX, minZ);
pathNode = isFinalPath ? pathNode.getNextPathNode() : pathNode.getPredecessor();
}
} else {
List<AStarNode> openNodes = this.aStarBase.getOpenNodes();
int index = openCount;
maxLength = 0;
while (--index >= 0) {
int pos = openCount - index;
if (pos > 51) {
break;
}
this.plot(openNodes.get(index).getPositionIndex(), (char)(pos >= 26 ? pos - 26 + 97 : pos + 65), map, minX, minZ);
}
}
this.plot(startPositionIndex, '@', map, minX, minZ);
this.drawMapFinish(map, minX, minZ);
this.loggerInfo
.log(
"== A* iter=%s, opens=%s total=%s maxLength=%s %s",
this.aStarBase.getIterations(),
openCount,
visitedBlocks.size(),
maxLength,
this.getExtraLogString(controller)
);
for (StringBuilder stringBuilder : map) {
this.loggerInfo.log(stringBuilder.toString());
}
}
protected void plot(long positionIndex, char character, @Nonnull StringBuilder[] map, int minX, int minZ) {
int row = AStarBase.zFromIndex(positionIndex) - minZ;
int column = AStarBase.xFromIndex(positionIndex) - minX + 1;
map[row].setCharAt(column, character);
}
protected void drawMapFinish(StringBuilder[] map, int minX, int minZ) {
}
protected int getDumpMapRegionZ(int def) {
return def;
}
protected int getDumpMapRegionX(int def) {
return def;
}
@Nonnull
protected String getExtraLogString(MotionController controller) {
return "";
}
}