生成条件(SpawnCriteria)
基本信息
| 属性 | 值 |
|---|---|
| 类 | greymerk.roguelike.dungeon.settings.SpawnCriteria(dungeon/settings/SpawnCriteria.java:17) |
| 实例字段 | weight、biomes、biomeTypes、dimensionBlackList、dimensionWhiteList(:19-23) |
| 判定方法 | isValid(IWorldEditor, Coord)(:89-130) |
| JSON 键 | weight、biomes、biomeTypes、dimensionBL、dimensionWL(:30,32,41,50,59) |
| 缺省权重 | 1(:26) |
| 承载者 | 每个 DungeonSettings 持有一个 criteria(SettingsResolver.java:59 为 base 装 new SpawnCriteria()) |
功能
SpawnCriteria 决定「这套地牢设置能不能在当前坐标生成」。判定分三道关,任一不过即返回 false:
- 维度黑名单:当前维度 ID 命中
dimensionBL→ 否决 - 维度白名单:白名单非空且当前维度不在其中 → 否决
- biome 过滤:两个列表都为
null时直接放行(:113);否则要求 biome 名或 biome 类型至少命中一项
白名单与黑名单的判定顺序是黑名单优先,两者可叠加:配置文件的 dimensionWL 会被 addAll 进每套设置自己的白名单。
判定流程
Integer dimID = editor.getDimension();
List<Integer> dimBL = new ArrayList<Integer>();
if (this.dimensionBlackList != null) {
this.dimensionBlackList.addAll(this.dimensionBlackList); // ← 见下方缺陷
}
dimBL.addAll(RogueConfig.getIntList(RogueConfig.DIMENSIONBL));
if (dimBL.contains(dimID)) return false;
(dungeon/settings/SpawnCriteria.java:91-101)
⚠️ 缺陷:dimensionBL 的 JSON 键被静默忽略
逐字引用 —— dungeon/settings/SpawnCriteria.java:95-97:
if (this.dimensionBlackList != null) {
this.dimensionBlackList.addAll(this.dimensionBlackList);
}
问题:这一行把列表加到它自己身上,而不是加到局部的 dimBL。紧接着 :99 才 dimBL.addAll(RogueConfig.getIntList(RogueConfig.DIMENSIONBL))——于是 dimBL 里只有配置文件里的维度,来自 JSON 的 dimensionBlackList 一次都没进来。对照紧随其后的白名单写法(:105-107 是 dimWL.addAll(this.dimensionWhiteList),目标正确),这一行应是 dimBL.addAll(this.dimensionBlackList)。
后果:JSON 设置包里写 "dimensionBL": [2] 完全无效,该地牢仍会在下界(维度 -1)生成。
副作用:每次调用 isValid 都会执行一次自我 addAll,使 this.dimensionBlackList 长度翻倍(ArrayList.addAll(this) 走 System.arraycopy 扩容后按 numNew 追加)。由于判定时读的是从未被填充的 dimBL,这个膨胀不影响判定结果,但会随判定次数单调增长。
意图证据:SpawnCriteria.java:95-97 处没有 TODO 或任何说明注释;紧邻的 :105-107 用了正确写法,说明 :96 更像是复制粘贴时的笔误而非有意设计。仓库只有 1 个 commit(git rev-list --count HEAD = 1),无提交历史可考。据此记录为缺陷,但不主张作者意图。
biome 判定
| 判定方式 | 实现 | 来源 |
|---|---|---|
| 按 biome 注册名 | this.biomes.contains(biome.biomeName) |
:119-121 |
按 BiomeDictionary.Type |
BiomeDictionary.isBiomeOfType(biome, type) |
:123-127 |
两种方式都是或关系:任一命中即 biomeFound = true。列表为 null 时该项被跳过。
另有第二层独立的 biome 过滤:Dungeon.validLocation 无条件排除 RIVER / BEACH / MUSHROOM / OCEAN(dungeon/Dungeon.java:168-174),这一层不受 SpawnCriteria 控制。
数值
| 数值名 | 值 | 来源 |
|---|---|---|
| 判定方法内检查的关卡数 | 3(维度黑、维度白、biome) | dungeon/settings/SpawnCriteria.java:101,111,113 |
缺省 weight |
1 | dungeon/settings/SpawnCriteria.java:26 |
缺省 dimensionWL(配置) |
[0] —— 仅主世界 |
config/RogueConfig.java:88-91 |
缺省 dimensionBL(配置) |
[] —— 空 |
config/RogueConfig.java:92-93 |
| 无条件排除的 biome 类型数 | 4 | dungeon/Dungeon.java:169-170 |
isValid 提前放行条件 |
两个 biome 列表均为 null |
dungeon/settings/SpawnCriteria.java:113 |
交互
| 触发 | 行为 |
|---|---|
| 每套内置/自定义地牢设置被考虑时 | SettingsResolver.getBuiltin / getCustom 逐个调 setting.isValid(editor, pos)(SettingsResolver.java:227,239) |
/roguelike settings reload |
重新构造 SettingsResolver,criteria 随之重建 |
修改 dimensionWL |
需 /roguelike config reload 后生效 |
/roguelike dim |
打印当前维度 ID,便于对照白名单配置 |
相关条目
- 配置项 -
dimensionWL/dimensionBL的定义与默认值 - JSON 地牢设置包 -
SpawnCriteria的 5 个 JSON 键由设置包提供 - 世界生成流程 -
isValid的调用方与网格算法