首页
社区
课程
招聘
[求助]一款网络游戏的3D地图内存算法,求大牛写出BOOL地图
发表于: 2013-7-10 15:01 5635

[求助]一款网络游戏的3D地图内存算法,求大牛写出BOOL地图

2013-7-10 15:01
5635
先定位核心移动判断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地图或者地型图

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
是那个游戏哦
2013-7-10 16:38
0
游客
登录 | 注册 方可回帖
返回
//