跳到正文

点数成本购买一条指令,并不指定该僵尸的生命值。强度通过三个独立输入确定:指令请求等级、创建修正后的实体有效等级,以及共享生命值/攻击表。首领标记则是之后的另一次操作。

从显示关卡数到整数请求

基线系数为 ZombieLevelBase = 0.9 和 ZombieLevelAdd = 0.1。令 F32F_{32} 表示舍入到 float32,fma⁡32(x,y,z)\operatorname{fma}_{32}(x,y,z) 表示融合计算 xy+zxy+z 后再进行该舍入。十进制截断与等级曲线为

D(x)=F32 ⁣(trunc⁡(F32(10x))10),q(L)=min⁡(10,D ⁣(fma⁡32(L,F32(0.1),F32(0.9)))).\begin{aligned} D(x)&=F_{32}\!\left(\frac{\operatorname{trunc}(F_{32}(10x))}{10}\right),\\ q(L)&=\min\left(10,D\!\left(\operatorname{fma}_{32}(L,F_{32}(0.1),F_{32}(0.9))\right)\right). \end{aligned}

定义整数边界 a=clamp⁡(⌊q⌋,1,10)a=\operatorname{clamp}(\lfloor q\rfloor,1,10) 与 b=clamp⁡(⌈q⌉,1,10)b=\operatorname{clamp}(\lceil q\rceil,1,10)。若 a=ba=b,每条指令都请求该等级。否则,对下一个整数抽取令 d=u mod 100d=u\bmod100,并计算

