联网推进36,部分功能已经可用

This commit is contained in:
MrZ626
2021-02-07 03:50:24 +08:00
parent eec05e7eb6
commit d86eb59963
22 changed files with 454 additions and 100 deletions

View File

@@ -349,11 +349,6 @@ function draw.norm(P)
--Field-related things
gc_push("transform")
gc_translate(150,0)
if P.userName then
setFont(30)
gc_setColor(1,1,1)
mStr(P.userName,150,-60)
end
--Things shake with field
gc_push("transform")
@@ -479,8 +474,8 @@ function draw.norm(P)
gc_rectangle("fill",-14,599,11,-b*.6)
gc_setColor(P.b2b<40 and COLOR.white or P.b2b<=800 and COLOR.lRed or COLOR.lBlue)
gc_rectangle("fill",-14,599,11,-a*.6)
gc_setColor(1,1,1)
if t%.5<.3 then
gc_setColor(1,1,1)
gc_rectangle("fill",-15,b<40 and 568.5 or 118.5,13,3)
end
@@ -638,13 +633,309 @@ function draw.norm(P)
--Draw starting counter
gc_setColor(1,1,1)
if GAME.frame<180 then
local count=179-GAME.frame
if GAME.net and GAME.frame==0 then
setFont(70)
mStr(text.waiting,305,220)
else
local count=179-GAME.frame
gc_push("transform")
gc_translate(305,220)
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
end
gc_pop()
end
function draw.remote_norm(P)
local _
local ENV=P.gameEnv
local FBN,FUP=P.fieldBeneath,P.fieldUp
local t=TIME()
gc_push("transform")
gc_translate(P.x,P.y)gc_scale(P.size)
--Field-related things
gc_push("transform")
gc_translate(150,0)
--Draw username
setFont(30)
gc_setColor(1,1,1)
mStr(P.userName,150,-60)
--Things shake with field
gc_push("transform")
gc_translate(305,220)
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_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,ENV.grid)end
--In-field things
gc_push("transform")
if ENV.flipBoard then
if ENV.flipBoard=="U-D"then
gc_translate(0,590)
gc_scale(1,-1)
elseif ENV.flipBoard=="L-R"then
gc_translate(300,0)
gc_scale(-1,1)
elseif ENV.flipBoard=="180"then
gc_translate(300,590)
gc_scale(-1,-1)
end
end
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,-FUP-FBN-10)
--Draw field
drawField(P)
--Draw spawn line
gc_setColor(1,sin(t)*.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
local trans=P.lockDelay/ENV.lock
local centerX=30*(P.curX+P.sc[2])-15
--Draw ghost & rotation center
if ENV.ghost then drawGhost(P,curColor)end
if ENV.center and ENV.ghost then
gc_setColor(1,1,1,trans*ENV.center)
gc_draw(IMG.spinCenter,centerX,-30*(P.ghoY+P.sc[1])+15,nil,nil,nil,4,4)
end
local dy=ENV.smooth and P.ghoY~=P.curY and(P.dropDelay/ENV.drop-1)*30 or 0
gc_translate(0,-dy)
--Draw block & rotation center
if ENV.block then
drawBlockOutline(P,SKIN.curText[curColor],trans)
drawBlock(P,curColor)
end
if ENV.center and ENV.block then
gc_setColor(1,1,1,ENV.center)
gc_draw(IMG.spinCenter,centerX,-30*(P.curY+P.sc[1])+15,nil,nil,nil,4,4)
end
gc_translate(0,dy)
end
--Draw next preview
if ENV.nextPos and P.nextQueue[1]then
drawNextPreview(P,P.nextQueue[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 a=math.sin((t-i)*30)*.5+.5
local c1,c2=attackColor[A.lv][1],attackColor[A.lv][2]
gc_setColor(c1[1]*a+c2[1]*(1-a),c1[2]*a+c2[2]*(1-a),c1[3]*a+c2[3]*(1-a))
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*.6)
gc_setColor(P.b2b<40 and COLOR.white or P.b2b<=800 and COLOR.lRed or COLOR.lBlue)
gc_rectangle("fill",-14,599,11,-a*.6)
if t%.5<.3 then
gc_setColor(1,1,1)
gc_rectangle("fill",-15,b<40 and 568.5 or 118.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(P.freshTime,15)do
gc_rectangle("fill",x,615,14,5)
x=x+20
end
--Draw Hold
P:drawHold()
--Draw Next(s)
P:drawNext()
--Draw target selecting pad
if GAME.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(35)
for i=1,4 do
gc_rectangle("line",RCPB[2*i-1],RCPB[2*i],90,35,8,4)
gc.printf(text.atkModeName[i],RCPB[2*i-1]-4,RCPB[2*i]+4,200,"center",nil,.5)
end
end
if ENV.hideBoard then
gc.stencil(hideBoardStencil[ENV.hideBoard],"replace",1)
gc.setStencilTest("equal",1)
gc_setLineWidth(20)
for i=0,24 do
gc_setColor(COLOR.rainbow_grey(t*.626+i*.1))
gc_line(20*i-190,-2,20*i+10,602)
end
gc.setStencilTest()
end
gc_pop()
--Bonus texts
TEXT.draw(P.bonus)
gc_pop()
--Speed dials
setFont(25)
drawDial(510,510,P.dropSpeed)
drawDial(555,565,P.keySpeed)
local S=P.stat
--Score & Time
setFont(25)
gc_setColor(0,0,0,.3)
gc_print(P.score1,18,509)
gc_print(format("%.2f",S.time),18,539)
gc_setColor(COLOR.lYellow)gc_print(P.score1,20,510)
gc_setColor(COLOR.sky)gc_print(format("%.2f",S.time),20,540)
--FinesseCombo
if P.finesseCombo>2 then
_=P.finesseComboTime
local str=P.finesseCombo.."x"
if S.finesseRate==5*S.piece then
gc_setColor(.9,.9,.3,_*.2)
elseif S.maxFinesseCombo==S.piece then
gc_setColor(.7,.7,1,_*.2)
else
gc_setColor(1,1,1,_*.2)
end
gc_print(str,20,570)
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,595,nil,.8)
end
else
gc_draw(IMG.lifeIcon,475,595,nil,.8)
setFont(20)
gc_print("x",503,595)
gc_print(P.life,517,595)
end
end
--Other messages
gc_setColor(1,1,1)
if GAME.curMode.mesDisp then
GAME.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(t*6.26),.4)
else
gc_setColor(1,1,1)
end
gc_print(missionEnum[L[P.curMission]],85,110)
--Draw next mission
setFont(20)
for i=1,3 do
local m=L[P.curMission+i]
if m then
m=missionEnum[m]
gc_print(m,87-28*i,117)
else
break
end
end
end
--Draw starting counter
gc_setColor(1,1,1)
if GAME.frame<180 then
if GAME.frame==0 then
setFont(70)
mStr(text.waiting,305,220)
else
local count=179-GAME.frame
gc_push("transform")
gc_translate(305,220)
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
end
gc_pop()
end

View File

@@ -358,12 +358,15 @@ function PLY.newRemotePlayer(id,mini,playerData)
P.type="remote"
P.update=PLY.update.remote_alive
P.draw=PLY.draw.remote_norm
P.stream={}
P.streamProgress=1
playerData.p=P
P.userName=playerData.name
P.userID=playerData.id
P.subID=playerData.sid
loadRemoteEnv(P,playerData.conf or{})
applyGameEnv(P)

View File

@@ -234,11 +234,11 @@ end
function Player.getHolePos(P)--Get a good garbage-line hole position
if P.garbageBeneath==0 then
return P:RND(10)
return generateLine(P:RND(10))
else
local p=P:RND(10)
if P.field[1][p]<=0 then
return P:RND(10)
return generateLine(P:RND(10))
end
return p
end
@@ -248,7 +248,7 @@ function Player.garbageRelease(P)--Check garbage buffer and try to release them
while true do
local A=P.atkBuffer[n]
if A and A.countdown<=0 and not A.sent then
P:garbageRise(19+A.lv,A.amount,A.pos)
P:garbageRise(19+A.lv,A.amount,A.line)
P.atkBuffer.sum=P.atkBuffer.sum-A.amount
A.sent,A.time=true,0
P.stat.pend=P.stat.pend+A.amount
@@ -260,13 +260,15 @@ function Player.garbageRelease(P)--Check garbage buffer and try to release them
end
if flag and P.AI_mode=="CC"then CC.updateField(P)end
end
function Player.garbageRise(P,color,amount,pos)--Release n-lines garbage to field
function Player.garbageRise(P,color,amount,line)--Release n-lines garbage to field
local _
local t=P.showTime*2
for _=1,amount do
ins(P.field,1,FREEROW.get(color,true))
ins(P.field,1,FREEROW.get(0,true))
ins(P.visTime,1,FREEROW.get(t))
P.field[1][pos]=0
for i=1,10 do
P.field[1][i]=bit.rshift(line,i-1)%2==1 and color or 0
end
end
P.fieldBeneath=P.fieldBeneath+amount*30
if P.cur then
@@ -336,22 +338,36 @@ function Player.ifoverlap(P,bk,x,y)
end
end
end
function Player.attack(P,R,send,time,...)
if SETTING.atkFX>0 then
P:createBeam(R,send,time,...)
end
function Player.attack(P,R,send,time,line,fromStream)
print(string.format("P%d attack P%d with %d lines, %d frames, line data:%d",P.id,R.id,send,time,line))
if GAME.net then
if P.type=="human"then
--TODO
if P.type=="human"then--Local player attack others
ins(GAME.rep,GAME.frame+1)
ins(GAME.rep,
R.subID+
send*0x100+
time*0x10000+
line*0x100000000+
0x2000000000000
)
end
if R.type=="human"then
--TODO
if fromStream and R.type=="human"then--Local player receiving lines
ins(GAME.rep,GAME.frame+1)
ins(GAME.rep,
P.subID+
send*0x100+
time*0x10000+
line*0x100000000+
0x1000000000000
)
R:receive(P,send,time,line)
end
else
R:receive(P,send,time)
R:receive(P,send,time,line)
end
end
function Player.receive(P,A,send,time)
function Player.receive(P,A,send,time,line)
print(string.format("P%d was attacked by P%d's %d lines, %d frames, line data:%d",P.id,A.id,send,time,line))
P.lastRecv=A
local B=P.atkBuffer
if B.sum<26 then
@@ -362,7 +378,7 @@ function Player.receive(P,A,send,time)
B[i+1]=B[i]
end
B[k]={
pos=A:RND(10),
line=line,
amount=send,
countdown=time,
cd0=time,
@@ -1204,7 +1220,7 @@ do--Player.drop(P)--Place piece
end
P:showText(text.clear[cc],0,-30,35,"appear",(8-cc)*.3)
atk=cc-.5
sendTime=20+atk*20
sendTime=20+int(atk*20)
cscore=cscore+clearSCR[cc]
end
@@ -1250,7 +1266,10 @@ do--Player.drop(P)--Place piece
local M=#P.atker
if M>0 then
for i=1,M do
P:attack(P.atker[i],send,C.color)
P:attack(P.atker[i],send,sendTime,generateLine(P:RND(10)))
if SETTING.atkFX>0 then
P:createBeam(P.atker[i],send,C.color)
end
end
else
T=randomTarget(P)
@@ -1263,7 +1282,10 @@ do--Player.drop(P)--Place piece
T=randomTarget(P)
end
if T then
P:attack(T,send,C.color)
P:attack(T,send,sendTime,generateLine(P:RND(10)))
if SETTING.atkFX>0 then
P:createBeam(T,send,C.color)
end
end
end
if P.sound and send>3 then SFX.play("emit",min(send,7)*.1)end

View File

@@ -380,20 +380,41 @@ function update.remote_alive(P,dt)
local eventTime=P.stream[pos]
if eventTime then
if P.stat.frame==eventTime then
local key=P.stream[pos+1]
if key==0 then--Just wait
elseif key<=32 then--Press key
P:pressKey(key)
elseif key<=64 then--Release key
P:releaseKey(key-32)
elseif key>1023 then--Receiving garbage
local line=key%1024
local amount=int(key/1024)%256
local color=int(key/262144)%256
local sid=int(key/67108864)%256
local time=int(key/17179869184)%256
P:receive()
--TODO
local event=P.stream[pos+1]
if event==0 then--Just wait
elseif event<=32 then--Press key
P:pressKey(event)
elseif event<=64 then--Release key
P:releaseKey(event-32)
elseif event>0x2000000000000 then--Sending lines
local sid=event%0x100
local amount=int(event/0x100)%0x100
local time=int(event/0x10000)%0x10000
local line=int(event/0x100000000)%0x10000
local L=PLAYERS.alive
for i=1,#L do
if L[i].subID==sid then
P:attack(L[i],amount,time,line,true)
if SETTING.atkFX>0 then
P:createBeam(L[i],amount,P.cur.color)
end
break
end
end
elseif event>0x1000000000000 then--Receiving lines
local L=PLAYERS.alive
local sid=event%0x100
for i=1,#L do
if L[i].subID==sid then
P:receive(
L[i],
int(event/0x100)%0x100,--amount
int(event/0x10000)%0x10000,--time
int(event/0x100000000)%0x10000--line
)
break
end
end
end
P.streamProgress=pos+2
goto readNext