From 558384727c537329c1d684ac8ee334d93f5522d8 Mon Sep 17 00:00:00 2001
From: MrZ626 <1046101471@qq.com>
Date: Wed, 11 Nov 2020 15:18:36 +0800
Subject: [PATCH] =?UTF-8?q?player=E6=A8=A1=E5=9D=97=E5=88=86=E6=96=87?=
=?UTF-8?q?=E4=BB=B6=EF=BC=8C=E9=A1=BA=E4=BE=BF=E6=8A=8A=E9=83=A8=E5=88=86?=
=?UTF-8?q?CC=E6=95=B0=E6=8D=AE=E5=88=86=E7=A6=BB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
parts/ai.lua | 34 +-
parts/player/draw.lua | 625 +++++++++++++
parts/player/gameEnv0.lua | 47 +
parts/{player.lua => player/init.lua} | 1173 +------------------------
parts/player/prepareSequence.lua | 132 +++
parts/player/update.lua | 338 +++++++
6 files changed, 1180 insertions(+), 1169 deletions(-)
create mode 100644 parts/player/draw.lua
create mode 100644 parts/player/gameEnv0.lua
rename parts/{player.lua => player/init.lua} (63%)
create mode 100644 parts/player/prepareSequence.lua
create mode 100644 parts/player/update.lua
diff --git a/parts/ai.lua b/parts/ai.lua
index 76bde561..1e268b3d 100644
--- a/parts/ai.lua
+++ b/parts/ai.lua
@@ -15,27 +15,27 @@ local Timer=love.timer.getTime
-- 11~13:LL,RR,DD
local blockPos={4,4,4,4,4,5,4}
-------------------------------------------------Cold clear
-CC=LOADLIB("CC")
-if CC then
+local _CC=LOADLIB("CC")
+if _CC then
local CCblockID={6,5,4,3,2,1,0}
CC={
- getConf= CC.get_default_config ,--()options,weights
- fastWeights=CC.fast_weights ,--(weights)
- --setConf= CC.set_options ,--(options,hold,20g,bag7)
+ getConf= _CC.get_default_config ,--()options,weights
+ fastWeights=_CC.fast_weights ,--(weights)
+ --setConf= _CC.set_options ,--(options,hold,20g,bag7)
- new= CC.launch_async ,--(options,weights)bot
- addNext= CC.add_next_piece_async ,--(bot,piece)
- update= CC.reset_async ,--(bot,field,b2b,combo)
- think= CC.request_next_move ,--(bot)
- getMove= CC.poll_next_move ,--(bot)success,dest,hold,move
- destroy= CC.destroy_async ,--(bot)
+ new= _CC.launch_async ,--(options,weights)bot
+ addNext= function(bot,id)_CC.add_next_piece_async(bot,CCblockID[id])end ,--(bot,piece)
+ update= _CC.reset_async ,--(bot,field,b2b,combo)
+ think= _CC.request_next_move ,--(bot)
+ getMove= _CC.poll_next_move ,--(bot)success,dest,hold,move
+ destroy= _CC.destroy_async ,--(bot)
- setHold= CC.set_hold ,--(opt,bool)
- set20G= CC.set_20g ,--(opt,bool)
- -- setPCLoop= CC.set_pcloop ,--(opt,bool)
- setBag= CC.set_bag7 ,--(opt,bool)
- setNode= CC.set_max_nodes ,--(opt,bool)
- free= CC.free ,--(opt/wei)
+ setHold= _CC.set_hold ,--(opt,bool)
+ set20G= _CC.set_20g ,--(opt,bool)
+ -- setPCLoop= _CC.set_pcloop ,--(opt,bool)
+ setBag= _CC.set_bag7 ,--(opt,bool)
+ setNode= _CC.set_max_nodes ,--(opt,bool)
+ free= _CC.free ,--(opt/wei)
}
function CC.updateField(P)
local F,i={},1
diff --git a/parts/player/draw.lua b/parts/player/draw.lua
new file mode 100644
index 00000000..8edd2fbb
--- /dev/null
+++ b/parts/player/draw.lua
@@ -0,0 +1,625 @@
+local gc=love.graphics
+local Timer=love.timer.getTime
+local int,ceil,rnd=math.floor,math.ceil,math.random
+local max,min,sin=math.max,math.min,math.sin
+local format=string.format
+local SCR=SCR
+local setFont=setFont
+
+local frameColorList={
+ [0]=COLOR.white,
+ COLOR.lGreen,
+ COLOR.lBlue,
+ COLOR.lPurple,
+ COLOR.lOrange,
+}
+--local function drawCell(y,x,id)gc.draw(SKIN.curText[id],30*x-30,-30*y)end
+local function drawGrid(P)
+ local FBN,FUP=P.fieldBeneath,P.fieldUp
+ gc.setLineWidth(1)
+ gc.setColor(1,1,1,.2)
+ for x=1,9 do
+ gc.line(30*x,-10,30*x,600)
+ end
+ for y=0,19 do
+ y=30*(y-int((FBN+FUP)/30))+FBN+FUP
+ gc.line(0,y,300,y)
+ end
+end
+local function drawField(P)
+ local V,F=P.visTime,P.field
+ local start=int((P.fieldBeneath+P.fieldUp)/30+1)
+ local rep=GAME.replaying
+ local texture=SKIN.curText
+ if P.falling==-1 then--Blocks only
+ for j=start,min(start+21,#F)do
+ for i=1,10 do
+ if F[j][i]>0 then
+ if V[j][i]>0 then
+ gc.setColor(1,1,1,min(V[j][i]*.05,1))
+ gc.draw(texture[F[j][i]],30*i-30,-30*j)-- drawCell(j,i,F[j][i])
+ elseif rep then
+ gc.setColor(1,1,1,.3+.08*sin(.5*(j-i)+Timer()*4))
+ gc.rectangle("fill",30*i-30,-30*j,30,30)
+ end
+ end
+ end
+ end
+ else--With falling animation
+ local ENV=P.gameEnv
+ local stepY=ENV.smooth and(P.falling/(ENV.fall+1))^2.5*30 or 30
+ local A=P.falling/ENV.fall
+ local h=1
+ gc.push("transform")
+ for j=start,min(start+21,#F)do
+ while j==P.clearingRow[h]do
+ h=h+1
+ gc.translate(0,-stepY)
+ gc.setColor(1,1,1,A)
+ gc.rectangle("fill",0,30-30*j,300,stepY)
+ end
+ for i=1,10 do
+ if F[j][i]>0 then
+ if V[j][i]>0 then
+ gc.setColor(1,1,1,min(V[j][i]*.05,1))
+ gc.draw(texture[F[j][i]],30*i-30,-30*j)-- drawCell(j,i,F[j][i])
+ elseif rep then
+ gc.setColor(1,1,1,.2)
+ gc.rectangle("fill",30*i-30,-30*j,30,30)
+ end
+ end
+ end
+ end
+ gc.pop()
+ end
+end
+local function drawFXs(P)
+ --LockFX
+ for i=1,#P.lockFX do
+ local S=P.lockFX[i]
+ if S[3]<.5 then
+ gc.setColor(1,1,1,2*S[3])
+ gc.rectangle("fill",S[1],S[2],60*S[3],30)
+ else
+ gc.setColor(1,1,1,2-2*S[3])
+ gc.rectangle("fill",S[1]+30,S[2],60*S[3]-60,30)
+ end
+ end
+
+ --DropFX
+ for i=1,#P.dropFX do
+ local S=P.dropFX[i]
+ gc.setColor(1,1,1,.6-S[5]*.6)
+ local w=30*S[3]*(1-S[5]*.5)
+ gc.rectangle("fill",30*S[1]-30+15*S[3]-w*.5,-30*S[2],w,30*S[4])
+ end
+
+ --MoveFX
+ local texture=SKIN.curText
+ for i=1,#P.moveFX do
+ local S=P.moveFX[i]
+ gc.setColor(1,1,1,.6-S[4]*.6)
+ gc.draw(texture[S[1]],30*S[2]-30,-30*S[3])-- drawCell(S[3],S[2],S[1])
+ end
+
+ --ClearFX
+ for i=1,#P.clearFX do
+ local S=P.clearFX[i]
+ local t=S[2]
+ local x=t<.3 and 1-(3.3333*t-1)^2 or 1
+ local y=t<.2 and 5*t or 1-1.25*(t-.2)
+ gc.setColor(1,1,1,y)
+ gc.rectangle("fill",150-x*150,15-S[1]*30-y*15,300*x,y*30)
+ end
+end
+local function drawGhost(P,clr)
+ gc.setColor(1,1,1,P.gameEnv.ghost)
+ local texture=SKIN.curText
+ for i=1,P.r do for j=1,P.c do
+ if P.cur.bk[i][j]then
+ gc.draw(texture[clr],30*(j+P.curX-1)-30,-30*(i+P.imgY-1))-- drawCell(i+P.imgY-1,j+P.curX-1,clr)
+ end
+ end end
+end
+local function drawBlockOutline(P,texture,trans)
+ SHADER.alpha:send("a",trans)
+ gc.setShader(SHADER.alpha)
+ for i=1,P.r do for j=1,P.c do
+ if P.cur.bk[i][j]then
+ local x=30*(j+P.curX)-60-3
+ local y=30-30*(i+P.curY)-3
+ gc.draw(texture,x,y)
+ gc.draw(texture,x+6,y+6)
+ gc.draw(texture,x+6,y)
+ gc.draw(texture,x,y+6)
+ end
+ end end
+ gc.setShader()
+end
+local function drawBlock(P,clr)
+ gc.setColor(1,1,1)
+ local texture=SKIN.curText
+ for i=1,P.r do for j=1,P.c do
+ if P.cur.bk[i][j]then
+ gc.draw(texture[clr],30*(j+P.curX-1)-30,-30*(i+P.curY-1))-- drawCell(i+P.curY-1,j+P.curX-1,clr)
+ end
+ end end
+end
+local function drawNextPreview(P,B)
+ gc.setColor(1,1,1,.8)
+ local x=int(6-#B[1]*.5)
+ local y=21+ceil(P.fieldBeneath/30)
+ for i=1,#B do for j=1,#B[1]do
+ if B[i][j]then
+ gc.draw(puzzleMark[-1],30*(x+j-2),30*(1-y-i))
+ end
+ end end
+end
+local function drawHold(P,clr)
+ local B=P.hd.bk
+ local texture=SKIN.curText
+ for i=1,#B do for j=1,#B[1]do
+ if B[i][j]then
+ gc.draw(texture[clr],30*(j+2.06-#B[1]*.5)-30,-30*(i+1.36-#B*.5))-- drawCell(i+1.36-#B*.5,j+2.06-#B[1]*.5,clr)
+ end
+ end end
+end
+
+local draw={}
+
+function draw.drawTargetLine(P,r)
+ if r<21+(P.fieldBeneath+P.fieldUp)/30 and r>0 then
+ gc.setLineWidth(4)
+ gc.setColor(1,r>10 and 0 or rnd(),.5)
+ local dx,dy=150+P.fieldOff.x,70+P.fieldOff.y+P.fieldBeneath+P.fieldUp
+ gc.line(dx,600-30*r+dy,300+dx,600-30*r+dy)
+ end
+end
+
+local attackColor={
+ {COLOR.dGrey,COLOR.white},
+ {COLOR.grey,COLOR.white},
+ {COLOR.lPurple,COLOR.white},
+ {COLOR.lRed,COLOR.white},
+ {COLOR.dGreen,COLOR.cyan},
+}
+local RCPB={10,33,200,33,105,5,105,60}
+local function drawDial(x,y,speed)
+ gc.setColor(1,1,1)
+ mStr(int(speed),x,y-18)
+
+ gc.setLineWidth(4)
+ gc.setColor(1,1,1,.4)
+ gc.circle("line",x,y,30,10)
+
+ gc.setLineWidth(2)
+ gc.setColor(1,1,1,.6)
+ gc.circle("line",x,y,30,10)
+
+ gc.setColor(1,1,1,.8)
+ gc.draw(IMG.dialNeedle,x,y,2.094+(speed<=175 and .02094*speed or 4.712-52.36/(speed-125)),nil,nil,5,4)
+end
+function draw.norm(P)
+ local _
+ local ENV=P.gameEnv
+ local FBN,FUP=P.fieldBeneath,P.fieldUp
+ gc.push("transform")
+ gc.translate(P.x,P.y)gc.scale(P.size)
+
+ --Field-related things
+ gc.push("transform")
+ gc.translate(150,70)
+
+ --Things shake with field
+ gc.push("transform")
+ gc.translate(P.fieldOff.x,P.fieldOff.y)
+
+ --Fill field
+ gc.setColor(0,0,0,.6)
+ gc.rectangle("fill",0,-10,300,610)
+
+ --Draw grid
+ if ENV.grid then drawGrid(P)end
+
+ --In-field things
+ gc.push("transform")
+ gc.translate(0,600+FBN+FUP)
+ gc.setScissor(SCR.x+(P.absFieldX+P.fieldOff.x)*SCR.k,SCR.y+(P.absFieldY+P.fieldOff.y)*SCR.k,300*P.size*SCR.k,610*P.size*SCR.k)
+
+ --Draw dangerous area
+ gc.setColor(1,0,0,.3)
+ gc.rectangle("fill",0,-600,300,-610-FUP-FBN)
+
+ --Draw field
+ drawField(P)
+
+ --Draw spawn line
+ gc.setColor(1,sin(Timer())*.4+.5,0,.5)
+ gc.setLineWidth(4)
+ gc.line(0,-600-FBN,300,-600-FBN)
+
+ --Draw FXs
+ drawFXs(P)
+
+ --Draw current block
+ if P.cur and P.waiting==-1 then
+ local curColor=P.cur.color
+
+ --Draw ghost
+ if ENV.ghost then drawGhost(P,curColor)end
+
+ local dy=ENV.smooth and P.imgY~=P.curY and(P.dropDelay/ENV.drop-1)*30 or 0
+ gc.translate(0,-dy)
+ local trans=P.lockDelay/ENV.lock
+
+ --Draw block
+ if ENV.block then
+ drawBlockOutline(P,SKIN.curText[curColor],trans)
+ drawBlock(P,curColor)
+ end
+
+ --Draw rotate center
+ local x=30*(P.curX+P.sc[2])-15
+ if ENV.center and ENV.block then
+ gc.setColor(1,1,1,ENV.center)
+ gc.draw(IMG.spinCenter,x,-30*(P.curY+P.sc[1])+15,nil,nil,nil,4,4)
+ end
+ gc.translate(0,dy)
+ if ENV.center and ENV.ghost then
+ gc.setColor(1,1,1,trans*ENV.center)
+ gc.draw(IMG.spinCenter,x,-30*(P.imgY+P.sc[1])+15,nil,nil,nil,4,4)
+ end
+ end
+
+ --Draw next preview
+ if ENV.nextPos and P.next[1]then
+ drawNextPreview(P,P.next[1].bk)
+ end
+
+ gc.setScissor()
+ gc.pop()
+
+ gc.setLineWidth(2)
+ gc.setColor(frameColorList[P.frameColor])
+ gc.rectangle("line",-1,-11,302,612)--Boarder
+ gc.rectangle("line",301,-3,15,604)--AtkBuffer boarder
+ gc.rectangle("line",-16,-3,15,604)--B2b bar boarder
+
+ --Buffer line
+ local h=0
+ for i=1,#P.atkBuffer do
+ local A=P.atkBuffer[i]
+ local bar=A.amount*30
+ if h+bar>600 then bar=600-h end
+ if not A.sent then
+ --Appear
+ if A.time<20 then
+ bar=bar*(20*A.time)^.5*.05
+ end
+ if A.countdown>0 then
+ --Timing
+ gc.setColor(attackColor[A.lv][1])
+ gc.rectangle("fill",303,599-h,11,-bar)
+ gc.setColor(attackColor[A.lv][2])
+ gc.rectangle("fill",303,599-h-bar,11,bar*(1-A.countdown/A.cd0))
+ else
+ --Warning
+ local t=math.sin((Timer()-i)*30)*.5+.5
+ local c1,c2=attackColor[A.lv][1],attackColor[A.lv][2]
+ gc.setColor(c1[1]*t+c2[1]*(1-t),c1[2]*t+c2[2]*(1-t),c1[3]*t+c2[3]*(1-t))
+ gc.rectangle("fill",303,599-h,11,-bar)
+ end
+ else
+ gc.setColor(attackColor[A.lv][1])
+ bar=bar*(20-A.time)*.05
+ gc.rectangle("fill",303,599-h,11,-bar)
+ --Disappear
+ end
+ h=h+bar
+ end
+
+ --B2B indictator
+ local a,b=P.b2b,P.b2b1 if a>b then a,b=b,a end
+ gc.setColor(.8,1,.2)
+ gc.rectangle("fill",-14,599,11,-b*.5)
+ gc.setColor(P.b2b<40 and COLOR.white or P.b2b<=1e3 and COLOR.lRed or COLOR.lBlue)
+ gc.rectangle("fill",-14,599,11,-a*.5)
+ gc.setColor(1,1,1)
+ if Timer()%.5<.3 then
+ gc.rectangle("fill",-15,b<40 and 578.5 or 98.5,13,3)
+ end
+
+ --LockDelay indicator
+ if ENV.easyFresh then
+ gc.setColor(1,1,1)
+ else
+ gc.setColor(1,.26,.26)
+ end
+ if P.lockDelay>=0 then
+ gc.rectangle("fill",0,602,300*P.lockDelay/ENV.lock,6)--Lock delay indicator
+ end
+ local x=3
+ for _=1,min(ENV.freshLimit-P.freshTime,15)do
+ gc.rectangle("fill",x,615,14,5)
+ x=x+20
+ end
+
+ --Draw Hold
+ if ENV.hold then
+ gc.push("transform")
+ gc.translate(-140,116)
+ gc.setColor(0,0,0,.4)gc.rectangle("fill",0,-80,124,80)
+ gc.setColor(1,1,1)gc.rectangle("line",0,-80,124,80)
+ if P.holded then gc.setColor(.6,.4,.4)end
+ mText(drawableText.hold,62,-131)
+ if P.hd then drawHold(P,P.hd.color)end
+ gc.pop()
+ end
+
+ --Draw Next(s)
+ local N=ENV.next*72
+ if ENV.next>0 then
+ gc.setColor(0,0,0,.4)gc.rectangle("fill",316,36,124,N)
+ gc.setColor(1,1,1)gc.rectangle("line",316,36,124,N)
+ mText(drawableText.next,378,-15)
+ N=1
+ local texture=SKIN.curText
+ while N<=ENV.next and P.next[N]do
+ local bk,clr=P.next[N].bk,P.next[N].color
+ for i=1,#bk do for j=1,#bk[1] do
+ if bk[i][j]then
+ gc.draw(texture[clr],30*(j+12.6-#bk[1]*.5)-30,-30*(i-2.4*N-#bk*.5))-- drawCell(i-2.4*N-#bk*.5,j+12.6-#bk[1]*.5,clr)
+ end
+ end end
+ N=N+1
+ end
+ end
+
+ --Draw Bagline(s)
+ if ENV.bagLine then
+ local L=ENV.bagLen
+ local C=-P.pieceCount%L--Phase
+ gc.setColor(.8,.5,.5)
+ for i=C,N-1,L do
+ local y=72*i+36
+ gc.line(318+P.fieldOff.x,y,438,y)
+ end
+ end
+
+ --Draw target selecting pad
+ if modeEnv.royaleMode then
+ if P.atkMode then
+ gc.setColor(1,.8,0,P.swappingAtkMode*.02)
+ gc.rectangle("fill",RCPB[2*P.atkMode-1],RCPB[2*P.atkMode],90,35,8,4)
+ end
+ gc.setColor(1,1,1,P.swappingAtkMode*.025)
+ setFont(18)
+ for i=1,4 do
+ gc.rectangle("line",RCPB[2*i-1],RCPB[2*i],90,35,8,4)
+ mStr(text.atkModeName[i],RCPB[2*i-1]+45,RCPB[2*i]+3)
+ end
+ end
+ gc.pop()
+
+ --Bonus texts
+ TEXT.draw(P.bonus)
+
+ --Display Ys
+ -- gc.setLineWidth(6)
+ -- if P.curY then gc.setColor(1,.4,0,.42)gc.line(0,611-P.curY*30,300,611-P.curY*30)end
+ -- if P.imgY then gc.setColor(0,1,.4,.42)gc.line(0,615-P.imgY*30,300,615-P.imgY*30)end
+ -- if P.minY then gc.setColor(0,.4,1,.42)gc.line(0,619-P.minY*30,300,619-P.minY*30)end
+ -- gc.setColor(0,.4,1,.42)gc.line(0,600-P.garbageBeneath*30,300,600-P.garbageBeneath*30)
+ gc.pop()
+
+ --Speed dials
+ setFont(25)
+ drawDial(510,580,P.dropSpeed)
+ drawDial(555,635,P.keySpeed)
+ gc.setColor(1,1,1)
+ gc.draw(drawableText.bpm,540,550)
+ gc.draw(drawableText.kpm,494,643)
+
+ --Score & Time
+ setFont(25)
+ gc.setColor(0,0,0,.3)
+ gc.print(P.score1,18,579)
+ gc.print(format("%.2f",P.stat.time),18,609)
+
+ gc.setColor(COLOR.lYellow)gc.print(P.score1,20,580)
+ gc.setColor(COLOR.sky)gc.print(format("%.2f",P.stat.time),20,610)
+
+ --FinesseCombo
+ if P.finesseCombo>2 then
+ _=P.finesseComboTime
+ local T=P.finesseCombo.."x"
+ if _>0 then
+ gc.setColor(1,1,1,_*.2)
+ gc.print(T,20,640)
+ gc.setColor(1,1,1,1.2-_*.1)
+ gc.push("transform")
+ gc.translate(20,670)
+ gc.scale(1+_*.08)
+ gc.print(T,0,-30)
+ gc.pop()
+ else
+ gc.setColor(1,1,1)
+ gc.print(T,20,640)
+ end
+ end
+
+ --Lives
+ if P.life>0 then
+ gc.setColor(1,1,1)
+ if P.life<=3 then
+ for i=1,P.life do
+ gc.draw(IMG.lifeIcon,450+25*i,665,nil,.8)
+ end
+ else
+ gc.draw(IMG.lifeIcon,475,665,nil,.8)
+ setFont(20)
+ gc.print("x",503,665)
+ gc.print(P.life,517,665)
+ end
+ end
+
+ --Other messages
+ gc.setColor(1,1,1)
+ if CURMODE.mesDisp then
+ CURMODE.mesDisp(P)
+ end
+
+ --Missions
+ if P.curMission then
+ local missionEnum=missionEnum
+ local L=ENV.mission
+
+ --Draw current mission
+ setFont(35)
+ if ENV.missionKill then
+ gc.setColor(1,.7+.2*sin(Timer()*6.26),.4)
+ else
+ gc.setColor(1,1,1)
+ end
+ gc.print(missionEnum[L[P.curMission]],85,180)
+
+ --Draw next mission
+ setFont(17)
+ for i=1,3 do
+ local t=L[P.curMission+i]
+ if t then
+ t=missionEnum[t]
+ gc.print(t,87-26*i,187)
+ else
+ break
+ end
+ end
+ end
+
+ --Draw starting counter
+ gc.setColor(1,1,1)
+ if GAME.frame<180 then
+ local count=179-GAME.frame
+ gc.push("transform")
+ gc.translate(305,290)
+ setFont(95)
+ if count%60>45 then gc.scale(1+(count%60-45)^2*.01,1)end
+ mStr(int(count/60+1),0,0)
+ gc.pop()
+ end
+ gc.pop()
+end
+
+function draw.small(P)
+ --Draw content
+ P.frameWait=P.frameWait-1
+ if P.frameWait==0 then
+ P.frameWait=10
+ gc.setCanvas(P.canvas)
+ gc.clear(0,0,0,.4)
+ gc.push("transform")
+ gc.origin()
+ gc.setColor(1,1,1,P.result and max(20-P.endCounter,0)*.05 or 1)
+
+ --Field
+ local F=P.field
+ local texture=SKIN.curTextMini
+ for j=1,#F do
+ for i=1,10 do if F[j][i]>0 then
+ gc.draw(texture[F[j][i]],6*i-6,120-6*j)
+ end end
+ end
+
+ --Draw boarder
+ if P.alive then
+ gc.setLineWidth(2)
+ gc.setColor(frameColorList[P.frameColor])
+ gc.rectangle("line",0,0,60,120)
+ end
+
+ --Draw badge
+ if modeEnv.royaleMode then
+ gc.setColor(1,1,1)
+ for i=1,P.strength do
+ gc.draw(IMG.badgeIcon,12*i-7,4,nil,.5)
+ end
+ end
+
+ --Draw result
+ if P.result then
+ gc.setColor(1,1,1,min(P.endCounter,60)*.01)
+ setFont(17)mStr(P.result,32,47)
+ setFont(15)mStr(P.modeData.event,30,82)
+ end
+ gc.pop()
+ gc.setCanvas()
+ end
+
+ --Draw Canvas
+ gc.setColor(1,1,1)
+ gc.draw(P.canvas,P.x,P.y,nil,P.size*10)
+ if P.killMark then
+ gc.setLineWidth(3)
+ gc.setColor(1,0,0,min(P.endCounter,25)*.04)
+ gc.circle("line",P.centerX,P.centerY,(840-20*min(P.endCounter,30))*P.size)
+ end
+ setFont(30)
+end
+
+function draw.demo(P)
+ local _
+ local ENV=P.gameEnv
+ local curColor=P.cur.color
+
+ --Camera
+ gc.push("transform")
+ gc.translate(P.x,P.y)gc.scale(P.size)
+ gc.push("transform")
+ gc.translate(P.fieldOff.x,P.fieldOff.y)
+
+ --Frame
+ gc.setColor(0,0,0,.6)
+ gc.rectangle("fill",0,0,300,600)
+ gc.setLineWidth(2)
+ gc.setColor(1,1,1)
+ gc.rectangle("line",-1,-1,302,602)
+
+ gc.push("transform")
+ gc.translate(0,600)
+ drawField(P)
+ drawFXs(P)
+ if P.cur and P.waiting==-1 then
+ if ENV.ghost then drawGhost(P,curColor)end
+ if ENV.block then
+ drawBlockOutline(P,SKIN.curText[curColor],P.lockDelay/ENV.lock)
+ drawBlock(P,curColor)
+ end
+ end
+ gc.pop()
+
+ --Draw hold
+ local blockImg=TEXTURE.miniBlock
+ if P.hd then
+ local id=P.hd.id
+ _=P.color[id]
+ gc.setColor(_[1],_[2],_[3],.3)
+ _=blockImg[id]
+ gc.draw(_,15,30,nil,16,nil,0,_:getHeight()*.5)
+ end
+
+ --Draw next
+ local N=1
+ while N<=ENV.next and P.next[N]do
+ local id=P.next[N].id
+ _=P.color[id]
+ gc.setColor(_[1],_[2],_[3],.3)
+ _=blockImg[id]
+ gc.draw(_,285,40*N-10,nil,16,nil,_:getWidth(),_:getHeight()*.5)
+ N=N+1
+ end
+ gc.pop()
+ TEXT.draw(P.bonus)
+ gc.pop()
+end
+
+return draw
\ No newline at end of file
diff --git a/parts/player/gameEnv0.lua b/parts/player/gameEnv0.lua
new file mode 100644
index 00000000..a5a27eed
--- /dev/null
+++ b/parts/player/gameEnv0.lua
@@ -0,0 +1,47 @@
+return{
+ das=10,arr=2,sddas=2,sdarr=2,
+ ihs=true,irs=true,ims=true,
+ swap=true,
+
+ ghost=.3,center=1,
+ smooth=false,grid=false,
+ bagLine=false,
+ text=true,
+ score=true,
+ lockFX=2,
+ dropFX=2,
+ moveFX=2,
+ clearFX=2,
+ shakeFX=3,
+
+ highCam=false,
+ nextPos=false,
+
+ drop=60,lock=60,
+ wait=0,fall=0,
+ bone=false,
+ next=6,
+ hold=true,oncehold=true,
+ ospin=true,
+ sequence="bag",
+ freshMethod=NULL,
+ bag={1,2,3,4,5,6,7},
+ face=NULL,skin=NULL,
+ mission=NULL,
+
+ life=0,
+ pushSpeed=3,
+ block=true,
+ noTele=false,
+ visible="show",
+ freshLimit=1e99,easyFresh=true,
+
+ Fkey=NULL,
+ keyCancel={},
+ fine=false,fineKill=false,
+ missionKill=false,
+ target=1e99,dropPiece=NULL,
+ mindas=0,minarr=0,minsdarr=0,
+
+ bg="none",bgm="race"
+}
\ No newline at end of file
diff --git a/parts/player.lua b/parts/player/init.lua
similarity index 63%
rename from parts/player.lua
rename to parts/player/init.lua
index 8ae3dcef..8d262ca7 100644
--- a/parts/player.lua
+++ b/parts/player/init.lua
@@ -1,1020 +1,18 @@
-local gc=love.graphics
local mt=love.math
-local Timer=love.timer.getTime
local int,ceil,rnd=math.floor,math.ceil,math.random
-local max,min,abs,sin=math.max,math.min,math.abs,math.sin
+local max,min=math.max,math.min
local ins,rem=table.insert,table.remove
-local format=string.format
-local SCR=SCR
-local setFont=setFont
-----------------------------------------------------
-local gameEnv0={
- das=10,arr=2,sddas=2,sdarr=2,
- ihs=true,irs=true,ims=true,
- swap=true,
-
- ghost=.3,center=1,
- smooth=false,grid=false,
- bagLine=false,
- text=true,
- score=true,
- lockFX=2,
- dropFX=2,
- moveFX=2,
- clearFX=2,
- shakeFX=3,
-
- highCam=false,
- nextPos=false,
-
- drop=60,lock=60,
- wait=0,fall=0,
- bone=false,
- next=6,
- hold=true,oncehold=true,
- ospin=true,
- sequence="bag",
- freshMethod=NULL,
- bag={1,2,3,4,5,6,7},
- face=NULL,skin=NULL,
- mission=NULL,
-
- life=0,
- pushSpeed=3,
- block=true,
- noTele=false,
- visible="show",
- freshLimit=1e99,easyFresh=true,
-
- Fkey=NULL,
- keyCancel={},
- fine=false,fineKill=false,
- missionKill=false,
- target=1e99,dropPiece=NULL,
- mindas=0,minarr=0,minsdarr=0,
-
- bg="none",bgm="race"
+local PLY={
+ update=require("parts/player/update"),
+ draw=require("parts/player/draw"),
}
-local scs=spinCenters
+local Player={}--Player class
+
+local gameEnv0=require("parts/player/gameEnv0")
+local prepareSequence=require("parts/player/prepareSequence")
local kickList=require("parts/kickList")
-local CCblockID={6,5,4,3,2,1,0}
-----------------------------------------------------
-
-----------------------------------------------------
-local Player={}--Player object
-local PLY={}--Lib
-----------------------------------------------------
-
-----------------------------------------------------
-local function updateLine(P)--Attacks, line pushing, cam moving
- local bf=P.atkBuffer
- for i=#bf,1,-1 do
- local A=bf[i]
- A.time=A.time+1
- if not A.sent then
- if A.countdown>0 then
- A.countdown=max(A.countdown-GAME.garbageSpeed,0)
- end
- else
- if A.time>20 then
- rem(bf,i)
- end
- end
- end
-
- local y=P.fieldBeneath
- if y>0 then
- P.fieldBeneath=max(y-P.gameEnv.pushSpeed,0)
- end
-
- if P.gameEnv.highCam then
- local f=P.fieldUp
- if not P.alive then
- y=0
- else
- y=30*max(min(#P.field-19.5-P.fieldBeneath/30,P.imgY-17),0)
- end
- if f~=y then
- P.fieldUp=f>y and max(f*.95+y*.05-2,y)or min(f*.97+y*.03+1,y)
- end
- end
-end
-local function updateFXs(P,dt)
- if P.stat.score>P.score1 then
- if P.stat.score-P.score1<10 then
- P.score1=P.score1+1
- else
- P.score1=int(min(P.score1*.9+P.stat.score*.1+1))
- end
- end
-
- --LockFX
- for i=#P.lockFX,1,-1 do
- local S=P.lockFX[i]
- S[3]=S[3]+S[4]*dt
- if S[3]>1 then
- rem(P.lockFX,i)
- end
- end
-
- --DropFX
- for i=#P.dropFX,1,-1 do
- local S=P.dropFX[i]
- S[5]=S[5]+S[6]*dt
- if S[5]>1 then
- rem(P.dropFX,i)
- end
- end
-
- --MoveFX
- for i=#P.moveFX,1,-1 do
- local S=P.moveFX[i]
- S[4]=S[4]+S[5]*dt
- if S[4]>1 then
- rem(P.moveFX,i)
- end
- end
-
- --ClearFX
- for i=#P.clearFX,1,-1 do
- local S=P.clearFX[i]
- S[2]=S[2]+S[3]*dt
- if S[2]>1 then
- rem(P.clearFX,i)
- end
- end
-
- --Field shaking
- if P.gameEnv.shakeFX then
- local O=P.fieldOff
- O.vx,O.vy=O.vx*.8-abs(O.x)^1.2*(O.x>0 and .1 or -.1),O.vy*.8-abs(O.y)^1.2*(O.y>0 and .1 or -.1)
- O.x,O.y=O.x+O.vx,O.y+O.vy
- if abs(O.x)<.3 then O.x=0 end
- if abs(O.y)<.3 then O.y=0 end
- end
-
- if P.bonus then
- TEXT.update(P.bonus)
- end
-end
-local function updateTasks(P)
- local L=P.tasks
- for i=#L,1,-1 do
- if L[i].code(P,L[i].data)then rem(L,i)end
- end
-end
-local function Pupdate_alive(P,dt)
- if P.timing then P.stat.time=P.stat.time+dt end
- if P.keyRec then--Update speeds
- local _=GAME.frame
-
- local v=0
- for i=2,10 do v=v+i*(i-1)*7.2/(_-P.keyTime[i]+1)end
- P.keySpeed=P.keySpeed*.99+v*.1
-
- v=0
- for i=2,10 do v=v+i*(i-1)*7.2/(_-P.dropTime[i])end
- P.dropSpeed=P.dropSpeed*.99+v*.1
-
- if modeEnv.royaleMode then
- if P.keyPressing[9]then
- P.swappingAtkMode=min(P.swappingAtkMode+2,30)
- else
- P.swappingAtkMode=P.swappingAtkMode+((#P.field>15 and P.swappingAtkMode>4 or P.swappingAtkMode>8)and -1 or 1)
- end
- end
- end
-
- if not P.human and P.control and P.waiting==-1 then
- local C=P.AI_keys
- P.AI_delay=P.AI_delay-1
- if not C[1]then
- P.AI_stage=AIFUNC[P.AI_mode][P.AI_stage](P,C)
- elseif P.AI_delay<=0 then
- P:pressKey(C[1])P:releaseKey(C[1])
- if P.AI_mode~="CC"or C[1]>3 then
- P.AI_delay=P.AI_delay0*2
- else
- P.AI_delay=P.AI_delay0*.5
- end
- rem(C,1)
- end
- end
-
- --Fresh visible time
- if not P.keepVisible then
- for j=1,#P.field do for i=1,10 do
- if P.visTime[j][i]>0 then P.visTime[j][i]=P.visTime[j][i]-1 end
- end end
- end
-
- --Moving pressed
- if P.movDir~=0 then
- local das,arr=P.gameEnv.das,P.gameEnv.arr
- local mov=P.moving
- if P.waiting==-1 then
- if P.movDir==1 then
- if P.keyPressing[2]then
- if arr>0 then
- if mov==das+arr or mov==das then
- if not P.cur or P:ifoverlap(P.cur.bk,P.curX+1,P.curY)then
- mov=das+arr-1
- else
- P:act_moveRight(true)
- mov=das
- end
- end
- mov=mov+1
- else
- if mov==das then
- P:act_insRight(true)
- else
- mov=mov+1
- end
- end
- if mov>=das and P.gameEnv.shakeFX and P.cur and P:ifoverlap(P.cur.bk,P.curX+1,P.curY)then
- P.fieldOff.vx=P.gameEnv.shakeFX*.5
- end
- else
- P.movDir=0
- end
- else
- if P.keyPressing[1]then
- if arr>0 then
- if mov==das+arr or mov==das then
- if not P.cur or P:ifoverlap(P.cur.bk,P.curX-1,P.curY)then
- mov=das+arr-1
- else
- P:act_moveLeft(true)
- mov=das
- end
- end
- mov=mov+1
- else
- if mov==das then
- P:act_insLeft(true)
- else
- mov=mov+1
- end
- end
- if mov>=das and P.gameEnv.shakeFX and P.cur and P:ifoverlap(P.cur.bk,P.curX-1,P.curY)then
- P.fieldOff.vx=-P.gameEnv.shakeFX*.5
- end
- else
- P.movDir=0
- end
- end
- elseif mov1 then
- if P.gameEnv.sdarr>0 then
- if d%P.gameEnv.sdarr==0 then
- P:act_down1()
- end
- else
- P:act_insDown()
- end
- if P.gameEnv.shakeFX then
- P.fieldOff.vy=P.gameEnv.shakeFX*.3
- end
- end
- else
- P.downing=0
- end
-
- --Falling animation
- if P.falling>=0 then
- P.falling=P.falling-1
- if P.falling>=0 then
- goto stop
- else
- local L=#P.clearingRow
- if P.sound and P.gameEnv.fall>0 and #P.field+L>P.clearingRow[L]then SFX.play("fall")end
- P.clearingRow={}
- end
- end
-
- --Try spawn new block
- if not P.control then goto stop end
- if P.waiting>=0 then
- P.waiting=P.waiting-1
- if P.waiting<0 then P:popNext()end
- goto stop
- end
-
- --Natural block falling
- if P.cur then
- if P.curY>P.imgY then
- local D=P.dropDelay
- if D>1 then
- P.dropDelay=D-1
- goto stop
- end
-
- if D==1 then
- if P.gameEnv.moveFX and P.gameEnv.block then
- P:createMoveFX("down")
- end
- P.curY=P.curY-1
- else
- D=1/D--Fall dist
- if D>P.curY-P.imgY then D=P.curY-P.imgY end
- if P.gameEnv.moveFX and P.gameEnv.block then
- for _=1,D do
- P:createMoveFX("down")
- P.curY=P.curY-1
- end
- else
- P.curY=P.curY-D
- end
- end
- P:freshBlock(true,true)
- P.spinLast=false
-
- if P.imgY~=P.curY then
- P.dropDelay=P.gameEnv.drop
- elseif P.AI_mode=="CC"then
- CC.updateField(P)
- if not P.AIdata._20G and P.gameEnv.drop=0 then goto stop end
- P:drop()
- if P.AI_mode=="CC"then
- CC.updateField(P)
- end
- end
- end
- ::stop::
- if P.b2b1==P.b2b then
- elseif P.b2b10 then
- P.finesseComboTime=P.finesseComboTime-1
- end
- updateLine(P)
- updateFXs(P,dt)
- updateTasks(P)
-end
-local function Pupdate_dead(P,dt)
- if P.timing then P.stat.time=P.stat.time+dt end
- if P.keyRec then
- P.keySpeed=P.keySpeed*.96+P.stat.key/P.stat.time*60*.04
- P.dropSpeed=P.dropSpeed*.96+P.stat.piece/P.stat.time*60*.04
- --Final average speeds
- if modeEnv.royaleMode then
- P.swappingAtkMode=min(P.swappingAtkMode+2,30)
- end
- end
- if P.falling>=0 then
- P.falling=P.falling-1
- if P.falling<0 then
- local L=#P.clearingRow
- if P.sound and P.gameEnv.fall>0 and #P.field+L>P.clearingRow[L]then SFX.play("fall")end
- P.clearingRow={}
- end
- end
- if P.b2b1>0 then
- P.b2b1=max(0,P.b2b1*.92-1)
- end
- if P.finesseComboTime>0 then
- P.finesseComboTime=P.finesseComboTime-1
- end
- updateLine(P)
- updateFXs(P,dt)
- updateTasks(P)
-end
-----------------------------------------------------
-
-----------------------------------------------------
-local frameColor={
- [0]=COLOR.white,
- COLOR.lGreen,
- COLOR.lBlue,
- COLOR.lPurple,
- COLOR.lOrange,
-}
---local function drawCell(y,x,id)gc.draw(SKIN.curText[id],30*x-30,-30*y)end
-local function drawGrid(P)
- local FBN,FUP=P.fieldBeneath,P.fieldUp
- gc.setLineWidth(1)
- gc.setColor(1,1,1,.2)
- for x=1,9 do
- gc.line(30*x,-10,30*x,600)
- end
- for y=0,19 do
- y=30*(y-int((FBN+FUP)/30))+FBN+FUP
- gc.line(0,y,300,y)
- end
-end
-local function drawField(P)
- local V,F=P.visTime,P.field
- local start=int((P.fieldBeneath+P.fieldUp)/30+1)
- local rep=GAME.replaying
- local texture=SKIN.curText
- if P.falling==-1 then--Blocks only
- for j=start,min(start+21,#F)do
- for i=1,10 do
- if F[j][i]>0 then
- if V[j][i]>0 then
- gc.setColor(1,1,1,min(V[j][i]*.05,1))
- gc.draw(texture[F[j][i]],30*i-30,-30*j)-- drawCell(j,i,F[j][i])
- elseif rep then
- gc.setColor(1,1,1,.3+.08*sin(.5*(j-i)+Timer()*4))
- gc.rectangle("fill",30*i-30,-30*j,30,30)
- end
- end
- end
- end
- else--With falling animation
- local ENV=P.gameEnv
- local stepY=ENV.smooth and(P.falling/(ENV.fall+1))^2.5*30 or 30
- local A=P.falling/ENV.fall
- local h=1
- gc.push("transform")
- for j=start,min(start+21,#F)do
- while j==P.clearingRow[h]do
- h=h+1
- gc.translate(0,-stepY)
- gc.setColor(1,1,1,A)
- gc.rectangle("fill",0,30-30*j,300,stepY)
- end
- for i=1,10 do
- if F[j][i]>0 then
- if V[j][i]>0 then
- gc.setColor(1,1,1,min(V[j][i]*.05,1))
- gc.draw(texture[F[j][i]],30*i-30,-30*j)-- drawCell(j,i,F[j][i])
- elseif rep then
- gc.setColor(1,1,1,.2)
- gc.rectangle("fill",30*i-30,-30*j,30,30)
- end
- end
- end
- end
- gc.pop()
- end
-end
-local function drawFXs(P)
- --LockFX
- for i=1,#P.lockFX do
- local S=P.lockFX[i]
- if S[3]<.5 then
- gc.setColor(1,1,1,2*S[3])
- gc.rectangle("fill",S[1],S[2],60*S[3],30)
- else
- gc.setColor(1,1,1,2-2*S[3])
- gc.rectangle("fill",S[1]+30,S[2],60*S[3]-60,30)
- end
- end
-
- --DropFX
- for i=1,#P.dropFX do
- local S=P.dropFX[i]
- gc.setColor(1,1,1,.6-S[5]*.6)
- local w=30*S[3]*(1-S[5]*.5)
- gc.rectangle("fill",30*S[1]-30+15*S[3]-w*.5,-30*S[2],w,30*S[4])
- end
-
- --MoveFX
- local texture=SKIN.curText
- for i=1,#P.moveFX do
- local S=P.moveFX[i]
- gc.setColor(1,1,1,.6-S[4]*.6)
- gc.draw(texture[S[1]],30*S[2]-30,-30*S[3])-- drawCell(S[3],S[2],S[1])
- end
-
- --ClearFX
- for i=1,#P.clearFX do
- local S=P.clearFX[i]
- local t=S[2]
- local x=t<.3 and 1-(3.3333*t-1)^2 or 1
- local y=t<.2 and 5*t or 1-1.25*(t-.2)
- gc.setColor(1,1,1,y)
- gc.rectangle("fill",150-x*150,15-S[1]*30-y*15,300*x,y*30)
- end
-end
-local function drawGhost(P,clr)
- gc.setColor(1,1,1,P.gameEnv.ghost)
- local texture=SKIN.curText
- for i=1,P.r do for j=1,P.c do
- if P.cur.bk[i][j]then
- gc.draw(texture[clr],30*(j+P.curX-1)-30,-30*(i+P.imgY-1))-- drawCell(i+P.imgY-1,j+P.curX-1,clr)
- end
- end end
-end
-local function drawBlockOutline(P,texture,trans)
- SHADER.alpha:send("a",trans)
- gc.setShader(SHADER.alpha)
- for i=1,P.r do for j=1,P.c do
- if P.cur.bk[i][j]then
- local x=30*(j+P.curX)-60-3
- local y=30-30*(i+P.curY)-3
- gc.draw(texture,x,y)
- gc.draw(texture,x+6,y+6)
- gc.draw(texture,x+6,y)
- gc.draw(texture,x,y+6)
- end
- end end
- gc.setShader()
-end
-local function drawBlock(P,clr)
- gc.setColor(1,1,1)
- local texture=SKIN.curText
- for i=1,P.r do for j=1,P.c do
- if P.cur.bk[i][j]then
- gc.draw(texture[clr],30*(j+P.curX-1)-30,-30*(i+P.curY-1))-- drawCell(i+P.curY-1,j+P.curX-1,clr)
- end
- end end
-end
-local function drawNextPreview(P,B)
- gc.setColor(1,1,1,.8)
- local x=int(6-#B[1]*.5)
- local y=21+ceil(P.fieldBeneath/30)
- for i=1,#B do for j=1,#B[1]do
- if B[i][j]then
- gc.draw(puzzleMark[-1],30*(x+j-2),30*(1-y-i))
- end
- end end
-end
-local function drawHold(P,clr)
- local B=P.hd.bk
- local texture=SKIN.curText
- for i=1,#B do for j=1,#B[1]do
- if B[i][j]then
- gc.draw(texture[clr],30*(j+2.06-#B[1]*.5)-30,-30*(i+1.36-#B*.5))-- drawCell(i+1.36-#B*.5,j+2.06-#B[1]*.5,clr)
- end
- end end
-end
-
-local Pdraw_norm do
- local attackColor={
- {COLOR.dGrey,COLOR.white},
- {COLOR.grey,COLOR.white},
- {COLOR.lPurple,COLOR.white},
- {COLOR.lRed,COLOR.white},
- {COLOR.dGreen,COLOR.cyan},
- }
- local RCPB={10,33,200,33,105,5,105,60}
- local function drawDial(x,y,speed)
- gc.setColor(1,1,1)
- mStr(int(speed),x,y-18)
-
- gc.setLineWidth(4)
- gc.setColor(1,1,1,.4)
- gc.circle("line",x,y,30,10)
-
- gc.setLineWidth(2)
- gc.setColor(1,1,1,.6)
- gc.circle("line",x,y,30,10)
-
- gc.setColor(1,1,1,.8)
- gc.draw(IMG.dialNeedle,x,y,2.094+(speed<=175 and .02094*speed or 4.712-52.36/(speed-125)),nil,nil,5,4)
- end
- function Pdraw_norm(P)
- local _
- local ENV=P.gameEnv
- local FBN,FUP=P.fieldBeneath,P.fieldUp
- gc.push("transform")
- gc.translate(P.x,P.y)gc.scale(P.size)
-
- --Field-related things
- gc.push("transform")
- gc.translate(150,70)
-
- --Things shake with field
- gc.push("transform")
- gc.translate(P.fieldOff.x,P.fieldOff.y)
-
- --Fill field
- gc.setColor(0,0,0,.6)
- gc.rectangle("fill",0,-10,300,610)
-
- --Draw grid
- if ENV.grid then drawGrid(P)end
-
- --In-field things
- gc.push("transform")
- gc.translate(0,600+FBN+FUP)
- gc.setScissor(SCR.x+(P.absFieldX+P.fieldOff.x)*SCR.k,SCR.y+(P.absFieldY+P.fieldOff.y)*SCR.k,300*P.size*SCR.k,610*P.size*SCR.k)
-
- --Draw dangerous area
- gc.setColor(1,0,0,.3)
- gc.rectangle("fill",0,-600,300,-610-FUP-FBN)
-
- --Draw field
- drawField(P)
-
- --Draw spawn line
- gc.setColor(1,sin(Timer())*.4+.5,0,.5)
- gc.setLineWidth(4)
- gc.line(0,-600-FBN,300,-600-FBN)
-
- --Draw FXs
- drawFXs(P)
-
- --Draw current block
- if P.cur and P.waiting==-1 then
- local curColor=P.cur.color
-
- --Draw ghost
- if ENV.ghost then drawGhost(P,curColor)end
-
- local dy=ENV.smooth and P.imgY~=P.curY and(P.dropDelay/ENV.drop-1)*30 or 0
- gc.translate(0,-dy)
- local trans=P.lockDelay/ENV.lock
-
- --Draw block
- if ENV.block then
- drawBlockOutline(P,SKIN.curText[curColor],trans)
- drawBlock(P,curColor)
- end
-
- --Draw rotate center
- local x=30*(P.curX+P.sc[2])-15
- if ENV.center and ENV.block then
- gc.setColor(1,1,1,ENV.center)
- gc.draw(IMG.spinCenter,x,-30*(P.curY+P.sc[1])+15,nil,nil,nil,4,4)
- end
- gc.translate(0,dy)
- if ENV.center and ENV.ghost then
- gc.setColor(1,1,1,trans*ENV.center)
- gc.draw(IMG.spinCenter,x,-30*(P.imgY+P.sc[1])+15,nil,nil,nil,4,4)
- end
- end
-
- --Draw next preview
- if ENV.nextPos and P.next[1]then
- drawNextPreview(P,P.next[1].bk)
- end
-
- gc.setScissor()
- gc.pop()
-
- gc.setLineWidth(2)
- gc.setColor(P.frameColor)
- gc.rectangle("line",-1,-11,302,612)--Boarder
- gc.rectangle("line",301,-3,15,604)--AtkBuffer boarder
- gc.rectangle("line",-16,-3,15,604)--B2b bar boarder
-
- --Buffer line
- local h=0
- for i=1,#P.atkBuffer do
- local A=P.atkBuffer[i]
- local bar=A.amount*30
- if h+bar>600 then bar=600-h end
- if not A.sent then
- --Appear
- if A.time<20 then
- bar=bar*(20*A.time)^.5*.05
- end
- if A.countdown>0 then
- --Timing
- gc.setColor(attackColor[A.lv][1])
- gc.rectangle("fill",303,599-h,11,-bar)
- gc.setColor(attackColor[A.lv][2])
- gc.rectangle("fill",303,599-h-bar,11,bar*(1-A.countdown/A.cd0))
- else
- --Warning
- local t=math.sin((Timer()-i)*30)*.5+.5
- local c1,c2=attackColor[A.lv][1],attackColor[A.lv][2]
- gc.setColor(c1[1]*t+c2[1]*(1-t),c1[2]*t+c2[2]*(1-t),c1[3]*t+c2[3]*(1-t))
- gc.rectangle("fill",303,599-h,11,-bar)
- end
- else
- gc.setColor(attackColor[A.lv][1])
- bar=bar*(20-A.time)*.05
- gc.rectangle("fill",303,599-h,11,-bar)
- --Disappear
- end
- h=h+bar
- end
-
- --B2B indictator
- local a,b=P.b2b,P.b2b1 if a>b then a,b=b,a end
- gc.setColor(.8,1,.2)
- gc.rectangle("fill",-14,599,11,-b*.5)
- gc.setColor(P.b2b<40 and COLOR.white or P.b2b<=1e3 and COLOR.lRed or COLOR.lBlue)
- gc.rectangle("fill",-14,599,11,-a*.5)
- gc.setColor(1,1,1)
- if Timer()%.5<.3 then
- gc.rectangle("fill",-15,b<40 and 578.5 or 98.5,13,3)
- end
-
- --LockDelay indicator
- if ENV.easyFresh then
- gc.setColor(1,1,1)
- else
- gc.setColor(1,.26,.26)
- end
- if P.lockDelay>=0 then
- gc.rectangle("fill",0,602,300*P.lockDelay/ENV.lock,6)--Lock delay indicator
- end
- local x=3
- for _=1,min(ENV.freshLimit-P.freshTime,15)do
- gc.rectangle("fill",x,615,14,5)
- x=x+20
- end
-
- --Draw Hold
- if ENV.hold then
- gc.push("transform")
- gc.translate(-140,116)
- gc.setColor(0,0,0,.4)gc.rectangle("fill",0,-80,124,80)
- gc.setColor(1,1,1)gc.rectangle("line",0,-80,124,80)
- if P.holded then gc.setColor(.6,.4,.4)end
- mText(drawableText.hold,62,-131)
- if P.hd then drawHold(P,P.hd.color)end
- gc.pop()
- end
-
- --Draw Next(s)
- local N=ENV.next*72
- if ENV.next>0 then
- gc.setColor(0,0,0,.4)gc.rectangle("fill",316,36,124,N)
- gc.setColor(1,1,1)gc.rectangle("line",316,36,124,N)
- mText(drawableText.next,378,-15)
- N=1
- local texture=SKIN.curText
- while N<=ENV.next and P.next[N]do
- local bk,clr=P.next[N].bk,P.next[N].color
- for i=1,#bk do for j=1,#bk[1] do
- if bk[i][j]then
- gc.draw(texture[clr],30*(j+12.6-#bk[1]*.5)-30,-30*(i-2.4*N-#bk*.5))-- drawCell(i-2.4*N-#bk*.5,j+12.6-#bk[1]*.5,clr)
- end
- end end
- N=N+1
- end
- end
-
- --Draw Bagline(s)
- if ENV.bagLine then
- local L=ENV.bagLen
- local C=-P.pieceCount%L--Phase
- gc.setColor(.8,.5,.5)
- for i=C,N-1,L do
- local y=72*i+36
- gc.line(318+P.fieldOff.x,y,438,y)
- end
- end
-
- --Draw target selecting pad
- if modeEnv.royaleMode then
- if P.atkMode then
- gc.setColor(1,.8,0,P.swappingAtkMode*.02)
- gc.rectangle("fill",RCPB[2*P.atkMode-1],RCPB[2*P.atkMode],90,35,8,4)
- end
- gc.setColor(1,1,1,P.swappingAtkMode*.025)
- setFont(18)
- for i=1,4 do
- gc.rectangle("line",RCPB[2*i-1],RCPB[2*i],90,35,8,4)
- mStr(text.atkModeName[i],RCPB[2*i-1]+45,RCPB[2*i]+3)
- end
- end
- gc.pop()
-
- --Bonus texts
- TEXT.draw(P.bonus)
-
- --Display Ys
- -- gc.setLineWidth(6)
- -- if P.curY then gc.setColor(1,.4,0,.42)gc.line(0,611-P.curY*30,300,611-P.curY*30)end
- -- if P.imgY then gc.setColor(0,1,.4,.42)gc.line(0,615-P.imgY*30,300,615-P.imgY*30)end
- -- if P.minY then gc.setColor(0,.4,1,.42)gc.line(0,619-P.minY*30,300,619-P.minY*30)end
- -- gc.setColor(0,.4,1,.42)gc.line(0,600-P.garbageBeneath*30,300,600-P.garbageBeneath*30)
- gc.pop()
-
- --Speed dials
- setFont(25)
- drawDial(510,580,P.dropSpeed)
- drawDial(555,635,P.keySpeed)
- gc.setColor(1,1,1)
- gc.draw(drawableText.bpm,540,550)
- gc.draw(drawableText.kpm,494,643)
-
- --Score & Time
- setFont(25)
- gc.setColor(0,0,0,.3)
- gc.print(P.score1,18,579)
- gc.print(format("%.2f",P.stat.time),18,609)
-
- gc.setColor(COLOR.lYellow)gc.print(P.score1,20,580)
- gc.setColor(COLOR.sky)gc.print(format("%.2f",P.stat.time),20,610)
-
- --FinesseCombo
- if P.finesseCombo>2 then
- _=P.finesseComboTime
- local T=P.finesseCombo.."x"
- if _>0 then
- gc.setColor(1,1,1,_*.2)
- gc.print(T,20,640)
- gc.setColor(1,1,1,1.2-_*.1)
- gc.push("transform")
- gc.translate(20,670)
- gc.scale(1+_*.08)
- gc.print(T,0,-30)
- gc.pop()
- else
- gc.setColor(1,1,1)
- gc.print(T,20,640)
- end
- end
-
- --Lives
- if P.life>0 then
- gc.setColor(1,1,1)
- if P.life<=3 then
- for i=1,P.life do
- gc.draw(IMG.lifeIcon,450+25*i,665,nil,.8)
- end
- else
- gc.draw(IMG.lifeIcon,475,665,nil,.8)
- setFont(20)
- gc.print("x",503,665)
- gc.print(P.life,517,665)
- end
- end
-
- --Other messages
- gc.setColor(1,1,1)
- if CURMODE.mesDisp then
- CURMODE.mesDisp(P)
- end
-
- --Missions
- if P.curMission then
- local missionEnum=missionEnum
- local L=ENV.mission
-
- --Draw current mission
- setFont(35)
- if ENV.missionKill then
- gc.setColor(1,.7+.2*sin(Timer()*6.26),.4)
- else
- gc.setColor(1,1,1)
- end
- gc.print(missionEnum[L[P.curMission]],85,180)
-
- --Draw next mission
- setFont(17)
- for i=1,3 do
- local t=L[P.curMission+i]
- if t then
- t=missionEnum[t]
- gc.print(t,87-26*i,187)
- else
- break
- end
- end
- end
-
- --Draw starting counter
- gc.setColor(1,1,1)
- if GAME.frame<180 then
- local count=179-GAME.frame
- gc.push("transform")
- gc.translate(305,290)
- setFont(95)
- if count%60>45 then gc.scale(1+(count%60-45)^2*.01,1)end
- mStr(int(count/60+1),0,0)
- gc.pop()
- end
- gc.pop()
- end
-end
-local function Pdraw_small(P)
- --Draw content
- P.frameWait=P.frameWait-1
- if P.frameWait==0 then
- P.frameWait=10
- gc.setCanvas(P.canvas)
- gc.clear(0,0,0,.4)
- gc.push("transform")
- gc.origin()
- gc.setColor(1,1,1,P.result and max(20-P.endCounter,0)*.05 or 1)
-
- --Field
- local F=P.field
- local texture=SKIN.curTextMini
- for j=1,#F do
- for i=1,10 do if F[j][i]>0 then
- gc.draw(texture[F[j][i]],6*i-6,120-6*j)
- end end
- end
-
- --Draw boarder
- if P.alive then
- gc.setLineWidth(2)
- gc.setColor(P.frameColor)
- gc.rectangle("line",0,0,60,120)
- end
-
- --Draw badge
- if modeEnv.royaleMode then
- gc.setColor(1,1,1)
- for i=1,P.strength do
- gc.draw(IMG.badgeIcon,12*i-7,4,nil,.5)
- end
- end
-
- --Draw result
- if P.result then
- gc.setColor(1,1,1,min(P.endCounter,60)*.01)
- setFont(17)mStr(P.result,32,47)
- setFont(15)mStr(P.modeData.event,30,82)
- end
- gc.pop()
- gc.setCanvas()
- end
-
- --Draw Canvas
- gc.setColor(1,1,1)
- gc.draw(P.canvas,P.x,P.y,nil,P.size*10)
- if P.killMark then
- gc.setLineWidth(3)
- gc.setColor(1,0,0,min(P.endCounter,25)*.04)
- gc.circle("line",P.centerX,P.centerY,(840-20*min(P.endCounter,30))*P.size)
- end
- setFont(30)
-end
-local function Pdraw_demo(P)
- local _
- local ENV=P.gameEnv
- local curColor=P.cur.color
-
- --Camera
- gc.push("transform")
- gc.translate(P.x,P.y)gc.scale(P.size)
- gc.push("transform")
- gc.translate(P.fieldOff.x,P.fieldOff.y)
-
- --Frame
- gc.setColor(0,0,0,.6)
- gc.rectangle("fill",0,0,300,600)
- gc.setLineWidth(2)
- gc.setColor(1,1,1)
- gc.rectangle("line",-1,-1,302,602)
-
- gc.push("transform")
- gc.translate(0,600)
- drawField(P)
- drawFXs(P)
- if P.cur and P.waiting==-1 then
- if ENV.ghost then drawGhost(P,curColor)end
- if ENV.block then
- drawBlockOutline(P,SKIN.curText[curColor],P.lockDelay/ENV.lock)
- drawBlock(P,curColor)
- end
- end
- gc.pop()
-
- --Draw hold
- local blockImg=TEXTURE.miniBlock
- if P.hd then
- local id=P.hd.id
- _=P.color[id]
- gc.setColor(_[1],_[2],_[3],.3)
- _=blockImg[id]
- gc.draw(_,15,30,nil,16,nil,0,_:getHeight()*.5)
- end
-
- --Draw next
- local N=1
- while N<=ENV.next and P.next[N]do
- local id=P.next[N].id
- _=P.color[id]
- gc.setColor(_[1],_[2],_[3],.3)
- _=blockImg[id]
- gc.draw(_,285,40*N-10,nil,16,nil,_:getWidth(),_:getHeight()*.5)
- N=N+1
- end
- gc.pop()
- TEXT.draw(P.bonus)
- gc.pop()
-end
-function Player.drawTargetLine(P,r)
- if r<21+(P.fieldBeneath+P.fieldUp)/30 and r>0 then
- gc.setLineWidth(4)
- gc.setColor(1,r>10 and 0 or rnd(),.5)
- local dx,dy=150+P.fieldOff.x,70+P.fieldOff.y+P.fieldBeneath+P.fieldUp
- gc.line(dx,600-30*r+dy,300+dx,600-30*r+dy)
- end
-end
-----------------------------------------------------
+local scs=spinCenters
----------------------------------------------------
local function without(L,e)
@@ -1177,136 +175,6 @@ local function applyGameEnv(P)--Finish gameEnv processing
if ENV.center==0 then ENV.center=nil end
end
-local prepareSequence do
- local freshMethod
- local freshPrepare={
- rnd=function(P)
- local bag=P.gameEnv.bag
- P:getNext(bag[rnd(#bag)])
- freshMethod.rnd(P)
- end,
- fixed=function(P)
- local bag=P.gameEnv.bag
- local L=#bag
- for i=1,L do
- P.seqData[i]=bag[L+1-i]
- end
- while #P.next<6 do
- if P.seqData[1]then
- P:getNext(rem(P.seqData))
- else
- break
- end
- end
- end,
- }
- freshMethod={
- none=NULL,
- bag=function(P)
- local bag=P.seqData
- while #P.next<6 do
- if #bag==0 then--Copy a new bag
- local bag0=P.gameEnv.bag
- for i=1,#bag0 do bag[i]=bag0[i]end
- end
- P:getNext(rem(bag,P:RND(#bag)))
- end
- end,
- his4=function(P)
- while #P.next<6 do
- local bag=P.gameEnv.bag
- local L=#bag
- for n=1,4 do
- local j,i=0
- repeat
- i=bag[P:RND(L)]
- j=j+1
- until i~=P.seqData[1]and i~=P.seqData[2]and i~=P.seqData[3]and i~=P.seqData[4]or j==4
- P.seqData[n]=i
- P:getNext(i)
- end
- end
- end,
- rnd=function(P)
- while #P.next<6 do
- local bag=P.gameEnv.bag
- local L=#bag
- for i=1,4 do
- local count=0
- repeat
- i=bag[P:RND(L)]
- count=count+1
- until i~=P.next[#P.next].id or count>=L
- P:getNext(i)
- end
- end
- end,
- reverb=function(P)
- local seq=P.seqData
- while #P.next<6 do
- if #seq==0 then
- local bag0=P.gameEnv.bag
- for i=1,#bag0 do seq[i]=bag0[i]end
- local bag={}
- repeat
- local r=rem(seq,P:RND(#bag))
- local p=1
- repeat
- ins(bag,r)
- p=p-.15-P:RND()
- until p<0
- until #seq==0
- for i=1,#bag do
- seq[i]=bag[i]
- end
- end
- P:getNext(rem(seq))
- end
- end,
- loop=function(P)
- while #P.next<6 do
- if #P.seqData==0 then
- local bag=P.gameEnv.bag
- local L=#bag
- for i=1,L do
- P.seqData[i]=bag[L+1-i]
- end
- end
- P:getNext(rem(P.seqData))
- end
- end,
- fixed=function(P)
- while #P.next<6 do
- if P.seqData[1]then
- P:getNext(rem(P.seqData))
- else
- if not(P.cur or P.hd)then P:lose(true)end
- return
- end
- end
- end,
- }
- function prepareSequence(P)--Call freshPrepare and set newNext
- local ENV=P.gameEnv
- if type(ENV.sequence)=="string"then
- P.newNext=freshMethod[ENV.sequence]
- if freshPrepare[ENV.sequence]then
- freshPrepare[ENV.sequence](P)
- else
- P:newNext()
- end
- else
- if type(ENV.freshMethod)=="function"then
- if ENV.sequence then ENV.sequence(P)end
- P.newNext=ENV.freshMethod
- else
- LOG.print("Wrong sequence generator code","warn")
- ENV.sequence="bag"
- prepareSequence(P)
- end
- end
- end
-end
local function loadAI(P,AIdata)--Load AI params
local ENV=P.gameEnv
P.AI_mode=AIdata.type
@@ -1340,7 +208,7 @@ local function loadAI(P,AIdata)--Load AI params
P.AI_bot=CC.new(opt,wei)
CC.free(opt)CC.free(wei)
for i=1,AIdata.next do
- CC.addNext(P.AI_bot,CCblockID[P.next[i].id])
+ CC.addNext(P.AI_bot,P.next[i].id)
end
end
end
@@ -1351,6 +219,7 @@ local function newEmptyPlayer(id,x,y,size)
--Inherit functions of player class
for k,v in next,Player do P[k]=v end
+
if P.id==1 and GAME.recording then
P.pressKey=pressKey_Rec
P.releaseKey=releaseKey_Rec
@@ -1358,24 +227,24 @@ local function newEmptyPlayer(id,x,y,size)
P.pressKey=pressKey
P.releaseKey=releaseKey
end
- P.update=Pupdate_alive
+ P.update=PLY.update.alive
P.fieldOff={x=0,y=0,vx=0,vy=0}--For shake FX
P.x,P.y,P.size=x,y,size or 1
- P.frameColor=frameColor[0]
+ P.frameColor=0
P.small=P.size<.1--If draw in small mode
if P.small then
P.centerX,P.centerY=P.x+300*P.size,P.y+600*P.size
P.canvas=love.graphics.newCanvas(60,120)
P.frameWait=rnd(30,120)
- P.draw=Pdraw_small
+ P.draw=PLY.draw.small
else
P.keyRec=true--If calculate keySpeed
P.centerX,P.centerY=P.x+300*P.size,P.y+370*P.size
P.absFieldX=P.x+150*P.size
P.absFieldY=P.y+60*P.size
- P.draw=Pdraw_norm
+ P.draw=PLY.draw.norm
P.bonus={}--Text objects
end
P.randGen=mt.newRandomGenerator(GAME.seed)
@@ -1985,7 +854,7 @@ function Player.hold(P,ifpre)
if P.AI_mode=="CC"then
local next=P.next[P.AIdata.next]
if next then
- CC.addNext(P.AI_bot,CCblockID[next.id])
+ CC.addNext(P.AI_bot,next.id)
end
end
else
@@ -2025,7 +894,7 @@ function Player.popNext(P)--Pop next queue to hand
if P.AI_mode=="CC"then
local next=P.next[P.AIdata.next]
if next then
- CC.addNext(P.AI_bot,CCblockID[next.id])
+ CC.addNext(P.AI_bot,next.id)
end
end
@@ -2703,7 +1572,7 @@ function Player.die(P)--Called both when win/lose!
P.alive=false
P.timing=false
P.control=false
- P.update=Pupdate_dead
+ P.update=PLY.update.dead
P.waiting=1e99
P.b2b=0
P.tasks={}
@@ -2813,7 +1682,7 @@ function Player.lose(P,force)
for j=A.strength+1,4 do
if A.badge>=royaleData.powerUp[j]then
A.strength=j
- A.frameColor=frameColor[A.strength]
+ A.frameColor=A.strength
end
end
P.lastRecv=A
@@ -3140,7 +2009,7 @@ end
function PLY.check_attackReach(P)
if P.stat.atk>=P.gameEnv.target then
P:win("finish")
-end
+ end
end
function PLY.newDemoPlayer(id,x,y,size)
@@ -3152,7 +2021,7 @@ function PLY.newDemoPlayer(id,x,y,size)
P.centerX,P.centerY=P.x+300*P.size,P.y+600*P.size
P.absFieldX=P.x+150*P.size
P.absFieldY=P.y+60*P.size
- P.draw=Pdraw_demo
+ P.draw=PLY.draw.demo
P.control=true
P.gameEnv={
das=10,arr=2,sddas=2,sdarr=2,
diff --git a/parts/player/prepareSequence.lua b/parts/player/prepareSequence.lua
new file mode 100644
index 00000000..657b0dee
--- /dev/null
+++ b/parts/player/prepareSequence.lua
@@ -0,0 +1,132 @@
+local rnd=math.random
+local ins,rem=table.insert,table.remove
+
+local freshMethod
+local freshPrepare={
+ rnd=function(P)
+ local bag=P.gameEnv.bag
+ P:getNext(bag[rnd(#bag)])
+ freshMethod.rnd(P)
+ end,
+ fixed=function(P)
+ local bag=P.gameEnv.bag
+ local L=#bag
+ for i=1,L do
+ P.seqData[i]=bag[L+1-i]
+ end
+ while #P.next<6 do
+ if P.seqData[1]then
+ P:getNext(rem(P.seqData))
+ else
+ break
+ end
+ end
+ end,
+}
+freshMethod={
+ none=NULL,
+ bag=function(P)
+ local bag=P.seqData
+ while #P.next<6 do
+ if #bag==0 then--Copy a new bag
+ local bag0=P.gameEnv.bag
+ for i=1,#bag0 do bag[i]=bag0[i]end
+ end
+ P:getNext(rem(bag,P:RND(#bag)))
+ end
+ end,
+ his4=function(P)
+ while #P.next<6 do
+ local bag=P.gameEnv.bag
+ local L=#bag
+ for n=1,4 do
+ local j,i=0
+ repeat
+ i=bag[P:RND(L)]
+ j=j+1
+ until i~=P.seqData[1]and i~=P.seqData[2]and i~=P.seqData[3]and i~=P.seqData[4]or j==4
+ P.seqData[n]=i
+ P:getNext(i)
+ end
+ end
+ end,
+ rnd=function(P)
+ while #P.next<6 do
+ local bag=P.gameEnv.bag
+ local L=#bag
+ for i=1,4 do
+ local count=0
+ repeat
+ i=bag[P:RND(L)]
+ count=count+1
+ until i~=P.next[#P.next].id or count>=L
+ P:getNext(i)
+ end
+ end
+ end,
+ reverb=function(P)
+ local seq=P.seqData
+ while #P.next<6 do
+ if #seq==0 then
+ local bag0=P.gameEnv.bag
+ for i=1,#bag0 do seq[i]=bag0[i]end
+ local bag={}
+ repeat
+ local r=rem(seq,P:RND(#bag))
+ local p=1
+ repeat
+ ins(bag,r)
+ p=p-.15-P:RND()
+ until p<0
+ until #seq==0
+ for i=1,#bag do
+ seq[i]=bag[i]
+ end
+ end
+ P:getNext(rem(seq))
+ end
+ end,
+ loop=function(P)
+ while #P.next<6 do
+ if #P.seqData==0 then
+ local bag=P.gameEnv.bag
+ local L=#bag
+ for i=1,L do
+ P.seqData[i]=bag[L+1-i]
+ end
+ end
+ P:getNext(rem(P.seqData))
+ end
+ end,
+ fixed=function(P)
+ while #P.next<6 do
+ if P.seqData[1]then
+ P:getNext(rem(P.seqData))
+ else
+ if not(P.cur or P.hd)then P:lose(true)end
+ return
+ end
+ end
+ end,
+}
+local function prepareSequence(P)--Call freshPrepare and set newNext
+ local ENV=P.gameEnv
+ if type(ENV.sequence)=="string"then
+ P.newNext=freshMethod[ENV.sequence]
+ if freshPrepare[ENV.sequence]then
+ freshPrepare[ENV.sequence](P)
+ else
+ P:newNext()
+ end
+ else
+ if type(ENV.freshMethod)=="function"then
+ if ENV.sequence then ENV.sequence(P)end
+ P.newNext=ENV.freshMethod
+ else
+ LOG.print("Wrong sequence generator code","warn")
+ ENV.sequence="bag"
+ prepareSequence(P)
+ end
+ end
+end
+return prepareSequence
\ No newline at end of file
diff --git a/parts/player/update.lua b/parts/player/update.lua
new file mode 100644
index 00000000..c829fe18
--- /dev/null
+++ b/parts/player/update.lua
@@ -0,0 +1,338 @@
+local int,max,min,abs=math.floor,math.max,math.min,math.abs
+local rem=table.remove
+
+local function updateLine(P)--Attacks, line pushing, cam moving
+ local bf=P.atkBuffer
+ for i=#bf,1,-1 do
+ local A=bf[i]
+ A.time=A.time+1
+ if not A.sent then
+ if A.countdown>0 then
+ A.countdown=max(A.countdown-GAME.garbageSpeed,0)
+ end
+ else
+ if A.time>20 then
+ rem(bf,i)
+ end
+ end
+ end
+
+ local y=P.fieldBeneath
+ if y>0 then
+ P.fieldBeneath=max(y-P.gameEnv.pushSpeed,0)
+ end
+
+ if P.gameEnv.highCam then
+ local f=P.fieldUp
+ if not P.alive then
+ y=0
+ else
+ y=30*max(min(#P.field-19.5-P.fieldBeneath/30,P.imgY-17),0)
+ end
+ if f~=y then
+ P.fieldUp=f>y and max(f*.95+y*.05-2,y)or min(f*.97+y*.03+1,y)
+ end
+ end
+end
+local function updateFXs(P,dt)
+ if P.stat.score>P.score1 then
+ if P.stat.score-P.score1<10 then
+ P.score1=P.score1+1
+ else
+ P.score1=int(min(P.score1*.9+P.stat.score*.1+1))
+ end
+ end
+
+ --LockFX
+ for i=#P.lockFX,1,-1 do
+ local S=P.lockFX[i]
+ S[3]=S[3]+S[4]*dt
+ if S[3]>1 then
+ rem(P.lockFX,i)
+ end
+ end
+
+ --DropFX
+ for i=#P.dropFX,1,-1 do
+ local S=P.dropFX[i]
+ S[5]=S[5]+S[6]*dt
+ if S[5]>1 then
+ rem(P.dropFX,i)
+ end
+ end
+
+ --MoveFX
+ for i=#P.moveFX,1,-1 do
+ local S=P.moveFX[i]
+ S[4]=S[4]+S[5]*dt
+ if S[4]>1 then
+ rem(P.moveFX,i)
+ end
+ end
+
+ --ClearFX
+ for i=#P.clearFX,1,-1 do
+ local S=P.clearFX[i]
+ S[2]=S[2]+S[3]*dt
+ if S[2]>1 then
+ rem(P.clearFX,i)
+ end
+ end
+
+ --Field shaking
+ if P.gameEnv.shakeFX then
+ local O=P.fieldOff
+ O.vx,O.vy=O.vx*.8-abs(O.x)^1.2*(O.x>0 and .1 or -.1),O.vy*.8-abs(O.y)^1.2*(O.y>0 and .1 or -.1)
+ O.x,O.y=O.x+O.vx,O.y+O.vy
+ if abs(O.x)<.3 then O.x=0 end
+ if abs(O.y)<.3 then O.y=0 end
+ end
+
+ if P.bonus then
+ TEXT.update(P.bonus)
+ end
+end
+local function updateTasks(P)
+ local L=P.tasks
+ for i=#L,1,-1 do
+ if L[i].code(P,L[i].data)then rem(L,i)end
+ end
+end
+
+local update={}
+function update.alive(P,dt)
+ if P.timing then P.stat.time=P.stat.time+dt end
+ if P.keyRec then--Update speeds
+ local _=GAME.frame
+
+ local v=0
+ for i=2,10 do v=v+i*(i-1)*7.2/(_-P.keyTime[i]+1)end
+ P.keySpeed=P.keySpeed*.99+v*.1
+
+ v=0
+ for i=2,10 do v=v+i*(i-1)*7.2/(_-P.dropTime[i])end
+ P.dropSpeed=P.dropSpeed*.99+v*.1
+
+ if modeEnv.royaleMode then
+ if P.keyPressing[9]then
+ P.swappingAtkMode=min(P.swappingAtkMode+2,30)
+ else
+ P.swappingAtkMode=P.swappingAtkMode+((#P.field>15 and P.swappingAtkMode>4 or P.swappingAtkMode>8)and -1 or 1)
+ end
+ end
+ end
+
+ if not P.human and P.control and P.waiting==-1 then
+ local C=P.AI_keys
+ P.AI_delay=P.AI_delay-1
+ if not C[1]then
+ P.AI_stage=AIFUNC[P.AI_mode][P.AI_stage](P,C)
+ elseif P.AI_delay<=0 then
+ P:pressKey(C[1])P:releaseKey(C[1])
+ if P.AI_mode~="CC"or C[1]>3 then
+ P.AI_delay=P.AI_delay0*2
+ else
+ P.AI_delay=P.AI_delay0*.5
+ end
+ rem(C,1)
+ end
+ end
+
+ --Fresh visible time
+ if not P.keepVisible then
+ for j=1,#P.field do for i=1,10 do
+ if P.visTime[j][i]>0 then P.visTime[j][i]=P.visTime[j][i]-1 end
+ end end
+ end
+
+ --Moving pressed
+ if P.movDir~=0 then
+ local das,arr=P.gameEnv.das,P.gameEnv.arr
+ local mov=P.moving
+ if P.waiting==-1 then
+ if P.movDir==1 then
+ if P.keyPressing[2]then
+ if arr>0 then
+ if mov==das+arr or mov==das then
+ if not P.cur or P:ifoverlap(P.cur.bk,P.curX+1,P.curY)then
+ mov=das+arr-1
+ else
+ P:act_moveRight(true)
+ mov=das
+ end
+ end
+ mov=mov+1
+ else
+ if mov==das then
+ P:act_insRight(true)
+ else
+ mov=mov+1
+ end
+ end
+ if mov>=das and P.gameEnv.shakeFX and P.cur and P:ifoverlap(P.cur.bk,P.curX+1,P.curY)then
+ P.fieldOff.vx=P.gameEnv.shakeFX*.5
+ end
+ else
+ P.movDir=0
+ end
+ else
+ if P.keyPressing[1]then
+ if arr>0 then
+ if mov==das+arr or mov==das then
+ if not P.cur or P:ifoverlap(P.cur.bk,P.curX-1,P.curY)then
+ mov=das+arr-1
+ else
+ P:act_moveLeft(true)
+ mov=das
+ end
+ end
+ mov=mov+1
+ else
+ if mov==das then
+ P:act_insLeft(true)
+ else
+ mov=mov+1
+ end
+ end
+ if mov>=das and P.gameEnv.shakeFX and P.cur and P:ifoverlap(P.cur.bk,P.curX-1,P.curY)then
+ P.fieldOff.vx=-P.gameEnv.shakeFX*.5
+ end
+ else
+ P.movDir=0
+ end
+ end
+ elseif mov1 then
+ if P.gameEnv.sdarr>0 then
+ if d%P.gameEnv.sdarr==0 then
+ P:act_down1()
+ end
+ else
+ P:act_insDown()
+ end
+ if P.gameEnv.shakeFX then
+ P.fieldOff.vy=P.gameEnv.shakeFX*.3
+ end
+ end
+ else
+ P.downing=0
+ end
+
+ --Falling animation
+ if P.falling>=0 then
+ P.falling=P.falling-1
+ if P.falling>=0 then
+ goto stop
+ else
+ local L=#P.clearingRow
+ if P.sound and P.gameEnv.fall>0 and #P.field+L>P.clearingRow[L]then SFX.play("fall")end
+ P.clearingRow={}
+ end
+ end
+
+ --Try spawn new block
+ if not P.control then goto stop end
+ if P.waiting>=0 then
+ P.waiting=P.waiting-1
+ if P.waiting<0 then P:popNext()end
+ goto stop
+ end
+
+ --Natural block falling
+ if P.cur then
+ if P.curY>P.imgY then
+ local D=P.dropDelay
+ if D>1 then
+ P.dropDelay=D-1
+ goto stop
+ end
+
+ if D==1 then
+ if P.gameEnv.moveFX and P.gameEnv.block then
+ P:createMoveFX("down")
+ end
+ P.curY=P.curY-1
+ else
+ D=1/D--Fall dist
+ if D>P.curY-P.imgY then D=P.curY-P.imgY end
+ if P.gameEnv.moveFX and P.gameEnv.block then
+ for _=1,D do
+ P:createMoveFX("down")
+ P.curY=P.curY-1
+ end
+ else
+ P.curY=P.curY-D
+ end
+ end
+ P:freshBlock(true,true)
+ P.spinLast=false
+
+ if P.imgY~=P.curY then
+ P.dropDelay=P.gameEnv.drop
+ elseif P.AI_mode=="CC"then
+ CC.updateField(P)
+ if not P.AIdata._20G and P.gameEnv.drop=0 then goto stop end
+ P:drop()
+ if P.AI_mode=="CC"then
+ CC.updateField(P)
+ end
+ end
+ end
+ ::stop::
+ if P.b2b1==P.b2b then
+ elseif P.b2b10 then
+ P.finesseComboTime=P.finesseComboTime-1
+ end
+ updateLine(P)
+ updateFXs(P,dt)
+ updateTasks(P)
+end
+function update.dead(P,dt)
+ if P.timing then P.stat.time=P.stat.time+dt end
+ if P.keyRec then
+ P.keySpeed=P.keySpeed*.96+P.stat.key/P.stat.time*60*.04
+ P.dropSpeed=P.dropSpeed*.96+P.stat.piece/P.stat.time*60*.04
+ --Final average speeds
+ if modeEnv.royaleMode then
+ P.swappingAtkMode=min(P.swappingAtkMode+2,30)
+ end
+ end
+ if P.falling>=0 then
+ P.falling=P.falling-1
+ if P.falling<0 then
+ local L=#P.clearingRow
+ if P.sound and P.gameEnv.fall>0 and #P.field+L>P.clearingRow[L]then SFX.play("fall")end
+ P.clearingRow={}
+ end
+ end
+ if P.b2b1>0 then
+ P.b2b1=max(0,P.b2b1*.92-1)
+ end
+ if P.finesseComboTime>0 then
+ P.finesseComboTime=P.finesseComboTime-1
+ end
+ updateLine(P)
+ updateFXs(P,dt)
+ updateTasks(P)
+end
+return update
\ No newline at end of file