τ=F32 ⁣(100F32(q−a)),ℓrequest={b,d<τ,a,d≥τ.\tau=F_{32}\!\left(100F_{32}(q-a)\right),\qquad \ell_{\mathrm{request}}=\begin{cases} b,&d<\tau,\\ a,&d\ge\tau. \end{cases}

因此,小数部分用于在相邻整数等级之间选择,本身不是存储的实体等级。在基线中,从第 91 关起,请求固定为 [10,10][10,10]。11Float32 等级请求原生流程使用 float32 基础值/增量系数进行融合乘加,再做小数截断、限制上限为 10,最后将下取整/上取整结果限制到 1–10。边界不同时,整数余数小于 float32 小数部分乘以 100 的结果,就接受较高等级。默认输入 2 与 3 都产生约 1.100000024,并接受余数 0–10。0x101d4561c0x101b3a27c

Float32 无法精确表示每个十进制小数。输入 2 和 3 经过原生截断序列后,都得到约 1.100000024;它们略大于 10 的阈值接受余数 0–10。下方视图公开每个普通关卡的边界、阈值与接受余数。

第 3 关

q
1.100000024介于 1 与 2 之间
τ
10.000002

余数 d = u mod 100

  • 11 个余数请求 2 级
  • 89 个余数请求 1 级
图版 4.1每个显示关卡数是一个格子,每行十个:一行从一个整数等级经过各十分位走向下一个,直到第 91 关起请求固定为 10;格子按请求上界的余数比例填充,5 的倍数选择 Boss 文件,留空。第 3 关的 q = 1.100000024,介于 1 与 2 之间,τ = 10.000002,因此余数 0–10 请求 2 级。

这个余数检查属于普通生成指令。摩登世界传送门子僵尸使用相同的等级边界,但采用另一条全局浮点抽取路径。

确定实体等级,再选择模式对应的表

创建过程可以先应用等级模块修正,再保存有效等级 ℓ\ell。ZombieMaxLevel 默认为 −1-1,因此除非被覆盖,否则其限制不生效。普通关卡定义没有施加五级上限。

对于 DangerRoom 中的非 Zomboss 实体,两种倍率都来自共享的 ZombieLevelStats 向量,使用索引 ℓ−1\ell-1。这条路径不读取类型自身的等级数值向量。潘妮的追击使用独立的 Rift 配置;NewPVP 还有另一条共享表分支。

无尽实战参考

生命值示例,包括波次构建视图,默认使用下列十级无尽参考。

等级生命值攻击(反馈)
111
221.2
331.4
451.6
5152
6503
72505
81,00010
95,00030
10100,000100
图版 4.2十级无尽参考,两列都相对于 1 级。生命值按对数刻度绘制,每条网格线相差十倍:十级之间增长 100,000 倍。攻击列是反馈值,不是原生 AttackLevel 输入。

两列都相对于 1 级。攻击一列是反馈的相对数值;下方啃咬公式中的 aℓa_\ell 则是独立的原生 AttackLevel 输入。将最终伤害比例代入这个输入,会重复计算额外等级因子。

DangerRoom 的五行表与替换规则

DefaultDangerRoomProps 包含五行:HitPointsLevel 与 AttackLevel 都是 1、2、3、4.5 和 5。索引缺失时返回倍率 1,既不重复最后一行,也不外推增长公式。生成器的 1–10 请求范围与这张表的长度是独立输入。22共享表查询与缺失行非 Zomboss 的 DangerRoom 查询使用共享 ZombieLevelStats 向量,以实体有效等级减一作为索引。包内向量有五行,缺失行返回倍率 1;neccd.zls 可以替换有序数值对。采用的十级无尽参考来自实战反馈。其中攻击一列是反馈比例,与原生 AttackLevel 输入分开处理。Rift 与 NewPVP 有独立的选表分支;NewPVP 对应的玩家可见模式未确定。等级模块的 ZombieMaxLevel 默认为 -1,普通定义未声明覆盖值。0x1019938a00x101993af80x101d6db000x100fd8a100x10067f50c

neccd.zls 可以用攻击/生命值对替换整个有序向量。行顺序决定每个有效等级读取哪一对数值。替换表格不需要改变等级曲线,模块级覆盖也不会创建缺失的表格行。

其他表格采用不同的增长序列:

  • 潘妮的追击使用 Rift 路径。其表有 19 行;等级 9–19 的两个字段均声明为 11–21。
  • 在 140 个文件中,主线关卡的五行序列出现在 1,050 处声明中的 916 处。它很常见,但其他类型的声明可能不同。
  • NewPVP 表在等级 8 及之前匹配反馈的 Battlez 数值,等级 9–10 则声明为 10 和 20。
  • 旧版 PvP 对照在等级 4 及之前匹配反馈,但还有数值为 5 的第五行。LocalDiyZombieStatsDefault 的前八个数值与 Rift 相同,随后是 11 和 12。
行Danger­RoomRift主线NewPVP旧版 PvP本地 DIY
1111111
222221.52
3333323
44.54.54.542.54.5
5555555
6缺失:1868
7979
810810
9111011
10122012
1113
1214
1315
1416
1517
1618
1719
1820
1921
Danger­Room
无尽:包内共享表 DefaultDangerRoomProps
Rift
潘妮的追击:Rift 配置 RiftBaseConfigKey
主线
主线关卡对照:木乃伊属性 ZombieMummyDefault
NewPVP
NewPVP:模式对应关系未确定 DefaultNewPVPProps
旧版 PvP
旧版 PvP 对照:小鬼属性 ZombiePVPImpDefault
本地 DIY
本地 DIY 配置 LocalDiyZombieStatsDefault
图版 4.3随包的各张强度表并列,每行对应各表的同一行;格内是该行的 HitPointsLevel,各表每行的 AttackLevel 与之相同。数值越大,底色越深。第 5 行之后 DangerRoom 表没有行,查询在那里读到倍率 1。

反馈的等级 10、100,000 倍生命值可以通过替换路径表示。保存的本体与头盔 HP 仍不同于向波次调度报告的有符号 32 位数值:这条报告路径可能饱和。

生命值与啃咬使用不同计算

其他生命值修正均为中性时,资源数值给出

Hbody=Hbasehℓ,Hhelmet=Hhelm,basehℓH_{\mathrm{body}}=H_{\mathrm{base}}h_\ell,\qquad H_{\mathrm{helmet}}=H_{\mathrm{helm,base}}h_\ell

其中头盔公式在头盔存在时适用。实现还会考虑模块修正与现有生命值削减因子。

啃咬速率查询按以下优先级选择基础速率 EE:

  1. 正值 EatDPSRatio 乘以最大本体 HP。
  2. 否则,使用正的实例 m_extraEatDPS。
  3. 否则,使用正的实例 m_baseEatDPS。
  4. 否则,使用属性 EatDPS。

对于基础啃咬实现,令 aℓa_\ell 表示原生 AttackLevel 字段。在其他目标/类型修正为中性时,

ΔHplant=max⁡ ⁣(0,  E aℓ vattack Δt [1+0.2(ℓ−1)]).\Delta H_{\mathrm{plant}}=\max\!\left(0,\;E\,a_\ell\,v_{\mathrm{attack}}\,\Delta t\,[1+0.2(\ell-1)]\right).

其中 vattackv_{\mathrm{attack}} 是由状态决定的攻击速度因子,Δt\Delta t 是游戏时钟增量。因此,表中的攻击倍率只是一个因子;固定 EatDPS 并不是完整的最终啃咬速率。子类的特殊攻击可以使用其他实现。33基础啃咬速率的选择链速率查询先使用正值 EatDPSRatio 乘以最大本体生命值,再依次选择正值 extraEatDPS、正值 baseEatDPS,最后回退到属性 EatDPS。基础啃咬路径将选中速率乘以攻击表倍率、攻击速度、帧时间和 1 + 0.2 ×(有效等级 - 1),还包含其他状态/类型修正及非负限制。0x1019b55b00x10199f658

对于中性条件下的 5 级 mummy_armor1,声明的本体/头盔 HP 270/370 在反馈生命值倍率 15 下变为 4050/5550。反馈攻击相对于 1 级为 2,不能据此确定原生啃咬速率。

作为对照,DangerRoom 的五行表给出 1350/1850 HP。其 EatDPS = 100、原生攻击倍率 5 与等级因子 1.8,在攻击速度为 1 时产生每游戏秒 900 伤害。视图可以在无尽参考与这项 DangerRoom 表计算之间切换。

实体值声明值倍率实体值
本体生命值270× 154,050
头盔生命值370× 155,550
每游戏秒啃咬100反馈攻击 ×2:啃咬需要原生 AttackLevel
图版 4.4中性 mummy_armor1 在 5 级、采用无尽参考时的数值;上方是两者下各级的生命值倍率,按对数刻度绘制。反馈攻击为 1 级的 2 倍,并不决定啃咬速率。

首领标记改变当前与最大生命值

首次设置真值首领标记时,当前本体 HP 乘以 LeaderStrengthenRate,结果成为最大本体 HP。基线倍率为 2。已有头盔单独强化,重新应用现有护甲生命值削减因子,并限制为非负;所得当前 HP 也成为其最大值。

重复设置真值标记,不会再次相乘;调用假值也不会撤销之前的操作。这条路径既不改变 ℓ\ell,也不改变缓存的攻击表倍率。对于上面使用固定 EatDPS 的路障僵尸,采用的生命值参考给出中性首领结果 8100/11100 HP。在包内表对照中,结果为 2700/3700 HP,计算出的啃咬速率仍是 900。使用 EatDPSRatio 的类型则可以通过更高的最大本体 HP 间接增加啃咬伤害。

首领更新会在本体/头盔合计生命值降至合计最大值约 67% 和 33% 时改变叠加外观。这些转换不会治疗它。在普通五行布局中,符合条件的首领于 X<232X<232 时进入撤退路径,开始 2.3 游戏秒倒计时,并在到期后请求移除。44首领标记与撤退首次标记缩放当前本体生命值并保存为最大生命值;头盔处理还考虑其削减因子。重复设置真值不会再次执行这一操作。这条路径不改变实体等级,也不直接乘算缓存攻击值。外观阈值使用本体/头盔最大生命值之和。普通撤退阈值为 X < 232,倒计时为 2.3 游戏秒。0x1019afe480x10199a84c

注释

每条论断的依据:代码路径,以及追踪到它的原生地址。

  1. 1

    Float32 等级请求

    原生流程使用 float32 基础值/增量系数进行融合乘加,再做小数截断、限制上限为 10,最后将下取整/上取整结果限制到 1–10。边界不同时,整数余数小于 float32 小数部分乘以 100 的结果,就接受较高等级。默认输入 2 与 3 都产生约 1.100000024,并接受余数 0–10。

    0x101d4561c0x101b3a27c
  2. 2

    共享表查询与缺失行

    非 Zomboss 的 DangerRoom 查询使用共享 ZombieLevelStats 向量,以实体有效等级减一作为索引。包内向量有五行,缺失行返回倍率 1;neccd.zls 可以替换有序数值对。采用的十级无尽参考来自实战反馈。其中攻击一列是反馈比例,与原生 AttackLevel 输入分开处理。Rift 与 NewPVP 有独立的选表分支;NewPVP 对应的玩家可见模式未确定。等级模块的 ZombieMaxLevel 默认为 -1,普通定义未声明覆盖值。

    0x1019938a00x101993af80x101d6db000x100fd8a100x10067f50c
  3. 3

    基础啃咬速率的选择链

    速率查询先使用正值 EatDPSRatio 乘以最大本体生命值,再依次选择正值 extraEatDPS、正值 baseEatDPS,最后回退到属性 EatDPS。基础啃咬路径将选中速率乘以攻击表倍率、攻击速度、帧时间和 1 + 0.2 ×(有效等级 - 1),还包含其他状态/类型修正及非负限制。

    0x1019b55b00x10199f658
  4. 4

    首领标记与撤退

    首次标记缩放当前本体生命值并保存为最大生命值;头盔处理还考虑其削减因子。重复设置真值不会再次执行这一操作。这条路径不改变实体等级,也不直接乘算缓存攻击值。外观阈值使用本体/头盔最大生命值之和。普通撤退阈值为 X < 232,倒计时为 2.3 游戏秒。

    0x1019afe480x10199a84c