【我帮鹰角修bug】囚犯们神秘的解放机制
前言和bug简介
这个系列内容大概是科学分析一些游戏bug或"bug"的原理并给出可能的解决方案
往期内容欢迎查看本人专栏
本期的是新囚犯敌人专场,新囚犯敌人的解放机制上出现了2个bug
第一个:囚犯敌人处于警报模式时(即身上橙光闪烁),无法被重犯强制激活。详情可见此视频约1分30秒处
第二个:弓箭手囚犯解放后被禁锢,再次进入解放模式仅需3次远程攻击,且跳过警报模式
本期内容中第2个bug的分析与fux2大佬共同完成,在此特别感谢

囚犯机制的详解
在弄清楚bug的成因前,首先需要知道囚犯的详细机制
囚犯一共拥有3种模式,分别为:禁锢模式,警报模式,解放模式
进入禁锢模式时,会创建4层buff(以下简称为计数buff)
计数buff的效果为:在进行攻击前,减少一层计数buff(最低降至0),随后判断计数buff的层数,如层数等于1,则切换至警报模式
进入警报模式0.05s后,会创建另一个buff(以下简称为警报buff)
警报buff的效果为:在进行攻击前,减少一层计数buff(最低降至0),随后切换至解放模式
警报buff属于衍生buff,仅可存在于警报模式下(退出警报模式时自动结束)
解放模式下,会持有特征buff,方便禁锢装置判断目标是否处于解放模式

无法强制解放的警报模式
首先是第一个bug,警报模式的囚犯无法被重犯(或杰斯顿)强制激活
重犯的强制解放的机制为,检测敌人身上是否持有计数buff,如果持有计数buff,则清空计数buff(层数直接归0),并直接将其切换至解放模式
这里可以直接进行推测,由于某种原因,警报模式下的囚犯,身上不存在计数buff,因此无法被重犯强制解放
进一步推测可以发现,导致计数出问题的,只可能出现在“进行攻击前”这个节点上
让我们实际推一遍囚犯计数buff的变化:
4层buff -> 攻击前,4-1层,剩余3层 -> 第1次攻击 -> 攻击前,3-1层,剩余2层 -> 第2次攻击 -> 攻击前,2-1层,剩余1层,切换至警报模式
问题出现在这里,切换至警报模式后,原本还未进行的攻击由于模式切换不复存在,无法继续进行
而切换至新模式后,程序会立刻尝试下一次攻击,触发成功后会再次触发一个“进行攻击前”的节点
因此后续的逻辑为:
攻击前,2-1层,剩余1层,切换至警报模式 -> 攻击前,1-1层,剩余0层 -> 第3次攻击
很明显可以看出,在第3次攻击开始后,计数buff由于“进行攻击前”节点的多次触发,已经不复存在
因此,重犯无法强制激活警报模式下的敌人
修复方案1:进入警报模式极短时间后,再创建一层计数buff(不推荐)
修复方案2:让重犯在检测到禁锢模式特征buff(enemy_confinement)或警报模式特征buff(enemy_liberty[warning])时,可强制解放目标

只需三次攻击解放的弓箭手
然后是第二个bug,弓箭手囚犯解放后被禁锢,再次进入解放模式仅需3次远程攻击,且跳过警报模式

这个bug比较诡异,我们可以先从逻辑上进行一些推理
首先,不考虑其它单位的情况下,能切换至解放模式只有一种手段,就是触发了警报buff(即在已经获得了警报buff的情况下,触发一次“进行攻击前”节点)
但是获取警报buff只有一种途径,即切换至警报模式0.05s后
所以,从理论上来讲,警报模式不可能被跳过,只是持续了一个极短的时间
但是,最令人迷惑的点不是上面的内容,而是:为什么解放后再禁锢会导致前后出现差异?这其中发生了什么变化吗?
多遍确认后,可以确定:对比再次禁锢前后的禁锢模式,buff并没有发生任何变化
那么可以确定变化并不是出在buff身上
这个bug还有一点很特殊的地方在于
囚犯敌人中仅弓箭手会出现这个bug
经测试后发现,出现这个bug的条件是使用远程攻击,弓箭手使用近战攻击时并不会触发这个bug
对于敌方单位来说,近战攻击和远程攻击的不同之处在于状态机的不同(近战阻挡使用Combat,远程攻击使用Attack)
而状态机的不同,带来的一个区别是,敌人的远程攻击需要使用触发器(Trigger)来判断条件进行触发,而近战攻击不需要这个,可以直接触发
每个模式使用不同的触发器
最常用的一种触发器是选择触发器(SelectorTrigger)
大概逻辑就是,攻击范围内有指定个符合选择器条件的单位时,触发攻击
这种触发器有一个很有意思的地方,就是它是有冷却的
每次搜索目标后,触发器都会进入持续3帧的冷却。在这段时间内,尝试搜索目标都会直接失败
对机制比较熟悉的朋友应该能想到,这就是所谓的“索敌帧”(其实我不喜欢这个称呼,因为它并不准确,我会在下文中称其为“索敌冷却”)
那么,在考虑了索敌冷却后,我们再来推一遍禁锢前囚犯身上发生的变化,为了简便直接从身上剩余2层计数buff开始:
2层计数buff -> 尝试触发攻击,成功,禁锢模式触发器进入3帧冷却 -> 攻击前,2-1层,剩余1层,切换至警报模式 -> 尝试触发攻击,成功,警报模式触发器进入3帧冷却 -> 攻击前,1-1层,剩余0层 -> 第3次攻击开始 -> 获得警报buff -> 第3次攻击结束 -> 尝试触发攻击,成功,警报模式触发器进入3帧冷却 -> 攻击前,切换至解放模式
毫无问题是吗?
我们现在加入一个条件,切换至一个模式后,其它模式的选择触发器不会进行冷却更新
注意上面过程中加粗的地方,由于在警报模式的触发器进入冷却后,立刻从警报模式切换至了解放模式,因此警报模式的触发器,在再次切换至警报模式前,始终保持3帧的冷却
让我们推一遍,保持着这个冷却的情况下,也就是再次禁锢后,囚犯身上发生的变化:
2层计数buff -> 尝试触发攻击,成功,禁锢模式触发器进入3帧冷却 -> 攻击前,2-1层,剩余1层,切换至警报模式 -> 尝试触发攻击,失败!(警报模式触发器仍处于3帧冷却) -> 获得警报buff(3帧>0.05s) -> 尝试触发攻击,成功,警报模式触发器进入3帧冷却 -> 攻击前,1-1,剩余0层;切换至解放模式 -> 第3次攻击开始
注意上文的加粗部分
由于触发器的冷却,导致禁锢后再次切换至警报模式后,攻击无法立刻触发,需等待3帧
而3帧的时间>添加警报buff所需的0.05s
第3次攻击触发后,警报buff已经被添加,因此这次攻击前的行动节点会直接将弓箭手切换至解放模式
警报模式仅仅存在了3帧,一般情况下很难观察到

修复方案1:切换模式时,重置切换前模式攻击触发器的索敌冷却
修复方案2:延长进入警报状态后添加警报buff的延迟时间至0.1s以上
本文原载于NGA:https://ngabbs.com/read.php?tid=24802079
作者为本人
此专栏以CC BY-NC-SA 4.0协议发布