Merge branch 'main' of https://github.com/26F-Studio/Techmino into main
This commit is contained in:
@@ -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())
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
30
main.lua
30
main.lua
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")..
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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{}
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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={
|
||||
|
||||
@@ -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={
|
||||
|
||||
@@ -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={
|
||||
|
||||
@@ -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={
|
||||
|
||||
@@ -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={
|
||||
|
||||
@@ -46,7 +46,6 @@ return{
|
||||
createRoomTooFast="手痒要开这么多房间?",
|
||||
createRoomSuccessed="创好了",
|
||||
started="开了",
|
||||
ready="预备!",
|
||||
champion="神仙是 $1",
|
||||
|
||||
stat={
|
||||
|
||||
@@ -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,"你有一个好"},
|
||||
|
||||
@@ -19,6 +19,7 @@ return{
|
||||
drop=0,lock=15,
|
||||
wait=15,fall=6,
|
||||
nextCount=3,
|
||||
sequence='hisPool',
|
||||
visible='fast',
|
||||
freshLimit=15,
|
||||
dropPiece=score,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
109
parts/net.lua
109
parts/net.lua
@@ -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
221
parts/netPlayer.lua
Normal 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
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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={}
|
||||
|
||||
@@ -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
|
||||
@@ -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]
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
},
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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"\\"},
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user