Files
Techmino/parts/player/init.lua
2020-12-16 00:08:13 +08:00

379 lines
8.1 KiB
Lua

local Player=require"parts/player/player"
local prepareSequence=require"parts/player/prepareSequence"
local gameEnv0=require"parts/player/gameEnv0"
local mt=love.math
local rnd,max=math.random,math.max
local ins=table.insert
local PLY={
update=require"parts/player/update",
draw=require"parts/player/draw",
}
--------------------------<Lib Func>--------------------------
local function getNewStatTable()
local T={
time=0,frame=0,score=0,
key=0,rotate=0,hold=0,
extraPiece=0,finesseRate=0,
piece=0,row=0,dig=0,
atk=0,digatk=0,
send=0,recv=0,pend=0,off=0,
clear={},clears={},spin={},spins={},
pc=0,hpc=0,b2b=0,b3b=0,
maxCombo=0,maxFinesseCombo=0,
}
for i=1,25 do
T.clear[i]={0,0,0,0,0,0}
T.spin[i]={0,0,0,0,0,0,0}
T.clears[i]=0
T.spins[i]=0
end
return T
end
local function pressKey(P,keyID)
if P.keyAvailable[keyID]then
P.keyPressing[keyID]=true
P.actList[keyID](P)
if P.control then
if P.keyRec then
ins(P.keyTime,1,GAME.frame)
P.keyTime[11]=nil
end
end
P.stat.key=P.stat.key+1
end
end
local function releaseKey(P,keyID)
P.keyPressing[keyID]=false
end
local function pressKey_Rec(P,keyID)
if P.keyAvailable[keyID]then
if GAME.recording then
ins(GAME.rep,GAME.frame+1)
ins(GAME.rep,keyID)
end
P.keyPressing[keyID]=true
P.actList[keyID](P)
if P.control then
if P.keyRec then
ins(P.keyTime,1,GAME.frame)
P.keyTime[11]=nil
end
end
P.stat.key=P.stat.key+1
end
end
local function releaseKey_Rec(P,keyID)
if GAME.recording then
ins(GAME.rep,GAME.frame+1)
ins(GAME.rep,-keyID)
end
P.keyPressing[keyID]=false
end
local function newEmptyPlayer(id,mini)
local P={id=id}
PLAYERS[id]=P
PLAYERS.alive[id]=P
--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
else
P.pressKey=pressKey
P.releaseKey=releaseKey
end
P.update=PLY.update.alive
P.fieldOff={x=0,y=0,vx=0,vy=0}--For shake FX
P.x,P.y,P.size=0,0,1
P.frameColor=0
P.mini=mini--If draw in small mode
--Set these at Player:setPosition()
-- P.fieldX,P.fieldY=...
-- P.centerX,P.centerY=...
-- P.absFieldX,P.absFieldY=...
if P.mini then
P.canvas=love.graphics.newCanvas(60,120)
P.frameWait=rnd(30,120)
P.draw=PLY.draw.small
else
P.keyRec=true--If calculate keySpeed
P.draw=PLY.draw.norm
end
P.randGen=mt.newRandomGenerator(GAME.seed)
P.alive=true
P.control=false
P.timing=false
P.stat=getNewStatTable()
P.modeData={point=0,event=0,counter=0}--Data use by mode
P.keyTime={}P.keySpeed=0
P.dropTime={}P.dropSpeed=0
for i=1,10 do P.keyTime[i]=-1e5 end
for i=1,10 do P.dropTime[i]=-1e5 end
P.field,P.visTime={},{}
P.atkBuffer={sum=0}
--Royale-related
P.badge,P.strength=0,0
P.atkMode,P.swappingAtkMode=1,20
P.atker,P.atking,P.lastRecv={}
P.dropDelay,P.lockDelay=0,0
P.color={}
P.showTime=nil
P.keepVisible=true
--P.cur={bk=matrix[2], id=shapeID, color=colorID, name=nameID}
--P.sc,P.dir={0,0},0--SpinCenterCoord, direction
--P.r,P.c=0,0--row, col
-- P.curX,P.curY,P.imgY,P.minY=0,0,0,0--x,y,ghostY
P.holdQueue={}
P.holdTime=0
P.nextQueue={}
P.seqData={}
P.freshTime=0
P.spinLast=false
P.lastPiece={
id=0,name=0,--block id/name
finePts=0,--finesse Points
row=0,dig=0,--lines/garbage cleared
score=0,--score gained
atk=0,exblock=0,--lines attack/defend
off=0,send=0,--lines offset/sent
spin=false,mini=false,--if spin/mini
pc=false,hpc=false,--if pc/hpc
special=false,--if special clear (spin, >=4, pc)
}
P.spinSeq=0--For Ospin, each digit mean a spin
P.ctrlCount=0--Key press time, for finesse check
P.pieceCount=0--Count pieces from next, for drawing bagline
P.type="none"
P.sound=false
-- P.newNext=nil--Call prepareSequence()to get a function to get new next
P.keyPressing={}for i=1,12 do P.keyPressing[i]=false end
P.movDir,P.moving,P.downing=0,0,0--Last move key,DAS charging,downDAS charging
P.waiting,P.falling=-1,-1
P.clearingRow,P.clearedRow={},{}--Clearing animation height,cleared row mark
P.combo,P.b2b=0,0
P.finesseCombo=0
P.garbageBeneath=0
P.fieldBeneath=0
P.fieldUp=0
P.score1,P.b2b1=0,0
P.finesseComboTime=0
P.dropFX,P.moveFX,P.lockFX,P.clearFX={},{},{},{}
P.tasks={}--Tasks
P.bonus={}--Text objects
P.endCounter=0--Used after gameover
P.result=nil--String:"WIN"/"K.O."
return P
end
local function loadGameEnv(P)--Load gameEnv
P.gameEnv={}--Current game setting environment
local ENV=P.gameEnv
local GAME=GAME
local SETTING=SETTING
--Load game settings
for k,v in next,gameEnv0 do
if GAME.modeEnv[k]~=nil then
v=GAME.modeEnv[k] --Mode setting
-- DBP("mode-"..k..":"..tostring(v))
elseif GAME.setting[k]~=nil then
v=GAME.setting[k] --Game setting
-- DBP("game-"..k..":"..tostring(v))
elseif SETTING[k]~=nil then
v=SETTING[k] --Global setting
-- DBP("global-"..k..":"..tostring(v))
-- else
-- DBP("default-"..k..":"..tostring(v))
end
if type(v)~="table"then--Default setting
ENV[k]=v
else
ENV[k]=copyTable(v)
end
end
if not ENV.noMod then
for _,M in next,GAME.mod do
M.func(P,M.list[M.sel])
end
end
end
local function applyGameEnv(P)--Finish gameEnv processing
local ENV=P.gameEnv
P._20G=ENV.drop==0
P.dropDelay=ENV.drop
P.lockDelay=ENV.lock
P.freshTime=ENV.freshLimit
P.color={}
for _=1,7 do
P.color[_]=SKIN.libColor[ENV.skin[_]]
end
P.life=ENV.life
P.keyAvailable={true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true}
if ENV.noTele then
for i=11,20 do
if i~=14 then
P.keyAvailable[i]=false
end
end
end
if not ENV.Fkey then
P.keyAvailable[9]=false
end
for _,v in next,ENV.keyCancel do
P.keyAvailable[v]=false
end
P:setInvisible(
ENV.visible=="show"and -1 or
ENV.visible=="time"and 300 or
ENV.visible=="fast"and 20 or
ENV.visible=="none"and 0
)
P:set20G(P._20G)
P:setHold(ENV.holdCount)
P:setNext(ENV.nextCount,ENV.nextStartPos>1)
P:setRS(ENV.RS)
if type(ENV.mission)=="table"then
P.curMission=1
end
ENV.das=max(ENV.das,ENV.mindas)
ENV.arr=max(ENV.arr,ENV.minarr)
ENV.sdarr=max(ENV.sdarr,ENV.minsdarr)
if ENV.sequence~="bag"and ENV.sequence~="loop"then
ENV.bagLine=false
else
ENV.bagLen=#ENV.bag
end
if ENV.nextCount==0 then ENV.nextPos=false end
if P.mini then
ENV.lockFX=nil
ENV.dropFX=nil
ENV.moveFX=nil
ENV.clearFX=nil
ENV.splashFX=nil
ENV.shakeFX=nil
ENV.text=nil
else
if ENV.lockFX==0 then ENV.lockFX=nil end
if ENV.dropFX==0 then ENV.dropFX=nil end
if ENV.moveFX==0 then ENV.moveFX=nil end
if ENV.clearFX==0 then ENV.clearFX=nil end
if ENV.splashFX==0 then ENV.splashFX=nil end
if ENV.shakeFX==0 then ENV.shakeFX=nil end
end
if ENV.ghost==0 then ENV.ghost=nil end
if ENV.center==0 then ENV.center=nil end
end
--------------------------</Lib Func>--------------------------
--------------------------<Public>--------------------------
function PLY.check_lineReach(P)
if P.stat.row>=P.gameEnv.target then
P:win("finish")
end
end
function PLY.check_attackReach(P)
if P.stat.atk>=P.gameEnv.target then
P:win("finish")
end
end
local DemoEnv={
face={0,0,0,0,0,0,0},
das=10,arr=2,sddas=2,sdarr=2,
drop=60,lock=60,
wait=10,fall=20,
highCam=false,
life=1e99,
noMod=true,
}
function PLY.newDemoPlayer(id)
local P=newEmptyPlayer(id)
P.type="computer"
P.sound=true
P.demo=true
P.draw=PLY.draw.demo
P.control=true
GAME.modeEnv=DemoEnv
loadGameEnv(P)
applyGameEnv(P)
prepareSequence(P)
P:loadAI{
type="CC",
next=5,
hold=true,
delay=30,
delta=6,
bag="bag",
node=100000,
}
P:popNext()
end
function PLY.newRemotePlayer(id,mini)
local P=newEmptyPlayer(id,mini)
P.type="remote"
P.update=PLY.update.remote_alive
P.stream={}
P.streamProgress=1
loadGameEnv(P)
applyGameEnv(P)
prepareSequence(P)
end
function PLY.newAIPlayer(id,AIdata,mini)
local P=newEmptyPlayer(id,mini)
P.type="computer"
loadGameEnv(P)
local ENV=P.gameEnv
ENV.face={0,0,0,0,0,0,0}
ENV.skin={1,7,11,3,14,4,9}
applyGameEnv(P)
prepareSequence(P)
P:loadAI(AIdata)
end
function PLY.newPlayer(id,mini)
local P=newEmptyPlayer(id,mini)
P.type="human"
P.sound=true
loadGameEnv(P)
applyGameEnv(P)
prepareSequence(P)
end
--------------------------</Public>--------------------------
return PLY