Advertisement
Guest User

SMBbot by HappyLee

a guest
Oct 10th, 2018
654
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 37.84 KB | None | 0 0
  1. function everything()
  2. gui.text(0,0,"JT="..JumpTimer)
  3. gui.text(32,0,"Jump="..FrameJump)
  4. gui.text(96,0,"State="..CurrentState.."-"..AttamptCount[CurrentState])
  5. gui.text(160,0,"SD="..SameDeathCount)
  6. gui.text(192,0,"FH="..FailHoleCount)
  7. gui.text(224,0,"FE="..FailEnemyCount)
  8. gui.text(0,8,"Retry:"..RetryCount)
  9. gui.text(64,8,"Enemy:"..EnemyCount)
  10. gui.text(128,8,"Hole:"..HoleCount)
  11. gui.text(192,8,"Wall:"..WallCount)
  12. gui.text(0,16,"G="..Gaming)
  13. gui.text(32,16,"FD="..FailDeathCount) --若卡在一片区域过不去,这个值就会累计,累计8次奖励1次新存档尝试机会
  14. gui.text(64,16,"LW="..SameLastWallCount) --越不过同一个墙时会累计,累计到99次时该墙免疫
  15. gui.text(96,16,"WR="..WallAllowRetry) --允许墙计数器
  16. gui.text(128,16,"WT="..WallFreeTriggerCount) --无进展撞墙计数器,达到800次开启自由撞墙模式
  17. gui.text(160,16,"WF="..WallFreeMode) --自由撞墙模式,一般是关的
  18. gui.text(192,16,"MF="..MazeFailCount) --迷宫走失败次数
  19. gui.text(224,16,"JC="..FirstFrameJumpChance)
  20. end
  21.  
  22. AutoTurbo=false --自动加速重复部分
  23. PersistSavestate=false --是否存档到文件
  24. AttamptAllowed=10 --设定每个新存档允许尝试次数
  25. JumpRandomness=32 --设定跳跃概率为1/32
  26. SwimRandomnessSlow=50 --设定游泳概率为1/50
  27. SwimRandomnessFast=15 --设定游泳频繁游泳概率为1/15
  28. SwimMax=120 --设定水下最大存档间隔为120帧(2秒)
  29. HoleMax=25 --设定连续落同样沟最多次数
  30. HoleDiff=50 --设定落沟时间最大误差
  31. WallMax=25 --设定连续撞同样墙最多次数
  32. SameWallMax=99 --设定撞同样墙最多次数(不一定连续),超过该次数则该墙免疫,相同墙撞99次应该够多了吧
  33. WallAllowedTime=30 --设定撞墙后允许的时间间隔
  34. WallFreeTrigger=800 --设定无进展撞墙多少次后开启自由撞墙模式,默认800
  35. WallFreeTimer1=54 --设定自由撞墙模式下第一次撞墙后过多少帧后判断Mario是否向右,默认64(经4-4手动测算)
  36. WallFreeTimer2=110 --设定自由撞墙模式下第一次撞墙后过多少帧后判断Mario是否已超越撞墙位置,默认112(经4-4手动测算)
  37. WallFreeTimer3=32 --设定自由撞墙模式下第一次撞墙过后向右走多少帧后判断Mario是否已超越撞墙位置,默认32(经手动测算,针对8-4)
  38.  
  39. lastst=st
  40. lastframe=0
  41. Gaming=0 --游戏状态,0表示不在游戏,1表示在游戏,>1表示在执行开局倒跳
  42. JumpTimer=0
  43. RetryCount=0
  44. EnemyCount=0
  45. HoleCount=0
  46. WallCount=0
  47. FrameFall=9999999
  48. FrameLast=0
  49. CurrentState=9
  50. FrameJump=0
  51. FrameRetry=0
  52. Castle=0
  53. WallAllowedFrame=0 --允许撞墙的最大时间帧数
  54. WallAllowX0=0 --允许撞的墙X坐标大
  55. WallAllowX1=0 --允许撞的墙X坐标
  56. WallFreeMode=0 --自由撞墙模式,一般是关的
  57. WallFreeTriggerCount=0 --判断有多少次无进展撞墙,达到WallFreeTrigger设定值后开启自由撞墙模式
  58. WallFreeFrame0=0 --第一次撞墙时间
  59. WallFreeFrame1=0 --第一次撞墙时间+WallFreeTimer1
  60. WallFreeFrame2=0 --第一次撞墙时间+WallFreeTimer2
  61. WallFreeX0=0 --第一次撞墙X坐标
  62. WallFreeX1=0
  63. Turbo=false --初始为false,判断是否在Turbo状态用
  64. FrameMax=0 --到达最大帧数
  65. SwimRandomness=SwimRandomnessSlow
  66. SuggestJumpAtStart=false --开启时会提示一读档就跳
  67. AttamptCount={0,0,0,0,0,0,0,0,0} --在当前存档的尝试次数
  68. FrameStart={0,0,0,0,0,0,0,0,0} --起始帧
  69. FrameRunningLast={0,0,0,0,0,0,0,0,0} --未防止跑动中撞到敌人或墙,在观看World3录像后决定加
  70. DeathBy=0
  71. DeathFrame=0 --死亡时间帧数记录
  72. DeathX0=0 --对撞墙有用的X位置记录
  73. DeathX1=0 --对撞墙有用的X位置记录
  74. SameDeathCount=0 --相同连续死亡积累次数
  75. SameLastWallCount=0 --达到最终的墙次数,次数累积太多(和SameWallMax(默认50次)相比)会对该墙产生免疫,免疫就可越过该墙
  76. FailDeathCount=0 --探索未成功的死亡次数积累
  77. FailHoleCount=0 --每增加10,增加1首帧跳跃几率
  78. FailEnemyCount=0 --每增加600,返回安全大存档减速重来
  79. BestDeath=0 --最佳死亡时间帧数
  80. BestHoleDeath=0 --最佳落沟死亡时间帧数
  81. BestWallHit=0 --最佳撞墙时间帧数
  82. BestDeathX0=0 --最佳死亡X位置大
  83. BestDeathX1=0 --最佳死亡X位置小
  84. DeathState={0,0} --死亡存档时间帧数,目前只设两个死亡存档记录
  85. DeathStateCount={0,0} --死亡存档死亡率
  86. PressLeft=0 --特殊情况按左
  87. PressDown=0 --特殊情况按下
  88. MazeTimer=0 --迷宫中加载判定点后的计时器
  89. MazeTimer0=0 --为记录MazeTimer+8特殊情况的一个计数器
  90. MazeFailCount=0 --走迷宫失败次数
  91. MazeMode=false --迷宫模式
  92. PipeMazeMode=false --水管迷宫模式
  93. PipeExitBan=0 --会始终为刚开局时的750水管出口信息,随后只有水管出口信息不等于这个值时才有机会按下,防止进入错误管道
  94. PipeExitBan2=0 --对应751的值
  95. PipeExitBan3=0 --对应751的值
  96. FirstFrameJumpChance=0 --落地第一帧即跳的几率,默认是0,每未成功落沟死10次加一,达到5即最大(表示5/6的几率落地即跳),达到10即大力度跳概率最大(为1/2),达到50即清零防死循环
  97. StateCloseAllow=0 --允许最接近存档,只对两种撞墙模式有效,水面和普通不一样,为防止7-2陷入墙缝
  98. WarpZoneCount=0
  99. FrameEnd=9999999
  100. SS={}
  101. SS[2]=savestate.object(2)
  102. SS[3]=savestate.object(3)
  103. SS[4]=savestate.object(4)
  104. SS[5]=savestate.object(5)
  105. SS[6]=savestate.object(6)
  106. SS[7]=savestate.object(7)
  107. SS[8]=savestate.object(8)
  108. SS[9]=savestate.object(9)
  109. InputLeft={}
  110. InputRight={}
  111. InputDown={}
  112. InputA={}
  113. InputB={}
  114. controller={down=false,left=false,right=false,A=false,B=false,start=false}
  115. Acceleration={false,true,true, true,true,false, true,true,false, true,true,false, true,true,false, true,true,false, true,true,false, true,true,false, true,true,false, true,true,false, true,true,false, true,true,false, true,true,false, true,true,false, true,true,false, true,true,false, true,true,false, true,true,false, true,true,false, true,true,false, false,false,false, false,true,false, true,false,false, false,true,true}
  116.  
  117. function add1(a) --循环加法,例如输入8输出为2
  118.     if a+1>8 then
  119.         return a+1-7
  120.     else
  121.         return a+1
  122.     end
  123. end
  124. function sub1(a) --循环减法,例如输入2输出为8
  125.     if a-1<2 then
  126.         return a-1+7
  127.     else
  128.         return a-1
  129.     end
  130. end
  131. function diadd()
  132.     di=di+1
  133.     if di>80 then
  134.         di=1
  135.     end
  136. end
  137. function djsub()
  138.     dj=dj-1
  139.     if dj<1 then
  140.         dj=80
  141.     end
  142. end
  143. function SwitchLeftRight() --调换左右方向,在自由撞墙模式用
  144.     if PressLeft>0 then
  145.         PressLeft=0 --如果当前按左,则开始按右
  146.     else
  147.         PressLeft=120 --设定向左至少2秒时间
  148.     end
  149.     emu.print("SwitchLeftRight")
  150. end
  151. function AddChance(a) --奖励允许尝试次数
  152.     AttamptCount[CurrentState]=AttamptCount[CurrentState]+a
  153.     AttamptCount[CurrentState-1]=AttamptCount[CurrentState-1]+a
  154.     if a>0 then emu.print("AddChance="..a) end
  155. end
  156. function WallFreeEmpty() --清空自由撞墙模式下相关数值,但不关闭自由撞墙模式本身
  157.     WallFreeFrame0=0
  158.     WallFreeFrame1=0
  159.     WallFreeFrame2=0
  160.     WallFreeX0=0
  161.     WallFreeX1=0
  162. end
  163. function DeathStatAdd(a) --添加死亡记录,1=碰敌人,2=落沟,3=撞墙,4=其他,同时计算一些数据
  164.     local b
  165.     if a==DeathBy and ((a==1 and emu.framecount()==DeathFrame) or (a==2 and math.abs(emu.framecount()-DeathFrame)<HoleDiff) or (a==3 and (emu.framecount()==DeathFrame or (X0==DeathX0 and X1==DeathX1)))) then
  166.         SameDeathCount=SameDeathCount+1 --添加重复死亡次数
  167.         b=5 --设定存档死亡指数添加值,因为是重复死亡所以加的多
  168.     else
  169.         SameDeathCount=0 --设定新死亡记录
  170.         DeathBy=a --新死亡方式
  171.         DeathFrame=emu.framecount() --新死亡时间
  172.         DeathX0=X0 --新死亡X坐标
  173.         DeathX1=X1
  174.         b=1
  175.     end
  176.     if FrameStart[CurrentState]==DeathState[2] then --假如恰巧和2号死亡存档撞上,则将2的数据复制到1,再进行添加值等操作
  177.         DeathState[1]=DeathState[2]
  178.         DeathStateCount[1]=DeathStateCount[2]
  179.     end
  180.     if FrameStart[CurrentState]==DeathState[1] then --假如新死亡存档和前一死亡一样
  181.         DeathStateCount[1]=DeathStateCount[1]+b --死亡指数根据死亡方式不同,添加值不一样
  182.     else
  183.         DeathState[2]=DeathState[1] --将1的数据转移到2,然后给1写入新数据
  184.         DeathStateCount[2]=DeathStateCount[1]
  185.         DeathState[1]=FrameStart[CurrentState] --不一样则清空之前的死亡存档记录,新建死亡存档
  186.         DeathStateCount[1]=b --新建存档初始值和添加值一样
  187.     end
  188.     if emu.framecount()<=BestDeath or (a==2 and emu.framecount()<BestHoleDeath+20) or ((WallFreeMode>0 or Swimming) and (X0<BestDeathX0 or (X0==BestDeathX0 and X1<=BestDeathX1))) then --若死亡时间没超过之前的最好成绩,假如自由撞墙模式开启或游泳模式则需判断X位置才知道是否为最好成绩
  189.         if a==3 then --如果无进展撞墙
  190.             if X0==BestDeathX0 and X1==BestDeathX1 then --若在最佳位置死亡(肯定是撞到了同样的墙)
  191.                 SameLastWallCount=SameLastWallCount+1 --撞同样最终墙次数积累
  192.                 if SameLastWallCount==SameWallMax then--若计数器已达到设定次数(默认50次够多了)
  193.                     WallAllowedFrame=BestWallHit+WallAllowedTime --设定允许撞墙时间范围,WallAllowedTime默认60
  194.                     WallAllowX0=BestDeathX0 --这三个值对MarioWall判定很重要,一旦设定则不更改,直到在下个墙也撞50次,或关卡结尾
  195.                     WallAllowX1=BestDeathX1
  196.                     emu.print(WallAllowedFrame..",X0="..WallAllowX0..",X1="..WallAllowX1)
  197.                 end
  198.             end
  199.             WallFreeTriggerCount=WallFreeTriggerCount+1 --无进展撞墙计数+1
  200.             if WallFreeTriggerCount>=WallFreeTrigger then --若超过无进展撞墙数设定(默认500),则开启自由撞墙模式
  201.                 WallFreeMode=1
  202.                 FirstFrameJumpChance=0 --刚开启自由撞墙模式后,首帧起跳概率经常清零
  203.             end
  204.             if X0>BestDeathX0 or (X0==BestDeathX0 and X1>BestDeathX1) then --若已超过最佳死亡位置记录(因为落沟死不加位置记录)
  205.                 SameLastWallCount=0
  206.                 BestDeathX0=X0
  207.                 BestDeathX1=X1
  208.                 BestWallHit=emu.framecount()
  209.             end
  210.         elseif a==2 then --落沟死,则添加无进展落沟死计数
  211.             if emu.framecount()>BestHoleDeath then --落沟死给了20帧的容错空间,若没超过20帧就算作同一个沟
  212.                 BestHoleDeath=emu.framecount()
  213.                 BestDeath=math.max(BestDeath,BestHoleDeath)
  214.             end
  215.             FailHoleCount=FailHoleCount+1
  216.             if FailHoleCount%10==0 then --无进展落沟每10次,首帧跳跃几率增加1
  217.                 FirstFrameJumpChance=FirstFrameJumpChance+1
  218.                 if FirstFrameJumpChance>50 then FirstFrameJumpChance=0 end --首帧跳概率过大的话(超过50)清零,防止死循环
  219.                 emu.print("FirstFrameJumpChance="..FirstFrameJumpChance)
  220.             end
  221.         elseif a==1 then --碰敌人死,添加无进展碰敌人死亡计数
  222.             FailEnemyCount=FailEnemyCount+1
  223.             if X0>BestDeathX0 or (X0==BestDeathX0 and X1>BestDeathX1) then --若已超过最佳死亡位置记录(因为落沟死不加位置记录)
  224.                 SameLastWallCount=0
  225.                 BestDeathX0=X0
  226.                 BestDeathX1=X1
  227.             end
  228.         end
  229.         FailDeathCount=FailDeathCount+1 --未成功死亡次数积累,和奖励次数有关
  230.         if FailDeathCount%300==0 and FailEnemyCount%500~=0 then --累计300次返回3存档
  231.             CurrentState=sub1(sub1(sub1(CurrentState)))
  232.             emu.print("Reverse 3 states")
  233.         end
  234.         if FailDeathCount%1000==0 and FailEnemyCount%500~=0 then --若未成功死亡次数积累过1000,则返回之前稳定大存档重试
  235.             LoadStateBig9()
  236.         end
  237.     else --若已超过之前的最好成绩(若自由撞墙模式则表示已超过之前最好位置)
  238.         AddChance(math.floor(FailDeathCount/10)) --奖励当前存档的尝试次数,累积死10次前后存档各奖励1次
  239.         BestDeath=emu.framecount() --若成功达到新最好成绩
  240.         if a~=2 then
  241.             SameLastWallCount=0 --撞同样墙死亡次数清零,因为已越过该墙,证明该墙是可以通过的,更新落沟死不算,落沟死前撞的墙依然有效(针对4-3的情况)
  242.             BestDeathX0=X0 --记录最好X坐标,落沟死不记录X坐标
  243.             BestDeathX1=X1
  244.         end
  245.         FailDeathCount=0 --未成功死亡次数清零
  246.         FailHoleCount=0
  247.         FailEnemyCount=0
  248.         FirstFrameJumpChance=0 --首帧即跳概率清零
  249.         WallFreeMode=0 --关闭自由撞墙模式
  250.         WallFreeTriggerCount=0 --清空
  251.         WallFreeEmpty() --清空
  252.         if a==3 then BestWallHit=emu.framecount() end --添加最好撞墙时间记录
  253.         if a==2 then BestHoleDeath=emu.framecount() end --添加最好落沟死记录
  254.     end
  255. end
  256. function SaveNewState() --存档,可用存档范围:2-8,9为大档,轻易不存9
  257.     CurrentState=add1(CurrentState) --存档位置+1
  258.     AttamptCount[CurrentState]=AttamptAllowed --设定每个新存档允许尝试次数
  259.     FrameStart[CurrentState]=emu.framecount() --保存存档位置帧数
  260.     FrameRunningLast[CurrentState]=0 --清空允许最后跑动帧记录
  261.     savestate.save(SS[CurrentState]) --存档
  262.     if PersistSavestate then savestate.persist(SS[CurrentState]) end --存档到文件(这两行加一起才算正式存档)
  263.     emu.print("Saved state:"..CurrentState)
  264. end
  265. function SaveNewStateBig9() --存大档,即第9存档,每次保证100%准确时才存(在每关开头或迷宫关解开迷宫后)
  266.     savestate.save(SS[9]) --存大档
  267.     if PersistSavestate then savestate.persist(SS[9]) end --存档到文件(这两行加一起才算正式存档)
  268.     SaveNewState() --存完大档再存个小档(因为大档不常读取)
  269.     AttamptCount[CurrentState]=888 --设定该小档能无限读取
  270.     emu.print("SaveNewStateBig9")
  271. end
  272. function LoadStateBig9() --读大档,即第9存档
  273.     savestate.load(SS[9])
  274.     SaveNewState() --存完大档再存个小档(因为大档不常读取)
  275.     SaveNewState() --存两个档,防止连续死亡后又返回了读大档前的存档
  276.     AttamptCount[CurrentState]=999 --设定该小档能无限读取
  277.     FrameRetry=0
  278.     Retry()
  279.     emu.print("LoadStateBig9")
  280. end
  281. function RestartLevel() --从关卡开头重试
  282.     LoadStateBig9()
  283.     WallAllowX0=0 --开局将墙允许信息清零
  284.     WallAllowX1=0
  285.     WallAllowedFrame=0
  286.     FailDeathCount=0
  287.     FailEnemyCount=0
  288.     FailHoleCount=0
  289.     FirstFrameJumpChance=0 --清空第一帧跳跃几率
  290.     MazeFailCount=0
  291.     MazeTimer=0
  292.     WarpZoneCount=0
  293.     MazeMode=false
  294.     PipeMazeMode=false
  295.     PipeExitBan=memory.readbyte(0x750)
  296. end
  297. function MazeJudge() --判断迷宫,之所以放在这里是因为如果放在主循环则只能检测一次,这个必须每次读档后都重新检测
  298.     if LoopCommand>0 then --检测到迷宫循环判定
  299.         MazeX0=X0
  300.         MazeX1=math.floor(X1/16)*16 --将X1值统一为16整数倍,避免出现位置不同加载迷宫判定导致判定错误等尴尬局面
  301.         MazeTimer=emu.framecount()+1 --指定迷宫判定点为下一帧
  302.         MazeTimer0=MazeTimer
  303.         if PipeMazeMode then MazeTimer=MazeTimer+9 end --水管迷宫模式可将判定时间随机延后8帧,这样8-4第一场景才能进入水管
  304.         MazeMode=true
  305.     elseif emu.framecount()-MazeTimer>=0 and emu.framecount()-MazeTimer<2 then --若当前帧为迷宫判定点
  306.         if X0<MazeX0 or memory.readbyte(0x6D9)~=memory.readbyte(0x6DA) then --若检测到循环,或在7-4走分支失败,走迷宫失败
  307.             MazeFailCount=MazeFailCount+1
  308.             if MazeFailCount>=20 then --连续走迷宫失败20次
  309.                 WallFreeTriggerCount=math.max(WallFreeTrigger-100,WallFreeTriggerCount) --例如WallFreeTrigger默认是800,一走迷宫失败就设置成至少700,相当于省了很多撞墙时间
  310.                 if MazeX0>BestDeathX0 or (MazeX0==BestDeathX0 and MazeX1>BestDeathX1) then --若走迷宫失败,添加最佳死亡位置记录
  311.                     BestDeathX0=MazeX0
  312.                     BestDeathX1=MazeX1
  313.                 end
  314.                 SuggestJumpAtStart=true --暗示开头起跳
  315.                 LoadStateBig9() --返回大存档,一般是关卡开头或上一次走迷宫成功处
  316.                 MazeFailCount=0 --迷宫失败次数清零
  317.                 MazeTimer=0
  318.             else --还没失败20次
  319.                 X0=MazeX0 --即将记录的X位置用前一帧的数据,X坐标+15表示防止在迷宫左侧碰敌人死亡也被算X位置超越
  320.                 X1=MazeX1+15
  321.                 DeathStatAdd(4) --添加失败数据记录,以保存X位置等信息
  322.                 if MazeFailCount==15 then CurrentState=sub1(CurrentState) end --失败第15次时,再返回一层存档
  323.                 if FrameStart[CurrentState]>MazeTimer0-3 then CurrentState=sub1(CurrentState) end --避免让存档点离迷宫判定点太近,如果不做这判断很可能会在迷宫判定点落地而出现问题
  324.                 if WallFreeFrame2>=MazeTimer then --假如迷宫重试时,还在第一次撞墙之后,则FrameRetry要设置对,防止继续撞墙
  325.                     FrameRetry=WallFreeFrame0
  326.                 else
  327.                     FrameRetry=emu.framecount()+40 --防止总在迷宫点附近起跳
  328.                 end
  329.                 Retry() --再试看看能否走出迷宫,同时迷宫时间点清零
  330.                 MazeTimer=0
  331.                 emu.print("Maze fail, MFC="..MazeFailCount)
  332.             end
  333.         elseif (X0==MazeX0 and X1>MazeX1) or X0>MazeX0 then --若没循环,表示走迷宫成功!
  334.             WallFreeMode=0 --关闭自由撞墙模式
  335.             WallFreeTriggerCount=0
  336.             WallFreeEmpty() --清空自由撞墙模式下相关数值
  337.             MazeTimer=0
  338.             MazeFailCount=0 --迷宫失败次数清零
  339.             MazeMode=false
  340.             PipeMazeMode=false
  341.             SaveNewStateBig9() --保存大存档
  342.             emu.print("Maze win!")
  343.         end
  344.     elseif MazeMode==false then --若LoopCommand==0
  345.         MazeTimer=0 --迷宫时间点清空
  346.     end
  347. end
  348. function MarioJump() --跳跃
  349.     if PressDown==0 or Swimming then JumpTimer=math.random(1,35) end --跳跃力度在1-32之间
  350. end
  351. function MarioBigJump() --大力度跳跃
  352.     JumpTimer=math.random(24,35) --跳跃力度在1-32之间
  353.     emu.print("MarioBigJump")
  354. end
  355. function Retry() --重试
  356.     RetryCount=RetryCount+1
  357.     if AttamptCount[CurrentState]>0 then
  358.         AttamptCount[CurrentState]=AttamptCount[CurrentState]-1 --减少一次该存档对应的剩余尝试次数
  359.     else --要是剩余尝试次数为0了
  360.         CurrentState=sub1(CurrentState)
  361.     end
  362.     savestate.load(SS[CurrentState]) --读档
  363.     X0=memory.readbyte(0x6D)
  364.     if X0>128 then X0=0 end --防止迷宫中此值能达到255影响判断
  365.     X1=memory.readbyte(0x86) --读档后更新内存地址,防止后面判断出错
  366.     X2=memory.readbyte(0x400)
  367.     Y0=memory.readbyte(0xB5)
  368.     Y1=memory.readbyte(0xCE)
  369.     SX1=memory.readbyte(0x57)
  370.     SY1=memory.readbyte(0x9F)
  371.     S1=memory.readbyte(0x3AD)
  372.     S2=memory.readbyte(0x71C)
  373.     st=memory.readbyte(0x1D)
  374.     E0=memory.readbyte(0x0E)
  375.     ScrollLock=memory.readbyte(0x723)
  376.     LoopCommand=memory.readbyte(0x745) --读档后必须刷新迷宫循环判定,否则之前信息延留会出现问题
  377.     if FrameFall>FrameStart[CurrentState] then --假如掉落时间在存档后,则在开始和掉落这段时间内起跳
  378.         FrameLast=math.min(FrameFall-1,FrameRetry-2) --计算有效范围最后一帧
  379.     else --掉落时间无效,于是在开始和重试-2这段时间内起跳
  380.         FrameLast=FrameRetry-2 --计算不算掉落帧的话有效范围最后一帧
  381.     end
  382.     if FrameRunningLast[CurrentState]>=FrameStart[CurrentState] then --FrameRunningLast表示允许跑动的最后一帧,也就是说在开始跑动帧到这帧中间必须起跳
  383.         FrameLast=math.min(FrameLast,FrameRunningLast[CurrentState])
  384.     end
  385.     if FrameLast>FrameStart[CurrentState] then
  386.         FrameJump=math.random(FrameStart[CurrentState],FrameLast) --将跳跃位置定在有效范围中间
  387.     else
  388.         FrameJump=FrameStart[CurrentState] --如果FrameLast比存档起始帧小的话,就在起始帧起跳
  389.     end
  390.     if math.random(10)==1 or (FrameRunningLast[CurrentState]==0 and math.random(5)==1) then --有1/10的概率将起跳时间前移,有可能导致不起跳,为了避免离敌人比较近的时候每次试都是跳着试,给一点点跑过去的机会
  391.         if FrameRunningLast[CurrentState]>=FrameStart[CurrentState] then --若最后允许跑动帧有效,则跳跃随机在存档和最后允许跑动帧中间
  392.             FrameJump=math.random(FrameStart[CurrentState],FrameRunningLast[CurrentState])
  393.         else --最后允许跑动帧无效,则跳跃时间提前40帧,有可能导致不起跳
  394.             FrameJump=FrameJump-40
  395.         end
  396.     end
  397.     if FrameRetry==0 then --FrameRetry=0暗示读档后计算起跳时间无效,会沿用随机起跳状态
  398.         FrameJump=FrameStart[CurrentState]-9
  399.     end
  400.     if SuggestJumpAtStart then
  401.         if math.random(3)<3 then
  402.             FrameJump=FrameStart[CurrentState] --赋予2/3的几率刚读档就起跳
  403.         end
  404.         SuggestJumpAtStart=false
  405.     end
  406.     if FirstFrameJumpChance>0 and not Swimming and SX1>24 then --检测到有首帧即跳的概率,会随机一部分(1/6到5/6的概率)让其首帧跳
  407.         if math.random(6)<=math.min(FirstFrameJumpChance,5) then --最小概率1/6,最大概率5/6
  408.             FrameJump=FrameStart[CurrentState] --刚读档就起跳
  409.         end
  410.     end
  411.     if Swimming then --游泳时加入慢游快游两种状态,读档后随机其中一种
  412.         if math.random(2)==1 then --一半概率为慢游 一半概率为快游
  413.             SwimRandomness=SwimRandomnessSlow
  414.         else
  415.             SwimRandomness=SwimRandomnessFast
  416.         end
  417.     end
  418.     st=memory.readbyte(0x1D) --重新判断状态,很可能为0
  419.     lastst=0 --读档后将上一个st清零,不然会判断错误陷入死循环
  420.     lastframe=0
  421.     JumpTimer=0
  422.     WallFreeEmpty() --自由撞墙模式的数值清空
  423.     MazeJudge() --读档后再次判断迷宫
  424.     PressLeft=0 --向右走
  425.     JustLoaded=1
  426. end
  427. function MarioEnemy() --马里奥碰敌人
  428.     EnemyCount=EnemyCount+1
  429.     DeathStatAdd(1) --添加碰敌人死亡记录
  430.     if lastst==0 and lastframe+1==emu.framecount() then --如果重试的前一帧马里奥还在地面跑,将最后一帧跑动帧设置成当前帧
  431.         FrameRunningLast[CurrentState]=math.max(FrameStart[CurrentState],emu.framecount()-3)
  432.     end
  433.     if FailEnemyCount>=500 then --无进展碰敌人每500次,返回之前安全大存档减速重试
  434.         RestartLevel()
  435.         PressLeft=math.random(120) --随机按左0-2秒
  436.         emu.print("PressLeft="..PressLeft)
  437.     else
  438.         FrameRetry=emu.framecount()-1 --假如碰敌人死,死亡时间前移1帧(需要提前3帧起跳才有可能避开敌人,后面会减2帧)
  439.         Retry()
  440.     end
  441. end
  442. function MarioHole() --马里奥落沟中死亡
  443.     HoleCount=HoleCount+1
  444.     DeathStatAdd(2) --添加落沟死亡记录
  445.     if FrameFall>FrameStart[CurrentState] and FrameFall<emu.framecount() then --判断如果跑入沟中,则将坠落前一帧设为允许跑动最后一帧
  446.         FrameRunningLast[CurrentState]=FrameFall-1
  447.     end
  448.     if SameDeathCount>=HoleMax then --假如同一沟中死亡次数过多
  449.         CurrentState=sub1(CurrentState) --返回前一存档
  450.         SuggestJumpAtStart=true --建议开头跳跃
  451.         emu.print("HoleMax!")
  452.     end
  453.     FrameRetry=emu.framecount()-8 --假如掉沟死,死亡时间前移8帧
  454.     Retry()
  455. end
  456. function MarioWall() --马里奥撞墙,假如在允许的时间内撞到允许的墙则没事,关键参数WallAllowedFrame、WallAllowX0和WallAllowX1都是在DeathStatAdd()中计算
  457.     local SameWallAsAllowed
  458.     X1=math.floor(X1/16)*16+2 --如果撞墙,将X1值统一为16整数倍+2,避免出现穿墙或斜角入墙导致判定错误等尴尬局面
  459.     if WallFreeMode==0 then --正常模式(非自由撞墙模式)
  460.         if X0==WallAllowX0 and X1==WallAllowX1 then --判断是否撞到了允许的墙上
  461.             SameWallAsAllowed=true --撞到了允许的墙上
  462.         else
  463.             SameWallAsAllowed=false --撞到的是别的墙
  464.         end --以上代码没啥用,以下代码是关键
  465.         if SameWallAsAllowed==false then --假如撞的墙不是允许的墙
  466.             WallCount=WallCount+1
  467.             DeathStatAdd(3) --添加撞墙记录
  468.             if SameDeathCount>=WallMax then --假如连续太多次(25)撞到相同墙
  469.                 CurrentState=sub1(CurrentState) --返回前一存档
  470.                 SuggestJumpAtStart=true --建议开头跳跃
  471.                 emu.print("WallMax!")
  472.             end
  473.             if ScrollLock==1 then --如果到水关结尾位置(或城堡关最后),撞100次墙后就赋予Mario自由撞墙能力
  474.                 WallFreeTriggerCount=math.max(WallFreeTrigger-50,WallFreeTriggerCount) --例如WallFreeTrigger默认是500,一到水关结尾就设置成至少400,相当于省了很多撞墙时间
  475.             end
  476.             if lastst==0 and lastframe+1==emu.framecount() then --如果重试的前一帧马里奥还在地面跑,将最后一帧跑动帧设置成当前帧
  477.                 FrameRunningLast[CurrentState]=math.max(FrameStart[CurrentState],emu.framecount()-2)
  478.             end
  479.             FrameRetry=emu.framecount()
  480.             Retry() --普通撞墙重试
  481.         else --撞到允许墙
  482.             if emu.framecount()>WallAllowedFrame then --假如已经越过允许的最大撞墙时间,又撞到了被允许的墙上
  483.                 while FrameStart[sub1(CurrentState)]>BestDeath-20 do --前一存档的起始时间必须小于撞墙时间10帧,不然就前一一存档,这是为防止2-2结尾进入1格狭缝做大量存档导致死循环
  484.                     CurrentState=sub1(CurrentState)
  485.                 end
  486.                 WallFreeTriggerCount=WallFreeTriggerCount+1 --无进展撞墙计数+1
  487.                 FrameRetry=BestWallHit --重试时间设为初次撞墙时间
  488.                 Retry() --则不计入撞墙和死亡记录,但依然会重来
  489.             end
  490.             emu.print("Same wall again!")
  491.         end
  492.     elseif WallFreeMode==1 then --假如到自由撞墙模式(累计无进展撞墙次数过多导致,一般是在2-2结尾或迷宫关)
  493.         if emu.framecount()>WallFreeFrame2 then --第一次撞墙,或若在第一次撞墙2秒后又撞到墙,则设定为新第一次撞墙
  494.             WallFreeFrame0=emu.framecount()
  495.             WallFreeX0=X0
  496.             WallFreeX1=X1
  497.             if math.random(3)<=2 and SY1>1 and SY1<9 and MazeMode and not PipeMazeMode then --2/3的概率且有向下速度的时候向左走,例如4-4的情况
  498.                 PressLeft=120
  499.                 WallFreeFrame1=WallFreeFrame0+WallFreeTimer1 --第一个判定节点,马里奥按右才能通过
  500.                 WallFreeFrame2=WallFreeFrame0+WallFreeTimer2 --第二个判定节点,马里奥比撞墙时X位置大才能通过
  501.             else --1/3的概率或二段跳的时候向右走,例如2-2和8-4的情况
  502.                 WallFreeFrame2=WallFreeFrame0+WallFreeTimer3 --第二个判定节点,马里奥比撞墙时X位置大才能通过
  503.             end
  504.             if st>0 and SY1<9 and memory.readbyte(0x86)>=X1+2 and memory.readbyte(0x86)<=X1+3 then --检测穿墙
  505.                 PressLeft=3
  506.                 SuggestJumpAtStart=true --落地即跳
  507.             end
  508.             if S1>236 then --防止4-2进入Warp Zone死循环
  509.                 WarpZoneCount=WarpZoneCount+1
  510.                 if WarpZoneCount>9 then
  511.                     RestartLevel()
  512.                     WallFreeMode=0 --关闭自由撞墙模式
  513.                     WallFreeTriggerCount=0 --清空
  514.                     WallFreeEmpty() --自由撞墙模式的数值清空
  515.                 end
  516.             end
  517.             emu.print("First wall bump at "..WallFreeFrame0)
  518.         else --若本次撞墙还在撞墙时间范围内
  519.             if X0==WallFreeX0 and X1==WallFreeX1 then --若撞的墙是第一次撞墙,保持撞墙后随机的方向
  520.            
  521.             else --若撞的墙和第一次撞墙不是一个墙,则有很大概率会向右走
  522.                 PressLeft=0
  523.             end
  524.         end
  525.     end
  526. end
  527. function MarioFall() --马里奥开始下落
  528.     FrameFall=emu.framecount()
  529.     if math.random(3)==1 and WallFreeMode==0 and SY1<8 then --下落有三分之一概率会重试,为提高4-3和4-4等关卡的概率,判断纵向速度是Mars的主意,为防止踩弹簧弹跳也重来
  530.         FrameRetry=emu.framecount()+1
  531.         Retry()
  532.     end
  533. end
  534. function MarioLand() --马里奥刚落地
  535.     if WallFreeMode==0 or emu.framecount()>WallFreeFrame2 or emu.framecount()==WallFreeFrame0 then --正常模式,或自由撞墙模式已过时间范围,或落地这帧刚好是第一次撞墙帧,允许二段跳的可能
  536.         if (emu.framecount()==DeathState[1] and math.random(DeathStateCount[1])>10) or (emu.framecount()==DeathState[2] and math.random(DeathStateCount[2])>10 and SX1~=0 and memory.readbyte(0x70E)==0) then --若触发死亡存档以及死亡概率,DeathStateCount越大重试概率越大
  537.             FrameRetry=emu.framecount()
  538.             Retry() --重新再来
  539.             emu.print("DeathStateCount[1]="..DeathStateCount[1]..", DeathStateCount[2]="..DeathStateCount[2])
  540.         else --假如没触发死亡存档,则可新建存档
  541.             SaveNewState()
  542.             if FirstFrameJumpChance>0 and not Swimming and SX1>24 then --检测到有首帧即跳的概率,会随机一部分(1/6到5/6的概率)让其一落地就跳
  543.                 if math.random(6)<=math.min(FirstFrameJumpChance,5) then --最小概率1/6,最大概率5/6
  544.                     MarioJump() --瞬间起跳
  545.                     if math.random(30)<=math.min(FirstFrameJumpChance,10) then --最小概率1/30,最大概率10/30即三分之一的概率大力度起跳
  546.                         MarioBigJump() --用24-35之间的大力度跳
  547.                     end
  548.                 end
  549.             end
  550.             if SX1==0 and (WallFreeMode==0 or emu.framecount()==WallFreeFrame0) then --如果落地瞬间速度为0,暗示很可能是二段跳瞬间,不能放过
  551.                 MarioBigJump() --瞬间大力度起跳
  552.                 PressLeft=0 --确保是向右跳,向左跳无意义
  553.                 AttamptCount[CurrentState]=AttamptCount[CurrentState]+2 --因为可能是二段跳,奖励两次尝试机会
  554.             elseif PipeMazeMode and memory.readbyte(0x750)~=PipeExitBan and memory.readbyte(0x751)~=PipeExitBan2 and memory.readbyte(0x751)~=PipeExitBan3 then --如果是水管迷宫模式,水管出口信息和关卡开头不一样,则按下1帧
  555.                 PressDown=1
  556.             elseif memory.readbyte(0x750)==PipeExitBan then --设置并判断第二个不允许的管道信息,751
  557.                 if PipeExitBan2==memory.readbyte(0x751) then
  558.                    
  559.                 else
  560.                     PipeExitBan3=PipeExitBan2
  561.                     PipeExitBan2=memory.readbyte(0x751)
  562.                 end
  563.             end
  564.         end
  565.     elseif SuggestJumpAtStart then --假如自由撞墙模式开启且在时间范围内,落地就不存档
  566.         MarioJump() --落地即起跳,可能是前面有穿墙动作,建议起跳
  567.         SuggestJumpAtStart=false
  568.     end
  569. end
  570. function MarioFlagpole() --马里奥碰旗杆
  571.     Gaming=0
  572.     WallFreeMode=0
  573.     emu.print("MarioFlagpole")
  574. end
  575. function MarioPipe() --马里奥进水管
  576.     Gaming=0
  577.     WallFreeMode=0
  578.     emu.print("MarioPipe")
  579. end
  580. function MarioCastle() --马里奥城堡关碰斧头
  581.     Gaming=0
  582.     WallFreeMode=0
  583.     Castle=1
  584.     emu.print("MarioCastle="..Castle)
  585. end
  586. function MarioSwim() --水下游泳状态
  587.     if math.random(SwimRandomness)==1 then
  588.         JumpTimer=2 --这里不用MarioJump,因为游泳每下如果游多可能会冲突
  589.     end
  590.     if emu.framecount()-FrameStart[CurrentState]>SwimMax and WallFreeMode==0 then --到达最大存档间隔,水中默认最多每隔2秒保存一个存档
  591.         SaveNewState()
  592.     end
  593.     if SX1>16 then --在水中地面上速度大于16就按下
  594.         controller.down=true
  595.     end
  596. end
  597.  
  598. gui.register(everything) --显示值用
  599.  
  600. while true do --主循环
  601. controller.down=false
  602. controller.left=false
  603. controller.right=false
  604. controller.A=false
  605. controller.B=false
  606. controller.start=false
  607. X0=memory.readbyte(0x6D)
  608. if X0>128 then X0=0 end --防止迷宫中此值能达到255影响判断
  609. X1=memory.readbyte(0x86)
  610. X2=memory.readbyte(0x400)
  611. Y0=memory.readbyte(0xB5)
  612. Y1=memory.readbyte(0xCE)
  613. SX1=memory.readbyte(0x57)
  614. SY1=memory.readbyte(0x9F)
  615. S1=memory.readbyte(0x3AD)
  616. S2=memory.readbyte(0x71C)
  617. st=memory.readbyte(0x1D)
  618. E0=memory.readbyte(0x0E)
  619. ScrollLock=memory.readbyte(0x723)
  620. LoopCommand=memory.readbyte(0x745) --迷宫循环判定
  621. JustLoaded=0 --为防止读档后st值错乱加的判定
  622.  
  623.  
  624. if Gaming>1 then --执行开局倒跳
  625.     controller.B=true
  626.     controller.left=Acceleration[(25-Gaming)*3+1]
  627.     controller.right=Acceleration[(25-Gaming)*3+2]
  628.     controller.A=Acceleration[(25-Gaming)*3+3] --用存储在Acceleration中的按键
  629.     Gaming=Gaming-1
  630.     if Gaming==4 and st==0 then --这帧默认是左右都不按,但要是这帧在地上则要按左右
  631.         controller.left=true
  632.         controller.right=true
  633.         controller.B=true
  634.     end
  635.     if Gaming==2 then --存个大档
  636.         SaveNewStateBig9()
  637.     end
  638. elseif Gaming==1 then --主要游戏部分
  639.     if Y1>196 and Y0==1 then --掉坑的新判定,不用以前的音效,而是用坐标
  640.         MarioHole()
  641.     elseif memory.readbyte(0x00FC)==1 then
  642.         MarioEnemy()
  643.     elseif memory.readbyte(0x0713)==64 then
  644.         MarioFlagpole()
  645.     elseif E0==3 or E0==2 then
  646.         MarioPipe()
  647.     elseif SX1==0 then --撞墙
  648.         MarioWall()
  649.     elseif memory.readbyte(0x770)==2 then --判断碰斧头通关
  650.         MarioCastle()
  651.     end
  652.     if Gaming==1 then --如果游戏还在继续
  653.         if memory.readbyte(0x0704)==1 then --判断游泳状态
  654.             Swimming=true
  655.             MarioSwim()
  656.             StateCloseAllow=30 --游泳时设置值大一些
  657.         else
  658.             Swimming=false
  659.             StateCloseAllow=20
  660.         end
  661.         if WallFreeMode>0 then --若是自由撞墙模式,有两个时间节点要判断
  662.             if emu.framecount()<=WallFreeFrame2 and X0==WallFreeX0 and X1>WallFreeX1+4 then --若过了第一次撞墙的位置
  663.                 if st==0 then SaveNewState() end --还在地面就存个档,如果在空中就不必存档了,因为落地时会存档
  664.                 WallFreeEmpty() --自由撞墙模式的数值清空
  665.             elseif emu.framecount()==WallFreeFrame1 and PressLeft>0 then --在第一时间节点Mario必须是向右走的,向左走不允许
  666.                 while WallFreeFrame0>0 and FrameStart[sub1(CurrentState)]>WallFreeFrame0-StateCloseAllow do --前一存档的起始时间必须小于撞墙时间20帧,不然就前移一存档,这是为防止2-2结尾进入1格狭缝做大量存档导致死循环
  667.                     CurrentState=sub1(CurrentState)
  668.                 end
  669.                 FrameRetry=WallFreeFrame0 --重试时间设为第一次撞墙时间
  670.                 Retry() --返回撞墙前重试,同时将自由撞墙模式数值清空
  671.             elseif emu.framecount()==WallFreeFrame2 then --到第二个节点,但没过第一次撞墙位置
  672.                 while WallFreeFrame0>0 and FrameStart[sub1(CurrentState)]>WallFreeFrame0-StateCloseAllow do --前一存档的起始时间必须小于撞墙时间20帧,不然就前移一存档,这是为防止2-2结尾进入1格狭缝做大量存档导致死循环
  673.                     CurrentState=sub1(CurrentState)
  674.                 end
  675.                 FrameRetry=WallFreeFrame0 --重试时间设为第一次撞墙时间
  676.                 Retry() --返回撞墙前重试,同时将自由撞墙模式数值清空
  677.             end
  678.         end
  679.         if MazeMode and memory.readbyte(0x750)~=PipeExitBan then PipeMazeMode=true end --迷宫模式下,检测到水管信息变化,则开启水管迷宫模式
  680.         MazeJudge()
  681.         controller.B=true --B键一直打开
  682.         if st==2 and lastst==0 and lastframe+1==emu.framecount() and JustLoaded==0 and Swimming==false then --判断两个st状态差,若开始下落
  683.             MarioFall()
  684.         elseif st==0 and lastst>0 and lastframe+1==emu.framecount() and JustLoaded==0 then --判断刚刚落地状态
  685.             MarioLand()
  686.         elseif PipeMazeMode and st==0 and memory.readbyte(0x86)%16==3 and memory.readbyte(0x750)~=PipeExitBan and memory.readbyte(0x751)~=PipeExitBan2 and memory.readbyte(0x751)~=PipeExitBan3 then --水管迷宫模式在地面跑动到像19这样的位置时会按下1帧
  687.             PressDown=1
  688.         end
  689.         if PressLeft>0 then --如遇特殊情况需要按左
  690.             controller.left=true
  691.             PressLeft=PressLeft-1
  692.         elseif PressDown>0 then
  693.             controller.down=true
  694.             PressDown=0
  695.         else --PressLeft==0并且PressDown==0,表示向右走
  696.             controller.right=true --一直按住右键
  697.         end
  698.         if st==0 then --在地面跑动中
  699.             if FrameJump==emu.framecount() then --若指定当前帧跳
  700.                 MarioJump()
  701.                 if FirstFrameJumpChance>0 and not Swimming then --检测到有首帧即跳的概率,会随机一部分(1/20到10/30的概率)让其最大力度跳跃
  702.                     if math.random(30)<=math.min(FirstFrameJumpChance,10) then --最小概率1/30,最大概率10/30即三分之一的概率最大力度起跳
  703.                         MarioBigJump() --用24-35之间的大力度跳
  704.                     end
  705.                 end
  706.             elseif FrameJump>emu.framecount() then --若指定帧在后面,则继续跑
  707.                
  708.             elseif math.random(JumpRandomness)==1 then --若没指定跳跃帧的话,参考设定的跳跃概率做随机跳跃
  709.                 MarioJump()
  710.             end
  711.         end
  712.         if JumpTimer>0 then --跳跃?
  713.             controller.A=true
  714.             JumpTimer=JumpTimer-1
  715.         end
  716.         lastst=st
  717.         lastframe=emu.framecount()
  718.     end
  719. else --Gaming==0 游戏还未开始
  720.     if emu.framecount()==41 then --判断按Start的帧
  721.         controller.start=true
  722.     end
  723.     if Castle==1 and E0==0 then
  724.         Castle=0
  725.     end
  726.     if emu.framecount()>99 and E0==8 and Castle==0 then --0x0E=8说明准备开始游戏
  727.         if SY1==0 and memory.readbyte(0x0704)~=1 then --如果在地面且不在游泳
  728.             Gaming=25 --开始开局倒跳
  729.         else
  730.             Gaming=1 --不开局倒跳
  731.             SaveNewStateBig9() --存个大档
  732.         end
  733.         WallAllowX0=0 --开局将墙允许信息清零
  734.         WallAllowX1=0
  735.         WallAllowedFrame=0
  736.         WallFreeMode=0 --关闭自由撞墙模式
  737.         WallFreeTriggerCount=0 --清空
  738.         WallFreeEmpty() --自由撞墙模式的数值清空
  739.         FailDeathCount=0
  740.         FailEnemyCount=0
  741.         FailHoleCount=0
  742.         FirstFrameJumpChance=0 --清空第一帧跳跃几率
  743.         MazeFailCount=0
  744.         MazeTimer=0
  745.         WarpZoneCount=0
  746.         MazeMode=false
  747.         PipeMazeMode=false
  748.         PipeExitBan=memory.readbyte(0x750)
  749.         controller.left=true
  750.         controller.right=true --开局左右1帧
  751.     end
  752.     if memory.readbyte(0x00FC)==4 and emu.framecount()<FrameEnd then --见到公主音乐响起,保存按键到文件
  753.         file=io.open("SMBbotInput_"..emu.framecount().."_Retry"..RetryCount..".txt","w")
  754.         for FrameEnd=0,emu.framecount() do
  755.             if FrameEnd==41 then file:write("|0|....T...|||\n")
  756.             else
  757.                 if (InputRight[FrameEnd]==true) then file:write("|0|R")
  758.                 else file:write("|0|.") end
  759.                 if (InputLeft[FrameEnd]==true) then file:write("L")
  760.                 else file:write(".") end
  761.                 if (InputDown[FrameEnd]==true) then file:write("D...")
  762.                 else file:write("....") end
  763.                 if (InputB[FrameEnd]==true) then file:write("B")
  764.                 else file:write(".") end
  765.                 if (InputA[FrameEnd]==true) then file:write("A|||\n")
  766.                 else file:write(".|||\n") end
  767.             end
  768.         end
  769.         emu.pause()
  770.     end
  771. end
  772. if FrameMax<emu.framecount() then --当前帧大于此前最好成绩
  773.     FrameMax=emu.framecount()
  774.     if Turbo and AutoTurbo then
  775.         emu.speedmode("normal") --恢复正常速度
  776.         Turbo=false
  777.     end
  778. else
  779.     if AutoTurbo and Turbo==false then
  780.         emu.speedmode("maximum") --加速重复部分
  781.         Turbo=true
  782.     end
  783. end
  784. joypad.set(1,controller)
  785. if controller.left then InputLeft[emu.framecount()]=true
  786. else InputLeft[emu.framecount()]=false end
  787. if controller.right then InputRight[emu.framecount()]=true
  788. else InputRight[emu.framecount()]=false end
  789. if controller.down then InputDown[emu.framecount()]=true
  790. else InputDown[emu.framecount()]=false end
  791. if controller.A then InputA[emu.framecount()]=true
  792. else InputA[emu.framecount()]=false end
  793. if controller.B then InputB[emu.framecount()]=true
  794. else InputB[emu.framecount()]=false end
  795. emu.frameadvance()
  796. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement