原帖内容
star175

2008-6-6 20:28
增加兵种相克的新思路

关于增加兵种相克的方法目前都是通过语句跳转到空白处来增加,这样的方法对于少量的相克关系尚可应付,但如果需要设置大量的相克关系,就非常不利于代码修改和维护,而且写出的代码的可读性极差,一旦以后又需要要增加新的兵种相克,又需要重新书写代码,修改和重写代码的工作量相当大。为了较好的解决这个问题,我通过反复测试,终于发现可以使用使用27*27=729共字节设置一个兵种相克表,再利用查表的方法来设置兵种相克,这样可以随意设置兵种相克,相当方便,现在把方法公布,希望能对大家有所帮助。

以下代码和说明均以我发布的exe第四版为例。

在CCZ原版exe中,兵种相克关系是在函数43BC4B中设置的,同时这个函数还有一些宝物的处理代码,比如减轻远距伤害,骑马攻击等,在我发布的exe第四版里,这个函数的地址没变,但新增了破甲攻击和减轻物理伤害的效果

下面是我改写过的代码:(由于代码较多,只帖出了修改过的地方)

0043BC4B      55            PUSH EBP                             '函数开始
0043BC4C      8BEC          MOV EBP,ESP
0043BC4E      83EC 3C       SUB ESP,3C
      .
      .
      .
0043BC76     /E9 76020000   JMP 0043BEF1
      .
      .
      .
0043BD06     /E9 E6010000   JMP 0043BEF1
      .
      .
      .
