标题: 1个字节表示4个兵种相克的办法, 用于小兵种相克设置
性别:女-离线 afl001
(安风陵)

★★

Rank: 6Rank: 6Rank: 6
组别 轩辕郡主
级别 护军
好贴 3
功绩 53
帖子 451
编号 71615
注册 2006-6-6


发表于 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

★★
谏议大夫

Rank: 16
组别 翰林学士
级别 征北将军
功绩 380
帖子 4210
编号 170977
注册 2007-6-3
家族 轩辕学院


发表于 2012-3-22 00:54 资料 个人空间 短消息 只看该作者
我去!碉堡了!(话说我对威风曹操传的印象还停留在那个SE31.WAV上面……)
不想作者居然会汇编!

不过这样要改相克的话不是很好改,至少UE不管用了,有配套的二进制修改器就好了。


顶部
性别:男-离线 阿尔法孝直
(雀力日进)

闽国公
遂安军节度使
★★★★★★

Rank: 19Rank: 19Rank: 19Rank: 19
柱国(正二品) 轩辕春秋年度最佳(游戏人生区)
组别 节度使
级别 卫将军
好贴 2
功绩 1796
帖子 6036
编号 19070
注册 2004-10-16
家族 轩辕雀党


发表于 2012-3-22 01:48 资料 个人空间 短消息 只看该作者 QQ


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
(安风陵)

★★

Rank: 6Rank: 6Rank: 6
组别 轩辕郡主
级别 护军
好贴 3
功绩 53
帖子 451
编号 71615
注册 2006-6-6


发表于 2012-3-22 01:59 资料 个人空间 短消息 只看该作者
回复 #2 WHITESHIP 的帖子
SE31是不是那个让人菊花一紧的暴击被格挡音效?已经不止一个人吐槽了。。

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

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

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




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

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

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