[抛砖引玉科普] 于mugen代码,澄清一些误区之一


本文由Eagrose发布在贴吧https://tieba.baidu.com/p/1906365893


第二个问题:

这里重申一下,【hitdef有几个容易混淆的参数】

1)attr 
这个参数,表示攻击的“表面上的定义”
HitDefAttr 检测的也正是这个值。这个参数同时也与“hitby、nothitby”遥相呼应。
它的格式,和hitby一样,形如:
SCA,AA,AT,AP (即 SCA,NA,SA,HA,NP,SP,HP,NT,ST,HT )

2)hitflag
这个参数,决定了“对手”处于哪些state状态类型下,自己的攻击方可命中
可选值:HLAFDP+-
H高位,L低位(M同时包括H和L)
A空中,F落下(注意!AF都在空中,但本质不同,挨打movetype=H的空中算F不算A)
(所以hitflag=MAF能打中那些已经挨打的空中目标,但MA打不中!)
(MA常用于普通立回拳脚,因为在有的原作中,地面拳脚只能首发命中空中目标,但后续不能在空中连段,如拳皇)
D倒地(倒地追击即使用该参数,但是注意起身瞬间默认完全无敌,有这个参数也白搭)
P飞行道具(该参数极为特殊,以后详述)
+加号表示该次攻击只能命中“已经挨打的角色”
-减号表示该次攻击只能命中“没有挨打的角色”如普通投

3)guardflag
这个参数,决定了对手如何才能防御自己的这个攻击
(所以注意!绝不是hitflag的攻击身位决定哪些不可防,而是这个参数决定)
可选值:MHLA
M=HL,这里H为站立,L为下蹲。
A即是否允许空中防御。
(不写A虽然理论上不允许空中防御,但某些人物修改了防御代码,空中时“强行”切换到站立防御状态进行防御,那么这个设定也就白搭了。)
(还有一个隐含参数,N或者不写,表示完全的不可防御)
本质上guardflag对应于120-159的【mugen内建机制之一:防御状态】

受香蕉君启发,补充一句:hitflag用于在对方【非防御】时决定能否命中,guardflag用于在对方【防御】时决定能否命中


以上述第二个问题为基础,
第三个问题:
【澄清关于AI重要参数 HitDefAttr 的实际作用机理】

HitDefAttr,顾名思义,返回的是攻击器(hitdef)的攻击类型值(attr)。

1)【它的表达式怎么判断的?】

类似于hitby。
如trigger1 = hitdefattr = SCA,AA
检测【自己】的攻击类型为站蹲空、任何物理攻击时,返回真。

但是!螺丝这里重申一个BUG(mugen BUG真多...)
如果你按照说明文档的例子,写成
trigger1 = hitdefattr != SCA,AA
会怎么样呢?

实验:
-2下加入如下DEBUG信息:

[State -2, DisplayToClipBoard];debug
Type = DisplayToClipBoard
Trigger1 = 1
Text = "inguard=%d, attr.NASAHA=%d, attr.NPSPHP=%d, attr.NTSTHT=%d, "
Params = inguarddist,(hitdefattr=SCA,AA),(hitdefattr=SCA,AP),(hitdefattr=SCA,AT)
IgnoreHitPause = 1

[State -2, DisplayToClipBoard];debug
Type = ApPendToClipBoard
Trigger1 = 1
Text = "\n!attr.NASAHA=%d, !attr.NPSPHP=%d, !attr.NTSTHT=%d, "
Params = (hitdefattr!=SCA,AA),(hitdefattr!=SCA,AP),(hitdefattr!=SCA,AT)
IgnoreHitPause = 1

然后实测:

e6310cb30f2442a796cad729d143ad4bd31302d1.jpg

伊格尼斯的超重击吹飞,攻击类型为物理(SA)

我们可见,hitdefattr=SCA,AA 返回了真,符合我们的设想(是物理攻击)。
hitdefattr=SCA,AP 和 hitdefattr=SCA,AT 返回了假,也符合我们的设想(不是投技也不是飞行道具)

但是诡异的一幕出现了:
hitdefattr!=SCA,AA 也返回了真....
【不等于物理攻击】竟然在物理攻击时,为真...
再看另外两个不等式,
hitdefattr!=SCA,AP 和 hitdefattr!=SCA,AT,
【不等于投技】【不等于飞行道具】此时“应该”为真,但反而为假...

结论:
hitdefattr的判别式,不能用不等号“!=”,因为用了和没用一样,黑白是非颠倒...
(这个BUG让人非常无语)

那么我们如何判断“不等于XXX类型攻击”呢?
答案是,把不等号放在外面,如:
trigger1 = !(hitdefattr=SCA,AA)
先让hitdefattr运算完毕,再取负数。


2)【hitdefattr的检测对象】
螺丝提及
trigger1 = hitdefattr = SCA,AA
检测的是【自己】,那么检测对手呢?
enemynear(X)重定向即可。
(注意双打模式的“最近之活敌”问题,这个问题螺丝之前在2D、贴吧提过,后面详述)

但是一个显而易见的问题是:
检测“本体”的时候,Helper的能检测到么?Projectile能检测到么?
答案是:都不能...

859aac51f3deb48f79b4b752f01f3a292cf57839.jpg

图中,DEBUG信息不变。
大蛇使用援护(典型的helper),即便已经inguarddist,马上就要挨打
伊格尼斯所有DEBUG信息的hitdefattr依旧均返回“假”。

原因在于
【helper发出的hitdef,参数应该重定向到helper,才能检测到。】
如“helper(XXX),hitdefattr”

问题来了,如何得知对方的helper编号?
这是一个棘手的问题,目前而言最好的办法也只是“遍历所有的helper编号来穷举”

吃力不讨好的“遍历穷举法”还能够用于记忆对手哪些helper具有攻击性,而哪些又是“无害”的。这一点在AI Helper所能达到的极限精度中,是重要的一环(比较繁琐)。

——————————————————————————————
Projectile型飞行道具,也具有attr属性。
但是显然proj没有“重定向”之类的。

我们知道无论是不是helper创造的proj,都属于本体,
是不是可以直接检测本体?
答案是:不能

749432adcbef76099e1789132edda3cc7dd99efa.jpg

伊格尼斯放出圣光箭,使用proj编写的飞行道具。
本体debug信息,attr依旧全为假。

——————————————————————————————————
由此可见,mugen的三大控制器,检测attr可以总结如下

自己本体、对手本体的hitdef可检测。(对手要重定向)
对手helper的hitdef难以检测。(非要检测,遍历穷举编号)

projectile 完全无法检测。(无任何办法)

Reversaldef 如果不写attr,检测不到。
(如果写attr会导致另一个严重BUG,后文单独作为一个问题详述)
——————————————————————————————————
那我们要这个参数做什么?
检测本体的攻击。

由于一般只有物理攻击和投技是基于本体的,飞行道具则往往是proj或helper,
所以一般而言这个参数用于检测对手是物理攻击,则AI可用物理当身技,还击对方。

投技呢?如果你的当身技可以反弹投技(...)并且对手不是0帧投,
那么你可以尝试反弹对手。
对于0帧投,等hitdefattr判定返回真时,你已经挨打了,AI没有反应的机会了。

检测本体投技的另一个用处是,非0帧投的时候,你可以尝试后退、跳跃、攻击,
总之AI至少知道不用原地防御/闪避了,因为面对投技,防/闪了也白搭。

根据相关规定,发布评论前必须绑定手机前往绑定
你,确定要这么做吗?
正在处理中...