This commit is contained in:
user670
2021-05-09 21:38:13 +08:00
46 changed files with 944 additions and 698 deletions

View File

@@ -54,11 +54,12 @@ local setFont=setFont
local int,rnd,abs=math.floor,math.random,math.abs
local min,sin=math.min,math.sin
local ins,rem=table.insert,table.remove
local SCR=SCR
local WIDGET,SCR,SCN=WIDGET,SCR,SCN
local xOy=SCR.xOy
local mx,my,mouseShow=-20,-20,false
local touching--First touching ID(userdata)
local xOy=SCR.xOy
joysticks={}
local devMode
@@ -118,7 +119,7 @@ function love.mousepressed(x,y,k,touch)
if SCN.mouseDown then SCN.mouseDown(mx,my,k)end
WIDGET.press(mx,my,k)
lastX,lastY=mx,my
if SETTING.clickFX then SYSFX.newTap(3,mx,my,30)end
if SETTING.clickFX then SYSFX.newTap(3,mx,my)end
end
function love.mousemoved(x,y,dx,dy,touch)
if touch then return end
@@ -188,7 +189,7 @@ function love.touchreleased(id,x,y)
if SCN.touchUp then SCN.touchUp(x,y)end
if(x-lastX)^2+(y-lastY)^2<62 then
if SCN.touchClick then SCN.touchClick(x,y)end
if SETTING.clickFX then SYSFX.newTap(3,x,y,30)end
if SETTING.clickFX then SYSFX.newTap(3,x,y)end
end
end
@@ -325,6 +326,12 @@ end
function love.sendData(data)end
function love.receiveData(id,data)end
]]
function love.filedropped(file)
if SCN.fileDropped then SCN.fileDropped(file)end
end
function love.directorydropped(dir)
if SCN.directoryDropped then SCN.directoryDropped(dir)end
end
local lastGCtime=0
function love.lowmemory()
if TIME()-lastGCtime>6.26 then
@@ -336,6 +343,7 @@ end
function love.resize(w,h)
SCR.resize(w,h)
if BG.resize then BG.resize(w,h)end
if SCN.resize then SCN.resize(w,h)end
SHADER.warning:send("w",w*SCR.dpi)
SHADER.warning:send("h",h*SCR.dpi)
@@ -457,16 +465,15 @@ love.draw,love.update=nil--remove default draw/update
function love.run()
local love=love
local SCN,WIDGET=SCN,WIDGET
local VOC,BG,SYSFX=VOC,BG,SYSFX
local TASK,LOG,TEXT=TASK,LOG,TEXT
local SETTING=SETTING
local TIME=TIME
local TEXTURE,TIME=TEXTURE,TIME
local SETTING,VERSION=SETTING,VERSION
local destroyPlayers=destroyPlayers
local STEP,WAIT=love.timer.step,love.timer.sleep
local FPS=love.timer.getFPS
local MINI=love.window.isMinimized
local FPS,MINI=love.timer.getFPS,love.window.isMinimized
local PUMP,POLL=love.event.pump,love.event.poll
local frameTimeList={}
@@ -485,9 +492,9 @@ function love.run()
return function()
local _
local t=TIME()
local dt=t-lastFrame
lastFrame=t
local time=TIME()
local dt=time-lastFrame
lastFrame=time
--EVENT
PUMP()
@@ -531,13 +538,18 @@ function love.run()
--Draw widgets
WIDGET.draw()
--Draw Version string
gc_setColor(.8,.8,.8,.4)
setFont(20)
mStr(VERSION.string,640,693)
--Draw cursor
if mouseShow then
local R=int((t+1)/2)%7+1
local R=int((time+1)/2)%7+1
_=minoColor[SETTING.skin[R]]
gc_setColor(_[1],_[2],_[3],min(abs(1-t%2),.3))
gc_setColor(_[1],_[2],_[3],min(abs(1-time%2),.3))
_=SCS[R][0]
gc_draw(TEXTURE.miniBlock[R],mx,my,t%3.14159265359*4,16,16,_[2]+.5,#BLOCKS[R][0]-_[1]-.5)
gc_draw(TEXTURE.miniBlock[R],mx,my,time%3.14159265359*4,16,16,_[2]+.5,#BLOCKS[R][0]-_[1]-.5)
gc_setColor(1,1,1)
gc_draw(TEXTURE[ms.isDown(1)and'cursor_hold'or'cursor'],mx,my,nil,nil,nil,8,8)
end
@@ -560,8 +572,6 @@ function love.run()
--Draw FPS
setFont(15)
_=SCR.h
gc_setColor(.8,.8,.8,.4)
gc_print(VERSION.string,SCR.safeX+50,_-20)
gc_setColor(1,1,1)
gc_print(FPS(),SCR.safeX+5,_-20)
@@ -594,7 +604,7 @@ function love.run()
gc_setColor(1,1,1)
gc_draw(TEXTURE.ws_dead,-20,20*i-20)
elseif status=='connecting'then
gc_setColor(1,1,1,.5+.3*sin(t*6.26))
gc_setColor(1,1,1,.5+.3*sin(time*6.26))
gc_draw(TEXTURE.ws_connecting,-20,20*i-20)
elseif status=='running'then
gc_setColor(1,1,1)
@@ -622,10 +632,10 @@ function love.run()
end
--Fresh power info.
if t-lastFreshPow>2.6 then
if time-lastFreshPow>2.6 then
if SETTING.powerInfo and LOADED then
updatePowerInfo()
lastFreshPow=t
lastFreshPow=time
end
if gc.getWidth()~=SCR.w then
love.resize(gc.getWidth(),gc.getHeight())

View File

@@ -35,7 +35,7 @@ function LOG.draw()
end
end
end
function LOG.print(text,T,C)--text,type/time,color
function LOG.print(text,T,C)--text,type/time/color,color
local time
local his
if T=='warn'then

View File

@@ -34,6 +34,9 @@ local SCN={
keyUp=false,
gamepadDown=false,
gamepadUp=false,
fileDropped=false,
directoryDropped=false,
resize=false,
socketRead=false,
}--Scene datas, returned
@@ -78,6 +81,9 @@ function SCN.init(s,org)
SCN.keyUp=S.keyUp
SCN.gamepadDown=S.gamepadDown
SCN.gamepadUp=S.gamepadUp
SCN.fileDropped=S.fileDropped
SCN.directoryDropped=S.directoryDropped
SCN.resize=S.resize
SCN.socketRead=S.socketRead
if S.sceneInit then S.sceneInit(org)end
end

View File

@@ -1,6 +1,15 @@
local next,type=next,type
local TABLE={}
--Get a new filled table
function TABLE.new(val,count)
local L={}
for i=1,count do
L[i]=val
end
return L
end
--Get a copy of [1~#] elements
function TABLE.shift(org)
local L={}
@@ -27,7 +36,7 @@ function TABLE.copy(org)
return L
end
--For all things in G if same type in base, push to base
--For all things in new if same type in base, push to old
function TABLE.update(new,old)
for k,v in next,new do
if type(v)==type(old[k])then
@@ -40,13 +49,14 @@ function TABLE.update(new,old)
end
end
--For all things in G if no val in base, push to base
--For all things in new if no val in base, push to old
function TABLE.complete(new,old)
for k,v in next,new do
if old[k]==nil then
old[k]=v
elseif type(v)=='table'and type(old[k])=='table'then
if type(v)=='table'then
if old[k]==nil then old[k]={}end
TABLE.complete(v,old[k])
elseif old[k]==nil then
old[k]=v
end
end
end

View File

@@ -882,6 +882,7 @@ function textBox:press(x,y)
if not self.fix and x>self.x+self.w-40 and y<self.y+40 then
if self.sure>0 then
self:clear()
self.new=false
self.sure=0
else
self.sure=60
@@ -907,6 +908,7 @@ end
function textBox:clear()
self.texts={}
self.scrollPos=0
self.new=false
SFX.play('fall')
end
function textBox:draw()

View File

@@ -59,6 +59,15 @@ require"parts.list"
require"parts.globalTables"
require"parts.gametoolfunc"
--Load shader files from SOURCE ONLY
SHADER={}
for _,v in next,fs.getDirectoryItems("parts/shaders")do
if fs.getRealDirectory("parts/shaders/"..v)~=SAVEDIR then
local name=v:sub(1,-6)
SHADER[name]=love.graphics.newShader("parts/shaders/"..name..".glsl")
end
end
FREEROW= require"parts.freeRow"
DATA= require"parts.data"
@@ -68,6 +77,7 @@ USERS= require"parts.users"
NET= require"parts.net"
VK= require"parts.virtualKey"
PLY= require"parts.player"
netPLY= require"parts.netPlayer"
AIFUNC= require"parts.ai"
AIBUILDER= require"parts.AITemplate"
MODES= require"parts.modes"
@@ -204,16 +214,6 @@ LANG.init(
},
}
)
--Load shader files from SOURCE ONLY
SHADER={}
for _,v in next,fs.getDirectoryItems("parts/shaders")do
if fs.getRealDirectory("parts/shaders/"..v)~=SAVEDIR then
local name=v:sub(1,-6)
SHADER[name]=love.graphics.newShader("parts/shaders/"..name..".glsl")
end
end
--Load background files from SOURCE ONLY
for _,v in next,fs.getDirectoryItems("parts/backgrounds")do
if fs.getRealDirectory("parts/backgrounds/"..v)~=SAVEDIR then
@@ -263,7 +263,6 @@ do
if STAT.version<1400 then
fs.remove("conf/user")
fs.remove("conf/key")
SETTING.appLock=false
needSave=true
autoRestart=true
end
@@ -271,14 +270,9 @@ do
fs.remove("conf/user")
autoRestart=true
end
SETTING.appLock=nil
for _,v in next,VK_org do
if not v.color then
fs.remove("conf/virtualkey")
autoRestart=true
break
end
end
for _,v in next,VK_org do v.color=nil end
if STAT.version~=VERSION.code then
newVersionLaunch=true

View File

@@ -32,7 +32,7 @@ function back.update()
end
end
function back.draw()
gc.clear(.15,.15,.15)
gc.clear(.1,.1,.1)
gc.push('transform')
gc.origin()
gc.setColor(1,1,1,.4)

View File

@@ -40,7 +40,7 @@ function back.update()
end
end
function back.draw()
gc.clear(.15,.15,.15)
gc.clear(.1,.1,.1)
gc.push('transform')
gc.origin()
for i=1,#mino do

View File

@@ -13,16 +13,16 @@ function back.init()
end
function back.update()
t=t+1
if t%2==0 then
if t%3==0 then
local r=rnd(29)
ins(mino,{
block=TEXTURE.miniBlock[r],
color=minoColor[SETTING.skin[r]],
ang=6.2832*rnd(),
rotate=6.2832*rnd(),
vr=.03-rnd()*.06,
vr=.05-rnd()*.1,
d=0,
v=1,
v=.5+rnd(),
})
end
local rad=SCR.rad
@@ -33,12 +33,12 @@ function back.update()
rem(mino,i)
else
M.rotate=M.rotate+M.vr
M.v=M.v*(1+M.d/SCR.rad*.2)
M.v=M.v*(1+M.d/SCR.rad*.05)
end
end
end
function back.draw()
gc.clear(.15,.15,.15)
gc.clear(.1,.1,.1)
gc.push('transform')
gc.origin()
gc.translate(SCR.w/2,SCR.h/2)

View File

@@ -13,7 +13,7 @@ function back.update(dt)
t=t+dt
end
function back.draw()
gc.clear(.15,.15,.15)
gc.clear(.1,.1,.1)
gc.push('transform')
local k=SCR.k
gc.scale(k)

View File

@@ -31,7 +31,7 @@ function back.update()
end
end
function back.draw()
gc.clear(.15,.15,.15)
gc.clear(.1,.1,.1)
if not stars[1]then return end
gc.translate(-10,-10)
gc.setColor(.8,.8,.8)

View File

@@ -368,7 +368,7 @@ do--function DATA.saveRecording()
end
--Write file
local fileName="replay/"..os.date("%Y_%m_%d_%a_%H%M%S.rep")
local fileName=os.date("replay/%Y_%m_%d_%a_%H%M%S.rep")
if not love.filesystem.getInfo(fileName)then
local fileHead=
os.date("%Y/%m/%d %A %H:%M:%S\n")..

View File

@@ -1,4 +1,5 @@
local gc=love.graphics
local ins,rem=table.insert,table.remove
@@ -164,7 +165,6 @@ function scoreValid()--Check if any unranked mods are activated
return true
end
function destroyPlayers()--Destroy all player objects, restore freerows and free CCs
local rem=table.remove
for i=#PLAYERS,1,-1 do
local P=PLAYERS[i]
if P.canvas then P.canvas:release()end
@@ -234,6 +234,63 @@ function loadGame(M,ifQuickPlay,ifNet)--Load a mode and go to game scene
end
end
end
function gameOver()--Save record
if GAME.replaying then return end
FILE.save(STAT,'conf/data')
local M=GAME.curMode
local R=M.getRank
if R then
local P=PLAYERS[1]
R=R(P)--New rank
if R then
if R>0 then
GAME.rank=R
end
if scoreValid()and M.score then
if RANKS[M.name]then--Old rank exist
local needSave
if R>RANKS[M.name]then
RANKS[M.name]=R
needSave=true
end
if R>0 then
if M.unlock then
for i=1,#M.unlock do
local m=M.unlock[i]
local n=MODES[m].name
if not RANKS[n]then
RANKS[n]=MODES[m].getRank and 0 or 6
needSave=true
end
end
end
end
if needSave then
FILE.save(RANKS,'conf/unlock','q')
end
end
local D=M.score(P)
local L=M.records
local p=#L--Rank-1
if p>0 then
while M.comp(D,L[p])do--If higher rank
p=p-1
if p==0 then break end
end
end
if p<10 then
if p==0 then
P:showTextF(text.newRecord,0,-100,100,'beat',.5)
end
D.date=os.date("%Y/%m/%d %H:%M")
ins(L,p+1,D)
if L[11]then L[11]=nil end
FILE.save(L,('record/%s.rec'):format(M.name),'lq')
end
end
end
end
end
function initPlayerPosition(sudden)--Set initial position for every player
local L=PLY_ALIVE
if not sudden then

View File

@@ -119,7 +119,7 @@ MODOPT={--Mod options
},
{no=19,id="CS",name="customSeq",
key="b",x=680,y=470,color='B',
list={'bag','his4','c2','rnd','mess','reverb'},
list={'bag','his','hisPool','c2','rnd','mess','reverb'},
func=function(P,O)P.gameEnv.sequence=O end,
unranked=true,
},
@@ -144,7 +144,6 @@ end
--Game tables
PLAYERS={}--Players data
PLY_ALIVE={}
PLY_NET={}
FIELD={}--Field(s) for custom game
BAG={}--Sequence for custom game
MISSION={}--Clearing mission for custom game
@@ -247,7 +246,6 @@ SETTING={--Settings
reTime=4,
autoPause=true,
fine=false,
appLock=false,
simpMode=false,
lang=1,
skinSet=1,
@@ -339,25 +337,25 @@ keyMap=FILE.load("conf/key")or{--Key setting
},
}
VK_org=FILE.load("conf/virtualkey")or{--Virtualkey layout, refresh all VKs' position with this before each game
{ava=true, x=80, y=720-200, r=80,color=COLOR.L},--moveLeft
{ava=true, x=320, y=720-200, r=80,color=COLOR.L},--moveRight
{ava=true, x=1280-80, y=720-200, r=80,color=COLOR.R},--rotRight
{ava=true, x=1280-200, y=720-80, r=80,color=COLOR.O},--rotLeft
{ava=true, x=1280-200, y=720-320, r=80,color=COLOR.M},--rot180
{ava=true, x=200, y=720-320, r=80,color=COLOR.C},--hardDrop
{ava=true, x=200, y=720-80, r=80,color=COLOR.S},--softDrop
{ava=true, x=1280-320, y=720-200, r=80,color=COLOR.Y},--hold
{ava=true, x=1280-80, y=280, r=80,color=COLOR.lR},--func1
{ava=true, x=80, y=280, r=80,color=COLOR.lM},--func2
{ava=false, x=100, y=50, r=80,color=COLOR.A},--insLeft
{ava=false, x=200, y=50, r=80,color=COLOR.A},--insRight
{ava=false, x=300, y=50, r=80,color={COLOR.rainbow(3.5)}},--insDown
{ava=false, x=400, y=50, r=80,color={COLOR.rainbow(3.3)}},--down1
{ava=false, x=500, y=50, r=80,color={COLOR.rainbow(3.1)}},--down4
{ava=false, x=600, y=50, r=80,color={COLOR.rainbow(2.9)}},--down10
{ava=false, x=700, y=50, r=80,color=COLOR.lL},--dropLeft
{ava=false, x=800, y=50, r=80,color=COLOR.lL},--dropRight
{ava=false, x=900, y=50, r=80,color=COLOR.lA},--addToLeft
{ava=false, x=1000, y=50, r=80,color=COLOR.lA},--addToRight
{ava=true, x=80, y=720-200, r=80},--moveLeft
{ava=true, x=320, y=720-200, r=80},--moveRight
{ava=true, x=1280-80, y=720-200, r=80},--rotRight
{ava=true, x=1280-200, y=720-80, r=80},--rotLeft
{ava=true, x=1280-200, y=720-320, r=80},--rot180
{ava=true, x=200, y=720-320, r=80},--hardDrop
{ava=true, x=200, y=720-80, r=80},--softDrop
{ava=true, x=1280-320, y=720-200, r=80},--hold
{ava=true, x=1280-80, y=280, r=80},--func1
{ava=true, x=80, y=280, r=80},--func2
{ava=false, x=100, y=50, r=80},--insLeft
{ava=false, x=200, y=50, r=80},--insRight
{ava=false, x=300, y=50, r=80},--insDown
{ava=false, x=400, y=50, r=80},--down1
{ava=false, x=500, y=50, r=80},--down4
{ava=false, x=600, y=50, r=80},--down10
{ava=false, x=700, y=50, r=80},--dropLeft
{ava=false, x=800, y=50, r=80},--dropRight
{ava=false, x=900, y=50, r=80},--addToLeft
{ava=false, x=1000, y=50, r=80},--addToRight
}
REPLAY=FILE.load("conf/replay")or{}

View File

@@ -554,7 +554,7 @@ return{
{"His generator",
"history hisgenerator",
"term",
"A way to generate pieces, notably used in Tetris: The Grand Master games. Every time a random Tetrimino is selected, but if this Tetrimino is the same as one of the few previous pieces, then reroll until a different piece is rolled or until a reroll limit is reached.\nFor example, a \"his 4 roll 6\" (h4r6) generator rerolls when the piece is the same as one of the 4 previous pieces, and rerolls up to 6 times.",
"A way to generate pieces, notably used in Tetris: The Grand Master games. Every time a random Tetrimino is selected, but if this Tetrimino is the same as one of the few previous pieces, then reroll until a different piece is rolled or until a reroll limit is reached.\nFor example, a \"his 4 roll 6\" (h4r6) generator rerolls when the piece is the same as one of the 4 previous pieces, and rerolls up to 6 times.",--TODO
},
{"Hypertapping",
"hypertapping",

View File

@@ -489,7 +489,7 @@ return{
{"C4W",
"连击 ·c4w center4wide",
"term",
"Center 4 Wide\n中间空四列,一种连击打法,能打出很高的连击,利用了大多数专业对战方块游戏的死亡判定机制,可以放心堆高不担心被顶死,然后开始连击。是一种利用游戏机制的不平衡策略(尤其在开局时),观赏性不是很强还可以以弱胜强,成本太低所以成为了部分游戏中约定的类似 禁招 的东西,请在了解情况后再使用,不然可能会被别人骂。\n\n本游戏里考虑到了平衡问题所以c4w的强度没有别的游戏那么夸张。",
"Center 4 Wide\n中间空四列,一种连击打法,能打出很高的连击,利用了大多数专业对战方块游戏的死亡判定机制,可以放心堆高不担心被顶死,然后开始连击。是一种利用游戏机制的不平衡策略(尤其在开局时),观赏性不是很强还可以以弱胜强,成本太低所以成为了部分游戏中约定的类似 禁招 的东西,请在了解情况后再使用,不然可能会被别人骂。\n本游戏里考虑到了平衡问题所以c4w的强度没有别的游戏那么夸张。",
},
{"N-res",
"连击 ·residual c4w s4w",
@@ -564,7 +564,7 @@ return{
{"His出块",
"his出块 history",
"term",
"一种出块方式例如his 4 roll 6 (h4r6) 就是在随机生成新的next的时候随机一个跟最后4次生成的next中有一样的就重新随机直到已经尝试6次或和那4个都不一样。",
"一种出块方式例如his4 roll6 (h4r6) 就是在随机生成新的next的时候随机一个跟最后4次生成的next中有一样的就重新随机直到已经尝试6次或和那4个都不一样。另有拓展算法his4 roll6 pool35等更复杂的算法能让序列更稳定更接近bag。\n本游戏的his序列模式中最大roll次数为序列长度的一半(向上取整)",
},
{"Hypertap",
"超连点 hypertap",

View File

@@ -101,6 +101,7 @@ return{
joinRoom="has joined the room.",
leaveRoom="has left the room.",
ready="READY",
set="SET",
champion="$1 won",
chatRemain="Online: ",
chatStart="------Beginning of log------",
@@ -201,6 +202,7 @@ return{
Beepbox
GFIE
Goldwave
FL Mobile
Libs used:
Cold_Clear [MinusKelvin]
json.lua [rxi]
@@ -275,11 +277,10 @@ return{
reTime="Start Delay",
RS="Rotation System",
layout="Layout",
dataSaving="Data saving",
autoPause="Pause while unfocused",
swap="Key Combination (Change Atk. Mode)",
fine="Finesse Error SFX",
appLock="App Lock (Password: 6+26)",
dataSaving="Data saving",
simpMode="Simplistic Style",
},
setting_video={

View File

@@ -102,6 +102,7 @@ return{
joinRoom="a rejoint le salon.",
leaveRoom="a quitté le salon.",
-- ready="READY",
-- set="SET",
champion="$1 a gagné",
chatRemain="En ligne : ",
chatStart="--------Début des logs--------",
@@ -178,6 +179,7 @@ return{
Beepbox
GFIE
Goldwave
FL Mobile
Libs utilisées:
Cold_Clear [MinusKelvin]
json.lua [rxi]
@@ -247,11 +249,10 @@ return{
reTime="Délai de démarrage",
RS="Système de rotation",
layout="Disposition",
-- dataSaving="Data saving",
autoPause="Mettre en pause en cas de perte de focus",
swap="Combinaison de touches (changer le mode d'attaque)",
fine="Son d'erreur de Finesse",
appLock="Verrouillage d'appli (MDP : 6+26)",
-- dataSaving="Data saving",
-- simpMode="Simple mode",
},
setting_video={

View File

@@ -102,6 +102,7 @@ return{
joinRoom="Entrou a sala.",
leaveRoom="Saiu da sala.",
-- ready="READY",
-- set="SET",
-- champion="$1 won",
chatRemain="Online: ",
chatStart="------Começo do log------",
@@ -202,6 +203,7 @@ return{
Beepbox
GFIE
Goldwave
FL Mobile
Libs used:
Cold_Clear [MinusKelvin]
json.lua [rxi]
@@ -276,11 +278,10 @@ return{
reTime="Demora iniciação",
RS="Sistema de rotação",
layout="Layout",
-- dataSaving="Data saving",
autoPause="Pausar quando foco for perco",
swap="Combinação de tecla(Mudar modo de atk)",
fine="Som Falha de destreza",
appLock="App Lock (Senha: 6+26)",
-- dataSaving="Data saving",
-- simpMode="Simple mode",
},
setting_video={

View File

@@ -102,6 +102,7 @@ return{
joinRoom="entró a la sala.",
leaveRoom="salió de la sala.",
-- ready="READY",
-- set="SET",
champion="$1 ganó!",
chatRemain="Usuarios en línea: ",
chatStart="------Comienzo del historial------",
@@ -179,6 +180,7 @@ return{
Beepbox
GFIE
Goldwave
FL Mobile
Librerías usadas:
Cold_Clear [MinusKelvin]
json.lua [rxi]
@@ -253,11 +255,10 @@ return{
reTime="Retraso de Inicio",
RS="Sistema de Rotación",
layout="Diseño",
-- dataSaving="Data saving",
autoPause="Pausar cuando la ventana no está enfocada",
swap="Combinación de Teclas (Cambiar Modo de Ataque)",
fine="Sonido de Error de Finesse",
appLock="Bloqueo de App (Contraseña: 6+26)",
-- dataSaving="Data saving",
simpMode="Modo Sencillo",
},
setting_video={

View File

@@ -134,11 +134,10 @@ return{
reTime="3-2-1",
RS="''?",
layout="=-=-=",
dataSaving="XX.",
autoPause="A||",
swap="=+=+=",
fine="12 X 21",
appLock="?XX(=6+26)",
dataSaving="XX.",
simpMode=".",
},
setting_video={

View File

@@ -46,7 +46,6 @@ return{
createRoomTooFast="手痒要开这么多房间?",
createRoomSuccessed="创好了",
started="开了",
ready="预备!",
champion="神仙是 $1",
stat={

View File

@@ -100,7 +100,8 @@ return{
started="游戏中",
joinRoom="进入房间",
leaveRoom="离开房间",
ready="准备!",
ready="各就各位!",
set="预备!",
champion="$1 获胜",
chatRemain="人数:",
chatStart="------消息的开头------",
@@ -201,6 +202,7 @@ return{
Beepbox
GFIE
Goldwave
FL Mobile
使用库:
Cold_Clear [MinusKelvin]
json.lua [rxi]
@@ -275,11 +277,10 @@ return{
reTime="开局等待时间",
RS="旋转系统",
layout="外观",
dataSaving="省流模式",
autoPause="失去焦点自动暂停",
swap="组合键切换攻击模式",
fine="极简操作提示音",
appLock="软件锁(密码6+26)",
dataSaving="省流模式",
simpMode="简洁模式",
},
setting_video={
@@ -767,7 +768,10 @@ return{
"(a+b)³=a³+3a²b+3ab²+b³",
"(RUR'U')R'FR2U'R'U'(RUR'F')",
"《多练的力量》",
"《教育的力量》",
"《梦想的意义》",
"《天赋的力量》",
"《游戏的意义》",
"《知识的力量》",
"\"TechminOS\"",
"↑↑↓↓←→←→BA",
@@ -786,10 +790,11 @@ return{
"3.1415926535897932384 ? ? ?",
"3next 1hold?",
"40行世界纪录:15.654s by VinceHD",
"626r/s",
"6236326236327175",
"6next 1hold!",
"6next 6hold?!",
"7宽三SZ架空捐了解一下",
"9999in1",
"按钮风格进化史",
"把手机调到特殊的日期也许会发生什么",
"报时机器人:新的一天开始了",
@@ -836,11 +841,10 @@ return{
"方块默认出现的方向都是重心在下哦",
"方块能吃吗",
"服务器随时爆炸",
"开启省流模式后将不会加载用户头像(应该能省不少流吧)",
"感觉自己明明按键了但是没反应?你真的按到了吗?",
"感觉自己速度到上限了?试着把das调低一点",
"感谢群友帮忙想tip",
"感谢Orzmic为这个tip显示框提供灵感",
"感谢Orzmic为这个tip显示框提出意见",
"刚接触方块的话多玩玩就行,40行两分钟以外没啥好针对性练习的",
"刚开始练全隐形可以尽量堆平,留一列消四",
"隔断消除即将到来!",
@@ -864,6 +868,7 @@ return{
"健康小贴士:玩游戏多眨眼,不然会干眼病",
"键位是可以自定义的",
"觉得移动速度太慢或太快,手感不好?快去设置调整DAS/ARR",
"开启省流模式后将不会加载用户头像(应该能省不少流吧)",
"快去打一把100%极简看看会怎样",
"来学编程,好玩的",
"六连块总共有…?那不重要,不会做的",
@@ -877,18 +882,6 @@ return{
"魔方也是方块(确信",
"你的双手是为了你的一生服务的,而不是Techmino",
"你今天的人品值是:"..math.random(100),
"你今天的人品值是:0.22",
"你今天的人品值是:0.26",
"你今天的人品值是:12.7",
"你今天的人品值是:2.6",
"你今天的人品值是:22",
"你今天的人品值是:26",
"你今天的人品值是:28.3",
"你今天的人品值是:6.26",
"你今天的人品值是:6.26",
"你今天的人品值是:62.6",
"你今天的人品值是:87.2",
"你今天的人品值是:9999%",
"你可以从统计页面打开游戏存档目录",
"你们考虑过Z酱的感受吗?没有!你们只考虑你自己。",
"你说彩蛋?嗯…算是有,可以找找",
@@ -902,7 +895,9 @@ return{
"去玩别的方块的时候记得没有Ospin!",
"全球应该没人能全S评价(大爆炸不算)",
"群友翻译的中文方块百科全书! tetris.huijiwiki.com",
"让他三尺又何妨",
"如果打开简洁模式那这个菜单就没有彩蛋了",
"如何O-spin: 一秒转626圈(误",
"三连块只有2种",
"三岁通关困难马拉松",
"上面这个不是录像,是机器人实时在玩",
@@ -911,21 +906,25 @@ return{
"手机玩也可以外接键盘哦",
"术语不认识?去帮助-词典里查查吧",
"水平是随着时间一点点提升的,不是几天几星期就能玩好的哦",
"睡眠不足会引起不可逆的脑损伤(变傻)",
"四连块总共7种",
"虽然极简连击和极简率计算看着很怪,但以后你会发现还挺科学!",
"提前旋转等功能可以用来救命",
"天哪,我竟然是一条凑数tip",
"退一步海阔天空",
"挖掘能力在对战里非常非常非常重要!!!!",
"玩到一半弹出消息框?快去设置禁止弹窗",
"玩得开心的话游戏作者也会很开心哦",
"为了保护玩家们的健康,本游戏有一个临时的简易防沉迷系统!(不过估计你也触发不了/笑)",
"为什么关卡那么少!因为前一模式成绩连D都没达到,再加把劲吧~",
"我曾经在极度愤怒的时候15秒消了40行",
"我们联合!",
"我们是不是第一个在方块游戏做tip的?",
"我是一条凑数tip",
"我也不知道分数有啥用应该只是好看的,建议别管他,只看关卡要求你做啥",
"我也是一条凑数tip",
"我一个滑铲就挖了个11renPC",
"我永远喜…",
"无聊翻翻设置是好习惯",
"五连块总共18种",
"物理hold了解一下",
@@ -1060,7 +1059,6 @@ return{
{C.lC,"26连T2来一个?"},
{C.lC,"Xspin",C.Z,"是啥"},
{C.lH,"腱鞘炎警告"},
{C.lH,"看起来是个计算器,其实…"},
{C.lH,"没学过编曲,音乐都是自己瞎写的,觉得不好听就去设置关了吧"},
{C.lH,"秘密数字:626"},
{C.lH,"你有一个好"},

View File

@@ -19,6 +19,7 @@ return{
drop=0,lock=15,
wait=15,fall=6,
nextCount=3,
sequence='hisPool',
visible='fast',
freshLimit=15,
dropPiece=score,

View File

@@ -8,7 +8,7 @@ return{
drop=0,lock=15,
wait=10,fall=10,
nextCount=2,
sequence='his4',
sequence='his',
task=function(P)P.modeData.target=12 end,
dropPiece=function(P)
local p=P.modeData.pt+P.lastPiece.row

View File

@@ -10,14 +10,9 @@ return{
},
load=function()
PLY.newPlayer(1)
local N=2
for i=1,#PLY_NET do
if PLY_NET[i].uid==USER.uid then
PLAYERS[1].sid=PLY_NET[1].sid
else
PLY.newRemotePlayer(N,false,PLY_NET[i])
N=N+1
end
PLAYERS[1].sid=netPLY.getSID(USER.uid)
for i=2,netPLY.getCount()do
PLY.newRemotePlayer(i,false,netPLY.getPLY(i))
end
end,
}

View File

@@ -1,15 +1,24 @@
local data=love.data
local ins,rem=table.insert,table.remove
local rem=table.remove
local WS,TIME=WS,TIME
local NET={
connected=false,
allow_online=false,
allReady=false,
serverGaming=false,
roomList={},
accessToken=false,
rid=false,
rsid=false,
roomList={},
roomInfo={
-- rid=false,
name=false,
-- type=false,
private=false,
-- count=false,
capacity=false,
},
allReady=false,
connectingStream=false,
streamRoomID=false,
serverGaming=false,
}
local mesType={
@@ -107,7 +116,7 @@ function NET.wsconn_stream()
WS.connect('stream','/stream',JSON.encode{
uid=USER.uid,
accessToken=NET.accessToken,
rid=NET.rsid,
rid=NET.streamRoomID,
})
TASK.new(NET.updateWS_stream)
end
@@ -167,27 +176,34 @@ function NET.fetchRoom()
})
end
end
function NET.createRoom(roomType,name)
function NET.createRoom(roomType,roomName)
if NET.lock('enterRoom',1.26)then
NET.roomInfo.name=roomName or"?"
NET.roomInfo.type=roomType or"?"
NET.roomInfo.private=false
NET.roomInfo.capacity="?"
WS.send('play',JSON.encode{
action=1,
data={
type=roomType,
name=name,
name=roomName,
password=nil,
config=dumpBasicConfig(),
}
})
end
end
function NET.enterRoom(roomID,password)
function NET.enterRoom(room,password)
if NET.lock('enterRoom',1.26)then
SFX.play('reach',.6)
NET.rid=roomID
NET.roomInfo.name=room.name or"?"
NET.roomInfo.type=room.type or"?"
NET.roomInfo.private=not not password
NET.roomInfo.capacity=room.capacity or"?"
WS.send('play',JSON.encode{
action=2,
data={
rid=roomID,
rid=room.rid,
config=dumpBasicConfig(),
password=password,
}
@@ -351,42 +367,38 @@ function NET.updateWS_play()
elseif res.action==2 then--Player join
if res.type=='Self'then
--Enter new room
TABLE.cut(PLY_NET)
netPLY.clear()
if d.players then
for _,p in next,d.players do
ins(PLY_NET,p.uid==USER.uid and 1 or #PLY_NET+1,{
netPLY.add{
uid=p.uid,
username=p.username,
sid=p.sid,
ready=p.ready,
config=p.config,
})
}
end
end
loadGame('netBattle',true,true)
else
--Load other players
ins(PLY_NET,{
netPLY.add{
uid=d.uid,
username=d.username,
sid=d.sid,
ready=d.ready,
config=d.config,
})
if SCN.socketRead then SCN.socketRead('Join',d)end
}
if SCN.socketRead then SCN.socketRead('join',d)end
NET.allReady=false
end
elseif res.action==3 then--Player leave
if not d.uid then
NET.wsclose_stream()
SCN.back()
NET.unlock('quit')
SCN.back()
else
for i=1,#PLY_NET do
if PLY_NET[i].sid==d.sid then
rem(PLY_NET,i)
break
end
end
netPLY.remove(d.sid)
for i=1,#PLAYERS do
if PLAYERS[i].sid==d.sid then
rem(PLAYERS,i)
@@ -399,51 +411,25 @@ function NET.updateWS_play()
break
end
end
if SCN.socketRead then SCN.socketRead('Leave',d)end
if SCN.socketRead then SCN.socketRead('leave',d)end
end
elseif res.action==4 then--Player talk
if SCN.socketRead then SCN.socketRead('Talk',d)end
if SCN.socketRead then SCN.socketRead('talk',d)end
elseif res.action==5 then--Player change settings
if tostring(USER.uid)~=d.uid then
for i=1,#PLY_NET do
if PLY_NET[i].uid==d.uid then
PLY_NET[i].config=d.config
break
end
end
end
netPLY.setConf(d.uid,d.config)
elseif res.action==6 then--One ready
for i,p in next,PLY_NET do
if p.uid==d.uid then
if p.ready~=d.ready then
p.ready=d.ready
if not d.ready then NET.allReady=false end
SFX.play('spin_0',.6)
if i==1 then
NET.unlock('ready')
elseif not PLY_NET[1].ready then
for j=2,#PLY_NET do
if not PLY_NET[j].ready then
goto BREAK_notAllReady
end
end
SFX.play('blip_2',.5)
::BREAK_notAllReady::
end
end
break
end
end
netPLY.setReady(d.uid,d.ready)
elseif res.action==7 then--All Ready
SFX.play('reach',.6)
NET.allReady=true
elseif res.action==8 then--Set
NET.rsid=d.rid
NET.streamRoomID=d.rid
NET.allReady=false
NET.connectingStream=true
NET.wsconn_stream()
elseif res.action==9 then--Game finished
NET.allReady=false
NET.wsclose_stream()
if SCN.socketRead then SCN.socketRead('Finish',d)end
if SCN.socketRead then SCN.socketRead('finish',d)end
end
else
WS.alert('play')
@@ -472,7 +458,8 @@ function NET.updateWS_stream()
if res.type=='Connect'then
NET.unlock('wsc_stream')
elseif res.action==0 then--Game start
SCN.socketRead('Go',d)
NET.connectingStream=false
SCN.socketRead('go',d)
elseif res.action==1 then--Game finished
--?
elseif res.action==2 then--Player join
@@ -487,7 +474,7 @@ function NET.updateWS_stream()
end
end
elseif res.action==5 then--Receive stream
SCN.socketRead('Stream',d)
SCN.socketRead('stream',d)
end
else
WS.alert('stream')

221
parts/netPlayer.lua Normal file
View File

@@ -0,0 +1,221 @@
local gc=love.graphics
local rnd,min=math.random,math.min
local sin,cos=math.sin,math.cos
local ins,rem=table.insert,table.remove
local posLists={
--1~5
(function()
local L={}
for i=1,5 do
L[i]={x=70,y=20+90*i,w=1000,h=80}
end
return L
end)(),
--6~17
(function()
local L={}
for i=1,10 do
L[i]={x=40,y=60+55*i,w=520,h=50}
end
for i=1,7 do
L[10+i]={x=600,y=60+55*i,w=520,h=50}
end
return L
end)(),
--18~31
(function()
local L={}
for i=1,11 do L[i]= {x=40,y=65+50*i,w=330,h=45}end
for i=1,11 do L[11+i]= {x=400,y=65+50*i,w=330,h=45}end
for i=1,9 do L[22+i]= {x=760,y=65+50*i,w=330,h=45}end
return L
end)(),
--32~49
(function()
local L={}
for i=1,10 do L[i]= {x=30,y=60+50*i,w=200,h=45}end
for i=1,10 do L[10+i]= {x=240,y=60+50*i,w=200,h=45}end
for i=1,10 do L[20+i]= {x=450,y=60+50*i,w=200,h=45}end
for i=1,10 do L[30+i]= {x=660,y=60+50*i,w=200,h=45}end
for i=1,9 do L[40+i]= {x=870,y=60+50*i,w=200,h=45}end
return L
end)(),
--50~99
(function()
local L={}
for i=1,11 do L[i]= {x=30,y=60+50*i,w=100,h=45}end
for i=1,11 do L[i+11]= {x=135,y=60+50*i,w=100,h=45}end
for i=1,11 do L[i+22]= {x=240,y=60+50*i,w=100,h=45}end
for i=1,11 do L[i+33]= {x=345,y=60+50*i,w=100,h=45}end
for i=1,11 do L[i+44]= {x=450,y=60+50*i,w=100,h=45}end
for i=1,11 do L[i+55]= {x=555,y=60+50*i,w=100,h=45}end
for i=1,11 do L[i+66]= {x=660,y=60+50*i,w=100,h=45}end
for i=1,11 do L[i+77]= {x=765,y=60+50*i,w=100,h=45}end
for i=1,7 do L[i+88]= {x=870,y=60+50*i,w=100,h=45}end
for i=1,4 do L[i+95]= {x=975,y=60+50*i,w=100,h=45}end
return L
end)(),
}
local posList
local PLY=setmetatable({},{
__index=function(self,uid)
for _,p in next,self do
if p.uid==uid then
return p
end
end
end
})
local netPLY={list=PLY}
local function freshPosList()
if #PLY<=5 then
posList=posLists[1]
elseif #PLY<=17 then
posList=posLists[2]
elseif #PLY<=31 then
posList=posLists[3]
elseif #PLY<=49 then
posList=posLists[4]
else--if #PLY<=99 then
posList=posLists[5]
end
end
function netPLY.clear()for _=1,netPLY.getCount()do rem(PLY)end end
function netPLY.add(p)
ins(PLY,p.uid==USER.uid and 1 or #PLY+1,p)
local a=rnd()*6.2832
p.x,p.y,p.w,p.h=640+2600*cos(a),360+2600*sin(a),47,47
freshPosList()
end
function netPLY.remove(sid)
for i=1,#PLY do
if PLY[i].sid==sid then
rem(PLY,i)
break
end
end
freshPosList()
end
function netPLY.getCount()return #PLY end
function netPLY.getPLY(i)return PLY[i]end
function netPLY.getUsername(uid)return PLY[uid].username end
function netPLY.getSID(uid)return PLY[uid].sid end
function netPLY.getSelfReady()return PLY[1].ready end
function netPLY.setPlayerObj(ply,p) ply.p=p end
function netPLY.setConf(uid,config)PLY[uid].config=config end
function netPLY.setReady(uid,ready)
for i,p in next,PLY do
if p.uid==uid then
if p.ready~=ready then
p.ready=ready
if not ready then NET.allReady=false end
SFX.play('spin_0',.6)
if i==1 then
NET.unlock('ready')
elseif not PLY[1].ready then
for j=2,#PLY do
if not PLY[j].ready then
return
end
end
SFX.play('blip_2',.5)
end
end
return
end
end
end
function netPLY.resetReady()
for i=1,#PLY do
PLY[i].ready=false
end
end
local selP,mouseX,mouseY
function netPLY.mouseMove(x,y)
selP=nil
for i=1,#PLY do
local p=PLY[i]
if x>p.x and y>p.y and x<p.x+p.w and y<p.y+p.h then
mouseX,mouseY=x,y
selP=p
break
end
end
end
function netPLY.update(dt)
for i=1,#PLY do
local p=PLY[i]
local t=posList[i]
p.x=p.x*.9+t.x*.1
p.y=p.y*.9+t.y*.1
p.w=p.w*.9+t.w*.1
p.h=p.h*.9+t.h*.1
end
end
local stencilW,stencilH
local function plyStencil()
gc.rectangle('fill',0,0,stencilW,stencilH)
end
function netPLY.draw()
for i=1,#PLY do
local p=PLY[i]
gc.translate(p.x,p.y)
--Rectangle
gc.setColor(COLOR[p.ready and'G'or'Z'])
gc.setLineWidth(2)
gc.rectangle('line',0,0,p.w,p.h)
--Stencil
stencilW,stencilH=p.w,p.h
gc.setStencilTest('equal',1)
gc.stencil(plyStencil,'replace',1)
gc.setColor(1,1,1)
--Avatar
local avatarSize=min(p.h,50)/128*.9
gc.draw(USERS.getAvatar(p.uid),2,2,nil,avatarSize)
--UID & Username
if p.h>=47 then
setFont(40)
gc.print("#"..p.uid,50,-5)
gc.print(p.username,210,-5)
else
setFont(159)
gc.print("#"..p.uid,p.h,-2)
setFont(30)
gc.print(p.username,p.h,8)
end
gc.setStencilTest()
gc.translate(-p.x,-p.y)
end
if selP then
gc.translate(min(mouseX,880),min(mouseY,460))
gc.setColor(.2,.2,.2,.7)
gc.rectangle('fill',0,0,400,260)
gc.setColor(1,1,1)
gc.setLineWidth(2)
gc.rectangle('line',0,0,400,260)
gc.draw(USERS.getAvatar(selP.uid),5,5,nil,.5)
setFont(30)
gc.print("#"..selP.uid,75,0)
setFont(35)
gc.print(selP.username,75,25)
gc.translate(-min(mouseX,880),-min(mouseY,460))
end
end
return netPLY

View File

@@ -2,39 +2,54 @@ local gc=love.graphics
local gc_push,gc_pop,gc_clear,gc_origin=gc.push,gc.pop,gc.clear,gc.origin
local gc_translate,gc_scale,gc_rotate=gc.translate,gc.scale,gc.rotate
local gc_setCanvas,gc_setShader=gc.setCanvas,gc.setShader
local gc_draw,gc_line,gc_rectangle,gc_circle=gc.draw,gc.line,gc.rectangle,gc.circle
local gc_draw,gc_line,gc_rectangle=gc.draw,gc.line,gc.rectangle
local gc_print,gc_printf=gc.print,gc.printf
local gc_setColor,gc_setLineWidth=gc.setColor,gc.setLineWidth
local gc_stencil,gc_setStencilTest=gc.stencil,gc.setStencilTest
local int,ceil,rnd=math.floor,math.ceil,math.random
local max,min,sin,modf=math.max,math.min,math.sin,math.modf
local setFont,mDraw,mStr=setFont,mDraw,mStr
local TIME=TIME
local setFont,mDraw,mStr,mText=setFont,mDraw,mStr,mText
local SKIN,TEXTURE,IMG=SKIN,TEXTURE,IMG
local TEXT,COLOR,GAME,TIME=TEXT,COLOR,GAME,TIME
local shader_alpha,shader_lighter=SHADER.alpha,SHADER.lighter
local drawableText,missionEnum,minoColor=drawableText,missionEnum,minoColor
local frameColorList={
[0]=COLOR.Z,
COLOR.lG,
COLOR.lB,
COLOR.lV,
COLOR.lO,
local RCPB={5,33,195,33,100,5,100,60}
local frameColorList={[0]=COLOR.Z,COLOR.lG,COLOR.lB,COLOR.lV,COLOR.lO}
local attackColor={
{COLOR.dH,COLOR.Z},
{COLOR.H,COLOR.Z},
{COLOR.lV,COLOR.Z},
{COLOR.lR,COLOR.Z},
{COLOR.dG,COLOR.C},
}
--local function drawCell(y,x,id)gc_draw(SKIN.curText[id],30*x-30,-30*y)end
local function stencilBoard()gc_rectangle('fill',0,-10,300,610)end
local function drawGrid(P)
local d=P.fieldBeneath+P.fieldUp
gc_setLineWidth(1)
gc_setColor(1,1,1,P.gameEnv.grid)
for x=1,9 do
gc_line(30*x,-10,30*x,600)
end
gc_push('transform')
gc_translate(0,d-30*int(d/30))
for y=0,19 do
gc_line(0,30*y,300,30*y)
end
gc_pop()
local hideBoardStencil={
up=function()gc_rectangle('fill',0,0,300,300)end,
down=function()gc_rectangle('fill',0,300,300,300)end,
all=function()gc_rectangle('fill',0,0,300,600)end,
}
local dialFrame=DOGC{70,70,
{'setLW',2},
{'dCirc',35,35,30,6},
{'setCL',1,1,1,.6},
{'setLW',4},
{'dCirc',35,35,30,6},
}
local multiple=DOGC{15,15,
{'setLW',3},
{'line',2,2,12,12},
{'line',2,12,12,2},
}
local gridLines do
local L={300,640,{'setLW',2}}
for x=1,9 do table.insert(L,{'line',30*x,0,30*x,640})end
for y=0,19 do table.insert(L,{'line',0,40+30*y,300,40+30*y})end
gridLines=DOGC(L)
end
local LDmarks=gc.newSpriteBatch(DOGC{14,5,{'clear',1,1,1}},15,'static')
for i=0,14 do LDmarks:add(3+20*i,615)end
local function boardTransform(mode)
if mode then
if mode=="U-D"then
@@ -49,15 +64,27 @@ local function boardTransform(mode)
end
end
end
local function applyFieldOffset(P,notNorm)
if not notNorm then gc_translate(150,0)end
local O=P.fieldOff
gc_translate(O.x+150,O.y+300)
gc_rotate(O.a)
gc_translate(-150,-300)
end
local function stencilBoard()gc_rectangle('fill',0,-10,300,610)end
local function drawGrid(P,alpha)
gc_setColor(1,1,1,alpha)
gc_draw(gridLines,0,-10+(P.fieldBeneath+P.fieldUp)%30)
end
local function drawRow(h,V,L,showInvis)
local texture=SKIN.curText
local t=TIME()*4
for i=1,10 do
if L[i]>0 then
if V[i]>0 then
local a=V[i]*.05
gc_setColor(1,1,1,a)
gc_draw(texture[L[i]],30*i-30,-30*h)-- drawCell(j,i,L[i])
gc_setColor(1,1,1,V[i]*.05)
gc_draw(texture[L[i]],30*i-30,-30*h)
elseif showInvis then
gc_setColor(1,1,1,.3+.08*sin(.5*(h-i)+t))
gc_rectangle('fill',30*i-30,-30*h,30,30)
@@ -72,7 +99,7 @@ local function drawField(P)
if P.falling==-1 then--Blocks only
if ENV.upEdge then
gc_setShader(SHADER.lighter)
gc_setShader(shader_lighter)
gc_translate(0,-4)
--<drawRow>
for j=start,min(start+21,#F)do drawRow(j,V[j],F[j])end
@@ -90,7 +117,7 @@ local function drawField(P)
local h=1
if ENV.upEdge then
gc_push('transform')
gc_setShader(SHADER.lighter)
gc_setShader(shader_lighter)
gc_translate(0,-4)
--<drawRow>
for j=start,min(start+21,#F)do
@@ -149,7 +176,7 @@ local function drawFXs(P)
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])
gc_draw(texture[S[1]],30*S[2]-30,-30*S[3])
end
--ClearFX
@@ -168,13 +195,13 @@ local function drawGhost(P,clr)
local CB=P.cur.bk
for i=1,#CB do for j=1,#CB[1]do
if CB[i][j]then
gc_draw(texture[clr],30*(j+P.curX-1)-30,-30*(i+P.ghoY-1))-- drawCell(i+P.ghoY-1,j+P.curX-1,clr)
gc_draw(texture[clr],30*(j+P.curX-1)-30,-30*(i+P.ghoY-1))
end
end end
end
local function drawBlockOutline(P,texture,trans)
SHADER.alpha:send("a",trans)
gc_setShader(SHADER.alpha)
shader_alpha:send("a",trans)
gc_setShader(shader_alpha)
local CB=P.cur.bk
for i=1,#CB do for j=1,#CB[1]do
if CB[i][j]then
@@ -190,11 +217,11 @@ local function drawBlockOutline(P,texture,trans)
end
local function drawBlock(P,clr)
gc_setColor(1,1,1)
local texture=SKIN.curText
local texture=SKIN.curText[clr]
local CB=P.cur.bk
for i=1,#CB do for j=1,#CB[1]do
if CB[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)
gc_draw(texture,30*(j+P.curX-1)-30,-30*(i+P.curY-1))
end
end end
end
@@ -217,13 +244,6 @@ local function drawBoarders(P)
gc_rectangle('line',301,-3,15,604)--AtkBuffer boarder
gc_rectangle('line',-16,-3,15,604)--B2b bar boarder
end
local attackColor={
{COLOR.dH,COLOR.Z},
{COLOR.H,COLOR.Z},
{COLOR.lV,COLOR.Z},
{COLOR.lR,COLOR.Z},
{COLOR.dG,COLOR.C},
}
local function drawBuffer(P)
local h=0
for i=1,#P.atkBuffer do
@@ -267,8 +287,8 @@ local function drawB2Bbar(P)
gc_setColor(1,1,1)
gc_rectangle('fill',-15,b<40 and 568.5 or 118.5,13,3)
end
--LockDelay indicator
end
local function drawLDI(P)--Lock Delay Indicator
if P.gameEnv.easyFresh then
gc_setColor(1,1,1)
else
@@ -277,18 +297,17 @@ local function drawB2Bbar(P)
if P.lockDelay>=0 then
gc_rectangle('fill',0,602,300*P.lockDelay/P.gameEnv.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
if P.freshTime>0 then
LDmarks:setDrawRange(1,min(P.freshTime,15))
gc_draw(LDmarks)
end
end
local function drawHold(P)
local ENV=P.gameEnv
if ENV.holdCount==0 then return end
local holdQueue=P.holdQueue
local N=ENV.holdCount*72
local texture=SKIN.curText
gc_push('transform')
gc_translate(-140,36)
gc_setColor(0,0,0,.4)gc_rectangle('fill',0,0,124,N+8)
@@ -297,21 +316,22 @@ local function drawHold(P)
mText(drawableText.hold,62,-51)
gc_setColor(1,1,1)
if #P.holdQueue<P.gameEnv.holdCount and P.nextQueue[1]then
if #holdQueue<ENV.holdCount and P.nextQueue[1]then
N=1
else
N=P.holdTime+1
end
gc_push('transform')
gc_translate(62,40)
for n=1,#P.holdQueue do
gc_translate(62,40)
for n=1,#holdQueue do
if n==N then gc_setColor(.6,.4,.4)end
local bk,clr=P.holdQueue[n].bk,P.holdQueue[n].color
local bk,clr=holdQueue[n].bk,holdQueue[n].color
local texture=SKIN.curText[clr]
local k=#bk>2 and 2.2/#bk or 1
gc_scale(k)
for i=1,#bk do for j=1,#bk[1]do
if bk[i][j]then
gc_draw(texture[clr],30*(j-#bk[1]*.5)-30,-30*(i-#bk*.5))-- drawCell(i+1.36-#B*.5,j+2.06-#B[1]*.5,clr)
gc_draw(texture,30*(j-#bk[1]*.5)-30,-30*(i-#bk*.5))
end
end end
gc_scale(1/k)
@@ -320,59 +340,36 @@ local function drawHold(P)
gc_pop()
gc_pop()
end
local RCPB={5,33,195,33,100,5,100,60}
local hideBoardStencil={
up=function()gc_rectangle('fill',0,0,300,300)end,
down=function()gc_rectangle('fill',0,300,300,300)end,
all=function()gc_rectangle('fill',0,0,300,600)end,
}
local function drawDial(x,y,speed)
gc_setColor(1,1,1)
setFont(25)
mStr(int(speed),x,y-18)
gc_setLineWidth(2)
gc_circle('line',x,y,30,6)
setFont(25)mStr(int(speed),x,y-18)
gc_draw(dialFrame,x,y,nil,nil,nil,35,35)
gc_draw(IMG.dialNeedle,x,y,2.094+(speed<=175 and .02094*speed or 4.712-52.36/(speed-125)),nil,nil,5,4)
gc_setLineWidth(4)
gc_setColor(1,1,1,.4)
gc_circle('line',x,y,30,6)
end
local function drawFinesseCombo_norm(P)
if P.finesseCombo>2 then
local S=P.stat
local _=P.finesseComboTime
local t=P.finesseComboTime
local str=P.finesseCombo.."x"
if S.finesseRate==5*S.piece then
gc_setColor(.9,.9,.3,_*.2)
gc_setColor(.9,.9,.3,t*.2)
gc_print(str,20,570)
gc_setColor(.9,.9,.3,1.2-_*.1)
gc_setColor(.9,.9,.3,1.2-t*.1)
elseif S.maxFinesseCombo==S.piece then
gc_setColor(.7,.7,1,_*.2)
gc_setColor(.7,.7,1,t*.2)
gc_print(str,20,570)
gc_setColor(.7,.7,1,1.2-_*.1)
else
gc_setColor(1,1,1,_*.2)
gc_print(str,20,570)
gc_setColor(1,1,1,1.2-_*.1)
end
if _>0 then
gc_push('transform')
gc_translate(20,600)
gc_scale(1+_*.08)
gc_print(str,0,-30)
gc_pop()
gc_setColor(.7,.7,1,1.2-t*.1)
else
gc_setColor(1,1,1,t*.2)
gc_print(str,20,570)
gc_setColor(1,1,1,1.2-t*.1)
end
gc_print(str,20,600,nil,1+t*.08,nil,0,30)
end
end
local function drawFinesseCombo_remote(P)
if P.finesseCombo>2 then
local S=P.stat
local str=P.finesseCombo.."x"
if S.finesseRate==5*S.piece then
gc_setColor(.9,.9,.3)
elseif S.maxFinesseCombo==S.piece then
@@ -380,26 +377,22 @@ local function drawFinesseCombo_remote(P)
else
gc_setColor(1,1,1)
end
gc_print(str,20,570)
gc_print(P.finesseCombo.."x",20,570)
end
end
local function drawLife(life)
gc_setColor(1,1,1)
gc_draw(IMG.lifeIcon,475,595,nil,.8)
if life>3 then
gc_setColor(1,1,1)
gc_draw(IMG.lifeIcon,475,595,nil,.8)
setFont(20)
gc_print("x",503,595)
gc_print(life,517,595)
elseif life>0 then
gc_setColor(1,1,1)
for i=1,life do
gc_draw(IMG.lifeIcon,450+25*i,595,nil,.8)
end
gc_draw(multiple,502,602)
setFont(20)gc_print(life,517,595)
else
if life>1 then gc_draw(IMG.lifeIcon,500,595,nil,.8)end
if life>2 then gc_draw(IMG.lifeIcon,525,595,nil,.8)end
end
end
local function drawMission(P)
if not P.curMission then return end
local missionEnum=missionEnum
local L=P.gameEnv.mission
local cur=P.curMission
@@ -424,24 +417,20 @@ local function drawMission(P)
end
end
end
local function drawStartCounter(P)
local function drawStartCounter(count)
gc_setColor(1,1,1)
if P.frameRun<180 then
local count=179-P.frameRun
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
gc_push('transform')
gc_translate(305,220)
if count%60>45 then gc_scale(1+(count%60-45)^2*.01,1)end
setFont(95)
mStr(int(count/60+1),0,0)
gc_pop()
end
local draw={}
function draw.drawNext_norm(P)
local ENV=P.gameEnv
local texture=SKIN.curText
gc_push('transform')
gc_translate(316,36)
local N=ENV.nextCount*72
gc_setColor(0,0,0,.4)gc_rectangle('fill',0,0,124,N+8)
@@ -449,14 +438,14 @@ function draw.drawNext_norm(P)
mText(drawableText.next,62,-51)
N=1
gc_push('transform')
gc_translate(62,40)
gc_translate(62,40)
while N<=ENV.nextCount and P.nextQueue[N]do
local bk,clr=P.nextQueue[N].bk,P.nextQueue[N].color
local bk,sprite=P.nextQueue[N].bk,texture[P.nextQueue[N].color]
local k=#bk>2 and 2.2/#bk or 1
gc_scale(k)
for i=1,#bk do for j=1,#bk[1]do
if bk[i][j]then
gc_draw(texture[clr],30*(j-#bk[1]*.5)-30,-30*(i-#bk*.5))-- drawCell(i-#bk*.5,j-#bk[1]*.5,clr)
gc_draw(sprite,30*(j-#bk[1]*.5)-30,-30*(i-#bk*.5))
end
end end
gc_scale(1/k)
@@ -466,20 +455,16 @@ function draw.drawNext_norm(P)
gc_pop()
if ENV.bagLine then
local len=ENV.bagLen
local phase=-P.pieceCount%len
gc_setColor(.8,.5,.5)
for i=phase,N-1,len do
local y=72*i+3
gc_line(2+P.fieldOff.x,y,120,y)
for i=-P.pieceCount%ENV.bagLen,N-1,ENV.bagLen do--i=phase
gc_rectangle('fill',2,72*i+3,120,2)
end
end
gc_pop()
gc_translate(-316,-36)
end
function draw.drawNext_hidden(P)
local ENV=P.gameEnv
local texture=SKIN.curText
gc_push('transform')
gc_translate(316,36)
local N=ENV.nextCount*72
gc_setColor(.5,0,0,.4)gc_rectangle('fill',0,0,124,N+8)
@@ -487,14 +472,15 @@ function draw.drawNext_hidden(P)
mText(drawableText.next,62,-51)
N=min(ENV.nextStartPos,P.pieceCount+1)
gc_push('transform')
gc_translate(62,40)
while N<=ENV.nextCount and P.nextQueue[N]do
local bk,clr=P.nextQueue[N].bk,P.nextQueue[N].color
gc_translate(62,40)
local queue=P.nextQueue
while N<=ENV.nextCount and queue[N]do
local bk,sprite=queue[N].bk,texture[queue[N].color]
local k=#bk>2 and 2.2/#bk or 1
gc_scale(k)
for i=1,#bk do for j=1,#bk[1]do
if bk[i][j]then
gc_draw(texture[clr],30*(j-#bk[1]*.5)-30,-30*(i-#bk*.5))-- drawCell(i-#bk*.5,j-#bk[1]*.5,clr)
gc_draw(sprite,30*(j-#bk[1]*.5)-30,-30*(i-#bk*.5))
end
end end
gc_scale(1/k)
@@ -504,31 +490,21 @@ function draw.drawNext_hidden(P)
gc_pop()
if ENV.bagLine then
local len=ENV.bagLen
local phase=-P.pieceCount%len
gc_setColor(.8,.5,.5)
for i=phase,N-1,len do
local y=72*i+3
gc_line(2+P.fieldOff.x,y,120,y)
for i=-P.pieceCount%ENV.bagLen,N-1,ENV.bagLen do--i=phase
gc_rectangle('fill',2,72*i+3,120,2)
end
end
gc_pop()
gc_translate(-316,-36)
end
draw.applyFieldOffset=applyFieldOffset
function draw.applyFieldOffset(P,notNorm)
if not notNorm then gc_translate(150,0)end
local O=P.fieldOff
gc_translate(O.x,O.y)
gc_translate(150,300)
gc_rotate(O.a)
gc_translate(-150,-300)
end
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)
gc_push('transform')
draw.applyFieldOffset(P)
applyFieldOffset(P)
gc_line(0,600-30*r,300,600-30*r)
gc_pop()
end
@@ -539,11 +515,12 @@ function draw.norm(P)
local FBN,FUP=P.fieldBeneath,P.fieldUp
local t=TIME()
gc_push('transform')
gc_translate(P.x,P.y)gc_scale(P.size)
gc_translate(P.x,P.y)
gc_scale(P.size)
--Field-related things
gc_push('transform')
draw.applyFieldOffset(P)
applyFieldOffset(P)
--Fill field
gc_setColor(0,0,0,.6)
@@ -556,7 +533,7 @@ function draw.norm(P)
boardTransform(ENV.flipBoard)
--Draw grid
if ENV.grid then drawGrid(P)end
if ENV.grid then drawGrid(P,ENV.grid)end
--Move camera
gc_translate(0,600+FBN+FUP)
@@ -585,10 +562,12 @@ function draw.norm(P)
local centerX=30*(P.curX+P.cur.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.cur.sc[1])+15,nil,nil,nil,4,4)
if ENV.ghost then
drawGhost(P,curColor)
if ENV.center then
gc_setColor(1,1,1,trans*ENV.center)
gc_draw(IMG.spinCenter,centerX,-30*(P.ghoY+P.cur.sc[1])+15,nil,nil,nil,4,4)
end
end
local dy=ENV.smooth and P.ghoY~=P.curY and(P.dropDelay/ENV.drop-1)*30 or 0
@@ -624,6 +603,7 @@ function draw.norm(P)
drawBoarders(P)
drawBuffer(P)
drawB2Bbar(P)
drawLDI(P)
drawHold(P)
P:drawNext()
@@ -683,9 +663,9 @@ function draw.norm(P)
gc_setColor(COLOR.N)gc_print(tm,20,540)
drawFinesseCombo_norm(P)
drawLife(P.life)
if P.life>0 then drawLife(P.life)end
drawMission(P)
drawStartCounter(P)
if P.frameRun<180 then drawStartCounter(179-P.frameRun)end
gc_pop()
end
function draw.norm_remote(P)
@@ -693,11 +673,12 @@ function draw.norm_remote(P)
local FBN,FUP=P.fieldBeneath,P.fieldUp
local t=TIME()
gc_push('transform')
gc_translate(P.x,P.y)gc_scale(P.size)
gc_translate(P.x,P.y)
gc_scale(P.size)
--Field-related things
gc_push('transform')
draw.applyFieldOffset(P)
applyFieldOffset(P)
--Draw username
setFont(30)
@@ -715,7 +696,7 @@ function draw.norm_remote(P)
boardTransform(ENV.flipBoard)
--Draw grid
if ENV.grid then drawGrid(P)end
if ENV.grid then drawGrid(P,ENV.grid)end
--Move camera
gc_translate(0,600+FBN+FUP)
@@ -744,10 +725,12 @@ function draw.norm_remote(P)
local centerX=30*(P.curX+P.cur.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.cur.sc[1])+15,nil,nil,nil,4,4)
if ENV.ghost then
drawGhost(P,curColor)
if ENV.center then
gc_setColor(1,1,1,trans*ENV.center)
gc_draw(IMG.spinCenter,centerX,-30*(P.ghoY+P.cur.sc[1])+15,nil,nil,nil,4,4)
end
end
local dy=ENV.smooth and P.ghoY~=P.curY and(P.dropDelay/ENV.drop-1)*30 or 0
@@ -774,6 +757,7 @@ function draw.norm_remote(P)
drawBoarders(P)
drawBuffer(P)
drawB2Bbar(P)
drawLDI(P)
drawHold(P)
P:drawNext()
@@ -816,21 +800,21 @@ function draw.norm_remote(P)
--Score & Time
setFont(25)
local tm=int(P.stat.time*100)*.01
local time=int(P.stat.time*100)*.01
gc_setColor(0,0,0,.3)
gc_print(P.score1,18,509)
gc_print(tm,18,539)
gc_print(time,18,539)
gc_setColor(COLOR.lY)gc_print(P.score1,20,510)
gc_setColor(COLOR.N)gc_print(tm,20,540)
gc_setColor(COLOR.N)gc_print(time,20,540)
drawFinesseCombo_remote(P)
drawLife(P.life)
if P.life>0 then drawLife(P.life)end
drawMission(P)
drawStartCounter(P)
if P.frameRun<180 then drawStartCounter(179-P.frameRun)end
gc_pop()
end
function draw.small(P)
--Draw content
--Update canvas
P.frameWait=P.frameWait-1
if P.frameWait==0 then
P.frameWait=10
@@ -876,13 +860,12 @@ function draw.small(P)
--Draw Canvas
gc_setColor(1,1,1)
gc_draw(P.canvas,P.x,P.y,nil,P.size*10)
local size=P.size
gc_draw(P.canvas,P.x,P.y,nil,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)
gc_setColor(1,0,0)
gc_rectangle('fill',P.x+40*size,P.y+40*size,160*size,160*size)
end
setFont(30)
end
function draw.demo(P)
local _
@@ -894,7 +877,7 @@ function draw.demo(P)
gc_translate(P.x,P.y)
gc_scale(P.size)
gc_push('transform')
draw.applyFieldOffset(P,true)
applyFieldOffset(P,true)
--Frame
gc_setColor(0,0,0,.6)
@@ -920,13 +903,12 @@ function draw.demo(P)
gc_pop()
local blockImg=TEXTURE.miniBlock
local libColor=minoColor
local skinSet=ENV.skin
--Draw hold
local N=1
while P.holdQueue[N]do
local id=P.holdQueue[N].id
_=libColor[skinSet[id]]
_=minoColor[skinSet[id]]
gc_setColor(_[1],_[2],_[3],.3)
_=blockImg[id]
gc_draw(_,15,40*N-10,nil,16,nil,0,_:getHeight()*.5)
@@ -937,7 +919,7 @@ function draw.demo(P)
N=1
while N<=ENV.nextCount and P.nextQueue[N]do
local id=P.nextQueue[N].id
_=libColor[skinSet[id]]
_=minoColor[skinSet[id]]
gc_setColor(_[1],_[2],_[3],.3)
_=blockImg[id]
gc_draw(_,285,40*N-10,nil,16,nil,_:getWidth(),_:getHeight()*.5)

View File

@@ -1,14 +1,13 @@
local Player=require"parts.player.player"
local getSeqGen=require"parts.player.getSeqGen"
local seqGenerators=require"parts.player.seqGenerators"
local gameEnv0=require"parts.player.gameEnv0"
local rnd,max=math.random,math.max
local ins=table.insert
local PLY={
update=require"parts.player.update",
draw=require"parts.player.draw",
}
local ply_draw=require"parts.player.draw"
local ply_update=require"parts.player.update"
local PLY={draw=ply_draw}
--------------------------<Libs>--------------------------
local modeDataMeta do
@@ -87,7 +86,7 @@ local function newEmptyPlayer(id,mini)
P.pressKey=pressKey
P.releaseKey=releaseKey
end
P.update=PLY.update.alive
P.update=ply_update.alive
P.fieldOff={--Shake FX
x=0,y=0,
@@ -107,9 +106,9 @@ local function newEmptyPlayer(id,mini)
if mini then
P.canvas=love.graphics.newCanvas(60,120)
P.frameWait=rnd(26,62)
P.draw=PLY.draw.small
P.draw=ply_draw.small
else
P.draw=PLY.draw.norm
P.draw=ply_draw.norm
end
P.randGen=love.math.newRandomGenerator(GAME.seed)
@@ -136,9 +135,9 @@ local function newEmptyPlayer(id,mini)
P.atker,P.atking,P.lastRecv={}
--Network-related
P.username='_'
P.uid=-1
P.sid=-1
P.username="_"
P.uid=false
P.sid=false
P.dropDelay,P.lockDelay=0,0
P.showTime=false
@@ -314,7 +313,7 @@ local function applyGameEnv(P)--Finish gameEnv processing
if ENV.nextCount==0 then ENV.nextPos=false end
P.newNext=coroutine.wrap(getSeqGen(P))
P.newNext=coroutine.wrap(seqGenerators(P))
P.newNext(P,P.gameEnv.seqData)
if P.mini then
@@ -334,6 +333,7 @@ local function applyGameEnv(P)--Finish gameEnv processing
if ENV.shakeFX==0 then ENV.shakeFX=false end
if ENV.atkFX==0 then ENV.atkFX=false end
if ENV.ghost==0 then ENV.ghost=false end
if ENV.grid==0 then ENV.grid=false end
if ENV.center==0 then ENV.center=false end
end
--------------------------</Libs>--------------------------
@@ -356,7 +356,7 @@ function PLY.newDemoPlayer(id)
P.demo=true
P.frameRun=180
P.draw=PLY.draw.demo
P.draw=ply_draw.demo
P.control=true
GAME.modeEnv=DemoEnv
loadGameEnv(P)
@@ -372,21 +372,21 @@ function PLY.newDemoPlayer(id)
}
P:popNext()
end
function PLY.newRemotePlayer(id,mini,data)
function PLY.newRemotePlayer(id,mini,ply)
local P=newEmptyPlayer(id,mini)
P.type='remote'
P.update=PLY.update.remote_alive
P.update=ply_update.remote_alive
P.draw=PLY.draw.norm_remote
P.draw=ply_draw.norm_remote
P.stream={}
P.streamProgress=1
data.p=P
P.uid=data.uid
P.username=data.username
P.sid=data.sid
loadRemoteEnv(P,data.config)
netPLY.setPlayerObj(ply,P)
P.uid=ply.uid
P.username=ply.username
P.sid=ply.sid
loadRemoteEnv(P,ply.config)
applyGameEnv(P)
end
@@ -408,7 +408,6 @@ function PLY.newPlayer(id,mini)
P.sound=true
P.uid=USER.uid
P.sid=-1
loadGameEnv(P)
applyGameEnv(P)

View File

@@ -8,7 +8,13 @@ local max,min,modf=math.max,math.min,math.modf
local ins,rem=table.insert,table.remove
local resume,yield,status=coroutine.resume,coroutine.yield,coroutine.status
local SFX,BGM,VOC,VIB,SYSFX,SKIN=SFX,BGM,VOC,VIB,SYSFX,SKIN
local FREEROW,TABLE,TEXT,NET,TASK=FREEROW,TABLE,TEXT,NET,TASK
local PLAYERS,PLY_ALIVE,GAME=PLAYERS,PLY_ALIVE,GAME
local kickList=require"parts.kickList"
local ply_draw=require"parts.player.draw"
local ply_update=require"parts.player.update"
--------------------------<FX>--------------------------
function Player:showText(text,dx,dy,font,style,spd,stop)
@@ -195,9 +201,9 @@ function Player:setNext(next,hidden)--Set next count (use hidden=true if set e
if next==0 then
self.drawNext=NULL
elseif not hidden then
self.drawNext=PLY.draw.drawNext_norm
self.drawNext=ply_draw.drawNext_norm
else
self.drawNext=PLY.draw.drawNext_hidden
self.drawNext=ply_draw.drawNext_hidden
end
end
function Player:setInvisible(time)--Time in frames
@@ -705,7 +711,7 @@ function Player:hold(ifpre)
end
end
self.freshTime=int(min(self.freshTime+ENV.freshLimit*.25,ENV.freshLimit*((self.holdTime+1)/ENV.holdCount)))
self.freshTime=int(min(self.freshTime+ENV.freshLimit*.25,ENV.freshLimit*((self.holdTime+1)/ENV.holdCount),ENV.freshLimit))
if not ENV.infHold then
self.holdTime=self.holdTime-1
end
@@ -1607,69 +1613,11 @@ end
--------------------------</Ticks>--------------------------
--------------------------<Events>--------------------------
local function gameOver()--Save record
if GAME.replaying then return end
FILE.save(STAT,'conf/data')
local M=GAME.curMode
local R=M.getRank
if R then
local P=PLAYERS[1]
R=R(P)--New rank
if R then
if R>0 then
GAME.rank=R
end
if scoreValid()and M.score then
if RANKS[M.name]then--Old rank exist
local needSave
if R>RANKS[M.name]then
RANKS[M.name]=R
needSave=true
end
if R>0 then
if M.unlock then
for i=1,#M.unlock do
local m=M.unlock[i]
local n=MODES[m].name
if not RANKS[n]then
RANKS[n]=MODES[m].getRank and 0 or 6
needSave=true
end
end
end
end
if needSave then
FILE.save(RANKS,'conf/unlock','q')
end
end
local D=M.score(P)
local L=M.records
local p=#L--Rank-1
if p>0 then
while M.comp(D,L[p])do--If higher rank
p=p-1
if p==0 then break end
end
end
if p<10 then
if p==0 then
P:showTextF(text.newRecord,0,-100,100,'beat',.5)
end
D.date=os.date("%Y/%m/%d %H:%M")
ins(L,p+1,D)
if L[11]then L[11]=nil end
FILE.save(L,('record/%s.rec'):format(M.name),'lq')
end
end
end
end
end
function Player:die()--Called both when win/lose!
self.alive=false
self.timing=false
self.control=false
self.update=PLY.update.dead
self.update=ply_update.dead
self.waiting=1e99
self.b2b=0
self.tasks={}

View File

@@ -1,7 +1,8 @@
local ins,rem=table.insert,table.remove
local ceil=math.ceil
local yield=YIELD
local seqGens={
local seqGenerators={
none=function()while true do yield()end end,
bag=function(P,seq0)
local len=#seq0
@@ -18,20 +19,87 @@ local seqGens={
yield()
end
end,
his4=function(P,seq0)
his=function(P,seq0)
local len=#seq0
local his={0,0,0,0}
local hisLen=ceil(len*.5)
local history=TABLE.new(0,hisLen)
while true do
while #P.nextQueue<6 do
for n=1,4 do
local j,i=0
repeat
i=seq0[P:RND(len)]
j=j+1
until i~=his[1]and i~=his[2]and i~=his[3]and i~=his[4]or j==4
his[n]=i
P:getNext(i)
local r
for _=1,hisLen do--Reroll up to [hisLen] times
r=P:RND(len)
for i=1,hisLen do
if r==history[i]then
goto CONTINUE_rollAgain
end
end
do break end
::CONTINUE_rollAgain::
end
if history[1]~=0 then P:getNext(r)end
rem(history,1)ins(history,r)
end
yield()
end
end,
hisPool=function(P,seq0)
local len=#seq0
local hisLen=ceil(len*.5)
local history=TABLE.new(0,hisLen)--Indexes of mino-index
local poolLen=5*len
local droughtTimes=TABLE.new(len,len)--Drought times of seq0
local pool={}for i=1,len do for _=1,5 do ins(pool,i)end end--5 times indexes of seq0
local function poolPick()
local r=P:RND(poolLen)
local res=pool[r]
--Find droughtest(s) minoes
local droughtList={1}--Droughtst minoes' indexes of seq0
local maxTime=droughtTimes[1]
for i=2,len do
if droughtTimes[i]>maxTime then
maxTime=droughtTimes[i]
if #droughtList==1 then droughtList[1]=i else droughtList={i}end
elseif droughtTimes[i]==maxTime then
ins(droughtList,i)
end
end
--Update droughtTimes
for i=1,len do droughtTimes[i]=droughtTimes[i]+1 end
droughtTimes[res]=0
--Update pool
-- print("Rem "..res)
pool[r]=droughtList[P:RND(#droughtList)]
-- print("Add "..pool[r])
return res
end
while true do
while #P.nextQueue<6 do
-- print"======================"
--Pick a mino from pool
local tryTime=0
::REPEAT_pickAgain::
local r=poolPick()--Random mino-index in pool
for i=1,len do
if r==history[i]then
tryTime=tryTime+1
if tryTime<hisLen then goto REPEAT_pickAgain end
end
end
--Give mino to player & update history
if history[1]~=0 then P:getNext(seq0[r])end
rem(history,1)ins(history,r)
-- print("Player GET: "..r)
-- print("History: "..table.concat(history,","))
-- local L={"","","","","","","",}
-- for _,v in next,pool do L[v]=L[v].."+"end
-- for i=1,#L do print(i,droughtTimes[i],L[i])end
end
yield()
end
@@ -143,8 +211,8 @@ return function(P)--Return a piece-generating funtion for player P
local s=P.gameEnv.sequence
if type(s)=='function'then
return s
elseif type(s)=='string'and seqGens[s]then
return seqGens[s]
elseif type(s)=='string'and seqGenerators[s]then
return seqGenerators[s]
else
LOG.print(
type(s)=='string'and
@@ -152,6 +220,6 @@ return function(P)--Return a piece-generating funtion for player P
"Wrong sequence generator",
'warn')
P.gameEnv.sequence='bag'
return seqGens.bag
return seqGenerators.bag
end
end

View File

@@ -3,7 +3,11 @@ local int,abs,rnd=math.floor,math.abs,math.random
local rem=table.remove
local assert,resume,status=assert,coroutine.resume,coroutine.status
local function updateLine(P)--Attacks, line pushing, cam moving
local TEXT,GAME=TEXT,GAME
local PLAYERS,PLY_ALIVE=PLAYERS,PLY_ALIVE
local function updateLine(P)--Attacks, line pushing, camear moving
local bf=P.atkBuffer
for i=#bf,1,-1 do
local A=bf[i]

View File

@@ -9,28 +9,30 @@ function scene.sceneInit()
end
function scene.draw()
--Draw all texts
--Texts
setFont(20)
gc.setColor(1,1,1)
for i=1,#text.help do
gc.printf(text.help[i],150,35*i+40,1000,'center')
end
--Group
setFont(20)
mStr(text.group,640,480)
--Lib used
setFont(15)
gc.print(text.used,30,330)
gc.print(text.used,30,320)
--Logo
local t=TIME()
--Sponsor code
gc.draw(TEXTURE.title,280,610,.1,.4+.03*sin(t*2.6),nil,580,118)
gc.setLineWidth(3)
--QR Code frame
gc.rectangle('line',18,18,263,263)
gc.rectangle('line',1012,18,250,250)
--Group code
setFont(20)
mStr(text.group,640,490)
--Support text
gc.setColor(1,1,1,sin(t*20)*.3+.6)
setFont(30)

View File

@@ -8,7 +8,7 @@ local outputBox=WIDGET.newTextBox{name="output",x=40,y=30,w=1200,h=610,font=25,l
local function log(str)outputBox:push(str)end
log{C.lP,"Techmino Console"}
log{C.lC,"©2020 26F Studio some rights reserved"}
log{C.lC,"©2021 26F Studio some rights reserved"}
log{C.dR,"DO NOT RUN ANY CODE YOU DON'T UNDERSTAND"}
local history,hisPtr={"?"}
@@ -36,8 +36,7 @@ do--commands.help(arg)
"help",
"help [command_name]",
},
},
["?"]="help",
},["?"]="help",
["#"]={
description="Run arbitrary Lua code.",
details={
@@ -95,21 +94,23 @@ do--commands.help(arg)
details={
"Attempt to delete a file or directory (in saving directory)",
"",
"Aliases: rm",
"Aliases: del rm",
"",
"Usage: del [filename|dirname]",
"Usage: del -s [dirname]",
},
},rm="del",
ren={
description="Rename a file (in saving directory)",
mv={
description="Rename or move a file (in saving directory)",
details={
"Rename a file (in saving directory)",
"Rename or move a file (in saving directory)",
{C.lY,"Warning: file name with space is not allowed"},
"",
"Usage: ren [oldfilename] [newfilename]",
"Aliases: mv ren",
"",
"Usage: mv [oldfilename] [newfilename]",
},
},
},ren="mv",
cls={
description="Clear the log output.",
details={
@@ -159,13 +160,12 @@ do--commands.help(arg)
"Usage: gammacorrect <true|false>",
},
},
rmwtm={
description="Remove the \"no recording\" watermark.",
["\114\109\119\116\109"]={
description="Remove something",
details={
"Remove the \"no recording\" watermark.",
"You will need a password to do that.",
"Remove something",
"",
"Usage: rmwtm [password]",
"Usage: ?",
},
},
unlockall={
@@ -218,12 +218,12 @@ do--commands.help(arg)
"Usage: theme <classic|xmas|sprfes|zday1/2/3>",
},
},
demo={
description="Go to an empty demo scene",
test={
description="Go to an empty test scene",
details={
"Go to an empty demo scene",
"Go to an empty test scene",
"",
"Usage: demo",
"Usage: test",
},
},
applet={
@@ -237,7 +237,7 @@ do--commands.help(arg)
"applet -list",
"applet [appName]",
},
},
},app="applet",
}TABLE.reIndex(command_help_messages)
local command_help_list={
@@ -249,21 +249,21 @@ do--commands.help(arg)
"url",
"tree",
"del",
"ren",
"mv",
"cls",
"rst",
"fn",
"scrinfo",
"wireframe",
"gammacorrect",
"rmwtm",
"\114\109\119\116\109",
"unlockall",
"play",
"playbgm",
"stopbgm",
"setbg",
"theme",
"demo",
"test",
"applet",
}
function commands.help(arg)
@@ -411,7 +411,7 @@ do--function commands.del(name)
end
commands.rm=commands.del
end
function commands.ren(arg)
function commands.mv(arg)
--Check arguments
arg=STRING.split(arg," ")
if #arg>2 then
@@ -442,6 +442,8 @@ function commands.ren(arg)
log{C.Y,("Succesfully renamed file '%s' to '%s'"):format(arg[1],arg[2])}
end
commands.ren=commands.mv
commands.exit=backScene
commands.quit=backScene
commands.bye=backScene
@@ -478,13 +480,11 @@ function commands.gammacorrect(bool)
log{C.aqua,"Usage: gammacorrect <true|false>"}
end
end
function commands.rmwtm(pw)
commands["\114\109\119\116\109"]=function(pw)
if pw==the_secret then
_G["\100\114\97\119\70\87\77"]=NULL
log{C.lC,"\87\97\116\101\114\109\97\114\107\32\82\101\109\111\118\101\100"}
SFX.play('clear')
else
log{C.aqua,"Usage: rmwtm [password]"}
end
end
function commands.unlockall(bool)
@@ -556,7 +556,7 @@ function commands.theme(name)
log{C.aqua,"Usage: theme [themeName]"}
end
end
function commands.demo()
function commands.test()
SCN.go('test','none')
end
do--commands.applet(name)
@@ -626,6 +626,8 @@ local function log_user(str)
log(noLog and"CHEATER."or tostring(str))
end
local userG={
timer=TIME,
_VERSION=VERSION.code,
assert=assert,error=error,
tonumber=tonumber,tostring=tostring,
@@ -771,8 +773,8 @@ function scene.keyDown(k)
inputBox.value=res[1]
end
end
elseif k=="scrollup"then outputBox:scroll(-1)
elseif k=="scrolldown"then outputBox:scroll(1)
elseif k=="scrollup"then outputBox:scroll(-5)
elseif k=="scrolldown"then outputBox:scroll(5)
elseif k=="pageup"then outputBox:scroll(-20)
elseif k=="pagedown"then outputBox:scroll(20)
elseif k=="home"then outputBox:scroll(-1e99)

View File

@@ -3,7 +3,6 @@ local kb=love.keyboard
local sin=math.sin
local ins,rem=table.insert,table.remove
local sub=string.sub
local scene={}
@@ -194,7 +193,7 @@ scene.widgetList={
WIDGET.newText{name="subTitle",x=530,y=50,font=35,align='L',color='H'},
WIDGET.newSelector{name="sequence",x=1080,y=60,w=200,color='Y',
list={'bag','his4','c2','rnd','mess','reverb','loop','fixed'},
list={'bag','his','hisPool','c2','rnd','mess','reverb','loop','fixed'},
disp=CUSval("sequence"),
code=CUSsto("sequence")
},

View File

@@ -10,7 +10,7 @@ local shadePhase1,shadePhase2
local progress=0
local studioLogo--Studio logo text object
local logoColor1,logoColor2
local skip,locked
local skip
local light={}
for i=0,26 do
@@ -21,13 +21,6 @@ end
for _=1,3 do
light[math.random(7,25)*3]=true
end
local function switchLight(i)
light[3*i]=not light[3*i]
if light[6*3]and light[26*3]then
locked=false
skip=0
end
end
local function upFloor()
progress=progress+1
@@ -212,9 +205,8 @@ function scene.sceneInit()
shadePhase1=6.26*math.random()
shadePhase2=6.26*math.random()
skip=0--Skip time
locked=SETTING.appLock
consoleLaunchKey=0
if not locked then light[6*3],light[26*3]=true,true end
light[6*3],light[26*3]=true,true
kb.setKeyRepeat(false)
end
function scene.sceneBack()
@@ -226,21 +218,11 @@ function scene.keyDown(key)
SCN.back()
elseif key=="s"then
skip=999
elseif locked and #key==1 and key:byte()>=97 and key:byte()<=122 then
switchLight(key:byte()-96)
else
skip=skip+1
end
end
function scene.mouseDown(x,y)
if locked then
for i=1,27 do
if(x-light[3*i-2])^2+(y-light[3*i-1])^2<=626 then
switchLight(i)
return
end
end
end
function scene.mouseDown()
scene.keyDown("mouse")
end
scene.touchDown=scene.mouseDown
@@ -251,23 +233,21 @@ function scene.update(dt)
if blackTime>0 then
blackTime=blackTime-dt
end
if not locked then
if progress<25 then
local p=progress
repeat
loadingThread()
until LOADED or skip<=0 or progress~=p
if skip>0 then skip=skip-1 end
else
openTime=openTime+dt
if skip>0 then
openTime=openTime+.26
skip=skip-1
end
if openTime>=3.26 and not SCN.swapping then
SCN.swapTo('intro')
love.keyboard.setKeyRepeat(true)
end
if progress<25 then
local p=progress
repeat
loadingThread()
until LOADED or skip<=0 or progress~=p
if skip>0 then skip=skip-1 end
else
openTime=openTime+dt
if skip>0 then
openTime=openTime+.26
skip=skip-1
end
if openTime>=3.26 and not SCN.swapping then
SCN.swapTo('intro')
love.keyboard.setKeyRepeat(true)
end
end
end
@@ -345,7 +325,7 @@ function scene.draw()
gc.setColor(1,1,1)
gc.draw(TEXTURE.pixelNum[d2],1040,40,nil,8)
gc.draw(TEXTURE.pixelNum[d1],1100,40,nil,8)
if not locked and progress~=25 then
if progress~=25 then
setFont(40)
gc.setColor(1,.9,.8)
gc.print("",1150,26)

View File

@@ -161,14 +161,6 @@ function scene.draw()
--Player
PLAYERS[1]:draw()
--Special area
gc.setColor(1,1,1,.8)
gc.setLineWidth(10)
gc.line(515,215,515,135,595,135)
gc.line(765,215,765,135,685,135)
gc.line(515,545,515,625,595,625)
gc.line(765,545,765,625,685,625)
--Profile
drawSelfProfile()
end

View File

@@ -21,8 +21,7 @@ local scene={}
function scene.sceneInit(org)
BG.set()
destroyPlayers()
local cam=mapCam
cam.zoomK=org=="main"and 5 or 1
mapCam.zoomK=org=="main"and 5 or 1
end
local function getK()

View File

@@ -1,7 +1,7 @@
local gc,tc=love.graphics,love.touch
local ins=table.insert
local SCR,VK,NET=SCR,VK,NET
local PLAYERS,PLY_NET,GAME=PLAYERS,PLY_NET,GAME
local SCR,VK,NET,netPLY=SCR,VK,NET,netPLY
local PLAYERS,GAME=PLAYERS,GAME
local textBox=WIDGET.newTextBox{name="texts",x=340,y=80,w=600,h=550,hide=false}
@@ -33,8 +33,9 @@ function scene.sceneInit(org)
end
scene.mouseDown=NULL
function scene.mouseMove(x,y)netPLY.mouseMove(x,y)end
function scene.touchDown(x,y)
if noTouch or not playing then return end
if not playing or noTouch then return end
local t=VK.on(x,y)
if t then
@@ -43,7 +44,7 @@ function scene.touchDown(x,y)
end
end
function scene.touchUp(x,y)
if noTouch or not playing then return end
if not playing or noTouch then return end
local n=VK.on(x,y)
if n then
@@ -51,8 +52,9 @@ function scene.touchUp(x,y)
VK.release(n)
end
end
function scene.touchMove()
if noTouch or touchMoveLastFrame or not playing then return end
function scene.touchMove(x,y)
if not playing then netPLY.mouseMove(x,y)end
if touchMoveLastFrame or noTouch then return end
touchMoveLastFrame=true
local L=tc.getTouches()
@@ -93,9 +95,9 @@ function scene.keyDown(key)
end
else
if key=="space"then
NET.signal_ready(not PLY_NET[1].ready)
NET.signal_ready(not netPLY.getSelfReady())
elseif key=="s"then
if not(PLY_NET[1].ready or NET.getlock('ready'))then
if not(netPLY.getSelfReady()or NET.getlock('ready'))then
SCN.go('setting_game')
end
end
@@ -118,7 +120,6 @@ function scene.gamepadDown(key)
LOG.print(text.sureQuit,COLOR.O)
end
else
if noKey then return end
local k=keyMap.joystick[key]
if k and k>0 then
PLAYERS[1]:pressKey(k)
@@ -127,48 +128,45 @@ function scene.gamepadDown(key)
end
end
function scene.gamepadUp(key)
if noKey then return end
local k=keyMap.joystick[key]
if k and k>0 then
PLAYERS[1]:releaseKey(k)
VK.release(k)
return
end
end
function scene.socketRead(cmd,d)
if cmd=="Join"then
if cmd=='join'then
textBox:push{
COLOR.lR,d.username,
COLOR.dY,"#"..d.uid.." ",
COLOR.Y,text.joinRoom,
}
SFX.play('click')
elseif cmd=="Leave"then
elseif cmd=='leave'then
textBox:push{
COLOR.lR,d.username,
COLOR.dY,"#"..d.uid.." ",
COLOR.Y,text.leaveRoom,
}
elseif cmd=="Talk"then
elseif cmd=='talk'then
textBox:push{
COLOR.Z,d.username,
COLOR.dY,"#"..d.uid.." ",
COLOR.N,d.message or"[_]",
}
elseif cmd=="Go"then
elseif cmd=='go'then
if not playing then
playing=true
for i=1,#PLY_NET do
PLY_NET[i].ready=false
end
netPLY.resetReady()
netPLY.mouseMove(0,0)
lastUpstreamTime=0
upstreamProgress=1
resetGameData('n',d.seed)
else
LOG.print("Redundant [Go]",30,COLOR.G)
end
elseif cmd=="Finish"then
elseif cmd=='finish'then
playing=false
local winnerUID
for _,p in next,d.result do
@@ -177,14 +175,10 @@ function scene.socketRead(cmd,d)
break
end
end
if not winnerUID then return end
for _,p in next,PLY_NET do
if p.uid==winnerUID then
TEXT.show(text.champion:gsub("$1",p.username),640,260,80,'zoomout',.26)
break
end
if winnerUID then
TEXT.show(text.champion:gsub("$1",netPLY.getUsername(winnerUID)),640,260,80,'zoomout',.26)
end
elseif cmd=="Stream"then
elseif cmd=='stream'then
if d.uid~=USER.uid and playing then
for _,P in next,PLAYERS do
if P.uid==d.uid then
@@ -205,30 +199,32 @@ function scene.update(dt)
NET.wsclose_stream()
SCN.back()
end
if not playing then return end
if playing then
local P1=PLAYERS[1]
local P1=PLAYERS[1]
touchMoveLastFrame=false
VK.update()
touchMoveLastFrame=false
VK.update()
--Update players
for p=1,#PLAYERS do PLAYERS[p]:update(dt)end
--Update players
for p=1,#PLAYERS do PLAYERS[p]:update(dt)end
--Warning check
checkWarning()
--Warning check
checkWarning()
--Upload stream
if P1.frameRun-lastUpstreamTime>8 then
local stream
stream,upstreamProgress=DATA.dumpRecording(GAME.rep,upstreamProgress)
if #stream>0 then
NET.uploadRecStream(stream)
else
ins(GAME.rep,P1.frameRun)
ins(GAME.rep,0)
--Upload stream
if P1.frameRun-lastUpstreamTime>8 then
local stream
stream,upstreamProgress=DATA.dumpRecording(GAME.rep,upstreamProgress)
if #stream>0 then
NET.uploadRecStream(stream)
else
ins(GAME.rep,P1.frameRun)
ins(GAME.rep,0)
end
lastUpstreamTime=PLAYERS[1].alive and P1.frameRun or 1e99
end
lastUpstreamTime=PLAYERS[1].alive and P1.frameRun or 1e99
else
netPLY.update(dt)
end
end
@@ -247,34 +243,26 @@ function scene.draw()
--Warning
drawWarning()
else
for i=1,#PLY_NET do
local p=PLY_NET[i]
--Users
netPLY.draw()
--Rectangle
gc.setColor(COLOR[p.ready and'G'or'Z'])
gc.setLineWidth(2)
gc.rectangle('line',40,65+50*i,1000,46)
--UID
setFont(40)
gc.setColor(.5,.5,.5)
gc.print("#"..p.uid,50,60+50*i)
--Avatar
gc.setColor(1,1,1)
gc.draw(USERS.getAvatar(p.uid),200,68+50*i,nil,.3125)
--Username
gc.print(p.username,240,60+50*i)
end
--All-ready mark
if NET.allReady then
gc.setColor(.1,1,0,.9)
setFont(60)
--Ready & Set mark
gc.setColor(.1,1,0,.9)
setFont(60)
if NET.connectingStream then
mStr(text.set,640,10)
elseif NET.allReady then
mStr(text.ready,640,10)
end
--Room info.
gc.setColor(1,1,1)
setFont(25)
gc.printf(NET.roomInfo.name,0,685,1270,'right')
setFont(40)
gc.print(netPLY.getCount().."/"..NET.roomInfo.capacity,70,655)
if NET.roomInfo.private then gc.draw(IMG.lock,30,668)end
--Profile
drawSelfProfile()
end
@@ -282,27 +270,27 @@ function scene.draw()
--New message
if textBox.new then
setFont(40)
gc.setColor(1,.5+.5*math.sin(TIME()*26),0)
gc.setColor(1,1,0)
gc.print("M",430,10)
end
end
scene.widgetList={
textBox,
WIDGET.newKey{name="setting",fText=TEXTURE.setting,x=1200,y=160,w=90,h=90,code=pressKey"s",hide=function()return playing or PLY_NET[1].ready or NET.getlock('ready')end},
WIDGET.newKey{name="ready",x=900,y=560,w=400,h=100,color='lB',font=40,code=pressKey"space",
WIDGET.newKey{name="setting",fText=TEXTURE.setting,x=1200,y=160,w=90,h=90,code=pressKey"s",hide=function()return playing or netPLY.getSelfReady()or NET.getlock('ready')end},
WIDGET.newKey{name="ready",x=1060,y=630,w=300,h=80,color='lB',font=40,code=pressKey"space",
hide=function()
return
playing or
NET.serverGaming or
PLY_NET[1].ready or
netPLY.getSelfReady()or
NET.getlock('ready')
end},
WIDGET.newKey{name="cancel",x=900,y=560,w=400,h=100,color='H',font=40,code=pressKey"space",
WIDGET.newKey{name="cancel",x=1060,y=630,w=300,h=80,color='H',font=40,code=pressKey"space",
hide=function()
return
playing or
NET.serverGaming or
not PLY_NET[1].ready or
not netPLY.getSelfReady()or
NET.getlock('ready')
end},
WIDGET.newKey{name="hideChat",fText="...",x=380,y=35,w=60,font=35,code=pressKey"\\"},

View File

@@ -16,7 +16,7 @@ end
scene.widgetList={
WIDGET.newKey{name="setting",fText=TEXTURE.setting,x=1200,y=160,w=90,h=90,code=goScene"setting_game"},
WIDGET.newButton{name="ffa", x=640, y=200,w=350,h=120,font=40,code=function()NET.enterRoom("ffa")end},
WIDGET.newButton{name="ffa", x=640, y=200,w=350,h=120,font=40,code=function()NET.enterRoom({name="ffa"})end},
WIDGET.newButton{name="rooms", x=640, y=360,w=350,h=120,font=40,code=goScene"net_rooms"},
WIDGET.newButton{name="chat", x=640, y=540,w=350,h=120,color='D',font=40,code=NULL},
WIDGET.newButton{name="logout", x=880, y=40,w=180,h=60,color='dR',

View File

@@ -17,6 +17,8 @@ local scene={}
function scene.sceneInit()
BG.set()
NET.allReady=false
NET.connectingStream=false
scrollPos=0
selected=1
fetchRoom()
@@ -66,7 +68,7 @@ function scene.keyDown(k)
LOG.print("Can't enter private room now")
return
end
NET.enterRoom(NET.roomList[selected].rid)--,password
NET.enterRoom(NET.roomList[selected])--,password
end
end
end
@@ -139,7 +141,7 @@ function scene.draw()
end
if R.start then
gc.setColor(0,1,0)
gc.print(text.started,620,66+40*i)
gc.print(text.started,660,66+40*i)
end
gc.setColor(.9,.9,1)
gc.print(pos+i,95,66+40*i)

View File

@@ -30,11 +30,10 @@ scene.widgetList={
WIDGET.newSlider{name="reTime", x=350, y=340, w=300,unit=10,disp=SETval("reTime"),code=SETsto("reTime"),show=function(S)return(.5+S.disp()*.25).."s"end},
WIDGET.newSelector{name="RS", x=500, y=420, w=300,color='S',list={'TRS','SRS','C2','C2sym','Classic','None'},disp=SETval("RS"),code=SETsto("RS")},
WIDGET.newButton{name="layout", x=250, y=540, w=200,h=70,font=35, code=goScene"setting_skin"},
WIDGET.newSwitch{name="dataSaving", x=750, y=550, font=20,disp=SETval("dataSaving"), code=function()SETTING.dataSaving=not SETTING.dataSaving if not SETTING.dataSaving then USERS.forceFreshAvatar()end end},
WIDGET.newSwitch{name="autoPause", x=1060, y=310, font=20,disp=SETval("autoPause"), code=SETrev("autoPause")},
WIDGET.newSwitch{name="swap", x=1060, y=370, font=20,disp=SETval("swap"), code=SETrev("swap")},
WIDGET.newSwitch{name="fine", x=1060, y=430, font=20,disp=SETval("fine"), code=function()SETTING.fine=not SETTING.fine if SETTING.fine then SFX.play('finesseError',.6)end end},
WIDGET.newSwitch{name="appLock", x=1060, y=490, font=20,disp=SETval("appLock"), code=SETrev("appLock")},
WIDGET.newSwitch{name="dataSaving", x=1060, y=490, font=20,disp=SETval("dataSaving"), code=function()SETTING.dataSaving=not SETTING.dataSaving if not SETTING.dataSaving then USERS.forceFreshAvatar()end end},
WIDGET.newSwitch{name="simpMode", x=1060, y=550, font=25,disp=SETval("simpMode"),
code=function()
SETTING.simpMode=not SETTING.simpMode

View File

@@ -32,14 +32,19 @@ end
function scene.keyUp(key)
push{COLOR.H,"[keyUp] <"..key..">"}
end
function scene.mouseClick(x,y)
SYSFX.newRipple(.5,x,y,50)
push("[mouseClick]")
end
function scene.mouseDown(x,y,k)
SYSFX.newShade(.5,x-10,y-10,20,20)
push(("[mouseDown] <%d: %d, %d>"):format(k,x,y))
end
function scene.mouseMove(x,y)
SYSFX.newShade(.5,x-3,y-3,7,7)
SYSFX.newShade(.5,x-3,y-3,6,6)
end
function scene.mouseUp(x,y,k)
SYSFX.newRectRipple(1,x-10,y-10,21,21)
SYSFX.newRectRipple(1,x-10,y-10,20,20)
push{COLOR.H,"[mouseUp] <"..k..">"}
end
function scene.touchClick(x,y)
@@ -47,19 +52,25 @@ function scene.touchClick(x,y)
push("[touchClick]")
end
function scene.touchDown(x,y)
SYSFX.newRipple(.5,x,y,50)
SYSFX.newShade(.5,x-10,y-10,20,20)
push(("[touchDown] <%d, %d>"):format(x,y))
end
function scene.touchMove(x,y)
SYSFX.newRipple(.5,x,y,50)
SYSFX.newShade(.5,x-3,y-3,6,6)
end
function scene.touchUp(x,y)
SYSFX.newRipple(.5,x,y,50)
SYSFX.newRectRipple(1,x-10,y-10,20,20)
push{COLOR.H,"[touchUp]"}
end
function scene.wheelMoved(dx,dy)
push(("[wheelMoved] <%d, %d>"):format(dx,dy))
end
function scene.fileDropped(file)
push(("[fileDropped] <%s>"):format(file:getFilename()))
end
function scene.directoryDropped(path)
push(("[directoryDropped] <%s>"):format(path))
end
function scene.update(dt)
if timer>0 then

View File

@@ -29,10 +29,7 @@ end
local db_img={}
local db=setmetatable({},{__index=function(self,uid)
if not uid then
db_img[uid]=defaultAvatar[1]
return emptyUser
end
if not uid then return emptyUser end
local file="cache/user"..uid..".dat"
local d=fs.getInfo(file)and JSON.decode(fs.read(file))or TABLE.copy(emptyUser)
rawset(self,uid,d)
@@ -65,11 +62,15 @@ function USERS.getUsername(uid)return db[uid].username end
function USERS.getMotto(uid)return db[uid].motto end
function USERS.getHash(uid)return db[uid].hash end
function USERS.getAvatar(uid)
if not db[uid].new then
NET.getUserInfo(uid)
db[uid].new=true
if uid then
if not db[uid].new then
NET.getUserInfo(uid)
db[uid].new=true
end
return db_img[uid]
else
return defaultAvatar[1]
end
return db_img[uid]
end
function USERS.forceFreshAvatar()
for _,U in next,db do

View File

@@ -1,6 +1,7 @@
local gc=love.graphics
local SETTING=SETTING
local next=next
local SETTING,TIME=SETTING,TIME
local VK_org=VK_org
--Virtualkey icons
local VKIcon={}
@@ -17,13 +18,12 @@ local VK={keys=keys}
function VK.on(x,y)
local dist,nearest=1e10
for K=1,#keys do
local B=keys[K]
for id,B in next,keys do
if B.ava then
local d1=(x-B.x)^2+(y-B.y)^2
if d1<B.r^2 then
if d1<dist then
nearest,dist=K,d1
nearest,dist=id,d1
end
end
end
@@ -47,8 +47,7 @@ function VK.touch(id,x,y)
--Button collision (not accurate)
if SETTING.VKDodge then
for i=1,#keys do
local b=keys[i]
for _,b in next,keys do
local d=B.r+b.r-((B.x-b.x)^2+(B.y-b.y)^2)^.5--Hit depth(Neg means distance)
if d>0 then
b.x=b.x+(b.x-B.x)*d*b.r*2.6e-5
@@ -81,23 +80,21 @@ function VK.restore()
B.x=O.x
B.y=O.y
B.r=O.r
B.color=O.color
B.isDown=false
B.pressTime=0
end
for k,v in next,PLAYERS[1].keyAvailable do
for id,v in next,PLAYERS[1].keyAvailable do
if not v then
keys[k].ava=false
keys[id].ava=false
end
end
end
function VK.update()
if SETTING.VKSwitch then
for i=1,#keys do
local _=keys[i]
if _.pressTime>0 then
_.pressTime=_.pressTime-1
for _,B in next,keys do
if B.pressTime>0 then
B.pressTime=B.pressTime-1
end
end
end
@@ -105,72 +102,64 @@ end
local gc_circle,gc_draw,gc_setColor,gc_setLineWidth=gc.circle,gc.draw,gc.setColor,gc.setLineWidth
function VK.draw()
if SETTING.VKSwitch then
local a=SETTING.VKAlpha
if SETTING.VKIcon then
for i=1,#keys do
if keys[i].ava then
local B=keys[i]
if not SETTING.VKSwitch then return end
local a=SETTING.VKAlpha
if SETTING.VKIcon then
for i,B in next,keys do
if B.ava then
--Button outline
gc_setColor(1,1,1,a)
gc_setLineWidth(B.r*.07)
gc_circle('line',B.x,B.y,B.r,10)
--Button outline
gc_setColor(1,1,1,a)
gc_setLineWidth(B.r*.07)
gc_circle('line',B.x,B.y,B.r,10)
--Icon
local _=B.pressTime
gc_setColor(1,1,1,a)
gc_draw(VKIcon[i],B.x,B.y,nil,B.r*.026+_*.08,nil,18,18)
--Icon
local _=keys[i].pressTime
local c=B.color
gc_setColor(c[1],c[2],c[3],a)
gc_draw(VKIcon[i],B.x,B.y,nil,B.r*.026+_*.08,nil,18,18)
--Ripple
if _>0 then
gc_setColor(1,1,1,a*_*.08)
gc_circle('line',B.x,B.y,B.r*(1.4-_*.04),10)
end
--Ripple
if _>0 then
gc_setColor(1,1,1,a*_*.08)
gc_circle('line',B.x,B.y,B.r*(1.4-_*.04),10)
end
--Glow when press
if B.isDown then
gc_setColor(1,1,1,a*.4)
gc_circle('fill',B.x,B.y,B.r*.94,10)
end
--Glow when press
if B.isDown then
gc_setColor(1,1,1,a*.4)
gc_circle('fill',B.x,B.y,B.r*.94,10)
end
end
else
for i=1,#keys do
if keys[i].ava then
local B=keys[i]
gc_setColor(1,1,1,a)
gc_setLineWidth(B.r*.07)
gc_circle('line',B.x,B.y,B.r,10)
local _=keys[i].pressTime
if _>0 then
gc_setColor(1,1,1,a*_*.08)
gc_circle('fill',B.x,B.y,B.r*.94,10)
gc_circle('line',B.x,B.y,B.r*(1.4-_*.04),10)
end
end
else
for _,B in next,keys do
if B.ava then
gc_setColor(1,1,1,a)
gc_setLineWidth(B.r*.07)
gc_circle('line',B.x,B.y,B.r,10)
local _=B.pressTime
if _>0 then
gc_setColor(1,1,1,a*_*.08)
gc_circle('fill',B.x,B.y,B.r*.94,10)
gc_circle('line',B.x,B.y,B.r*(1.4-_*.04),10)
end
end
end
end
end
function VK.preview(selected)
if SETTING.VKSwitch then
for i=1,#VK_org do
local B=VK_org[i]
if B.ava then
if not SETTING.VKSwitch then return end
for id,B in next,VK_org do
if B.ava then
gc_setColor(1,1,1,SETTING.VKAlpha)
gc_setLineWidth(B.r*.07)
gc_circle('line',B.x,B.y,B.r,10)
if selected==id and TIME()%.26<.13 then
gc_setColor(1,1,1,SETTING.VKAlpha*.62)
gc_circle('fill',B.x,B.y,B.r,10)
end
if SETTING.VKIcon then
gc_setColor(1,1,1,SETTING.VKAlpha)
gc_setLineWidth(B.r*.07)
gc_circle('line',B.x,B.y,B.r,10)
if selected==i and TIME()%.26<.13 then
gc_setColor(1,1,1,SETTING.VKAlpha*.62)
gc_circle('fill',B.x,B.y,B.r,10)
end
if SETTING.VKIcon then
local c=B.color
gc_setColor(c[1],c[2],c[3],SETTING.VKAlpha)
gc_draw(VKIcon[i],B.x,B.y,nil,B.r*.025,nil,18,18)
end
gc_draw(VKIcon[id],B.x,B.y,nil,B.r*.025,nil,18,18)
end
end
end