标题: 增加兵种相克的新思路, 利用查表的方法方便的增加兵种相克
性别:未知-离线 star175

★★

Rank: 9Rank: 9Rank: 9
轩辕春秋年度最佳(轩辕工作室)
组别 白衣卿相
级别 讨逆将军
好贴 3
功绩 153
帖子 686
编号 91725
注册 2006-11-16


发表于 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 好帖奖励


顶部
性别:男-离线 周瑜

栎阳侯谏议大夫

Rank: 16
组别 翰林学士
级别 征西将军
好贴 10
功绩 943
帖子 4717
编号 1808
注册 2003-11-3
家族 瓦岗寨


发表于 2008-6-6 20:37 资料 主页 文集 短消息 只看该作者
貌似我就是这么做的,而且用的是一个字节表示两个相克的方法,可以节省一半空间,不过被克兵种数要是偶数才行。


顶部
性别:男-离线 hhccz
(遥不可及的梦想)

Rank: 3Rank: 3Rank: 3
组别 士兵
级别 忠义校尉
功绩 3
帖子 254
编号 199637
注册 2007-8-8
家族 肉肉门


发表于 2008-6-6 20:51 资料 主页 短消息 只看该作者
看不懂。  还是支持,周大降临了。
顶部
性别:男-离线 colalove12
(ぷ迷途ぷ归惘)

Rank: 1
组别 百姓
级别 在野武将
功绩 0
帖子 11
编号 90986
注册 2006-11-11


发表于 2008-6-6 21:21 资料 短消息 只看该作者
强大啊~~~完全看不懂,看来只能做伸手党了
顶部
性别:男-离线 godtype
(毅)

刘国公
广南东路经略使
枢密直学士
★★★★★★★★★★★★
★★★

Rank: 24Rank: 24Rank: 24
柱国(正二品) 轩辕春秋年度最佳(轩辕工作室)
组别 经略使
级别 卫将军
好贴 1
功绩 1314
帖子 6207
编号 111321
注册 2007-2-18
来自 我家
家族 轩辕学院


发表于 2008-6-6 22:09 资料 个人空间 短消息 只看该作者
终于发布出来了,昨天听你说过之后,我也尝试写了一段新代码,不过看完你这个之后,比我新写的要好得多呀,还是用你这个好。
另外想问一下,为什么破甲攻击要调用一次那个函数?

[ 本帖最后由 godtype 于 2008-6-6 22:13 编辑 ]
顶部
性别:未知-离线 star175

★★

Rank: 9Rank: 9Rank: 9
轩辕春秋年度最佳(轩辕工作室)
组别 白衣卿相
级别 讨逆将军
好贴 3
功绩 153
帖子 686
编号 91725
注册 2006-11-16


发表于 2008-6-6 23:23 资料 文集 短消息 只看该作者
回复 #5 godtype 的帖子

我的目的是要把这个自定义函数变为一个标准的通用函数,凡是需要计算百分数的地方都能使用这个函数,其实在exe中有很多类似的地方,只要重新设置一下两个入栈参数,都能直接调用这个函数,这样即节省空间,也便于代码维护

但破甲攻击为百分数伤害时完全可以适用这个函数
顶部
性别:男-离线 godtype
(毅)

刘国公
广南东路经略使
枢密直学士
★★★★★★★★★★★★
★★★

Rank: 24Rank: 24Rank: 24
柱国(正二品) 轩辕春秋年度最佳(轩辕工作室)
组别 经略使
级别 卫将军
好贴 1
功绩 1314
帖子 6207
编号 111321
注册 2007-2-18
来自 我家
家族 轩辕学院


发表于 2008-6-7 00:28 资料 个人空间 短消息 只看该作者
0043BD69  |.  6BC0 1B       IMUL EAX,EAX,1B

0043BD73  |.  8A9408 D7094D>MOV DL,BYTE PTR DS:[EAX+ECX+4D09D7]

个人认为将上面的1B改成20,4D09D7改成4D09E0,相克表也改成从4D09E0开始,会适合一些用UE且比较懒和不想慢慢数数的人(例如本人)。
虽然这样会增加不少字节(5*27),而且每一个兵种的相克表最后5个字节变成无意义,但是这样就可以令到每一个兵种的相克表都是从A***0开始,例如00兵种从A1DE0开始,01兵种从A1E00开始……方便了用UE且比较懒和不想慢慢数数的人(再次例如本人)。而且我还喜欢将最后5个字节改成3030909090、3031909090等等,都是为了方便修改而已。
顶部
性别:男-离线 paro
(皮哥)

Rank: 5Rank: 5
组别 士兵
级别 讨逆将军
功绩 6
帖子 615
编号 17220
注册 2004-9-7
家族 肉肉门


技术上又进了一步,呵呵!
顶部
性别:男-离线 37610716
(妖)

白衣伯爵

Rank: 11Rank: 11Rank: 11Rank: 11Rank: 11
轩辕春秋年度最佳(轩辕工作室)
组别 白衣卿相
级别 平东将军
好贴 1
功绩 151
帖子 2567
编号 214815
注册 2007-9-12


发表于 2008-6-7 19:07 资料 个人空间 短消息 只看该作者
主要是不知道地址重复了没!
顶部
性别:男-离线 godtype
(毅)

刘国公
广南东路经略使
枢密直学士
★★★★★★★★★★★★
★★★

Rank: 24Rank: 24Rank: 24
柱国(正二品) 轩辕春秋年度最佳(轩辕工作室)
组别 经略使
级别 卫将军
好贴 1
功绩 1314
帖子 6207
编号 111321
注册 2007-2-18
来自 我家
家族 轩辕学院


发表于 2008-6-7 20:15 资料 个人空间 短消息 只看该作者
回复 #9 37610716 的帖子

放心按教程改吧,没有重复的。
顶部
性别:男-离线 天翼之神
(信心第一, 成功跟随)

Rank: 4
组别 士兵
级别 牙门将军
功绩 5
帖子 546
编号 281131
注册 2008-6-7
家族 圣剑兄弟会


发表于 2008-6-8 03:46 资料 短消息 只看该作者 QQ
又有个新的了, 我来看看.
顶部
性别:未知-离线 kaopamao

Rank: 1
组别 百姓
级别 在野武将
功绩 0
帖子 7
编号 278877
注册 2008-5-20


发表于 2008-6-9 15:38 资料 短消息 只看该作者
好深奥哦!!不过希望你们越做越好!永远支持创作者!!!!
顶部
性别:女-离线 子·房
(吾之子房也)

Rank: 1
组别 百姓
级别 在野武将
功绩 0
帖子 15
编号 281532
注册 2008-6-9


发表于 2008-6-9 16:21 资料 短消息 只看该作者 QQ
不是新人能看懂的
顶部
性别:男-离线 三国赤壁周郎
(魏君子)

Rank: 8Rank: 8
组别 校尉
级别 平北将军
功绩 19
帖子 1865
编号 273194
注册 2008-3-31
来自 蓬莱仙境


发表于 2008-6-18 18:06 资料 文集 短消息 只看该作者
这个设想不错,支持!
顶部
性别:男-离线 513633522
(小越)

Rank: 7Rank: 7Rank: 7Rank: 7
组别 校尉
级别 右将军
功绩 12
帖子 1179
编号 349592
注册 2009-12-6
家族 轩辕狼党


发表于 2010-6-18 08:24 资料 文集 短消息 只看该作者
收下仔细看吧……不是一天两天能学会的
顶部

正在浏览此帖的会员 - 共 2 人在线




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

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

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