v1.2.1: 修复飞地检测——按 dynmap even-odd 规则解析领土多边形,内圈孔洞(国中飞地边界)不再被并集填充掩盖
这个提交包含在:
@@ -15,13 +15,13 @@
|
||||
- 实时地图 GUI(通过 Ctrl+R 打开)
|
||||
- 监听聊天/字幕消息判断开垦结果
|
||||
- 刷新地图时与最新 `markers.json` 核对已占领区块,丢弃地图未确认的超期假占领,避免高地扩地残留空洞
|
||||
- 飞地(疏漏区块)检测:自动扫描每个邦国内外接矩形内"四周被同邦国占领但自身未占领"的区块,内置地图用红色标出己方飞地,自动扩地时优先填补这些缺口
|
||||
- 飞地(疏漏区块)检测:按 dynmap 奇偶填充规则解析领土多边形,正确识别国中由边界围出的内圈空腔;内置地图用红色标出己方飞地,自动扩地时优先填补这些缺口
|
||||
- 日志导出:GUI 右上角“导出日志”按钮,或 `/autostore log` 命令,记录寻路、坐标、状态、路径事件等
|
||||
|
||||
## 安装
|
||||
|
||||
1. 安装 Fabric Loader 0.16.14+ 和 Fabric API
|
||||
2. 将 `autostore-1.2.0.jar` 放入 `.minecraft/mods/` 目录
|
||||
2. 将 `autostore-1.2.1.jar` 放入 `.minecraft/mods/` 目录
|
||||
3. 启动游戏,按 `Ctrl+R` 打开 GUI
|
||||
|
||||
## 构建
|
||||
@@ -31,7 +31,7 @@
|
||||
./build_mod.sh
|
||||
```
|
||||
|
||||
输出文件:`autostore-1.2.0.jar`
|
||||
输出文件:`autostore-1.2.1.jar`
|
||||
|
||||
## 赞助支持
|
||||
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ yarn_mappings=1.21.4+build.8
|
||||
loader_version=0.19.3
|
||||
|
||||
# Mod Properties
|
||||
mod_version=1.2.0
|
||||
mod_version=1.2.1
|
||||
maven_group=autostore
|
||||
archives_base_name=autostore
|
||||
|
||||
|
||||
@@ -269,9 +269,9 @@ public final class TerritoryDataService {
|
||||
return;
|
||||
}
|
||||
Set chunks = claims.computeIfAbsent(name, ignored -> new HashSet());
|
||||
for (List<int[]> polygon : TerritoryDataService.extractPolygons(marker.get("points"))) {
|
||||
TerritoryDataService.fillPolygon(chunks, polygon);
|
||||
}
|
||||
// 一个 marker 的多个多边形遵循 dynmap 的 even-odd 填充规则:
|
||||
// 外圈为正,内圈多边形(国中飞地的边界)作为孔洞被减去,而非作为独立领土并集填充。
|
||||
TerritoryDataService.fillPolygonEvenOdd(chunks, TerritoryDataService.extractPolygons(marker.get("points")));
|
||||
colors.putIfAbsent(name, TerritoryDataService.parseColor(TerritoryDataService.stringOr(marker, "color", "#75bd20")));
|
||||
}
|
||||
|
||||
@@ -337,34 +337,49 @@ public final class TerritoryDataService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 将多边形覆盖的区块填充进集合:
|
||||
* 先算出多边形外接矩形(换算为区块坐标),再逐区块用"点在多边形内"算法判断,
|
||||
* 以区块中心点(cx*16+8, cz*16+8)是否落在多边形内为准。
|
||||
* 面积超过 600 万区块时直接放弃,防止异常数据导致卡死。
|
||||
* 将多边形组覆盖的区块按 even-odd 规则填充进集合。
|
||||
*
|
||||
* <p>一个 marker 里的多个多边形遵循 dynmap 的奇偶填充:区块落入<b>奇数个</b>多边形内时才视为领土;
|
||||
* 这样内圈多边形(国中飞地/孔洞的边界)会被正确减去,而不是像并集那样把孔洞也填成领土。</p>
|
||||
*
|
||||
* @param output 输出集合(该邦国的区块集合)
|
||||
* @param polygons 该 marker 的全部多边形,第一个为外圈、可为多个内圈孔洞
|
||||
*/
|
||||
private static void fillPolygon(Set<ChunkPos> output, List<int[]> polygon) {
|
||||
int area;
|
||||
private static void fillPolygonEvenOdd(Set<ChunkPos> output, List<List<int[]>> polygons) {
|
||||
if (polygons.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
int minX = Integer.MAX_VALUE;
|
||||
int maxX = Integer.MIN_VALUE;
|
||||
int minZ = Integer.MAX_VALUE;
|
||||
int maxZ = Integer.MIN_VALUE;
|
||||
for (List<int[]> polygon : polygons) {
|
||||
for (int[] point : polygon) {
|
||||
minX = Math.min(minX, Math.floorDiv(point[0], 16));
|
||||
maxX = Math.max(maxX, Math.floorDiv(point[0], 16));
|
||||
minZ = Math.min(minZ, Math.floorDiv(point[1], 16));
|
||||
maxZ = Math.max(maxZ, Math.floorDiv(point[1], 16));
|
||||
}
|
||||
int n = area = ((maxX - minX) + 1L) * ((maxZ - minZ) + 1L) > Integer.MAX_VALUE ? Integer.MAX_VALUE : (maxX - minX + 1) * (maxZ - minZ + 1);
|
||||
if (area > 6000000) {
|
||||
}
|
||||
// 面积超过 600 万区块时直接放弃,防止异常数据导致卡死
|
||||
if ((long)(maxX - minX + 1) * (maxZ - minZ + 1) > 6000000L) {
|
||||
return;
|
||||
}
|
||||
for (int cx = minX; cx <= maxX; ++cx) {
|
||||
for (int cz = minZ; cz <= maxZ; ++cz) {
|
||||
if (!TerritoryDataService.pointInPolygon(cx * 16 + 8, cz * 16 + 8, polygon)) continue;
|
||||
// 奇偶填充:落在奇数个多边形内则为领土;否则(含恰好落在偶数个内圈孔洞中)忽略
|
||||
boolean inside = false;
|
||||
for (List<int[]> polygon : polygons) {
|
||||
if (TerritoryDataService.pointInPolygon(cx * 16 + 8, cz * 16 + 8, polygon)) {
|
||||
inside = !inside;
|
||||
}
|
||||
}
|
||||
if (inside) {
|
||||
output.add(new ChunkPos(cx, cz));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 射线法判断点 (x, z) 是否在多边形内(经典奇偶规则) */
|
||||
private static boolean pointInPolygon(int x, int z, List<int[]> polygon) {
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"schemaVersion":1,"id":"autostore","version":"1.2.0","name":"AutoStore","description":"","authors":[],"contact":{},"license":"All-Rights-Reserved","environment":"client","entrypoints":{"fabric-datagen":["autostore.client.AutoStoreModDataGenerator"],"client":["autostore.client.AutoStoreModClient"],"main":["autostore.AutoStoreMod"]},"mixins":["autostore.mixins.json",{"config":"autostore.client.mixins.json","environment":"client"}],"depends":{"fabricloader":">=0.16.14","fabric-api":"*","minecraft":"1.21.4"},"jars":[{"file":"META-INF/jars/baritone-api-fabric-1.13.1.jar"}]}
|
||||
{"schemaVersion":1,"id":"autostore","version":"1.2.1","name":"AutoStore","description":"","authors":[],"contact":{},"license":"All-Rights-Reserved","environment":"client","entrypoints":{"fabric-datagen":["autostore.client.AutoStoreModDataGenerator"],"client":["autostore.client.AutoStoreModClient"],"main":["autostore.AutoStoreMod"]},"mixins":["autostore.mixins.json",{"config":"autostore.client.mixins.json","environment":"client"}],"depends":{"fabricloader":">=0.16.14","fabric-api":"*","minecraft":"1.21.4"},"jars":[{"file":"META-INF/jars/baritone-api-fabric-1.13.1.jar"}]}
|
||||
在新工单中引用
屏蔽一个用户