原帖内容
ctermiii

2010-7-26 22:35
三国孔明传物理伤害分析

兵种以及地形等相关内容就不写了,这个老兄的帖子应该是比较详细的:
http://www.xycq.net/forum/thread-210344-1-1.html

按照攻击的视觉流程来写
Random标示随机数
%标示求余,比如A>1时,Random%A表示拿一个随机数去求除以A的余数,显然余数在0~(A-1)之间,A=1时显然%A=0
因为都是整数运算,所以除法等相关运算都是不包括小数部分的。

这个游戏是没有命中率的概念的,因为很多因素会导致伤害为0,显示xxx没有受到伤害。

1、判断攻击是物理攻击还是策略攻击;

具体位置:

QUOTE:
原帖由 ctermiii 于 2010-7-26 22:44 发表
00423914  |.  8A48 12       MOV CL,BYTE PTR DS:[EAX+12]
00423917  |.  83F9 01       CMP ECX,1          ;;  物理攻击1还是策略伤害2,其实还有第3种伤害,后边说明

2、伤害A计算:
A、1 如果Random%(攻方攻击力x攻方所在地形因素/10)<防御方防御力x防御方地形因素/10/10
并且防御方没有混乱,那么伤害A=0,(猜测:攻击方如果是敌人,那敌人是不会来打的,他似乎会实现有个模拟运算攻击过程,见下边程序注释处)
A、2 如果Random%(攻方攻击力x攻方所在地形因素/10)>=防御方防御力x防御方地形因素/10/10
那么又分为:
A、2-1:如果(防御力x地形因素/10+1)/2>攻击方攻击力x攻击方所在地形因素/10
那么伤害A=1;
A、2-2:如果(防御力x地形因素/10+1)/2<攻击方攻击力x攻击方所在地形因素/10
那么伤害A=攻击力x地形因素/10-防御力x地形因素/10/2
B、判断防御方兵种:
B、1:如果兵种代号为09,0A、0B时,伤害A=Ax75%;
B、2:如果兵种代号为1B、1C、1D时,伤害A=Ax150%;
B、3:如果兵种代号1E、1F时,伤害A=Ax50%;
B、4:如果兵种代号为22时,伤害A=1;

结论是:
除了几个特殊兵种怕或者不怕物理攻击外,没有什么相克关系
具体代码见6楼:

QUOTE:
原帖由 ctermiii 于 2010-7-26 22:44 发表
http://www.xycq.net/forum/viewth ... page%3D1#pid2991476

3、判断是范围攻击类第一次攻击伤害还是反击,如果非第一次攻击,或者为反击,则上边计算的A=A/2;
注:如果到目前为止,伤害计算为0,则跳过下边5、6条过程

代码部分:

QUOTE:
原帖由 ctermiii 于 2010-7-26 22:44 发表
0042393C  |.  837D 08 01    CMP DWORD PTR SS:[EBP+8],1               ;  >=1为范围类伤害第一次之后的伤害
00423940  |.  0F83 11000000 JNB EKD2Win.00423957
00423946  |.  8B45 EC       MOV EAX,DWORD PTR SS:[EBP-14]
00423949  |.  33C9          XOR ECX,ECX
0042394B  |.  8A48 13       MOV CL,BYTE PTR DS:[EAX+13]              ;  1反击0攻击
0042394E  |.  83F9 01       CMP ECX,1
00423951  |.  0F85 0C000000 JNZ EKD2Win.00423963
00423957  |>  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]
0042395A  |.  99            CDQ
0042395B  |.  2BC2          SUB EAX,EDX
0042395D  |.  C1F8 01       SAR EAX,1                                ;  原伤害变为50%
00423960  |.  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX

4、无论前边攻击计算是否造成伤害,特效都会进行判断;
象兵和蛇兵的兵种攻击特效(附加异常状态跟策略附加异常状态调用的计算函数一样)如下:
A、反击不会带特效

QUOTE:
原帖由 ctermiii 于 2010-7-26 22:44 发表
0042377A  |.  8A48 13       MOV CL,BYTE PTR DS:[EAX+13]              ;  是攻击还是反击?反击为1攻击为0
0042377D  |.  83F9 01       CMP ECX,1
00423780  |.  0F85 05000000 JNZ EKD2Win.0042378B

