-
-
[求助]一款网络游戏的3D地图内存算法,求大牛写出BOOL地图
-
发表于: 2013-7-10 15:01 5743
-
先定位核心移动判断CALL:一般此类CALL位于走路CALL前面~
00483FB5 8B8E DC000000 mov ecx,dword ptr ds:[esi+DC]
00483FBB 8B7C24 1C mov edi,dword ptr ss:[esp+1C]
00483FBF 8D4424 10 lea eax,dword ptr ss:[esp+10]
00483FC3 50 push eax ;var_1
00483FC4 51 push ecx ;角色角度
00483FC5 57 push edi ;最大移动增量
00483FC6 8BCE mov ecx,esi ;人物结构指针
00483FC8 E8 F3E0FFFF call 004820C0 ;核心CALL
00483FCD 83F8 01 cmp eax,1 ;返回1代表可通行
00483FD0 ^ 0F84 75FFFFFF je 00483F4B
00483FD6 83F8 03 cmp eax,3 ;返回3代表障碍
00483FD9 ^ 0F85 78FFFFFF jnz 00483F57
00483FDF 8B8E D0000000 mov ecx,dword ptr ds:[esi+D0]
00483FE5 83F9 02 cmp ecx,2
00483FE8 74 17 je short 00484001
00483FEA 3BC8 cmp ecx,eax
00483FEC 74 13 je short 00484001
00483FEE 83F9 06 cmp ecx,6
00483FF1 74 0E je short 00484001
00483FF3 83F9 11 cmp ecx,11
00483FF6 74 09 je short 00484001
///////////////////////////////////////////////////////////////////////////////////////
004820C0 83EC 18 sub esp,18
004820C3 53 push ebx
004820C4 8B5C24 24 mov ebx,dword ptr ss:[esp+24]
004820C8 33C0 xor eax,eax
004820CA 55 push ebp
004820CB 894424 08 mov dword ptr ss:[esp+8],eax
004820CF 894424 0C mov dword ptr ss:[esp+C],eax
004820D3 894424 1C mov dword ptr ss:[esp+1C],eax
004820D7 56 push esi
004820D8 B8 40000000 mov eax,40
004820DD 2BC3 sub eax,ebx
004820DF 57 push edi
004820E0 50 push eax ; param=0x40-角度
004820E1 8BF1 mov esi,ecx
004820E3 E8 58CAFFFF call 0047EB40 ; MoveAngleFuc
////////////////////////////////////////////////////////////////////////////////////////////////////////
0047EB40 8B4424 04 mov eax,dword ptr ss:[esp+4] ; param1
0047EB44 25 FF000080 and eax,800000FF ; eax=param1&0x800000FF
0047EB49 79 0E jns short 0047EB59 ; if (eax<0){
0047EB4B 48 dec eax ; eax--
0047EB4C 0D 00FFFFFF or eax,FFFFFF00 ; eax|=0xFFFFFF00
0047EB51 40 inc eax ; eax++
0047EB52 79 05 jns short 0047EB59 ; if (eax<0)
0047EB54 05 00010000 add eax,100 ; eax+=0x100}
0047EB59 83F8 40 cmp eax,40 ; if (eax>0x40)
0047EB5C 7F 08 jg short 0047EB66 ; //跳
0047EB5E 8B0485 60F64E00 mov eax,dword ptr ds:[eax*4+4EF660] ; //4EF660为DWORD数组 //返回值=DWORD_4EF660[eax]
0047EB65 C3 retn
0047EB66 3D 80000000 cmp eax,80 ; if (eax>0x80)
0047EB6B 7F 0E jg short 0047EB7B ; //跳
0047EB6D 03C0 add eax,eax
0047EB6F 03C0 add eax,eax ; 4*eax
0047EB71 B9 60F84E00 mov ecx,4EF860
0047EB76 2BC8 sub ecx,eax ; 4EF860-4*eax
0047EB78 8B01 mov eax,dword ptr ds:[ecx] ; 返回值=DWORD_4EF660[0x80-eax]
0047EB7A C3 retn
0047EB7B 3D C0000000 cmp eax,0C0 ; if (eax>0xC0)
0047EB80 7F 0A jg short 0047EB8C ; //跳
0047EB82 8B0485 60F44E00 mov eax,dword ptr ds:[eax*4+4EF460] ; DWORD_4EF660[eax-0x80]
0047EB89 F7D8 neg eax ; 返回值=-DWORD_4EF660[eax-0x80]
0047EB8B C3 retn
0047EB8C 8D1485 00000000 lea edx,dword ptr ds:[eax*4]
0047EB93 B8 60FA4E00 mov eax,4EFA60
0047EB98 2BC2 sub eax,edx
0047EB9A 8B00 mov eax,dword ptr ds:[eax] ; DWORD_4EF660[0x100-eax]
0047EB9C F7D8 neg eax ; 返回值=-DWORD_4EF660[0x100-eax]
0047EB9E C3 retn
---------------------------------------------------------------------------------------------------------------------
逆成函数:
int MoveAngelFuc(BYTE Angle)
{
int AngleRange;
int result;
CString str;
AngleRange = Angle & 0x800000FF;
if ( (Angle & 0x800000FF) < 0 )
{
AngleRange = ((AngleRange - 1) | 0xFFFFFF00) + 1;
if ( AngleRange < 0 )
AngleRange += 0x100;
}
if ( AngleRange > 0x40 )
{
if ( AngleRange > 0x80 )
{
if ( AngleRange > 0xC0 )
result = -AngleParam[0x100-AngleRange];
else
result = -AngleParam[AngleRange-0x80];
}
else
{
result = (int)AngleParam[0x80-AngleRange];
}
}
else
{
result = AngleParam[AngleRange];
}
return result;
}
----------------------------------------------------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////////
004820E8 8B6C24 30 mov ebp,dword ptr ss:[esp+30] ; 最大移动增量
004820EC 0FAFC5 imul eax,ebp ; eax*最大移动增量
004820EF 99 cdq
004820F0 81E2 FF0F0000 and edx,0FFF
004820F6 03C2 add eax,edx
004820F8 8BF8 mov edi,eax
004820FA 53 push ebx ; param=角度
004820FB C1FF 0C sar edi,0C ; edi/0x1000 //显然edi=Xchange
004820FE E8 3DCAFFFF call 0047EB40 ; MoveAngleFuc
00482103 0FAFC5 imul eax,ebp
00482106 8B5E 08 mov ebx,dword ptr ds:[esi+8]
00482109 8B6E 0C mov ebp,dword ptr ds:[esi+C]
0048210C 99 cdq
0048210D 81E2 FF0F0000 and edx,0FFF
00482113 03C2 add eax,edx
00482115 C1F8 0C sar eax,0C ; eax/0x1000 //显然eax=Ychange
00482118 03DF add ebx,edi ; ebx=NewX=X+Xchange
0048211A 83C4 08 add esp,8
0048211D 03E8 add ebp,eax ; ebp=NewY=Y+Ychange
0048211F 85DB test ebx,ebx ; if (ebx<0)
00482121 7C 21 jl short 00482144 ; //跳出
00482123 85ED test ebp,ebp ; if(ebp<0)
00482125 7C 1D jl short 00482144 ; //跳出
00482127 8B4E 48 mov ecx,dword ptr ds:[esi+48] ; [结构+0x48]=小地图指针=ecx
0048212A 8B91 78010000 mov edx,dword ptr ds:[ecx+178] ; [ecx+0x178]=横向小地图数=edx
00482130 C1E2 0B shl edx,0B ; edx<<0xb=最大横向坐标
00482133 3BDA cmp ebx,edx ; if(NewX>=最大横向坐标)
00482135 7D 0D jge short 00482144 ; 跳出
00482137 8B81 7C010000 mov eax,dword ptr ds:[ecx+17C] ; [ecx+0x178]=纵向小地图数=eax
0048213D C1E0 0B shl eax,0B ; eax<<0xb=最大纵向坐标
00482140 3BE8 cmp ebp,eax ; if(NewY<最大纵向坐标)
00482142 7C 16 jl short 0048215A ; 跳过
00482144 5F pop edi ; {
00482145 5E pop esi ; 坐标超出范围
00482146 C74424 08 02000>mov dword ptr ss:[esp+8],2
0048214E 8B4424 08 mov eax,dword ptr ss:[esp+8] ; 返回值=2 //代表坐标溢出
00482152 5D pop ebp
00482153 5B pop ebx
00482154 83C4 18 add esp,18
00482157 C2 0C00 retn 0C ; }
0048215A 8BC3 mov eax,ebx ; {eax=NewX//坐标合法
0048215C 99 cdq
0048215D 83E2 1F and edx,1F ; //开始计算
00482160 03C2 add eax,edx
00482162 8BF8 mov edi,eax
00482164 C1FF 05 sar edi,5
00482167 8BC7 mov eax,edi
00482169 25 3F000080 and eax,8000003F
0048216E 79 05 jns short 00482175
00482170 48 dec eax
00482171 83C8 C0 or eax,FFFFFFC0
00482174 40 inc eax
00482175 894424 18 mov dword ptr ss:[esp+18],eax ; [esp+0x18]=NewX/32%64
00482179 8BC5 mov eax,ebp ; eax=NewY
0048217B 99 cdq
0048217C 83E2 1F and edx,1F
0048217F 03C2 add eax,edx
00482181 C1F8 05 sar eax,5
00482184 8BD0 mov edx,eax
00482186 81E2 3F000080 and edx,8000003F
0048218C 79 05 jns short 00482193
0048218E 4A dec edx
0048218F 83CA C0 or edx,FFFFFFC0
00482192 42 inc edx
00482193 895424 1C mov dword ptr ss:[esp+1C],edx ; [esp+0x1C]=NewY/32%64
00482197 99 cdq
00482198 83E2 3F and edx,3F
0048219B 03C2 add eax,edx
0048219D C1F8 06 sar eax,6
004821A0 50 push eax ; param1=NewY/32/64
004821A1 8BC7 mov eax,edi
004821A3 99 cdq
004821A4 83E2 3F and edx,3F
004821A7 03C2 add eax,edx
004821A9 C1F8 06 sar eax,6
004821AC 50 push eax ; param2=NewX/32/64
004821AD E8 3E960000 call 0048B7F0 ; 获取小地图指针GetSmallMapThis
004821E8 85C0 test eax,eax ;判断小地图指针是否为0
004821EA 75 2A jnz short 00482216 ;不为0跳过
004821EC 68 6C894D00 push 4D896C
004821F1 68 EE1E0000 push 1EEE
004821F6 E9 00020000 jmp 004823FB
004821FB 6A 00 push 0
004821FD 56 push esi
004821FE E8 3D10FAFF call 00423240
00482203 85C0 test eax,eax
00482205 75 0F jnz short 00482216
00482207 68 6C894D00 push 4D896C
0048220C 68 F31E0000 push 1EF3
00482211 E9 E5010000 jmp 004823FB
00482216 5F pop edi
00482217 5E pop esi
00482218 C74424 08 04000>mov dword ptr ss:[esp+8],4
00482220 8B4424 08 mov eax,dword ptr ss:[esp+8]
00482224 5D pop ebp
00482225 5B pop ebx
00482226 83C4 18 add esp,18
00482229 C2 0C00 retn 0C
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
0048B7F0 8B4424 04 mov eax,dword ptr ss:[esp+4]
0048B7F4 85C0 test eax,eax ; param2
0048B7F6 7C 27 jl short 0048B81F ; <0跳出
0048B7F8 3B81 78010000 cmp eax,dword ptr ds:[ecx+178] ; param2与横向小地图数比较
0048B7FE 7D 1F jge short 0048B81F ; >=就跳出
0048B800 8B5424 08 mov edx,dword ptr ss:[esp+8]
0048B804 85D2 test edx,edx ; param1
0048B806 7C 17 jl short 0048B81F ; <0跳出
0048B808 3B91 7C010000 cmp edx,dword ptr ds:[ecx+17C] ; param1与纵向小地图数比较
0048B80E 7D 0F jge short 0048B81F ; >=0跳出
0048B810 C1E0 06 shl eax,6 ; param2<<6
0048B813 03C2 add eax,edx ; param2<<6+param1
0048B815 8B8481 80010000 mov eax,dword ptr ds:[ecx+eax*4+180] ; 返回值=[this+4*(param2<<6+param1)+0x180]
0048B81C C2 0800 retn 8
0048B81F 33C0 xor eax,eax ; 返回0
0048B821 C2 0800 retn 8
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
0048222C 8B86 D0000000 mov eax,dword ptr ds:[esi+D0] ; [结构+0xD0]=eax=移动状态
00482232 83F8 03 cmp eax,3 ; 移动状态==3//跑
00482235 C74424 2C 00010>mov dword ptr ss:[esp+2C],100 ; 最大移动增量=0x100
0048223D 74 17 je short 00482256 ; ||
0048223F 83F8 02 cmp eax,2 ; 移动状态==2 //慢跑
00482242 74 12 je short 00482256 ; ||
00482244 83F8 11 cmp eax,11 ; 移动状态==0x11
00482247 74 0D je short 00482256 ; ||
00482249 83F8 12 cmp eax,12 ; 移动状态==0x12
0048224C C74424 30 00000>mov dword ptr ss:[esp+30],0 ; [esp+0x30]==0
00482254 75 08 jnz short 0048225E
00482256 C74424 30 01000>mov dword ptr ss:[esp+30],1 ; [esp+0x30]==1
0048225E 83BE E0010000 0>cmp dword ptr ds:[esi+1E0],0 ; [结构+0x1E0]==0
00482265 74 18 je short 0048227F ; 跳过
00482267 F746 04 000000F>test dword ptr ds:[esi+4],F0000000 ; [结构+4]=人物ID与0xF0000000 //判断是否为怪物
0048226E 74 0F je short 0048227F ; 是人物跳过
00482270 837C24 30 00 cmp dword ptr ss:[esp+30],0 ; [esp+0x30]与0比较
00482275 74 08 je short 0048227F ; =0跳过
00482277 C74424 2C FFFFF>mov dword ptr ss:[esp+2C],3FFFFFFF ; 最大移动增量=0x3FFFFFFF
0048227F 8B4E 40 mov ecx,dword ptr ds:[esi+40] ; [结构+0x40]=坐标点指针=ecx
00482282 8B79 08 mov edi,dword ptr ds:[ecx+8] ; edi=[ecx+8]=该坐标点的Next坐标点指针
00482285 85FF test edi,edi ; edi?0
00482287 74 2F je short 004822B8
00482289 F647 02 01 test byte ptr ds:[edi+2],1 ; [edi+2]?1
0048228D 74 29 je short 004822B8
0048228F 0FB757 0C movzx edx,word ptr ds:[edi+C]
00482293 8B4E 48 mov ecx,dword ptr ds:[esi+48]
00482296 52 push edx
00482297 E8 84A70000 call 0048CA20 ; 此CALL均返回0
0048229C 85C0 test eax,eax
0048229E 74 18 je short 004822B8
004822A0 0FB74F 04 movzx ecx,word ptr ds:[edi+4] ; ecx=*(PWORD)(edi+4)
004822A4 8B46 2C mov eax,dword ptr ds:[esi+2C] ; [结构+0x2C]==人物身高
004822A7 0346 10 add eax,dword ptr ds:[esi+10] ; [结构+0x10]=人物Z坐标,与人物身高相加
004822AA 33D2 xor edx,edx
004822AC C1E1 06 shl ecx,6 ; ecx<<6
004822AF 3BC8 cmp ecx,eax ; 比较大小
004822B1 0F9CC2 setl dl ; 如果ecx<eax,edx=1否则edx=0
004822B4 8BC2 mov eax,edx
004822B6 EB 04 jmp short 004822BC
004822B8 8B4424 24 mov eax,dword ptr ss:[esp+24]
004822BC 8B4C24 34 mov ecx,dword ptr ss:[esp+34]
004822C0 51 push ecx ; var_1
004822C1 8B4C24 30 mov ecx,dword ptr ss:[esp+30]
004822C5 8D5424 18 lea edx,dword ptr ss:[esp+18]
004822C9 52 push edx ; &高度差
004822CA 8B56 10 mov edx,dword ptr ds:[esi+10]
004822CD 50 push eax ; param2=0
004822CE 8B46 2C mov eax,dword ptr ds:[esi+2C]
004822D1 50 push eax ; 人物身高
004822D2 8B4424 2C mov eax,dword ptr ss:[esp+2C]
004822D6 51 push ecx ; 最大移动增量
004822D7 8B4C24 2C mov ecx,dword ptr ss:[esp+2C]
004822DB 52 push edx ; 人物Z坐标
004822DC 50 push eax ; NewY/32%64
004822DD 51 push ecx ; NewX/32%64
004822DE 8B4C24 40 mov ecx,dword ptr ss:[esp+40] ; ecx=小地图指针
004822E2 E8 A9EF0000 call 00491290 ; 判断是否是障碍
004822E7 8BF8 mov edi,eax ; 返回NextPointThis
004822E9 85FF test edi,edi ; 如果为0
004822EB 0F84 B1000000 je 004823A2 ; 跳出 返回是障碍值
004822F1 8B5424 14 mov edx,dword ptr ss:[esp+14] ; 高度差
004822F5 83C2 FF add edx,-1
004822F8 81FA FE020000 cmp edx,2FE ; 高度差-1与0x2FE比较
004822FE 77 1D ja short 0048231D ; 大于就跳过
00482300 8B86 D0000000 mov eax,dword ptr ds:[esi+D0] ; eax=移动状态
00482306 83F8 01 cmp eax,1 ; 移动状态==1//不动
00482309 74 0A je short 00482315 ; ||
0048230B 83F8 02 cmp eax,2 ; 移动状态==2//慢跑
0048230E 74 05 je short 00482315 ; ||
00482310 83F8 03 cmp eax,3 ; 移动状态==3//跑步
00482313 75 08 jnz short 0048231D ; 不是就跳过
00482315 C74424 14 00000>mov dword ptr ss:[esp+14],0 ; 高度差=0
0048231D F746 04 000000F>test dword ptr ds:[esi+4],F0000000 ; 判断是否是玩家
00482324 0F84 8E000000 je 004823B8 ; 是就跳过
0048232A 8B86 F0060000 mov eax,dword ptr ds:[esi+6F0] ; //下面是怪物移动判断
/////////////////////////////////////////////////////////////////////////////////////////////////////////
004823B8 8B4C24 18 mov ecx,dword ptr ss:[esp+18]
004823BC 8B5424 1C mov edx,dword ptr ss:[esp+1C]
004823C0 895E 08 mov dword ptr ds:[esi+8],ebx ; 人物X坐标=[结构+8]=NewX
004823C3 896E 0C mov dword ptr ds:[esi+C],ebp ; 人物Y坐标=[结构+c]=NewY
004823C6 0FB747 06 movzx eax,word ptr ds:[edi+6] ; *(PWORD)(NextPointerThis+6)
004823CA C1E0 06 shl eax,6 ; *(PWORD)(NextPointerThis+6)<<6
004823CD 034424 14 add eax,dword ptr ss:[esp+14] ; *(PWORD)(NextPointerThis+6)<<6+高度差
004823D1 894E 18 mov dword ptr ds:[esi+18],ecx ; [结构+0x18]=NewX/32%64
004823D4 8946 10 mov dword ptr ds:[esi+10],eax ; NewZ=*(PWORD)(NextPointerThis+6)<<6+高度差
004823D7 8B4424 20 mov eax,dword ptr ss:[esp+20]
004823DB 3B46 44 cmp eax,dword ptr ds:[esi+44]
004823DE 8956 1C mov dword ptr ds:[esi+1C],edx ; [结构+0x1c]=NewY/32%64
004823E1 74 3B je short 0048241E
004823E3 8B16 mov edx,dword ptr ds:[esi]
004823E5 50 push eax
004823E6 8B42 08 mov eax,dword ptr ds:[edx+8]
004823E9 8BCE mov ecx,esi
004823EB FFD0 call eax
004823ED 85C0 test eax,eax
004823EF 75 2D jnz short 0048241E
004823F1 68 6C894D00 push 4D896C
004823F6 68 531F0000 push 1F53
004823FB 68 ACE44B00 push 4BE4AC
00482400 68 18E44B00 push 4BE418
00482405 6A 07 push 7
00482407 FF15 00E04B00 call dword ptr ds:[4BE000]
0048240D 8B4424 24 mov eax,dword ptr ss:[esp+24]
00482411 83C4 14 add esp,14
00482414 5F pop edi
00482415 5E pop esi
00482416 5D pop ebp
00482417 5B pop ebx
00482418 83C4 18 add esp,18
0048241B C2 0C00 retn 0C
总结:
当前大地图由[[结构+0x48]+0x178]*[[结构+0x48]+0x17C]张小地图组成
一张小地图由64*64的网格组成
一个网格由32*32个坐标点组成
游戏每次更新周围的几块小地图。
先根据人物角度,所在地表的最大移动增量算出下一个移动坐标点NewX,NewY
用NewX,NewY算出所在小地图指针
再把人物小地图指针给障碍判断算法,获得人物下一点的坐标指针,以及NewZ
求大牛写画BOOL地图或者地型图
00483FB5 8B8E DC000000 mov ecx,dword ptr ds:[esi+DC]
00483FBB 8B7C24 1C mov edi,dword ptr ss:[esp+1C]
00483FBF 8D4424 10 lea eax,dword ptr ss:[esp+10]
00483FC3 50 push eax ;var_1
00483FC4 51 push ecx ;角色角度
00483FC5 57 push edi ;最大移动增量
00483FC6 8BCE mov ecx,esi ;人物结构指针
00483FC8 E8 F3E0FFFF call 004820C0 ;核心CALL
00483FCD 83F8 01 cmp eax,1 ;返回1代表可通行
00483FD0 ^ 0F84 75FFFFFF je 00483F4B
00483FD6 83F8 03 cmp eax,3 ;返回3代表障碍
00483FD9 ^ 0F85 78FFFFFF jnz 00483F57
00483FDF 8B8E D0000000 mov ecx,dword ptr ds:[esi+D0]
00483FE5 83F9 02 cmp ecx,2
00483FE8 74 17 je short 00484001
00483FEA 3BC8 cmp ecx,eax
00483FEC 74 13 je short 00484001
00483FEE 83F9 06 cmp ecx,6
00483FF1 74 0E je short 00484001
00483FF3 83F9 11 cmp ecx,11
00483FF6 74 09 je short 00484001
///////////////////////////////////////////////////////////////////////////////////////
004820C0 83EC 18 sub esp,18
004820C3 53 push ebx
004820C4 8B5C24 24 mov ebx,dword ptr ss:[esp+24]
004820C8 33C0 xor eax,eax
004820CA 55 push ebp
004820CB 894424 08 mov dword ptr ss:[esp+8],eax
004820CF 894424 0C mov dword ptr ss:[esp+C],eax
004820D3 894424 1C mov dword ptr ss:[esp+1C],eax
004820D7 56 push esi
004820D8 B8 40000000 mov eax,40
004820DD 2BC3 sub eax,ebx
004820DF 57 push edi
004820E0 50 push eax ; param=0x40-角度
004820E1 8BF1 mov esi,ecx
004820E3 E8 58CAFFFF call 0047EB40 ; MoveAngleFuc
////////////////////////////////////////////////////////////////////////////////////////////////////////
0047EB40 8B4424 04 mov eax,dword ptr ss:[esp+4] ; param1
0047EB44 25 FF000080 and eax,800000FF ; eax=param1&0x800000FF
0047EB49 79 0E jns short 0047EB59 ; if (eax<0){
0047EB4B 48 dec eax ; eax--
0047EB4C 0D 00FFFFFF or eax,FFFFFF00 ; eax|=0xFFFFFF00
0047EB51 40 inc eax ; eax++
0047EB52 79 05 jns short 0047EB59 ; if (eax<0)
0047EB54 05 00010000 add eax,100 ; eax+=0x100}
0047EB59 83F8 40 cmp eax,40 ; if (eax>0x40)
0047EB5C 7F 08 jg short 0047EB66 ; //跳
0047EB5E 8B0485 60F64E00 mov eax,dword ptr ds:[eax*4+4EF660] ; //4EF660为DWORD数组 //返回值=DWORD_4EF660[eax]
0047EB65 C3 retn
0047EB66 3D 80000000 cmp eax,80 ; if (eax>0x80)
0047EB6B 7F 0E jg short 0047EB7B ; //跳
0047EB6D 03C0 add eax,eax
0047EB6F 03C0 add eax,eax ; 4*eax
0047EB71 B9 60F84E00 mov ecx,4EF860
0047EB76 2BC8 sub ecx,eax ; 4EF860-4*eax
0047EB78 8B01 mov eax,dword ptr ds:[ecx] ; 返回值=DWORD_4EF660[0x80-eax]
0047EB7A C3 retn
0047EB7B 3D C0000000 cmp eax,0C0 ; if (eax>0xC0)
0047EB80 7F 0A jg short 0047EB8C ; //跳
0047EB82 8B0485 60F44E00 mov eax,dword ptr ds:[eax*4+4EF460] ; DWORD_4EF660[eax-0x80]
0047EB89 F7D8 neg eax ; 返回值=-DWORD_4EF660[eax-0x80]
0047EB8B C3 retn
0047EB8C 8D1485 00000000 lea edx,dword ptr ds:[eax*4]
0047EB93 B8 60FA4E00 mov eax,4EFA60
0047EB98 2BC2 sub eax,edx
0047EB9A 8B00 mov eax,dword ptr ds:[eax] ; DWORD_4EF660[0x100-eax]
0047EB9C F7D8 neg eax ; 返回值=-DWORD_4EF660[0x100-eax]
0047EB9E C3 retn
---------------------------------------------------------------------------------------------------------------------
逆成函数:
int MoveAngelFuc(BYTE Angle)
{
int AngleRange;
int result;
CString str;
AngleRange = Angle & 0x800000FF;
if ( (Angle & 0x800000FF) < 0 )
{
AngleRange = ((AngleRange - 1) | 0xFFFFFF00) + 1;
if ( AngleRange < 0 )
AngleRange += 0x100;
}
if ( AngleRange > 0x40 )
{
if ( AngleRange > 0x80 )
{
if ( AngleRange > 0xC0 )
result = -AngleParam[0x100-AngleRange];
else
result = -AngleParam[AngleRange-0x80];
}
else
{
result = (int)AngleParam[0x80-AngleRange];
}
}
else
{
result = AngleParam[AngleRange];
}
return result;
}
----------------------------------------------------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////////
004820E8 8B6C24 30 mov ebp,dword ptr ss:[esp+30] ; 最大移动增量
004820EC 0FAFC5 imul eax,ebp ; eax*最大移动增量
004820EF 99 cdq
004820F0 81E2 FF0F0000 and edx,0FFF
004820F6 03C2 add eax,edx
004820F8 8BF8 mov edi,eax
004820FA 53 push ebx ; param=角度
004820FB C1FF 0C sar edi,0C ; edi/0x1000 //显然edi=Xchange
004820FE E8 3DCAFFFF call 0047EB40 ; MoveAngleFuc
00482103 0FAFC5 imul eax,ebp
00482106 8B5E 08 mov ebx,dword ptr ds:[esi+8]
00482109 8B6E 0C mov ebp,dword ptr ds:[esi+C]
0048210C 99 cdq
0048210D 81E2 FF0F0000 and edx,0FFF
00482113 03C2 add eax,edx
00482115 C1F8 0C sar eax,0C ; eax/0x1000 //显然eax=Ychange
00482118 03DF add ebx,edi ; ebx=NewX=X+Xchange
0048211A 83C4 08 add esp,8
0048211D 03E8 add ebp,eax ; ebp=NewY=Y+Ychange
0048211F 85DB test ebx,ebx ; if (ebx<0)
00482121 7C 21 jl short 00482144 ; //跳出
00482123 85ED test ebp,ebp ; if(ebp<0)
00482125 7C 1D jl short 00482144 ; //跳出
00482127 8B4E 48 mov ecx,dword ptr ds:[esi+48] ; [结构+0x48]=小地图指针=ecx
0048212A 8B91 78010000 mov edx,dword ptr ds:[ecx+178] ; [ecx+0x178]=横向小地图数=edx
00482130 C1E2 0B shl edx,0B ; edx<<0xb=最大横向坐标
00482133 3BDA cmp ebx,edx ; if(NewX>=最大横向坐标)
00482135 7D 0D jge short 00482144 ; 跳出
00482137 8B81 7C010000 mov eax,dword ptr ds:[ecx+17C] ; [ecx+0x178]=纵向小地图数=eax
0048213D C1E0 0B shl eax,0B ; eax<<0xb=最大纵向坐标
00482140 3BE8 cmp ebp,eax ; if(NewY<最大纵向坐标)
00482142 7C 16 jl short 0048215A ; 跳过
00482144 5F pop edi ; {
00482145 5E pop esi ; 坐标超出范围
00482146 C74424 08 02000>mov dword ptr ss:[esp+8],2
0048214E 8B4424 08 mov eax,dword ptr ss:[esp+8] ; 返回值=2 //代表坐标溢出
00482152 5D pop ebp
00482153 5B pop ebx
00482154 83C4 18 add esp,18
00482157 C2 0C00 retn 0C ; }
0048215A 8BC3 mov eax,ebx ; {eax=NewX//坐标合法
0048215C 99 cdq
0048215D 83E2 1F and edx,1F ; //开始计算
00482160 03C2 add eax,edx
00482162 8BF8 mov edi,eax
00482164 C1FF 05 sar edi,5
00482167 8BC7 mov eax,edi
00482169 25 3F000080 and eax,8000003F
0048216E 79 05 jns short 00482175
00482170 48 dec eax
00482171 83C8 C0 or eax,FFFFFFC0
00482174 40 inc eax
00482175 894424 18 mov dword ptr ss:[esp+18],eax ; [esp+0x18]=NewX/32%64
00482179 8BC5 mov eax,ebp ; eax=NewY
0048217B 99 cdq
0048217C 83E2 1F and edx,1F
0048217F 03C2 add eax,edx
00482181 C1F8 05 sar eax,5
00482184 8BD0 mov edx,eax
00482186 81E2 3F000080 and edx,8000003F
0048218C 79 05 jns short 00482193
0048218E 4A dec edx
0048218F 83CA C0 or edx,FFFFFFC0
00482192 42 inc edx
00482193 895424 1C mov dword ptr ss:[esp+1C],edx ; [esp+0x1C]=NewY/32%64
00482197 99 cdq
00482198 83E2 3F and edx,3F
0048219B 03C2 add eax,edx
0048219D C1F8 06 sar eax,6
004821A0 50 push eax ; param1=NewY/32/64
004821A1 8BC7 mov eax,edi
004821A3 99 cdq
004821A4 83E2 3F and edx,3F
004821A7 03C2 add eax,edx
004821A9 C1F8 06 sar eax,6
004821AC 50 push eax ; param2=NewX/32/64
004821AD E8 3E960000 call 0048B7F0 ; 获取小地图指针GetSmallMapThis
004821E8 85C0 test eax,eax ;判断小地图指针是否为0
004821EA 75 2A jnz short 00482216 ;不为0跳过
004821EC 68 6C894D00 push 4D896C
004821F1 68 EE1E0000 push 1EEE
004821F6 E9 00020000 jmp 004823FB
004821FB 6A 00 push 0
004821FD 56 push esi
004821FE E8 3D10FAFF call 00423240
00482203 85C0 test eax,eax
00482205 75 0F jnz short 00482216
00482207 68 6C894D00 push 4D896C
0048220C 68 F31E0000 push 1EF3
00482211 E9 E5010000 jmp 004823FB
00482216 5F pop edi
00482217 5E pop esi
00482218 C74424 08 04000>mov dword ptr ss:[esp+8],4
00482220 8B4424 08 mov eax,dword ptr ss:[esp+8]
00482224 5D pop ebp
00482225 5B pop ebx
00482226 83C4 18 add esp,18
00482229 C2 0C00 retn 0C
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
0048B7F0 8B4424 04 mov eax,dword ptr ss:[esp+4]
0048B7F4 85C0 test eax,eax ; param2
0048B7F6 7C 27 jl short 0048B81F ; <0跳出
0048B7F8 3B81 78010000 cmp eax,dword ptr ds:[ecx+178] ; param2与横向小地图数比较
0048B7FE 7D 1F jge short 0048B81F ; >=就跳出
0048B800 8B5424 08 mov edx,dword ptr ss:[esp+8]
0048B804 85D2 test edx,edx ; param1
0048B806 7C 17 jl short 0048B81F ; <0跳出
0048B808 3B91 7C010000 cmp edx,dword ptr ds:[ecx+17C] ; param1与纵向小地图数比较
0048B80E 7D 0F jge short 0048B81F ; >=0跳出
0048B810 C1E0 06 shl eax,6 ; param2<<6
0048B813 03C2 add eax,edx ; param2<<6+param1
0048B815 8B8481 80010000 mov eax,dword ptr ds:[ecx+eax*4+180] ; 返回值=[this+4*(param2<<6+param1)+0x180]
0048B81C C2 0800 retn 8
0048B81F 33C0 xor eax,eax ; 返回0
0048B821 C2 0800 retn 8
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
0048222C 8B86 D0000000 mov eax,dword ptr ds:[esi+D0] ; [结构+0xD0]=eax=移动状态
00482232 83F8 03 cmp eax,3 ; 移动状态==3//跑
00482235 C74424 2C 00010>mov dword ptr ss:[esp+2C],100 ; 最大移动增量=0x100
0048223D 74 17 je short 00482256 ; ||
0048223F 83F8 02 cmp eax,2 ; 移动状态==2 //慢跑
00482242 74 12 je short 00482256 ; ||
00482244 83F8 11 cmp eax,11 ; 移动状态==0x11
00482247 74 0D je short 00482256 ; ||
00482249 83F8 12 cmp eax,12 ; 移动状态==0x12
0048224C C74424 30 00000>mov dword ptr ss:[esp+30],0 ; [esp+0x30]==0
00482254 75 08 jnz short 0048225E
00482256 C74424 30 01000>mov dword ptr ss:[esp+30],1 ; [esp+0x30]==1
0048225E 83BE E0010000 0>cmp dword ptr ds:[esi+1E0],0 ; [结构+0x1E0]==0
00482265 74 18 je short 0048227F ; 跳过
00482267 F746 04 000000F>test dword ptr ds:[esi+4],F0000000 ; [结构+4]=人物ID与0xF0000000 //判断是否为怪物
0048226E 74 0F je short 0048227F ; 是人物跳过
00482270 837C24 30 00 cmp dword ptr ss:[esp+30],0 ; [esp+0x30]与0比较
00482275 74 08 je short 0048227F ; =0跳过
00482277 C74424 2C FFFFF>mov dword ptr ss:[esp+2C],3FFFFFFF ; 最大移动增量=0x3FFFFFFF
0048227F 8B4E 40 mov ecx,dword ptr ds:[esi+40] ; [结构+0x40]=坐标点指针=ecx
00482282 8B79 08 mov edi,dword ptr ds:[ecx+8] ; edi=[ecx+8]=该坐标点的Next坐标点指针
00482285 85FF test edi,edi ; edi?0
00482287 74 2F je short 004822B8
00482289 F647 02 01 test byte ptr ds:[edi+2],1 ; [edi+2]?1
0048228D 74 29 je short 004822B8
0048228F 0FB757 0C movzx edx,word ptr ds:[edi+C]
00482293 8B4E 48 mov ecx,dword ptr ds:[esi+48]
00482296 52 push edx
00482297 E8 84A70000 call 0048CA20 ; 此CALL均返回0
0048229C 85C0 test eax,eax
0048229E 74 18 je short 004822B8
004822A0 0FB74F 04 movzx ecx,word ptr ds:[edi+4] ; ecx=*(PWORD)(edi+4)
004822A4 8B46 2C mov eax,dword ptr ds:[esi+2C] ; [结构+0x2C]==人物身高
004822A7 0346 10 add eax,dword ptr ds:[esi+10] ; [结构+0x10]=人物Z坐标,与人物身高相加
004822AA 33D2 xor edx,edx
004822AC C1E1 06 shl ecx,6 ; ecx<<6
004822AF 3BC8 cmp ecx,eax ; 比较大小
004822B1 0F9CC2 setl dl ; 如果ecx<eax,edx=1否则edx=0
004822B4 8BC2 mov eax,edx
004822B6 EB 04 jmp short 004822BC
004822B8 8B4424 24 mov eax,dword ptr ss:[esp+24]
004822BC 8B4C24 34 mov ecx,dword ptr ss:[esp+34]
004822C0 51 push ecx ; var_1
004822C1 8B4C24 30 mov ecx,dword ptr ss:[esp+30]
004822C5 8D5424 18 lea edx,dword ptr ss:[esp+18]
004822C9 52 push edx ; &高度差
004822CA 8B56 10 mov edx,dword ptr ds:[esi+10]
004822CD 50 push eax ; param2=0
004822CE 8B46 2C mov eax,dword ptr ds:[esi+2C]
004822D1 50 push eax ; 人物身高
004822D2 8B4424 2C mov eax,dword ptr ss:[esp+2C]
004822D6 51 push ecx ; 最大移动增量
004822D7 8B4C24 2C mov ecx,dword ptr ss:[esp+2C]
004822DB 52 push edx ; 人物Z坐标
004822DC 50 push eax ; NewY/32%64
004822DD 51 push ecx ; NewX/32%64
004822DE 8B4C24 40 mov ecx,dword ptr ss:[esp+40] ; ecx=小地图指针
004822E2 E8 A9EF0000 call 00491290 ; 判断是否是障碍
004822E7 8BF8 mov edi,eax ; 返回NextPointThis
004822E9 85FF test edi,edi ; 如果为0
004822EB 0F84 B1000000 je 004823A2 ; 跳出 返回是障碍值
004822F1 8B5424 14 mov edx,dword ptr ss:[esp+14] ; 高度差
004822F5 83C2 FF add edx,-1
004822F8 81FA FE020000 cmp edx,2FE ; 高度差-1与0x2FE比较
004822FE 77 1D ja short 0048231D ; 大于就跳过
00482300 8B86 D0000000 mov eax,dword ptr ds:[esi+D0] ; eax=移动状态
00482306 83F8 01 cmp eax,1 ; 移动状态==1//不动
00482309 74 0A je short 00482315 ; ||
0048230B 83F8 02 cmp eax,2 ; 移动状态==2//慢跑
0048230E 74 05 je short 00482315 ; ||
00482310 83F8 03 cmp eax,3 ; 移动状态==3//跑步
00482313 75 08 jnz short 0048231D ; 不是就跳过
00482315 C74424 14 00000>mov dword ptr ss:[esp+14],0 ; 高度差=0
0048231D F746 04 000000F>test dword ptr ds:[esi+4],F0000000 ; 判断是否是玩家
00482324 0F84 8E000000 je 004823B8 ; 是就跳过
0048232A 8B86 F0060000 mov eax,dword ptr ds:[esi+6F0] ; //下面是怪物移动判断
/////////////////////////////////////////////////////////////////////////////////////////////////////////
004823B8 8B4C24 18 mov ecx,dword ptr ss:[esp+18]
004823BC 8B5424 1C mov edx,dword ptr ss:[esp+1C]
004823C0 895E 08 mov dword ptr ds:[esi+8],ebx ; 人物X坐标=[结构+8]=NewX
004823C3 896E 0C mov dword ptr ds:[esi+C],ebp ; 人物Y坐标=[结构+c]=NewY
004823C6 0FB747 06 movzx eax,word ptr ds:[edi+6] ; *(PWORD)(NextPointerThis+6)
004823CA C1E0 06 shl eax,6 ; *(PWORD)(NextPointerThis+6)<<6
004823CD 034424 14 add eax,dword ptr ss:[esp+14] ; *(PWORD)(NextPointerThis+6)<<6+高度差
004823D1 894E 18 mov dword ptr ds:[esi+18],ecx ; [结构+0x18]=NewX/32%64
004823D4 8946 10 mov dword ptr ds:[esi+10],eax ; NewZ=*(PWORD)(NextPointerThis+6)<<6+高度差
004823D7 8B4424 20 mov eax,dword ptr ss:[esp+20]
004823DB 3B46 44 cmp eax,dword ptr ds:[esi+44]
004823DE 8956 1C mov dword ptr ds:[esi+1C],edx ; [结构+0x1c]=NewY/32%64
004823E1 74 3B je short 0048241E
004823E3 8B16 mov edx,dword ptr ds:[esi]
004823E5 50 push eax
004823E6 8B42 08 mov eax,dword ptr ds:[edx+8]
004823E9 8BCE mov ecx,esi
004823EB FFD0 call eax
004823ED 85C0 test eax,eax
004823EF 75 2D jnz short 0048241E
004823F1 68 6C894D00 push 4D896C
004823F6 68 531F0000 push 1F53
004823FB 68 ACE44B00 push 4BE4AC
00482400 68 18E44B00 push 4BE418
00482405 6A 07 push 7
00482407 FF15 00E04B00 call dword ptr ds:[4BE000]
0048240D 8B4424 24 mov eax,dword ptr ss:[esp+24]
00482411 83C4 14 add esp,14
00482414 5F pop edi
00482415 5E pop esi
00482416 5D pop ebp
00482417 5B pop ebx
00482418 83C4 18 add esp,18
0048241B C2 0C00 retn 0C
总结:
当前大地图由[[结构+0x48]+0x178]*[[结构+0x48]+0x17C]张小地图组成
一张小地图由64*64的网格组成
一个网格由32*32个坐标点组成
游戏每次更新周围的几块小地图。
先根据人物角度,所在地表的最大移动增量算出下一个移动坐标点NewX,NewY
用NewX,NewY算出所在小地图指针
再把人物小地图指针给障碍判断算法,获得人物下一点的坐标指针,以及NewZ
求大牛写画BOOL地图或者地型图
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
看原图
赞赏
雪币:
留言: