植物大战僵尸吧 关注:580,789贴子:5,185,848

这两天研究了一下PVZ的出怪机制

只看楼主收藏回复

其实一开始对刷怪机制毫无头绪,感觉很难下手,没办法只好站在巨人的肩膀上了。
我下载了小王子的无尽刷怪修改器,并反汇编分析<应该可以吧>。首先是极限刷怪,方便起见我只选了一个橄榄,再给WriteProcessMemory下断,发现是在6a9ec0+768+6b4为首地址的连续1000个Dword内存区域写入我选择的僵尸,我这才知道原来每一轮所要出的所有僵尸在一轮的开始就全部确定了,而不是在每一波根据种子临时决定的。
下面要去找这个长度为1000的int数组是如何生成的,下断后得到
0040A094 E8 07380000 call PlantsVs.0040D8A0
0040A099 8BCB mov ecx,ebx
0040A09B 6BC9 32 imul ecx,ecx,0x32
0040A09E 8D91 AD010000 lea edx,dword ptr ds:[ecx+0x1AD]
0040A0A4 8B4C24 20 mov ecx,dword ptr ss:[esp+0x20]
0040A0A8 8D340A lea esi,dword ptr ds:[edx+ecx]
0040A0AB 83C1 01 add ecx,0x1
0040A0AE 83F9 32 cmp ecx,0x32
0040A0B1 8904B7 mov dword ptr ds:[edi+esi*4],eax//这里写入
每一波的每一只僵尸由函数0040d8a0得到
这个函数开头有个地方
0040D8B7 8D3CED 00000000 lea edi,dword ptr ds:[ebp*8]
0040D8BE 2BFD sub edi,ebp
0040D8C0 80BC2E D4540000 cmp byte ptr ds:[esi+ebp+0x54D4],0x0
0040D8C8 8D3CBD 80DA6900 lea edi,dword ptr ds:[edi*4+0x69DA80]
0040D8CF 897C24 14 mov dword ptr ss:[esp+0x14],edi
0040D8D3 0F84 B7010000 je PlantsVs.0040DA90//如果跳,表示无此僵尸
于是接着我去看byte ptr ds:[esi+ebp+0x54D4]的内存区域,果然发现以6a9ec0+768+54d4为首的连续33个byte内存区域内存放了每个僵尸是否写入出怪列表


1楼2013-05-04 10:20回复
    顺便说一下,其实出怪列表是连续2000个Dword,只是无尽模式中仅用了前面1000个,每50个为1波,总共20波,而PVZ中最高波数貌似是40波,像老虎机,宝石迷阵这种无限出怪的模式,实际上是到了第40波的时候,又改为39波,然后循环刷最后一波的怪


    2楼2013-05-04 10:25
    收起回复
      2026-03-14 20:07:49
      广告
      不感兴趣
      开通SVIP免广告
      留名


      IP属地:江苏3楼2013-05-04 10:28
      收起回复
        楼主好样的


        4楼2013-05-04 10:38
        回复
          但是也不是说哪个僵尸的种子值改成1,那个僵尸就一定会出现在每一波,我发现每一波都有一个总容量,而每个僵尸都有一个,姑且称之为级别吧,每一波的僵尸级别总和不能超过该波的容量,而且每波的僵尸在不足该波僵尸上限的情况下必须正好填满容量,不能有余数,比如无尽第一轮的时候,你只选了个红眼,然后调用函数写入列表,游戏直接crash
          上面那个函数的参数
          0040A090 50 push eax
          0040A091 53 push ebx // 第N波 N=0,1,...
          0040A092 51 push ecx // 剩余容量
          0040A093 57 push edi
          0040A094 E8 07380000 call PlantsVs.0040D8A0
          而每个僵尸的<级别> 存放在以0069da88为首的间隔为1C的内存区域内
          实际上,0069da80为首的区域内存放了每个僵尸的全局信息,+8处,也就是第3个变量内存放的是级别,而+14处貌似是存放僵尸出现的比重,旗帜,伴舞,小鬼,僵博,鸭子都是0,其他僵尸都有不同值,至于具体如何用这个值,不知道


          5楼2013-05-04 10:38
          收起回复
            楼主用伪代码写一下出怪的算法吧


            6楼2013-05-04 10:39
            回复
              厉害!


              IP属地:上海来自手机贴吧7楼2013-05-04 10:41
              回复
                高人呐,留名


                IP属地:陕西8楼2013-05-04 10:41
                回复
                  2026-03-14 20:01:49
                  广告
                  不感兴趣
                  开通SVIP免广告
                  0069da80一览

                  6a9ec0+768+54d4一览


                  9楼2013-05-04 10:46
                  收起回复
                    如何根据54d4处的1和0,再结合具体的模式以及F数得到出怪列表呢,游戏内有一个函数可以直接完成
                    mov edi,[006a9ec0]
                    mov edi,[edi+768]
                    call 004092e0
                    ret


                    10楼2013-05-04 10:50
                    回复
                      前排拜触


                      11楼2013-05-04 10:51
                      回复
                        基础研究,大师风范,也许哪天能不用辅助工具让小丑不爆


                        IP属地:湖南12楼2013-05-04 10:55
                        收起回复
                          这个好


                          14楼2013-05-04 11:11
                          回复
                            厉害,楼主牛人!这个研究很有意义,比如出怪多少关到达峰值,多少关一次完全的循环……对判定阵型能否无尽可提供一个新的标准。另外我的感觉,打DE时,因为对红眼、白眼、冰车、橄榄同出难度比较大印象比较深,貌似是每39F这个组合重复出现;每关出怪并不是随机的,是游戏设定好的。


                            IP属地:河南来自手机贴吧15楼2013-05-04 11:12
                            回复
                              2026-03-14 19:55:49
                              广告
                              不感兴趣
                              开通SVIP免广告
                              (#啊!)(#啊!)(#啊!)(#啊!)求分析下波僵尸刷新倒计时的计算机制


                              来自手机贴吧16楼2013-05-04 11:25
                              回复