
百分比护甲伤害减免框架 - BG3SE资源
MODDER'S RESOURCE —— 非独立平衡模组。一个BG3脚本扩展器参考实现,用于为护甲添加真实基于百分比的伤害减免,并同步生命值伤害、头顶数字和战斗日志输出。
查看大图百分比护甲伤害减免框架
这是一个模组制作者的资源和参考技术实现,用于使用 Norbyte 的 BG3 脚本扩展器为《博德之门 3》添加基于真实百分比的护甲伤害减免。
该项目始于一项实验,旨在寻找一种可靠的方法来实现百分比护甲伤害减免,而无需依赖固定的 DamageReduction 加成或特定来源的法术/武器豁免。
内置的基线实现保持原版护甲等级不变,并为每件已映射的护甲赋予与其 AC 值相等的自定义伤害减免百分比。
例如: 板甲:AC 18 + 18% 自定义护甲伤害减免 板甲 +1:AC 19 + 19% 自定义护甲伤害减免 板甲 +2:AC 20 + 20% 自定义护甲伤害减免 板甲 +3 / AC 21 护甲:21% 自定义护甲伤害减免
此映射仅为基线。百分比曲线可以自由更改,无需改动底层的伤害处理架构。
该框架的功能
该系统是事件驱动且来源无关的。 它不需要针对个别武器、法术、炸弹、神圣打击、物品附加伤害或范围效果进行特殊处理。相反,它基于引擎产生的实际伤害数据包运作。
该实现:
- 在
DealDamage期间检测目标的已映射护甲 - 通过同步 LIFO 上下文栈将护甲信息传递到
BeforeDealDamage - 读取
Hit.DamageList - 跳过持续性的
StatusTick伤害 - 为当前伤害事件计算一个百分比减免
- 通过
Hit.TotalDamageDone写入真实 HP 结果 - 同步
Hit.DamageList,使飘字伤害数字和战斗日志显示相同的结果 - 在
DealtDamage期间弹出上下文
最重要的实证发现是 BG3 暴露了两个具有不同实际效果的可写伤害表示:
Hit.TotalDamageDone 控制实际的 HP 损失。
Hit.DamageList[].Amount 控制用于飘字和战斗日志的显示伤害路径。
仅修改 DamageList 可以使显示的伤害看起来减少,但目标仍会损失原始 HP 量。一个正确的实现需要以协调的方式同时更新两者。
伤害类型
内置基线将护甲伤害减免应用于所有 13 种标准 BG3 伤害类型,条件是事件为直接 / 非 StatusTick:
强酸 钝击 冷冻 火焰 力场 闪电 黯蚀 穿刺 毒素 心灵 光耀 挥砍 雷鸣
持续性伤害被全局处理:
CauseType == StatusTick → 无自定义护甲伤害减免
这意味着诸如持续的燃烧、强酸伤害和持续性区域效果的脉冲会绕过自定义护甲层,而无需法术特定的豁免。
强酸护甲腐蚀
参考实现还包含了与原版 ACID 状态的可选交互。
该状态本身可以保留:
AC(-2)
当目标处于 ACID 状态时,Lua 层会额外将自定义护甲伤害减免降低 2 个百分点,最低为 0%。
示例: 皮甲:11% → 9% 锁子甲:16% → 14% 板甲:18% → 16% AC 21 护甲:21% → 19%
这让强酸能够表现为真正的护甲腐蚀,而不仅仅是在伤害上加成。
重要的引擎发现
在达成当前实现之前,测试了多种方法。
仅修改 DamageList 不会改变真实 HP 伤害
早期实验直接修改了 Hit.DamageList 和 Attack.DamageList。
飘字伤害数字和战斗日志发生了改变,但实际 HP 损失并未改变。
这最初看起来像是一个失败的方法,但后来在真实伤害值被修改后,它成为同步 UI 的解决方案。
Hit.TotalDamageDone 是真实的每事件 HP 写入
写入:
hit.TotalDamageDone = finalDamage 在测试路径中一致地改变了实际的 HP 损失。
不要使用 Attack.TotalDamageDone 作为每事件伤害
在神圣打击测试期间,Attack.TotalDamageDone 在构成性伤害事件之间变得具有累积性。
例如,一个 32 伤害的主事件后跟一个 12 伤害的反应神圣打击事件,在第二个事件期间产生了 44 的攻击总伤害。
因此,该框架从不使用 Attack.TotalDamageDone 作为权威的每事件值。
不要使用 Hit/Attack 指针身份关联事件
DealDamage 和 BeforeDealDamage 暴露的 Hit 和 Attack 对象在测试期间没有保留有用的指针身份。
同步的 LIFO 上下文栈保持对齐,并被证明是实用的解决方案。
CauseType == Attack 并不意味着"攻击检定"
豁免/范围法术路径(如闪电链)可能显示为 CauseType = Attack,而反应神圣打击伤害可能显示为 CauseType = None。
因此,该框架不使用 CauseType 作为通用的伤害来源分类器。
唯一的特殊全局情况是:
StatusTick → 绕过护甲伤害减免。
混合伤害与取整
混合伤害需要特别注意。
考虑:
5 挥砍 + 5 火焰 在 13% 护甲伤害减免下。
正确的事件级减免为:
round(10 × 0.13) = 1
如果每个数据包独立取整:
round(5 × 0.13) + round(5 × 0.13) = 1 + 1 = 2 则 UI 会显示 8 点伤害,而实际 HP 损失会是 9。
因此,内置的同步函数一次计算总减免量,并将该精确的整数减免分配到符合条件的 Hit.DamageList 数据包中。
这保证了:
实际 HP 损失 = 飘字伤害 = 战斗日志伤害
已测试的伤害路径
该架构针对多种伤害来源进行了测试,包括:
- 普通近战和远程攻击
- 混合伤害数据包
- 强酸箭
- 魔法飞弹
- 符文火药爆炸
- 寒冰锥
- 闪电链
- 震荡猛击 / 姿态破坏
- 神圣打击
- 反应神圣打击
- 强化神圣打击
- 武器和物品附加伤害
- 范围法术伤害
- StatusTick 效果,如燃烧、强酸和匕首之云
神圣打击测试尤其有用,因为引擎对普通神圣打击、反应神圣打击和强化神圣打击有着不同的打包方式。基于 DamageList 的方法无需神圣打击特定代码即可处理所有情况。
与原版减伤机制的交互
自定义护甲伤害减免作用于已经到达 BeforeDealDamage 的伤害值。
在一个测试过的地狱狱甲路径中:
13 点原始伤害
-3 点火焰至高守护
= 10 点进入自定义护甲伤害减免的伤害
百分比减免随后基于该剩余值计算。
因此,在测试设置中,抗性也是以乘法而非加法方式组合的。
示例:
100 点伤害
50% 抗性 → 50
18% 护甲伤害减免 → 41
总有效减免为 59%,而非 68%。
包含的文件
压缩包内包含:
BootstrapServer.lua
可用的基线 BG3SE 实现。
技术文档 (.docx) 包含实验、失败方法、引擎观察、伤害策略决策和实现架构的详细记录。
功能性的 BootstrapClient.lua 对此资源并非必需,因为伤害系统在服务端运行。
重要集成说明
包含的示例通过自定义的隐藏 LIB_* 被动技能来识别护甲。
这些被动 ID 是原型识别数据,而非该架构的必需条件。
如果将该系统集成到另一个模组中,请用适合您项目的任何系统替换护甲映射/识别层。
可复用的关键部分包括:
DealDamage → BeforeDealDamage → DealtDamage的 LIFO 桥接Hit.TotalDamageDone真实伤害写入Hit.DamageList分类和 UI 同步- 事件级百分比计算
- 精确的混合数据包减免分配
护甲百分比表本身只是调优数据。
要求
Norbyte 的《博德之门 3》脚本扩展器
这主要被设计为模组制作者的资源,而非一个成品独立游戏模组。 建议具备 BG3 数据基础和脚本扩展器 Lua 的基本知识。
已知边界
StatusTick被有意排除在护甲伤害减免之外。- 坠落伤害未出现在测试过的
DealDamage → BeforeDealDamage桥接中。 - 测试过的流血状态脉冲也未出现在该桥接中。
- 每个伤害事件执行一次百分比取整运算。
- 如果一个概念性攻击被分割为多个引擎伤害事件,每个事件独立取整。
- 未知的未来伤害类型不会被盲目减免,除非添加到已识别的类型表中。
这些是刻意的架构边界,而非试图对每种可能的伤害来源进行特殊处理。
为何将此作为资源发布?
这个项目的有用之处不仅在于最终的 Lua 文件。 大量测试用于确定哪些可写伤害值实际影响 HP,哪些仅影响 UI 输出,多事件伤害如何表现,以及哪些事件关联是可靠的。
与其将这些发现保密,不如将资源发布,以便其他 BG3 模组制作者可以使用、修改、改进或在此基础上构建。 这里并未声称这是 BG3 有史以来第一个百分比护甲伤害减免实现。 目标只是记录一种经过测试的方法,并让底层信息对社区可用。
安装 / 集成
这主要是一个模组制作者资源。
示例脚本扩展器结构为:
Mods
└── ArmorDR
└── ScriptExtender
├── Config.json
└── Lua
├── BootstrapServer.lua
└── BootstrapClient.lua
伤害实现本身运行在 BootstrapServer.lua 中。
BootstrapClient.lua 不需要功能代码即可运行该系统。
包含的 Lua 期望原型 LIB_* 护甲识别被动技能。如果在其他项目中使用该资源,请复现相关的被动映射,或使用您自己的护甲检测方法替换 GetArmorProfile()。
提供的基线期望护甲 AC 值保持原版,并将相同的数值映射为护甲伤害减免百分比。
兼容性
该资源不会直接替换原版伤害法术、武器攻击或个别伤害来源。
兼容性主要取决于:
- 其他模组如何识别或修改护甲
- 其他脚本扩展器模组是否在同一伤害事件期间也写入
Hit.TotalDamageDone或Hit.DamageList - 其他模组是否大幅改变 BG3SE 伤害事件的管线
只添加武器、法术、炸弹或伤害附加效果的模组通常不需要来源特定的支持,因为该框架作用于最终的伤害数据包,而非硬编码的法术或武器 ID。
如果另一个模组也在 BeforeDealDamage 中修改最终伤害,应测试加载/顺序交互,而非凭空假设。
权限
欢迎将本代码和记录的发现自由使用、修改、改编或整合到您自己的 BG3 模组中。 无需请求许可。 注明出处值得感谢,但并非强制要求。
如果您改进了实现或发现了额外的引擎行为,欢迎与社区分享这些发现。
正在加载版本记录…
正在加载评论…
评论在新手盒子客户端中发表,这里同步展示。