新增简易TAS工具,ctrl+T进入,f1暂停/开始,f2减速,f3加速/下一帧

This commit is contained in:
MrZ626
2021-08-16 22:45:55 +08:00
parent 42620bf739
commit d457fb0011
11 changed files with 163 additions and 96 deletions

View File

@@ -194,6 +194,9 @@ function scoreValid()--Check if any unranked mods are activated
return false return false
end end
end end
if GAME.tasUsed then
return false
end
return true return true
end end
function destroyPlayers()--Destroy all player objects, restore freerows and free CCs function destroyPlayers()--Destroy all player objects, restore freerows and free CCs
@@ -477,6 +480,7 @@ do--function resetGameData(args)
if not args then args=""end if not args then args=""end
trySave() trySave()
GAME.tasUsed=false
GAME.result=false GAME.result=false
GAME.rank=0 GAME.rank=0
GAME.warnLVL0=0 GAME.warnLVL0=0

View File

@@ -176,6 +176,7 @@ GAME={--Global game data
recording=false, --If recording recording=false, --If recording
replaying=false, --If replaying replaying=false, --If replaying
saved=false, --If recording saved saved=false, --If recording saved
tasUsed=false, --If tasMode used
prevBG=false, --Previous background, for restore BG when quit setting page prevBG=false, --Previous background, for restore BG when quit setting page

View File

@@ -897,6 +897,11 @@ return{
"english", "english",
"Short for \"Background music\".", "Short for \"Background music\".",
}, },
{"TAS",
"tas",
"english",
"Short for \"Tool-Assisted Speedrun(Supergaming)\"",--TODO
},
{"AFK", {"AFK",
"afk", "afk",
"english", "english",

View File

@@ -923,6 +923,11 @@ return{
"english", "english",
"Background Music\n背景音乐", "Background Music\n背景音乐",
}, },
{"TAS",
"tas",
"english",
"Tool-Assisted Speedrun(Supergaming)\n使用特殊工具在不破坏游戏规则(允许超越人类操作,只是在程序层面不作弊)进行的游戏\n一般用于冲击理论值或者达成各种有趣的目标用来观赏\n本游戏中内置了非常简单的TAS工具",
},
{"AFK", {"AFK",
"afk", "afk",
"english", "english",

View File

@@ -23,6 +23,7 @@ return{
mini="Mini",b2b="B2B ",b3b="B2B2B ", mini="Mini",b2b="B2B ",b3b="B2B2B ",
PC="Perfect Clear",HPC="Hemi-Perfect Clear", PC="Perfect Clear",HPC="Hemi-Perfect Clear",
replaying="[Replay]", replaying="[Replay]",
tasUsing="[TAS]",
stage="Stage $1", stage="Stage $1",
great="Great!", great="Great!",

View File

@@ -13,6 +13,7 @@ return{
mini="Mini",b2b="B2B ",b3b="B2B2B ", mini="Mini",b2b="B2B ",b3b="B2B2B ",
PC="Perfect Clear",HPC="Half Clear", PC="Perfect Clear",HPC="Half Clear",
replaying="[Repetición]", replaying="[Repetición]",
-- tasUsing="[TAS]",
stage="Nivel $1", stage="Nivel $1",
great="¡Genial!", great="¡Genial!",

View File

@@ -13,6 +13,7 @@ return{
mini="Mini",b2b="B2B ",b3b="B2B2B ", mini="Mini",b2b="B2B ",b3b="B2B2B ",
PC="Perfect Clear",HPC="Clear", PC="Perfect Clear",HPC="Clear",
replaying="[Replay]", replaying="[Replay]",
-- tasUsing="[TAS]",
stage="Etape $1", stage="Etape $1",
great="Bien !", great="Bien !",

View File

@@ -14,6 +14,7 @@ return{
mini="Mini",b2b="B2B ",b3b="B2B2B ", mini="Mini",b2b="B2B ",b3b="B2B2B ",
PC="Perfect Clear",HPC="Clear", PC="Perfect Clear",HPC="Clear",
replaying="[Replay]", replaying="[Replay]",
-- tasUsing="[TAS]",
stage="Fase $1", stage="Fase $1",
great="Ótimo!", great="Ótimo!",

View File

@@ -9,6 +9,7 @@ return{
mini="v",b2b="^ ",b3b="^^ ", mini="v",b2b="^ ",b3b="^^ ",
PC="#<>#",HPC="<>", PC="#<>#",HPC="<>",
replaying="[R]", replaying="[R]",
tasUsing="[TAS]",
stage="::$1::", stage="::$1::",
great="!~", great="!~",

View File

@@ -23,6 +23,7 @@ return{
mini="Mini",b2b="B2B ",b3b="B2B2B ", mini="Mini",b2b="B2B ",b3b="B2B2B ",
PC="Perfect Clear",HPC="Half Clear", PC="Perfect Clear",HPC="Half Clear",
replaying="[回放]", replaying="[回放]",
tasUsing="[TAS]",
stage="关卡 $1", stage="关卡 $1",
great="Great!", great="Great!",

View File

@@ -1,73 +1,127 @@
local gc,tc=love.graphics,love.touch local gc,kb,tc=love.graphics,love.keyboard,love.touch
local sin=math.sin local sin=math.sin
local SCR,VK=SCR,VK local SCR,VK=SCR,VK
local GAME=GAME local GAME=GAME
local noTouch,noKey=false,false local noTouch,noKey=false,false
local touchMoveLastFrame=false local touchMoveLastFrame=false
local floatRepRate,replayRate local floatGameRate,gameRate
local modeTextPos local modeTextPos
local tasMode
local replaying local replaying
local repRateStrings={[0]="pause",[.125]="0.125x",[.5]="0.5x",[1]="1x",[2]="2x",[5]="5x"} local repRateStrings={[0]="pause",[.125]="0.125x",[.5]="0.5x",[1]="1x",[2]="2x",[5]="5x"}
local scene={} local scene={}
local function updateMenuButtons()
WIDGET.active.restart.hide=replaying
local pos=(tasMode or replaying)and'right'or SETTING.menuPos
if GAME.replaying or pos=='right'then
WIDGET.active.restart.x=1125
WIDGET.active.pause.x=1195
modeTextPos=1100-drawableText.modeName:getWidth()
elseif pos=='middle'then
WIDGET.active.restart.x=360
WIDGET.active.pause.x=860
modeTextPos=940
elseif pos=='left'then
WIDGET.active.restart.x=120
WIDGET.active.pause.x=190
modeTextPos=1200-drawableText.modeName:getWidth()
end
end
local function updateRepButtons() local function updateRepButtons()
local L=scene.widgetList local L=scene.widgetList
if replaying then if replaying or tasMode then
for i=1,6 do L[i].hide=false end L[7].hide=true for i=1,6 do L[i].hide=false end L[7].hide=true
if replayRate==0 then if gameRate==0 then
L[1].hide=true L[1].hide=true
L[7].hide=false L[7].hide=false
elseif replayRate==.125 then elseif gameRate==.125 then
L[2].hide=true L[2].hide=true
elseif replayRate==.5 then elseif gameRate==.5 then
L[3].hide=true L[3].hide=true
elseif replayRate==1 then elseif gameRate==1 then
L[4].hide=true L[4].hide=true
elseif replayRate==2 then elseif gameRate==2 then
L[5].hide=true L[5].hide=true
elseif replayRate==5 then elseif gameRate==5 then
L[6].hide=true L[6].hide=true
end end
else else
for i=1,7 do L[i].hide=true end for i=1,7 do L[i].hide=true end
end end
end end
local function speedUp()
if gameRate==.125 then gameRate=.5
elseif gameRate==.5 then gameRate=1
elseif gameRate==1 then gameRate=2
elseif gameRate==2 then gameRate=5
end
updateRepButtons()
end
local function speedDown()
if gameRate==.5 then gameRate=.125
elseif gameRate==1 then gameRate=.5
elseif gameRate==2 then gameRate=1
elseif gameRate==5 then gameRate=2
end
updateRepButtons()
end
local function _rep0() local function _rep0()
scene.widgetList[1].hide=true scene.widgetList[1].hide=true
scene.widgetList[7].hide=false scene.widgetList[7].hide=false
replayRate=0 gameRate=0
updateRepButtons() updateRepButtons()
end end
local function _repP8() local function _repP8()
scene.widgetList[2].hide=true scene.widgetList[2].hide=true
replayRate=.125 gameRate=.125
updateRepButtons() updateRepButtons()
end end
local function _repP2() local function _repP2()
scene.widgetList[3].hide=true scene.widgetList[3].hide=true
replayRate=.5 gameRate=.5
updateRepButtons() updateRepButtons()
end end
local function _rep1() local function _rep1()
scene.widgetList[4].hide=true scene.widgetList[4].hide=true
replayRate=1 gameRate=1
updateRepButtons() updateRepButtons()
end end
local function _rep2() local function _rep2()
scene.widgetList[5].hide=true scene.widgetList[5].hide=true
replayRate=2 gameRate=2
updateRepButtons() updateRepButtons()
end end
local function _rep5() local function _rep5()
scene.widgetList[6].hide=true scene.widgetList[6].hide=true
replayRate=5 gameRate=5
updateRepButtons() updateRepButtons()
end end
local function _step()floatRepRate=floatRepRate+1 end local function _step()floatGameRate=floatGameRate+1 end
local function restart()
resetGameData(PLAYERS[1].frameRun<240 and'q')
noKey=replaying
noTouch=replaying
end
local function gameKeyDown(key)
local k=keyMap.keyboard[key]
if k then
if k>0 then
if noKey then return end
PLAYERS[1]:pressKey(k)
VK.press(k)
elseif not GAME.fromRepMenu then
restart()
end
elseif key=="escape"then
pauseGame()
end
end
function scene.sceneInit(org) function scene.sceneInit(org)
if GAME.init then if GAME.init then
@@ -75,39 +129,25 @@ function scene.sceneInit(org)
GAME.init=false GAME.init=false
end end
tasMode=GAME.tasUsed
replaying=GAME.replaying replaying=GAME.replaying
noKey=replaying noKey=replaying
noTouch=not SETTING.VKSwitch or replaying noTouch=not SETTING.VKSwitch or replaying
if org~='depause'and org~='pause'then
floatRepRate,replayRate=0,1 if tasMode then
floatGameRate,gameRate=0,0
elseif org~='depause'and org~='pause'then
floatGameRate,gameRate=0,1
end end
updateRepButtons() updateRepButtons()
WIDGET.active.restart.hide=replaying updateMenuButtons()
if GAME.replaying or SETTING.menuPos=='right'then
WIDGET.active.restart.x=1125
WIDGET.active.pause.x=1195
modeTextPos=1100-drawableText.modeName:getWidth()
elseif SETTING.menuPos=='middle'then
WIDGET.active.restart.x=360
WIDGET.active.pause.x=860
modeTextPos=940
elseif SETTING.menuPos=='left'then
WIDGET.active.restart.x=120
WIDGET.active.pause.x=190
modeTextPos=1200-drawableText.modeName:getWidth()
end
end end
function scene.sceneBack() function scene.sceneBack()
destroyPlayers() destroyPlayers()
end end
scene.mouseDown=NULL scene.mouseDown=NULL
local function restart()
resetGameData(PLAYERS[1].frameRun<240 and'q')
noKey=replaying
noTouch=replaying
end
function scene.touchDown(x,y) function scene.touchDown(x,y)
if noTouch then return end if noTouch then return end
@@ -150,46 +190,56 @@ function scene.touchMove()
end end
end end
function scene.keyDown(key,isRep) function scene.keyDown(key,isRep)
if not replaying then if replaying then
if isRep then return end if key=="space"then
local k=keyMap.keyboard[key] if not isRep then gameRate=gameRate==0 and 1 or 0 end
if k then updateRepButtons()
if k>0 then elseif key=="left"then
if noKey then return end if not isRep then
PLAYERS[1]:pressKey(k) speedDown()
VK.press(k) end
elseif not GAME.fromRepMenu then elseif key=="right"then
restart() if gameRate==0 then
_step()
elseif not isRep then
speedUp()
end end
elseif key=="escape"then elseif key=="escape"then
pauseGame() pauseGame()
end end
else else
if key=="space"then if isRep then
if not isRep then replayRate=replayRate==0 and 1 or 0 end return
updateRepButtons() elseif tasMode then
elseif key=="right"then if key=="f1"then
if replayRate==0 then if not isRep then gameRate=gameRate==0 and .125 or 0 end
_step()
elseif not isRep then
if replayRate==.125 then replayRate=.5
elseif replayRate==.5 then replayRate=1
elseif replayRate==1 then replayRate=2
elseif replayRate==2 then replayRate=5
end
updateRepButtons() updateRepButtons()
end elseif key=='f2'then
elseif key=="left"then if not isRep then
if replayRate~=0 and not isRep then speedDown()
if replayRate==.5 then replayRate=.125
elseif replayRate==1 then replayRate=.5
elseif replayRate==2 then replayRate=1
elseif replayRate==5 then replayRate=2
end end
elseif key=='f3'then
if gameRate==0 then
_step()
elseif not isRep then
speedUp()
end
elseif key=="t"and kb.isDown('lctrl','rctrl')then
tasMode=false
floatGameRate,gameRate=0,1
updateRepButtons() updateRepButtons()
updateMenuButtons()
end
else
if key=="t"and kb.isDown('lctrl','rctrl')then
gameRate=0
tasMode=true
GAME.tasUsed=true
updateRepButtons()
updateMenuButtons()
else
gameKeyDown(key)
end end
elseif key=="escape"then
pauseGame()
end end
end end
end end
@@ -228,6 +278,23 @@ function scene.gamepadUp(key)
end end
end end
local function update_replay(repPtr)
local P1=PLAYERS[1]
local L=GAME.rep
while P1.frameRun==L[repPtr]do
local key=L[repPtr+1]
if key==0 then--Just wait
elseif key<=32 then--Press key
P1:pressKey(key)
VK.press(key)
elseif key<=64 then--Release key
P1:releaseKey(key-32)
VK.release(key-32)
end
repPtr=repPtr+2
end
GAME.replaying=repPtr
end
local function update_common(dt) local function update_common(dt)
--Update control --Update control
touchMoveLastFrame=false touchMoveLastFrame=false
@@ -245,31 +312,10 @@ local function update_common(dt)
checkWarning() checkWarning()
end end
function scene.update(dt) function scene.update(dt)
local repPtr=GAME.replaying floatGameRate=floatGameRate+gameRate
if repPtr then while floatGameRate>=1 do
floatRepRate=floatRepRate+replayRate floatGameRate=floatGameRate-1
while floatRepRate>=1 do if GAME.replaying then update_replay(GAME.replaying)end
floatRepRate=floatRepRate-1
if repPtr then
local P1=PLAYERS[1]
local L=GAME.rep
while P1.frameRun==L[repPtr]do
local key=L[repPtr+1]
if key==0 then--Just wait
elseif key<=32 then--Press key
P1:pressKey(key)
VK.press(key)
elseif key<=64 then--Release key
P1:releaseKey(key-32)
VK.release(key-32)
end
repPtr=repPtr+2
end
GAME.replaying=repPtr
end
update_common(dt)
end
else
update_common(dt) update_common(dt)
end end
end end
@@ -320,12 +366,12 @@ function scene.draw()
gc.draw(drawableText.modeName,modeTextPos,10) gc.draw(drawableText.modeName,modeTextPos,10)
--Replaying --Replaying
if replaying then if replaying or tasMode then
setFont(20) setFont(20)
gc.setColor(1,1,TIME()%.8>.4 and 1 or 0) gc.setColor(1,1,TIME()%.8>.4 and 1 or 0)
mStr(text.replaying,770,6) mStr(text[replaying and'replaying'or'tasUsing'],770,6)
gc.setColor(1,1,1,.8) gc.setColor(1,1,1,.8)
mStr(("%s %sf"):format(repRateStrings[replayRate],PLAYERS[1].frameRun),770,31) mStr(("%s %sf"):format(repRateStrings[gameRate],PLAYERS[1].frameRun),770,31)
end end
--Warning --Warning