Task模块全部改用协程

This commit is contained in:
MrZ626
2020-12-04 16:09:17 +08:00
parent 6f49341ba5
commit 98629be450
21 changed files with 607 additions and 474 deletions

View File

@@ -1,4 +1,6 @@
local rem=table.remove local rem=table.remove
local ct=coroutine
local assert=assert
local tasks={} local tasks={}
local TASK={ local TASK={
@@ -10,24 +12,40 @@ end
function TASK.update() function TASK.update()
for i=#tasks,1,-1 do for i=#tasks,1,-1 do
local T=tasks[i] local T=tasks[i]
if T.code(T.data)then assert(ct.resume(T.thread))
if T.data.net then if ct.status(T.thread)=="dead"then
if T.net then
TASK.netTaskCount=TASK.netTaskCount-1 TASK.netTaskCount=TASK.netTaskCount-1
end end
rem(tasks,i) rem(tasks,i)
end end
end end
end end
function TASK.new(code,data) function TASK.new(code,...)
tasks[#tasks+1]={ local thread=ct.create(code)
code=code, if ...~=nil then ct.resume(thread,...)end
data=data, if ct.status(thread)~="dead"then
} tasks[#tasks+1]={
thread=thread,
code=code,
}
end
end
function TASK.newNet(code,...)
local thread=ct.create(code)
if ...~=nil then ct.resume(thread,...)end
if ct.status(thread)~="dead"then
tasks[#tasks+1]={
thread=thread,
code=code,
net=true,
}
end
end end
function TASK.changeCode(c1,c2) function TASK.changeCode(c1,c2)
for i=#tasks,1,-1 do for i=#tasks,1,-1 do
if tasks[i].code==c1 then if tasks[i].thread==c1 then
tasks[i].code=c2 tasks[i].thread=c2
end end
end end
end end

View File

@@ -548,13 +548,12 @@ do--httpRequest & wsConnect
client and function(tick,path,method,header,body) client and function(tick,path,method,header,body)
local task,err=client.httpraw{ local task,err=client.httpraw{
url="http://krakens.tpddns.cn:10026"..path, url="http://krakens.tpddns.cn:10026"..path,
-- url="http://127.0.0.1:10026"..path,
method=method or"GET", method=method or"GET",
header=header, header=header,
body=body, body=body,
} }
if task then if task then
TASK.new(tick,{task=task,time=0,net=true}) TASK.newNet(tick,task)
else else
LOG.print("NETlib error: "..err,"warn") LOG.print("NETlib error: "..err,"warn")
end end
@@ -569,12 +568,10 @@ do--httpRequest & wsConnect
local task,err=client.wsraw{ local task,err=client.wsraw{
url="ws://krakens.tpddns.cn:10026"..path, url="ws://krakens.tpddns.cn:10026"..path,
origin="krakens.tpddns.cn", origin="krakens.tpddns.cn",
-- url="ws://127.0.0.1:10026"..path,
-- origin="127.0.0.1",
header=header, header=header,
} }
if task then if task then
TASK.new(tick,{wsconntask=task,time=0,net=true}) TASK.newNet(tick,task)
else else
LOG.print("NETlib error: "..err,"warn") LOG.print("NETlib error: "..err,"warn")
end end

View File

@@ -487,7 +487,7 @@ function resetGameData(replaying)
STAT.game=STAT.game+1 STAT.game=STAT.game+1
FREEROW.reset(30*#PLAYERS) FREEROW.reset(30*#PLAYERS)
TASK.removeTask_code(TICK.showMods) TASK.removeTask_code(TICK.showMods)
TASK.new(TICK.showMods,{0}) TASK.new(TICK.showMods)
SFX.play("ready") SFX.play("ready")
collectgarbage() collectgarbage()
end end

View File

@@ -23,11 +23,14 @@ return{
freshLimit=15, freshLimit=15,
dropPiece=score, dropPiece=score,
task=function(P) task=function(P)
while true do
coroutine.yield()
if P.stat.frame>=53.5*60 then if P.stat.frame>=53.5*60 then
P.modeData.point=min(P.modeData.point+16,80) P.modeData.point=min(P.modeData.point+16,80)
P.modeData.event=sectionName[int(P.modeData.point*.1)+1] P.modeData.event=sectionName[int(P.modeData.point*.1)+1]
P:win("finish") P:win("finish")
return true return
end
end end
end, end,
bg="tunnel",bgm="far", bg="tunnel",bgm="far",

View File

@@ -6,29 +6,31 @@ return{
freshLimit=15, freshLimit=15,
pushSpeed=2, pushSpeed=2,
task=function(P) task=function(P)
if not(P.control and SCN.cur=="play")then return end while true do
if P.atkBuffer.sum==0 then coroutine.yield()
local p=#P.atkBuffer+1 if P.control and SCN.cur=="play"and P.atkBuffer.sum==0 then
local B,D=P.atkBuffer,P.modeData local p=#P.atkBuffer+1
local t local B,D=P.atkBuffer,P.modeData
if D.event<20 then local t
t=1500-30*D.event--1500~900 if D.event<20 then
B[p]= {pos=P:RND(4,7),amount=12,countdown=t,cd0=t,time=0,sent=false,lv=3} t=1500-30*D.event--1500~900
B[p+1]= {pos=P:RND(3,8),amount=10,countdown=t,cd0=t,time=0,sent=false,lv=4} B[p]= {pos=P:RND(4,7),amount=12,countdown=t,cd0=t,time=0,sent=false,lv=3}
else B[p+1]= {pos=P:RND(3,8),amount=10,countdown=t,cd0=t,time=0,sent=false,lv=4}
t=900-10*(D.event-20)--900~600 else
B[p]= {pos=P:RND(10),amount=14,countdown=t,cd0=t,time=0,sent=false,lv=4} t=900-10*(D.event-20)--900~600
B[p+1]= {pos=P:RND(4,7),amount=8,countdown=t,cd0=t,time=0,sent=false,lv=5} B[p]= {pos=P:RND(10),amount=14,countdown=t,cd0=t,time=0,sent=false,lv=4}
end B[p+1]= {pos=P:RND(4,7),amount=8,countdown=t,cd0=t,time=0,sent=false,lv=5}
B.sum=B.sum+22 end
P.stat.recv=P.stat.recv+22 B.sum=B.sum+22
D.event=D.event+1 P.stat.recv=P.stat.recv+22
if D.event%10==0 then D.event=D.event+1
if D.event==20 then if D.event%10==0 then
P:showTextF(text.great,0,-140,100,"appear",.6) if D.event==20 then
P.gameEnv.pushSpeed=3 P:showTextF(text.great,0,-140,100,"appear",.6)
elseif D.event==50 then P.gameEnv.pushSpeed=3
P:showTextF(text.maxspeed,0,-140,100,"appear",.6) elseif D.event==50 then
P:showTextF(text.maxspeed,0,-140,100,"appear",.6)
end
end end
end end
end end

View File

@@ -5,37 +5,39 @@ return{
fall=8, fall=8,
freshLimit=15, freshLimit=15,
task=function(P) task=function(P)
if not(P.control and SCN.cur=="play")then return end while true do
if P.atkBuffer.sum<4 then coroutine.yield()
local p=#P.atkBuffer+1 if P.control and SCN.cur=="play"and P.atkBuffer.sum<4 then
local B,D=P.atkBuffer,P.modeData local p=#P.atkBuffer+1
local s local B,D=P.atkBuffer,P.modeData
local t=800-10*D.event--800~700~600~500 local s
if D.event<10 then local t=800-10*D.event--800~700~600~500
B[p]= {pos=P:RND(5,6),amount=9,countdown=t,cd0=t,time=0,sent=false,lv=3} if D.event<10 then
B[p+1]= {pos=P:RND(4,7),amount=11,countdown=t,cd0=t+62,time=0,sent=false,lv=4} B[p]= {pos=P:RND(5,6),amount=9,countdown=t,cd0=t,time=0,sent=false,lv=3}
s=20 B[p+1]= {pos=P:RND(4,7),amount=11,countdown=t,cd0=t+62,time=0,sent=false,lv=4}
elseif D.event<20 then s=20
B[p]= {pos=P:RND(3,8),amount=11,countdown=t,cd0=t,time=0,sent=false,lv=4} elseif D.event<20 then
B[p+1]= {pos=P:RND(4,7),amount=13,countdown=t,cd0=t+62,time=0,sent=false,lv=5} B[p]= {pos=P:RND(3,8),amount=11,countdown=t,cd0=t,time=0,sent=false,lv=4}
s=24 B[p+1]= {pos=P:RND(4,7),amount=13,countdown=t,cd0=t+62,time=0,sent=false,lv=5}
else s=24
B[p]= {pos=P:RND(2)*9-8,amount=14,countdown=t,cd0=t,time=0,sent=false,lv=5} else
B[p+1]= {pos=P:RND(3,8),amount=14,countdown=t+62,cd0=t,time=0,sent=false,lv=5} B[p]= {pos=P:RND(2)*9-8,amount=14,countdown=t,cd0=t,time=0,sent=false,lv=5}
s=28 B[p+1]= {pos=P:RND(3,8),amount=14,countdown=t+62,cd0=t,time=0,sent=false,lv=5}
end s=28
B.sum=B.sum+s end
P.stat.recv=P.stat.recv+s B.sum=B.sum+s
D.event=D.event+1 P.stat.recv=P.stat.recv+s
if D.event%10==0 then D.event=D.event+1
if D.event==10 then if D.event%10==0 then
P:showTextF(text.great,0,-140,100,"appear",.6) if D.event==10 then
P.gameEnv.pushSpeed=4 P:showTextF(text.great,0,-140,100,"appear",.6)
elseif D.event==20 then P.gameEnv.pushSpeed=4
P:showTextF(text.awesome,0,-140,100,"appear",.6) elseif D.event==20 then
P.gameEnv.pushSpeed=5 P:showTextF(text.awesome,0,-140,100,"appear",.6)
elseif D.event==30 then P.gameEnv.pushSpeed=5
P:showTextF(text.maxspeed,0,-140,100,"appear",.6) elseif D.event==30 then
P:showTextF(text.maxspeed,0,-140,100,"appear",.6)
end
end end
end end
end end

View File

@@ -8,31 +8,35 @@ return{
freshLimit=15, freshLimit=15,
pushSpeed=2, pushSpeed=2,
task=function(P) task=function(P)
if not(P.control and SCN.cur=="play")then return end while true do
P.modeData.counter=P.modeData.counter+1 coroutine.yield()
local t=240-2*P.modeData.event if P.control and SCN.cur=="play"then
if P.modeData.counter>=t then P.modeData.counter=P.modeData.counter+1
P.modeData.counter=0 local t=240-2*P.modeData.event
for _=1,4 do if P.modeData.counter>=t then
P.atkBuffer[#P.atkBuffer+1]={pos=P:RND(10),amount=1,countdown=5*t,cd0=5*t,time=0,sent=false,lv=2} P.modeData.counter=0
end for _=1,4 do
P.atkBuffer.sum=P.atkBuffer.sum+4 P.atkBuffer[#P.atkBuffer+1]={pos=P:RND(10),amount=1,countdown=5*t,cd0=5*t,time=0,sent=false,lv=2}
P.stat.recv=P.stat.recv+4 end
local D=P.modeData P.atkBuffer.sum=P.atkBuffer.sum+4
if D.event<75 then P.stat.recv=P.stat.recv+4
D.event=D.event+1 local D=P.modeData
D.point=int(144e3/(240-2*D.event))*.1 if D.event<75 then
if D.event==25 then D.event=D.event+1
P:showTextF(text.great,0,-140,100,"appear",.6) D.point=int(144e3/(240-2*D.event))*.1
P.gameEnv.pushSpeed=3 if D.event==25 then
P.dropDelay,P.gameEnv.drop=4,4 P:showTextF(text.great,0,-140,100,"appear",.6)
elseif D.event==50 then P.gameEnv.pushSpeed=3
P:showTextF(text.awesome,0,-140,100,"appear",.6) P.dropDelay,P.gameEnv.drop=4,4
P.gameEnv.pushSpeed=4 elseif D.event==50 then
P.dropDelay,P.gameEnv.drop=3,3 P:showTextF(text.awesome,0,-140,100,"appear",.6)
elseif D.event==75 then P.gameEnv.pushSpeed=4
P:showTextF(text.maxspeed,0,-140,100,"appear",.6) P.dropDelay,P.gameEnv.drop=3,3
P.dropDelay,P.gameEnv.drop=2,2 elseif D.event==75 then
P:showTextF(text.maxspeed,0,-140,100,"appear",.6)
P.dropDelay,P.gameEnv.drop=2,2
end
end
end end
end end
end end

View File

@@ -8,33 +8,37 @@ return{
freshLimit=15, freshLimit=15,
pushSpeed=1, pushSpeed=1,
task=function(P) task=function(P)
if not(P.control and SCN.cur=="play")then return end while true do
P.modeData.counter=P.modeData.counter+1 coroutine.yield()
local t=360-P.modeData.event*2 if P.control and SCN.cur=="play"then
if P.modeData.counter>=t then P.modeData.counter=P.modeData.counter+1
P.modeData.counter=0 local t=360-P.modeData.event*2
for _=1,3 do if P.modeData.counter>=t then
P.atkBuffer[#P.atkBuffer+1]={pos=P:RND(2,9),amount=1,countdown=2*t,cd0=2*t,time=0,sent=false,lv=1} P.modeData.counter=0
end for _=1,3 do
P.atkBuffer.sum=P.atkBuffer.sum+3 P.atkBuffer[#P.atkBuffer+1]={pos=P:RND(2,9),amount=1,countdown=2*t,cd0=2*t,time=0,sent=false,lv=1}
P.stat.recv=P.stat.recv+3 end
local D=P.modeData P.atkBuffer.sum=P.atkBuffer.sum+3
if D.event<90 then P.stat.recv=P.stat.recv+3
D.event=D.event+1 local D=P.modeData
D.point=int(108e3/(360-D.event*2))*.1 if D.event<90 then
if D.event==25 then D.event=D.event+1
P:showTextF(text.great,0,-140,100,"appear",.6) D.point=int(108e3/(360-D.event*2))*.1
P.gameEnv.pushSpeed=2 if D.event==25 then
P.dropDelay,P.gameEnv.drop=20,20 P:showTextF(text.great,0,-140,100,"appear",.6)
elseif D.event==50 then P.gameEnv.pushSpeed=2
P:showTextF(text.awesome,0,-140,100,"appear",.6) P.dropDelay,P.gameEnv.drop=20,20
P.gameEnv.pushSpeed=3 elseif D.event==50 then
P.dropDelay,P.gameEnv.drop=10,10 P:showTextF(text.awesome,0,-140,100,"appear",.6)
elseif D.event==90 then P.gameEnv.pushSpeed=3
P.dropDelay,P.gameEnv.drop=5,5 P.dropDelay,P.gameEnv.drop=10,10
P:showTextF(text.maxspeed,0,-140,100,"appear",.6) elseif D.event==90 then
P.dropDelay,P.gameEnv.drop=5,5
P:showTextF(text.maxspeed,0,-140,100,"appear",.6)
end
end
end end
end end
end end
end, end,
bg="rainbow2",bgm="storm", bg="rainbow2",bgm="storm",

View File

@@ -1,4 +1,3 @@
local max=math.max
return{ return{
color=COLOR.magenta, color=COLOR.magenta,
env={ env={
@@ -6,14 +5,18 @@ return{
fall=20, fall=20,
freshLimit=15, freshLimit=15,
task=function(P) task=function(P)
if not(P.control and SCN.cur=="play")then return end while true do
local D=P.modeData coroutine.yield()
D.counter=D.counter+1 if P.control and SCN.cur=="play"then
if D.counter>=max(90,180-D.event)then local D=P.modeData
P:garbageRise(21,1,P:getHolePos()) D.counter=D.counter+1
P.stat.recv=P.stat.recv+1 if D.counter>=math.max(90,180-D.event)then
D.counter=0 P:garbageRise(21,1,P:getHolePos())
D.event=D.event+1 P.stat.recv=P.stat.recv+1
D.counter=0
D.event=D.event+1
end
end
end end
end, end,
bg="bg2",bgm="down", bg="bg2",bgm="down",

View File

@@ -1,18 +1,21 @@
local max=math.max
return{ return{
color=COLOR.lYellow, color=COLOR.lYellow,
env={ env={
drop=10,lock=30, drop=10,lock=30,
freshLimit=15, freshLimit=15,
task=function(P) task=function(P)
if not(P.control and SCN.cur=="play")then return end while true do
local D=P.modeData coroutine.yield()
D.counter=D.counter+1 if P.control and SCN.cur=="play"then
if D.counter>=max(30,80-.3*D.event)then local D=P.modeData
P:garbageRise(20+D.event%5,1,P:getHolePos()) D.counter=D.counter+1
P.stat.recv=P.stat.recv+1 if D.counter>=math.max(30,80-.3*D.event)then
D.counter=0 P:garbageRise(20+D.event%5,1,P:getHolePos())
D.event=D.event+1 P.stat.recv=P.stat.recv+1
D.counter=0
D.event=D.event+1
end
end
end end
end, end,
bg="bg2",bgm="down", bg="bg2",bgm="down",

View File

@@ -7,14 +7,17 @@ local PClist=require"parts/modes/PClist"
local PCtype={[0]=1,2,3,2,3} local PCtype={[0]=1,2,3,2,3}
local function task_PC(P) local function task_PC(P)
P.modeData.counter=P.modeData.counter+1 local D=P.modeData
if P.modeData.counter==26 then while true do
local base=PCbase[P.modeData.type] coroutine.yield()
P:pushLineList(base[P:RND(#base)],P.modeData.symmetry) D.counter=D.counter+1
return true if D.counter==26 then
local base=PCbase[D.type]
P:pushLineList(base[P:RND(#base)],D.symmetry)
end
end end
end end
local function newPC(P) local function check(P)
local r=P.field local r=P.field
if r[1]then if r[1]then
r=r[#r] r=r[#r]
@@ -55,7 +58,7 @@ return{
fall=20, fall=20,
sequence="none", sequence="none",
freshLimit=15, freshLimit=15,
dropPiece=newPC, dropPiece=check,
RS="SRS", RS="SRS",
ospin=false, ospin=false,
bg="rgb",bgm="oxygen", bg="rgb",bgm="oxygen",
@@ -63,7 +66,7 @@ return{
pauseLimit=true, pauseLimit=true,
load=function() load=function()
PLY.newPlayer(1,340,15) PLY.newPlayer(1,340,15)
newPC(PLAYERS[1]) check(PLAYERS[1])
end, end,
mesDisp=function(P) mesDisp=function(P)
setFont(75) setFont(75)

View File

@@ -13,14 +13,17 @@ local PCtype={
3, 3,
} }
local function task_PC(P) local function task_PC(P)
P.modeData.counter=P.modeData.counter+1 local D=P.modeData
if P.modeData.counter==26 then while true do
local base=PCbase[P.modeData.type] D.counter=D.counter+1
P:pushLineList(base[P:RND(#base)],P.modeData.symmetry) if D.counter==26 then
return true local base=PCbase[D.type]
P:pushLineList(base[P:RND(#base)],D.symmetry)
end
coroutine.yield()
end end
end end
local function newPC(P) local function check(P)
local r=P.field local r=P.field
if r[1]then if r[1]then
r=r[#r] r=r[#r]
@@ -47,7 +50,7 @@ return{
drop=120,lock=180, drop=120,lock=180,
fall=20, fall=20,
sequence="none", sequence="none",
dropPiece=newPC, dropPiece=check,
RS="SRS", RS="SRS",
ospin=false, ospin=false,
bg="rgb",bgm="oxygen", bg="rgb",bgm="oxygen",
@@ -55,7 +58,7 @@ return{
pauseLimit=true, pauseLimit=true,
load=function() load=function()
PLY.newPlayer(1,340,15) PLY.newPlayer(1,340,15)
newPC(PLAYERS[1]) check(PLAYERS[1])
end, end,
mesDisp=function(P) mesDisp=function(P)
setFont(75) setFont(75)

View File

@@ -1,19 +1,22 @@
local max=math.max
return{ return{
color=COLOR.cyan, color=COLOR.cyan,
env={ env={
drop=30,lock=45, drop=30,lock=45,
freshLimit=10, freshLimit=10,
task=function(P) task=function(P)
if not(P.control and SCN.cur=="play")then return end while true do
P.modeData.counter=P.modeData.counter+1 coroutine.yield()
if P.modeData.counter>=max(60,150-2*P.modeData.event)and P.atkBuffer.sum<4 then if P.control and SCN.cur=="play"then
P.atkBuffer[#P.atkBuffer+1]={pos=P:RND(10),amount=1,countdown=30,cd0=30,time=0,sent=false,lv=1} P.modeData.counter=P.modeData.counter+1
P.atkBuffer.sum=P.atkBuffer.sum+1 if P.modeData.counter>=math.max(60,150-2*P.modeData.event)and P.atkBuffer.sum<4 then
P.stat.recv=P.stat.recv+1 P.atkBuffer[#P.atkBuffer+1]={pos=P:RND(10),amount=1,countdown=30,cd0=30,time=0,sent=false,lv=1}
if P.modeData.event==45 then P:showTextF(text.maxspeed,0,-140,100,"appear",.6)end P.atkBuffer.sum=P.atkBuffer.sum+1
P.modeData.counter=0 P.stat.recv=P.stat.recv+1
P.modeData.event=P.modeData.event+1 if P.modeData.event==45 then P:showTextF(text.maxspeed,0,-140,100,"appear",.6)end
P.modeData.counter=0
P.modeData.event=P.modeData.event+1
end
end
end end
end, end,
bg="glow",bgm="new era", bg="glow",bgm="new era",

View File

@@ -1,25 +1,28 @@
local max=math.max
return{ return{
color=COLOR.magenta, color=COLOR.magenta,
env={ env={
drop=30,lock=45, drop=30,lock=45,
freshLimit=10, freshLimit=10,
task=function(P) task=function(P)
if not(P.control and SCN.cur=="play")then return end while true do
P.modeData.counter=P.modeData.counter+1 coroutine.yield()
local B=P.atkBuffer if P.control and SCN.cur=="play"then
if P.modeData.counter>=max(60,180-2*P.modeData.event)and B.sum<15 then P.modeData.counter=P.modeData.counter+1
B[#B+1]= local B=P.atkBuffer
P.modeData.event%3<2 and if P.modeData.counter>=math.max(60,180-2*P.modeData.event)and B.sum<15 then
{pos=P:RND(10),amount=1,countdown=0,cd0=0,time=0,sent=false,lv=1} B[#B+1]=
or P.modeData.event%3<2 and
{pos=P:RND(10),amount=3,countdown=60,cd0=60,time=0,sent=false,lv=2} {pos=P:RND(10),amount=1,countdown=0,cd0=0,time=0,sent=false,lv=1}
local R=(P.modeData.event%3<2 and 1 or 3) or
B.sum=B.sum+R {pos=P:RND(10),amount=3,countdown=60,cd0=60,time=0,sent=false,lv=2}
P.stat.recv=P.stat.recv+R local R=(P.modeData.event%3<2 and 1 or 3)
if P.modeData.event==60 then P:showTextF(text.maxspeed,0,-140,100,"appear",.6)end B.sum=B.sum+R
P.modeData.counter=0 P.stat.recv=P.stat.recv+R
P.modeData.event=P.modeData.event+1 if P.modeData.event==60 then P:showTextF(text.maxspeed,0,-140,100,"appear",.6)end
P.modeData.counter=0
P.modeData.event=P.modeData.event+1
end
end
end end
end, end,
bg="glow",bgm="secret7th", bg="glow",bgm="secret7th",

View File

@@ -1,20 +1,23 @@
local max=math.max
return{ return{
color=COLOR.red, color=COLOR.red,
env={ env={
drop=30,lock=45, drop=30,lock=45,
freshLimit=10, freshLimit=10,
task=function(P) task=function(P)
if not(P.control and SCN.cur=="play")then return end while true do
P.modeData.counter=P.modeData.counter+1 coroutine.yield()
if P.modeData.counter>=max(60,150-P.modeData.event)and P.atkBuffer.sum<20 then if P.control and SCN.cur=="play"then
local t=max(60,90-P.modeData.event) P.modeData.counter=P.modeData.counter+1
P.atkBuffer[#P.atkBuffer+1]={pos=P:RND(10),amount=4,countdown=t,cd0=t,time=0,sent=false,lv=3} if P.modeData.counter>=math.max(60,150-P.modeData.event)and P.atkBuffer.sum<20 then
P.atkBuffer.sum=P.atkBuffer.sum+4 local t=math.max(60,90-P.modeData.event)
P.stat.recv=P.stat.recv+4 P.atkBuffer[#P.atkBuffer+1]={pos=P:RND(10),amount=4,countdown=t,cd0=t,time=0,sent=false,lv=3}
if P.modeData.event==60 then P:showTextF(text.maxspeed,0,-140,100,"appear",.6)end P.atkBuffer.sum=P.atkBuffer.sum+4
P.modeData.counter=0 P.stat.recv=P.stat.recv+4
P.modeData.event=P.modeData.event+1 if P.modeData.event==60 then P:showTextF(text.maxspeed,0,-140,100,"appear",.6)end
P.modeData.counter=0
P.modeData.event=P.modeData.event+1
end
end
end end
end, end,
bg="glow",bgm="storm", bg="glow",bgm="storm",

View File

@@ -1,24 +1,27 @@
local max=math.max
return{ return{
color=COLOR.green, color=COLOR.green,
env={ env={
drop=30,lock=45, drop=30,lock=45,
freshLimit=10, freshLimit=10,
task=function(P) task=function(P)
if not(P.control and SCN.cur=="play")then return end while true do
P.modeData.counter=P.modeData.counter+1 coroutine.yield()
if P.modeData.counter>=max(90,180-2*P.modeData.event)and P.atkBuffer.sum<8 then if P.control and SCN.cur=="play"then
local d=P.modeData.event+1 P.modeData.counter=P.modeData.counter+1
P.atkBuffer[#P.atkBuffer+1]= if P.modeData.counter>=math.max(90,180-2*P.modeData.event)and P.atkBuffer.sum<8 then
d%4==0 and{pos=P:RND(10),amount=1,countdown=60,cd0=60,time=0,sent=false,lv=1}or local d=P.modeData.event+1
d%4==1 and{pos=P:RND(10),amount=2,countdown=70,cd0=70,time=0,sent=false,lv=1}or P.atkBuffer[#P.atkBuffer+1]=
d%4==2 and{pos=P:RND(10),amount=3,countdown=80,cd0=80,time=0,sent=false,lv=2}or d%4==0 and{pos=P:RND(10),amount=1,countdown=60,cd0=60,time=0,sent=false,lv=1}or
d%4==3 and{pos=P:RND(10),amount=4,countdown=90,cd0=90,time=0,sent=false,lv=3} d%4==1 and{pos=P:RND(10),amount=2,countdown=70,cd0=70,time=0,sent=false,lv=1}or
P.atkBuffer.sum=P.atkBuffer.sum+d%4+1 d%4==2 and{pos=P:RND(10),amount=3,countdown=80,cd0=80,time=0,sent=false,lv=2}or
P.stat.recv=P.stat.recv+d%4+1 d%4==3 and{pos=P:RND(10),amount=4,countdown=90,cd0=90,time=0,sent=false,lv=3}
if P.modeData.event==45 then P:showTextF(text.maxspeed,0,-140,100,"appear",.6)end P.atkBuffer.sum=P.atkBuffer.sum+d%4+1
P.modeData.counter=0 P.stat.recv=P.stat.recv+d%4+1
P.modeData.event=d if P.modeData.event==45 then P:showTextF(text.maxspeed,0,-140,100,"appear",.6)end
P.modeData.counter=0
P.modeData.event=d
end
end
end end
end, end,
bg="glow",bgm="secret8th", bg="glow",bgm="secret8th",

View File

@@ -1,4 +1,3 @@
local max=math.max
return{ return{
color=COLOR.lYellow, color=COLOR.lYellow,
env={ env={
@@ -7,20 +6,24 @@ return{
freshLimit=15, freshLimit=15,
pushSpeed=2, pushSpeed=2,
task=function(P) task=function(P)
if not(P.control and SCN.cur=="play")then return end while true do
P.modeData.counter=P.modeData.counter+1 coroutine.yield()
if P.modeData.counter>=max(300,600-10*P.modeData.event)and P.atkBuffer.sum<20 then if P.control and SCN.cur=="play"then
local t=max(300,480-12*P.modeData.event) P.modeData.counter=P.modeData.counter+1
local p=#P.atkBuffer+1 if P.modeData.counter>=math.max(300,600-10*P.modeData.event)and P.atkBuffer.sum<20 then
P.atkBuffer[p] ={pos=P:RND(10),amount=4,countdown=t,cd0=t,time=0,sent=false,lv=2} local t=math.max(300,480-12*P.modeData.event)
P.atkBuffer[p+1]={pos=P:RND(10),amount=4,countdown=t,cd0=t,time=0,sent=false,lv=3} local p=#P.atkBuffer+1
P.atkBuffer[p+2]={pos=P:RND(10),amount=6,countdown=1.2*t,cd0=1.2*t,time=0,sent=false,lv=4} P.atkBuffer[p] ={pos=P:RND(10),amount=4,countdown=t,cd0=t,time=0,sent=false,lv=2}
P.atkBuffer[p+3]={pos=P:RND(10),amount=6,countdown=1.5*t,cd0=1.5*t,time=0,sent=false,lv=5} P.atkBuffer[p+1]={pos=P:RND(10),amount=4,countdown=t,cd0=t,time=0,sent=false,lv=3}
P.atkBuffer.sum=P.atkBuffer.sum+20 P.atkBuffer[p+2]={pos=P:RND(10),amount=6,countdown=1.2*t,cd0=1.2*t,time=0,sent=false,lv=4}
P.stat.recv=P.stat.recv+20 P.atkBuffer[p+3]={pos=P:RND(10),amount=6,countdown=1.5*t,cd0=1.5*t,time=0,sent=false,lv=5}
if P.modeData.event==31 then P:showTextF(text.maxspeed,0,-140,100,"appear",.6)end P.atkBuffer.sum=P.atkBuffer.sum+20
P.modeData.counter=0 P.stat.recv=P.stat.recv+20
P.modeData.event=P.modeData.event+1 if P.modeData.event==31 then P:showTextF(text.maxspeed,0,-140,100,"appear",.6)end
P.modeData.counter=0
P.modeData.event=P.modeData.event+1
end
end
end end
end, end,
bg="welcome",bgm="storm", bg="welcome",bgm="storm",

View File

@@ -8,15 +8,18 @@ return{
drop=60,lock=60, drop=60,lock=60,
fall=20, fall=20,
task=function(P) task=function(P)
local _=P.modeData.counter+1 while true do
if P.stat.frame>=warnTime[_]*60 then coroutine.yield()
if _<9 then local _=P.modeData.counter+1
P.modeData.counter=_ if P.stat.frame>=warnTime[_]*60 then
SFX.play("ready",.7+_*.03) if _<9 then
else P.modeData.counter=_
SFX.play("start") SFX.play("ready",.7+_*.03)
P:win("finish") else
return true SFX.play("start")
P:win("finish")
return
end
end end
end end
end, end,

View File

@@ -7,6 +7,7 @@ local Player={}--Player class
local int,ceil,rnd=math.floor,math.ceil,math.random local int,ceil,rnd=math.floor,math.ceil,math.random
local max,min=math.max,math.min local max,min=math.max,math.min
local ins,rem=table.insert,table.remove local ins,rem=table.insert,table.remove
local ct=coroutine
local kickList=require"parts/kickList" local kickList=require"parts/kickList"
local scs=spinCenters local scs=spinCenters
@@ -124,12 +125,11 @@ function Player.RND(P,a,b)
local R=P.randGen local R=P.randGen
return R:random(a,b) return R:random(a,b)
end end
function Player.newTask(P,code,data) function Player.newTask(P,code)
local L=P.tasks local L=P.tasks
ins(L,{ local thread=ct.create(code)
code=code, ct.resume(thread,P)
data=data, L[#L+1]=thread
})
end end
function Player.set20G(P,if20g,init)--Only set init=true when initialize CC, do not use it function Player.set20G(P,if20g,init)--Only set init=true when initialize CC, do not use it
@@ -1453,7 +1453,7 @@ function Player.win(P,result)
end end
if P.human then if P.human then
gameOver() gameOver()
TASK.new(TICK.autoPause,{0}) TASK.new(TICK.autoPause)
if MARKING then if MARKING then
P:showTextF(text.marking,0,-226,25,"appear",.4,.0626) P:showTextF(text.marking,0,-226,25,"appear",.4,.0626)
end end
@@ -1532,7 +1532,7 @@ function Player.lose(P,force)
end end
P.lastRecv=A P.lastRecv=A
if P.id==1 or A.id==1 then if P.id==1 or A.id==1 then
TASK.new(TICK.throwBadge,{A.ai,P,max(3,P.badge)*4}) TASK.new(TICK.throwBadge,A.ai,P,max(3,P.badge)*4)
end end
end end
else else
@@ -1561,7 +1561,7 @@ function Player.lose(P,force)
end end
gameOver() gameOver()
P:newTask(#PLAYERS>1 and TICK.lose or TICK.finish) P:newTask(#PLAYERS>1 and TICK.lose or TICK.finish)
TASK.new(TICK.autoPause,{0}) TASK.new(TICK.autoPause)
if MARKING then if MARKING then
P:showTextF(text.marking,0,-226,25,"appear",.4,.0626) P:showTextF(text.marking,0,-226,25,"appear",.4,.0626)
end end

View File

@@ -1,5 +1,7 @@
local int,max,min,abs=math.floor,math.max,math.min,math.abs local int,max,min,abs=math.floor,math.max,math.min,math.abs
local rem=table.remove local rem=table.remove
local ct=coroutine
local assert=assert
local function updateLine(P)--Attacks, line pushing, cam moving local function updateLine(P)--Attacks, line pushing, cam moving
local bf=P.atkBuffer local bf=P.atkBuffer
@@ -95,7 +97,10 @@ end
local function updateTasks(P) local function updateTasks(P)
local L=P.tasks local L=P.tasks
for i=#L,1,-1 do for i=#L,1,-1 do
if L[i].code(P,L[i].data)then rem(L,i)end assert(ct.resume(L[i]))
if ct.status(L[i])=="dead"then
rem(L,i)
end
end end
end end

View File

@@ -1,151 +1,248 @@
local function checkTimeout(data,time) local yield=coroutine.yield
data.time=data.time+1
if data.time==time then
LOG.print(text.httpTimeout,"message")
return true
end
end
local Tick={} local Tick={}
function Tick.showMods(data) function Tick.showMods()
local d=data[1]+1 local time=0
if d%20==0 then while true do
local M=GAME.mod[d/20] yield()
if M then time=time+1
TEXT.show(M.id,700+(d-20)%120*4,36,45,"spin",.5) if time%20==0 then
else local M=GAME.mod[time/20]
return true if M then
TEXT.show(M.id,700+(time-20)%120*4,36,45,"spin",.5)
else
return
end
end end
end end
data[1]=d
end end
function Tick.finish(P) function Tick.finish(P)
P.endCounter=P.endCounter+1 while true do
if P.endCounter<40 then yield()
--Make field visible P.endCounter=P.endCounter+1
for j=1,#P.field do for i=1,10 do if P.endCounter<40 then
if P.visTime[j][i]<20 then P.visTime[j][i]=P.visTime[j][i]+.5 end --Make field visible
end end for j=1,#P.field do for i=1,10 do
elseif P.endCounter==60 then if P.visTime[j][i]<20 then P.visTime[j][i]=P.visTime[j][i]+.5 end
return true end end
elseif P.endCounter==60 then
return
end
end end
end end
function Tick.lose(P) function Tick.lose(P)
P.endCounter=P.endCounter+1 while true do
if P.endCounter<40 then yield()
--Make field visible P.endCounter=P.endCounter+1
for j=1,#P.field do for i=1,10 do if P.endCounter<40 then
if P.visTime[j][i]<20 then P.visTime[j][i]=P.visTime[j][i]+.5 end --Make field visible
end end for j=1,#P.field do for i=1,10 do
elseif P.endCounter>80 then if P.visTime[j][i]<20 then P.visTime[j][i]=P.visTime[j][i]+.5 end
for i=1,#P.field do end end
for j=1,10 do elseif P.endCounter>80 then
if P.visTime[i][j]>0 then for i=1,#P.field do
P.visTime[i][j]=P.visTime[i][j]-1 for j=1,10 do
if P.visTime[i][j]>0 then
P.visTime[i][j]=P.visTime[i][j]-1
end
end end
end end
end if P.endCounter==120 then
if P.endCounter==120 then for _=#P.field,1,-1 do
for _=#P.field,1,-1 do FREEROW.discard(P.field[_])
FREEROW.discard(P.field[_]) FREEROW.discard(P.visTime[_])
FREEROW.discard(P.visTime[_]) P.field[_],P.visTime[_]=nil
P.field[_],P.visTime[_]=nil end
return
end end
return true
end end
end if not GAME.modeEnv.royaleMode and #PLAYERS>1 then
if not GAME.modeEnv.royaleMode and #PLAYERS>1 then P.y=P.y+P.endCounter*.26
P.y=P.y+P.endCounter*.26 P.absFieldY=P.absFieldY+P.endCounter*.26
P.absFieldY=P.absFieldY+P.endCounter*.26 end
end end
end end
function Tick.throwBadge(data)--{ifAI,Sender,timer} function Tick.throwBadge(ifAI,sender,time)
data[3]=data[3]-1 while true do
if data[3]%4==0 then yield()
local S,R=data[2],data[2].lastRecv time=time-1
local x1,y1,x2,y2 if time%4==0 then
if S.small then local S,R=sender,sender.lastRecv
x1,y1=S.centerX,S.centerY local x1,y1,x2,y2
else if S.small then
x1,y1=S.x+308*S.size,S.y+450*S.size x1,y1=S.centerX,S.centerY
end else
if R.small then x1,y1=S.x+308*S.size,S.y+450*S.size
x2,y2=R.centerX,R.centerY end
else if R.small then
x2,y2=R.x+66*R.size,R.y+344*R.size x2,y2=R.centerX,R.centerY
end else
x2,y2=R.x+66*R.size,R.y+344*R.size
end
--Generate badge object --Generate badge object
SYSFX.newBadge(x1,y1,x2,y2) SYSFX.newBadge(x1,y1,x2,y2)
if not data[1]and data[3]%8==0 then if not ifAI and time%8==0 then
SFX.play("collect") SFX.play("collect")
end
end end
if time<=0 then return end
end end
if data[3]<=0 then return true end
end end
function Tick.autoPause(data) function Tick.autoPause()
data[1]=data[1]+1 local time=0
if SCN.cur~="play"then return true end while true do
if data[1]==120 then yield()
if SCN.cur=="play"then time=time+1
if SCN.cur~="play"then
return
elseif time==120 then
pauseGame() pauseGame()
return
end end
return true
end end
end end
function Tick.httpREQ_launch(data) function Tick.httpREQ_launch(task)
local response,request_error=client.poll(data.task) local time=0
if response then while true do
local res=json.decode(response.body) yield()
if res then local response,request_error=client.poll(task)
if response.code==200 then if response then
LOG.print(res.notice,360,COLOR.sky) local res=json.decode(response.body)
if VERSION_CODE>=res.version_code then if res then
LOG.print(text.versionIsNew,360,COLOR.sky) if response.code==200 then
LOG.print(res.notice,360,COLOR.sky)
if VERSION_CODE>=res.version_code then
LOG.print(text.versionIsNew,360,COLOR.sky)
else
LOG.print(string.gsub(text.versionIsOld,"$1",res.version_name),"warn")
end
else else
LOG.print(string.gsub(text.versionIsOld,"$1",res.version_name),"warn") LOG.print(text.netErrorCode..response.code..": "..res.message,"warn")
end
end
return
elseif request_error then
LOG.print(text.getNoticeFail..": "..request_error,"warn")
return
end
time=time+1
if time>360 then
LOG.print(text.httpTimeout,"message")
return
end
end
end
function Tick.httpREQ_register(task)
local time=0
while true do
yield()
local response,request_error=client.poll(task)
if response then
local res=json.decode(response.body)
if res then
if response.code==200 then
LOG.print(text.registerSuccessed..": "..res.message)
else
LOG.print(text.netErrorCode..response.code..": "..res.message,"warn")
end
end
return
elseif request_error then
LOG.print(text.loginFailed..": "..request_error,"warn")
return
end
time=time+1
if time>360 then
LOG.print(text.httpTimeout,"message")
return
end
end
end
function Tick.httpREQ_newLogin(task)
local time=0
while true do
yield()
local response,request_error=client.poll(task)
if response then
local res=json.decode(response.body)
LOGIN=response.code==200
if res then
if LOGIN then
LOG.print(text.loginSuccessed)
ACCOUNT.email=res.email
ACCOUNT.auth_token=res.auth_token
FILE.save(ACCOUNT,"account","")
httpRequest(
TICK.httpREQ_getAccessToken,
PATH.api..PATH.access,
"POST",
{["Content-Type"]="application/json"},
json.encode{
email=ACCOUNT.email,
auth_token=ACCOUNT.auth_token,
}
)
else
LOG.print(text.netErrorCode..response.code..": "..res.message,"warn")
end
end
return
elseif request_error then
LOG.print(text.loginFailed..": "..request_error,"warn")
return
end
time=time+1
if time>360 then
LOG.print(text.httpTimeout,"message")
return
end
end
end
function Tick.httpREQ_autoLogin(task)
local time=0
while true do
yield()
local response,request_error=client.poll(task)
if response then
if response.code==200 then
LOGIN=true
local res=json.decode(response.body)
if res then
LOG.print(text.loginSuccessed)
end end
else else
LOG.print(text.netErrorCode..response.code..": "..res.message,"warn") LOGIN=false
local err=json.decode(response.body)
if err then
LOG.print(text.loginFailed..": "..text.netErrorCode..response.code.."-"..err.message,"warn")
end
end end
return
elseif request_error then
LOG.print(text.loginFailed..": "..request_error,"warn")
return
end
time=time+1
if time>360 then
LOG.print(text.httpTimeout,"message")
return
end end
return true
elseif request_error then
LOG.print(text.getNoticeFail..": "..request_error,"warn")
return true
end end
return checkTimeout(data,260)
end end
function Tick.httpREQ_register(data) function Tick.httpREQ_checkAccessToken(task)
local response,request_error=client.poll(data.task) local time=0
if response then while true do
local res=json.decode(response.body) yield()
if res then local response,request_error=client.poll(task)
if response then
if response.code==200 then if response.code==200 then
LOG.print(text.registerSuccessed..": "..res.message) LOG.print(text.accessSuccessed)
else SCN.pop()
LOG.print(text.netErrorCode..response.code..": "..res.message,"warn") SCN.go("netgame")
end elseif response.code==403 or response.code==401 then
end
return true
elseif request_error then
LOG.print(text.loginFailed..": "..request_error,"warn")
return true
end
return checkTimeout(data,360)
end
function Tick.httpREQ_newLogin(data)
local response,request_error=client.poll(data.task)
if response then
local res=json.decode(response.body)
LOGIN=response.code==200
if res then
if LOGIN then
LOG.print(text.loginSuccessed)
ACCOUNT.email=res.email
ACCOUNT.auth_token=res.auth_token
FILE.save(ACCOUNT,"account","")
httpRequest( httpRequest(
TICK.httpREQ_getAccessToken, TICK.httpREQ_getAccessToken,
PATH.api..PATH.access, PATH.api..PATH.access,
@@ -157,144 +254,115 @@ function Tick.httpREQ_newLogin(data)
} }
) )
else else
LOG.print(text.netErrorCode..response.code..": "..res.message,"warn") local err=json.decode(response.body)
if err then
LOG.print(text.netErrorCode..response.code..": "..err.message,"warn")
end
end end
return
elseif request_error then
LOG.print(text.loginFailed..": "..request_error,"warn")
return
end end
return true time=time+1
elseif request_error then if time>360 then
LOG.print(text.loginFailed..": "..request_error,"warn") LOG.print(text.httpTimeout,"message")
return true return
end
return checkTimeout(data,360)
end
function Tick.httpREQ_autoLogin(data)
local response,request_error=client.poll(data.task)
if response then
if response.code==200 then
LOGIN=true
local res=json.decode(response.body)
if res then
LOG.print(text.loginSuccessed)
end
else
LOGIN=false
local err=json.decode(response.body)
if err then
LOG.print(text.loginFailed..": "..text.netErrorCode..response.code.."-"..err.message,"warn")
end
end end
return true
elseif request_error then
LOG.print(text.loginFailed..": "..request_error,"warn")
return true
end end
return checkTimeout(data,360)
end end
function Tick.httpREQ_checkAccessToken(data) function Tick.httpREQ_getAccessToken(task)
local response,request_error=client.poll(data.task) local time=0
if response then while true do
if response.code==200 then yield()
LOG.print(text.accessSuccessed) local response,request_error=client.poll(task)
SCN.pop() if response then
SCN.go("netgame") if response.code==200 then
elseif response.code==403 or response.code==401 then local res=json.decode(response.body)
httpRequest( if res then
TICK.httpREQ_getAccessToken, LOG.print(text.accessSuccessed)
PATH.api..PATH.access, ACCOUNT.access_token=res.access_token
"POST", FILE.save(ACCOUNT,"account","")
{["Content-Type"]="application/json"}, SCN.pop()
json.encode{ SCN.go("netgame")
email=ACCOUNT.email, else
auth_token=ACCOUNT.auth_token, LOG.print(text.netErrorCode..response.code..": "..res.message,"warn")
} SCN.pop()
) SCN.go("main")
else end
local err=json.decode(response.body)
if err then
LOG.print(text.netErrorCode..response.code..": "..err.message,"warn")
end
end
return true
elseif request_error then
LOG.print(text.loginFailed..": "..request_error,"warn")
return true
end
return checkTimeout(data,360)
end
function Tick.httpREQ_getAccessToken(data)
local response,request_error=client.poll(data.task)
if response then
if response.code==200 then
local res=json.decode(response.body)
if res then
LOG.print(text.accessSuccessed)
ACCOUNT.access_token=res.access_token
FILE.save(ACCOUNT,"account","")
SCN.pop()
SCN.go("netgame")
else else
LOG.print(text.netErrorCode..response.code..": "..res.message,"warn") LOGIN=false
ACCOUNT.access_token=nil
ACCOUNT.auth_token=nil
local err=json.decode(response.body)
if err then
LOG.print(text.loginFailed..": "..text.netErrorCode..response.code.."-"..err.message,"warn")
else
LOG.print(text.loginFailed..": "..text.netErrorCode,"warn")
end
SCN.pop() SCN.pop()
SCN.go("main") SCN.go("main")
end end
else return
LOGIN=false elseif request_error then
ACCOUNT.access_token=nil LOG.print(text.loginFailed..": "..request_error,"warn")
ACCOUNT.auth_token=nil return
local err=json.decode(response.body) end
if err then time=time+1
LOG.print(text.loginFailed..": "..text.netErrorCode..response.code.."-"..err.message,"warn") if time>360 then
else LOG.print(text.httpTimeout,"message")
LOG.print(text.loginFailed..": "..text.netErrorCode,"warn") return
end
SCN.pop()
SCN.go("main")
end end
return true
elseif request_error then
LOG.print(text.loginFailed..": "..request_error,"warn")
return true
end end
return checkTimeout(data,360)
end end
function Tick.wsCONN_connect(data) function Tick.wsCONN_connect(task)
if data.wsconntask then local time=0
local wsconn,connErr=client.poll(data.wsconntask) while true do
yield()
local wsconn,connErr=client.poll(task)
if wsconn then if wsconn then
WSCONN = wsconn WSCONN=wsconn
TASK.new(Tick.wsCONN_read) TASK.new(Tick.wsCONN_read)
return true return
elseif connErr then elseif connErr then
LOG.print(text.wsFailed..": "..connErr,"warn") LOG.print(text.wsFailed..": "..connErr,"warn")
return true return
end
time=time+1
if time>360 then
LOG.print(text.httpTimeout,"message")
return
end end
end end
return checkTimeout(data,360)
end end
function Tick.wsCONN_read() function Tick.wsCONN_read()
local messages,readErr=client.read(WSCONN) while true do
if messages then yield()
if messages[1] then local messages,readErr=client.read(WSCONN)
LOG.print(messages[1]) if messages then
if messages[1]then
LOG.print(messages[1])
end
elseif readErr then
print("Read error: "..readErr)
if readErr=="EOF"then
LOG.print("Socket closed!","warn")
end
WSCONN=nil
return
end end
elseif readErr then
print("Read error: "..readErr)
if readErr == "EOF" then
LOG.print("Socket closed!","warn")
end
WSCONN = nil
return true
end end
end end
-- function Tick.wsCONN_write(data) -- function Tick.wsCONN_write()
-- if not data.net then -- while true do
-- return true -- local message=yield()
-- if message then
-- local writeErr=client.write(WSCONN,message)
-- if writeErr then
-- print(writeErr,"warn")
-- end
-- end
-- end -- end
-- local writeErr=client.write(WSCONN,data.message)
-- if writeErr then
-- print(writeErr, "warn")
-- end
-- return true
-- end -- end
return Tick return Tick