新增简易TAS工具,ctrl+T进入,f1暂停/开始,f2减速,f3加速/下一帧
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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!",
|
||||||
|
|||||||
@@ -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!",
|
||||||
|
|||||||
@@ -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 !",
|
||||||
|
|||||||
@@ -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!",
|
||||||
|
|||||||
@@ -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="!~",
|
||||||
|
|||||||
@@ -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!",
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user