共同阵容构建之后,世界仍可以改变方案。摇滚年代替换普通指令;恐龙危机和摩登世界添加独立动作;蒸汽时代则在更晚的设置阶段安装场地系统。要理解最终战斗,需要知道事件安排、每个事件执行的操作,以及这些结果进入 Board 的先后顺序。
先抽取端点,再插值
多个设计器使用同一个辅助函数。对于关卡边界为 的参数,它先从包含两端的低关卡和高关卡端点范围中抽取整数 与 ,再计算
原生运算使用 float32 与融合乘加。固定端点仍消耗一次抽取;即使限制后的比例为 0 或 1,也会抽取两个端点。因此,端点范围表定义的是先抽取、再插值,而不是在两个插值后的边界之间均匀抽取。
摇滚年代:安排音乐并替换指令
DangerRoomJamDesigner 在普通填充之后运行,使用全局 RNG。它在战斗创建这些僵尸之前,就将音乐事件准备到波次属性中。
先选择音乐集合
第 7 关之前,候选为 Pop、Punk、Rap 和 8-bit。Metal 从第 7 关加入。所需的不同音乐数量从第 1 关的 2 插值到第 15 关的 5,并受合格候选数量限制。设计器重复抽取候选,直到拥有足够多的不同类型。重复结果被丢弃,但仍消耗该次随机抽取。
之后,每个事件都从这个完整子集中抽取。连续事件可以选择相同音乐。 子集选择不重复,不代表事件序列也不重复。jam_ballad 出现在更广泛的音乐列表中,但不属于这份无尽候选列表。
再选择事件波次
音乐安排独立于第 1 章中的旗帜间隔。令 表示第 个事件从零开始的波次索引:
每个 都是一次新的端点抽取插值,使用关卡边界 1–15。在 时继续添加事件。
| 参数 | 第 1 关端点 | 第 15 关及以后端点 |
|---|---|---|
| 不同音乐类型数量 | 2 | 5 |
| 首次事件,从零开始的波次索引 | 3–4 | 1–2 |
| 后续事件间隔,单位为波 | 4–5 | 2–3 |
因此,低端点的首个事件位于玩家视角第 4–5 波,高端点则位于第 2–3 波。事件间隔按波计数,不按秒;每个事件之后的间隔都会重新抽取。
一个事件改变什么
对于一次事件,设计器从下表选择一种替换类型。Rap 为整个事件选择一次,而不是为每条被替换指令单独选择。
| 通知事件 | 替换类型 |
|---|---|
jam_pop | eighties_glitter |
jam_punk | eighties_punk |
jam_rap | eighties_mc 或 eighties_breakdancer |
jam_8bit | eighties_arcade |
jam_metal | eighties_gargantuar_danger |
替换数量使用独立的关卡范围 1–50,端点范围为 1–2 和 5–7。结果不超过当前指令数。每次移除时,设计器从剩余索引中选择一个,保存该指令的等级,将最后一条指令移入其槽位,再缩短向量。之后,使用保存的等级,追加选定替换类型的新指令。
只有等级被带入新指令。新指令的其他字段采用默认值,包括为假的首领标记。未选中指令保留自身字段,但交换移除可以改变其顺序。最终数量与等级多重集保持不变,总成本和首领标记则可能变化。流程不重新执行普通预算检查,因此 Metal 可以加入巨人,即使替换成本超过原始额度。
事件名被追加到 NotificationEvents。运行时,动作先创建并放置整批实体,再发出这些通知。替换早已在生成阶段决定;通知送达,才是音乐事件之后进入 Board 的时点。
AdditionalPlantfood 保持不变。其携带者请求之后才根据修改后的顺序和类型分配。一般掉落分配也在之后运行,使用替换后的成本。最后,波次生命值快照在位置处理后测量最终符合条件的实体。这是同一个替换流程对三个后续环节产生的不同影响。
恐龙危机:在阵容之外追加事件
候选类型为 raptor、stego、ptero、tyranno 和 ankylo。设计器通过重复抽取不同类型形成子集,再为每个恐龙事件选择一种类型。端点插值使用关卡边界 1–20。
| 参数 | 第 1 关端点 | 第 20 关及以后端点 |
|---|---|---|
| 选中的恐龙类型 | 2 | 5 |
| 首次事件,从零开始的波次索引 | 3–4 | 2–3 |
| 后续事件间隔,单位为波 | 3–4 | 1–2 |
| 事件中的恐龙数量 | 1–2 | 3–4 |
首次索引与后续间隔共同定义事件序列,方式与上文相同。事件发生的波次中,请求数量的恐龙动作被追加到普通僵尸动作旁。行号从 0–4 的可消耗列表中抽取;若剩余条目不足以供下一个事件使用,就补充列表。这些选择消耗全局 RNG,不花费普通僵尸预算。
摩登世界:事件创建带有独立队列的传送门
回退候选包含十个家族:摇滚年代、恐龙危机、失落之城、冰河世界、巨浪沙滩、黑暗时代、未来世界、狂野西部、古埃及和海盗港湾。它们的初始选择权重均为 1.0。设计器不放回地选择家族,子集大小从第 1 关的 1 增长到第 30 关的 4。每个传送门事件波从这个子集中选择一个家族。
| 事件参数 | 第 1 关端点 | 第 30 关及以后端点 |
|---|---|---|
| 首次事件,从零开始的波次索引 | 4 | 2–3 |
| 后续事件间隔,单位为波 | 4 | 2 |
| 一次事件中的传送门数量 | 1 | 3–4 |
| 生成列,从零开始 | 8 | 5–6 |
| 计算出的每门僵尸数量 | 1–2 | 3–4 |
| 计算出的列表起始索引 | 0 | 0 |
| 计算出的列表结束索引 | 0 | 3 |
行号从 0–4 中不放回抽取,并按需补充。家族与行选择使用传入的设计器 RNG;端点插值消耗全局 RNG。
最后三个计算值没有被普通 SpawnModernPortalsWaveAction 传递。它只传递传送门家族和位置,让运行时数量/起始/结束覆盖值保持默认。这些被丢弃的计算仍消耗了随机抽取。
因此,传送门复制家族的完整四槽列表,再通过导入的 C++ RNG 机制打乱。重复名称仍然是独立槽位。古埃及的源列表为 ra、explorer、explorer、pharaoh:包含两个 Explorer 槽位,而非一个。下方视图可以检查全部十个家族。
开启、释放与关闭
首次请求截止时间为创建时刻加上随机偏移;该偏移在零与一个从 10–12 秒区间抽出的值之间抽取。释放还要等待开启完成。每个后续间隔加在前一次计划截止时间上,而不是简单地加在延迟发生的实际释放时刻上。
每个释放出的子僵尸获得波次标记 。它不计入普通当前波次生命值,也不获得初始场外加速,但仍参与独立的胜利和失败谓词。其请求等级边界来自共享 DangerRoom 曲线,但使用全局浮点抽取进行选择,而非普通指令的整数余数比较。
最后一个槽位释放后,传送门仍会安排下一次到期检查。之后的检查发现空队列,才开始关闭;关闭动画回调随后请求移除。在移除之前,传送门自身仍是完成阻塞因素,与存活的子僵尸相互独立。
蒸汽时代:固定场地系统与独立时钟
蒸汽时代使用更晚的设置钩子。令 ,其数量为
烟雾孔数量在第 34、67、100 关首次达到 1、2、3;管道数量在第 21、41、61、81、100 关达到 1–5。位置固定:玩家视角中,烟雾位于第 6 列,从第 2 行起;管道从第 7 列通往第 5 列,从第 1 行起。
首次烟雾启动参数从 15 插值到 30 秒。烟雾伤害与管道堵塞伤害都从 30 插值到 100,使用管道命名的伤害字段。烟雾启动调用使用字段的顺序,与 Min/Max 名称暗示的顺序相反。
烟雾等待事件
开始调用时,首次预警截止时间为 ;首次喷发截止时间则独立设为 。喷发动画完成才激活烟雾。活动期间,累计值严格大于 1 秒时执行一次伤害检查,再减去 1 秒。检查在烟雾孔所在格及周围八格中,各选择一个植物目标,而非独立伤害每一个叠放层。
活动烟雾不会自动在五秒后到期。必须先完成 blow_off 或 absorb 等清除路径。其移除事件开始冷却:下次预警为清除时刻 + 5 秒,下次喷发再晚 3 秒,尚未计入额外延迟。所检查的移除事件没有携带所属烟雾孔参数,而是广播给已注册的烟雾孔处理器。
管道保留同一批实体
进入要求实体位于入口格、X 坐标与入口距离严格小于 0.5、运行时体型为 small,并通过包含 CanBeLaunchedByPlants 在内的共享能力/状态检查。蒸汽时代矿工为 mid,巨人为 big,因此不能通过这个体型条件。
普通路径的两列距离产生 2 秒时长参数,但实体截止时间分别为 、 和 。它从地下阶段截止时间起使用出口位置,只有严格超过最终截止时间才完成。多个僵尸可以同时处于运输中;这并非一次只服务一个对象的队列。
作为阻挡植物的平顶菇(flattenedshroom)可以延长地下与完成截止时间;其随包 BlockTime 为 12 秒。只要仍有运输对象引用,每次更新就对每株阻挡植物施加一次 DamagePerSecond 乘以游戏时间增量的伤害,不按运输僵尸数量重复施加。运输保留原等级与波次标记,基础当前波次生命值查询也不排除 ZS_StuckInGround 状态。