Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9046a0a7c8 | ||
|
|
4173441d3c | ||
|
|
b5c3af05d8 | ||
|
|
6fa9aa30fa | ||
|
|
41ce44fc0e | ||
|
|
59848cd559 | ||
|
|
092c944d27 | ||
|
|
8ec051f523 | ||
|
|
22cc708a65 | ||
|
|
4e577a01ae | ||
|
|
5b43ff8c45 | ||
|
|
d07075ca9c | ||
|
|
cd49507a2b | ||
|
|
00464f1e80 | ||
|
|
6ec902e618 | ||
|
|
30e276b132 | ||
|
|
b8597d1518 | ||
|
|
5543f29e4f | ||
|
|
dc67239382 | ||
|
|
2a571bbb97 | ||
|
|
2824bef04a | ||
|
|
8fc7ebdab7 | ||
|
|
793d6780f3 | ||
|
|
605561148b | ||
|
|
54daef0cd9 | ||
|
|
ac0ff16537 | ||
|
|
e44053446a | ||
|
|
d4fb606c72 | ||
|
|
4cfdd4e58b | ||
|
|
3b82a144ea | ||
|
|
2f06c1b476 | ||
|
|
25b6b2c5ba | ||
|
|
9948505145 | ||
|
|
9d8feab2cc | ||
|
|
bcb5d3eba4 | ||
|
|
d7a10c00ed | ||
|
|
d2593cfb81 | ||
|
|
8101cf89f8 | ||
|
|
8636c6dcd5 | ||
|
|
b9c5599f95 | ||
|
|
93f854e6e4 | ||
|
|
ffc09b0801 | ||
|
|
d246064ded | ||
|
|
468f264545 | ||
|
|
9bec223b09 | ||
|
|
4606bb4d01 | ||
|
|
c8405c8924 | ||
|
|
95a33c0e6c | ||
|
|
ed2ad35dde | ||
|
|
234ae08c76 | ||
|
|
d21506b8d7 |
@@ -160,6 +160,7 @@ function love.touchpressed(id,x,y)
|
||||
if SCN.swapping then return end
|
||||
if not touching then
|
||||
touching=id
|
||||
WIDGET.unFocus(true)
|
||||
love.touchmoved(id,x,y,0,0)
|
||||
end
|
||||
x,y=xOy:inverseTransformPoint(x,y)
|
||||
@@ -172,14 +173,10 @@ function love.touchmoved(_,x,y,dx,dy)
|
||||
x,y=xOy:inverseTransformPoint(x,y)
|
||||
if SCN.touchMove then SCN.touchMove(x,y,dx/SCR.k,dy/SCR.k)end
|
||||
if WIDGET.sel then
|
||||
if touching then
|
||||
WIDGET.drag(x,y,dx,dy)
|
||||
end
|
||||
if touching then WIDGET.drag(x,y,dx,dy)end
|
||||
else
|
||||
WIDGET.cursorMove(x,y)
|
||||
if not WIDGET.sel then
|
||||
touching=false
|
||||
end
|
||||
if not WIDGET.sel then touching=false end
|
||||
end
|
||||
end
|
||||
function love.touchreleased(id,x,y)
|
||||
@@ -188,10 +185,9 @@ function love.touchreleased(id,x,y)
|
||||
if id==touching then
|
||||
WIDGET.press(x,y,1)
|
||||
WIDGET.release(x,y)
|
||||
WIDGET.cursorMove(x,y)
|
||||
WIDGET.unFocus()
|
||||
touching=false
|
||||
if WIDGET.sel and not WIDGET.sel.keepFocus then
|
||||
WIDGET.sel=false
|
||||
end
|
||||
end
|
||||
if SCN.touchUp then SCN.touchUp(x,y)end
|
||||
if(x-lastX)^2+(y-lastY)^2<62 then
|
||||
@@ -214,7 +210,7 @@ local function noDevkeyPressed(key)
|
||||
end
|
||||
end
|
||||
elseif key=="f4"then if not kb.isDown("lalt","ralt")then LOG.copy()end
|
||||
elseif key=="f5"then if WIDGET.sel then print(WIDGET.sel)end
|
||||
elseif key=="f5"then print(WIDGET.isFocus()or"no widget selected")
|
||||
elseif key=="f6"then for k,v in next,_G do print(k,v)end
|
||||
elseif key=="f7"then if love._openConsole then love._openConsole()end
|
||||
elseif key=="f8"then devMode=nil LOG.print("DEBUG OFF")
|
||||
@@ -224,8 +220,8 @@ local function noDevkeyPressed(key)
|
||||
elseif key=="f12"then devMode=4 LOG.print("DEBUG 4")
|
||||
elseif key=="\\"then _G["\100\114\97\119\70\87\77"]=NULL
|
||||
elseif devMode==2 then
|
||||
if WIDGET.sel then
|
||||
local W=WIDGET.sel
|
||||
local W=WIDGET.sel
|
||||
if W then
|
||||
if key=="left"then W.x=W.x-10
|
||||
elseif key=="right"then W.x=W.x+10
|
||||
elseif key=="up"then W.y=W.y-10
|
||||
@@ -464,11 +460,11 @@ local devColor={
|
||||
local WS=WS
|
||||
local WSnames={'app','user','play','stream','chat'}
|
||||
local WScolor={
|
||||
{1,.5,.5,.7},
|
||||
{1,.8,.3,.7},
|
||||
{1,1,.4,.7},
|
||||
{.4,1,.7,.7},
|
||||
{.5,.8,1,.7},
|
||||
{1,.6,.6,.7},
|
||||
{1,.8,.4,.7},
|
||||
{1,1,.5,.7},
|
||||
{.5,1,.8,.7},
|
||||
{.6,.9,1,.7},
|
||||
}
|
||||
local ws_deadImg=DOGC{20,20,
|
||||
{'setFT',20},
|
||||
@@ -626,26 +622,26 @@ function love.run()
|
||||
|
||||
--Websocket status
|
||||
gc_push('transform')
|
||||
gc.translate(SCR.w,SCR.h-100)
|
||||
gc.translate(SCR.w,SCR.h)
|
||||
gc.scale(SCR.k)
|
||||
for i=1,5 do
|
||||
local status=WS.status(WSnames[i])
|
||||
gc_setColor(WScolor[i])
|
||||
gc_rectangle('fill',0,20*i,-80,-20)
|
||||
gc_rectangle('fill',0,20*i-100,-80,-20)
|
||||
if status=='dead'then
|
||||
gc_setColor(1,1,1)
|
||||
gc_draw(ws_deadImg,-20,20*i-20)
|
||||
gc_draw(ws_deadImg,-20,20*i-120)
|
||||
elseif status=='connecting'then
|
||||
gc_setColor(1,1,1,.5+.3*sin(time*6.26))
|
||||
gc_draw(ws_connectingImg,-20,20*i-20)
|
||||
gc_draw(ws_connectingImg,-20,20*i-120)
|
||||
elseif status=='running'then
|
||||
gc_setColor(1,1,1)
|
||||
gc_draw(ws_runningImg,-20,20*i-20)
|
||||
gc_draw(ws_runningImg,-20,20*i-120)
|
||||
end
|
||||
local t1,t2,t3=WS.getTimers(WSnames[i])
|
||||
gc_setColor(1,1,1,t1)gc_rectangle('fill',-60,20*i,-20,-20)
|
||||
gc_setColor(0,1,0,t2)gc_rectangle('fill',-40,20*i,-20,-20)
|
||||
gc_setColor(1,0,0,t3)gc_rectangle('fill',-20,20*i,-20,-20)
|
||||
gc_setColor(1,1,1,t1)gc_rectangle('fill',-60,20*i-100,-20,-20)
|
||||
gc_setColor(0,1,0,t2)gc_rectangle('fill',-40,20*i-100,-20,-20)
|
||||
gc_setColor(1,0,0,t3)gc_rectangle('fill',-20,20*i-100,-20,-20)
|
||||
end
|
||||
gc_pop()
|
||||
|
||||
|
||||
@@ -10,33 +10,28 @@ return function(name,libName)
|
||||
local fs=love.filesystem
|
||||
local platform={'arm64-v8a','armeabi-v7a'}
|
||||
|
||||
local libFunc=package.loadlib(SAVEDIR.."/lib/"..libName.Android,libName.libFunc)
|
||||
if libFunc then
|
||||
LOG.print(name.." lib loaded",'message')
|
||||
else
|
||||
for i=1,#platform do
|
||||
local soFile,_,_,mes1=fs.read('data',"libAndroid/"..platform[i].."/"..libName.Android)
|
||||
if soFile then
|
||||
local success,mes2=fs.write("lib/"..libName.Android,soFile)
|
||||
if success then
|
||||
libFunc,mes2=package.loadlib(SAVEDIR.."/lib/"..libName.Android,libName.libFunc)
|
||||
if libFunc then
|
||||
LOG.print(name.." lib loaded",'message')
|
||||
break
|
||||
else
|
||||
LOG.print("Cannot load "..name..": "..mes2,'error')
|
||||
end
|
||||
for i=1,#platform do
|
||||
local soFile,_,_,mes1=fs.read('data',"libAndroid/"..platform[i].."/"..libName.Android)
|
||||
if soFile then
|
||||
local success,mes2=fs.write("lib/"..libName.Android,soFile)
|
||||
if success then
|
||||
libFunc,mes2=package.loadlib(SAVEDIR.."/lib/"..libName.Android,libName.libFunc)
|
||||
if libFunc then
|
||||
LOG.print(name.." lib loaded",'message')
|
||||
break
|
||||
else
|
||||
LOG.print(("Write %s-%s to saving failed: %s"):format(name,platform[i],mes2),'error')
|
||||
LOG.print("Cannot load "..name..": "..mes2,'error')
|
||||
end
|
||||
else
|
||||
LOG.print(("Read %s-%s to saving failed: %s"):format(name,platform[i],mes1),'error')
|
||||
LOG.print(("Write %s-%s to saving failed: %s"):format(name,platform[i],mes2),'error')
|
||||
end
|
||||
else
|
||||
LOG.print(("Read %s-%s to saving failed: %s"):format(name,platform[i],mes1),'error')
|
||||
end
|
||||
if not libFunc then
|
||||
LOG.print("Cannot load "..name,'error')
|
||||
return
|
||||
end
|
||||
end
|
||||
if not libFunc then
|
||||
LOG.print("Cannot load "..name,'error')
|
||||
return
|
||||
end
|
||||
return libFunc()
|
||||
else
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
-- local host="127.0.0.1"
|
||||
-- local host="192.168.114.102"
|
||||
-- local host="krakens.tpddns.cn"
|
||||
-- local host="hdustea.3322.org"
|
||||
local host="game.techmino.org"
|
||||
local host="krakens.tpddns.cn"
|
||||
-- local host="game.techmino.org"
|
||||
local port="10026"
|
||||
local path="/tech/socket/v1"
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
local kb=love.keyboard
|
||||
local gc=love.graphics
|
||||
local kb,gc=love.keyboard,love.graphics
|
||||
|
||||
local next=next
|
||||
local int,abs=math.floor,math.abs
|
||||
local max,min=math.max,math.min
|
||||
local sub=string.sub
|
||||
local ins=table.insert
|
||||
local setFont,mStr=setFont,mStr
|
||||
local mDraw_X,mDraw_Y=ADRAW.simpX,ADRAW.simpY
|
||||
local sub,ins=string.sub,table.insert
|
||||
local getFont,setFont,mStr=getFont,setFont,mStr
|
||||
local mDraw,mDraw_X,mDraw_Y=ADRAW.draw,ADRAW.simpX,ADRAW.simpY
|
||||
|
||||
local clearIcon=DOGC{40,40,
|
||||
{'setLW',6},
|
||||
@@ -519,7 +518,7 @@ function slider:drag(x)
|
||||
if p~=P then
|
||||
self.code(P)
|
||||
end
|
||||
if self.change and TIME()-self.lastTime>.18 then
|
||||
if self.change and TIME()-self.lastTime>.26 then
|
||||
self.lastTime=TIME()
|
||||
self.change()
|
||||
end
|
||||
@@ -1035,7 +1034,7 @@ WIDGET.indexMeta={
|
||||
end
|
||||
}
|
||||
function WIDGET.set(list)
|
||||
WIDGET.sel=false
|
||||
WIDGET.unFocus()
|
||||
WIDGET.active=list or NONE
|
||||
|
||||
--Reset all widgets
|
||||
@@ -1072,23 +1071,42 @@ function WIDGET.setLang(widgetText)
|
||||
end
|
||||
end
|
||||
end
|
||||
function WIDGET.isFocus(W)
|
||||
return W==nil and WIDGET.sel or WIDGET.sel==W
|
||||
end
|
||||
function WIDGET.focus(W)
|
||||
if WIDGET.sel==W then return end
|
||||
if WIDGET.sel and WIDGET.sel.type=='inputBox'then kb.setTextInput(false)end
|
||||
WIDGET.sel=W
|
||||
if W and W.type=='inputBox'then
|
||||
local _,y1=SCR.xOy:transformPoint(0,W.y+W.h)
|
||||
kb.setTextInput(true,0,y1,1,1)
|
||||
end
|
||||
end
|
||||
function WIDGET.unFocus(force)
|
||||
local W=WIDGET.sel
|
||||
if W and(force or not W.keepFocus)then
|
||||
if W.type=='inputBox'then kb.setTextInput(false)end
|
||||
WIDGET.sel=false
|
||||
end
|
||||
end
|
||||
|
||||
function WIDGET.cursorMove(x,y)
|
||||
for _,W in next,WIDGET.active do
|
||||
if not W.hide and W.resCtr and W:isAbove(x,y)then
|
||||
WIDGET.sel=W
|
||||
WIDGET.focus(W)
|
||||
return
|
||||
end
|
||||
end
|
||||
if WIDGET.sel and not WIDGET.sel.keepFocus then
|
||||
WIDGET.sel=false
|
||||
WIDGET.unFocus()
|
||||
end
|
||||
end
|
||||
function WIDGET.press(x,y,k)
|
||||
local W=WIDGET.sel
|
||||
if not W then return end
|
||||
W:press(x,y,k)
|
||||
if W.hide then WIDGET.sel=false end
|
||||
if W.hide then WIDGET.unFocus()end
|
||||
end
|
||||
function WIDGET.drag(x,y,dx,dy)
|
||||
local W=WIDGET.sel
|
||||
@@ -1096,7 +1114,7 @@ function WIDGET.drag(x,y,dx,dy)
|
||||
if W.type=='slider'or W.type=='textBox'then
|
||||
W:drag(x,y,dx,dy)
|
||||
elseif not W:isAbove(x,y)then
|
||||
WIDGET.sel=false
|
||||
WIDGET.unFocus(true)
|
||||
end
|
||||
end
|
||||
function WIDGET.release(x,y)
|
||||
@@ -1107,25 +1125,24 @@ function WIDGET.release(x,y)
|
||||
end
|
||||
end
|
||||
function WIDGET.keyPressed(k)
|
||||
local W=WIDGET.sel
|
||||
if k=="space"or k=="return"then
|
||||
WIDGET.press()
|
||||
elseif kb.isDown("lshift","lalt","lctrl")and(k=="left"or k=="right")then
|
||||
--When hold [↑], control slider with left/right
|
||||
local W=WIDGET.sel
|
||||
if W and W.type=='slider'or W.type=='selector'then
|
||||
W:arrowKey(k=="left")
|
||||
end
|
||||
elseif k=="up"or k=="down"or k=="left"or k=="right"then
|
||||
if not WIDGET.sel then
|
||||
for _,W in next,WIDGET.active do
|
||||
if not W.hide and W.isAbove then
|
||||
WIDGET.sel=W
|
||||
if not W then
|
||||
for _,w in next,WIDGET.active do
|
||||
if not w.hide and w.isAbove then
|
||||
WIDGET.focus(w)
|
||||
return
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
local W=WIDGET.sel
|
||||
if not W.getCenter then return end
|
||||
local WX,WY=W:getCenter()
|
||||
local dir=(k=="right"or k=="down")and 1 or -1
|
||||
@@ -1151,10 +1168,9 @@ function WIDGET.keyPressed(k)
|
||||
end
|
||||
end
|
||||
if tar then
|
||||
WIDGET.sel=tar
|
||||
WIDGET.focus(tar)
|
||||
end
|
||||
else
|
||||
local W=WIDGET.sel
|
||||
if W and W.type=='inputBox'then
|
||||
W:keypress(k)
|
||||
end
|
||||
@@ -1205,12 +1221,7 @@ end
|
||||
|
||||
function WIDGET.update()
|
||||
for _,W in next,WIDGET.active do
|
||||
if W.hideF then
|
||||
local h=W.hideF()
|
||||
if h~=W.hide then
|
||||
W.hide=h
|
||||
end
|
||||
end
|
||||
if W.hideF then W.hide=W.hideF()end
|
||||
if W.update then W:update()end
|
||||
end
|
||||
end
|
||||
|
||||
7
conf.lua
7
conf.lua
@@ -1,7 +1,8 @@
|
||||
VERSION={
|
||||
code=1408,
|
||||
string="Alpha V0.14.8",
|
||||
name="冰激凌 Icecream",
|
||||
code=1500,
|
||||
short="V0.15.0",
|
||||
string="Alpha V0.15.0",
|
||||
name="超新星 Supernovas",
|
||||
}
|
||||
function love.conf(t)
|
||||
t.identity='Techmino'--Saving folder
|
||||
|
||||
33
main.lua
33
main.lua
@@ -236,18 +236,16 @@ for _,v in next,fs.getDirectoryItems("parts/scenes")do
|
||||
LANG.addScene(sceneName)
|
||||
end
|
||||
end
|
||||
LANG.set(SETTING.lang)
|
||||
|
||||
--Update data
|
||||
do
|
||||
local needSave
|
||||
local autoRestart
|
||||
local needSave,autoRestart
|
||||
|
||||
if type(STAT.version)~='number'then
|
||||
STAT.version=0
|
||||
needSave=true
|
||||
end
|
||||
if STAT.version<1300 then
|
||||
if STAT.version<1302 then
|
||||
STAT.frame=math.floor(STAT.time*60)
|
||||
STAT.lastPlay='sprint_10l'
|
||||
RANKS.sprintFix=nil
|
||||
@@ -256,38 +254,30 @@ do
|
||||
for _,name in next,fs.getDirectoryItems("replay")do
|
||||
fs.remove("replay/"..name)
|
||||
end
|
||||
end
|
||||
if STAT.version<1302 then
|
||||
if RANKS.pctrain_n then RANKS.pctrain_n=0 end
|
||||
if RANKS.pctrain_l then RANKS.pctrain_l=0 end
|
||||
fs.remove("conf/settings")
|
||||
needSave=true
|
||||
autoRestart=true
|
||||
end
|
||||
if STAT.version<1400 then
|
||||
if STAT.version<1405 then
|
||||
fs.remove("conf/user")
|
||||
fs.remove("conf/key")
|
||||
needSave=true
|
||||
autoRestart=true
|
||||
end
|
||||
if STAT.version<1405 then
|
||||
fs.remove("conf/user")
|
||||
autoRestart=true
|
||||
end
|
||||
if not TABLE.find({8,10,13,17,22,29,37,47,62,80,100},SETTING.frameMul)then
|
||||
SETTING.frameMul=100
|
||||
end
|
||||
SETTING.appLock=nil
|
||||
|
||||
for _,v in next,VK_org do v.color=nil end
|
||||
|
||||
if STAT.version~=VERSION.code then
|
||||
STAT.version=VERSION.code
|
||||
CLEAR("lib")
|
||||
needSave=true
|
||||
autoRestart=true
|
||||
end
|
||||
|
||||
if not SETTING.VKSkin then SETTING.VKSkin=1 end
|
||||
if not TABLE.find({8,10,13,17,22,29,37,47,62,80,100},SETTING.frameMul)then
|
||||
SETTING.frameMul=100
|
||||
end
|
||||
SETTING.appLock=nil
|
||||
for _,v in next,VK_org do v.color=nil end
|
||||
if RANKS.GM then RANKS.GM=0 end
|
||||
if RANKS.infinite then RANKS.infinite=6 end
|
||||
if RANKS.infinite_dig then RANKS.infinite_dig=6 end
|
||||
@@ -326,4 +316,7 @@ do
|
||||
if autoRestart then
|
||||
love.event.quit('restart')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
LANG.set(SETTING.lang)
|
||||
VK.setShape(SETTING.VKSkin)
|
||||
BIN
media/SFX/connect.ogg
Normal file
BIN
media/SFX/connect.ogg
Normal file
Binary file not shown.
BIN
media/SFX/connected.ogg
Normal file
BIN
media/SFX/connected.ogg
Normal file
Binary file not shown.
@@ -1,4 +1,3 @@
|
||||
local kb=love.keyboard
|
||||
local gc=love.graphics
|
||||
local gc_push,gc_pop=gc.push,gc.pop
|
||||
local gc_origin,gc_translate=gc.origin,gc.translate
|
||||
@@ -11,8 +10,8 @@ local ins,rem=table.insert,table.remove
|
||||
local SETTING,GAME,SCR=SETTING,GAME,SCR
|
||||
|
||||
|
||||
|
||||
--System
|
||||
function enableTextInput()if not MOBILE then kb.setTextInput(true)end end
|
||||
function switchFullscreen()
|
||||
SETTING.fullscreen=not SETTING.fullscreen
|
||||
love.window.setFullscreen(SETTING.fullscreen)
|
||||
@@ -545,36 +544,6 @@ end
|
||||
|
||||
|
||||
--Game draw
|
||||
do--function drawFWM()
|
||||
local m={
|
||||
string.char(230,184,184,230,136,143,228,189,156,232,128,133,58,77,114,90,95,50,54,10,228,187,187,228,189,149,232,167,134,233,162,145,47,231,155,180,230,146,173,228,184,141,229,190,151,229,135,186,231,142,176,230,173,164,230,176,180,229,141,176,10,228,187,187,228,189,149,232,189,172,232,191,176,229,163,176,230,152,142,230,151,160,230,149,136),
|
||||
string.char(230,184,184,230,136,143,228,189,156,232,128,133,58,77,114,90,95,50,54,10,228,187,187,228,189,149,232,167,134,233,162,145,47,231,155,180,230,146,173,228,184,141,229,190,151,229,135,186,231,142,176,230,173,164,230,176,180,229,141,176,10,228,187,187,228,189,149,232,189,172,232,191,176,229,163,176,230,152,142,230,151,160,230,149,136),
|
||||
string.char(230,184,184,230,136,143,228,189,156,232,128,133,58,77,114,90,95,50,54,10,228,187,187,228,189,149,232,167,134,233,162,145,47,231,155,180,230,146,173,228,184,141,229,190,151,229,135,186,231,142,176,230,173,164,230,176,180,229,141,176,10,228,187,187,228,189,149,232,189,172,232,191,176,229,163,176,230,152,142,230,151,160,230,149,136),
|
||||
string.char(65,117,116,104,111,114,58,32,77,114,90,95,50,54,10,82,101,99,111,114,100,105,110,103,115,32,99,111,110,116,97,105,110,105,110,103,32,116,104,105,115,10,119,97,116,101,114,109,97,114,107,32,97,114,101,32,117,110,97,117,116,104,111,114,105,122,101,100),
|
||||
string.char(67,114,195,169,97,116,101,117,114,32,100,117,32,106,101,117,58,32,77,114,90,95,50,54,10,69,110,114,101,103,105,115,116,114,101,109,101,110,116,32,110,111,110,32,97,117,116,111,114,105,115,195,169,10,99,111,110,116,101,110,97,110,116,32,99,101,32,102,105,108,105,103,114,97,110,101),
|
||||
string.char(65,117,116,111,114,58,32,77,114,90,95,50,54,10,71,114,97,98,97,99,105,195,179,110,32,110,111,32,97,117,116,111,114,105,122,97,100,97,32,113,117,101,10,99,111,110,116,105,101,110,101,32,101,115,116,97,32,109,97,114,99,97,32,100,101,32,97,103,117,97),
|
||||
string.char(65,117,116,111,114,32,100,111,32,106,111,103,111,58,32,77,114,90,95,50,54,10,71,114,97,118,97,195,167,195,181,101,115,32,99,111,110,116,101,110,100,111,32,101,115,116,97,32,77,97,114,99,97,10,100,101,32,195,161,103,117,97,32,110,195,163,111,32,115,195,163,111,32,97,117,116,111,114,105,122,97,100,97,115),
|
||||
string.char(65,117,116,104,111,114,58,32,77,114,90,95,50,54,10,82,101,99,111,114,100,105,110,103,115,32,99,111,110,116,97,105,110,105,110,103,32,116,104,105,115,10,119,97,116,101,114,109,97,114,107,32,97,114,101,32,117,110,97,117,116,104,111,114,105,122,101,100),
|
||||
}
|
||||
--你竟然找到了这里!那么在动手之前读读下面这些吧。
|
||||
--【魔幻错别字躲关键字搜索警告,看得懂就行】
|
||||
--千万不要为了在网络公共场合发视屏或者直播需要而擅自删除这部分代码!
|
||||
--录制视屏上传到公共场合(包括但不限于任何视屏平台/论坛/好几十个人及以上的非方块社区/群等)很可能会对Techmino未来的发展有负面影响
|
||||
--如果被TTC发现,随时可能被他们用DMCA从法律层面强迫停止开发,到时候谁都没得玩。这是真的,已经有几个方块这么死了…
|
||||
--氵印限制还可以减少低质量视屏泛滥,也能减轻过多不是真的感兴趣路人玩家入坑可能带来的压力
|
||||
--想发视屏的话请先向作者申请,描述录制的大致内容,同意了才可以去关闭氵印
|
||||
--等Techmino发展到一定程度之后会解除这个限制
|
||||
--最后,别把藏在这里的东西截图/复制出去哦~
|
||||
--感谢您对Techmino的支持!!!
|
||||
local sin=math.sin
|
||||
local setFont,TIME,mStr=setFont,TIME,mStr
|
||||
function drawFWM()
|
||||
local t=TIME()
|
||||
setFont(25)
|
||||
gc.setColor(1,1,1,.2+.1*(sin(3*t)+sin(2.6*t)))
|
||||
mStr(m[_G["\83\69\84\84\73\78\71"]["\108\97\110\103"]or m[1]],240,60+26*sin(t))
|
||||
end
|
||||
end
|
||||
do--function drawSelfProfile()
|
||||
local name
|
||||
local textObject,scaleK,width,offY
|
||||
@@ -608,7 +577,7 @@ do--function drawSelfProfile()
|
||||
gc_pop()
|
||||
end
|
||||
end
|
||||
do
|
||||
do--function drawOnlinePlayerCount()
|
||||
function drawOnlinePlayerCount()
|
||||
setFont(20)
|
||||
gc_setColor(1,1,1)
|
||||
@@ -629,6 +598,20 @@ do--function drawWarning()
|
||||
end
|
||||
end
|
||||
end
|
||||
do--function drawSystemInfo(
|
||||
--你竟然找到了这里!那么在动手之前读读下面这些吧。
|
||||
--【魔幻错别字躲关键字搜索警告,看得懂就行】
|
||||
--千万不要为了在网络公共场合发视屏或者直播需要而擅自删除这部分代码!
|
||||
--录制视屏上传到公共场合(包括但不限于任何视屏平台/论坛/好几十个人及以上的非方块社区/群等)很可能会对Techmino未来的发展有负面影响
|
||||
--如果被TTC发现,随时可能被他们用DMCA从法律层面强迫停止开发,到时候谁都没得玩。这是真的,已经有几个方块这么死了…
|
||||
--氵印限制还可以减少低质量视屏泛滥,也能减轻过多不是真的感兴趣路人玩家入坑可能带来的压力
|
||||
--想发视屏的话请先向作者申请,描述录制的大致内容,同意了才可以去关闭氵印
|
||||
--等Techmino发展到一定程度之后会解除这个限制
|
||||
--最后,别把藏在这里的东西截图/复制出去哦~
|
||||
--感谢您对Techmino的支持!!!
|
||||
loadstring(love.data.decode('string','base64',"CWxvY2FsIGc9bG92ZS5ncmFwaGljcztsb2NhbCB4LHMsVCxkLGM9Zy5uZXdUZXh0KGdldEZvbnQoMjUpKSxtYXRoLnNpbixUSU1FLGcuZHJhdyxnLnNldENvbG9yO3g6c2V0ZigiQXV0aOS9nOiAhTpNclpfMjZcbkFscGhh5YaF5rWL56aB5q2i5b2V5bGPL+ebtOaSrVxuTm8gcmVjb3JkaW5nL3N0cmVhbWluZyIsMzAwLCdjZW50ZXInKWZ1bmN0aW9uIGRyYXdGV00oKWxvY2FsIHQ9VCgpYygxLDEsMSwuMTYrLjA2KihzKDMuNTUqdCkrcygyLjYqdCkpKWQoeCwzMCw3Mys1MypzKHQqLjI2KSllbmQK"))()
|
||||
end
|
||||
|
||||
|
||||
|
||||
--Widget function shortcuts
|
||||
|
||||
@@ -281,14 +281,15 @@ SETTING={--Settings
|
||||
|
||||
text=true,
|
||||
score=true,
|
||||
warn=true,
|
||||
bufferWarn=true,
|
||||
showSpike=true,
|
||||
highCam=true,
|
||||
nextPos=true,
|
||||
fullscreen=true,
|
||||
bg=true,
|
||||
powerInfo=false,
|
||||
clickFX=true,
|
||||
warn=true,
|
||||
|
||||
--Sound
|
||||
sfx=1,
|
||||
@@ -304,6 +305,7 @@ SETTING={--Settings
|
||||
VKSFX=.2,--SFX volume
|
||||
VKVIB=0,--VIB
|
||||
VKSwitch=false,--If disp
|
||||
VKSkin=1,--If disp
|
||||
VKTrack=false,--If tracked
|
||||
VKDodge=false,--If dodge
|
||||
VKTchW=.3,--Touch-Pos Weight
|
||||
|
||||
@@ -6,6 +6,12 @@ return{
|
||||
"help",
|
||||
"This translation of the TetroDictionary is provided by me, User670 (Discord: User670#9501).\n\nThe translation may not completely reflect the contents of the original Chinese text."
|
||||
},
|
||||
{"Official website",
|
||||
"official website homepage",
|
||||
"help",
|
||||
"Official website of Techmino!\nYou can modify your profile on it",
|
||||
"home.techmino.org",
|
||||
},
|
||||
{"To New Players",
|
||||
"guide newbie noob",
|
||||
"help",
|
||||
@@ -377,7 +383,6 @@ return{
|
||||
"term",
|
||||
"Special T-Spin techniques that exploit the T piece's kicks and T-Spin detections.\nThey might worth different values in different games (some games consider them Minis), and hardly have real value in combat due to their relatively complex setup.",
|
||||
},
|
||||
|
||||
{"Modern Stack-game",
|
||||
"modern",
|
||||
"term",
|
||||
@@ -438,6 +443,11 @@ return{
|
||||
"term",
|
||||
"Known in Japan as REN.\nConsecutive line clears make up combos. The second line clear in the combo is 1 combo, and the third line clear is 2 combo, and so on.\nUnlike Back to Back, placing a piece that does not clear a line will break the combo.",
|
||||
},
|
||||
{"Spike",
|
||||
"spike",
|
||||
"term",
|
||||
"",--TODO:"爆发攻击\n指短时间内打出大量的攻击,本游戏和TETR.IO中有spike计数器,可以看到自己短时间内打出了多少攻击。\n注意,网络卡顿导致的累计攻击瞬间释放不算spike。",
|
||||
},
|
||||
{"Side well",
|
||||
"sidewell",
|
||||
"term",
|
||||
|
||||
@@ -7,6 +7,12 @@ return{
|
||||
"致想深入玩下去的新人:\n\t两大根本原则:\n\t\t1.选手感好的版本(Techmino/Tetr.io/Jstris/TOP/Tetr.js),别用编程练习渣版本\n\t\t2.踏实打好基础(预判next稳定消四等),别总想着炫酷T旋,对未来发展没好处\n\t两大主要技巧:\n\t\t1.熟悉初始位置以及到各个位置的初始操作\n\t\t2.提前计算好下一块能放哪\n(推荐阅读专栏)一位块圈dalao给新人的话\n\n[点击右下角按钮打开链接]",
|
||||
"https://bilibili.com/read/cv2352939",
|
||||
},
|
||||
{"游戏官网",
|
||||
"official website homepage guanwang",
|
||||
"help",
|
||||
"Techmino的官网!\n可以在上面修改头像和个人信息",
|
||||
"home.techmino.org",
|
||||
},
|
||||
{"Tetris Wiki",
|
||||
"tetris wiki",
|
||||
"help",
|
||||
@@ -363,7 +369,7 @@ return{
|
||||
"Techmino Rotation System\nTechmino独有的旋转系统,基于SRS设计,修补了一些常见SZ卡死的地形,增加了不少实用踢墙,每个五连块也基本按照SRS的spin逻辑单独设计了踢墙表。",
|
||||
},
|
||||
|
||||
--术语(游戏内名词)
|
||||
--术语(其他)
|
||||
{"B2B",
|
||||
"大满贯 b2b btb backtoback",
|
||||
"term",
|
||||
@@ -379,8 +385,6 @@ return{
|
||||
"term",
|
||||
"一种特殊T2的名字,不同的游戏内的攻击可能不一样,没有特殊价值,可以不详细了解。",
|
||||
},
|
||||
|
||||
--术语(其他)
|
||||
{"现代方块",
|
||||
"现代方块 modern xiandaikuai",
|
||||
"term",
|
||||
@@ -441,6 +445,11 @@ return{
|
||||
"term",
|
||||
"从第二次消除起叫1ren/combo,打出的攻击根据游戏设计的不同也不同",
|
||||
},
|
||||
{"Spike",
|
||||
"spike baofa xingbao",
|
||||
"term",
|
||||
"爆发攻击\n指短时间内打出大量的攻击,本游戏和TETR.IO中有spike计数器,可以看到自己短时间内打出了多少攻击。\n注意,网络卡顿导致的累计攻击瞬间释放不算spike。",
|
||||
},
|
||||
{"Side",
|
||||
"连击 ·side",
|
||||
"term",
|
||||
@@ -810,27 +819,27 @@ return{
|
||||
{"重置设置",
|
||||
"reset setting chongzhi qingkong shezhi",
|
||||
"command",
|
||||
"前往控制台输入\"rm conf/setting\"并回车\n需要重启游戏生效,若反悔,进入设置菜单再退出即可恢复文件",
|
||||
"前往控制台输入\"rm conf/setting\"并回车\n需要重启游戏生效,若反悔,进入设置菜单再退出即可恢复文件",
|
||||
},
|
||||
{"重置统计数据",
|
||||
"reset statistic data chongzhi tongji shuju",
|
||||
"command",
|
||||
"前往控制台输入\"rm conf/data\"并回车\n需要重启游戏生效,若反悔,玩一局并触发结算即可恢复文件",
|
||||
"前往控制台输入\"rm conf/data\"并回车\n需要重启游戏生效,若反悔,玩一局并触发结算即可恢复文件",
|
||||
},
|
||||
{"重置解锁状态",
|
||||
"reset unlock chongzhi qingkong jiesuo",
|
||||
"command",
|
||||
"前往控制台输入\"rm conf/unlock\"并回车\n需要重启游戏生效,若反悔,刷新任意一个模式在地图上的状态即可恢复文件",
|
||||
"前往控制台输入\"rm conf/unlock\"并回车\n需要重启游戏生效,若反悔,刷新任意一个模式在地图上的状态即可恢复文件",
|
||||
},
|
||||
{"重置本地排行榜",
|
||||
"reset chongzhi paihangbang",
|
||||
"command",
|
||||
"前往控制台输入\"rm -s record\"并回车\n需要重启游戏生效,若反悔,玩一局并更新模式排行榜即可恢复对应模式的单个排行榜文件",
|
||||
"前往控制台输入\"rm -s record\"并回车\n需要重启游戏生效,若反悔,玩一局并更新模式排行榜即可恢复对应模式的单个排行榜文件",
|
||||
},
|
||||
{"删除键位",
|
||||
"reset virtualkey",
|
||||
"command",
|
||||
"前往控制台输入\"rm conf/键位文件\"并回车\n键盘是key,虚拟按键是virtualkey,虚拟按键预设是vkSave1(2)\n前两者重启生效,若反悔,进入对应的设置菜单再返回即可恢复文件",
|
||||
"前往控制台输入\"rm conf/键位文件\"并回车\n键盘是key,虚拟按键是virtualkey,虚拟按键预设是vkSave1(2)\n前两者重启生效,若反悔,进入对应的设置菜单再返回即可恢复文件",
|
||||
},
|
||||
{"删除录像",
|
||||
"reset replay luxiang",
|
||||
|
||||
@@ -17,7 +17,6 @@ return{
|
||||
clear={"Single","Double","Triple","Techrash","Pentacrash","Hexacrash"},
|
||||
mini="Mini",b2b="B2B ",b3b="B2B2B ",
|
||||
PC="Perfect Clear",HPC="Hemi-Perfect Clear",
|
||||
hold="HOLD",next="NEXT",
|
||||
replaying="[Replay]",
|
||||
|
||||
stage="Stage $1",
|
||||
@@ -78,7 +77,6 @@ return{
|
||||
getVersionFail="Update detection failed",
|
||||
oldVersion="Version $1 is now available!",
|
||||
needUpdate="Newer version required!",
|
||||
noInternet="Not connected to the network",
|
||||
notFinished="Coming soon!",
|
||||
|
||||
jsonError="JSON error",
|
||||
@@ -107,10 +105,11 @@ return{
|
||||
started="Playing",
|
||||
joinRoom="has joined the room.",
|
||||
leaveRoom="has left the room.",
|
||||
ready="READY",
|
||||
connStream="CONNECTING",
|
||||
waitStream="WAITING",
|
||||
ready="Ready",
|
||||
connStream="Connecting",
|
||||
waitStream="Waiting",
|
||||
champion="$1 won",
|
||||
spectating="Spectating",
|
||||
chatRemain="Online",
|
||||
chatStart="------Beginning of log------",
|
||||
chatHistory="------New messages below------",
|
||||
@@ -268,6 +267,7 @@ return{
|
||||
},
|
||||
net_game={
|
||||
ready="Ready",
|
||||
spectate="Spectate",
|
||||
cancel="Cancel",
|
||||
},
|
||||
setting_game={
|
||||
@@ -312,8 +312,8 @@ return{
|
||||
|
||||
text="Line Clear Pop-up",
|
||||
score="Score Pop-up",
|
||||
warn="Danger Alert",
|
||||
bufferWarn="Buffer Alert",
|
||||
showSpike="Spike Counter",
|
||||
highCam="Screen Scrolling",
|
||||
|
||||
nextPos="Next Preview",
|
||||
@@ -321,6 +321,7 @@ return{
|
||||
power="Power Info",
|
||||
clickFX="Click FX",
|
||||
bg="Background",
|
||||
warn="Danger Alert",
|
||||
clean="Fast Draw",
|
||||
},
|
||||
setting_sound={
|
||||
@@ -388,6 +389,7 @@ return{
|
||||
save2="Save2",
|
||||
load2="Load2",
|
||||
size="Size",
|
||||
shape="Shape",
|
||||
},
|
||||
setting_touchSwitch={
|
||||
b1= "Move Left:", b2="Move Right:", b3="Rotate Right:", b4="Rotate Left:",
|
||||
@@ -793,6 +795,7 @@ return{
|
||||
"40-line Sprint WR: 15.654s by VinceHD",
|
||||
"6next 1hold!",
|
||||
"6next 6hold?!",
|
||||
"Achievement system coming soon!",
|
||||
"ALL SPIN!",
|
||||
"Am G F G",
|
||||
"B2B2B???",
|
||||
@@ -813,15 +816,14 @@ return{
|
||||
"Got any suggestions? Post them in our Discord!",
|
||||
"Headphones recommended for a better experience.",
|
||||
"Hello world!",
|
||||
"if a==true",
|
||||
"I3 and L3 are the only two unique triminoes.",
|
||||
"if a==true",
|
||||
"Increase your frame rate for a better experience.",
|
||||
"Initial [insert action] system can save you.",
|
||||
"Is B2B2B2B possible?",
|
||||
"It's possible to finish 40L without left/right button.",
|
||||
"It's really loading! Not just a cutscene!",
|
||||
"Join our discord!",
|
||||
"l-=-1",
|
||||
"Let the bass kick!",
|
||||
"LrL RlR LLr RRl RRR LLL FFF RfR RRf rFF",
|
||||
"Lua No.1",
|
||||
@@ -832,12 +834,14 @@ return{
|
||||
"O-Spin Triple!",
|
||||
"OHHHHHHHHHHHHHH",
|
||||
"Online mode is planned - please be patient.",
|
||||
"Playing good takes some time!",
|
||||
"Play single-handedly!",
|
||||
"Playing good takes some time!",
|
||||
"Powered by Love2D",
|
||||
"Powered by Un..Love2D",
|
||||
"pps-0.01",
|
||||
"REGRET!!",
|
||||
"Secret number: 626",
|
||||
"Server down randomly",
|
||||
"Some requirements to achieve rank S are intentionally set to be difficult for even the best players.",
|
||||
"Soon, you'll be able to play against friends and foes all over the world.",
|
||||
"Split clear coming soon!",
|
||||
@@ -849,6 +853,7 @@ return{
|
||||
"There are three hidden modes in the game.",
|
||||
"There is a total of 18 different pentominoes.",
|
||||
"There is a total of 7 different tetrominoes.",
|
||||
"Try multi-hold!",
|
||||
"Try using two rotate buttons. All three is better.",
|
||||
"Warning: Programmer Art",
|
||||
"What about 20 PCs?",
|
||||
@@ -866,11 +871,12 @@ return{
|
||||
{C.C,"Also try 15puzzle!"},
|
||||
{C.C,"Also try Minecraft!"},
|
||||
{C.C,"Also try Minesweeper!"},
|
||||
{C.C,"Also try Orzmic!"},
|
||||
{C.C,"Also try osu!"},
|
||||
{C.C,"Also try Phigros!"},
|
||||
{C.C,"Also try Rubic's cube!"},
|
||||
{C.C,"Also try Terraria!"},
|
||||
{C.C,"Also try VVVVVVV!"},
|
||||
{C.C,"Also try VVVVVV!"},
|
||||
{C.F,"Also try Cultris II!"},
|
||||
{C.F,"Also try Jstris"},
|
||||
{C.F,"Also try NullpoMino!"},
|
||||
|
||||
@@ -16,7 +16,6 @@ return{
|
||||
clear={"Simple","Double","Triple","Techrash","Pentacrash","Hexacrash"},
|
||||
mini="Mini",b2b="B2B ",b3b="B2B2B ",
|
||||
PC="Perfect Clear",HPC="Clear",
|
||||
hold="RESERVE",next="SUIVANT",
|
||||
replaying="[Replay]",
|
||||
|
||||
stage="Etape $1",
|
||||
@@ -78,7 +77,6 @@ return{
|
||||
getVersionFail="Echec d'obtention de la dernière version",
|
||||
oldVersion="La version $1 est disponible !",
|
||||
-- needUpdate="Newer version required!",
|
||||
-- noInternet="Not connected to the network",
|
||||
-- notFinished="Coming soon!",
|
||||
|
||||
jsonError="Erreur json",
|
||||
@@ -111,6 +109,7 @@ return{
|
||||
-- connStream="CONNECTING",
|
||||
-- waitStream="WAITING",
|
||||
champion="$1 a gagné",
|
||||
-- spectating="Spectating",
|
||||
chatRemain="En ligne : ",
|
||||
chatStart="--------Début des logs--------",
|
||||
chatHistory="-Nouveaux messages en dessous-",
|
||||
@@ -238,6 +237,7 @@ return{
|
||||
},
|
||||
net_game={
|
||||
-- ready="Ready",
|
||||
-- spectate="Spectate",
|
||||
-- cancel="Cancel",
|
||||
},
|
||||
setting_game={
|
||||
@@ -284,7 +284,6 @@ return{
|
||||
|
||||
text="Texte d'action",
|
||||
score="Pop-up de score",
|
||||
warn="Alerte de danger",
|
||||
-- bufferWarn="Buffer Alert",
|
||||
highCam="Vue d'oiseau",
|
||||
|
||||
@@ -293,6 +292,7 @@ return{
|
||||
power="Infos d'alimentation",
|
||||
-- clickFX="Click FX",
|
||||
bg="Arrière-plan",
|
||||
warn="Alerte de danger",
|
||||
-- clean="Fast Draw",
|
||||
},
|
||||
setting_sound={
|
||||
@@ -358,6 +358,7 @@ return{
|
||||
-- save2="Save2",
|
||||
-- load2="Load2",
|
||||
size="Taille",
|
||||
-- shape="Shape",
|
||||
},
|
||||
setting_touchSwitch={
|
||||
b1= "Déplacement vers la gauche :",b2="Déplacement vers la droite:",
|
||||
|
||||
@@ -17,7 +17,6 @@ return{
|
||||
clear={"Single","Double","Triple","Techrash","Pentacrash","Hexacrash"},
|
||||
mini="Mini",b2b="B2B ",b3b="B2B2B ",
|
||||
PC="Perfect Clear",HPC="Clear",
|
||||
hold="HOLD",next="NEXT",
|
||||
replaying="[Replay]",
|
||||
|
||||
stage="Fase $1",
|
||||
@@ -78,7 +77,6 @@ return{
|
||||
getVersionFail="Falha ao detectar uma versão nova",
|
||||
oldVersion="Versão $1 esta disponível agora!",
|
||||
-- needUpdate="Newer version required!",
|
||||
-- noInternet="Not connected to the network",
|
||||
-- notFinished="Coming soon!",
|
||||
|
||||
jsonError="Json error",
|
||||
@@ -268,6 +266,7 @@ return{
|
||||
},
|
||||
net_game={
|
||||
-- ready="Ready",
|
||||
-- spectate="Spectate",
|
||||
-- cancel="Cancel",
|
||||
},
|
||||
setting_game={
|
||||
@@ -312,8 +311,8 @@ return{
|
||||
|
||||
text="Texto de ação",
|
||||
score="Pop-up de pontos",
|
||||
warn="Alerta de perigo",
|
||||
-- bufferWarn="Buffer Alert",
|
||||
-- showSpike="Spike Counter",
|
||||
highCam="Vista Olho-de-pássaro",
|
||||
|
||||
nextPos="Próxima Pos.",
|
||||
@@ -321,6 +320,7 @@ return{
|
||||
power="Informação bateria",
|
||||
-- clickFX="Click FX",
|
||||
bg="Fundo",
|
||||
warn="Alerta de perigo",
|
||||
-- clean="Fast Draw",
|
||||
},
|
||||
setting_sound={
|
||||
@@ -388,6 +388,7 @@ return{
|
||||
-- save2="Save2",
|
||||
-- load2="Load2",
|
||||
size="Tamanho",
|
||||
-- shape="Shape",
|
||||
},
|
||||
setting_touchSwitch={
|
||||
b1= "Esquerda:", b2="Direita:", b3="Giro Dir.:", b4="Giro Esq.:",
|
||||
|
||||
@@ -16,7 +16,6 @@ return{
|
||||
clear={"Single","Doble","Triple","Techrash","Pentacrash","Hexacrash"},
|
||||
mini="Mini",b2b="B2B ",b3b="B2B2B ",
|
||||
PC="Perfect Clear",HPC="Half Clear",
|
||||
hold="Reserva",next="Sig.",
|
||||
replaying="[Repetición]",
|
||||
|
||||
stage="Nivel $1",
|
||||
@@ -78,7 +77,6 @@ return{
|
||||
getVersionFail="Error al buscar nuevas versiones.",
|
||||
oldVersion="¡Está disponible la nueva versión $1!",
|
||||
needUpdate="¡Nueva versión requerida!",
|
||||
-- noInternet="Not connected to the network",
|
||||
notFinished="Próximamente",
|
||||
|
||||
jsonError="Error en Json",
|
||||
@@ -111,6 +109,7 @@ return{
|
||||
-- connStream="CONNECTING",
|
||||
-- waitStream="WAITING",
|
||||
champion="$1 ganó!",
|
||||
-- spectating="Spectating",
|
||||
chatRemain="Usuarios en línea: ",
|
||||
chatStart="------Comienzo del historial------",
|
||||
chatHistory="------Nuevos mensajes------",
|
||||
@@ -245,6 +244,7 @@ return{
|
||||
},
|
||||
net_game={
|
||||
ready="Estoy Listo",
|
||||
-- spectate="Spectate",
|
||||
-- cancel="Cancel",
|
||||
},
|
||||
setting_game={
|
||||
@@ -289,8 +289,8 @@ return{
|
||||
|
||||
text="Texto de Acciones",
|
||||
score="Puntaje en Pantalla",
|
||||
warn="Alerta de Peligro",
|
||||
-- bufferWarn="Buffer Alert",
|
||||
-- showSpike="Spike Counter",
|
||||
highCam="Cám. Vista Aérea",
|
||||
|
||||
nextPos="Ver Spawn de Pza. Sig.",
|
||||
@@ -298,6 +298,7 @@ return{
|
||||
power="Inf. de Batería",
|
||||
-- clickFX="Click FX",
|
||||
bg="Fondo",
|
||||
warn="Alerta de Peligro",
|
||||
clean="Fast Draw",
|
||||
},
|
||||
setting_sound={
|
||||
@@ -361,6 +362,7 @@ return{
|
||||
-- save2="Save2",
|
||||
-- load2="Load2",
|
||||
size="Tamaño",
|
||||
-- shape="Shape",
|
||||
},
|
||||
setting_touchSwitch={
|
||||
b1= "Mover Izq.:",b2="Mover Der.:",b3="Rotar Der.:",b4="Rotar Izq.:",
|
||||
|
||||
@@ -12,7 +12,6 @@ return{
|
||||
clear={"1","2","3","4","5","6"},
|
||||
mini="v",b2b="^ ",b3b="^^ ",
|
||||
PC="#<>#",HPC="<>",
|
||||
hold="[ ]",next="→",
|
||||
replaying="[R]",
|
||||
|
||||
stage="::$1::",
|
||||
@@ -168,8 +167,8 @@ return{
|
||||
|
||||
text="ABC",
|
||||
score="+123",
|
||||
warn="!↑↑↑!",
|
||||
-- bufferWarn="Buffer Alert",
|
||||
bufferWarn="^+",
|
||||
showSpike="→→+",
|
||||
highCam="↑__↑",
|
||||
|
||||
nextPos="???←",
|
||||
@@ -177,6 +176,7 @@ return{
|
||||
power="+.",
|
||||
clickFX="_.~",
|
||||
bg="__?__",
|
||||
warn="!↑↑↑!",
|
||||
clean="[]→→O",
|
||||
},
|
||||
setting_sound={
|
||||
@@ -241,6 +241,7 @@ return{
|
||||
save2=">2",
|
||||
load2="2>",
|
||||
size="←→",
|
||||
shape="@?",
|
||||
},
|
||||
setting_touchSwitch={
|
||||
b1="←:", b2="→:", b3="R→:", b4="←R:",
|
||||
|
||||
@@ -47,6 +47,7 @@ return{
|
||||
createRoomSuccessed="创好了",
|
||||
started="开了",
|
||||
champion="神仙是 $1",
|
||||
spectating="看戏中",
|
||||
|
||||
stat={
|
||||
"开了几次:",
|
||||
@@ -83,9 +84,8 @@ return{
|
||||
|
||||
text="招式名",
|
||||
score="跳分",
|
||||
warn="要死",
|
||||
bufferWarn="离死差多远",
|
||||
highCam="拉镜",
|
||||
warn="要死",
|
||||
},
|
||||
setting_sound={
|
||||
title="改声音",
|
||||
|
||||
@@ -17,7 +17,6 @@ return{
|
||||
clear={"single","double","triple","Techrash","Pentcrash","Hexcrash"},
|
||||
mini="Mini",b2b="B2B ",b3b="B2B2B ",
|
||||
PC="Perfect Clear",HPC="Half Clear",
|
||||
hold="暂存",next="下一个",
|
||||
replaying="[回放]",
|
||||
|
||||
stage="关卡 $1",
|
||||
@@ -78,7 +77,6 @@ return{
|
||||
getVersionFail="检测新版本失败",
|
||||
oldVersion="最新版本$1可以下载了!",
|
||||
needUpdate="请更新游戏!",
|
||||
noInternet="还未连接到网络",
|
||||
notFinished="暂未完成,敬请期待!",
|
||||
|
||||
jsonError="json错误",
|
||||
@@ -111,6 +109,7 @@ return{
|
||||
connStream="正在连接",
|
||||
waitStream="等待其他人连接",
|
||||
champion="$1 获胜",
|
||||
spectating="观战中",
|
||||
chatRemain="人数:",
|
||||
chatStart="------消息的开头------",
|
||||
chatHistory="------以上是历史消息------",
|
||||
@@ -268,6 +267,7 @@ return{
|
||||
},
|
||||
net_game={
|
||||
ready="准备",
|
||||
spectate="观战",
|
||||
cancel="取消",
|
||||
},
|
||||
setting_game={
|
||||
@@ -312,8 +312,8 @@ return{
|
||||
|
||||
text="消行文本",
|
||||
score="分数动画",
|
||||
warn="死亡预警",
|
||||
bufferWarn="缓冲预警",
|
||||
showSpike="爆发累计",
|
||||
highCam="超屏视野",
|
||||
|
||||
nextPos="生成预览",
|
||||
@@ -321,6 +321,7 @@ return{
|
||||
power="电量显示",
|
||||
clickFX="点按特效",
|
||||
bg="背景",
|
||||
warn="死亡预警",
|
||||
clean="绘制优化",
|
||||
},
|
||||
setting_sound={
|
||||
@@ -387,6 +388,7 @@ return{
|
||||
save2="保存2",
|
||||
load2="读取2",
|
||||
size="大小",
|
||||
shape="形状",
|
||||
},
|
||||
setting_touchSwitch={
|
||||
b1= "左移:", b2="右移:", b3="顺时针旋转:", b4="逆时针旋转:",
|
||||
@@ -807,10 +809,10 @@ return{
|
||||
"3next 1hold?",
|
||||
"40行世界纪录:15.654s by VinceHD",
|
||||
"6236326236327175",
|
||||
"626in1",
|
||||
"6next 1hold!",
|
||||
"6next 6hold?!",
|
||||
"7宽三SZ架空捐了解一下",
|
||||
"626in1",
|
||||
"按钮风格进化史",
|
||||
"把手机调到特殊的日期也许会发生什么",
|
||||
"报时机器人:新的一天开始了",
|
||||
@@ -818,7 +820,7 @@ return{
|
||||
"本游戏不是产品,是作品(至少目前是,嗯…)",
|
||||
"本游戏的一部分内容是国际合作的!",
|
||||
"本游戏的B2B是气槽机制,和传统的开关机制不一样哦",
|
||||
"本游戏内置了几个休(ying)闲(he)小游戏哦~入口就藏在这个菜单",
|
||||
"本游戏内置了几个休(ying)闲(he)小游戏哦~",
|
||||
"本游戏在设计的时候受到了大量其他块游甚至一些音游的启发",
|
||||
"必须要软降才能到达的位置都会判定为极简操作",
|
||||
"别看攻击效率不高,其实消四还是很强的",
|
||||
@@ -843,7 +845,6 @@ return{
|
||||
"低帧率会降低游戏体验",
|
||||
"点击添加标题",
|
||||
"点击添加副标题",
|
||||
"点击退出按钮会有极小概率会…",
|
||||
"电脑游玩自带按键显示~",
|
||||
"对编程有真·兴趣推荐Lua,安装无脑 语法简单 执行速度快 远离枯燥学校编程(雾",
|
||||
"对战游戏不是单机游戏,所以timing在对战里也非常重要!",
|
||||
@@ -956,6 +957,8 @@ return{
|
||||
"音乐使用beepbox制作",
|
||||
"音游方块是一家(暴论",
|
||||
"游戏使用love2d引擎制作",
|
||||
"游戏使用un...love2d引擎制作",
|
||||
"游戏也是一种艺术形式",
|
||||
"游戏中左下角三个信息分别是分数/时间/极简连击数",
|
||||
"有建议的话可以把信息反馈给作者~",
|
||||
"有三个隐藏模式不能从地图进入,到处找找看吧",
|
||||
@@ -966,7 +969,7 @@ return{
|
||||
"众所周知俄罗斯方块是经典编程练手游戏(?",
|
||||
"注意到方块\"旋转\"的时候到底发生了些什么吗?",
|
||||
"自定义场地可以画图实现逐页演示",
|
||||
"总共有300多条tip哦",
|
||||
"总共有将近400条tip哦",
|
||||
"作者40行sub26了",
|
||||
"作者电脑上装了10个方块",
|
||||
"作者浏览器收藏夹里有6个方块",
|
||||
@@ -1123,20 +1126,27 @@ return{
|
||||
{C.dH,"3pps不是人均水平?"},
|
||||
{C.dH,"40行还要40多秒,就这?"},
|
||||
{C.dH,"别动不动大惊小怪,就你没见过"},
|
||||
{C.dH,"别会个c4w就以为自己多强,基本功罢了。"},
|
||||
{C.dH,"别会个c4w就以为自己多强,基本功之一罢了。"},
|
||||
{C.dH,"别人用跳舞毯打得都比你好"},
|
||||
{C.dH,"别人只用一只手都能玩,你呢?"},
|
||||
{C.dH,"除了雨宫太阳你还认识谁?Jonas知道吗?Ajanba听过吗?"},
|
||||
{C.dH,"单旋没前途的,别玩了"},
|
||||
{C.dH,"还搁这玩手机呢,作业做完了?"},
|
||||
{C.dH,"激烈的竞争不应当充斥整个游戏"},
|
||||
{C.dH,"极限20G不是随手通?"},
|
||||
{C.dH,"腱鞘炎警告"},
|
||||
{C.dH,"叫你多练就多练,想着几天变神仙,当自己是谁?"},
|
||||
{C.dH,"经典块的水也很深,不要小看经典块玩家"},
|
||||
{C.dH,"经典块跟现代块是两个游戏,别拿多少年前水平秀优越,请从头练起。"},
|
||||
{C.dH,"经典块和渣方块是两个概念"},
|
||||
{C.dH,"觉得Techmino好玩是你的幸运,不是你有优越感的理由"},
|
||||
{C.dH,"卖弱不是谦虚,请看场合。"},
|
||||
{C.dH,"卖弱是要遭报应的"},
|
||||
{C.dH,"满口PCDT信天翁,还会点别的么?"},
|
||||
{C.dH,"没那水平别天天整什么花里胡哨的,人家玩了几年你想几天赶上?"},
|
||||
{C.dH,"没学过编曲,音乐都是自己瞎写的,觉得不好听就去设置关了吧"},
|
||||
{C.dH,"你不会以为S和Z只有两个方向吧"},
|
||||
{C.dH,"请自己先搞搞清楚再去教别人"},
|
||||
{C.dH,"全隐40行全消四很难吗??"},
|
||||
{C.dH,"少玩点游戏,多注意眨眼和休息,瞎了别怪我没提醒你"},
|
||||
{C.dH,"设置都看过一遍了吗?明明都有还在那嫌弃,谁的问题?"},
|
||||
@@ -1151,6 +1161,7 @@ return{
|
||||
{C.dH,"隐形哪难了,你练了吗?没专门练几个小时就说难也太没耐心了吧"},
|
||||
{C.dH,"有问题建议先找找是不是自己的问题,那么多人怎么就你事多?"},
|
||||
{C.dH,"这不是休闲游戏…别怪关卡要求太高,就是你菜,请多练。"},
|
||||
{C.dH,"这年头不会双旋还敢跟人打对战?"},
|
||||
{C.dH,"Techmino没有抽卡没有氪金没有逼肝,良不良心自己没点数?"},
|
||||
}
|
||||
}
|
||||
@@ -161,7 +161,6 @@ do--drawableText
|
||||
|
||||
anykey=T(40),
|
||||
replaying=T(20),
|
||||
next=T(40),hold=T(40),
|
||||
win=T(120),lose=T(120),
|
||||
finish=T(120),
|
||||
gamewin=T(100),gameover=T(100),pause=T(120),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
local yield=YIELD
|
||||
return{
|
||||
color=COLOR.white,
|
||||
env={
|
||||
@@ -6,13 +7,25 @@ return{
|
||||
pushSpeed=5,
|
||||
garbageSpeed=2,
|
||||
allowMod=false,
|
||||
task=function(P)
|
||||
local S=P.stat
|
||||
while true do yield()if S.frame>90*60 then P.strength=1;P:setFrameColor(1)break end end
|
||||
while true do yield()if S.frame>135*60 then P.strength=2;P:setFrameColor(2)break end end
|
||||
while true do yield()if S.frame>180*60 then P.strength=3;P:setFrameColor(3)break end end
|
||||
while true do yield()if S.frame>260*60 then P.strength=4;P:setFrameColor(4)break end end
|
||||
end,
|
||||
bgm={'battle','cruelty','distortion','far','final','hope','magicblock','new era','push','race','rockblock','secret7th','secret8th','shining terminal','storm','super7th','warped','waterfall'},
|
||||
},
|
||||
load=function()
|
||||
PLY.newPlayer(1)
|
||||
PLAYERS[1].sid=netPLY.getSID(USER.uid)
|
||||
local N=2
|
||||
for i=2,netPLY.getCount()do
|
||||
PLY.newRemotePlayer(i,false,netPLY.rawgetPLY(i))
|
||||
local p=netPLY.rawgetPLY(i)
|
||||
if p.connected then
|
||||
PLY.newRemotePlayer(N,false,p)
|
||||
N=N+1
|
||||
end
|
||||
end
|
||||
end,
|
||||
}
|
||||
139
parts/net.lua
139
parts/net.lua
@@ -8,21 +8,26 @@ local NET={
|
||||
connected=false,
|
||||
allow_online=false,
|
||||
accessToken=false,
|
||||
roomList={},
|
||||
roomInfo={
|
||||
-- rid=false,
|
||||
name=false,
|
||||
-- type=false,
|
||||
private=false,
|
||||
-- count=false,
|
||||
roomList={},--Local roomlist, updated frequently
|
||||
roomState={--A copy of room structure on server
|
||||
roomInfo={
|
||||
name=false,
|
||||
type=false,
|
||||
version=false,
|
||||
},
|
||||
roomData={},
|
||||
count=false,
|
||||
capacity=false,
|
||||
private=false,
|
||||
start=false,
|
||||
},
|
||||
spectate=false,--If player is spectating
|
||||
streamRoomID=false,
|
||||
seed=false,
|
||||
|
||||
allReady=false,
|
||||
connectingStream=false,
|
||||
waitingStream=false,
|
||||
serverGaming=false,
|
||||
streamRoomID=false,
|
||||
|
||||
UserCount="_",
|
||||
PlayCount="_",
|
||||
@@ -130,11 +135,11 @@ function NET.wsconn_play()
|
||||
end
|
||||
function NET.wsconn_stream()
|
||||
if NET.lock('wsc_stream',5)then
|
||||
NET.serverGaming=true
|
||||
NET.roomState.start=true
|
||||
WS.connect('stream','/stream',JSON.encode{
|
||||
uid=USER.uid,
|
||||
accessToken=NET.accessToken,
|
||||
rid=NET.streamRoomID,
|
||||
srid=NET.streamRoomID,
|
||||
})
|
||||
TASK.new(NET.updateWS_stream)
|
||||
end
|
||||
@@ -145,7 +150,7 @@ function NET.wsclose_app()WS.close('app')end
|
||||
function NET.wsclose_user()WS.close('user')end
|
||||
function NET.wsclose_play()WS.close('play')end
|
||||
function NET.wsclose_stream()
|
||||
NET.serverGaming=false
|
||||
NET.roomState.start=false
|
||||
WS.close('stream')
|
||||
end
|
||||
|
||||
@@ -162,6 +167,18 @@ function NET.register(username,email,password)
|
||||
})
|
||||
end
|
||||
end
|
||||
function NET.tryLogin(ifAuto)
|
||||
if NET.allow_online then
|
||||
if WS.status('user')=='running'then
|
||||
NET.getAccessToken()
|
||||
elseif not ifAuto then
|
||||
SCN.go('login')
|
||||
end
|
||||
else
|
||||
TEXT.show(text.needUpdate,640,450,60,'flicker')
|
||||
SFX.play('finesseError')
|
||||
end
|
||||
end
|
||||
function NET.pong(wsName,message)
|
||||
WS.send(wsName,type(message)=='string'and message or"",'pong')
|
||||
end
|
||||
@@ -204,17 +221,20 @@ function NET.fetchRoom()
|
||||
end
|
||||
function NET.createRoom(roomName,capacity,roomType,password)
|
||||
if NET.lock('enterRoom',1.26)then
|
||||
NET.roomInfo.name=roomName
|
||||
NET.roomInfo.type=roomType
|
||||
NET.roomInfo.private=not not password
|
||||
NET.roomInfo.capacity=capacity
|
||||
NET.roomState.private=not not password
|
||||
NET.roomState.capacity=capacity
|
||||
WS.send('play',JSON.encode{
|
||||
action=1,
|
||||
data={
|
||||
name=roomName,
|
||||
capacity=capacity,
|
||||
roomData={type=roomType},
|
||||
password=password,
|
||||
roomInfo={
|
||||
name=roomName,
|
||||
type=roomType,
|
||||
version=VERSION.short,
|
||||
},
|
||||
roomData={_=0},
|
||||
|
||||
config=dumpBasicConfig(),
|
||||
}
|
||||
})
|
||||
@@ -223,11 +243,6 @@ end
|
||||
function NET.enterRoom(room,password)
|
||||
if NET.lock('enterRoom',1.26)then
|
||||
SFX.play('reach',.6)
|
||||
NET.roomInfo.name=room.name
|
||||
NET.roomInfo.type=room.type
|
||||
NET.roomInfo.private=not not password
|
||||
NET.roomInfo.capacity=room.capacity
|
||||
NET.roomInfo.start=room.start
|
||||
WS.send('play',JSON.encode{
|
||||
action=2,
|
||||
data={
|
||||
@@ -254,9 +269,9 @@ end
|
||||
function NET.changeConfig()
|
||||
WS.send('play','{"action":5,"data":'..JSON.encode({config=dumpBasicConfig()})..'}')
|
||||
end
|
||||
function NET.signal_ready(ready)
|
||||
if NET.lock('ready',3)and not NET.serverGaming then
|
||||
WS.send('play','{"action":6,"data":{"ready":'..tostring(ready)..'}}')
|
||||
function NET.signal_joinMode(ready)
|
||||
if NET.lock('ready',3)and not NET.roomState.start then
|
||||
WS.send('play','{"action":6,"data":'..JSON.encode{mode=ready}..'}')
|
||||
end
|
||||
end
|
||||
function NET.signal_die()
|
||||
@@ -296,12 +311,15 @@ function NET.updateWS_app()
|
||||
NET.allow_online=true
|
||||
if USER.authToken then
|
||||
NET.wsconn_user_token(USER.uid,USER.authToken)
|
||||
elseif SCN.cur=='main'then
|
||||
SCN.go('login')
|
||||
end
|
||||
end
|
||||
if VERSION.code<res.newestCode then
|
||||
LOG.print(text.oldVersion:gsub("$1",res.newestName),180,'message')
|
||||
end
|
||||
LOG.print(res.notice,300,'message')
|
||||
NET.tryLogin(true)
|
||||
elseif res.action==0 then--Get new version info
|
||||
--?
|
||||
elseif res.action==1 then--Get notice
|
||||
@@ -392,6 +410,7 @@ function NET.updateWS_play()
|
||||
SCN.go('net_menu')
|
||||
NET.unlock('wsc_play')
|
||||
NET.unlock('access_and_login')
|
||||
SFX.play('connected')
|
||||
elseif res.action==0 then--Fetch rooms
|
||||
NET.roomList=res.roomList
|
||||
NET.unlock('fetchRoom')
|
||||
@@ -407,20 +426,38 @@ function NET.updateWS_play()
|
||||
uid=p.uid,
|
||||
username=p.username,
|
||||
sid=p.sid,
|
||||
ready=p.ready,
|
||||
mode=p.mode,
|
||||
config=p.config,
|
||||
}
|
||||
end
|
||||
end
|
||||
--TODO: d.roomData (json)
|
||||
NET.roomState.roomInfo=d.roomInfo
|
||||
NET.roomState.roomData=d.roomData
|
||||
NET.roomState.count=d.count
|
||||
NET.roomState.capacity=d.capacity
|
||||
NET.roomState.private=d.private
|
||||
NET.roomState.start=d.start
|
||||
|
||||
NET.allReady=false
|
||||
NET.connectingStream=false
|
||||
NET.waitingStream=false
|
||||
|
||||
NET.spectate=false
|
||||
NET.streamRoomID=false
|
||||
|
||||
loadGame('netBattle',true,true)
|
||||
if d.srid then
|
||||
NET.spectate=true
|
||||
NET.streamRoomID=d.srid
|
||||
NET.connectingStream=true
|
||||
end
|
||||
else
|
||||
--Load other players
|
||||
netPLY.add{
|
||||
uid=d.uid,
|
||||
username=d.username,
|
||||
sid=d.sid,
|
||||
ready=d.ready,
|
||||
mode=d.mode,
|
||||
config=d.config,
|
||||
}
|
||||
if SCN.socketRead then SCN.socketRead('join',d)end
|
||||
@@ -442,20 +479,21 @@ function NET.updateWS_play()
|
||||
if SCN.socketRead then SCN.socketRead('talk',d)end
|
||||
elseif res.action==5 then--Player change settings
|
||||
netPLY.setConf(d.uid,d.config)
|
||||
elseif res.action==6 then--One ready
|
||||
netPLY.setReady(d.uid,d.ready)
|
||||
elseif res.action==6 then--Player change join mode
|
||||
netPLY.setJoinMode(d.uid,d.mode)
|
||||
elseif res.action==7 then--All Ready
|
||||
SFX.play('reach',.6)
|
||||
NET.allReady=true
|
||||
elseif res.action==8 then--Set
|
||||
NET.streamRoomID=d.rid
|
||||
NET.streamRoomID=d.srid
|
||||
NET.allReady=false
|
||||
NET.connectingStream=true
|
||||
NET.wsconn_stream()
|
||||
elseif res.action==9 then--Game finished
|
||||
NET.wsclose_stream()
|
||||
NET.roomState.start=false
|
||||
NET.spectate=false
|
||||
if SCN.socketRead then SCN.socketRead('finish',d)end
|
||||
NET.roomInfo.start=false
|
||||
NET.wsclose_stream()
|
||||
end
|
||||
else
|
||||
WS.alert('play')
|
||||
@@ -484,17 +522,38 @@ function NET.updateWS_stream()
|
||||
if res.type=='Connect'then
|
||||
NET.unlock('wsc_stream')
|
||||
NET.connectingStream=false
|
||||
NET.waitingStream=true
|
||||
netPLY.setConnect(USER.uid)
|
||||
netPLY.freshStreamConn(res.data.connected)
|
||||
elseif res.action==0 then--Game start
|
||||
NET.waitingStream=false
|
||||
if SCN.socketRead then SCN.socketRead('go',d)end
|
||||
NET.roomInfo.start=true
|
||||
SCN.socketRead('go')
|
||||
elseif res.action==1 then--Game finished
|
||||
--?
|
||||
elseif res.action==2 then--Player join
|
||||
netPLY.setConnect(d.uid)
|
||||
if res.type=='Self'then
|
||||
NET.seed=d.seed
|
||||
NET.spectate=d.spectate
|
||||
netPLY.setConnect(d.uid)
|
||||
for _,p in next,d.connected do
|
||||
if not p.spectate then
|
||||
netPLY.setConnect(p.uid)
|
||||
end
|
||||
end
|
||||
if d.spectate then
|
||||
if d.start then
|
||||
SCN.socketRead('go')
|
||||
for _,v in next,d.history or{}do
|
||||
SCN.socketRead('stream',v)
|
||||
end
|
||||
end
|
||||
else
|
||||
NET.waitingStream=true
|
||||
end
|
||||
else
|
||||
if d.spectate then
|
||||
netPLY.setJoinMode(d.uid,2)
|
||||
else
|
||||
netPLY.setConnect(d.uid)
|
||||
end
|
||||
end
|
||||
elseif res.action==3 then--Player leave
|
||||
--?
|
||||
elseif res.action==4 then--Player died
|
||||
|
||||
@@ -87,6 +87,7 @@ end
|
||||
|
||||
function netPLY.clear()for _=1,netPLY.getCount()do rem(PLY)end end
|
||||
function netPLY.add(p)
|
||||
p.mode=0
|
||||
p.connected=false
|
||||
ins(PLY,p.uid==USER.uid and 1 or #PLY+1,p)
|
||||
local a=rnd()*6.2832
|
||||
@@ -99,23 +100,23 @@ end
|
||||
|
||||
function netPLY.getCount()return #PLY end
|
||||
function netPLY.rawgetPLY(i)return PLY[i]end
|
||||
function netPLY.getUsername(uid)return getPLY(uid).username end
|
||||
function netPLY.getSID(uid)return getPLY(uid).sid end
|
||||
function netPLY.getSelfReady()return PLY[1].ready end
|
||||
function netPLY.getSelfJoinMode()return PLY[1].mode end
|
||||
function netPLY.getSelfReady()return PLY[1].mode>0 end
|
||||
function netPLY.setPlayerObj(ply,p)ply.p=p end
|
||||
function netPLY.setConf(uid,config)getPLY(uid).config=config end
|
||||
function netPLY.setReady(uid,ready)
|
||||
function netPLY.setJoinMode(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
|
||||
if p.mode~=ready then
|
||||
p.mode=ready
|
||||
if ready==0 then NET.allReady=false end
|
||||
SFX.play('spin_0',.6)
|
||||
if i==1 then
|
||||
NET.unlock('ready')
|
||||
elseif not PLY[1].ready then
|
||||
elseif PLY[1].mode==0 then
|
||||
for j=2,#PLY do
|
||||
if not PLY[j].ready then
|
||||
if PLY[j].mode==0 then
|
||||
return
|
||||
end
|
||||
end
|
||||
@@ -126,22 +127,10 @@ function netPLY.setReady(uid,ready)
|
||||
end
|
||||
end
|
||||
end
|
||||
function netPLY.setConnect(uid)
|
||||
for _,p in next,PLY do
|
||||
if p.uid==uid then
|
||||
p.connected=true
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
function netPLY.freshStreamConn(list)
|
||||
for _,p in next,list do
|
||||
getPLY(p.uid).connected=true
|
||||
end
|
||||
end
|
||||
function netPLY.setConnect(uid)getPLY(uid).connected=true end
|
||||
function netPLY.resetState()
|
||||
for i=1,#PLY do
|
||||
PLY[i].ready=false
|
||||
PLY[i].mode=0
|
||||
PLY[i].connected=false
|
||||
end
|
||||
end
|
||||
@@ -179,7 +168,11 @@ function netPLY.draw()
|
||||
local p=PLY[i]
|
||||
gc.translate(p.x,p.y)
|
||||
--Rectangle
|
||||
gc.setColor(COLOR[p.connected and"N"or p.ready and'A'or'Z'])
|
||||
gc.setColor(COLOR[
|
||||
p.mode==0 and'Z'or
|
||||
p.mode==1 and(p.connected and"N"or"G")or
|
||||
p.mode==2 and(p.connected and"Y"or"F")
|
||||
])
|
||||
gc.setLineWidth(2)
|
||||
gc.rectangle('line',0,0,p.w,p.h)
|
||||
|
||||
@@ -199,8 +192,8 @@ function netPLY.draw()
|
||||
gc.print("#"..p.uid,50,-5)
|
||||
gc.print(p.username,210,-5)
|
||||
else
|
||||
setFont(159)
|
||||
gc.print("#"..p.uid,p.h,-2)
|
||||
setFont(15)
|
||||
gc.print("#"..p.uid,46,-1)
|
||||
setFont(30)
|
||||
gc.print(p.username,p.h,8)
|
||||
end
|
||||
|
||||
@@ -111,6 +111,11 @@ return{
|
||||
font=65,
|
||||
color=C.rainbow_dark,
|
||||
},
|
||||
{
|
||||
name="亮君吧",
|
||||
font=65,
|
||||
color=C.rainbow_dark,
|
||||
},
|
||||
|
||||
{
|
||||
name="八零哥",
|
||||
|
||||
@@ -9,7 +9,7 @@ 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,mText=setFont,mDraw,mStr,mText
|
||||
local setFont,mDraw,mStr=setFont,mDraw,mStr
|
||||
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
|
||||
@@ -50,6 +50,12 @@ local spinCenterImg=DOGC{9,9,
|
||||
{'setCL',1,1,1},
|
||||
{'fRect',3,3,3,3},
|
||||
}
|
||||
local playerBoarders=DOGC{334,614,
|
||||
{'setLW',2},
|
||||
{'dRect',16,1,302,612},
|
||||
{'dRect',318,9,15,604},
|
||||
{'dRect',1,9,15,604},
|
||||
}
|
||||
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
|
||||
@@ -249,13 +255,6 @@ local function drawNextPreview(P,B)
|
||||
end
|
||||
end end
|
||||
end
|
||||
local function drawBoarders(P)
|
||||
gc_setLineWidth(2)
|
||||
gc_setColor(P.frameColor)
|
||||
gc_rectangle('line',-1,-11,302,612)--Bis Boarder
|
||||
gc_rectangle('line',301,-3,15,604)
|
||||
gc_rectangle('line',-16,-3,15,604)--B2b bar boarder
|
||||
end
|
||||
local function drawBuffer(P)
|
||||
local h=0
|
||||
for i=1,#P.atkBuffer do
|
||||
@@ -312,14 +311,14 @@ local function drawB2Bbar(P)
|
||||
gc_rectangle('fill',-15,b<40 and 568.5 or 118.5,13,3)
|
||||
end
|
||||
end
|
||||
local function drawLDI(P)--Lock Delay Indicator
|
||||
if P.gameEnv.easyFresh then
|
||||
local function drawLDI(P,ENV)--Lock Delay Indicator
|
||||
if ENV.easyFresh then
|
||||
gc_setColor(1,1,1)
|
||||
else
|
||||
gc_setColor(1,.26,.26)
|
||||
end
|
||||
if P.lockDelay>=0 then
|
||||
gc_rectangle('fill',0,602,300*P.lockDelay/P.gameEnv.lock,6)--Lock delay indicator
|
||||
gc_rectangle('fill',0,602,300*P.lockDelay/ENV.lock,6)--Lock delay indicator
|
||||
end
|
||||
if P.freshTime>0 then
|
||||
LDmarks:setDrawRange(1,min(P.freshTime,15))
|
||||
@@ -333,11 +332,10 @@ local function drawHold(P)
|
||||
local holdQueue=P.holdQueue
|
||||
local N=ENV.holdCount*72
|
||||
gc_push('transform')
|
||||
gc_translate(-140,36)
|
||||
gc_translate(-140,20)
|
||||
gc_setColor(0,0,0,.4)gc_rectangle('fill',0,0,124,N+8)
|
||||
gc_setColor(1,1,1)gc_rectangle('line',0,0,124,N+8)
|
||||
if P.holdTime==0 then gc_setColor(.6,.4,.4)end
|
||||
mText(drawableText.hold,62,-51)
|
||||
|
||||
gc_setColor(1,1,1)
|
||||
if #holdQueue<ENV.holdCount and P.nextQueue[1]then
|
||||
@@ -455,11 +453,10 @@ local draw={}
|
||||
function draw.drawNext_norm(P)
|
||||
local ENV=P.gameEnv
|
||||
local texture=SKIN.curText
|
||||
gc_translate(316,36)
|
||||
gc_translate(316,20)
|
||||
local N=ENV.nextCount*72
|
||||
gc_setColor(0,0,0,.4)gc_rectangle('fill',0,0,124,N+8)
|
||||
gc_setColor(1,1,1)gc_rectangle('line',0,0,124,N+8)
|
||||
mText(drawableText.next,62,-51)
|
||||
N=1
|
||||
gc_push('transform')
|
||||
gc_translate(62,40)
|
||||
@@ -484,16 +481,15 @@ function draw.drawNext_norm(P)
|
||||
gc_rectangle('fill',2,72*i+3,120,2)
|
||||
end
|
||||
end
|
||||
gc_translate(-316,-36)
|
||||
gc_translate(-316,-20)
|
||||
end
|
||||
function draw.drawNext_hidden(P)
|
||||
local ENV=P.gameEnv
|
||||
local texture=SKIN.curText
|
||||
gc_translate(316,36)
|
||||
gc_translate(316,20)
|
||||
local N=ENV.nextCount*72
|
||||
gc_setColor(.5,0,0,.4)gc_rectangle('fill',0,0,124,N+8)
|
||||
gc_setColor(1,1,1)gc_rectangle('line',0,0,124,N+8)
|
||||
mText(drawableText.next,62,-51)
|
||||
N=min(ENV.nextStartPos,P.pieceCount+1)
|
||||
gc_push('transform')
|
||||
gc_translate(62,40)
|
||||
@@ -519,7 +515,7 @@ function draw.drawNext_hidden(P)
|
||||
gc_rectangle('fill',2,72*i+3,120,2)
|
||||
end
|
||||
end
|
||||
gc_translate(-316,-36)
|
||||
gc_translate(-316,-20)
|
||||
end
|
||||
draw.applyFieldOffset=applyFieldOffset
|
||||
|
||||
@@ -636,12 +632,16 @@ function draw.norm(P)
|
||||
gc_pop()
|
||||
gc_setStencilTest()
|
||||
|
||||
drawBoarders(P)
|
||||
gc_setLineWidth(2)
|
||||
P:drawNext()
|
||||
drawHold(P)
|
||||
drawBuffer(P)
|
||||
drawB2Bbar(P)
|
||||
drawLDI(P)
|
||||
drawHold(P)
|
||||
P:drawNext()
|
||||
drawLDI(P,ENV)
|
||||
|
||||
--Draw boarders
|
||||
gc_setColor(P.frameColor)
|
||||
gc.draw(playerBoarders,-17,-12)
|
||||
|
||||
--Draw target selecting pad
|
||||
if GAME.modeEnv.royaleMode then
|
||||
@@ -656,6 +656,8 @@ function draw.norm(P)
|
||||
gc_printf(text.atkModeName[i],RCPB[2*i-1]-4,RCPB[2*i]+4,200,"center",nil,.5)
|
||||
end
|
||||
end
|
||||
|
||||
--Board cover
|
||||
if ENV.hideBoard then
|
||||
gc_stencil(hideBoardStencil[ENV.hideBoard],'replace',1)
|
||||
gc_setStencilTest('equal',1)
|
||||
@@ -666,13 +668,22 @@ function draw.norm(P)
|
||||
end
|
||||
gc_setStencilTest()
|
||||
end
|
||||
|
||||
--Spike
|
||||
if ENV.showSpike and P.spikeTime>0 and P.spike>=10 then
|
||||
local gb=10/P.spike
|
||||
gc_setColor(1,gb,gb,min(P.spikeTime/30,.8))
|
||||
mDraw(P.spikeText,150,100,nil,min(.3+(P.spike/26)*.4+P.spikeTime/100*.3,1))
|
||||
end
|
||||
|
||||
--Bonus texts
|
||||
TEXT.draw(P.bonus)
|
||||
|
||||
--Display Ys
|
||||
-- gc_setLineWidth(6)
|
||||
-- if P.curY then gc_setColor(COLOR.R)gc_line(0,611-P.curY*30,300,610-P.curY*30)end
|
||||
-- if P.ghoY then gc_setColor(COLOR.G)gc_line(0,615-P.ghoY*30,300,615-P.ghoY*30)end
|
||||
-- if P.minY then gc_setColor(COLOR.B)gc_line(0,619-P.minY*30,300,620-P.minY*30)end
|
||||
-- if P.curY then gc_setColor(COLOR.R) gc_line(0,611-P.curY*30,300,610-P.curY*30)end
|
||||
-- if P.ghoY then gc_setColor(COLOR.G) gc_line(0,615-P.ghoY*30,300,615-P.ghoY*30)end
|
||||
-- if P.minY then gc_setColor(COLOR.B) gc_line(0,619-P.minY*30,300,620-P.minY*30)end
|
||||
-- gc_line(0,600-P.garbageBeneath*30,300,600-P.garbageBeneath*30)
|
||||
gc_pop()
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@ return{
|
||||
bufferWarn=false,
|
||||
highCam=false,
|
||||
nextPos=false,
|
||||
showSpike=false,
|
||||
|
||||
hideBoard=false,
|
||||
flipBoard=false,
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@ local function newEmptyPlayer(id,mini)
|
||||
--Inherit functions of Player class
|
||||
for k,v in next,Player do P[k]=v end
|
||||
|
||||
--Set key/timer event
|
||||
if P.id==1 and GAME.recording then
|
||||
P.pressKey=pressKey_Rec
|
||||
P.releaseKey=releaseKey_Rec
|
||||
@@ -88,6 +89,7 @@ local function newEmptyPlayer(id,mini)
|
||||
end
|
||||
P.update=ply_update.alive
|
||||
|
||||
--Field position
|
||||
P.fieldOff={--Shake FX
|
||||
x=0,y=0,
|
||||
vx=0,vy=0,
|
||||
@@ -101,8 +103,8 @@ local function newEmptyPlayer(id,mini)
|
||||
-- P.centerX,P.centerY=...
|
||||
-- P.absFieldX,P.absFieldY=...
|
||||
|
||||
--If draw in small mode
|
||||
P.mini=mini
|
||||
--Minimode
|
||||
P.miniMode=mini
|
||||
if mini then
|
||||
P.canvas=love.graphics.newCanvas(60,120)
|
||||
P.frameWait=rnd(26,62)
|
||||
@@ -111,60 +113,87 @@ local function newEmptyPlayer(id,mini)
|
||||
P.draw=ply_draw.norm
|
||||
end
|
||||
|
||||
--States
|
||||
P.type='none'
|
||||
P.sound=false
|
||||
P.alive=true
|
||||
P.control=false
|
||||
P.timing=false
|
||||
P.result=false--String: 'finish'|'win'|'lose'
|
||||
P.stat=getNewStatTable()
|
||||
P.modeData=setmetatable({},modeDataMeta)--Data use by mode
|
||||
P.keyPressing={}for i=1,12 do P.keyPressing[i]=false end
|
||||
P.clearingRow,P.clearedRow={},{}--Clearing animation height,cleared row mark
|
||||
P.dropFX,P.moveFX,P.lockFX,P.clearFX={},{},{},{}
|
||||
P.tasks={}
|
||||
P.bonus={}--Texts
|
||||
|
||||
--Times
|
||||
P.frameRun=GAME.frameStart--Frame run, mainly for replay
|
||||
P.endCounter=0--Used after gameover
|
||||
P.keyTime={}for i=1,10 do P.keyTime[i]=-1e99 end P.keySpeed=0
|
||||
P.dropTime={}for i=1,10 do P.dropTime[i]=-1e99 end P.dropSpeed=0
|
||||
|
||||
--Randomizers
|
||||
P.seqRND=love.math.newRandomGenerator(GAME.seed)
|
||||
P.atkRND=love.math.newRandomGenerator(GAME.seed)
|
||||
P.holeRND=love.math.newRandomGenerator(GAME.seed)
|
||||
P.aiRND=love.math.newRandomGenerator(GAME.seed)
|
||||
|
||||
P.frameRun=GAME.frameStart
|
||||
P.alive=true
|
||||
P.control=false
|
||||
P.timing=false
|
||||
P.stat=getNewStatTable()
|
||||
|
||||
P.modeData=setmetatable({},modeDataMeta)--Data use by mode
|
||||
|
||||
P.keyTime={}P.keySpeed=0
|
||||
P.dropTime={}P.dropSpeed=0
|
||||
for i=1,10 do P.keyTime[i]=-1e99 end
|
||||
for i=1,10 do P.dropTime[i]=-1e99 end
|
||||
|
||||
--Field-related
|
||||
P.field,P.visTime={},{}
|
||||
P.atkBuffer={}
|
||||
P.atkBufferSum=0
|
||||
P.atkBufferSum1=0
|
||||
P.keepVisible=true
|
||||
P.showTime=false
|
||||
P.garbageBeneath=0
|
||||
P.fieldBeneath=0
|
||||
P.fieldUp=0
|
||||
|
||||
--Royale-related
|
||||
--Attack-related
|
||||
P.atkBuffer={}
|
||||
P.atkBufferSum,P.atkBufferSum1=0,0
|
||||
P.spike,P.spikeTime=0,0
|
||||
P.spikeText=love.graphics.newText(getFont(100))
|
||||
|
||||
--Attacker-related
|
||||
P.badge,P.strength=0,0
|
||||
P.atkMode,P.swappingAtkMode=1,20
|
||||
P.atker,P.atking,P.lastRecv={}
|
||||
|
||||
--Network-related
|
||||
--User-related
|
||||
P.username=""
|
||||
P.uid=false
|
||||
P.sid=false
|
||||
|
||||
P.dropDelay,P.lockDelay=0,0
|
||||
P.showTime=false
|
||||
P.keepVisible=true
|
||||
|
||||
--Block states
|
||||
--[[
|
||||
P.cur={
|
||||
id=shapeID,
|
||||
bk=matrix[2],
|
||||
sc=table[2],
|
||||
dir=direction,
|
||||
name=nameID
|
||||
color=colorID,
|
||||
}
|
||||
P.curX,P.curY,P.ghoY,P.minY=0,0,0,0--x,y,ghostY
|
||||
P.cur={
|
||||
id=shapeID,
|
||||
bk=matrix[2],
|
||||
sc=table[2],
|
||||
dir=direction,
|
||||
name=nameID
|
||||
color=colorID,
|
||||
}
|
||||
P.newNext=false--Warped coroutine to get new next, loaded in applyGameEnv()
|
||||
]]
|
||||
-- P.curX,P.curY,P.ghoY,P.minY=0,0,0,0--x,y,ghostY
|
||||
P.holdQueue={}
|
||||
P.holdTime=0
|
||||
P.nextQueue={}
|
||||
|
||||
P.movDir,P.moving,P.downing=0,0,0--Last move key,DAS charging,downDAS charging
|
||||
P.dropDelay,P.lockDelay=0,0
|
||||
P.waiting,P.falling=-1,-1
|
||||
P.freshTime=0
|
||||
P.spinLast=false
|
||||
P.spinSeq=0--For Ospin, each digit mean a spin
|
||||
P.ctrlCount=0--Key press time, for finesse check
|
||||
|
||||
--Game states
|
||||
P.combo=0
|
||||
P.b2b,P.b2b1=0,0--B2B point & Displayed B2B point
|
||||
P.score1=0--Displayed score
|
||||
P.pieceCount=0--Count pieces from next, for drawing bagline
|
||||
P.finesseCombo,P.finesseComboTime=0,0
|
||||
P.nextQueue={}
|
||||
P.holdQueue={}
|
||||
P.holdTime=0
|
||||
P.lastPiece={
|
||||
id=0,name=0,--block id/name
|
||||
|
||||
@@ -179,34 +208,6 @@ local function newEmptyPlayer(id,mini)
|
||||
pc=false,hpc=false,--if pc/hpc
|
||||
special=false,--if special clear (spin, >=4, pc)
|
||||
}
|
||||
P.spinSeq=0--For Ospin, each digit mean a spin
|
||||
P.ctrlCount=0--Key press time, for finesse check
|
||||
P.pieceCount=0--Count pieces from next, for drawing bagline
|
||||
|
||||
P.type='none'
|
||||
P.sound=false
|
||||
|
||||
-- P.newNext=false--Warped coroutine to get new next, loaded in applyGameEnv()
|
||||
|
||||
P.keyPressing={}for i=1,12 do P.keyPressing[i]=false end
|
||||
P.movDir,P.moving,P.downing=0,0,0--Last move key,DAS charging,downDAS charging
|
||||
P.waiting,P.falling=-1,-1
|
||||
P.clearingRow,P.clearedRow={},{}--Clearing animation height,cleared row mark
|
||||
P.combo,P.b2b=0,0
|
||||
P.finesseCombo=0
|
||||
P.garbageBeneath=0
|
||||
P.fieldBeneath=0
|
||||
P.fieldUp=0
|
||||
|
||||
P.score1,P.b2b1=0,0
|
||||
P.finesseComboTime=0
|
||||
P.dropFX,P.moveFX,P.lockFX,P.clearFX={},{},{},{}
|
||||
P.tasks={}--Tasks
|
||||
P.bonus={}--Text objects
|
||||
|
||||
P.endCounter=0--Used after gameover
|
||||
P.result=false--String: 'finish'|'win'|'lose'
|
||||
|
||||
return P
|
||||
end
|
||||
local function loadGameEnv(P)--Load gameEnv
|
||||
@@ -321,7 +322,7 @@ local function applyGameEnv(P)--Finish gameEnv processing
|
||||
P.newNext=coroutine.wrap(seqGenerators(P))
|
||||
P.newNext(P,P.gameEnv.seqData)
|
||||
|
||||
if P.mini then
|
||||
if P.miniMode then
|
||||
ENV.lockFX=false
|
||||
ENV.dropFX=false
|
||||
ENV.moveFX=false
|
||||
|
||||
@@ -105,7 +105,7 @@ function Player:createClearingFX(y,spd)
|
||||
end
|
||||
function Player:createBeam(R,send,power,color)
|
||||
local x1,y1,x2,y2
|
||||
if self.mini then x1,y1=self.centerX,self.centerY
|
||||
if self.miniMode then x1,y1=self.centerX,self.centerY
|
||||
else x1,y1=self.x+(30*(self.curX+self.cur.sc[2])-30+15+150)*self.size,self.y+(600-30*(self.curY+self.cur.sc[1])+15)*self.size
|
||||
end
|
||||
if R.small then x2,y2=R.centerX,R.centerY
|
||||
@@ -136,7 +136,7 @@ end
|
||||
function Player:setPosition(x,y,size)
|
||||
size=size or 1
|
||||
self.x,self.y,self.size=x,y,size
|
||||
if self.mini or self.demo then
|
||||
if self.miniMode or self.demo then
|
||||
self.fieldX,self.fieldY=x,y
|
||||
self.centerX,self.centerY=x+300*size,y+600*size
|
||||
else
|
||||
@@ -1380,6 +1380,13 @@ do--Player.drop(self)--Place piece
|
||||
|
||||
self.combo=cmb
|
||||
|
||||
--Spike
|
||||
if atk>0 then
|
||||
self.spike=self.spikeTime==0 and atk or self.spike+atk
|
||||
self.spikeTime=min(self.spikeTime+atk*20,100)
|
||||
self.spikeText:set(self.spike)
|
||||
end
|
||||
|
||||
--DropSpeed bonus
|
||||
if self._20G then
|
||||
cscore=cscore*2
|
||||
@@ -1727,7 +1734,7 @@ function Player:lose(force)
|
||||
for i=A.strength+1,4 do
|
||||
if A.badge>=ROYALEDATA.powerUp[i]then
|
||||
A.strength=i
|
||||
A:setFrameColor(A.strength)
|
||||
A:setFrameColor(i)
|
||||
end
|
||||
end
|
||||
self.lastRecv=A
|
||||
@@ -1757,7 +1764,7 @@ function Player:lose(force)
|
||||
end
|
||||
gameOver()
|
||||
self:newTask(#PLAYERS>1 and tick_lose or tick_finish)
|
||||
if GAME.net then
|
||||
if GAME.net and not NET.spectate then
|
||||
NET.signal_die()
|
||||
else
|
||||
TASK.new(tick_autoPause)
|
||||
|
||||
@@ -3,7 +3,7 @@ local int,abs,rnd=math.floor,math.abs,math.random
|
||||
local rem=table.remove
|
||||
local assert,resume,status=assert,coroutine.resume,coroutine.status
|
||||
|
||||
local TEXT,GAME=TEXT,GAME
|
||||
local TEXT,GAME,CC=TEXT,GAME,CC
|
||||
local PLY_ALIVE=PLY_ALIVE
|
||||
|
||||
local function update_misc(P,dt)
|
||||
@@ -12,6 +12,9 @@ local function update_misc(P,dt)
|
||||
P.finesseComboTime=P.finesseComboTime-1
|
||||
end
|
||||
|
||||
--Update spike counter
|
||||
if P.spikeTime>0 then P.spikeTime=P.spikeTime-1 end
|
||||
|
||||
--Update atkBuffer alert
|
||||
local t=P.atkBufferSum1
|
||||
if t<P.atkBufferSum then
|
||||
@@ -402,14 +405,15 @@ function update.dead(P,dt)
|
||||
end
|
||||
function update.remote_alive(P,dt)
|
||||
local frameRate=(P.stream[#P.stream-1]or 0)-P.frameRun
|
||||
frameRate=frameRate<20 and 1 or
|
||||
frameRate<30 and rnd(2)or
|
||||
frameRate<60 and 2 or
|
||||
frameRate<90 and 3 or
|
||||
frameRate<120 and 5 or
|
||||
frameRate<150 and 7 or
|
||||
frameRate<180 and 10 or
|
||||
20
|
||||
frameRate=
|
||||
frameRate<20 and 1 or
|
||||
frameRate<30 and rnd(2)or
|
||||
frameRate<60 and 2 or
|
||||
frameRate<90 and 3 or
|
||||
frameRate<120 and 5 or
|
||||
frameRate<150 and 7 or
|
||||
frameRate<180 and 10 or
|
||||
20
|
||||
for _=1,frameRate do
|
||||
local eventTime=P.stream[P.streamProgress]
|
||||
if eventTime then--Normal state, event forward
|
||||
|
||||
@@ -677,8 +677,7 @@ userG.the_box=first_box
|
||||
local scene={}
|
||||
|
||||
function scene.sceneInit()
|
||||
TASK.new(function()YIELD()WIDGET.sel=inputBox end)
|
||||
enableTextInput()
|
||||
TASK.new(function()WIDGET.focus(inputBox)end)
|
||||
BG.set('none')
|
||||
end
|
||||
|
||||
@@ -688,7 +687,7 @@ end
|
||||
|
||||
function scene.keyDown(k)
|
||||
if k=="return"then
|
||||
local input=inputBox:getText()
|
||||
local input=STRING.trim(inputBox:getText())
|
||||
if input==""then return end
|
||||
|
||||
--Write History
|
||||
@@ -700,7 +699,6 @@ function scene.keyDown(k)
|
||||
log""
|
||||
|
||||
--Execute
|
||||
input=input:sub((input:find("%S")))
|
||||
if input:byte()==35 then
|
||||
--Execute lua code
|
||||
log{C.lC,"> "..input}
|
||||
@@ -780,13 +778,13 @@ function scene.keyDown(k)
|
||||
elseif combKey[k]and kb.isDown("lctrl","rctrl")then
|
||||
combKey[k]()
|
||||
elseif k=="escape"then
|
||||
if WIDGET.sel~=inputBox then
|
||||
WIDGET.sel=inputBox
|
||||
if not WIDGET.isFocus(inputBox)then
|
||||
WIDGET.focus(inputBox)
|
||||
else
|
||||
SCN.back()
|
||||
end
|
||||
else
|
||||
if WIDGET.sel~=inputBox then WIDGET.sel=inputBox end
|
||||
if not WIDGET.isFocus(inputBox)then WIDGET.focus(inputBox)end
|
||||
WIDGET.keyPressed(k)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -229,7 +229,6 @@ function scene.keyDown(key)
|
||||
if DATA.pasteBoard(str,page)then
|
||||
LOG.print(text.importSuccess,'message')
|
||||
else
|
||||
print(text.dataCorrupted)
|
||||
LOG.print(text.dataCorrupted,'error')
|
||||
end
|
||||
elseif key=="pageup"then
|
||||
|
||||
@@ -68,8 +68,7 @@ function scene.sceneInit()
|
||||
scrollPos=0
|
||||
|
||||
lastSearch=false
|
||||
TASK.new(function()YIELD()WIDGET.sel=inputBox end)
|
||||
enableTextInput()
|
||||
TASK.new(function()YIELD()WIDGET.focus(inputBox)end)
|
||||
BG.set('rainbow')
|
||||
end
|
||||
|
||||
|
||||
@@ -197,8 +197,8 @@ local loadingThread=coroutine.wrap(function()
|
||||
upFloor()
|
||||
end
|
||||
if progress==25 then
|
||||
SFX.play("emit",.6)
|
||||
SFX.play("enter",.8)
|
||||
SFX.play('emit',.6)
|
||||
SFX.play('enter',.8)
|
||||
SFX.play('welcome_sfx')
|
||||
VOC.play('welcome_voc')
|
||||
THEME.fresh()
|
||||
|
||||
@@ -29,7 +29,6 @@ function scene.sceneInit()
|
||||
emailBox:setText(data[1])
|
||||
passwordBox:setText(data[2])
|
||||
end
|
||||
enableTextInput()
|
||||
end
|
||||
|
||||
scene.widgetList={
|
||||
|
||||
@@ -46,10 +46,10 @@ function scene.mouseDown(x,y)
|
||||
end
|
||||
scene.touchDown=scene.mouseDown
|
||||
local function testButton(n)
|
||||
if WIDGET.sel==scene.widgetList[n]then
|
||||
if WIDGET.isFocus(scene.widgetList[n])then
|
||||
return true
|
||||
else
|
||||
WIDGET.sel=scene.widgetList[n]
|
||||
WIDGET.focus(scene.widgetList[n])
|
||||
end
|
||||
end
|
||||
function scene.keyDown(key)
|
||||
@@ -64,21 +64,11 @@ function scene.keyDown(key)
|
||||
elseif key=="a"then
|
||||
if testButton(3)then
|
||||
if NET.connected then
|
||||
if NET.allow_online then
|
||||
if WS.status('user')=='running'then
|
||||
NET.getAccessToken()
|
||||
else
|
||||
SCN.go('login')
|
||||
end
|
||||
else
|
||||
TEXT.show(text.needUpdate,640,450,60,'flicker')
|
||||
SFX.play('finesseError')
|
||||
end
|
||||
NET.tryLogin(false)
|
||||
else
|
||||
TEXT.show(text.noInternet,640,450,60,'flicker')
|
||||
NET.wsconn_app()
|
||||
LOG.print(text.wsConnecting,'message')
|
||||
SFX.play('finesseError')
|
||||
SFX.play('connect')
|
||||
end
|
||||
end
|
||||
elseif key=="z"then
|
||||
@@ -131,7 +121,7 @@ function scene.update(dt)
|
||||
end
|
||||
local L=scene.widgetList
|
||||
for i=1,8 do
|
||||
L[i].x=L[i].x*.9+(widgetX0[i]-400+(WIDGET.sel==L[i]and(i<5 and 100 or -100)or 0))*.1
|
||||
L[i].x=L[i].x*.9+(widgetX0[i]-400+(WIDGET.isFocus(L[i])and(i<5 and 100 or -100)or 0))*.1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ local scene={}
|
||||
function scene.sceneInit(org)
|
||||
BG.set()
|
||||
destroyPlayers()
|
||||
mapCam.zoomK=org=="main"and 5 or 1
|
||||
mapCam.zoomK=org=='main'and 5 or 1
|
||||
end
|
||||
|
||||
local function getK()
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
local gc,tc,kb=love.graphics,love.touch,love.keyboard
|
||||
local gc,tc=love.graphics,love.touch
|
||||
|
||||
local gc_setColor,gc_print=gc.setColor,gc.print
|
||||
local setFont,mStr=setFont,mStr
|
||||
|
||||
local ins=table.insert
|
||||
|
||||
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=560,hide=false}
|
||||
local inputBox=WIDGET.newInputBox{name="input",x=340,y=660,w=600,h=50,hide=false}
|
||||
local textBox=WIDGET.newTextBox{name="texts",x=340,y=80,w=600,h=560}
|
||||
local inputBox=WIDGET.newInputBox{name="input",x=340,y=660,w=600,h=50}
|
||||
|
||||
local playing
|
||||
local lastUpstreamTime
|
||||
@@ -13,6 +18,34 @@ local lastBackTime=0
|
||||
local noTouch,noKey=false,false
|
||||
local touchMoveLastFrame=false
|
||||
|
||||
local function _setReady()NET.signal_joinMode(1)end
|
||||
local function _setSpectate()NET.signal_joinMode(2)end
|
||||
local function _setCancel()NET.signal_joinMode(0)end
|
||||
local function _gotoSetting()
|
||||
if not(netPLY.getSelfReady()or NET.getlock('ready'))then
|
||||
SCN.go('setting_game')
|
||||
end
|
||||
end
|
||||
local function _quit()
|
||||
if TIME()-lastBackTime<1 then
|
||||
NET.signal_quit()
|
||||
else
|
||||
lastBackTime=TIME()
|
||||
LOG.print(text.sureQuit,'warn')
|
||||
end
|
||||
end
|
||||
local function _switchChat()
|
||||
if inputBox.hide then
|
||||
textBox.hide=false
|
||||
inputBox.hide=false
|
||||
WIDGET.focus(inputBox)
|
||||
else
|
||||
textBox.hide=true
|
||||
inputBox.hide=true
|
||||
WIDGET.unFocus(true)
|
||||
end
|
||||
end
|
||||
|
||||
local scene={}
|
||||
|
||||
function scene.sceneInit(org)
|
||||
@@ -25,8 +58,10 @@ function scene.sceneInit(org)
|
||||
lastUpstreamTime=0
|
||||
upstreamProgress=1
|
||||
|
||||
if org=="setting_game"then
|
||||
NET.changeConfig()
|
||||
if org=='setting_game'then NET.changeConfig()end
|
||||
if NET.streamRoomID then
|
||||
NET.wsconn_stream()
|
||||
NET.streamRoomID=false
|
||||
end
|
||||
end
|
||||
function scene.sceneBack()
|
||||
@@ -36,7 +71,8 @@ end
|
||||
scene.mouseDown=NULL
|
||||
function scene.mouseMove(x,y)netPLY.mouseMove(x,y)end
|
||||
function scene.touchDown(x,y)
|
||||
if not playing or noTouch then return end
|
||||
if not playing then netPLY.mouseMove(x,y)return end
|
||||
if noTouch then return end
|
||||
|
||||
local t=VK.on(x,y)
|
||||
if t then
|
||||
@@ -52,9 +88,8 @@ function scene.touchUp(x,y)
|
||||
VK.release(n)
|
||||
end
|
||||
end
|
||||
function scene.touchMove(x,y)
|
||||
if not playing then netPLY.mouseMove(x,y)return end
|
||||
if touchMoveLastFrame or noTouch then return end
|
||||
function scene.touchMove()
|
||||
if touchMoveLastFrame or not playing or noTouch then return end
|
||||
touchMoveLastFrame=true
|
||||
|
||||
local L=tc.getTouches()
|
||||
@@ -78,33 +113,27 @@ function scene.touchMove(x,y)
|
||||
end
|
||||
function scene.keyDown(key)
|
||||
if key=="escape"then
|
||||
if TIME()-lastBackTime<1 then
|
||||
NET.signal_quit()
|
||||
if not inputBox.hide then
|
||||
scene.keyDown("switchChat")
|
||||
else
|
||||
lastBackTime=TIME()
|
||||
LOG.print(text.sureQuit,'warn')
|
||||
_quit()
|
||||
end
|
||||
elseif key=="return"then
|
||||
if inputBox.hide then
|
||||
textBox.hide=false
|
||||
inputBox.hide=false
|
||||
TASK.new(function()YIELD()WIDGET.sel=inputBox end)
|
||||
enableTextInput()
|
||||
else
|
||||
local mes=STRING.trim(inputBox:getText())
|
||||
if mes and #mes>0 then
|
||||
local mes=STRING.trim(inputBox:getText())
|
||||
if not inputBox.hide then
|
||||
if #mes>0 then
|
||||
NET.sendMessage(mes)
|
||||
inputBox:clear()
|
||||
elseif #EDITING==0 then
|
||||
textBox.hide=true
|
||||
inputBox.hide=true
|
||||
WIDGET.sel=nil
|
||||
kb.setTextInput(false)
|
||||
_switchChat()
|
||||
end
|
||||
else
|
||||
_switchChat()
|
||||
end
|
||||
elseif not inputBox.hide then
|
||||
WIDGET.sel=inputBox
|
||||
WIDGET.keyPressed(key)
|
||||
print(1)
|
||||
WIDGET.focus(inputBox)
|
||||
inputBox:keypress(key)
|
||||
elseif playing then
|
||||
if not playing or noKey then return end
|
||||
local k=keyMap.keyboard[key]
|
||||
@@ -114,11 +143,17 @@ function scene.keyDown(key)
|
||||
end
|
||||
else
|
||||
if key=="space"then
|
||||
NET.signal_ready(not netPLY.getSelfReady())
|
||||
elseif key=="s"then
|
||||
if not(netPLY.getSelfReady()or NET.getlock('ready'))then
|
||||
SCN.go('setting_game')
|
||||
if netPLY.getSelfJoinMode()==0 then
|
||||
_setReady()
|
||||
else
|
||||
_setCancel()
|
||||
end
|
||||
elseif key=="p"then
|
||||
if netPLY.getSelfJoinMode()==0 then
|
||||
_setSpectate()
|
||||
end
|
||||
elseif key=="s"then
|
||||
_gotoSetting()
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -175,11 +210,10 @@ function scene.socketRead(cmd,d)
|
||||
if not playing then
|
||||
playing=true
|
||||
love.keyboard.setKeyRepeat(false)
|
||||
netPLY.resetState()
|
||||
netPLY.mouseMove(0,0)
|
||||
lastUpstreamTime=0
|
||||
upstreamProgress=1
|
||||
resetGameData('n',d.seed)
|
||||
resetGameData('n',NET.seed)
|
||||
netPLY.mouseMove(0,0)
|
||||
else
|
||||
LOG.print("Redundant [Go]",'warn')
|
||||
end
|
||||
@@ -194,10 +228,11 @@ function scene.socketRead(cmd,d)
|
||||
end
|
||||
end
|
||||
if winnerUID then
|
||||
TEXT.show(text.champion:gsub("$1",netPLY.getUsername(winnerUID)),640,260,80,'zoomout',.26)
|
||||
TEXT.show(text.champion:gsub("$1",USERS.getUsername(winnerUID)),640,260,80,'zoomout',.26)
|
||||
end
|
||||
netPLY.resetState()
|
||||
elseif cmd=='stream'then
|
||||
if d.uid~=USER.uid and playing then
|
||||
if d.uid~=USER.uid then
|
||||
for _,P in next,PLAYERS do
|
||||
if P.uid==d.uid then
|
||||
local res,stream=pcall(love.data.decode,'string','base64',d.stream)
|
||||
@@ -206,9 +241,11 @@ function scene.socketRead(cmd,d)
|
||||
else
|
||||
LOG.print("Bad stream from "..P.username.."#"..P.uid,30)
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -230,15 +267,19 @@ function scene.update(dt)
|
||||
checkWarning()
|
||||
|
||||
--Upload stream
|
||||
if P1.frameRun-lastUpstreamTime>8 then
|
||||
if not NET.spectate and P1.frameRun-lastUpstreamTime>8 then
|
||||
local stream
|
||||
stream,upstreamProgress=DATA.dumpRecording(GAME.rep,upstreamProgress)
|
||||
if #stream>0 then
|
||||
NET.uploadRecStream(stream)
|
||||
else
|
||||
if not GAME.rep[upstreamProgress]then
|
||||
ins(GAME.rep,P1.frameRun)
|
||||
ins(GAME.rep,0)
|
||||
end
|
||||
stream,upstreamProgress=DATA.dumpRecording(GAME.rep,upstreamProgress)
|
||||
if #stream%3==1 then
|
||||
stream=stream.."\0\0"
|
||||
elseif #stream%3==2 then
|
||||
stream=stream.."\0\0\0\0"
|
||||
end
|
||||
NET.uploadRecStream(stream)
|
||||
lastUpstreamTime=PLAYERS[1].alive and P1.frameRun or 1e99
|
||||
end
|
||||
else
|
||||
@@ -260,6 +301,12 @@ function scene.draw()
|
||||
|
||||
--Warning
|
||||
drawWarning()
|
||||
|
||||
if NET.spectate then
|
||||
setFont(30)
|
||||
gc_setColor(.2,1,0,.8)
|
||||
gc_print(text.spectating,940,0)
|
||||
end
|
||||
else
|
||||
--Users
|
||||
netPLY.draw()
|
||||
@@ -267,24 +314,24 @@ function scene.draw()
|
||||
--Ready & Set mark
|
||||
setFont(50)
|
||||
if NET.allReady then
|
||||
gc.setColor(0,1,.5,.9)
|
||||
gc_setColor(0,1,.5,.9)
|
||||
mStr(text.ready,640,15)
|
||||
elseif NET.connectingStream then
|
||||
gc.setColor(.1,1,.8,.9)
|
||||
gc_setColor(.1,1,.8,.9)
|
||||
mStr(text.connStream,640,15)
|
||||
elseif NET.waitingStream then
|
||||
gc.setColor(0,.8,1,.9)
|
||||
gc_setColor(0,.8,1,.9)
|
||||
mStr(text.waitStream,640,15)
|
||||
end
|
||||
|
||||
--Room info.
|
||||
gc.setColor(1,1,1)
|
||||
gc_setColor(1,1,1)
|
||||
setFont(25)
|
||||
gc.printf(NET.roomInfo.name,0,685,1270,'right')
|
||||
gc.printf(NET.roomState.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
|
||||
if NET.roomInfo.start then gc.setColor(0,1,0)gc.print(text.started,230,655)end
|
||||
gc.print(netPLY.getCount().."/"..NET.roomState.capacity,70,655)
|
||||
if NET.roomState.private then gc.draw(IMG.lock,30,668)end
|
||||
if NET.roomState.start then gc_setColor(0,1,0)gc_print(text.started,230,655)end
|
||||
|
||||
--Profile
|
||||
drawSelfProfile()
|
||||
@@ -296,32 +343,40 @@ function scene.draw()
|
||||
--New message
|
||||
if textBox.new then
|
||||
setFont(40)
|
||||
gc.setColor(1,1,0)
|
||||
gc_setColor(1,1,0)
|
||||
gc.print("M",430,10)
|
||||
end
|
||||
end
|
||||
scene.widgetList={
|
||||
textBox,
|
||||
inputBox,
|
||||
WIDGET.newKey{name="setting",fText=TEXTURE.setting,x=1200,y=160,w=90,h=90,code=pressKey"s",hideF=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",
|
||||
WIDGET.newKey{name="setting",fText=TEXTURE.setting,x=1200,y=160,w=90,h=90,code=_gotoSetting,hideF=function()return playing or netPLY.getSelfReady()or NET.getlock('ready')end},
|
||||
WIDGET.newKey{name="ready",x=950,y=630,w=190,h=80,color='lG',font=35,code=_setReady,
|
||||
hideF=function()
|
||||
return
|
||||
playing or
|
||||
NET.serverGaming or
|
||||
netPLY.getSelfReady()or
|
||||
NET.roomState.start or
|
||||
netPLY.getSelfReady() or
|
||||
NET.getlock('ready')
|
||||
end},
|
||||
WIDGET.newKey{name="cancel",x=1060,y=630,w=300,h=80,color='H',font=40,code=pressKey"space",
|
||||
WIDGET.newKey{name="spectate",x=1150,y=630,w=190,h=80,color='lO',font=35,code=_setSpectate,
|
||||
hideF=function()
|
||||
return
|
||||
playing or
|
||||
NET.serverGaming or
|
||||
not netPLY.getSelfReady()or
|
||||
NET.roomState.start or
|
||||
netPLY.getSelfReady() or
|
||||
NET.getlock('ready')
|
||||
end},
|
||||
WIDGET.newKey{name="hideChat",fText="...",x=380,y=35,w=60,font=35,code=pressKey"return"},
|
||||
WIDGET.newKey{name="quit",fText="X",x=900,y=35,w=60,font=40,code=pressKey"escape"},
|
||||
WIDGET.newKey{name="cancel",x=1050,y=630,w=390,h=80,color='lH',font=40,code=_setCancel,
|
||||
hideF=function()
|
||||
return
|
||||
playing or
|
||||
NET.roomState.start or
|
||||
not netPLY.getSelfReady() or
|
||||
NET.getlock('ready')
|
||||
end},
|
||||
WIDGET.newKey{name="hideChat",fText="...",x=380,y=35,w=60,font=35,code=_switchChat},
|
||||
WIDGET.newKey{name="quit",fText="X",x=900,y=35,w=60,font=40,code=_quit},
|
||||
}
|
||||
|
||||
return scene
|
||||
@@ -8,8 +8,20 @@ local scrollPos,selected
|
||||
local fetchTimer
|
||||
local lastCreateRoomTime=0
|
||||
|
||||
--[[room={
|
||||
rid="qwe",
|
||||
roomInfo={
|
||||
name="MrZ's room",
|
||||
type="classic",
|
||||
version=1409,
|
||||
},
|
||||
private=false,
|
||||
start=false,
|
||||
count=4,
|
||||
capacity=5,
|
||||
}]]
|
||||
local function fetchRoom()
|
||||
fetchTimer=5
|
||||
fetchTimer=10
|
||||
NET.fetchRoom()
|
||||
end
|
||||
|
||||
@@ -17,9 +29,6 @@ local scene={}
|
||||
|
||||
function scene.sceneInit()
|
||||
BG.set()
|
||||
NET.allReady=false
|
||||
NET.connectingStream=false
|
||||
NET.waitingStream=false
|
||||
scrollPos=0
|
||||
selected=1
|
||||
fetchRoom()
|
||||
@@ -30,7 +39,7 @@ function scene.wheelMoved(_,y)
|
||||
end
|
||||
function scene.keyDown(k)
|
||||
if k=="r"then
|
||||
if fetchTimer<=3.26 then
|
||||
if fetchTimer<=7 then
|
||||
fetchRoom()
|
||||
end
|
||||
elseif k=="s"then
|
||||
@@ -74,27 +83,26 @@ function scene.keyDown(k)
|
||||
end
|
||||
elseif k=="return"then
|
||||
if NET.getlock('fetchRoom')or not NET.roomList[selected]then return end
|
||||
if NET.roomList[selected].private then
|
||||
LOG.print("Can't enter private room now",'message')
|
||||
return
|
||||
end
|
||||
NET.enterRoom(NET.roomList[selected])--,password
|
||||
local R=NET.roomList[selected]
|
||||
if R.roomInfo.version~=VERSION.short then LOG.print("Version doesn't match",'message')return end
|
||||
if R.private then LOG.print("Can't enter private room now",'message')return end
|
||||
NET.enterRoom(R)--,password
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function scene.mouseMove(x,y,_,dy)
|
||||
if ms.isDown(1)and x>50 and x<1110 and y>110 and y<510 then
|
||||
if ms.isDown(1)and x>50 and x<850 and y>110 and y<510 then
|
||||
scene.wheelMoved(0,dy/40)
|
||||
end
|
||||
end
|
||||
function scene.touchMove(x,y,_,dy)
|
||||
if x>50 and x<1110 and y>110 and y<510 then
|
||||
if x>50 and x<850 and y>110 and y<510 then
|
||||
scene.wheelMoved(0,dy/40)
|
||||
end
|
||||
end
|
||||
function scene.mouseClick(x,y)
|
||||
if x>50 and x<1110 then
|
||||
if x>50 and x<850 then
|
||||
y=int((y-70)/40)
|
||||
if y>=1 and y<=10 then
|
||||
local s=int(y+scrollPos)
|
||||
@@ -129,46 +137,64 @@ end
|
||||
function scene.draw()
|
||||
--Fetching timer
|
||||
gc.setColor(1,1,1,.12)
|
||||
gc.arc('fill','pie',300,620,60,-1.5708,-1.5708-1.2566*fetchTimer)
|
||||
gc.arc('fill','pie',300,620,60,-1.5708,-1.5708-.6283*fetchTimer)
|
||||
|
||||
--Room list
|
||||
gc.setColor(1,1,1)
|
||||
gc.setLineWidth(2)
|
||||
gc.rectangle('line',50,110,1060,400)
|
||||
gc.rectangle('line',50,110,800,400)
|
||||
local roomCount=#NET.roomList
|
||||
if roomCount>0 then
|
||||
setFont(35)
|
||||
if roomCount>10 then
|
||||
local len=400*10/roomCount
|
||||
gc.rectangle('fill',837,110+(400-len)*scrollPos/(roomCount-10),12,len)
|
||||
end
|
||||
gc.push('transform')
|
||||
gc.stencil(roomListStencil,'replace',1)
|
||||
gc.setStencilTest('equal',1)
|
||||
gc.translate(0,scrollPos%1*-40)
|
||||
setFont(35)
|
||||
local pos=int(scrollPos)
|
||||
for i=1,math.min(11,roomCount-pos)do
|
||||
local R=NET.roomList[pos+i]
|
||||
if pos+i==selected then
|
||||
gc.setColor(1,1,1,.3)
|
||||
gc.rectangle('fill',50,70+40*i,1060,40)
|
||||
end
|
||||
if R.start then
|
||||
gc.setColor(0,1,0)
|
||||
gc.print(text.started,660,66+40*i)
|
||||
gc.rectangle('fill',50,70+40*i,800,40)
|
||||
end
|
||||
gc.setColor(1,1,1)
|
||||
if R.private then gc.draw(IMG.lock,60,75+40*i)end
|
||||
gc.print(R.count.."/"..R.capacity,720,66+40*i)
|
||||
|
||||
gc.setColor(.9,.9,1)
|
||||
gc.print(pos+i,95,66+40*i)
|
||||
gc.setColor(1,1,.7)
|
||||
gc.print(R.name,250,66+40*i)
|
||||
gc.setColor(1,1,1)
|
||||
gc.printf(R.type,430,66+40*i,500,'right')
|
||||
gc.print(R.count.."/"..R.capacity,980,66+40*i)
|
||||
if R.private then
|
||||
gc.draw(IMG.lock,59,75+40*i)
|
||||
|
||||
if R.start then
|
||||
gc.setColor(0,.4,.1)
|
||||
else
|
||||
gc.setColor(1,1,.7)
|
||||
end
|
||||
gc.print(R.roomInfo.name,250,66+40*i)
|
||||
end
|
||||
gc.setStencilTest()
|
||||
gc.pop()
|
||||
if roomCount>10 then
|
||||
local len=400*10/roomCount
|
||||
gc.rectangle('fill',1218,110+(400-len)*scrollPos/(roomCount-10),12,len)
|
||||
|
||||
gc.setColor(1,1,1)
|
||||
gc.rectangle('line',860,240,385,270)
|
||||
if NET.roomList[selected]then
|
||||
local R=NET.roomList[selected]
|
||||
setFont(25)
|
||||
gc.print(R.roomInfo.type,870,265)
|
||||
gc.setColor(1,1,.7)
|
||||
gc.printf(R.roomInfo.name,870,240,365)
|
||||
setFont(20)
|
||||
if R.start then
|
||||
gc.setColor(0,1,.2)
|
||||
gc.print(text.started,870,475)
|
||||
end
|
||||
if R.roomInfo.version~=VERSION.short then
|
||||
gc.setColor(1,.2,0)
|
||||
gc.printf(R.roomInfo.version,870,475,365,'right')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -181,9 +207,9 @@ end
|
||||
|
||||
scene.widgetList={
|
||||
WIDGET.newKey{name="setting",fText=TEXTURE.setting,x=1200,y=160,w=90,h=90,code=pressKey"s"},
|
||||
WIDGET.newText{name="refreshing",x=580,y=255,font=45,hideF=function()return not NET.getlock('fetchRoom')end},
|
||||
WIDGET.newText{name="noRoom", x=580,y=260,font=40,hideF=function()return #NET.roomList>0 or NET.getlock('fetchRoom')end},
|
||||
WIDGET.newKey{name="refresh", x=300,y=620,w=140,h=140,font=35,code=fetchRoom,hideF=function()return fetchTimer>3.26 end},
|
||||
WIDGET.newText{name="refreshing",x=450,y=255,font=45,hideF=function()return not NET.getlock('fetchRoom')end},
|
||||
WIDGET.newText{name="noRoom", x=450,y=260,font=40,hideF=function()return #NET.roomList>0 or NET.getlock('fetchRoom')end},
|
||||
WIDGET.newKey{name="refresh", x=300,y=620,w=140,h=140,font=35,code=fetchRoom,hideF=function()return fetchTimer>7 end},
|
||||
WIDGET.newKey{name="new", x=500,y=620,w=140,h=140,font=20,code=pressKey"n"},
|
||||
WIDGET.newKey{name="new2", x=700,y=620,w=140,h=140,font=20,code=pressKey"m"},
|
||||
WIDGET.newKey{name="join", x=900,y=620,w=140,h=140,font=40,code=pressKey"return",hideF=function()return #NET.roomList==0 or NET.getlock('enterRoom')end},
|
||||
|
||||
@@ -34,7 +34,7 @@ function scene.sceneInit(org)
|
||||
local P=PLAYERS[1]
|
||||
local S=P.stat
|
||||
|
||||
timer=org=="game"and 0 or 50
|
||||
timer=org=='game'and 0 or 50
|
||||
|
||||
local frameLostRate=(S.frame/S.time/60-1)*100
|
||||
form={
|
||||
|
||||
@@ -17,10 +17,6 @@ local function register()
|
||||
NET.register(username,email,password)
|
||||
end
|
||||
|
||||
function scene.sceneInit()
|
||||
enableTextInput()
|
||||
end
|
||||
|
||||
scene.widgetList={
|
||||
WIDGET.newText{name="title", x=80, y=50,font=70,align='L'},
|
||||
WIDGET.newButton{name="login", x=1140, y=100,w=170,h=80,color='lY',code=function()SCN.swapTo('login','swipeL')end},
|
||||
|
||||
@@ -76,7 +76,7 @@ function scene.touchUp()
|
||||
end
|
||||
end
|
||||
function scene.touchMove(_,_,dx,dy)
|
||||
if selected and not WIDGET.sel then
|
||||
if selected and WIDGET.isFocus(false)then
|
||||
local B=VK_org[selected]
|
||||
B.x,B.y=B.x+dx,B.y+dy
|
||||
end
|
||||
@@ -84,8 +84,8 @@ end
|
||||
|
||||
function scene.draw()
|
||||
gc.setColor(1,1,1)
|
||||
gc.setLineWidth(7)gc.rectangle('line',340,15,600,690)
|
||||
gc.setLineWidth(3)gc.rectangle('line',490,85,300,600)
|
||||
gc.setLineWidth(3)
|
||||
gc.rectangle('line',490,85,300,600)
|
||||
VK.preview(selected)
|
||||
if snapUnit>=10 then
|
||||
gc.setLineWidth(3)
|
||||
@@ -193,11 +193,8 @@ scene.widgetList={
|
||||
selected=false
|
||||
end},
|
||||
WIDGET.newSelector{name="snap", x=750,y=90,w=200,h=80,color='Y',list={1,10,20,40,60,80},disp=function()return snapUnit end,code=function(i)snapUnit=i end},
|
||||
WIDGET.newButton{name="option", x=530,y=190,w=200,h=80,font=40,
|
||||
code=function()
|
||||
SCN.go('setting_touchSwitch')
|
||||
end},
|
||||
WIDGET.newButton{name="back", x=750,y=190,w=200,h=70,font=35,code=backScene},
|
||||
WIDGET.newButton{name="option", x=530,y=190,w=200,h=80,font=40,code=function()SCN.go('setting_touchSwitch')end},
|
||||
WIDGET.newButton{name="back", x=750,y=190,w=200,h=80,font=35,code=backScene},
|
||||
WIDGET.newKey{name="save1", x=475,y=290,w=90,h=70,code=save1},
|
||||
WIDGET.newKey{name="load1", x=585,y=290,w=90,h=70,code=load1},
|
||||
WIDGET.newKey{name="save2", x=695,y=290,w=90,h=70,code=save2},
|
||||
@@ -214,6 +211,7 @@ scene.widgetList={
|
||||
hideF=function()
|
||||
return not selected
|
||||
end},
|
||||
WIDGET.newKey{name="shape",x=640,y=600,w=200,h=80,code=function()SETTING.VKSkin=VK.nextShape()end},
|
||||
}
|
||||
|
||||
return scene
|
||||
@@ -13,41 +13,42 @@ scene.widgetList={
|
||||
WIDGET.newButton{name="sound", x=200,y=80,w=240,h=80,color='lC',font=35,code=swapScene("setting_sound",'swipeR')},
|
||||
WIDGET.newButton{name="game", x=1080,y=80,w=240,h=80,color='lC',font=35,code=swapScene("setting_game",'swipeL')},
|
||||
|
||||
WIDGET.newSwitch{name="block", x=350,y=160,disp=SETval("block"),code=SETrev("block")},
|
||||
WIDGET.newSwitch{name="smooth", x=350,y=210,disp=SETval("smooth"),code=SETrev("smooth")},
|
||||
WIDGET.newSwitch{name="upEdge", x=350,y=260,disp=SETval("upEdge"),code=SETrev("upEdge")},
|
||||
WIDGET.newSwitch{name="bagLine", x=350,y=310,disp=SETval("bagLine"),code=SETrev("bagLine")},
|
||||
WIDGET.newSwitch{name="block", x=270,y=160,disp=SETval("block"),code=SETrev("block")},
|
||||
WIDGET.newSwitch{name="smooth", x=270,y=210,disp=SETval("smooth"),code=SETrev("smooth")},
|
||||
WIDGET.newSwitch{name="upEdge", x=270,y=260,disp=SETval("upEdge"),code=SETrev("upEdge")},
|
||||
WIDGET.newSwitch{name="bagLine", x=270,y=310,disp=SETval("bagLine"),code=SETrev("bagLine")},
|
||||
|
||||
WIDGET.newSlider{name="ghost", x=700,y=180,w=380,unit=.6, disp=SETval("ghost"),show="percent",code=SETsto("ghost")},
|
||||
WIDGET.newSlider{name="grid", x=700,y=240,w=380,unit=.4, disp=SETval("grid"),show="percent", code=SETsto("grid")},
|
||||
WIDGET.newSlider{name="center", x=700,y=300,w=380,unit=1, disp=SETval("center"), code=SETsto("center")},
|
||||
WIDGET.newSlider{name="ghost", x=610,y=180,w=320,unit=.6, disp=SETval("ghost"),show="percent",code=SETsto("ghost")},
|
||||
WIDGET.newSlider{name="grid", x=610,y=240,w=320,unit=.4, disp=SETval("grid"),show="percent", code=SETsto("grid")},
|
||||
WIDGET.newSlider{name="center", x=610,y=300,w=320,unit=1, disp=SETval("center"), code=SETsto("center")},
|
||||
|
||||
WIDGET.newSlider{name="lockFX", x=220,y=365,w=380,unit=5, disp=SETval("lockFX"), code=SETsto("lockFX")},
|
||||
WIDGET.newSlider{name="dropFX", x=220,y=405,w=380,unit=5, disp=SETval("dropFX"), code=SETsto("dropFX")},
|
||||
WIDGET.newSlider{name="moveFX", x=220,y=445,w=380,unit=5, disp=SETval("moveFX"), code=SETsto("moveFX")},
|
||||
WIDGET.newSlider{name="clearFX", x=220,y=485,w=380,unit=5, disp=SETval("clearFX"), code=SETsto("clearFX")},
|
||||
WIDGET.newSlider{name="splashFX", x=220,y=525,w=380,unit=5, disp=SETval("splashFX"),code=SETsto("splashFX")},
|
||||
WIDGET.newSlider{name="shakeFX", x=220,y=565,w=380,unit=5, disp=SETval("shakeFX"), code=SETsto("shakeFX")},
|
||||
WIDGET.newSlider{name="atkFX", x=220,y=605,w=380,unit=5, disp=SETval("atkFX"), code=SETsto("atkFX")},
|
||||
WIDGET.newSelector{name="frame", x=410,y=660,w=360,list={8,10,13,17,22,29,37,47,62,80,100},disp=SETval("frameMul"),code=SETsto("frameMul")},
|
||||
WIDGET.newSlider{name="dropFX", x=220,y=415,w=380,unit=5, disp=SETval("dropFX"), code=SETsto("dropFX")},
|
||||
WIDGET.newSlider{name="moveFX", x=220,y=465,w=380,unit=5, disp=SETval("moveFX"), code=SETsto("moveFX")},
|
||||
WIDGET.newSlider{name="clearFX", x=220,y=515,w=380,unit=5, disp=SETval("clearFX"), code=SETsto("clearFX")},
|
||||
WIDGET.newSlider{name="splashFX", x=220,y=565,w=380,unit=5, disp=SETval("splashFX"),code=SETsto("splashFX")},
|
||||
WIDGET.newSlider{name="shakeFX", x=220,y=615,w=380,unit=5, disp=SETval("shakeFX"), code=SETsto("shakeFX")},
|
||||
WIDGET.newSlider{name="atkFX", x=220,y=665,w=380,unit=5, disp=SETval("atkFX"), code=SETsto("atkFX")},
|
||||
WIDGET.newSelector{name="frame", x=830,y=640,w=360,list={8,10,13,17,22,29,37,47,62,80,100},disp=SETval("frameMul"),code=SETsto("frameMul")},
|
||||
|
||||
WIDGET.newSwitch{name="text", x=900,y=360,disp=SETval("text"), code=SETrev("text")},
|
||||
WIDGET.newSwitch{name="score", x=900,y=410,disp=SETval("score"), code=SETrev("score")},
|
||||
WIDGET.newSwitch{name="warn", x=900,y=460,disp=SETval('warn'), code=SETrev('warn')},
|
||||
WIDGET.newSwitch{name="bufferWarn", x=900,y=510,disp=SETval('bufferWarn'), code=SETrev('bufferWarn')},
|
||||
WIDGET.newSwitch{name="bufferWarn", x=900,y=460,disp=SETval('bufferWarn'), code=SETrev('bufferWarn')},
|
||||
WIDGET.newSwitch{name="showSpike", x=900,y=510,disp=SETval('showSpike'), code=SETrev('showSpike')},
|
||||
WIDGET.newSwitch{name="highCam", x=900,y=560,disp=SETval("highCam"), code=SETrev("highCam")},
|
||||
|
||||
WIDGET.newSwitch{name="nextPos", x=1180,y=360,disp=SETval("nextPos"), code=SETrev("nextPos")},
|
||||
WIDGET.newSwitch{name="fullscreen", x=1180,y=410,disp=SETval("fullscreen"), code=switchFullscreen},
|
||||
WIDGET.newSwitch{name="power", x=1180,y=460,disp=SETval("powerInfo"), code=SETrev("powerInfo")},
|
||||
WIDGET.newSwitch{name="clickFX", x=1180,y=510,disp=SETval("clickFX"), code=SETrev("clickFX")},
|
||||
WIDGET.newSwitch{name="bg", x=1180,y=560,disp=SETval("bg"),
|
||||
WIDGET.newSwitch{name="nextPos", x=1180,y=260,disp=SETval("nextPos"), code=SETrev("nextPos")},
|
||||
WIDGET.newSwitch{name="fullscreen", x=1180,y=310,disp=SETval("fullscreen"), code=switchFullscreen},
|
||||
WIDGET.newSwitch{name="power", x=1180,y=360,disp=SETval("powerInfo"), code=SETrev("powerInfo")},
|
||||
WIDGET.newSwitch{name="clickFX", x=1180,y=410,disp=SETval("clickFX"), code=SETrev("clickFX")},
|
||||
WIDGET.newSwitch{name="bg", x=1180,y=460,disp=SETval("bg"),
|
||||
code=function()
|
||||
BG.set('none')
|
||||
SETTING.bg=not SETTING.bg
|
||||
BG.set()
|
||||
end},
|
||||
WIDGET.newSwitch{name="clean", x=990,y=640,font=35,disp=SETval("cleanCanvas"),code=SETrev("cleanCanvas")},
|
||||
WIDGET.newSwitch{name="clean", x=1180,y=510,disp=SETval("cleanCanvas"),code=SETrev("cleanCanvas")},
|
||||
WIDGET.newSwitch{name="warn", x=1180,y=560,disp=SETval("warn"), code=SETrev("warn")},
|
||||
WIDGET.newButton{name="back", x=1140,y=640,w=170,h=80,font=40,code=backScene},
|
||||
}
|
||||
|
||||
|
||||
@@ -12,17 +12,39 @@ return STRING.split([=[
|
||||
Tetra-link; 速算(前缀后缀表达式,二八十六进制)
|
||||
连连看; 求合体; 坦克大战; 扫雷; 接水管
|
||||
其他未来内容:
|
||||
详细开房界面; 自适应UI; 高级自定义序列; 对战结束后展示数据和排行
|
||||
重做模式选择UI; MOD的UI; 可滚动控件模块(自定义/设置UI)
|
||||
XRS; 移动n格+硬降复合操作键; 更好的手柄支持
|
||||
自适应UI; 高级自定义序列; 对战结束后展示数据和排行
|
||||
重做模式选择UI, MOD的UI, 自定义游戏UI
|
||||
区分各种消除(隔断/架空/混合/彩色/穿墙)
|
||||
更复杂的垃圾行(数量/等待时间/抵消倍率/洞数/连接/炸弹/厚度)
|
||||
可调场地宽度; 左右三按键; 手势操作; 特殊控件(虚拟摇杆等); 切换高低镜头键
|
||||
DAS系统和Deepdrop系统更细节的选项; spike计数器
|
||||
成就系统; 更强的主题系统; 多方块; 3D背景
|
||||
工程编译到字节码; task-Z(新AI); 开房机制修改
|
||||
等级系统; 旁观; 收集向抽奖玩法
|
||||
录像回放菜单; 跳帧开关; 教学关; 超60帧; 热更新
|
||||
更复杂的垃圾行(数量/等待时间/抵消倍率/洞数/连接/炸弹/厚度)
|
||||
DAS系统和Deepdrop系统更细节的选项
|
||||
成就系统; 更强的主题系统; 3D背景
|
||||
工程编译到字节码; task-Z(新AI)
|
||||
等级系统; 收集向抽奖玩法; 教学关
|
||||
录像回放菜单; 跳帧开关; 多方块; 超60帧; 热更新
|
||||
|
||||
0.15.0: 超新星 Supernova
|
||||
新增:
|
||||
[双端]观战功能
|
||||
spike计数器
|
||||
全新房间列表ui
|
||||
重新启用临界时间(基于帧)
|
||||
新增虚拟按键形状设置
|
||||
改动:
|
||||
主菜单按钮行为更容易理解,添加连接音效和连接成功音效
|
||||
移除next和hold栏上的文本
|
||||
聊天窗交互更自然
|
||||
词典添加游戏官网词条
|
||||
修改默认空用户名
|
||||
更新cc模块
|
||||
代码:
|
||||
升级控件模块
|
||||
升级本地和服务器提供的房间数据格式
|
||||
修复:
|
||||
结算显示胜利者时可能报错
|
||||
"游戏中"标记会被带到别的房间
|
||||
命令行执行空白字符串报错
|
||||
|
||||
0.14.8: 冰激凌 Icecream
|
||||
新增:
|
||||
|
||||
@@ -13,7 +13,7 @@ local function loadAvatar(path)
|
||||
end
|
||||
|
||||
local emptyUser={
|
||||
username="Player",
|
||||
username="_Stacker",
|
||||
motto="",
|
||||
hash="",
|
||||
new=false,
|
||||
|
||||
@@ -1,8 +1,34 @@
|
||||
local gc=love.graphics
|
||||
local gc_draw,gc_setColor,gc_setLineWidth=gc.draw,gc.setColor,gc.setLineWidth
|
||||
|
||||
local next=next
|
||||
|
||||
local SETTING,TIME=SETTING,TIME
|
||||
local VK_org=VK_org
|
||||
|
||||
local skin=1
|
||||
local r=10
|
||||
local buttonImages={
|
||||
DOGC{200,200,{'setLW',4},{'dCirc',100,100,98},{'dCirc',100,100,90}},
|
||||
DOGC{200,200,{'setLW',4},{'dCirc',100,100,98,8},{'dCirc',100,100,90,8}},
|
||||
DOGC{200,200,{'setLW',4},{'dCirc',100,100,98,6},{'dCirc',100,100,90,6}},
|
||||
DOGC{200,200,{'setLW',4},{'dCirc',100,100,98,4},{'dCirc',100,100,89,4}},
|
||||
DOGC{200,200,{'setLW',4},{'dRect',31,31,138,138},{'dRect',39,39,122,122}},
|
||||
}
|
||||
local rippleImages={
|
||||
DOGC{200,200,{'setLW',4},{'dCirc',100,100,98}},
|
||||
DOGC{200,200,{'setLW',4},{'dCirc',100,100,98,8}},
|
||||
DOGC{200,200,{'setLW',4},{'dCirc',100,100,98,6}},
|
||||
DOGC{200,200,{'setLW',4},{'dCirc',100,100,98,4}},
|
||||
DOGC{200,200,{'setLW',4},{'dRect',31,31,138,138}},
|
||||
}
|
||||
local holdImages={
|
||||
DOGC{200,200,{'fCirc',100,100,86}},
|
||||
DOGC{200,200,{'fCirc',100,100,86,8}},
|
||||
DOGC{200,200,{'fCirc',100,100,85,6}},
|
||||
DOGC{200,200,{'fCirc',100,100,83,4}},
|
||||
DOGC{200,200,{'fRect',43,43,114,114}},
|
||||
}
|
||||
--Virtualkey icons
|
||||
local VKIcon={}
|
||||
gc.setDefaultFilter('nearest','nearest')
|
||||
@@ -69,6 +95,14 @@ function VK.release(id)
|
||||
keys[id].isDown=false
|
||||
end
|
||||
|
||||
function VK.setShape(s)
|
||||
skin=s
|
||||
end
|
||||
function VK.nextShape()
|
||||
skin=skin%#buttonImages+1
|
||||
return skin
|
||||
end
|
||||
|
||||
function VK.switchKey(id,on)
|
||||
keys[id].ava=on
|
||||
end
|
||||
@@ -100,47 +134,53 @@ function VK.update()
|
||||
end
|
||||
end
|
||||
|
||||
local gc_circle,gc_draw,gc_setColor,gc_setLineWidth=gc.circle,gc.draw,gc.setColor,gc.setLineWidth
|
||||
function VK.draw()
|
||||
if not SETTING.VKSwitch then return end
|
||||
local a=SETTING.VKAlpha
|
||||
local buttonImage=buttonImages[skin]
|
||||
local rippleImage=rippleImages[skin]
|
||||
local holdImage=holdImages[skin]
|
||||
if SETTING.VKIcon then
|
||||
for i,B in next,keys do
|
||||
if B.ava then
|
||||
local r=B.r
|
||||
--Button outline
|
||||
gc_setColor(1,1,1,a)
|
||||
gc_setLineWidth(B.r*.07)
|
||||
gc_circle('line',B.x,B.y,B.r,10)
|
||||
gc_setLineWidth(r*.07)
|
||||
gc_draw(buttonImage,B.x,B.y,nil,r*.01,nil,100,100)
|
||||
|
||||
--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)
|
||||
gc_draw(VKIcon[i],B.x,B.y,nil,r*.024+_*.06,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)
|
||||
local d=r*(1.4-_*.04)
|
||||
gc_draw(rippleImage,B.x,B.y,nil,d*.01,nil,100,100)
|
||||
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)
|
||||
gc_draw(holdImage,B.x,B.y,nil,r*.01,nil,100,100)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
for _,B in next,keys do
|
||||
if B.ava then
|
||||
local r=B.r
|
||||
gc_setColor(1,1,1,a)
|
||||
gc_setLineWidth(B.r*.07)
|
||||
gc_circle('line',B.x,B.y,B.r,10)
|
||||
gc_setLineWidth(r*.07)
|
||||
gc_draw(buttonImage,B.x,B.y,nil,r*.01,nil,100,100)
|
||||
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)
|
||||
gc_draw(holdImage,B.x,B.y,nil,r*.01,nil,100,100)
|
||||
local d=r*(1.4-_*.04)
|
||||
gc_draw(rippleImage,B.x,B.y,nil,d*.01,nil,100,100)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -148,18 +188,21 @@ function VK.draw()
|
||||
end
|
||||
function VK.preview(selected)
|
||||
if not SETTING.VKSwitch then return end
|
||||
for id,B in next,VK_org do
|
||||
local buttonImage=buttonImages[skin]
|
||||
local holdImage=holdImages[skin]
|
||||
for i,B in next,VK_org do
|
||||
if B.ava then
|
||||
local r=B.r
|
||||
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_setLineWidth(r*.07)
|
||||
gc_draw(buttonImage,B.x,B.y,nil,r*.01,nil,100,100)
|
||||
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)
|
||||
gc_draw(holdImage,B.x,B.y,nil,r*.01,nil,100,100)
|
||||
end
|
||||
if SETTING.VKIcon then
|
||||
gc_setColor(1,1,1,SETTING.VKAlpha)
|
||||
gc_draw(VKIcon[id],B.x,B.y,nil,B.r*.025,nil,18,18)
|
||||
gc_draw(VKIcon[i],B.x,B.y,nil,r*.024,nil,18,18)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user