394 lines
13 KiB
Lua
394 lines
13 KiB
Lua
local GAME,SCR=GAME,SCR
|
|
local sin,log,abs=math.sin,math.log10,math.abs
|
|
local GC=GC
|
|
|
|
local scene={}
|
|
|
|
local modUsed
|
|
local page
|
|
local timer1,timer2-- Animation timer
|
|
local form-- Form of clear & spins
|
|
local radar-- Radar chart
|
|
local radarOrgTouchPos-- For storing the first touch position in radar area
|
|
local val-- Radar chart normalizer
|
|
local standard-- Standard hexagon
|
|
local chartColor-- Color of radar chart
|
|
local rank-- Current rank
|
|
local trophy-- Current trophy
|
|
local trophyColor-- Current trophy color
|
|
|
|
function scene.enter()
|
|
modUsed=usingMod()
|
|
page=0
|
|
if type(SCN.prev)=='string' and SCN.prev:find("setting") then
|
|
TEXT.show(text.needRestart,640,410,50,'fly',.6)
|
|
end
|
|
local P1=PLAYERS[1]
|
|
local S=P1.stat
|
|
|
|
timer1=(SCN.prev=='game' or SCN.prev=='depause') and 0 or 1
|
|
timer2=timer1
|
|
|
|
local frameLostRate=(S.frame/S.time/60-1)*100
|
|
form={
|
|
{COLOR.Z,STRING.time(S.time),frameLostRate>10 and COLOR.R or frameLostRate>3 and COLOR.Y or COLOR.H,(" (%.2f%%)"):format(frameLostRate)},
|
|
("%d/%d/%d"):format(S.key,S.rotate,S.hold),
|
|
("%d %.2fPPS"):format(S.piece,S.piece/S.time),
|
|
("%d(%d) %.2fLPM"):format(S.row,S.dig,S.row/S.time*60),
|
|
("%d(%d) %.2fAPM"):format(S.atk,S.digatk,S.atk/S.time*60),
|
|
("%d(%d-%d)"):format(S.pend,S.recv,S.recv-S.pend),
|
|
("[1] %-7d[2] %-7d[3] %-7d[4] %-7d"):format(S.clears[1],S.clears[2],S.clears[3],S.clears[4]),
|
|
(CHAR.icon.num0InSpin.." %-8d"..CHAR.icon.num1InSpin.." %-8d"..CHAR.icon.num2InSpin.." %-8d"..CHAR.icon.num3InSpin.." %-8d"):format(S.spins[1],S.spins[2],S.spins[3],S.spins[4]),
|
|
("%d/%d ; %d/%d"):format(S.b2b,S.b3b,S.pc,S.hpc),
|
|
("%d/%dx/%.2f%%"):format(S.extraPiece,S.maxFinesseCombo,S.finesseRate*20/S.piece),
|
|
}
|
|
-- From right-down, 60 degree each
|
|
radar={
|
|
(S.off+S.dig)/S.time*60,-- DefPM
|
|
(S.atk+S.dig)/S.time*60,-- ADPM
|
|
S.atk/S.time*60, -- AtkPM
|
|
S.send/S.time*60, -- SendPM
|
|
S.piece/S.time*24, -- Line'PM
|
|
S.dig/S.time*60, -- DigPM
|
|
}
|
|
val={1/80,1/160,1/120,1/80,1/100,1/40}
|
|
|
|
-- Normalize Values
|
|
for i=1,6 do
|
|
val[i]=val[i]*radar[i] if val[i]>1.26 then val[i]=1.26+log(val[i]-.26) end
|
|
end
|
|
|
|
for i=1,6 do
|
|
radar[i]=("%.2f%s"):format(radar[i],text.radarData[i])
|
|
end
|
|
local f=1
|
|
for i=1,6 do
|
|
if val[i]>.5 then
|
|
f=2
|
|
end
|
|
if val[i]>1 then
|
|
f=3
|
|
break
|
|
end
|
|
end
|
|
if f==1 then chartColor,f={.4,.9,.5},1.25-- Vegetable
|
|
elseif f==2 then chartColor,f={.4,.7,.9},1 -- Normal
|
|
elseif f==3 then chartColor,f={1,.3,.3},.626 -- Diao
|
|
end
|
|
standard={
|
|
120*.5*f, 120*3^.5*.5*f,
|
|
120*-.5*f,120*3^.5*.5*f,
|
|
120*-1*f, 120*0*f,
|
|
120*-.5*f,120*-3^.5*.5*f,
|
|
120*.5*f, 120*-3^.5*.5*f,
|
|
120*1*f, 120*0*f,
|
|
}
|
|
|
|
for i=6,1,-1 do
|
|
val[2*i-1],val[2*i]=val[i]*standard[2*i-1],val[i]*standard[2*i]
|
|
end
|
|
|
|
if (P1.result=='win' or P1.result=='torikan') and P1.stat.piece>4 then
|
|
local acc=P1.stat.finesseRate*.2/P1.stat.piece
|
|
rank=CHAR.icon['rank'..(
|
|
acc==1. and "Z" or
|
|
acc>.97 and "S" or
|
|
acc>.94 and "A" or
|
|
acc>.87 and "B" or
|
|
acc>.70 and "C" or
|
|
acc>.50 and "D" or
|
|
acc>.30 and "E" or
|
|
"F"
|
|
)]
|
|
if acc==1 then
|
|
trophy=text.finesse_ap
|
|
trophyColor=COLOR.Y
|
|
elseif P1.stat.maxFinesseCombo==P1.stat.piece then
|
|
trophy=text.finesse_fc
|
|
trophyColor=COLOR.lC
|
|
else
|
|
trophy=nil
|
|
end
|
|
else
|
|
rank,trophy=nil
|
|
end
|
|
if GAME.prevBG then
|
|
BG.set(GAME.prevBG)
|
|
GAME.prevBG=false
|
|
end
|
|
end
|
|
function scene.leave()
|
|
trySave()
|
|
end
|
|
|
|
function scene.keyDown(key,isRep)
|
|
if isRep then return true end
|
|
if key=='q' then
|
|
GAME.playing=false
|
|
SCN.back()
|
|
elseif key=='escape' then
|
|
SCN.swapTo(GAME.result and 'game' or 'depause','none')
|
|
elseif key=='s' then
|
|
if not GAME.fromRepMenu then
|
|
GAME.prevBG=BG.cur
|
|
SCN.go('setting_sound')
|
|
end
|
|
elseif key=='r' then
|
|
if not GAME.fromRepMenu then
|
|
resetGameData()
|
|
SCN.swapTo('game','none')
|
|
end
|
|
elseif key=='p' then
|
|
if (GAME.result or GAME.replaying) and GAME.initPlayerCount==1 then
|
|
resetGameData('r')
|
|
PLAYERS[1]:startStreaming(GAME.rep)
|
|
SCN.swapTo('game','none')
|
|
end
|
|
elseif key=='o' then
|
|
if (GAME.result or GAME.replaying) and GAME.initPlayerCount==1 and not GAME.saved then
|
|
if DATA.saveReplay() then
|
|
GAME.saved=true
|
|
SFX.play('connected')
|
|
end
|
|
end
|
|
elseif key=='tab' or key=='Stab' then
|
|
if love.keyboard.isDown('lshift','rshift') or key=='Stab' then
|
|
page=(page-1)%2
|
|
else
|
|
page=(page+1)%2
|
|
end
|
|
timer2=0
|
|
elseif key=='t' then
|
|
if SETTING.allowTAS and not (GAME.result or GAME.replaying) then
|
|
GAME.tasUsed=true
|
|
SFX.play('ren_mega')
|
|
SFX.play('clear_3')
|
|
SYSFX.newShade(1.2,555,200,620,380,.6,.6,.6)
|
|
end
|
|
elseif KEY_MAP.keyboard[key]==0 then -- custom restart key
|
|
scene.keyDown('r')
|
|
else
|
|
return true
|
|
end
|
|
end
|
|
|
|
function scene.touchDown(x,y)
|
|
if 535<x and x<1195 and 200<y and y<580 then
|
|
radarOrgTouchPos={x,y}
|
|
end
|
|
end
|
|
function scene.touchUp(x1,y1)
|
|
if not (535<x1 and x1<1195 and 200<y1 and y1<580)
|
|
or not radarOrgTouchPos then return end
|
|
local x,y=radarOrgTouchPos[1],radarOrgTouchPos[2]
|
|
|
|
if abs(x1-x)<50 then return end -- The angle is too large/the movement is too short
|
|
scene.keyDown(x1-x>=50 and 'tab' or 'Stab')
|
|
radarOrgTouchPos=nil
|
|
end
|
|
scene.mouseUp=scene.touchUp
|
|
scene.mouseDown=scene.touchDown
|
|
|
|
function scene.gamepadDown(key)
|
|
if key=='back' then
|
|
scene.keyDown('escape')
|
|
elseif KEY_MAP.joystick[key]==0 then
|
|
scene.keyDown('r')
|
|
end
|
|
end
|
|
|
|
function scene.update(dt)
|
|
if not (GAME.result or GAME.replaying) then
|
|
GAME.pauseTime=GAME.pauseTime+dt
|
|
end
|
|
timer1=math.min(timer1+dt*60*.02,1)
|
|
timer2=math.min(timer2+dt*60*.04,1)
|
|
end
|
|
|
|
local hexList={1,0,.5,1.732*.5,-.5,1.732*.5}
|
|
for i=1,6 do hexList[i]=hexList[i]*150 end
|
|
local textPos={90,131,-90,131,-200,-25,-90,-181,90,-181,200,-25}
|
|
local dataPos={90,143,-90,143,-200,-13,-90,-169,90,-169,200,-13}
|
|
local tasText=GC.newText(getFont(100),"TAS")
|
|
function scene.draw()
|
|
if timer1<1 or GAME.result then
|
|
SCN.scenes.game.draw()
|
|
end
|
|
|
|
-- Dark BG
|
|
local _=timer1
|
|
if GAME.result then _=_*.76 end
|
|
GC.setColor(.12,.12,.12,_)
|
|
GC.replaceTransform(SCR.origin)
|
|
GC.rectangle('fill',0,0,SCR.w,SCR.h)
|
|
GC.replaceTransform(SCR.xOy)
|
|
|
|
GC.setColor(.97,.97,.97,timer1)
|
|
|
|
-- Result Text
|
|
mDraw(GAME.result and TEXTOBJ[GAME.result] or TEXTOBJ.pause,640,70-10*(5-timer1*5)^1.5)
|
|
|
|
-- Mode Info (outside)
|
|
GC.draw(TEXTOBJ.modeName,745-TEXTOBJ.modeName:getWidth(),143)
|
|
|
|
-- Level rank
|
|
if RANK_CHARS[GAME.rank] then
|
|
GC.push('transform')
|
|
GC.translate(1050,5)
|
|
FONT.set(80)
|
|
GC.setColor(0,0,0,timer1*.7)
|
|
GC.print(RANK_CHARS[GAME.rank],-5,-4,nil,1.5)
|
|
local L=RANK_COLORS[GAME.rank]
|
|
GC.setColor(L[1],L[2],L[3],timer1)
|
|
GC.print(RANK_CHARS[GAME.rank],0,0,nil,1.5)
|
|
GC.pop()
|
|
end
|
|
|
|
if GAME.tasUsed then
|
|
GC.setColor(.97,.97,.97,timer1*.08)
|
|
mDraw(tasText,870,395,.3,2.6)
|
|
end
|
|
|
|
-- Big info frame
|
|
if PLAYERS[1].frameRun>=180 then
|
|
GC.push('transform')
|
|
GC.translate(560,205)
|
|
GC.setLineWidth(2)
|
|
|
|
-- Pause Info (outside)
|
|
FONT.set(25)
|
|
if GAME.pauseCount>0 then
|
|
GC.setColor(.97,.97,.97,timer1*.06)
|
|
GC.rectangle('fill',-5,390,620,36,8)
|
|
GC.setColor(.97,.97,.97,timer1)
|
|
GC.rectangle('line',-5,390,620,36,8)
|
|
GC.mStr(("%s:[%d] %.2fs"):format(text.pauseCount,GAME.pauseCount,GAME.pauseTime),305,389)
|
|
end
|
|
|
|
-- Pages
|
|
if page==0 then
|
|
-- Frame
|
|
GC.setColor(.97,.97,.97,timer2*.06)
|
|
GC.rectangle('fill',-5,-5,620,380,8)
|
|
GC.setColor(.97,.97,.97,timer2)
|
|
GC.rectangle('line',-5,-5,620,380,8)
|
|
|
|
-- Game statistics
|
|
GC.push('transform')
|
|
GC.scale(.85)
|
|
GC.setLineWidth(2)
|
|
|
|
-- Stats
|
|
_=form
|
|
FONT.set(30)
|
|
GC.setColor(.97,.97,.97,timer2)
|
|
for i=1,10 do
|
|
GC.print(text.pauseStat[i],5,43*(i-1)+2)
|
|
GC.printf(_[i],210,43*(i-1)+2,500,'right')
|
|
end
|
|
|
|
-- Finesse rank & trophy
|
|
if rank then
|
|
FONT.set(40)
|
|
GC.setColor(.7,.7,.7,timer2)
|
|
GC.print(rank,405,383)
|
|
if trophy then
|
|
FONT.set(30)
|
|
GC.setColor(trophyColor[1],trophyColor[2],trophyColor[3],timer2*2-1)
|
|
GC.printf(trophy,95-120*(1-timer2^.5),390,300,'right')
|
|
end
|
|
end
|
|
GC.pop()
|
|
elseif page==1 then
|
|
-- Radar Chart
|
|
GC.setLineWidth(1)
|
|
GC.push('transform')
|
|
GC.translate(310,185)
|
|
|
|
-- Polygon
|
|
GC.push('transform')
|
|
GC.scale((3-2*timer2)*timer2)
|
|
GC.setColor(.97,.97,.97,timer2*(.5+.3*sin(TIME()*6.26)))
|
|
GC.regRoundPolygon('line',0,0,120,6,8)
|
|
GC.setColor(chartColor[1],chartColor[2],chartColor[3],timer2*.626)
|
|
for i=1,9,2 do
|
|
GC.polygon('fill',0,0,val[i],val[i+1],val[i+2],val[i+3])
|
|
end
|
|
GC.polygon('fill',0,0,val[11],val[12],val[1],val[2])
|
|
GC.setColor(.97,.97,.97,timer2)
|
|
for i=1,9,2 do
|
|
GC.line(val[i],val[i+1],val[i+2],val[i+3])
|
|
end
|
|
GC.line(val[11],val[12],val[1],val[2])
|
|
GC.pop()
|
|
|
|
-- Texts
|
|
local C
|
|
_=TIME()%MATH.tau
|
|
if _>3.142 then
|
|
GC.setColor(.97,.97,.97,-timer2*sin(_))
|
|
FONT.set(35)
|
|
C,_=text.radar,textPos
|
|
else
|
|
GC.setColor(.97,.97,.97,timer2*sin(_))
|
|
FONT.set(20)
|
|
C,_=radar,dataPos
|
|
end
|
|
for i=1,6 do
|
|
GC.mStr(C[i],_[2*i-1],_[2*i])
|
|
end
|
|
GC.pop()
|
|
end
|
|
GC.pop()
|
|
end
|
|
|
|
-- Mods
|
|
GC.push('transform')
|
|
GC.translate(131,600)
|
|
GC.scale(.65)
|
|
if modUsed then
|
|
GC.setLineWidth(2)
|
|
if scoreValid() then
|
|
GC.setColor(.7,.7,.7,timer1)
|
|
GC.rectangle('line',-5,-5,500,150,8)
|
|
GC.setColor(.7,.7,.7,timer1*.05)
|
|
GC.rectangle('fill',-5,-5,500,150,8)
|
|
else
|
|
GC.setColor(.8,0,0,timer1)
|
|
GC.rectangle('line',-5,-5,500,150,8)
|
|
GC.setColor(1,0,0,timer1*.05)
|
|
GC.rectangle('fill',-5,-5,500,150,8)
|
|
end
|
|
FONT.set(35)
|
|
for number,M in next,MODOPT do
|
|
if GAME.mod[number]>0 then
|
|
_=M.color
|
|
GC.setColor(_[1],_[2],_[3],timer1)
|
|
GC.mStr(M.id,35+M.no%8*60,math.floor(M.no/8)*45)
|
|
end
|
|
end
|
|
end
|
|
GC.pop()
|
|
end
|
|
|
|
scene.widgetList={
|
|
WIDGET.newKey{name='resume', x=290,y=240,w=300,h=70,code=pressKey'escape'},
|
|
WIDGET.newKey{name='restart', x=290,y=340,w=300,h=70,code=pressKey'r',hideF=function() return GAME.fromRepMenu end},
|
|
WIDGET.newKey{name='setting', x=290,y=440,w=300,h=70,code=pressKey's',hideF=function() return GAME.fromRepMenu end},
|
|
WIDGET.newKey{name='quit', x=290,y=540,w=300,h=70,code=pressKey'q'},
|
|
WIDGET.newKey{name='tas', x=290,y=620,w=240,h=50,code=pressKey't',hideF=function() return not SETTING.allowTAS or GAME.tasUsed or GAME.result or GAME.replaying end},
|
|
WIDGET.newKey{name='page_prev',x=500,y=390,w=70,code=pressKey'tab',
|
|
fText=GC.DO{70,70,{'setLW',2}, {'dRRPol',33,35,32,3,6,3.142},{'dRRPol',45,35,32,3,6,3.142}},
|
|
fShade=GC.DO{70,70,{'setCL',1,1,1,.4},{'draw',GC.DO{70,70,{'setCL',1,1,1,1},{'fRRPol',33,35,32,3,6,3.142},{'fRRPol',45,35,32,3,6,3.142}}}},
|
|
hideF=function() return PLAYERS[1].frameRun<=180 end,
|
|
},
|
|
WIDGET.newKey{name='page_next',x=1230,y=390,w=70,code=pressKey'Stab',
|
|
fText=GC.DO{70,70,{'setLW',2}, {'dRRPol',37,35,32,3,6},{'dRRPol',25,35,32,3,6}},
|
|
fShade=GC.DO{70,70,{'setCL',1,1,1,.4},{'draw',GC.DO{70,70,{'setCL',1,1,1,1},{'fRRPol',37,35,32,3,6},{'fRRPol',25,35,32,3,6}}}},
|
|
hideF=function() return PLAYERS[1].frameRun<=180 end,
|
|
},
|
|
WIDGET.newKey{name='replay', x=865,y=165,w=200,h=40,font=25,code=pressKey'p',hideF=function() return not (GAME.result or GAME.replaying) or GAME.initPlayerCount>1 end},
|
|
WIDGET.newKey{name='save', x=1075,y=165,w=200,h=40,font=25,code=pressKey'o',hideF=function() return not (GAME.result or GAME.replaying) or GAME.initPlayerCount>1 or GAME.saved end},
|
|
}
|
|
|
|
return scene |