B、已经混乱的不能被象兵再次混乱,已经有减血状态的不能被蛇兵再次附加减血状态;
C、有减轻策略伤害的buffer在的话,被附加异常状态buffer的几率减少,算法是仅仅增加跟随机数比较的“赌博”机会而已
2次都成功才可附加状态,意思就是说,第一次计算如果附加了状态,没有buffer的话就算是附加异常状态了,但如果有减轻策略损伤的buffer在,会再计算一次
如果成功才能附加异常状态,如果失败将不附加异常状态
更详细的注释看这里:
http://www.xycq.net/forum/viewth ... page%3D1#pid2996066

QUOTE:
原帖由 ctermiii 于 2010-7-26 22:44 发表
0040227F  |.  C645 EC 01    MOV BYTE PTR SS:[EBP-14],1     ;普通状态给1次赌博机会
00402283  |.  6A 08         PUSH 8                                   ; /Arg1 = 00000008
00402285  |.  33C0          XOR EAX,EAX                              ; |
00402287  |.  8A45 0C       MOV AL,BYTE PTR SS:[EBP+C]               ; |
0040228A  |.  8BC8          MOV ECX,EAX                              ; |
0040228C  |.  8D0440        LEA EAX,DWORD PTR DS:[EAX+EAX*2]         ; |
0040228F  |.  C1E0 03       SHL EAX,3                                ; |
00402292  |.  2BC1          SUB EAX,ECX                              ; |
00402294  |.  8D88 98C04600 LEA ECX,DWORD PTR DS:[EAX+46C098]        ; |
0040229A  |.  E8 B16E0000   CALL <EKD2Win.CheckIfSomeStatus>         ; \CheckIfSomeStatus
0040229F  |.  85C0          TEST EAX,EAX
004022A1  |.  0F84 04000000 JE EKD2Win.004022AB
004022A7  |.  C645 EC 02    MOV BYTE PTR SS:[EBP-14],2;如果有策略减伤buffer,给2次赌博机会

D、状态是否成功跟双方智力和随机数有关:
当Random%攻击方智力>=防御方智力/策略成功率基数时特效才能附加上
本次策略成功率基数=2
具体代码:

QUOTE:
原帖由 ctermiii 于 2010-7-26 22:44 发表
00402303  |.  33C9          |XOR ECX,ECX
00402305  |.  8AC8          |MOV CL,AL
00402307  |.  33DB          |XOR EBX,EBX
00402309  |.  8A5D 10       |MOV BL,BYTE PTR SS:[EBP+10]    ;策略成功率基数
0040230C  |.  8BC1          |MOV EAX,ECX
0040230E  |.  99            |CDQ
0040230F  |.  F7FB          |IDIV EBX
00402311  |.  8B4D E8       |MOV ECX,DWORD PTR SS:[EBP-18]
00402314  |.  3BC8          |CMP ECX,EAX                             ;  随机数%攻击方智力>=防御方智力/策略成功率基数

5、判断是否会全力一击
A、取得兵种攻击速度GSPD:
具体代码:

QUOTE:
原帖由 ctermiii 于 2010-7-26 22:44 发表
0042A3AE  |.  8A81 501F4500 MOV AL,BYTE PTR DS:[ECX+451F50]
0042A3B4  |.  8845 FC       MOV BYTE PTR SS:[EBP-4],AL
0042A3B7  |.  6A 02         PUSH 2                       ; /被减速
0042A3B9  |.  8B4D F8       MOV ECX,DWORD PTR SS:[EBP-8]             ; |
0042A3BC  |.  E8 8FEDFDFF   CALL <EKD2Win.CheckIfSomeStatus>      
0042A3C1  |.  85C0          TEST EAX,EAX
0042A3C3  |.  0F84 0B000000 JE EKD2Win.0042A3D4
0042A3C9  |.  33C0          XOR EAX,EAX
0042A3CB  |.  8A45 FC       MOV AL,BYTE PTR SS:[EBP-4]
0042A3CE  |.  C1F8 01       SAR EAX,1             ;速度/2

B、确认是否全力一击
当GSPD>Random%100是全力一击;
全力一击伤害A=Ax3/2=Ax150%
具体代码:

QUOTE:
原帖由 ctermiii 于 2010-7-26 22:44 发表
0042398C      6A 64         PUSH 64        ;100
0042398E  |.  E8 95390200   CALL <EKD2Win.Random%Arg1>               ; \Random%Arg1
00423993  |.  83C4 04       ADD ESP,4
00423996  |.  3BD8          CMP EBX,EAX
00423998  |.  0F86 16000000 JBE EKD2Win.004239B4                     ;  全力一击的概率
0042399E  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]
004239A1  |.  8D0440        LEA EAX,DWORD PTR DS:[EAX+EAX*2]         ;  致命一击伤害x3/2
004239A4  |.  99            CDQ
004239A5  |.  2BC2          SUB EAX,EDX
004239A7  |.  C1F8 01       SAR EAX,1
004239AA  |.  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX
004239AD  |.  C745 F0 01000>MOV DWORD PTR SS:[EBP-10],1     ;  全力一击标示

6、等级相关的随机因素造成伤害变动:
A、前边计算出基础伤害Abase;
B、取得防御方等级Flevel,然后取得0~FLevel-1的随机值Frnd1;
C、取得攻击方等级Glevel,然后取得0~Glelev-1的随机值Grnd1;
D、比较Frnd1与Grnd1的大小;
D、1如果Frnd1<Grnd1,或者产生了全力一击;
那么伤害会随机增加(0~Glevel-1)%6之间的随机值Grnd2,结果为Abase=Abase+Grnd2
D、2如果Frnd1>=Grnd1,
那么伤害随机减少(0~Flevel-1)%6的随机值Frnd2,如果伤害为1,减少了2,那只能取0和1-2的最大值,即保证伤害不能为负数,结果为Abase=Max(Abase-Frnd2,0)

7、确认防御方是我军(15个部队)还是敌军;
如果是我军,那个会去确认游戏难度;
A、难度为初级的话,我军受伤害为Abase=Abasex80%;
B、难度为高级的话,我军受伤害为Abase=Abasex120%;
注:没有中级难度计算,那明显伤害为Abase=Abasex100%;
7部分的代码:

QUOTE:
原帖由 ctermiii 于 2010-7-26 22:44 发表
00423AC9  |.  8B0C88        MOV ECX,DWORD PTR DS:[EAX+ECX*4]
00423ACC  |.  E8 4F57FEFF   CALL <EKD2Win.CheckIfWoJun>              ;  防御方是我军还是敌军
00423AD1  |.  83F8 01       CMP EAX,1
00423AD4  |.  0F85 4A000000 JNZ EKD2Win.00423B24
00423ADA  |.  B9 D0A64600   MOV ECX,EKD2Win.0046A6D0
00423ADF  |.  E8 CC7FFEFF   CALL <EKD2Win.GetDifficultLevel>         ;  游戏难度00~02
00423AE4  |.  85C0          TEST EAX,EAX
00423AE6  |.  0F85 11000000 JNZ EKD2Win.00423AFD
00423AEC  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]             ;  难度为初级00的时候敌军对我伤害只有80%
00423AEF  |.  C1E0 03       SHL EAX,3
00423AF2  |.  B9 0A000000   MOV ECX,0A
00423AF7  |.  99            CDQ
00423AF8  |.  F7F9          IDIV ECX
00423AFA  |.  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX
00423AFD  |>  B9 D0A64600   MOV ECX,EKD2Win.0046A6D0
00423B02  |.  E8 A97FFEFF   CALL <EKD2Win.GetDifficultLevel>
00423B07  |.  83F8 02       CMP EAX,2
00423B0A  |.  0F85 14000000 JNZ EKD2Win.00423B24
00423B10  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]             ;  游戏难度为高级的时候对我军伤害为120%
00423B13  |.  8D0440        LEA EAX,DWORD PTR DS:[EAX+EAX*2]         ;  没有计算中级难度,明显为100%,不加不减
00423B16  |.  C1E0 02       SHL EAX,2
00423B19  |.  B9 0A000000   MOV ECX,0A
00423B1E  |.  99            CDQ
00423B1F  |.  F7F9          IDIV ECX
00423B21  |.  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX

8、取得防御方当前耐久力,如果最终的ABase>=耐久力的话,伤害Abase=耐久力;
如果伤害<耐久力的哈,Abase不变,这个是为了防止打出比当前耐久力还大的数;