0043BD5F  |.  E8 0CF7FFFF   CALL Ekd5.0043B470                                        ;  取得攻击方兵种
0043BD64  |.  25 FF000000   AND EAX,0FF
0043BD69  |.  6BC0 1B       IMUL EAX,EAX,1B                                               ;  攻击方兵种*1B(27) 这句是重点 确定某个兵种的查表开始位置
0043BD6C  |.  33C9          XOR ECX,ECX
0043BD6E  |.  33D2          XOR EDX,EDX
0043BD70  |.  8A4D EC       MOV CL,BYTE PTR SS:[EBP-14]                           ;  被攻击方兵种
0043BD73  |.  8A9408 D7094D>MOV DL,BYTE PTR DS:[EAX+ECX+4D09D7]     ;  通过查表得到伤害系数  4D09D7是相克表开始处
0043BD7A  |.  FF75 FC       PUSH DWORD PTR SS:[EBP-4]                              ;  伤害值入栈
0043BD7D  |.  52            PUSH EDX                                                            ;  伤害系数入栈
0043BD7E  |.  E8 74010000   CALL Ekd5.0043BEF7                                       ;  调用自定义函数 重新计算伤害
0043BD83  |.  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX                        ;  保存重新计算后的伤害值
0043BD86  |.  8B4D D4       MOV ECX,DWORD PTR SS:[EBP-2C]                      ;  取出攻击方内存 4B****
0043BD89  |.  E8 CF420000   CALL Ekd5.0044005D                                       ;  判断攻击方是否为远程兵种
0043BD8E  |.  84C0          TEST AL,AL
0043BD90  |.  74 2E         JE SHORT Ekd5.0043BDC0                                    ;  不是远程 跳转
0043BD92  |.  6A 3D         PUSH 3D                                                            ; /这里开始检查被攻击方是否有降低远程伤害的道具
0043BD94  |.  8B4D 08       MOV ECX,DWORD PTR SS:[EBP+8]                              
0043BD97  |.  E8 6DBCFCFF   CALL Ekd5.00407A09                                        ; \Ekd5.00407A09
0043BD9C  |.  85C0          TEST EAX,EAX
0043BD9E  |.  74 20         JE SHORT Ekd5.0043BDC0                                    ;  没有装备 跳转
0043BDA0  |.  6A 3D         PUSH 3D                                 ; /Arg1 = 0000003D
0043BDA2  |.  8B4D 08       MOV ECX,DWORD PTR SS:[EBP+8]            ; |
0043BDA5  |.  E8 48BDFCFF   CALL Ekd5.00407AF2                                        ; \如果有装备 取得特殊效果值
0043BDAA  |.  25 FF000000   AND EAX,0FF
0043BDAF  |.  FF75 FC       PUSH DWORD PTR SS:[EBP-4]
0043BDB2  |.  50            PUSH EAX
0043BDB3  |.  E8 3F010000   CALL Ekd5.0043BEF7                                        ;  自定义函数 计算能降低多少伤害
0043BDB8  |.  8B55 FC       MOV EDX,DWORD PTR SS:[EBP-4]
0043BDBB  |.  2BD0          SUB EDX,EAX                             ;  减法
0043BDBD  |.  8955 FC       MOV DWORD PTR SS:[EBP-4],EDX                     ;  保存降低后的伤害
0043BDC0  |>  837D FC 00    CMP DWORD PTR SS:[EBP-4],0
0043BDC4  |.  75 07         JNZ SHORT Ekd5.0043BDCD
0043BDC6  |.  C745 FC 01000>MOV DWORD PTR SS:[EBP-4],1
0043BDCD  |>  FF75 D4       PUSH DWORD PTR SS:[EBP-2C]
0043BDD0  |.  FF75 DC       PUSH DWORD PTR SS:[EBP-24]
0043BDD3  |.  6A 00         PUSH 0
0043BDD5  |.  8B4D FC       MOV ECX,DWORD PTR SS:[EBP-4]
0043BDD8  |.  E8 8F52FDFF   CALL Ekd5.0041106C                                        ;  这个是原来的骑马攻击,现在是加强攻击
0043BDDD  |.  8955 FC       MOV DWORD PTR SS:[EBP-4],EDX
0043BDE0  |.  6A 2C         PUSH 2C                                                            ; /这个是减轻物理伤害
0043BDE2  |.  8B4D 08       MOV ECX,DWORD PTR SS:[EBP+8]                     ; |
0043BDE5  |.  E8 1FBCFCFF   CALL Ekd5.00407A09                                        ; \Ekd5.00407A09
0043BDEA  |.  85C0          TEST EAX,EAX
0043BDEC  |.  74 20         JE SHORT Ekd5.0043BE0E
0043BDEE  |.  6A 2C         PUSH 2C                                 ; /Arg1 = 0000002C
0043BDF0  |.  8B4D 08       MOV ECX,DWORD PTR SS:[EBP+8]            ; |
0043BDF3  |.  E8 FABCFCFF   CALL Ekd5.00407AF2                      ; \Ekd5.00407AF2
0043BDF8  |.  25 FF000000   AND EAX,0FF
0043BDFD  |.  FF75 FC       PUSH DWORD PTR SS:[EBP-4]
0043BE00  |.  50            PUSH EAX
0043BE01  |.  E8 F1000000   CALL Ekd5.0043BEF7                                          ;  自定义函数 计算能降低多少伤害
0043BE06  |.  8B55 FC       MOV EDX,DWORD PTR SS:[EBP-4]
0043BE09  |.  2BD0          SUB EDX,EAX
0043BE0B  |.  8955 FC       MOV DWORD PTR SS:[EBP-4],EDX
0043BE0E  |>  837D 10 00    CMP DWORD PTR SS:[EBP+10],0
0043BE12  |.  74 29         JE SHORT Ekd5.0043BE3D
0043BE14  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]
0043BE17  |.  6BC0 03       IMUL EAX,EAX,3
0043BE1A  |.  C1E8 02       SHR EAX,2
0043BE1D  |.  83F8 01       CMP EAX,1
0043BE20  |.  73 09         JNB SHORT Ekd5.0043BE2B
0043BE22  |.  C745 C8 01000>MOV DWORD PTR SS:[EBP-38],1
0043BE29  |.  EB 0C         JMP SHORT Ekd5.0043BE37
0043BE2B  |>  8B4D FC       MOV ECX,DWORD PTR SS:[EBP-4]
0043BE2E  |.  6BC9 03       IMUL ECX,ECX,3
0043BE31  |.  C1E9 02       SHR ECX,2
0043BE34  |.  894D C8       MOV DWORD PTR SS:[EBP-38],ECX
0043BE37  |>  8B55 C8       MOV EDX,DWORD PTR SS:[EBP-38]
0043BE3A  |.  8955 FC       MOV DWORD PTR SS:[EBP-4],EDX
0043BE3D  |>  8B4D D4       MOV ECX,DWORD PTR SS:[EBP-2C]
0043BE40  |.  E8 7B4B0900   CALL Ekd5.004D09C0                      ;  这里又是一个自定义函数 由4b****得到D6**** 很多地方要用到这个函数的代码,所以弄出来单独写了一个函数  传入ecx--传出ecx     
0043BE45  |.  894D F8       MOV DWORD PTR SS:[EBP-8],ECX
0043BE48  |.  6A 17         PUSH 17                                          ; /这里是破甲攻击
0043BE4A  |.  E8 BABBFCFF   CALL Ekd5.00407A09                      ; \Ekd5.00407A09
0043BE4F  |.  85C0          TEST EAX,EAX
0043BE51  |.  74 30         JE SHORT Ekd5.0043BE83
0043BE53  |.  6A 17         PUSH 17                                 ; /Arg1 = 00000017
0043BE55  |.  8B4D F8       MOV ECX,DWORD PTR SS:[EBP-8]            ; |
0043BE58  |.  E8 95BCFCFF   CALL Ekd5.00407AF2                      ; \Ekd5.00407AF2
0043BE5D  |.  33C9          XOR ECX,ECX
0043BE5F  |.  8AC8          MOV CL,AL
0043BE61  |.  894D FC       MOV DWORD PTR SS:[EBP-4],ECX
0043BE64  |.  803D 70234600>CMP BYTE PTR DS:[462370],1                       ;  如果462370 为1 就是固定伤害
0043BE6B  |.  74 69         JE SHORT Ekd5.0043BED6
0043BE6D  |.  8B4D 08       MOV ECX,DWORD PTR SS:[EBP+8]                     ;  否则为百分数伤害
0043BE70  |.  E8 B7B3FCFF   CALL Ekd5.0040722C
0043BE75  |.  FF75 FC       PUSH DWORD PTR SS:[EBP-4]
0043BE78  |.  50              PUSH EAX
0043BE79  |.  E8 79000000   CALL Ekd5.0043BEF7                                     ; 当破甲攻击为百分数伤害时,再次调用自定义函数
0043BE7E  |.  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX
0043BE81  |.  EB 53         JMP SHORT Ekd5.0043BED6
0043BE83  |>  837D 0C 00    CMP DWORD PTR SS:[EBP+C],0
0043BE87  |.  74 4D         JE SHORT Ekd5.0043BED6
0043BE89  |.  6A 07         PUSH 7                                  ; /Arg1 = 00000007
0043BE8B  |.  E8 833C0400   CALL Ekd5.0047FB13                      ; \Ekd5.0047FB13
0043BE90  |.  83C4 04       ADD ESP,4
0043BE93  |.  8945 D8       MOV DWORD PTR SS:[EBP-28],EAX
0043BE96  |.  83F8 02       CMP EAX,2
0043BE99  |.  76 0F         JBE SHORT Ekd5.0043BEAA
0043BE9B  |.  8B45 D8       MOV EAX,DWORD PTR SS:[EBP-28]
0043BE9E  |.  8B4D FC       MOV ECX,DWORD PTR SS:[EBP-4]
0043BEA1  |.  8D5401 FE     LEA EDX,DWORD PTR DS:[ECX+EAX-2]
0043BEA5  |.  8955 FC       MOV DWORD PTR SS:[EBP-4],EDX
0043BEA8  |.  EB 2C         JMP SHORT Ekd5.0043BED6
0043BEAA  |>  FF75 D8       PUSH DWORD PTR SS:[EBP-28]              ; /Arg2
0043BEAD  |.  FF75 FC       PUSH DWORD PTR SS:[EBP-4]               ; |Arg1
0043BEB0  |.  E8 E93B0400   CALL Ekd5.0047FA9E                      ; \Ekd5.0047FA9E
0043BEB5  |.  83C4 08       ADD ESP,8
0043BEB8  |.  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX
0043BEBB  |.  837D FC 00    CMP DWORD PTR SS:[EBP-4],0
0043BEBF  |.  75 09         JNZ SHORT Ekd5.0043BECA
0043BEC1  |.  C745 C4 01000>MOV DWORD PTR SS:[EBP-3C],1
0043BEC8  |.  EB 06         JMP SHORT Ekd5.0043BED0
0043BECA  |>  8B55 FC       MOV EDX,DWORD PTR SS:[EBP-4]
0043BECD  |.  8955 C4       MOV DWORD PTR SS:[EBP-3C],EDX
0043BED0  |>  8B45 C4       MOV EAX,DWORD PTR SS:[EBP-3C]
0043BED3  |.  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX
0043BED6  |>  8B4D DC       MOV ECX,DWORD PTR SS:[EBP-24]
0043BED9  |.  E8 B26D0300   CALL Ekd5.00472C90
0043BEDE  |.  3945 FC       CMP DWORD PTR SS:[EBP-4],EAX
0043BEE1  |.  76 0B         JBE SHORT Ekd5.0043BEEE
0043BEE3  |.  8B4D DC       MOV ECX,DWORD PTR SS:[EBP-24]
0043BEE6  |.  E8 A56D0300   CALL Ekd5.00472C90
0043BEEB  |.  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX
0043BEEE  |>  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]
0043BEF1  |>  8BE5          MOV ESP,EBP
0043BEF3  |.  5D            POP EBP
0043BEF4  \.  C2 0C00       RETN 0C


