Skip to content

Commit

Permalink
Add Autoskip feature to TAS (#992)
Browse files Browse the repository at this point in the history
  • Loading branch information
Not-A-Normal-Robot authored and MrZ626 committed Oct 5, 2023
1 parent eae441b commit 120dc45
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 32 deletions.
2 changes: 1 addition & 1 deletion parts/scenes/app_console.lua
Original file line number Diff line number Diff line change
Expand Up @@ -853,7 +853,7 @@ local commands={} do
saveSettings()
log("Allow TAS: "..bool)
if bool then
log("Hot keys: f1=play/pause f2=slow down f3=speed up/next frame")
log("Hot keys: f1=play/pause f2=slow down f3=speed up/next frame f4=adjust skip settings")
end
else
log{C.A,"Usage: tas <on|off>"}
Expand Down
130 changes: 99 additions & 31 deletions parts/scenes/game.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,62 +10,78 @@ local setFont,mStr=FONT.set,GC.mStr
local noTouch,noKey=false,false
local touchMoveLastFrame=false
local trigGameRate,gameRate
local autoSkip=0
local modeTextPos,modeTextWidK

local replaying
local repRateStrings={[0]="pause",[.125]="0.125x",[.5]="0.5x",[1]="1x",[2]="2x",[5]="5x"}

local scene={}

-- Widget hashmap (key = widget name, value = index)
local widgetHashmap={}
local function widgetWithName(name)
if #widgetHashmap==0 then widgetHashmap=TABLE.kvSwap(TABLE.extract(scene.widgetList,'name')) end
return scene.widgetList[widgetHashmap[name]]
end

local function _updateMenuButtons()
scene.widgetList.restart.hide=replaying
widgetWithName('restart').hide=replaying

local pos=(GAME.tasUsed or replaying) and 'right' or SETTING.menuPos
modeTextWidK=math.min(280/TEXTOBJ.modeName:getWidth(),1)
if SETTING.portrait then
scene.widgetList.restart.y=25-400
scene.widgetList.pause.y=25-400
widgetWithName('restart').y=25-400
widgetWithName('pause').y=25-400
else
scene.widgetList.restart.y=25
scene.widgetList.pause.y=25
widgetWithName('restart').y=25
widgetWithName('pause').y=25
end
if GAME.replaying then
scene.widgetList.pause.x=1195
widgetWithName('pause').x=1195
modeTextPos=1185-TEXTOBJ.modeName:getWidth()*modeTextWidK
elseif pos=='right' then
scene.widgetList.restart.x=1125
scene.widgetList.pause.x=1195
widgetWithName('restart').x=1125
widgetWithName('pause').x=1195
modeTextPos=1115-TEXTOBJ.modeName:getWidth()*modeTextWidK
elseif pos=='middle' then
scene.widgetList.restart.x=360
scene.widgetList.pause.x=860
widgetWithName('restart').x=360
widgetWithName('pause').x=860
modeTextPos=940
elseif pos=='left' then
scene.widgetList.restart.x=120
scene.widgetList.pause.x=190
widgetWithName('restart').x=120
widgetWithName('pause').x=190
modeTextPos=1200-TEXTOBJ.modeName:getWidth()*modeTextWidK
end
end

local speedButtons={'rep0','repP8','repP2','rep1','rep2','rep5'}
local stepButtons={'step','autoSkip'}
local replayButtons=TABLE.combine(speedButtons,stepButtons)
local function _updateRepButtons()
local L=scene.widgetList
if replaying or GAME.tasUsed then
for i=1,6 do L[i].hide=false end L[7].hide=true
for i=1,#speedButtons do
widgetWithName(speedButtons[i]).hide=false
end
for i=1,#stepButtons do
widgetWithName(stepButtons[i]).hide=gameRate~=0
end
if gameRate==0 then
L[1].hide=true
L[7].hide=false
widgetWithName('rep0').hide=true
elseif gameRate==.125 then
L[2].hide=true
widgetWithName('repP8').hide=true
elseif gameRate==.5 then
L[3].hide=true
widgetWithName('repP2').hide=true
elseif gameRate==1 then
L[4].hide=true
widgetWithName('rep1').hide=true
elseif gameRate==2 then
L[5].hide=true
widgetWithName('rep2').hide=true
elseif gameRate==5 then
L[6].hide=true
widgetWithName('rep5').hide=true
end
else
for i=1,7 do L[i].hide=true end
for i=1,#replayButtons do widgetWithName(replayButtons[i]).hide=true end
end
end
local function _speedUp()
Expand Down Expand Up @@ -115,7 +131,46 @@ local function _rep5()
gameRate=5
_updateRepButtons()
end
local function _step() trigGameRate=trigGameRate+1 end
local function _skip(P)
if P.frameRun<179 then
trigGameRate=trigGameRate+(179-P.frameRun)
else
trigGameRate=trigGameRate+MATH.clamp(P.waiting+P.falling,1,300)
end
end
local fastForwardObj = GC.newText(FONT.get(40),CHAR.icon.fastForward)
local nextFrameObj = GC.newText(FONT.get(40),CHAR.icon.nextFrame)
local function _updateStepButton()
local w=PLAYERS[1].waiting+PLAYERS[1].falling
if (autoSkip==1 and w>1) or (autoSkip>0 and PLAYERS[1].frameRun<178) then
widgetWithName('step').obj=fastForwardObj
else
widgetWithName('step').obj=nextFrameObj
end
end
local function _step()
local P=PLAYERS[1]
if autoSkip>0 then
_skip(P)
else
trigGameRate=trigGameRate+1
end
end
local function _fullSkipCheck()
if autoSkip<2 or PLAYERS[1].waiting+PLAYERS[1].falling<=0 then return end
_step()
end
local function _setAS(v)
autoSkip=v
if v==1 then _updateStepButton() end
end
local function _autoSkipDisp()
return (
autoSkip==0 and 'No skip' or
autoSkip==1 and 'Semi-skip' or
autoSkip==2 and 'Full skip'
)
end

local function _restart()
resetGameData(PLAYERS[1].frameRun<240 and 'q')
Expand All @@ -131,6 +186,8 @@ local function _checkGameKeyDown(key)
if noKey then return end
PLAYERS[1]:pressKey(k)
VK.press(k)
_updateStepButton()
_fullSkipCheck()
return
elseif not GAME.fromRepMenu then
_restart()
Expand All @@ -155,11 +212,14 @@ function scene.enter()
elseif not replaying then
if GAME.tasUsed then
trigGameRate,gameRate=0,0
autoSkip=1
else
trigGameRate,gameRate=0,1
autoSkip=0
end
end

_updateStepButton()
_updateRepButtons()
_updateMenuButtons()
end
Expand All @@ -172,6 +232,8 @@ function scene.touchDown(x,y)
if t then
PLAYERS[1]:pressKey(t)
VK.touch(t,x,y)
_updateStepButton()
_fullSkipCheck()
end
end
function scene.touchUp(x,y)
Expand Down Expand Up @@ -250,6 +312,8 @@ function scene.keyDown(key,isRep)
elseif not isRep then
_speedUp()
end
elseif key=='f4' then
autoSkip=(autoSkip+1)%3
end
end
if key=='escape' then
Expand All @@ -275,6 +339,8 @@ function scene.gamepadDown(key)
if k>0 then
PLAYERS[1]:pressKey(k)
VK.press(k)
_updateStepButton()
_fullSkipCheck()
else
_restart()
end
Expand Down Expand Up @@ -314,6 +380,7 @@ function scene.update(dt)
while trigGameRate>=1 do
trigGameRate=trigGameRate-1
_update_common(dt)
_updateStepButton()
end
end

Expand Down Expand Up @@ -403,15 +470,16 @@ function scene.draw()
drawWarning()
end
scene.widgetList={
WIDGET.newKey{name='rep0', x=40, y=50,w=60,code=_rep0, font=40,fText=CHAR.icon.pause},
WIDGET.newKey{name='repP8', x=105,y=50,w=60,code=_repP8, font=40,fText=CHAR.icon.speedOneEights},
WIDGET.newKey{name='repP2', x=170,y=50,w=60,code=_repP2, font=40,fText=CHAR.icon.speedOneHalf},
WIDGET.newKey{name='rep1', x=235,y=50,w=60,code=_rep1, font=40,fText=CHAR.icon.speedOne},
WIDGET.newKey{name='rep2', x=300,y=50,w=60,code=_rep2, font=40,fText=CHAR.icon.speedTwo},
WIDGET.newKey{name='rep5', x=365,y=50,w=60,code=_rep5, font=40,fText=CHAR.icon.speedFive},
WIDGET.newKey{name='step', x=430,y=50,w=60,code=_step, font=40,fText=CHAR.icon.nextFrame},
WIDGET.newKey{name='restart',x=0, y=25,w=60,code=_restart, font=40,fText=CHAR.icon.retry_spin},
WIDGET.newKey{name='pause', x=0, y=25,w=60,code=pauseGame,font=40,fText=CHAR.icon.pause},
WIDGET.newKey {name='rep0', x=40, y=50, w=60, code=_rep0, font=40, fText=CHAR.icon.pause}, -- 1
WIDGET.newKey {name='repP8', x=105,y=50, w=60, code=_repP8, font=40, fText=CHAR.icon.speedOneEights}, -- 2
WIDGET.newKey {name='repP2', x=170,y=50, w=60, code=_repP2, font=40, fText=CHAR.icon.speedOneHalf}, -- 3
WIDGET.newKey {name='rep1', x=235,y=50, w=60, code=_rep1, font=40, fText=CHAR.icon.speedOne}, -- 4
WIDGET.newKey {name='rep2', x=300,y=50, w=60, code=_rep2, font=40, fText=CHAR.icon.speedTwo}, -- 5
WIDGET.newKey {name='rep5', x=365,y=50, w=60, code=_rep5, font=40, fText=CHAR.icon.speedFive}, -- 6
WIDGET.newKey {name='step', x=40, y=50, w=60, code=_step, font=40, fText=CHAR.icon.nextFrame}, -- 7
WIDGET.newSlider{name='autoSkip',x=40, y=130,w=100,code=_setAS, axis={0,2,1}, disp=function()return autoSkip end,show=_autoSkipDisp},
WIDGET.newKey {name='restart', x=0, y=25, w=60, code=_restart, font=40, fText=CHAR.icon.retry_spin}, -- 10
WIDGET.newKey {name='pause', x=0, y=25, w=60, code=pauseGame,font=40, fText=CHAR.icon.pause}, -- 11
}

return scene

0 comments on commit 120dc45

Please sign in to comment.