生成条件(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:

  1. 维度黑名单:当前维度 ID 命中 dimensionBL → 否决
  2. 维度白名单:白名单非空且当前维度不在其中 → 否决
  3. 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,便于对照白名单配置

相关条目