上面的代码都加了注释,最关键的地方就是 0043BD5F 到0043BD83之间的代码


0043BEF7  /$  55            PUSH EBP                                                 ;重新计算伤害的自定义函数,上面的代码共调用此函数4次
0043BEF8  |.  8BEC          MOV EBP,ESP
0043BEFA  |.  8B45 0C       MOV EAX,DWORD PTR SS:[EBP+C]            ;  取出伤害值
0043BEFD  |.  8B55 08       MOV EDX,DWORD PTR SS:[EBP+8]            ;  取出伤害系数
0043BF00  |.  0FAFC2        IMUL EAX,EDX
0043BF03  |.  33D2          XOR EDX,EDX
0043BF05  |.  8BCA          MOV ECX,EDX
0043BF07  |.  B1 64         MOV CL,64
0043BF09  |.  F7F1          DIV ECX
0043BF0B  |.  8BE5          MOV ESP,EBP
0043BF0D  |.  5D            POP EBP
0043BF0E  \.  C3            RETN                                    ;  计算后的伤害值在eax中 返回

PS:在上面的代码中,每一行中间的部分就是UE代码,只会用UE的朋友也能自己修改,这里的UE 地址=OB地址-400C00
例如这个自定义函数的UE地址就是43BEF7-400C00=3B2F7,从这个位置开始把 55 8B EC 8B 45 0C... 等代码写入exe就行了

