Board logo

标题: 1个字节表示4个兵种相克的办法 [打印本页]

作者: afl001    时间: 2012-3-22 00:38     标题: 1个字节表示4个兵种相克的办法

最近在改威风曹操传V3,由于威风曹操传打散了全部兵种,所以就需要有一种设置小兵种间相克的办法。star175的兵种相克解决办法虽然完美,可是用来设置小兵种间的相克需要2809(53*53)字节,太浪费了,于是想了个新的办法,只需要53*14=742字节。
我们知道1个字节有8位数,要用1个字节表达4个相克,每个相克最多只能占用2位数。2进制2位数最大的是11,转成10进制就是3,也就是说,最多只能设定0、1、2、3这四种类型的相克。巧合的是,曹操传通常用到的相克类型实际上也只有四种,100%,60%,120%,150%。这样一来,思路就出来了。其实很简单。

自定义函数406BA0
功能:传入攻防双方战场内存地址,返回4种相克系数之一到EAX。
afl001首发于轩辕春秋,转载请注明出处。

00406BA0  /.  55                 PUSH    EBP
00406BA1  |.  8BEC               MOV     EBP,ESP
00406BA3  |.  8B4D 08            MOV     ECX,DWORD PTR SS:[EBP+8]
00406BA6  |.  E8 C5730100        CALL    0041DF70       //获取攻击武将的小兵种
00406BAB  |.  25 FF000000        AND     EAX,0FF
00406BB0  |.  6BC0 0E            IMUL    EAX,EAX,0E     //因为1个字节表达4个相克,所以乘以53/4≈14
00406BB3  |.  50                 PUSH    EAX
00406BB4  |.  8B4D 0C            MOV     ECX,DWORD PTR SS:[EBP+C]
00406BB7  |.  E8 B4730100        CALL    0041DF70       //获取被攻击武将的小兵种
00406BBC  |.  25 FF000000        AND     EAX,0FF
00406BC1  |.  8BD0               MOV     EDX,EAX
00406BC3  |.  33C9               XOR     ECX,ECX
00406BC5  |.  8AC8               MOV     CL,AL
00406BC7  |.  C0E9 02            SHR     CL,2           //同样除以4
00406BCA  |.  58                 POP     EAX
00406BCB  |.  8A8408 F0D64800    MOV     AL,BYTE PTR DS:[EAX+ECX+48D6F0]
00406BD2  |.  25 FF000000        AND     EAX,0FF
00406BD7  |.  50                 PUSH    EAX
00406BD8  |.  8BC2               MOV     EAX,EDX
00406BDA  |.  33D2               XOR     EDX,EDX
00406BDC  |.  6A 04              PUSH    4
00406BDE  |>  59                 POP     ECX
00406BDF  |.  F7F1               DIV     ECX
00406BE1  |.  80FA 00            CMP     DL,0
00406BE4  |.  75 06              JNZ     SHORT 00406BEC //不为0,跳过
00406BE6  |.  58                 POP     EAX
00406BE7  |.  83E0 03            AND     EAX,3          //保留低2位,清空其他
00406BEA  |.  EB 23              JMP     SHORT 00406C0F //得到结果跳走
00406BEC  |>  80FA 01            CMP     DL,1
00406BEF  |.  75 09              JNZ     SHORT 00406BFA //不为1,跳过
00406BF1  |.  58                 POP     EAX
00406BF2  |.  C1E8 02            SHR     EAX,2          //右移2位
00406BF5  |.  83E0 03            AND     EAX,3          //保留低2位,清空其他
00406BF8  |.  EB 15              JMP     SHORT 00406C0F //得到结果跳走
00406BFA  |>  80FA 02            CMP     DL,2
00406BFD  |.  75 09              JNZ     SHORT 00406C08 //不为2,跳过
00406BFF  |.  58                 POP     EAX
00406C00  |.  C1E8 04            SHR     EAX,4          //右移4位
00406C03  |.  83E0 03            AND     EAX,3          //保留低2位,清空其他
00406C06  |.  EB 07              JMP     SHORT 00406C0F //得到结果跳走
00406C08  |>  58                 POP     EAX            //不为0-2,则必定为3
00406C09  |.  C1E8 06            SHR     EAX,6          //右移6位
00406C0C  |.  83E0 03            AND     EAX,3          //保留低2位,清空其他
00406C0F  |>  3C 03              CMP     AL,3           //比较相克类型是否3
00406C11  |.  75 04              JNZ     SHORT 00406C17
00406C13  |.  B0 96              MOV     AL,96          //是3则系数设为150
00406C15  |.  EB 12              JMP     SHORT 00406C29
00406C17  |>  3C 02              CMP     AL,2           //相克类型是否2
00406C19  |.  75 04              JNZ     SHORT 00406C1F
00406C1B  |.  B0 78              MOV     AL,78          //是2设为120
00406C1D  |.  EB 0A              JMP     SHORT 00406C29
00406C1F  |>  3C 01              CMP     AL,1           //相克类型是否1
00406C21  |.  75 04              JNZ     SHORT 00406C27
00406C23  |.  B0 3C              MOV     AL,3C          //是1设为60
00406C25  |.  EB 02              JMP     SHORT 00406C29
00406C27  |>  B0 64              MOV     AL,64          //类型为0时,设为100
00406C29  |>  8BE5               MOV     ESP,EBP
00406C2B  |.  5D                 POP     EBP
00406C2C  \.  C2 0800            RETN    8

