标题: 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
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 |