【我帮鹰角修bug】神秘的掷能者索敌:开服以来从未注意的bug
这个系列内容大概是科学分析一些游戏bug或"bug"的原理并给出可能的解决方案
往期内容欢迎查看本人专栏
本期算是危机合约前紧急加的,比较短,所以作为半期
内容只有一个:掷能者的索敌,到底出了什么问题?
这个bug最早可查记录:https://ngabbs.com/read.php?tid=22591000
大概概括一下就是:掷能者组长有3个或以上备选目标,且至少一个备选目标位于协议入口时,掷能者组长不会选择最后一个部署的目标
这个问题可以说是非常奇怪了,单纯用权重排序无法解释
所以我们来看一下掷能者组长使用的是哪种索敌方式

可以看到,掷能者组长使用postFilter=4,即按仇恨值降序排序
使用secondaryFilter=3,即在权重排序后再优先携带指定buff的目标,buff名为tower_t_1[charge_range]
设置sortByTauntLevelAtLast=True,即在最后再按嘲讽等级将备选目标排序一次,这个机制是这次更新新加的
问题极大概率出现在这三步中的某一步
一开始想当然觉得嫌疑最大的是sortByTauntLevelAtLast,因为这个机制是这次新加入的
但仔细想想,bug的生效条件中有一条“至少一个备选目标位于协议入口”,说明bug的生效和secondaryFilter的排序有一定联系
我方干员使用secondaryFilter的还有对空狙,安德切尔和格劳克斯
于是拿同样会打多目标的蓝毒做了个实验
然后奇迹出现了...

蓝毒也出现了不打仇恨值最高(即离终点最近)目标的现象,例如视频中就不会攻击距离终点最近的源石虫
蓝毒并没有将sortByTauntLevelAtLast设为True
那么问题基本可以确定在secondaryFilter上
接下来就是翻代码...
然后发现最大目标数设为1和最大目标数>1是分开处理的
那么只看最大目标数>1的部分就好了

上面的代码只要看到132行就差不多了
部分函数和变量为了方便识别做了重命名(注意那个列表是个指针)
如果看不懂或者不想看这里解释一下
这一大坨的内容逻辑大概就是:(简化版逻辑,只保留了有效部分)
设置一个名为初始值为0的名为index的变量
从前到后遍历备选目标列表
如果发现某个元素满足secondaryFilter的条件
则将这个元素与第index项元素交换位置
然后index++
发现问题了吗...
举一个例子
假设我按 斑点->月见夜->末药->红豆 的顺序进行部署,其中最先部署的斑点位于协议入口
首先进行仇恨值排序,顺序为红豆>末药>月见夜>斑点
然后是secondaryFilter的排序,这个时候会从红豆开始进行遍历
前3项因不满足条件不会触发再排序
遍历至斑点时,按前文所述的逻辑,会将斑点与红豆(index=0)的位置进行对调
这样一来,整个优先顺序变成了:斑点>末药>月见夜>红豆...
在这种情况下,受攻击的会是位于协议入口的斑点,和倒数第二部署的末药。最后部署的红豆反而不会受到攻击
这就是这个bug的原因
另外我查看了直到0.8.72版本(没记错的话是开午间)的客户端,无一例外存在这个问题
这个问题极大可能从开服就一直存在,但是因为触发条件较苛刻,触发时不明显一直被忽略
直到这个版本才被扒出来...
解决方法:改掉底层逻辑(需客户端更新)
触发再排序时请将列表中从遍历项(不含)至index项(含)之间的全部项目后置一项
不要只是单纯交换了...
本文原载于NGA:https://ngabbs.com/read.php?tid=22618647
作者为本人
此专栏以CC BY-NC-SA 4.0协议发布