- 积分
- 34677
- 威望
- 499
- 魅力
- 507
- 经验
- 20326
- 热心度
- 9
- 注册时间
- 2006-3-13
- 最后登录
- 2024-9-30
- 主题
- 134
- 回帖
- 4949
- 精华
- 35
- 阅读权限
- 150
TA的每日心情 | 郁闷 2015-6-6 16:12 |
---|
签到天数: 52 天 连续签到: 1 天 [LV.5]女巫
超级版主
- 积分
- 34677
|
本帖最后由 贤知有您 于 2015-12-6 17:04 编辑
关于MF1触发器伤害类型的检测
ERMer们都知道,MF1触发器使人又爱又恨.
MF1触发器是能够更改战场伤害的唯一触发器,它触发在伤害计算后,实体伤害产生之前.
但WOG对于伤害的种类却没有明确的划分,甚至说是混乱.MF1的伤害几乎包含了战场上所有物理伤害类型(甚至有部分魔法伤害).
也就是说,当我们使用MF1触发器时,并不能知道当次伤害到底是属于普通战斗伤害还是死亡凝视伤害之类.
而大部分ERM脚本都希望更改肉搏和射击的伤害,而射击由于是单一伤害所以比较容易使用.而肉搏就复杂很多了.
肉搏复杂在于,它可以产生反击伤害,又可以在肉搏伤害后触发火盾伤害和特技伤害(如死亡凝视/雷鸟闪电等).
如何区别伤害类型成为难点.
先看看WOG时代MF1类型的大概检测过程(主要针对肉搏阶段)
1.检测MF:W,首先排除了箭塔和护城河伤害.
2.通常根据BG:A动作(肉搏=6),BG:Q当前攻击方,BG:N动作主动攻击方,BG:E动作被攻击方,MF:N当前受伤害堆栈来做判断.
BG:N和BG:E一般情况下,在整个肉搏过程都不会改变,而肉搏过程可以分为:主动攻击阶段和反击阶段.
怎样判断当前阶段属于主动攻击阶段还是反击阶段?
主动攻击阶段:
也就是开始的攻击以及BG:N堆栈可能的二次攻击(当然带野蛮战斧也一样).
此时BG:Q的当前攻击方就是BG:N的势力(左或右).
反击阶段:
这里讨论的是正常游戏,所以反击只有一次.此时BG:Q就是BG:E的势力.
明确了攻击阶段后,我们定义此时双方为<攻击者>(产生伤害的那一方)和<被攻击者>(被伤害的那一方).
此阶段过程主要伤害类型的特征如下:
1.龙息/环击/火球攻击/范围云攻击
<攻击者>肯定是BG:N或者BG:E,由阶段性确定.
<被攻击者>就是MF:N受伤害堆栈.
如果,<攻击者>和<被攻击者>正好是 BG:N和BG:E的组合,那说明是面对面攻击的双方(相当于说鼠标指向攻击的那个生物).
如果,<攻击者>是BG:N或BG:E,而<被攻击者>非两者之一,那说明这属于次伤害(非鼠标指向的那些),比如龙息伤害或环击对其它堆栈的伤害.
2.火盾
由于火盾是攻击者受伤,所以<攻击者>同时是受伤害方.
举个例子:
左方A首先攻击右方B,B对A产生了火盾伤害.
此时BG:Q=0,等同于BG:N的势力,而MF:N就是BG:N.
3.死亡凝视/雷击等
这些伤害跟正常攻击的伤害混淆起来了.没法通过当时攻击方和势力作用辨别出来.
沧海一粟曾经提出过,由于死亡凝视杀死的个数是整数,可以通过整数计算及堆栈生物类型大概推断.但显然并不是充要条件.
明白了上述这些复杂的攻击过程后,你会发现,MF1是何其难用.
归根结底就是没有判断伤害类型的好方法.这种问题一直困扰着众多ERM创作者.
在ERA出现之后,为了更好地使用生物攻击伤害的触发,当时想到的唯一方法是直接屏蔽一些伤害触发器.比如,屏蔽死亡凝视/雷鸟雷击等,使其不能触发!?MF1;
但这同时也使得我们不能用脚本来更改这些类型的伤害.(比如想改雷鸟的雷击伤害)
最近克招兄弟又提这个话题,我无意中在源码处发现了MF:W的秘密.
先看看这个语法在内存是怎样运作的.
00766923 - c7 45 fc 00 00 00 00 - mov [ebp-04],00000000 #MF:W默认是0
0076692A - 81 3d c0 26 83 02 98 9a 46 00 - cmp [028326c0],00469a98 #护城河伤害类型(返回地址是00469a98)
00766934 - 75 07 - jne 0076693d
00766936 - c7 45 fc 01 00 00 00 - mov [ebp-04],00000001 #MF:W=1
0076693D - 81 3d c0 26 83 02 64 59 46 00 - cmp [028326c0],00465964 #箭塔类型(返回地址是00465964)
00766947 - 75 07 - jne 00766950
00766949 - c7 45 fc 02 00 00 00 - mov [ebp-04],00000002 #MF:W=2
这些伤害类型是通过<返回地址>判断的.
所谓返回地址,就是WOG对原伤害地方HOOK出去触发MF1后的返回执行地址.(比较绕口)
既然不同的伤害类型产生在不同的地方,这个返回地址就可以对类型验明正身.
那么,我们在MF1触发器中检测 [028326c0] 的值,基本就能确定伤害的类型.
经过一大轮测试,得到的数据如下:
伤害类型 返回地址
火球伤害 0043F960
正常射击 0043FA63
范围云伤害 0043FD42
环击伤害 004400E4
火盾伤害 0044085D
死亡凝视伤害 00440E75
雷击伤害 0044104D
酸性攻击伤害 00441251
正常肉搏伤害 0044173E
龙息伤害 0044178F
箭塔伤害 00465964
护城河伤害 00469A98
死亡波纹伤害? 005A106A
举个例子:
- !?MF1;
- !!BG:N?y1 E?y2 Q?y3;
- !!MF:N?y4;
- !!UN:C42149568/4/?y10;[判断依据(028326c0)]
- !!IF&y10=4460149/y4=y2:M^当前属于主动攻击阶段的<死亡凝视>伤害类型^;[00440E75]
- !!IF&y10=4460149/y4=y1:M^当前属于反击阶段的<死亡凝视>伤害类型^;
复制代码
好了,说到这里,如果大家还是蒙查查,先抛弃所有内存概念,直接看最后的检测应用例子.
PS:(151206)
发生龙息攻击时,接触面的伤害属于普通肉搏伤害,第二个才真正属于龙息伤害判断.
而发生环击伤害时,所有一圈的伤害都属于环击伤害.(火球/范围云类似).
|
|