植物大战僵尸吧 关注:557,506贴子:5,062,678

关于近日小推车bug原理解释

只看楼主收藏回复

最近贴吧有个重新生成小推车的bug的贴,虽然最终证明是修改器导致的,但是为什么会造成这样在代码上还是值得讨论一下的,所以发此贴解析一手。


IP属地:河北来自Android客户端1楼2022-08-26 19:42回复
    首先我们需要了解一下游戏生成小推车相关。
    原版位于0040BC70的函数用于初始生成小推车。
    这里生成的小推车是隐形的,且横坐标为-160。
    然后在播放Ready,Start,Plant的时候,才让小推车显示出来,并前进到一般小推车的位置。


    IP属地:河北2楼2022-08-26 19:51
    收起回复
      前排顶帖


      IP属地:上海来自iPhone客户端3楼2022-08-26 19:52
      回复
        顶顶


        IP属地:上海来自Android客户端4楼2022-08-26 19:56
        回复
          前排膜。


          IP属地:湖北5楼2022-08-26 19:56
          回复
            而1.8.7修改器的相关代码是这么写的:
            恢复除草机:清除所有小推车,产生新的小推车
            看起来是不是不会有问题?
            但是你是不是忘了这么一件事?
            一.我在选卡恢复并启动小推车,此时原版原生的小推车并没有出现,修改器小推车编号(就是栈位)0到5;
            二.游戏开始时,创建正常的小推车,编号成了6到B(11)。
            是不是不会有什么问题?但是原版有个非常神(缺)奇(德)的地方,就是关卡开始更新小推车只会更新编号前6个。
            然后很神奇的,你已经启动的小推车被更新了,原版本来创建的小推车就很神奇的保持了初始状态。


            IP属地:河北6楼2022-08-26 20:02
            收起回复
              这里给大家看一下这个缺德的关卡准备阶段小推车更新:
              0043BE6C - xor ebx,ebx
              0043BE6E - mov edi,edi
              0043BE70 - mov edi,[ebx*4+006AA2AC]
              0043BE77 - add edi,[ebp+10]
              0043BE7A - add edi,[ebp+0C]
              0043BE7D - add edi,[ebp+20]
              0043BE80 - cmp [ebp+08],edi
              0043BE83 - jle 0043BEE0
              0043BE85 - mov edx,[ebp+04]
              0043BE88 - lea esi,[esp+24]
              0043BE8C - mov [esp+24],00000000
              0043BE94 - call 0041CA70
              0043BE99 - test al,al
              0043BE9B - je 0043BEE0
              0043BE9D - lea ecx,[ecx+00]
              0043BEA0 - mov esi,[esp+24]
              0043BEA4 - cmp [esi+14],ebx
              0043BEA7 - je 0043BEB8
              0043BEA9 - lea esi,[esp+24]
              0043BEAD - call 0041CA70
              0043BEB2 - test al,al
              0043BEB4 - jne 0043BEA0
              0043BEB6 - jmp 0043BEE0
              0043BEB8 - push 04
              0043BEBA - push -15
              0043BEBC - mov byte ptr [esi+31],01
              0043BEC0 - mov eax,[ebp+08]
              0043BEC3 - push -50
              0043BEC5 - lea ecx,[edi+000000FA]
              0043BECB - mov edx,edi
              0043BECD - call 00511C40
              0043BED2 - mov [esp+30],eax
              0043BED6 - fild dword ptr [esp+30]
              0043BEDA - add esp,0C
              0043BEDD - fstp dword ptr [esi+08]
              0043BEE0 - add ebx,01
              0043BEE3 - cmp ebx,06
              0043BEE6 - jl 0043BE70
              没错,每行只取一个。
              当然你也可以看我改了之后的意思差不多的C++代码,现写的,意思到就好:
              *Board MainBoard;
              for(int i=0;i<6;i++){
              //这里略去一些无关的部分
              *mower m=NULL;
              while(FindFirstMower(MainBoard,m)){
              if(m->mRow==i){
              m->mVisible=true;
              //这里省去运动的代码,问就是懒
              break;
              }
              }
              }


              IP属地:河北7楼2022-08-26 20:11
              回复
                基本原理基本就是这些了。
                我这里额外讨论一下为什么橄榄之类的能试出来。


                IP属地:河北8楼2022-08-26 20:12
                回复
                  首先先说一个题外话,食脑判定和小推车触发判定。
                  这两个有点不太一样的说。
                  ——————————————————————
                  食脑判定:
                  对于任何满足条件的僵尸,图像横坐标小于一定值X时,判定失败。
                  X默认为-100,针对以下僵尸改变:
                  巨人僵尸,红眼巨人僵尸,撑杆僵尸:改为-150
                  投石车僵尸,橄榄球僵尸,冰车僵尸:改为-175
                  舞王僵尸,伴舞僵尸,潜水僵尸:改为-130
                  ——————————————————————
                  小推车判定:
                  僵尸的所在矩形与小推车是否相交(部分情况有特殊判定,但是没啥影响,略过)
                  ——————————————————————


                  IP属地:河北9楼2022-08-26 20:23
                  回复
                    这样子,橄榄球僵尸、冰车僵尸、投石车僵尸能触发就是显而易见的了。
                    而由于小推车本身有宽度,撑杆僵尸判定相对靠左,所以撑杆僵尸也可以触发。
                    而普通僵尸食脑为-100,自然触发不了。
                    顺手一提,濒死的僵尸触发不了小推车,所以现象中的快死了才出发是子虚乌有的事,是因为他被小推车压死了)


                    IP属地:河北10楼2022-08-26 20:27
                    收起回复
                      另外,不仅1.8.7修改器,PT在第一次选卡时重生成-启动小推车也会有类似的效果。
                      最好的修复方法是不让选卡时点。
                      在原版函数加个小推车数量判断也是可行的,但是对于修改器太没有必要了。


                      IP属地:河北11楼2022-08-26 20:29
                      收起回复
                        这样,辣椒为什么触发不了的问题也迎刃而解了。


                        IP属地:河北12楼2022-08-26 20:29
                        回复
                          以上就是针对这个现象的完整解析,原版正常游戏过程中无法触发,自然也没办法在无尽中利用了。
                          这个让我看了一中午没复现的问题终于解决了。
                          由于今天下午有考试,研究到一半就去考试了,路上推测是修改器把推车隐形,坐标改负。
                          后面和六三enjoy讨论并一起得出是重初始化了推车的原因,在问题提出者给出更详细的测试结果后,问题也就迎刃而解了。
                          我说咋复现不了呢我还问了下零度、六三、小黑有没有复现,结果也是没有,然后想到了修改器的原因。
                          问题发现:@可爱的圆神
                          结论得出过程中重要的一环:@六三enjoy


                          IP属地:河北13楼2022-08-26 20:35
                          收起回复
                            ——————顺手一体的有趣的机制——————
                            原版有个类似调试模式的东西,打开后会有个功能。
                            叫做小推车删除后在本列再生成一个小推车。
                            原版只有两个地方调用过小推车生成,一个是这个,另一个是初始化。


                            IP属地:河北14楼2022-08-26 20:36
                            收起回复
                              顺手一体,在GhTr改版的设计过程中,这个小推车更新机制就被我发现了。
                              早期GhTr(重置前)红针花线的双重推车。
                              但是我最开始一直没往重生成小推车的思路走,不然可以少绕很多弯路的。


                              IP属地:河北15楼2022-08-26 20:39
                              回复