通过这条函数得到兵种相克系数,再调用star175的43BEF7函数,就能算出伤害值了。
afl001首发于轩辕春秋,转载请注明出处。

0043BEF7  /$  55                 PUSH EBP
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

从48D6F0开始连续742个字节,设置各小兵种间的相克类型。请自寻空白地址,以2进制进行设置,每2位一个相克。0类为00,1类为01,2类为10,3类为11,每个字节8位,刚好包含4个相克,顺序为从低位到高位,设好再转为16进制写入。

用法示例:在攻击伤害计算函数中调用
0043BD7E      FF75 DC            PUSH    DWORD PTR SS:[EBP-24] 输入被攻击武将战场内存
0043BD81      FF75 D4            PUSH    DWORD PTR SS:[EBP-2C] 输入攻击武将战场内存
0043BD84      E8 17AEFCFF        CALL    00406BA0              返回相克系数到EAX
0043BD89      FF75 FC            PUSH    DWORD PTR SS:[EBP-4]  输入当前伤害值
0043BD8C      50                 PUSH    EAX                   输入系数
0043BD8D      E8 65010000        CALL    0043BEF7              这就是star175的43BEF7函数,用来计算伤害结果

这个办法其实还可以和star175的办法混用,做到保持大兵种相克同时,各小兵种另有相克,小兵种相克与大兵种相克相乘就是最终的相克结果。(star175的方法见《增加兵种相克的新思路》)
afl001首发于轩辕春秋,转载请注明出处。

如果高手们有更加简单或者节省字节的办法,望不吝赐教。
作者: WHITESHIP    时间: 2012-3-22 00:54

我去!碉堡了!(话说我对威风曹操传的印象还停留在那个SE31.WAV上面……)
不想作者居然会汇编!

不过这样要改相克的话不是很好改,至少UE不管用了,有配套的二进制修改器就好了。
作者: 阿尔法孝直    时间: 2012-3-22 01:48



[Copy to clipboard]
CODE:
00406C0F  |>  3C 03              CMP     AL,3           //比较相克类型是否3
00406C11  |.  75 04              JNZ     SHORT 00406C17
00406C13  |.  B0 96              MOV     AL,96          //是3则系数设为150
00406C15  |.  EB 12              JMP     SHORT 00406C29
00406C17  |>  3C 02              CMP     AL,2           //相克类型是否2
00406C19  |.  75 04              JNZ     SHORT 00406C1F
00406C1B  |.  B0 78              MOV     AL,78          //是2设为120
00406C1D  |.  EB 0A              JMP     SHORT 00406C29
00406C1F  |>  3C 01              CMP     AL,1           //相克类型是否1
00406C21  |.  75 04              JNZ     SHORT 00406C27
00406C23  |.  B0 3C              MOV     AL,3C          //是1设为60
00406C25  |.  EB 02              JMP     SHORT 00406C29

这段用查表法会不会更好一点,就是先在起始地址x处连续存着100 60 120 150(DB 64 3C 78 96),然后用MOV AL, [x+EAX]
作者: afl001    时间: 2012-3-22 01:59

回复 #2 WHITESHIP 的帖子
SE31是不是那个让人菊花一紧的暴击被格挡音效?已经不止一个人吐槽了。。

回复 #3 阿尔法孝直 的帖子
果然是没有最省,只有更省。因为这里本来就只有四个数字,所以我根本就没往查表上面想。

[ 本帖最后由 afl001 于 2012-3-22 02:01 编辑 ]




欢迎光临 轩辕春秋文化论坛 (http://xycq.org.cn/forum/) Powered by Discuz! 5.0.0