从这个函数可以看出兵种相克是按百分数来计算的,也就是说如果要设置为正常伤害,就要设置相应的相克系数为64(100)。利用这个信息就可以设置相克表了

相克表的设置其实相当简单,先找27*27=729字节的空间,我现在使用了4D09D7--4D0CAF处的位置(UE地址 A1DD7--A20AF,这里UE地址=OB地址-42EC00),首先把这里的数据全部设为64,这样所有兵种间就是正常伤害了。

下面用两个例子说明这个表的设置方法:

首先一个要注意的是设置这个表应按16进制数来使用

在ccz原版有几个兵种相克,以步兵对骑兵60%的伤害为例

我们知道步兵的职业号是01(注意这里要使用16进制数据),而ccz共有27(1B)个职业。那么步兵系对其他兵种的伤害系数的地址就是从  (01×1B)+4d09d7=4D09F2开始

骑兵系的职业号是03,这样我们就得到了步兵对骑兵的伤害系数的地址: (01×1b)+4d09d7+03=4D09F5,下面只要把这个地址的值改为3C(60)即可。


以弓兵对骑兵150%的伤害为例
弓兵的职业号是02,用上面的方法得到弓兵对骑兵的伤害系数的地址: (02×1B)+4d09d7+03=4D0A10,把这个地址的值改为96(150)即可。

用这个方法我们就可以随意修改兵种相克了,彻底告别以前的那种复杂的设置方法,只会用Ue的朋友也可以方便的改出自己需要的兵种相克了。

[ 本帖最后由 star175 于 2008-6-6 20:35 编辑 ]

用户名时间功绩理由
炎帝瀑布碎 2008-6-6 20:34 +71 好帖奖励




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

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

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