三国孔明传物理伤害分析
兵种以及地形等相关内容就不写了,这个老兄的帖子应该是比较详细的:
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、判断攻击是物理攻击还是策略攻击;
具体位置:
原帖由 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楼:
3、判断是范围攻击类第一次攻击伤害还是反击,如果非第一次攻击,或者为反击,则上边计算的A=A/2;
注:如果到目前为止,伤害计算为0,则跳过下边5、6条过程
代码部分:
原帖由 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、反击不会带特效
原帖由 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
原帖由 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
具体代码:
原帖由 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:
具体代码:
原帖由 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%
具体代码:
原帖由 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部分的代码:
原帖由 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、已经连击过的话,不能再连击;
具体代码:
原帖由 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%,有点夸张
具体代码:
原帖由 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,无限随机连击噢,不必担心不能结束,一是有概率,二是看下一条
具体代码:
原帖由 ctermiii 于 2010-7-26 22:44 发表
004249CF C705 18184500>MOV DWORD PTR DS:[451818],1 ; 写入标示1 F、即便连击判定成功,如果对方耐久力为0,则不会发生连击
具体代码:
原帖由 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楼:
[ 本帖最后由 ctermiii 于 2010-8-2 15:21 编辑 ] |