9、关于连击
A、主动攻击的连击,还是主动攻击,反击的连击,还是反击,伤害按照上边的再次套用就行;
B、速度低于防御方的兵种,不会连击,至少跟防御方速度相等;
C、已经连击过的话,不能再连击;
具体代码:

QUOTE:
原帖由 ctermiii 于 2010-7-26 22:44 发表
0042497F  |.  8A5C01 36     MOV BL,BYTE PTR DS:[ECX+EAX+36]          ;  守方速度
00424983  |.  3BD3          CMP EDX,EBX                              ;  速度小于对方不能双击
00424985  |.  0F8C A2000000 JL EKD2Win.00424A2D
0042498B  |.  833D 18184500>CMP DWORD PTR DS:[451818],0 ;是否连击过,连击过则为1,下边有
00424992  |.  0F85 95000000 JNZ EKD2Win.00424A2D

D、连击算法要求:
攻击速度见上边5-A条
(攻击方速度-防御方速度+1)>Random%15
可见同等速度的话,有1/15的概率连击
武术家速度A,有好几个兵种速度只有2,连击概率:(10-2+1)/15=60%,有点夸张
具体代码:

QUOTE:
原帖由 ctermiii 于 2010-7-26 22:44 发表
004249BA  |.  2BDA          SUB EBX,EDX                              ;  二者速度差+1
004249BC  |.  43            INC EBX
004249BD      6A 0F         PUSH 0F
004249BF  |.  E8 64290200   CALL <EKD2Win.Random%Arg1>  
004249C4  |.  83C4 04       ADD ESP,4
004249C7  |.  3BD8          CMP EBX,EAX                              ;  (速度差+1)>15以内随机数,则连击
004249C9  |.  0F86 5E000000 JBE EKD2Win.00424A2D

E、连击判定成功的话,写入连击标识,下次不能连击
可以改成0,无限随机连击噢,不必担心不能结束,一是有概率,二是看下一条
具体代码:

QUOTE:
原帖由 ctermiii 于 2010-7-26 22:44 发表
004249CF      C705 18184500>MOV DWORD PTR DS:[451818],1              ;  写入标示1

F、即便连击判定成功,如果对方耐久力为0,则不会发生连击
具体代码:

QUOTE:
原帖由 ctermiii 于 2010-7-26 22:44 发表
004249EC  |.  85C0          TEST EAX,EAX
004249EE  |.  0F84 39000000 JE EKD2Win.00424A2D

附加:
10、由于没有设置兵种相克,我写了一个来满足一部分改造者的需求,基本思路是:
从0x42A66C开始:
00~27这40个兵种,需要一一给他设定一个大类,编号00~07,一共8大类,默认00

相克系数是0~255直接的任意值,我设定的结果是:
实际伤害=基本伤害x相克系数/100
这样可以有75%,65%这种不是整十的系数存在,设定系数的时候也不用绕弯子了,方便一点
最大是255%,最小0,如果嫌系数范围不够,也可以把100这个数缩小一下。
当然实现方法很多,这里仅仅是一个例子
0x42A62C开始为相克系数表格结构:
每8个一组,分别是第00,第01……第07类克制其他大类的系数;默认00,需要自己设定;
很明显,自己克制自己系数为1,也就是100%,因为我这个例子是除以100的,所以对应设置应该为64H;
如果你改了除数,记得系数也要同步改一下;
藤甲兵22H作为防御方时候单独计算;
具体代码见5楼:

QUOTE:
原帖由 ctermiii 于 2010-7-26 22:44 发表
http://www.xycq.net/forum/viewth ... page%3D1#pid2991468

[ 本帖最后由 ctermiii 于 2010-8-2 15:21 编辑 ]

用户名时间功绩理由
阿尔法孝直 2010-7-27 02:46 +500




当前时区 GMT+8, 现在时间是 2024-11-20 14:33
京ICP备2023018092号 轩辕春秋 2003-2023 www.xycq.org.cn

Powered by Discuz! 5.0.0 2001-2006 Comsenz Inc.
Processed in 0.009599 second(s), 6 queries , Gzip enabled

清除 Cookies - 联系我们 - 轩辕春秋 - Archiver - WAP