v1.2.5: 策略3落地为玩家周围扩地(按距离铺开);状态机switch改为具名分支;修复rings命令设置重启后失效

这个提交包含在:
lyizai
2026-08-31 13:14:02 +08:00
父节点 bc86c26d1e
当前提交 70ab6cc698
共修改 3 个文件,包含 43 行新增和 14 行删除
@@ -45,10 +45,10 @@ public final class ConfigStore {
if (loaded == null) { if (loaded == null) {
return new ExpansionConfig(); return new ExpansionConfig();
} }
// 以下字段为固定默认值,防止旧配置文件中的异常值影响运行 // autoEat/eatThreshold 字段为固定默认值,防止旧配置文件中的异常值影响运行;
// 注意:maxRings 由 /autostore rings 命令持久化,不得在此覆盖,否则命令设置会在重启后失效
loaded.autoEat = true; loaded.autoEat = true;
loaded.eatThreshold = 14; loaded.eatThreshold = 14;
loaded.maxRings = 0;
return loaded; return loaded;
} catch (Exception e) { } catch (Exception e) {
// 解析失败时回退到默认配置 // 解析失败时回退到默认配置
@@ -302,35 +302,36 @@ implements SubtitleChatMonitor.Listener, BaritoneBridge.PathListener {
this.tickSideStep(); this.tickSideStep();
return; return;
} }
switch (this.state.ordinal()) { switch (this.state) {
case 1: { case PLANNING: {
this.plan(); this.plan();
break; break;
} }
case 2: { case PATHING: {
this.tickPathing(); this.tickPathing();
break; break;
} }
case 3: { case WAITING: {
this.tickWaiting(); this.tickWaiting();
break; break;
} }
case 4: { case SUCCESS: {
this.tickSuccess(); this.tickSuccess();
break; break;
} }
case 5: { case FAIL: {
this.tickFail(); this.tickFail();
break; break;
} }
case 6: { case NEXT: {
this.tickNext(); this.tickNext();
break; break;
} }
case 7: { case RETURNING: {
this.tickReturning(); this.tickReturning();
break; break;
} }
// IDLE / COMPLETE / STOPPED 无需每帧驱动
} }
} }
@@ -20,11 +20,12 @@ import net.fabricmc.api.Environment;
/** /**
* 扩地规划器:根据当前邦国领土、配置与玩家位置,计算下一步要占领的区块列表。 * 扩地规划器:根据当前邦国领土、配置与玩家位置,计算下一步要占领的区块列表。
* *
* <p>支持三种扩地策略: * <p>支持四种扩地策略:
* <ul> * <ul>
* <li>策略 1:方形外扩(优先填内部空洞,再向外一圈圈扩展)</li> * <li>策略 1:方形外扩(优先填内部空洞,再向外一圈圈扩展)</li>
* <li>策略 3:玩家周围扩地(围绕玩家从近到远铺开)</li>
* <li>策略 4:绕国一圈(沿领土边界按角度均匀向外扩张)</li> * <li>策略 4:绕国一圈(沿领土边界按角度均匀向外扩张)</li>
* <li>其他(2/3):直线推进(沿一个方向连续向外延伸)</li> * <li>其他(2 无圈选区域 / 未知值):直线推进(沿一个方向连续向外延伸)</li>
* </ul> * </ul>
*/ */
public final class ExpansionPlanner { public final class ExpansionPlanner {
@@ -45,6 +46,8 @@ public final class ExpansionPlanner {
result = this.generateHolePriority(model, config, playerChunk); result = this.generateHolePriority(model, config, playerChunk);
} else if (config.strategy == 4) { } else if (config.strategy == 4) {
result = this.generatePerimeter(model, config, playerChunk); result = this.generatePerimeter(model, config, playerChunk);
} else if (config.strategy == 3) {
result = this.generateAroundPlayer(model, config, playerChunk);
} else if (config.strategy == 2 && config.regionMaxX >= config.regionMinX) { } else if (config.strategy == 2 && config.regionMaxX >= config.regionMinX) {
result = this.generateRectangle(model, config, playerChunk); result = this.generateRectangle(model, config, playerChunk);
} else { } else {
@@ -164,7 +167,32 @@ public final class ExpansionPlanner {
} }
/** /**
* 策略 2/3:直线推进。 * 策略 3:玩家周围扩地。
*
* <p>收集所有与己方领土相邻的合法区块,以玩家当前位置为中心,
* 按与玩家的曼哈顿距离由近到远排序(距离相同者优先邻居数多、形状更紧实的),
* 围绕玩家一圈圈向外铺开,而非沿固定方向直线推进。</p>
*/
private List<ChunkPos> generateAroundPlayer(TerritoryModel model, ExpansionConfig config, ChunkPos playerChunk) {
Set<ChunkPos> actualOwn = this.ownChunks(model);
Set<ChunkPos> allClaimed = model.allClaimedChunks();
if (actualOwn.isEmpty()) {
return List.of();
}
int limit = config.targetCount > 0 ? config.targetCount : 64;
HashSet<ChunkPos> plannedOwn = new HashSet<ChunkPos>(actualOwn);
HashSet<ChunkPos> candidates = new HashSet<ChunkPos>();
this.addNeighbors(plannedOwn, candidates, allClaimed, config);
if (candidates.isEmpty()) {
return List.of();
}
Comparator<ChunkPos> byDistance = Comparator.comparingInt(playerChunk::manhattanDistance)
.thenComparingInt(chunk -> -this.ownNeighbors(chunk, plannedOwn));
return candidates.stream().sorted(byDistance).limit((long)limit).toList();
}
/**
* 策略 2(无圈选区域时)/ 未知策略回退:直线推进。
* *
* <p>从玩家当前位置出发,沿一个方向连续向外延伸占领区块(形成一条"线")。 * <p>从玩家当前位置出发,沿一个方向连续向外延伸占领区块(形成一条"线")。
* 每步从候选集中挑选评分最优的区块:距离越近、越贴合当前方向、邻居越多、形状越规整越好。 * 每步从候选集中挑选评分最优的区块:距离越近、越贴合当前方向、邻居越多、形状越规整越好。
@@ -456,7 +484,7 @@ public final class ExpansionPlanner {
return chunk.x() >= config.regionMinX && chunk.x() <= config.regionMaxX return chunk.x() >= config.regionMinX && chunk.x() <= config.regionMaxX
&& chunk.z() >= config.regionMinZ && chunk.z() <= config.regionMaxZ; && chunk.z() >= config.regionMinZ && chunk.z() <= config.regionMaxZ;
} }
// 回退到圆形区域(中心+半径) // 回退到以中心+半径限定的正方形区域(切比雪夫距离,与"圈数"距离定义一致)
int dx = Math.abs(chunk.x() - config.regionCenterX); int dx = Math.abs(chunk.x() - config.regionCenterX);
return Math.max(dx, dz = Math.abs(chunk.z() - config.regionCenterZ)) <= Math.max(1, config.regionRadius); return Math.max(dx, dz = Math.abs(chunk.z() - config.regionCenterZ)) <= Math.max(1, config.regionRadius);
} }