Merge branch 'main' into main

This commit is contained in:
MrZ_26
2021-04-23 18:18:57 +08:00
committed by GitHub
52 changed files with 992 additions and 899 deletions

View File

@@ -4,6 +4,7 @@ local cmds={
trans="translate",
scale="scale",
rotat="rotate",
clear="clear",
setCL="setColor",
setCM="setColorMask",

View File

@@ -14,7 +14,6 @@ ADRAW=require"Zframework.aDraw"
mDraw=ADRAW.draw
JSON=require"Zframework.json"
TABLE=require"Zframework.tableExtend"
STRING=require"Zframework.stringExtend"
@@ -103,7 +102,7 @@ function love.mousepressed(x,y,k,touch)
mouseShow=true
mx,my=xOy:inverseTransformPoint(x,y)
if devMode==1 then
DBP(("(%d,%d)<-%d,%d ~~(%d,%d)<-%d,%d"):format(
print(("(%d,%d)<-%d,%d ~~(%d,%d)<-%d,%d"):format(
mx,my,
mx-lastX,my-lastY,
int(mx/10)*10,int(my/10)*10,
@@ -208,8 +207,8 @@ 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 DBP(WIDGET.sel)end
elseif key=="f6"then for k,v in next,_G do DBP(k,v)end
elseif key=="f5"then if WIDGET.sel then print(WIDGET.sel)end
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",COLOR.Y)
elseif key=="f9"then devMode=1 LOG.print("DEBUG 1",COLOR.Y)
@@ -372,7 +371,7 @@ function love.errorhandler(msg)
c=3
end
end
DBP(table.concat(err,"\n",1,c-2))
print(table.concat(err,"\n",1,c-2))
--Reset something
love.audio.stop()

View File

@@ -9,29 +9,34 @@ return function(name,libName)
elseif SYSTEM=="Android"then
local fs=love.filesystem
local platform={"arm64-v8a","armeabi-v7a"}
local libFunc
for i=1,#platform do
local soFile,size=fs.read("data","libAndroid/"..platform[i].."/"..libName.Android)
if soFile then
local success,message=fs.write(libName.Android,soFile,size)
if success then
libFunc,message=package.loadlib(table.concat({SAVEDIR,libName.Android},"/"),libName.libFunc)
if libFunc then
LOG.print(name.." lib loaded","warn",COLOR.G)
break
local libFunc=package.loadlib(SAVEDIR.."/lib/"..libName.Android,libName.libFunc)
if libFunc then
LOG.print(name.." lib loaded","warn",COLOR.G)
else
for i=1,#platform do
local soFile=fs.read("data","libAndroid/"..platform[i].."/"..libName.Android)
if soFile then
local success,message=fs.write("lib/"..libName.Android,soFile)
if success then
libFunc,message=package.loadlib(SAVEDIR.."/lib/"..libName.Android,libName.libFunc)
if libFunc then
LOG.print(name.." lib loaded","warn",COLOR.G)
break
else
LOG.print("Cannot load "..name..": "..message,"warn",COLOR.R)
end
else
LOG.print("Cannot load "..name..": "..message,"warn",COLOR.R)
LOG.print("Write "..name.."-"..platform[i].." to saving failed: "..message,"warn",COLOR.R)
end
else
LOG.print("Write "..name.."-"..platform[i].." to saving failed: "..message,"warn",COLOR.R)
LOG.print("Read "..name.."-"..platform[i].." failed","warn",COLOR.R)
end
else
LOG.print("Read "..name.."-"..platform[i].." failed","warn",COLOR.R)
end
end
if not libFunc then
LOG.print("Cannot load "..name,"warn",COLOR.R)
return
if not libFunc then
LOG.print("Cannot load "..name,"warn",COLOR.R)
return
end
end
return libFunc()
else

View File

@@ -6,7 +6,7 @@ local host="game.techmino.org"
local port="10026"
local path="/tech/socket/v1"
local debug=false
local debug=""--S:send, R:receive, M=mark
local wsThread=[[
-- lua + love2d threading websocket client
@@ -87,6 +87,7 @@ local _send do
local mask_str=char(unpack(mask_key))
function _send(op,message)
]]..(debug:find"S"and""or"--")..[[print((">> %s[%d]:%s"):format(threadName,#message,message))
--Message type
SOCK:send(char(bor(0x80,op)))
@@ -153,7 +154,7 @@ while true do--Running
if s then
res=s
elseif p then--UNF head
]]..(debug==1 and""or"--")..[[print(("%s[%d/%d]:%s"):format(threadName,#p,length,p))
]]..(debug:find"R"and""or"--")..[[print(("<< %s[%d/%d]:%s"):format(threadName,#p,length,#p<50 and p or p:sub(1,50)))
UFF=true
sBuffer=sBuffer..p
length=length-#p
@@ -165,11 +166,11 @@ while true do--Running
else
local s,e,p=SOCK:receive(length)
if s then
]]..(debug==1 and""or"--")..[[print(("%s<%d>:%s"):format(threadName,length,s))
]]..(debug:find"R"and""or"--")..[[print(("<< %s(%d):%s"):format(threadName,length,#s<50 and s or s:sub(1,50)))
sBuffer=sBuffer..s
length=length-#s
elseif p then
]]..(debug==1 and""or"--")..[[print(("%s<%d>:%s"):format(threadName,length,p))
]]..(debug:find"R"and""or"--")..[[print(("<< %s(%d):%s"):format(threadName,length,#p<50 and p or p:sub(1,50)))
sBuffer=sBuffer..p
length=length-#p
end
@@ -180,7 +181,7 @@ while true do--Running
break
end
end
]]..(debug==1 and""or"--")..[[print(("%s<[%d]>:%s"):format(threadName,#res,res))
]]..(debug:find"R"and""or"--")..[[print(("<< %s[(%d)]:%s"):format(threadName,#res,#res<800 and res or res:sub(1,150).."\n...\n"..res:sub(-150)))
--React
if op==8 then--8=close
@@ -195,21 +196,21 @@ while true do--Running
elseif op==0 then--0=continue
lBuffer=lBuffer..res
if fin then
]]..(debug==2 and""or"--")..[[print("FIN=1 (c")
]]..(debug:find"M"and""or"--")..[[print("FIN=1 (c")
readCHN:push(lBuffer)
lBuffer=""
else
]]..(debug==2 and""or"--")..[[print("FIN=0 (c")
]]..(debug:find"M"and""or"--")..[[print("FIN=0 (c")
end
else
readCHN:push(op)
if fin then
]]..(debug==2 and""or"--")..[[print("OP: "..op.."\tFIN=1")
]]..(debug:find"M"and""or"--")..[[print("OP: "..op.."\tFIN=1")
readCHN:push(res)
else
]]..(debug==2 and""or"--")..[[print("OP: "..op.."\tFIN=0")
]]..(debug:find"M"and""or"--")..[[print("OP: "..op.."\tFIN=0")
sBuffer=res
]]..(debug==2 and""or"--")..[[print("START pack: "..res)
]]..(debug:find"M"and""or"--")..[[print("START pack: "..res)
end
end
end

View File

@@ -9,10 +9,12 @@ local COLOR=COLOR
local setFont,mStr=setFont,mStr
local mDraw_X,mDraw_Y=ADRAW.simpX,ADRAW.simpY
local allowNoText={
image=true,
inputBox=true,
textBox=true,
local mustHaveText={
text=true,
button=true,
key=true,
switch=true,
selector=true,
}
local WIDGET={}
@@ -40,13 +42,12 @@ function text:draw()
if self.alpha>0 then
local c=self.color
gc.setColor(c[1],c[2],c[3],self.alpha)
local obj=self.obj
if self.align=="M"then
mDraw_X(obj,self.x,self.y)
mDraw_X(self.obj,self.x,self.y)
elseif self.align=="L"then
gc.draw(obj,self.x,self.y)
gc.draw(self.obj,self.x,self.y)
elseif self.align=="R"then
gc.draw(obj,self.x-obj:getWidth(),self.y)
gc.draw(self.obj,self.x-self.obj:getWidth(),self.y)
end
end
end
@@ -270,7 +271,7 @@ function key:draw()
elseif self.align=="L"then
mDraw_Y(self.obj,x+self.edge,y+h*.5)
elseif self.align=="R"then
mDraw_Y(self.obj,self.x-self.edge-self.obj:getWidth(),y+h*.5)
mDraw_Y(self.obj,x+w-self.edge-self.obj:getWidth(),y+h*.5)
end
end
function key:getInfo()
@@ -356,9 +357,8 @@ function switch:draw()
gc.rectangle("line",x,y,50,50)
--Drawable
local obj=self.obj
gc.setColor(self.color)
mDraw_Y(obj,x-12-ATV-obj:getWidth(),y+25)
mDraw_Y(self.obj,x-12-ATV-self.obj:getWidth(),y+25)
end
function switch:getInfo()
return format("x=%d,y=%d,font=%d",self.x,self.y,self.font)
@@ -478,9 +478,10 @@ function slider:draw()
end
--Drawable
local obj=self.obj
gc.setColor(self.color)
mDraw_Y(obj,x-12-ATV-obj:getWidth(),y)
if self.obj then
gc.setColor(self.color)
mDraw_Y(self.obj,x-12-ATV-self.obj:getWidth(),y)
end
end
function slider:getInfo()
return format("x=%d,y=%d,w=%d",self.x,self.y,self.w)
@@ -757,9 +758,8 @@ function inputBox:draw()
--Drawable
setFont(self.font)
local obj=self.obj
if obj then
mDraw_Y(obj,x-12-obj:getWidth(),y+h*.5)
if self.obj then
mDraw_Y(self.obj,x-12-self.obj:getWidth(),y+h*.5)
end
if self.secret then
for i=1,#self.value do
@@ -909,7 +909,7 @@ function textBox:draw()
--Frame
gc.setLineWidth(4)
gc.setColor(COLOR[WIDGET.sel==self and"Y"or"W"])
gc.setColor(COLOR[WIDGET.sel==self and"Y"or"Z"])
gc.rectangle("line",x,y,w,h)
--Slider
@@ -1016,7 +1016,7 @@ function WIDGET.setLang(widgetText)
if L.widgetList then
for _,W in next,L.widgetList do
local t=W.fText or widgetText[S][W.name]
if not t and not allowNoText[W.type]then
if not t and mustHaveText[W.type]then
t=W.name or"##"
W.color=COLOR.dV
end

View File

@@ -13,7 +13,7 @@
goto REM love=require"love"::REM::--Just tell IDE to load love-api, no actual usage
local fs=love.filesystem
NONE={}function NULL()end
DBP=print--Use this in permanent code
DBP=print--Use this in temporary code, easy to find and remove
TIME=love.timer.getTime
YIELD=coroutine.yield
SYSTEM=love.system.getOS()
@@ -34,14 +34,16 @@ love.keyboard.setTextInput(false)
love.mouse.setVisible(false)
--Delete all files from too old version
for _,name in next,fs.getDirectoryItems("")do
if fs.getRealDirectory(name)==SAVEDIR and fs.getInfo(name).type~="directory"then
fs.remove(name)
function CLEAR(root)
for _,name in next,fs.getDirectoryItems(root or"")do
if fs.getRealDirectory(name)==SAVEDIR and fs.getInfo(name).type~="directory"then
fs.remove(name)
end
end
end
end CLEAR()
--Create directories
for _,v in next,{"conf","record","replay","cache"}do
for _,v in next,{"conf","record","replay","cache","lib"}do
local info=fs.getInfo(v)
if not info then
fs.createDirectory(v)
@@ -53,24 +55,28 @@ end
--Load modules
require"Zframework"
SCR.setSize(1280,720)--Initialize Screen size
require"parts.list"
require"parts.globalTables"
require"parts.gametoolfunc"
SCR.setSize(1280,720)--Initialize Screen size
FIELD[1]=newBoard()--Initialize field[1]
NET= require"parts.net"
AIBUILDER= require"parts.AITemplate"
FREEROW= require"parts.freeRow"
USERS= require"parts.users"
DATA= require"parts.data"
USERS= require"parts.users"
TEXTURE= require"parts.texture"
SKIN= require"parts.skin"
NET= require"parts.net"
VK= require"parts.virtualKey"
PLY= require"parts.player"
AIFUNC= require"parts.ai"
AIBUILDER= require"parts.AITemplate"
MODES= require"parts.modes"
--Initialize field[1]
FIELD[1]=DATA.newBoard()
--First start for phones
if not fs.getInfo("conf/settings")and MOBILE then
SETTING.VKSwitch=true
@@ -234,11 +240,9 @@ do
local needSave
local autoRestart
if STAT.extraRate then
STAT.finesseRate=5*(STAT.piece-STAT.extraRate)
end
if type(STAT.version)~="number"then
STAT.version=0
needSave=true
end
if STAT.version<1300 then
STAT.frame=math.floor(STAT.time*60)
@@ -264,6 +268,10 @@ do
needSave=true
autoRestart=true
end
if STAT.version<1405 then
fs.remove("conf/user")
autoRestart=true
end
for _,v in next,VK_org do
if not v.color then
@@ -273,6 +281,14 @@ do
end
end
if STAT.version~=VERSION.code then
newVersionLaunch=true
STAT.version=VERSION.code
CLEAR("lib")
needSave=true
autoRestart=true
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
@@ -303,17 +319,15 @@ do
needSave=true
end
if STAT.version~=VERSION.code then
newVersionLaunch=true
STAT.version=VERSION.code
FILE.save(STAT,"conf/data","q")
end
if needSave then
FILE.save(RANKS,"conf/unlock","q")
FILE.save(SETTING,"conf/settings","q")
FILE.save(RANKS,"conf/unlock","q")
FILE.save(STAT,"conf/data","q")
end
if autoRestart then
love.event.quit("restart")
end
end
end
--Var leak check
-- setmetatable(_G,{__newindex=function(self,k,v)print('>>'..k,tostring(v))rawset(self,k,v)end})

394
parts/data.lua Normal file
View File

@@ -0,0 +1,394 @@
local data=love.data
local int=math.floor
local char,byte=string.char,string.byte
local ins=table.insert
local DATA={}
--Sep symbol: 33 (!)
--Safe char: 34~126
--[[
Count: 34~96
Block: 97~125
Encode: A[B] sequence, A = block ID, B = repeat times, no B means do not repeat.
Example: "abcdefg" is [SZJLTOI], "a^aDb)" is [Z*63,Z*37,S*10]
]]
function DATA.copySequence()
local BAG=BAG
local str=""
local count=1
for i=1,#BAG+1 do
if BAG[i+1]~=BAG[i]or count==64 then
str=str..char(96+BAG[i])
if count>1 then
str=str..char(32+count)
count=1
end
else
count=count+1
end
end
return str
end
function DATA.pasteSequence(str)
local b
local bag={}
local reg
for i=1,#str do
b=byte(str,i)
if not reg then
if b>=97 and b<=125 then
reg=b-96
else
return
end
else
if b>=97 and b<=125 then
ins(bag,reg)
reg=b-96
elseif b>=34 and b<=96 then
for _=1,b-32 do
ins(bag,reg)
end
reg=false
end
end
end
if reg then
ins(bag,reg)
end
BAG=bag
return true
end
function DATA.newBoard(f)--Generate a new board
if f then
return TABLE.shift(f)
else
local F={}
for i=1,20 do F[i]={0,0,0,0,0,0,0,0,0,0}end
return F
end
end
function DATA.copyBoard(page)--Copy the [page] board
local F=FIELD[page or 1]
local str=""
local H=0
for y=20,1,-1 do
for x=1,10 do
if F[y][x]~=0 then
H=y
goto BREAK_topFound
end
end
end
::BREAK_topFound::
--Encode field
for y=1,H do
local S=""
local L=F[y]
for x=1,10 do
S=S..char(L[x]+1)
end
str=str..S
end
return data.encode("string","base64",data.compress("string","zlib",str))
end
function DATA.copyBoards()
local out={}
for i=1,#FIELD do
out[i]=DATA.copyBoard(i)
end
return table.concat(out,"!")
end
function DATA.pasteBoard(str,page)--Paste [str] data to [page] board
if not page then page=1 end
if not FIELD[page]then FIELD[page]=DATA.newBoard()end
local F=FIELD[page]
local _,__
--Decode
_,str=pcall(data.decode,"string","base64",str)
if not _ then return end
_,str=pcall(data.decompress,"string","zlib",str)
if not _ then return end
local fX,fY=1,1--*ptr for Field(r*10+(c-1))
local p=1
while true do
_=byte(str,p)--1byte
--Str end
if not _ then
if fX~=1 then
return
else
break
end
end
__=_%32-1--Block id
if __>26 then return end--Illegal blockid
_=int(_/32)--Mode id
F[fY][fX]=__
if fX<10 then
fX=fX+1
else
fY=fY+1
if fY>20 then break end
fX=1
end
p=p+1
end
for y=fY,20 do
for x=1,10 do
F[y][x]=0
end
end
return true
end
--[[
Mission: 34~114
Count: 115~126
Encode: [A] or [AB] sequence, A = mission ID, B = repeat times, no B means do not repeat.
_1=01,_2=02,_3=03,_4=04,
A1=05,A2=06,A3=07,A4=08,
PC=09,
Z1=11,Z2=12,Z3=13,
S1=21,S2=22,S3=23,
J1=31,J2=32,J3=33,
L1=41,L2=42,L3=43,
T1=51,T2=52,T3=53,
O1=61,O2=62,O3=63,O4=64,
I1=71,I2=72,I3=73,I4=74,
]]
function DATA.copyMission()
local _
local MISSION=MISSION
local str=""
local count=1
for i=1,#MISSION+1 do
if MISSION[i+1]~=MISSION[i]or count==13 then
_=33+MISSION[i]
str=str..char(_)
if count>1 then
str=str..char(113+count)
count=1
end
else
count=count+1
end
end
return str
end
function DATA.pasteMission(str)
local b
local mission={}
local reg
for i=1,#str do
b=byte(str,i)
if not reg then
if b>=34 and b<=114 then
reg=b-33
else
return
end
else
if b>=34 and b<=114 then
if missionEnum[reg]then
ins(mission,reg)
reg=b-33
else
return
end
elseif b>=115 and b<=126 then
for _=1,b-113 do
ins(mission,reg)
end
reg=false
end
end
end
if reg then
ins(mission,reg)
end
MISSION=mission
return true
end
function DATA.copyQuestArgs()
local ENV=CUSTOMENV
local str=""..
ENV.holdCount..
(ENV.ospin and"O"or"Z")..
(ENV.missionKill and"M"or"Z")..
ENV.sequence
return str
end
do--function DATA.pasteQuestArgs(str)
local sub=string.sub
function pasteQuestArgs(str)
if #str<4 then return end
local ENV=CUSTOMENV
ENV.holdCount= byte(str,1)-48
ENV.ospin= byte(str,2)~=90
ENV.missionKill= byte(str,3)~=90
ENV.sequence= sub(str,4)
return true
end
end
--[[
Table data format:
{frame,event, frame,event, ...}
Byte data format: (1 byte each period)
dt, event, dt, event, ...
all data range from 0 to 127
large value will be encoded as 1xxxxxxx(high)-1xxxxxxx-...-0xxxxxxx(low)
Example (decoded):
6,1, 20,-1, 0,2, 26,-2, 872,4, ...
This means:
Press key1 at 6f
Release key1 at 26f (6+20)
Press key2 at the same time (26+0)
Release key 2 after 26 frame (26+26)
Press key 4 after 872 frame (52+872)
...
]]
function DATA.dumpRecording(list,ptr)
local out=""
local buffer,buffer2=""
if not ptr then ptr=1 end
local prevFrm=list[ptr-2]or 0
while list[ptr]do
--Flush buffer
if #buffer>10 then
out=out..buffer
buffer=""
end
--Encode time
local t=list[ptr]-prevFrm
prevFrm=list[ptr]
if t>=128 then
buffer2=char(t%128)
t=int(t/128)
while t>=128 do
buffer2=char(128+t%128)..buffer2
t=int(t/128)
end
buffer=buffer..char(128+t)..buffer2
else
buffer=buffer..char(t)
end
--Encode event
t=list[ptr+1]
if t>=128 then
buffer2=char(t%128)
t=int(t/128)
while t>=128 do
buffer2=char(128+t%128)..buffer2
t=int(t/128)
end
buffer=buffer..char(128+t)..buffer2
else
buffer=buffer..char(t)
end
--Step
ptr=ptr+2
end
return out..buffer,ptr
end
function DATA.pumpRecording(str,L)
local len=#str
local p=1
local curFrm=L[#L-1]or 0
local code
while p<=len do
--Read delta time
code=0
local b=byte(str,p)
while b>=128 do
code=code*128+b-128
p=p+1
b=byte(str,p)
end
curFrm=curFrm+code*128+b
L[#L+1]=curFrm
p=p+1
local event=0
b=byte(str,p)
while b>=128 do
event=event*128+b-128
p=p+1
b=byte(str,p)
end
L[#L+1]=event*128+b
p=p+1
end
end
do--function DATA.saveRecording()
local noRecList={"custom","solo","round","techmino"}
local function getModList()
local res={}
for _,v in next,GAME.mod do
if v.sel>0 then
ins(res,{v.no,v.sel})
end
end
return res
end
function DATA.saveRecording()
--Filtering modes that cannot be saved
for _,v in next,noRecList do
if GAME.curModeName:find(v)then
LOG.print("Cannot save recording of this mode now!",COLOR.N)
return
end
end
--Write file
local fileName="replay/"..os.date("%Y_%m_%d_%a_%H%M%S.rep")
if not love.filesystem.getInfo(fileName)then
local fileHead=
os.date("%Y/%m/%d %A %H:%M:%S\n")..
GAME.curModeName.."\n"..
VERSION.string.."\n"..
"Local Player"
local fileBody=
GAME.seed.."\n"..
JSON.encode(GAME.setting).."\n"..
JSON.encode(getModList()).."\n"..
DATA.dumpRecording(GAME.rep)
love.filesystem.write(fileName,fileHead.."\n"..data.compress("string","zlib",fileBody))
ins(REPLAY,fileName)
FILE.save(REPLAY,"conf/replay")
return true
else
LOG.print("Save failed: File already exists")
end
end
end
return DATA

View File

@@ -1,12 +1,7 @@
local data=love.data
local gc=love.graphics
local gc_setColor,gc_setLineWidth,gc_setShader=gc.setColor,gc.setLineWidth,gc.setShader
local gc_push,gc_pop,gc_origin,gc_translate=gc.push,gc.pop,gc.origin,gc.translate
local gc_draw,gc_rectangle,gc_circle=gc.draw,gc.rectangle,gc.circle
local int,rnd=math.floor,math.random
local char,byte=string.char,string.byte
local ins,rem=table.insert,table.remove
local gc_draw,gc_printf,gc_line,gc_rectangle=gc.draw,gc.printf,gc.line,gc.rectangle
@@ -19,258 +14,9 @@ end
--Encoding Functions
--Sep symbol: 33 (!)
--Safe char: 34~126
--[[
Count: 34~96
Block: 97~125
Encode: A[B] sequence, A = block ID, B = repeat times, no B means do not repeat.
Example: "abcdefg" is [SZJLTOI], "a^aDb)" is [Z*63,Z*37,S*10]
]]
function copySequence()
local BAG=BAG
local str=""
local count=1
for i=1,#BAG+1 do
if BAG[i+1]~=BAG[i]or count==64 then
str=str..char(96+BAG[i])
if count>1 then
str=str..char(32+count)
count=1
end
else
count=count+1
end
end
return str
end
function pasteSequence(str)
local b
local bag={}
local reg
for i=1,#str do
b=byte(str,i)
if not reg then
if b>=97 and b<=125 then
reg=b-96
else
return
end
else
if b>=97 and b<=125 then
ins(bag,reg)
reg=b-96
elseif b>=34 and b<=96 then
for _=1,b-32 do
ins(bag,reg)
end
reg=false
end
end
end
if reg then
ins(bag,reg)
end
BAG=bag
return true
end
function newBoard(f)--Generate a new board
if f then
return TABLE.shift(f)
else
local F={}
for i=1,20 do F[i]={0,0,0,0,0,0,0,0,0,0}end
return F
end
end
function copyBoard(page)--Copy the [page] board
local F=FIELD[page or 1]
local str=""
local H=0
for y=20,1,-1 do
for x=1,10 do
if F[y][x]~=0 then
H=y
goto BREAK_topFound
end
end
end
::BREAK_topFound::
--Encode field
for y=1,H do
local S=""
local L=F[y]
for x=1,10 do
S=S..char(L[x]+1)
end
str=str..S
end
return data.encode("string","base64",data.compress("string","zlib",str))
end
function copyBoards()
local out={}
for i=1,#FIELD do
out[i]=copyBoard(i)
end
return table.concat(out,"!")
end
function pasteBoard(str,page)--Paste [str] data to [page] board
if not page then page=1 end
if not FIELD[page]then FIELD[page]=newBoard()end
local F=FIELD[page]
local _,__
--Decode
_,str=pcall(data.decode,"string","base64",str)
if not _ then return end
_,str=pcall(data.decompress,"string","zlib",str)
if not _ then return end
local fX,fY=1,1--*ptr for Field(r*10+(c-1))
local p=1
while true do
_=byte(str,p)--1byte
--Str end
if not _ then
if fX~=1 then
return
else
break
end
end
__=_%32-1--Block id
if __>26 then return end--Illegal blockid
_=int(_/32)--Mode id
F[fY][fX]=__
if fX<10 then
fX=fX+1
else
fY=fY+1
if fY>20 then break end
fX=1
end
p=p+1
end
for y=fY,20 do
for x=1,10 do
F[y][x]=0
end
end
return true
end
--[[
Mission: 34~114
Count: 115~126
Encode: [A] or [AB] sequence, A = mission ID, B = repeat times, no B means do not repeat.
_1=01,_2=02,_3=03,_4=04,
A1=05,A2=06,A3=07,A4=08,
PC=09,
Z1=11,Z2=12,Z3=13,
S1=21,S2=22,S3=23,
J1=31,J2=32,J3=33,
L1=41,L2=42,L3=43,
T1=51,T2=52,T3=53,
O1=61,O2=62,O3=63,O4=64,
I1=71,I2=72,I3=73,I4=74,
]]
function copyMission()
local _
local MISSION=MISSION
local str=""
local count=1
for i=1,#MISSION+1 do
if MISSION[i+1]~=MISSION[i]or count==13 then
_=33+MISSION[i]
str=str..char(_)
if count>1 then
str=str..char(113+count)
count=1
end
else
count=count+1
end
end
return str
end
function pasteMission(str)
local b
local mission={}
local reg
for i=1,#str do
b=byte(str,i)
if not reg then
if b>=34 and b<=114 then
reg=b-33
else
return
end
else
if b>=34 and b<=114 then
if missionEnum[reg]then
ins(mission,reg)
reg=b-33
else
return
end
elseif b>=115 and b<=126 then
for _=1,b-113 do
ins(mission,reg)
end
reg=false
end
end
end
if reg then
ins(mission,reg)
end
MISSION=mission
return true
end
function copyQuestArgs()
local ENV=CUSTOMENV
local str=""..
ENV.holdCount..
(ENV.ospin and"O"or"Z")..
(ENV.missionKill and"M"or"Z")..
ENV.sequence
return str
end
do--function pasteQuestArgs(str)
local sub=string.sub
function pasteQuestArgs(str)
if #str<4 then return end
local ENV=CUSTOMENV
ENV.holdCount= byte(str,1)-48
ENV.ospin= byte(str,2)~=90
ENV.missionKill= byte(str,3)~=90
ENV.sequence= sub(str,4)
return true
end
end
--Royale mode
function randomTarget(P)--Return a random opponent for P
local rnd=math.random
if #PLY_ALIVE>1 then
local R
repeat
@@ -350,6 +96,7 @@ function royaleLevelup()
P.gameEnv.drop=spd
end
if GAME.curMode.name:find("_u")then
local int=math.floor
for i=1,#PLY_ALIVE do
local P=PLY_ALIVE[i]
P.gameEnv.drop=int(P.gameEnv.drop*.3)
@@ -363,108 +110,6 @@ end
--Virtualkey
local VK=virtualkey
function drawVirtualkeys()
if SETTING.VKSwitch then
local a=SETTING.VKAlpha
local _
if SETTING.VKIcon then
local icons=TEXTURE.VKIcon
for i=1,#VK do
if VK[i].ava then
local B=VK[i]
gc_setColor(1,1,1,a)
gc_setLineWidth(B.r*.07)
gc_circle("line",B.x,B.y,B.r,10)--Button outline
_=VK[i].pressTime
gc_setColor(B.color[1],B.color[2],B.color[3],a)
gc_draw(icons[i],B.x,B.y,nil,B.r*.026+_*.08,nil,18,18)--Icon
if _>0 then
gc_setColor(1,1,1,a*_*.08)
gc_circle("fill",B.x,B.y,B.r*.94,10)--Glow when press
gc_circle("line",B.x,B.y,B.r*(1.4-_*.04),10)--Ripple
end
end
end
else
for i=1,#VK do
if VK[i].ava then
local B=VK[i]
gc_setColor(1,1,1,a)
gc_setLineWidth(B.r*.07)
gc_circle("line",B.x,B.y,B.r,10)
_=VK[i].pressTime
if _>0 then
gc_setColor(1,1,1,a*_*.08)
gc_circle("fill",B.x,B.y,B.r*.94,10)
gc_circle("line",B.x,B.y,B.r*(1.4-_*.04),10)
end
end
end
end
end
end
function onVirtualkey(x,y)
local dist,nearest=1e10
for K=1,#VK do
local B=VK[K]
if B.ava then
local d1=(x-B.x)^2+(y-B.y)^2
if d1<B.r^2 then
if d1<dist then
nearest,dist=K,d1
end
end
end
end
return nearest
end
function pressVirtualkey(t,x,y)
local SETTING=SETTING
local B=VK[t]
B.isDown=true
B.pressTime=10
if x then
if SETTING.VKTrack then
--Auto follow
local O=VK_org[t]
local _FW,_CW=SETTING.VKTchW,1-SETTING.VKCurW
local _OW=1-_FW-_CW
--(finger+current+origin)
B.x=x*_FW+B.x*_CW+O.x*_OW
B.y=y*_FW+B.y*_CW+O.y*_OW
--Button collision (not accurate)
if SETTING.VKDodge then
for i=1,#VK do
local b=VK[i]
local d=B.r+b.r-((B.x-b.x)^2+(B.y-b.y)^2)^.5--Hit depth(Neg means distance)
if d>0 then
b.x=b.x+(b.x-B.x)*d*b.r*2.6e-5
b.y=b.y+(b.y-B.y)*d*b.r*2.6e-5
end
end
end
end
SFX.play("virtualKey",SETTING.VKSFX)
VIB(SETTING.VKVIB)
end
end
function updateVirtualkey()
if SETTING.VKSwitch then
for i=1,#VK do
local _=VK[i]
if _.pressTime>0 then
_.pressTime=_.pressTime-1
end
end
end
end
--Game
function generateLine(hole)
return 1023-2^(hole-1)
@@ -522,6 +167,7 @@ function scoreValid()--Check if any unranked mods are activated
return true
end
function destroyPlayers()--Destroy all player objects, restore freerows and free CCs
local rem=table.remove
for i=#PLAYERS,1,-1 do
local P=PLAYERS[i]
if P.canvas then P.canvas:release()end
@@ -540,23 +186,6 @@ function destroyPlayers()--Destroy all player objects, restore freerows and free
TABLE.clear(PLY_ALIVE)
collectgarbage()
end
function restoreVirtualkey()
for i=1,#VK_org do
local B,O=virtualkey[i],VK_org[i]
B.ava=O.ava
B.x=O.x
B.y=O.y
B.r=O.r
B.color=O.color
B.isDown=false
B.pressTime=0
end
for k,v in next,PLAYERS[1].keyAvailable do
if not v then
virtualkey[k].ava=false
end
end
end
function pauseGame()
if not SCN.swapping then
if not GAME.replaying then
@@ -735,7 +364,7 @@ do--function resetGameData(args)
GAME.replaying=1
else
GAME.frameStart=args:find("n")and 0 or 150-SETTING.reTime*15
GAME.seed=seed or rnd(1046101471,2662622626)
GAME.seed=seed or math.random(1046101471,2662622626)
GAME.pauseTime=0
GAME.pauseCount=0
GAME.saved=false
@@ -750,7 +379,7 @@ do--function resetGameData(args)
destroyPlayers()
GAME.curMode.load()
initPlayerPosition(args:find("q"))
restoreVirtualkey()
VK.restore()
if GAME.modeEnv.task then
for i=1,#PLAYERS do
PLAYERS[i]:newTask(GAME.modeEnv.task)
@@ -758,7 +387,7 @@ do--function resetGameData(args)
end
BG.set(GAME.modeEnv.bg)
local bgm=GAME.modeEnv.bgm
BGM.play(type(bgm)=="string"and bgm or type(bgm)=="table"and bgm[rnd(#bgm)])
BGM.play(type(bgm)=="string"and bgm or type(bgm)=="table"and bgm[math.random(#bgm)])
TEXT.clear()
if GAME.modeEnv.royaleMode then
@@ -816,146 +445,6 @@ do--function checkWarning()
end
end
--[[
Table data format:
{frame,event, frame,event, ...}
Byte data format: (1 byte each period)
dt, event, dt, event, ...
all data range from 0 to 127
large value will be encoded as 1xxxxxxx(high)-1xxxxxxx-...-0xxxxxxx(low)
Example (decoded):
6,1, 20,-1, 0,2, 26,-2, 872,4, ...
This means:
Press key1 at 6f
Release key1 at 26f (6+20)
Press key2 at the same time (26+0)
Release key 2 after 26 frame (26+26)
Press key 4 after 872 frame (52+872)
...
]]
function dumpRecording(list,ptr)
local out=""
local buffer,buffer2=""
if not ptr then ptr=1 end
local prevFrm=list[ptr-2]or 0
while list[ptr]do
--Flush buffer
if #buffer>10 then
out=out..buffer
buffer=""
end
--Encode time
local t=list[ptr]-prevFrm
prevFrm=list[ptr]
if t>=128 then
buffer2=char(t%128)
t=int(t/128)
while t>=128 do
buffer2=char(128+t%128)..buffer2
t=int(t/128)
end
buffer=buffer..char(128+t)..buffer2
else
buffer=buffer..char(t)
end
--Encode event
t=list[ptr+1]
if t>=128 then
buffer2=char(t%128)
t=int(t/128)
while t>=128 do
buffer2=char(128+t%128)..buffer2
t=int(t/128)
end
buffer=buffer..char(128+t)..buffer2
else
buffer=buffer..char(t)
end
--Step
ptr=ptr+2
end
return out..buffer,ptr
end
function pumpRecording(str,L)
local len=#str
local p=1
local curFrm=L[#L-1]or 0
local code
while p<=len do
--Read delta time
code=0
local b=byte(str,p)
while b>=128 do
code=code*128+b-128
p=p+1
b=byte(str,p)
end
curFrm=curFrm+code*128+b
L[#L+1]=curFrm
p=p+1
local event=0
b=byte(str,p)
while b>=128 do
event=event*128+b-128
p=p+1
b=byte(str,p)
end
L[#L+1]=event*128+b
p=p+1
end
end
do--function saveRecording()
local noRecList={"custom","solo","round","techmino"}
local function getModList()
local res={}
for _,v in next,GAME.mod do
if v.sel>0 then
ins(res,{v.no,v.sel})
end
end
return res
end
function saveRecording()
--Filtering modes that cannot be saved
for _,v in next,noRecList do
if GAME.curModeName:find(v)then
LOG.print("Cannot save recording of this mode now!",COLOR.N)
return
end
end
--File contents
local fileName="replay/"..os.date("%Y_%m_%d_%a_%H%M%S.rep")
local fileHead=
os.date("%Y/%m/%d %A %H:%M:%S\n")..
GAME.curModeName.."\n"..
VERSION.string.."\n"..
"Local Player"
local fileBody=
GAME.seed.."\n"..
JSON.encode(GAME.setting).."\n"..
JSON.encode(getModList()).."\n"..
dumpRecording(GAME.rep)
--Write file
if not love.filesystem.getInfo(fileName)then
love.filesystem.write(fileName,fileHead.."\n"..data.compress("string","zlib",fileBody))
ins(REPLAY,fileName)
FILE.save(REPLAY,"conf/replay")
return true
else
LOG.print("Save failed: File already exists")
end
end
end
--Game draw
@@ -989,21 +478,28 @@ do--function drawFWM()
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()
function drawSelfProfile()
local selfAvatar=USERS.getAvatar(USER.uid)
gc_push("transform")
gc_translate(1280,0)
function drawSelfProfile()
local selfAvatar=USERS.getAvatar(USER.uid)
gc_push("transform")
gc_translate(1280,0)
--Draw avatar
gc_setLineWidth(2)
gc_setColor(.3,.3,.3,.8)gc_rectangle("fill",-260,0,260,80)
gc_setColor(1,1,1)gc_rectangle("line",-260,0,260,80)
gc_rectangle("line",-73,7,66,66,2)
gc_draw(selfAvatar,-72,8,nil,.5)
--Draw avatar
gc_setLineWidth(2)
gc_setColor(.3,.3,.3,.8)gc_rectangle("fill",-260,0,260,80)
gc_setColor(1,1,1)gc_rectangle("line",-260,0,260,80)
gc_rectangle("line",-73,7,66,66,2)
gc_draw(selfAvatar,-72,8,nil,.5)
gc_pop()
end
--Draw username
setFont(30)
gc_printf(USERS.getUsername(USER.uid),-342,5,260,"right")
--Draw lv. & xp.
gc_draw(TEXTURE.lvIcon[USER.lv],-255,50)
gc_line(-230,55,-80,55,-80,70,-230,70)
gc_rectangle("fill",-230,55,150*USER.xp/USER.lv/USER.lv,15)
gc_pop()
end
function drawWarning()
if SETTING.warn and GAME.warnLVL>0 then

View File

@@ -178,6 +178,10 @@ GAME={--Global game data
mostDangerous=false,--Most dangerous player
secDangerous=false, --Second dangerous player
}
ROYALEDATA={
powerUp=false,
stage=false,
}
--Userdata tables
RANKS=FILE.load("conf/unlock")or{sprint_10l=0}--Ranks of modes
@@ -355,5 +359,4 @@ VK_org=FILE.load("conf/virtualkey")or{--Virtualkey layout, refresh all VKs' posi
{ava=false, x=900, y=50, r=80,color=COLOR.lA},--addToLeft
{ava=false, x=1000, y=50, r=80,color=COLOR.lA},--addToRight
}
virtualkey={}for i=1,#VK_org do virtualkey[i]={}end--In-game virtualkey layout
REPLAY=FILE.load("conf/replay")or{}

View File

@@ -511,6 +511,11 @@ return{
"term",
"\"Doing scientific research\" is a term sometimes used in the Chinese community, referring to researching/practicing techniques in a low-falling-speed, single player environment.",
},
{"Handling",
"feel handling",
"term",
"Several main factors that affecting the hand feel:\n(1) Input delay is affected by device configuration or device condition. Restart / change device.\n(2) Program stability, program design (or implementation) is not good, cause lagging too much. May be alleviated by lowering the effect setting.\n(3) Designed on purpose. Adapt it.\n(4) Improper parameter setting. Change the settings.\n(5) Improper play posture. It's not convenient to use force. Change your posture.\n(6) Not used to the operation after changing the key position or changing the device. Get used to it or change the settings.\n(7) Muscle fatigue, response and coordination ability decreased. Get some sleep or do some sports, and come back later (maybe a few days).",
},
{"DAS & ARR",
"das arr delayedautoshift autorepeatrate",
"term",

View File

@@ -61,43 +61,43 @@ return{
{"King of Stackers",
"回合制 kos kingofstackers",
"game",
"King of Stackers\n网页版回合制对战方块点击即玩(可能很卡),主要规则为以7块为一个回合双方轮流在自己场地中放置方块任何的攻击只在对方回合放一块不消行后生效策略性很强。有不同的伤害表设置。",
"简称KOSKing of Stackers\n网页版回合制对战方块点击即玩(可能很卡),主要规则为:以7块为一个回合双方轮流在自己场地中放置方块任何的攻击只在对方回合放一块不消行后生效策略性很强。有不同的伤害表设置。",
"https://kingofstackers.com/games.php",
},
{"Tetr.js",
"网页 手机 tetrjs",
"game",
"全平台网页版单机方块点击即玩,有对新人比较友好的全自定义(大多数常用功能),手机只能选几个默认按键组,不能自由摆放。别的都很好",
"简称屁块,全平台网页版单机方块点击即玩,有对新人比较友好的全自定义(大多数常用功能),手机只能选几个默认按键组,不能自由摆放。别的都很好",
"http://farter.cn/t",
},
{"Tetra Legends",
"网页 tl tetralegends",
"game",
"全平台网页版单机方块点击即玩(推荐使用电脑,移动设备需要外接键盘)(第一次加载可能很慢),除了手感不够舒适以外功能比较强大,动效很好看,还把很多别的游戏里不可见的机制可视化了,游戏体验很好。\n\n注:包含节奏模式!\n\n2020年12月基本确定由于各种原因不再继续开发",
"简称TL全平台网页版单机方块点击即玩(推荐使用电脑,移动设备需要外接键盘)(第一次加载可能很慢),除了手感不够舒适以外功能比较强大,动效很好看,还把很多别的游戏里不可见的机制可视化了,游戏体验很好。\n\n注:包含节奏模式!\n\n2020年12月基本确定由于各种原因不再继续开发",
"https://tetralegends.app",
},
{"Jstris",
"网页 手机 js jstris",
"game",
"全平台网页对战方块点击即玩(服务器在国外可能很卡)。有常用的科研向单机模式和自定义各种参数的功能,但没有很多强制速度向的挑战项目。都是纯色素材导致画面效果不怎么好。移动端的键位设置并不舒适。",
"简称JS全平台网页对战方块点击即玩(服务器在国外可能很卡)。有常用的科研向单机模式和自定义各种参数的功能,但没有很多强制速度向的挑战项目。都是纯色素材导致画面效果不怎么好。移动端的键位设置并不舒适。",
"https://jstris.jezevec10.com",
},
{"TETR.IO",
"网页 io tetrio",
"game",
"炫酷在线对战方块点击即玩(推荐使用电脑,移动设备需要外接键盘)(服务器在国外,可能超级慢甚至打不开)有很科学的排位系统,自定义功能非常全面,同时也提供电脑客户端下载(可以去除广告)。缺点是单机模式非常非常少。",
"简称IO炫酷在线对战方块点击即玩(推荐使用电脑,移动设备需要外接键盘)(服务器在国外,可能超级慢甚至打不开)有很科学的排位系统,自定义功能非常全面,同时也提供电脑客户端下载(可以去除广告)。缺点是单机模式非常非常少。",
"https://tetr.io",
},
{"World Wide Combo",
"网页 wwc worldwidecombo",
"game",
"网页全世界匹配制1对1方块点击即玩(服务器在国外可能很卡)",
"简称WWC网页全世界匹配制1对1方块点击即玩(服务器在国外可能很卡)",
"https://worldwidecombos.com",
},
{"Tetris Friends",
"网页 tf tetrisfriends",
"game",
"一个已经关服了的网页版方块,曾经是一个不错的对战平台\n现在有人架了私服(怀旧服?)",
"简称TF一个已经关服了的网页版方块,曾经是一个不错的对战平台\n现在有人架了私服(怀旧服?)",
"https://notrisfoes.com",
},
@@ -121,49 +121,49 @@ return{
{"Texmaster",
"txm texmaster",
"game",
"一个win平台方块包含TGM的所有模式可以用来练习TGM手感比真版较好不足的是world规则不完全一样(如软降到底无锁延,踢墙表有细节不同等)",
"简称Tex一个win平台方块包含TGM的所有模式可以用来练习TGM手感比真版较好不足的是world规则不完全一样(如软降到底无锁延,踢墙表有细节不同等)",
},
--游戏(PC/主机)
{"Tetris99",
"吃鸡 t99 tetris99",
"game",
"ns端方块主玩99人混战的吃鸡模式战术比重比较大胜率不只由玩家在平时1v1时的水平决定。也有一些常用单机模式如马拉松等",
"简称T99ns端方块主玩99人混战的吃鸡模式战术比重比较大胜率不只由玩家在平时1v1时的水平决定。也有一些常用单机模式如马拉松等",
},
{"Puyopuyo Tetris",
"ppt puyopuyotetris",
"game",
"多平台方块(steamPC版手感网络等都不太好不建议购买)将tetris和puyopuyo两个下落消除游戏放到一个游戏里二者可以对战联机单机模式都很多很有趣",
"简称PPT多平台方块(steamPC版手感网络等都不太好不建议购买)将tetris和puyopuyo两个下落消除游戏放到一个游戏里二者可以对战联机单机模式都很多很有趣",
},
{"Tetris Online",
"top tetris online study",
"game",
"一个win平台方块主要用来6人内对战/单挑/刷每日40L榜/挖掘模式/打机器人。支持自定义das/arr但都不能到0有一点输入延迟但问题不大是新人入块圈不错的选择。\n\n现在还开着的服务器有:\n\tTO-P(波兰服,服务器在波兰,可能会卡顿)\n\tTO-S(研究服,研究群群友自己开的服,很稳定,需要进群注册)\n\tTO-X(千雪服VUP星月千雪于20年9月开的服还处于实验阶段)",
"简称TO[服务器名首字母]一个win平台方块主要用来6人内对战/单挑/刷每日40L榜/挖掘模式/打机器人。支持自定义das/arr但都不能到0有一点输入延迟但问题不大是新人入块圈不错的选择。\n\n现在还开着的服务器有:\n\tTO-P(波兰服,服务器在波兰,可能会卡顿)\n\tTO-S(研究服,研究群群友自己开的服,很稳定,需要进群注册)\n\tTO-X(千雪服VUP星月千雪于20年9月开的服还处于实验阶段)",
},
{"Tetra Online",
"to tetraonline",
"game",
"PC方块打开Steam免费下载即玩(现在已经没了)开发团队只有Dr.Ocelot和Mine两个人(都没有很多开发经验)UI部分模仿PPT手感故意设计为较慢平时玩无延迟方块的玩家会很不习惯音乐不错攻击特效好看。2020年12月9日收到来自TTC的DCMA警告信于是被迫停止开发在一段时间后关服并下架。",
"简称TOPC方块打开Steam免费下载即玩(现在已经没了)开发团队只有Dr.Ocelot和Mine两个人(都没有很多开发经验)UI部分模仿PPT手感故意设计为较慢平时玩无延迟方块的玩家会很不习惯音乐不错攻击特效好看。2020年12月9日收到来自TTC的DCMA警告信于是被迫停止开发在一段时间后关服并下架。",
},
{"Tetris Effect",
"tec tetriseffectconnect",
"game",
"一个win/ps4/xbox平台方块特效方块游戏只有单机模式手感不算太好想看特效的可以一试只是去玩方块的不是很建议\n有一个拓展版本Tetris Effect: Connected增加了联网对战包含普通对战zone对战经典对战和boss战四个模式",
"简称TE(C)一个win/ps4/xbox平台方块特效方块游戏只有单机模式手感不算太好想看特效的可以一试只是去玩方块的不是很建议\n有一个拓展版本Tetris Effect: Connected增加了联网对战包含普通对战zone对战经典对战和boss战四个模式",
},
{"Techmino",
"techmino tieke",
"game",
"一个win/android/linux/macOS方块单机模式和各种设置都很齐全联机正在逐渐开发中输入延迟很小手感很好",
"简称Tech一个win/android/linux/macOS方块单机模式和各种设置都很齐全联机正在逐渐开发中输入延迟很小手感很好",
},
{"Cultris II",
"c2 cultris2 cultrisii",
"game",
"一个win/linux/macOS平台方块基于经典规则但支持自定义das/arr主玩对战,打法是基于时间的连击,考验玩家速度/wide打法/挖掘",
"简称C2一个win/linux/macOS平台方块设计基于经典规则出发但支持自定义das/arr对战的主要玩法是基于时间的连击,考验玩家速度/wide打法/挖掘",
},
{"Nullpomino",
"np nullpomino",
"game",
"一个win平台方块整个游戏自定义程度极高几乎任何参数都可以自己设置是一个专业级方块不太适合新人上手连菜单都不太好搞清楚",
"简称NP一个win平台方块整个游戏自定义程度极高几乎任何参数都可以自己设置是一个专业级方块不太适合新人上手连菜单都不太好搞清楚",
},
{"Touhoumino",
"touhoumino chewan dongfang",
@@ -520,6 +520,11 @@ return{
"term",
"常用语指在低重力的单人模式里减速研究怎么做各种Tspin本游戏中拓展了含义用于称呼几乎需要全程spin的游戏模式。",
},
{"手感",
"手感 feel shougan",
"term",
"决定手感的几个主要因素:\n(1)输入延迟受设备配置或者设备状况影响。可以重启/换设备解决\n(2)程序运行稳定性程序设计(或者实现)得不好,时不时会卡一下。把设置画面效果拉低可能可以缓解\n(3)游戏设计故意的。自己适应\n(4)参数设置设置不当。去改设置\n(5)游玩姿势姿势不当。不便用力,换个姿势\n(6)换键位或者换设备后不适应,操作不习惯。多习惯习惯,改改设置\n(7)肌肉疲劳反应和协调能力下降。睡一觉或者做点体育运动,过段时间(也可能要几天)再来玩",
},
{"DAS & ARR",
"灵敏度 das arr",
"term",
@@ -568,7 +573,7 @@ return{
{"C2序列",
"c2序列 seq",
"term",
"七个块初始权重0\n全体除以2再加0~1的随机数选数字最大的块出然后将其权重除以3.5,循环",
"七个块初始权重0\n全体除以2再加0~1的随机数选数字最大的块出然后将其权重除以3.5,循环",--Reversed by zxc
},
{"C2踢墙",
"c2踢墙 kick",

View File

@@ -220,7 +220,6 @@ return{
about="About",
dict="Zictionary",
manual="Manual",
quit="Exit",
},
main_simple={
sprint="Sprint",
@@ -858,23 +857,23 @@ return{
{C.C,"Also try Phigros!"},
{C.C,"Also try Rubic's cube!"},
{C.C,"Also try Terraria!"},
{C.C,"Also try VVVVVV!"},
{C.fire,"Also try Cultris II!"},
{C.fire,"Also try Jstris"},
{C.fire,"Also try NullpoMino!"},
{C.fire,"Also try TETR.IO!"},
{C.fire,"Also try Tetr.js!"},
{C.fire,"Also try Tetra Legends!"},
{C.purple,"T-spin!"},
{C.C,"Also try VVVVVVV!"},
{C.F,"Also try Cultris II!"},
{C.F,"Also try Jstris"},
{C.F,"Also try NullpoMino!"},
{C.F,"Also try TETR.IO!"},
{C.F,"Also try Tetr.js!"},
{C.F,"Also try Tetra Legends!"},
{C.H,"REGRET!!"},
{C.lR,"Z ",C.lG,"S ",C.lS,"J ",C.lO,"L ",C.lP,"T ",C.lY,"O ",C.lC,"I"},
{C.lY,"COOL!!"},
{C.N,"Lua",C.Z," No.1"},
{C.P,"T-spin!"},
{C.R,"\"DMCA abusing\""},
{C.R,"\"Intellectual property law\""},
{C.R,"DT",C.Z," Cannon=",C.purple,"TS",C.R,"D",C.Z,"+",C.purple,"TS",C.R,"T",C.Z," Cannon"},
{C.R,"LrL ",C.G,"RlR ",C.B,"LLr ",C.orange,"RRl ",C.purple,"RRR ",C.purple,"LLL ",C.C,"FFF ",C.Y,"RfR ",C.Y,"RRf ",C.Y,"rFF"},
{C.navy,"Lua",C.Z," No.1"},
{C.Z,"What is an ",c.lC,"X-Spin"?},
{C.R,"DT",C.Z," Cannon=",C.P,"TS",C.R,"D",C.Z,"+",C.P,"TS",C.R,"T",C.Z," Cannon"},
{C.R,"LrL ",C.G,"RlR ",C.B,"LLr ",C.O,"RRl ",C.P,"RRR ",C.P,"LLL ",C.C,"FFF ",C.Y,"RfR ",C.Y,"RRf ",C.Y,"rFF"},
{C.Y,"O-Spin Triple!"},
{C.Z,"What is an ",c.lC,"X-Spin"?},
}
}

View File

@@ -197,7 +197,6 @@ return{
-- about="About",
dict="Zictionary",
manual="Manuel",
quit="Quitter",
},
mode={
mod="Mods (F1)",

View File

@@ -221,7 +221,6 @@ return{
-- about="About",
dict="Zictionary",
manual="Manual",
quit="Saída",
},
main_simple={
sprint="Sprint",

View File

@@ -198,7 +198,6 @@ return{
about="Acerca del Juego",
dict="Zictionary",
manual="Manual",
quit="Salir",
},
main_simple={
sprint="Sprint",

View File

@@ -102,7 +102,6 @@ return{
about="?",
dict="z",
manual="???",
quit="X",
},
mode={
mod="?!?!?!(F1)",

View File

@@ -220,7 +220,6 @@ return{
about="关于",
dict="小Z词典",
manual="说明书",
quit="退出",
},
main_simple={
sprint="40行",
@@ -799,6 +798,7 @@ return{
"把手机调到特殊的日期也许会发生什么",
"报时机器人:新的一天开始了",
"背景影响游玩?可以去设置关闭",
"本游戏不是产品,是作品(至少目前是…)",
"本游戏的一部分内容是国际合作的!",
"本游戏的B2B是气槽机制,和传统的开关机制不一样哦",
"本游戏可不是休闲游戏。",
@@ -808,6 +808,8 @@ return{
"别问游戏名怎么取的,问就是随便想的",
"不同人打40行最合适的方式不一样,s1w/63/散消/s2w...",
"不同游戏(甚至不同模式)中不同战术的能力都不一样,并没有绝对的强弱之分",
"不要悲伤,不要心急",
"不知道有多少人玩游戏的时候会关心游戏是谁做的",
"部分手机系统开启震动会导致严重卡顿",
"彩色消除即将到来!",
"草(日本语)",
@@ -817,6 +819,7 @@ return{
"凑数tip什么时候能站起来!",
"打好块跟学习一样没有捷径,多练。",
"大概还是有人会看tip的",
"大陆的方块社区起步晚,所以世界级高手很少…下一个会是你吗?",
"大满贯10连击消四全清!",
"戴上耳机以获得最佳体验",
"单手也能玩!",
@@ -910,12 +913,14 @@ return{
"适度游戏益脑,沉迷游戏伤身,合理安排时间,享受健康生活",
"手机玩也可以外接键盘哦",
"术语不认识?去帮助-词典里查查吧",
"水平是随着时间一点点提升的,不是几天几星期就能玩好的哦",
"四连块总共7种",
"虽然极简连击和极简率计算看着很怪,但是很科学!",
"提前旋转等功能可以用来救命",
"天哪,我竟然是一条凑数tip",
"挖掘能力在对战里非常非常非常重要!!!!",
"玩到一半弹出消息框?快去设置禁止弹窗",
"玩得开心的话游戏作者也会很开心哦",
"为了保护玩家们的健康,本游戏有一个临时的简易防沉迷系统!(不过估计你也触发不了/笑)",
"为什么关卡那么少!因为前一模式成绩连D都没达到,再加把劲吧~",
"我曾经在极度愤怒的时候15秒消了40行",
@@ -946,7 +951,6 @@ return{
"这个菜单可以用纯键盘控制",
"这里的极简判定不松不严,放心软降,小心hold!",
"震惊,我只是一条凑数tip吗",
"中国的方块起步晚,所以世界级高手很少…下一个会是你吗?",
"众所周知俄罗斯方块是经典编程练手游戏(?",
"注意到方块\"旋转\"的时候到底发生了些什么吗?",
"自定义场地可以画图实现逐页演示",
@@ -973,6 +977,7 @@ return{
"e^(pi*i/4)=(1+i)/√2",
"Farter:\"成天被夸赞'好玩'的\"",
"Farter:\"可以形成方块圈子小中心话题,同作者一起衍生一些概念与梗的\"",
"Farter:\"论方块的软工意义(就算这么小个范围内,各种取舍蒙混翻车现象都总会以很易懂的方式出现(\"",
"Farter:\"民间微创新\"",
"Farter:\"民间音le与图案\"",
"Farter:\"民间游戏设计\"",
@@ -982,27 +987,29 @@ return{
"Farter:\"是民间UI动效艺术作品\"",
"Farter:\"是一滩散乱的代码组成的蜜汁结构\"",
"Farter:\"它是现在的techmino已发布版本\"",
"Farter:\"论方块的软工意义(就算这么小个范围内,各种取舍蒙混翻车现象都总会以很易懂的方式出现(\"",
"fin neo iso 是满足tspin条件的特殊t2的名字",
"git commit",
"hello world",
"if a==true",
"l-=-1",
"Let-The-Bass-Kick!",
"pps-0.01",
"shutdown -h now",
"sin(α+β)=SαCβ+SβCα",
"sin²α-cos²β=-C(α+β)C(α-β)",
"sin²α-sin²β=S(α+β)S(α-β)",
"sin2α=2SαCα",
"Staff名单里飘过的是赞助榜单,喜欢本游戏的话可以给Z酱打赞助",
"Staff名单里飘过的是赞助榜单,喜欢本游戏的话可以给我们打赞助支持开发哦~",
"SΔABC=√(h(h-a)(h-b)(h-c)), h=(a+b+c)/2",
"Tech生日不太清楚,那就定在2019.6.26吧",
"Tech也有节日主题了哦",
"Techmino = Technique + tetromino",
"Techmino n.铁壳米诺(游戏名)",
"Techmino console了解一下",
"Techmino安卓下载",
"Techmino好玩!",
"Techmino 好玩!",
"Techmino 濂界帺锛",
"Techmino console了解一下",
"Techmino n.铁壳米诺(游戏名)",
"Techmino安卓下载",
"Techmino好玩!",
"Techmino有一个Nspire-CX版本!",
"Techmino在哪里下载",
"Techminohaowan",
@@ -1014,7 +1021,7 @@ return{
"Z块等身抱枕来一个(x",
{C.A,"AQUA"},
{C.B,"BLUE"},
{C.C,"<PURE ",C.purple,"MEMORY>"},
{C.C,"<PURE ",C.P,"MEMORY>"},
{C.C,"15puzzle好玩!"},
{C.C,"魔方好玩!"},
{C.C,"扫雷好玩!"},
@@ -1047,7 +1054,8 @@ return{
{C.H,"感谢Phigros提供部分tip模板("},
{C.H,"暂定段位:9"},
{C.H,"REGRET!!"},
{C.jade,"JADE"},
{C.J,"JADE"},
{C.L,"LIME"},
{C.lC,"26连T2来一个?"},
{C.lC,"Xspin",C.Z,"是啥"},
{C.lH,"腱鞘炎警告"},
@@ -1057,7 +1065,6 @@ return{
{C.lH,"你有一个好"},
{C.lH,"STSD必死"},
{C.lH,"Techmino没有抽卡没有氪金,太良心了"},
{C.L,"LIME"},
{C.lP,"Naki",C.Z," 可爱!"},
{C.lR,"Z ",C.lG,"S ",C.lS,"J ",C.lO,"L ",C.lP,"T ",C.lY,"O ",C.lC,"I"},
{C.lS,"茶娘",C.Z," 可爱!"},
@@ -1077,9 +1084,9 @@ return{
{C.R,"请在有一定游戏基础之后再学Tspin!不然副作用非常大!"},
{C.R,"新人请千万记住,打好基础,不要太早学那些花里胡哨的。"},
{C.R,"长时间游戏状态会越来越差!玩久了记得放松一下~"},
{C.R,"DD",C.Z,"炮=",C.purple,"TS",C.R,"D",C.Z,"+",C.purple,"TS",C.R,"D",C.Z,""},
{C.R,"DT",C.Z,"炮=",C.purple,"TS",C.R,"D",C.Z,"+",C.purple,"TS",C.R,"T",C.Z,""},
{C.R,"LrL ",C.G,"RlR ",C.B,"LLr ",C.orange,"RRl ",C.purple,"RRR LLL ",C.C,"FFF ",C.Y,"RfR RRf rFF"},
{C.R,"DD",C.Z,"炮=",C.P,"TS",C.R,"D",C.Z,"+",C.P,"TS",C.R,"D",C.Z,""},
{C.R,"DT",C.Z,"炮=",C.P,"TS",C.R,"D",C.Z,"+",C.P,"TS",C.R,"T",C.Z,""},
{C.R,"LrL ",C.G,"RlR ",C.B,"LLr ",C.O,"RRl ",C.P,"RRR LLL ",C.C,"FFF ",C.Y,"RfR RRf rFF"},
{C.R,"RED"},
{C.S,"SEA"},
{C.V,"VIOLET"},

View File

@@ -28,10 +28,8 @@ return{
bg="rainbow",bgm="sugar fairy",
},
load=function()
royaleData={
powerUp={2,5,10,20},
stage={30,20,15,10,5},
}
ROYALEDATA.powerUp={2,5,10,20}
ROYALEDATA.stage={30,20,15,10,5}
PLY.newPlayer(1)
local L={}for i=1,49 do L[i]=true end
local t=CC and 2 or 0

View File

@@ -28,10 +28,8 @@ return{
bg="rainbow",bgm="rockblock",
},
load=function()
royaleData={
powerUp={2,5,10,20},
stage={30,20,15,10,5},
}
ROYALEDATA.powerUp={2,5,10,20}
ROYALEDATA.stage={30,20,15,10,5}
PLY.newPlayer(1)
local L={}for i=1,49 do L[i]=true end
local t=CC and 4 or 0

View File

@@ -28,10 +28,8 @@ return{
bg="rainbow",bgm="magicblock",
},
load=function()
royaleData={
powerUp={2,5,10,20},
stage={30,20,15,10,5},
}
ROYALEDATA.powerUp={2,5,10,20}
ROYALEDATA.stage={30,20,15,10,5}
PLY.newPlayer(1)
local L={}for i=1,49 do L[i]=true end
local t=CC and 6 or 0

View File

@@ -28,10 +28,8 @@ return{
bg="rainbow",bgm="sugar fairy",
},
load=function()
royaleData={
powerUp={2,6,14,30},
stage={75,50,35,20,10},
}
ROYALEDATA.powerUp={2,6,14,30}
ROYALEDATA.stage={75,50,35,20,10}
PLY.newPlayer(1)
local L={}for i=1,100 do L[i]=true end
local t=CC and 4 or 0

View File

@@ -28,10 +28,8 @@ return{
bg="rainbow",bgm="rockblock",
},
load=function()
royaleData={
powerUp={2,6,14,30},
stage={75,50,35,20,10},
}
ROYALEDATA.powerUp={2,6,14,30}
ROYALEDATA.stage={75,50,35,20,10}
PLY.newPlayer(1)
local L={}for i=1,100 do L[i]=true end
local t=CC and 4 or 0

View File

@@ -28,10 +28,8 @@ return{
bg="rainbow",bgm="magicblock",
},
load=function()
royaleData={
powerUp={2,6,14,30},
stage={75,50,35,20,10},
}
ROYALEDATA.powerUp={2,6,14,30}
ROYALEDATA.stage={75,50,35,20,10}
PLY.newPlayer(1)
local L={}for i=1,100 do L[i]=true end
local t=CC and 4 or 0

View File

@@ -141,7 +141,7 @@ function NET.getUserInfo(uid)
WS.send("user",JSON.encode{
action=1,
data={
id=uid,
uid=uid,
hash=hash,
},
})
@@ -249,8 +249,14 @@ function NET.updateWS_app()
elseif res.action==1 then--Get notice
--?
elseif res.action==2 then--Register
LOG.print(res.data.message,300,COLOR.N)
if SCN.cur=="register"then SCN.back()end
if res.type=="Self"or res.type=="Server"then
LOG.print(res.data.message,300,COLOR.N)
if SCN.cur=="register"then
SCN.back()
end
else
LOG.print(res.reason or"Registration failed",300,COLOR.N)
end
NET.unlock("register")
end
else

View File

@@ -213,15 +213,15 @@ local function loadGameEnv(P)--Load gameEnv
for k,v in next,gameEnv0 do
if GAME.modeEnv[k]~=nil then
v=GAME.modeEnv[k] --Mode setting
-- DBP("mode-"..k..":"..tostring(v))
-- print("mode-"..k..":"..tostring(v))
elseif GAME.setting[k]~=nil then
v=GAME.setting[k] --Game setting
-- DBP("game-"..k..":"..tostring(v))
-- print("game-"..k..":"..tostring(v))
elseif SETTING[k]~=nil then
v=SETTING[k] --Global setting
-- DBP("global-"..k..":"..tostring(v))
-- print("global-"..k..":"..tostring(v))
-- else
-- DBP("default-"..k..":"..tostring(v))
-- print("default-"..k..":"..tostring(v))
end
if type(v)~="table"then--Default setting
ENV[k]=v

View File

@@ -172,7 +172,7 @@ function Player:switchKey(id,on)
self:releaseKey(id)
end
if self.type=="human"then
virtualkey[id].ava=on
VK.switchKey(id,on)
end
end
function Player:set20G(if20g)
@@ -1798,7 +1798,7 @@ function Player:lose(force)
end
A.modeData.ko,A.badge=A.modeData.ko+1,A.badge+self.badge+1
for j=A.strength+1,4 do
if A.badge>=royaleData.powerUp[j]then
if A.badge>=ROYALEDATA.powerUp[j]then
A.strength=j
A.frameColor=A.strength
end
@@ -1814,7 +1814,7 @@ function Player:lose(force)
freshMostBadge()
freshMostDangerous()
if #PLY_ALIVE==royaleData.stage[GAME.stage]then
if #PLY_ALIVE==ROYALEDATA.stage[GAME.stage]then
royaleLevelup()
end
self:showTextF(self.modeData.place,0,120,60,"appear",.26,.9)

View File

@@ -7,8 +7,8 @@ function scene.sceneInit()
end
scene.widgetList={
WIDGET.newText{name="title", x=80, y=50,font=70,align="L"},
WIDGET.newButton{name="back", x=1140, y=640,w=170,h=80,font=40,code=backScene},
WIDGET.newText{name="title",x=80,y=50,font=70,align="L"},
WIDGET.newButton{name="back",x=1140,y=640,w=170,h=80,font=40,code=backScene},
}
return scene

View File

@@ -481,18 +481,18 @@ end
scene.widgetList={
WIDGET.newButton{name="reset", x=155,y=100,w=180,h=100,color="lG",font=40,code=pressKey"r"},
WIDGET.newSwitch{name="blind", x=240,y=300,w=60, font=40,disp=function()return blind end, code=pressKey"q",hide=function()return state==1 end},
WIDGET.newSwitch{name="tapControl", x=240,y=370,w=60, font=40,disp=function()return tapControl end, code=pressKey"w",hide=function()return state==1 end},
WIDGET.newSwitch{name="blind", x=240,y=300,w=60,font=40,disp=function()return blind end,code=pressKey"q",hide=function()return state==1 end},
WIDGET.newSwitch{name="tapControl", x=240,y=370,w=60,font=40,disp=function()return tapControl end,code=pressKey"w",hide=function()return state==1 end},
WIDGET.newKey{name="up", x=155,y=460,w=100,fText="",font=50,color="Y",code=pressKey"up",hide=function()return tapControl end},
WIDGET.newKey{name="down", x=155,y=660,w=100,fText="",font=50,color="Y",code=pressKey"down",hide=function()return tapControl end},
WIDGET.newKey{name="left", x=55,y=560,w=100,fText="",font=50,color="Y",code=pressKey"left",hide=function()return tapControl end},
WIDGET.newKey{name="right", x=255,y=560,w=100,fText="",font=50,color="Y",code=pressKey"right",hide=function()return tapControl end},
WIDGET.newKey{name="skip", x=155,y=400,w=100,font=20,color="Y",code=pressKey"space",hide=function()return state~=1 or not skipper.cd or skipper.cd>0 end},
WIDGET.newKey{name="record1", x=1100,y=390,w=220,h=50,fText="",color="H",code=pressKey"1",hide=function()return state==2 end},
WIDGET.newKey{name="record2", x=1100,y=450,w=220,h=50,fText="",color="H",code=pressKey"2",hide=function()return state==2 end},
WIDGET.newKey{name="replay1", x=1245,y=390,w=50,fText="!",color="G",code=pressKey"c1",hide=function()return state==2 or #repeater.seq[1]==0 end},
WIDGET.newKey{name="replay2", x=1245,y=450,w=50,fText="!",color="G",code=pressKey"c2",hide=function()return state==2 or #repeater.seq[2]==0 end},
WIDGET.newKey{name="skip", x=155,y=400,w=100,font=20, color="Y",code=pressKey"space",hide=function()return state~=1 or not skipper.cd or skipper.cd>0 end},
WIDGET.newKey{name="record1", x=1100,y=390,w=220,h=50,fText="", color="H",code=pressKey"1",hide=function()return state==2 end},
WIDGET.newKey{name="record2", x=1100,y=450,w=220,h=50,fText="", color="H",code=pressKey"2",hide=function()return state==2 end},
WIDGET.newKey{name="replay1", x=1245,y=390,w=50,fText="!", color="G",code=pressKey"c1",hide=function()return state==2 or #repeater.seq[1]==0 end},
WIDGET.newKey{name="replay2", x=1245,y=450,w=50,fText="!", color="G",code=pressKey"c2",hide=function()return state==2 or #repeater.seq[2]==0 end},
WIDGET.newButton{name="back", x=1140,y=640,w=170,h=80,font=40,code=backScene},
}

View File

@@ -2,11 +2,8 @@ local gc=love.graphics
local int,rnd,abs,sin,cos=math.floor,math.random,math.abs,math.sin,math.cos
local pow,ang
local state,timer
local score,combo
local x,y
local vx,vy
local ex,ey
local state,timer,score,combo
local x,y,vx,vy,ex,ey
local scene={}
function scene.sceneInit()
@@ -81,17 +78,17 @@ function scene.update()
end
local scoreColor={
"white",--0
"aqua",--20
"navy",--40
"blue",--60
"purple",--80
"wine",--100
"red","fire","orange","yellow","lAqua",--200
"lNavy","lBlue","lPurple","lWine","lRed",--300
"lFire","lOrange","lYellow","dAqua","dNavy",--400
"dBlue","dPurple","dWine","dRed","dFire",--500
"dYellow","lH","H","dH",--before 600, black after
"Z",--0
"A",--20
"N",--40
"B",--60
"P",--80
"W",--100
"R","F","O","Y","lA",--200
"lN","lB","lP","lW","lR",--300
"lF","lO","lY","dA","dN",--400
"dB","dP","dW","dR","dF",--500
"dY","lH","H","dH",--before 600, black after
}
function scene.draw()
--Spawn area
@@ -116,7 +113,7 @@ function scene.draw()
gc.setColor(1,1,.6)
gc.print("x"..combo,300,80)
end
gc.setColor(COLOR[scoreColor[int(score/20)+1]or"black"])
gc.setColor(COLOR[scoreColor[int(score/20)+1]or"D"])
gc.print(score,300,30)
--Cannon ball

View File

@@ -697,6 +697,12 @@ function scene.keyDown(k)
end
elseif combKey[k]and kb.isDown("lctrl","rctrl")then
combKey[k]()
elseif k=="escape"then
if WIDGET.sel~=inputBox then
WIDGET.sel=inputBox
else
SCN.back()
end
else
if WIDGET.sel~=inputBox then WIDGET.sel=inputBox end
WIDGET.keyPressed(k)

View File

@@ -14,6 +14,7 @@ local blind,disappear
local startTime,time
local state,progress
local tapFX,mistake
function scene.sceneInit()
BG.set("space")
BGM.play("way")

View File

@@ -73,8 +73,8 @@ function scene.draw()
end
scene.widgetList={
WIDGET.newKey{name="tap", x=640,y=540,w=626,h=260,fText="TAP",color="Z",font=100,code=pressKey"button"},
WIDGET.newButton{name="back", x=1140,y=640,w=170,h=80,font=40,code=backScene},
WIDGET.newKey{name="tap",x=640,y=540,w=626,h=260,fText="TAP",color="Z",font=100,code=pressKey"button"},
WIDGET.newButton{name="back",x=1140,y=640,w=170,h=80,font=40,code=backScene},
}
return scene

View File

@@ -64,11 +64,11 @@ function scene.keyDown(key)
elseif key=="a"then
SCN.go("custom_advance","swipeD")
elseif key=="c"and kb.isDown("lctrl","rctrl")or key=="cC"then
local str="Techmino Quest:"..copyQuestArgs().."!"
if #BAG>0 then str=str..copySequence()end
local str="Techmino Quest:"..DATA.copyQuestArgs().."!"
if #BAG>0 then str=str..DATA.copySequence()end
str=str.."!"
if #MISSION>0 then str=str..copyMission()end
sys.setClipboardText(str.."!"..copyBoards().."!")
if #MISSION>0 then str=str..DATA.copyMission()end
sys.setClipboardText(str.."!"..DATA.copyBoards().."!")
LOG.print(text.exportSuccess,COLOR.G)
elseif key=="v"and kb.isDown("lctrl","rctrl")or key=="cV"then
local str=sys.getClipboardText()
@@ -76,13 +76,13 @@ function scene.keyDown(key)
if #args<4 then goto THROW_fail end
if not(
pasteQuestArgs(args[1])and
pasteSequence(args[2])and
pasteMission(args[3])
DATA.pasteSequence(args[2])and
DATA.pasteMission(args[3])
)then goto THROW_fail end
repeat table.remove(FIELD)until #FIELD==0
FIELD[1]=newBoard()
FIELD[1]=DATA.newBoard()
for i=4,#args do
if not pasteBoard(args[i],i-3)and i<#args then goto THROW_fail end
if not DATA.pasteBoard(args[i],i-3)and i<#args then goto THROW_fail end
end
freshMiniFieldVisible()
LOG.print(text.importSuccess,COLOR.G)
@@ -165,7 +165,7 @@ scene.widgetList={
WIDGET.newButton{name="copy", x=1070, y=310,w=310,h=70,color="lR",font=25,code=pressKey"cC"},
WIDGET.newButton{name="paste", x=1070, y=390,w=310,h=70,color="lB",font=25,code=pressKey"cV"},
WIDGET.newButton{name="clear", x=1070, y=470,w=310,h=70,color="lY",font=35,code=pressKey"return"},
WIDGET.newButton{name="puzzle",x=1070, y=550,w=310,h=70,color="lM",font=35,code=pressKey"return2",hide=function()return not initField end},
WIDGET.newButton{name="puzzle", x=1070, y=550,w=310,h=70,color="lM",font=35,code=pressKey"return2",hide=function()return not initField end},
--More
WIDGET.newKey{name="advance", x=730, y=190,w=220,h=90,color="R",font=35,code=goScene"custom_advance"},

View File

@@ -212,7 +212,7 @@ function scene.keyDown(key)
SFX.play("fall",.8)
end
elseif key=="n"then
ins(FIELD,page+1,newBoard(FIELD[page]))
ins(FIELD,page+1,DATA.newBoard(FIELD[page]))
page=page+1
SFX.play("blip_1",.8)
SYSFX.newShade(3,200,60,300,600,.5,1,.5)
@@ -220,19 +220,19 @@ function scene.keyDown(key)
rem(FIELD,page)
page=max(page-1,1)
if not FIELD[1]then
ins(FIELD,newBoard())
ins(FIELD,DATA.newBoard())
end
SYSFX.newShade(3,200,60,300,600,1,.5,.5)
SFX.play("clear_4",.8)
SFX.play("fall",.8)
elseif key=="c"and kb.isDown("lctrl","rctrl")or key=="cC"then
sys.setClipboardText("Techmino Field:"..copyBoard(page))
sys.setClipboardText("Techmino Field:"..DATA.copyBoard(page))
LOG.print(text.exportSuccess,COLOR.G)
elseif key=="v"and kb.isDown("lctrl","rctrl")or key=="cV"then
local str=sys.getClipboardText()
local p=string.find(str,":")--ptr*
if p then str=sub(str,p+1)end
if pasteBoard(str,page)then
if DATA.pasteBoard(str,page)then
LOG.print(text.importSuccess,COLOR.G)
else
LOG.print(text.dataCorrupted,COLOR.R)
@@ -445,16 +445,16 @@ scene.widgetList={
WIDGET.newButton{name="b16", x=1140, y=210,w=75,fText="",color="W",code=setPen(16)},--B16
WIDGET.newButton{name="b17", x=580, y=290,w=75,fText="[ ]",color="dH", code=setPen(17)},--BONE
WIDGET.newButton{name="b18", x=660, y=290,w=75,fText="N", color="D", code=setPen(18)},--HIDE
WIDGET.newButton{name="b19", x=740, y=290,w=75,fText="B", color="lY", code=setPen(19)},--BOMB
WIDGET.newButton{name="b18", x=660, y=290,w=75,fText="N", color="D", code=setPen(18)},--HIDE
WIDGET.newButton{name="b19", x=740, y=290,w=75,fText="B", color="lY", code=setPen(19)},--BOMB
WIDGET.newButton{name="b20", x=820, y=290,w=75,fText="_", color="H", code=setPen(20)},--GB1
WIDGET.newButton{name="b21", x=900, y=290,w=75,fText="_", color="lH", code=setPen(21)},--GB2
WIDGET.newButton{name="b22", x=980, y=290,w=75,fText="_", color="dV", code=setPen(22)},--GB3
WIDGET.newButton{name="b23", x=1060, y=290,w=75,fText="_", color="dR", code=setPen(23)},--GB4
WIDGET.newButton{name="b24", x=1140, y=290,w=75,fText="_", color="dG", code=setPen(24)},--GB5
WIDGET.newButton{name="b22", x=980, y=290,w=75,fText="_", color="dV", code=setPen(22)},--GB3
WIDGET.newButton{name="b23", x=1060, y=290,w=75,fText="_", color="dR", code=setPen(23)},--GB4
WIDGET.newButton{name="b24", x=1140, y=290,w=75,fText="_", color="dG", code=setPen(24)},--GB5
WIDGET.newButton{name="any", x=600, y=400,w=120,color="lH", font=40,code=setPen(0)},
WIDGET.newButton{name="space", x=730, y=400,w=120,color="H", font=65,code=setPen(-1)},
WIDGET.newButton{name="any", x=600, y=400,w=120,color="lH", font=40,code=setPen(0)},
WIDGET.newButton{name="space", x=730, y=400,w=120,color="H", font=65,code=setPen(-1)},
WIDGET.newButton{name="smartPen", x=860, y=400,w=120,color="lG", font=30,code=setPen(-2)},
WIDGET.newButton{name="pushLine", x=990, y=400,w=120,h=120,color="lY",font=20,code=pressKey"k"},
WIDGET.newButton{name="delLine", x=1120, y=400,w=120,h=120,color="lY",font=20,code=pressKey"l"},

View File

@@ -72,14 +72,14 @@ function scene.keyDown(key)
end
elseif key=="c"and kb.isDown("lctrl","rctrl")or key=="cC"then
if #MISSION>0 then
sys.setClipboardText("Techmino Target:"..copyMission())
sys.setClipboardText("Techmino Target:"..DATA.copyMission())
LOG.print(text.exportSuccess,COLOR.G)
end
elseif key=="v"and kb.isDown("lctrl","rctrl")or key=="cV"then
local str=sys.getClipboardText()
local p=string.find(str,":")--ptr*
if p then str=sub(str,p+1)end
if pasteMission(str)then
if DATA.pasteMission(str)then
LOG.print(text.importSuccess,COLOR.G)
cur=#MISSION
else
@@ -187,51 +187,51 @@ scene.widgetList={
WIDGET.newText{name="title", x=520,y=5,font=70,align="R"},
WIDGET.newText{name="subTitle", x=530,y=50,font=35,align="L",color="H"},
WIDGET.newKey{name="_1", x=800, y=540, w=90, font=50,code=pressKey(01)},
WIDGET.newKey{name="_2", x=900, y=540, w=90, font=50,code=pressKey(02)},
WIDGET.newKey{name="_3", x=800, y=640, w=90, font=50,code=pressKey(03)},
WIDGET.newKey{name="_4", x=900, y=640, w=90, font=50,code=pressKey(04)},
WIDGET.newKey{name="any1", x=100, y=640, w=90, code=pressKey(05)},
WIDGET.newKey{name="any2", x=200, y=640, w=90, code=pressKey(06)},
WIDGET.newKey{name="any3", x=300, y=640, w=90, code=pressKey(07)},
WIDGET.newKey{name="any4", x=400, y=640, w=90, code=pressKey(08)},
WIDGET.newKey{name="PC", x=500, y=640, w=90, font=50,code=pressKey(09)},
WIDGET.newKey{name="_1", x=800,y=540,w=90,font=50,code=pressKey(01)},
WIDGET.newKey{name="_2", x=900,y=540,w=90,font=50,code=pressKey(02)},
WIDGET.newKey{name="_3", x=800,y=640,w=90,font=50,code=pressKey(03)},
WIDGET.newKey{name="_4", x=900,y=640,w=90,font=50,code=pressKey(04)},
WIDGET.newKey{name="any1", x=100,y=640,w=90, code=pressKey(05)},
WIDGET.newKey{name="any2", x=200,y=640,w=90, code=pressKey(06)},
WIDGET.newKey{name="any3", x=300,y=640,w=90, code=pressKey(07)},
WIDGET.newKey{name="any4", x=400,y=640,w=90, code=pressKey(08)},
WIDGET.newKey{name="PC", x=500,y=640,w=90,font=50,code=pressKey(09)},
WIDGET.newKey{name="Z1", x=100, y=340, w=90, font=50,code=pressKey(11)},
WIDGET.newKey{name="S1", x=200, y=340, w=90, font=50,code=pressKey(21)},
WIDGET.newKey{name="J1", x=300, y=340, w=90, font=50,code=pressKey(31)},
WIDGET.newKey{name="L1", x=400, y=340, w=90, font=50,code=pressKey(41)},
WIDGET.newKey{name="T1", x=500, y=340, w=90, font=50,code=pressKey(51)},
WIDGET.newKey{name="O1", x=600, y=340, w=90, font=50,code=pressKey(61)},
WIDGET.newKey{name="I1", x=700, y=340, w=90, font=50,code=pressKey(71)},
WIDGET.newKey{name="Z1", x=100,y=340,w=90,font=50,code=pressKey(11)},
WIDGET.newKey{name="S1", x=200,y=340,w=90,font=50,code=pressKey(21)},
WIDGET.newKey{name="J1", x=300,y=340,w=90,font=50,code=pressKey(31)},
WIDGET.newKey{name="L1", x=400,y=340,w=90,font=50,code=pressKey(41)},
WIDGET.newKey{name="T1", x=500,y=340,w=90,font=50,code=pressKey(51)},
WIDGET.newKey{name="O1", x=600,y=340,w=90,font=50,code=pressKey(61)},
WIDGET.newKey{name="I1", x=700,y=340,w=90,font=50,code=pressKey(71)},
WIDGET.newKey{name="Z2", x=100, y=440, w=90, font=50,code=pressKey(12)},
WIDGET.newKey{name="S2", x=200, y=440, w=90, font=50,code=pressKey(22)},
WIDGET.newKey{name="J2", x=300, y=440, w=90, font=50,code=pressKey(32)},
WIDGET.newKey{name="L2", x=400, y=440, w=90, font=50,code=pressKey(42)},
WIDGET.newKey{name="T2", x=500, y=440, w=90, font=50,code=pressKey(52)},
WIDGET.newKey{name="O2", x=600, y=440, w=90, font=50,code=pressKey(62)},
WIDGET.newKey{name="I2", x=700, y=440, w=90, font=50,code=pressKey(72)},
WIDGET.newKey{name="Z2", x=100,y=440,w=90,font=50,code=pressKey(12)},
WIDGET.newKey{name="S2", x=200,y=440,w=90,font=50,code=pressKey(22)},
WIDGET.newKey{name="J2", x=300,y=440,w=90,font=50,code=pressKey(32)},
WIDGET.newKey{name="L2", x=400,y=440,w=90,font=50,code=pressKey(42)},
WIDGET.newKey{name="T2", x=500,y=440,w=90,font=50,code=pressKey(52)},
WIDGET.newKey{name="O2", x=600,y=440,w=90,font=50,code=pressKey(62)},
WIDGET.newKey{name="I2", x=700,y=440,w=90,font=50,code=pressKey(72)},
WIDGET.newKey{name="Z3", x=100, y=540, w=90, font=50,code=pressKey(13)},
WIDGET.newKey{name="S3", x=200, y=540, w=90, font=50,code=pressKey(23)},
WIDGET.newKey{name="J3", x=300, y=540, w=90, font=50,code=pressKey(33)},
WIDGET.newKey{name="L3", x=400, y=540, w=90, font=50,code=pressKey(43)},
WIDGET.newKey{name="T3", x=500, y=540, w=90, font=50,code=pressKey(53)},
WIDGET.newKey{name="O3", x=600, y=540, w=90, font=50,code=pressKey(63)},
WIDGET.newKey{name="I3", x=700, y=540, w=90, font=50,code=pressKey(73)},
WIDGET.newKey{name="Z3", x=100,y=540,w=90,font=50,code=pressKey(13)},
WIDGET.newKey{name="S3", x=200,y=540,w=90,font=50,code=pressKey(23)},
WIDGET.newKey{name="J3", x=300,y=540,w=90,font=50,code=pressKey(33)},
WIDGET.newKey{name="L3", x=400,y=540,w=90,font=50,code=pressKey(43)},
WIDGET.newKey{name="T3", x=500,y=540,w=90,font=50,code=pressKey(53)},
WIDGET.newKey{name="O3", x=600,y=540,w=90,font=50,code=pressKey(63)},
WIDGET.newKey{name="I3", x=700,y=540,w=90,font=50,code=pressKey(73)},
WIDGET.newKey{name="O4", x=600, y=640, w=90, font=50,code=pressKey(64)},
WIDGET.newKey{name="I4", x=700, y=640, w=90, font=50,code=pressKey(74)},
WIDGET.newKey{name="O4", x=600,y=640,w=90,font=50,code=pressKey(64)},
WIDGET.newKey{name="I4", x=700,y=640,w=90,font=50,code=pressKey(74)},
WIDGET.newKey{name="left", x=800, y=440, w=90, color="lG",font=55,code=pressKey"left"},
WIDGET.newKey{name="right", x=900, y=440, w=90, color="lG",font=55,code=pressKey"right"},
WIDGET.newKey{name="ten", x=1000, y=440, w=90, color="lG",font=40,code=pressKey"ten"},
WIDGET.newKey{name="backsp", x=1000, y=540, w=90, color="lY",font=50,code=pressKey"backspace"},
WIDGET.newKey{name="reset", x=1000, y=640, w=90, color="lY",font=50,code=pressKey"delete"},
WIDGET.newButton{name="copy", x=1140, y=440, w=170,h=80, color="lR",font=40,code=pressKey"cC",hide=function()return #MISSION==0 end},
WIDGET.newButton{name="paste", x=1140, y=540, w=170,h=80, color="lB",font=40,code=pressKey"cV"},
WIDGET.newSwitch{name="mission",x=1150, y=350, disp=CUSval("missionKill"),code=CUSrev("missionKill")},
WIDGET.newKey{name="left", x=800, y=440,w=90, color="lG",font=55,code=pressKey"left"},
WIDGET.newKey{name="right", x=900, y=440,w=90, color="lG",font=55,code=pressKey"right"},
WIDGET.newKey{name="ten", x=1000, y=440,w=90, color="lG",font=40,code=pressKey"ten"},
WIDGET.newKey{name="backsp", x=1000, y=540,w=90, color="lY",font=50,code=pressKey"backspace"},
WIDGET.newKey{name="reset", x=1000, y=640,w=90, color="lY",font=50,code=pressKey"delete"},
WIDGET.newButton{name="copy", x=1140, y=440,w=170,h=80, color="lR",font=40,code=pressKey"cC",hide=function()return #MISSION==0 end},
WIDGET.newButton{name="paste", x=1140, y=540,w=170,h=80, color="lB",font=40,code=pressKey"cV"},
WIDGET.newSwitch{name="mission",x=1150, y=350,disp=CUSval("missionKill"),code=CUSrev("missionKill")},
WIDGET.newButton{name="back", x=1140, y=640, w=170,h=80, font=40,code=backScene},
}

View File

@@ -87,14 +87,14 @@ function scene.keyDown(key)
end
elseif key=="c"and kb.isDown("lctrl","rctrl")or key=="cC"then
if #BAG>0 then
sys.setClipboardText("Techmino SEQ:"..copySequence())
sys.setClipboardText("Techmino SEQ:"..DATA.copySequence())
LOG.print(text.exportSuccess,COLOR.G)
end
elseif key=="v"and kb.isDown("lctrl","rctrl")or key=="cV"then
local str=sys.getClipboardText()
local p=string.find(str,":")--ptr*
if p then str=sub(str,p+1)end
if pasteSequence(str)then
if DATA.pasteSequence(str)then
LOG.print(text.importSuccess,COLOR.G)
cur=#BAG
else
@@ -185,11 +185,10 @@ function scene.draw()
end
scene.widgetList={
WIDGET.newText{name="title", x=520,y=5,font=70,align="R"},
WIDGET.newText{name="title",x=520,y=5,font=70,align="R"},
WIDGET.newText{name="subTitle",x=530,y=50,font=35,align="L",color="H"},
WIDGET.newSelector{name="sequence",
x=1080,y=60,w=200,color="Y",
WIDGET.newSelector{name="sequence",x=1080,y=60,w=200,color="Y",
list={"bag","his4","c2","rnd","mess","reverb","loop","fixed"},
disp=CUSval("sequence"),
code=CUSsto("sequence")

View File

@@ -5,10 +5,7 @@ local tc=love.touch
local sin=math.sin
local SCR=SCR
local VK=virtualkey
local onVirtualkey=onVirtualkey
local pressVirtualkey=pressVirtualkey
local updateVirtualkey=updateVirtualkey
local VK=VK
local noTouch,noKey=false,false
local touchMoveLastFrame=false
@@ -34,16 +31,16 @@ end
function scene.touchDown(x,y)
if noTouch then return end
local t=onVirtualkey(x,y)
local t=VK.on(x,y)
if t then
PLAYERS[1]:pressKey(t)
pressVirtualkey(t,x,y)
VK.touch(t,x,y)
end
end
function scene.touchUp(x,y)
if noTouch then return end
local t=onVirtualkey(x,y)
local t=VK.on(x,y)
if t then
PLAYERS[1]:releaseKey(t)
end
@@ -56,8 +53,9 @@ function scene.touchMove()
for i=#L,1,-1 do
L[2*i-1],L[2*i]=SCR.xOy:inverseTransformPoint(tc.getPosition(L[i]))
end
for n=1,#VK do
local B=VK[n]
local keys=VK.keys
for n=1,#keys do
local B=keys[n]
if B.ava then
for i=1,#L,2 do
if(L[i]-B.x)^2+(L[i+1]-B.y)^2<=B.r^2 then
@@ -75,8 +73,9 @@ function scene.keyDown(key)
if k>0 then
if noKey then return end
PLAYERS[1]:pressKey(k)
VK[k].isDown=true
VK[k].pressTime=10
local vk=VK.keys[k]
vk.isDown=true
vk.pressTime=10
else
restart()
end
@@ -90,7 +89,7 @@ function scene.keyUp(key)
if k then
if k>0 then
PLAYERS[1]:releaseKey(k)
VK[k].isDown=false
VK.release(k)
end
elseif key=="back"then
pauseGame()
@@ -102,8 +101,7 @@ function scene.gamepadDown(key)
if k then
if k>0 then
PLAYERS[1]:pressKey(k)
VK[k].isDown=true
VK[k].pressTime=10
VK.press(k)
else
restart()
end
@@ -117,7 +115,7 @@ function scene.gamepadUp(key)
if k then
if k>0 then
PLAYERS[1]:releaseKey(k)
VK[k].isDown=false
VK.release(k)
end
elseif key=="back"then
pauseGame()
@@ -138,10 +136,10 @@ function scene.update(dt)
if key==0 then--Just wait
elseif key<=32 then--Press key
P1:pressKey(key)
pressVirtualkey(key)
VK.press(key)
elseif key<=64 then--Release key
P1:releaseKey(key-32)
VK[key-32].isDown=false
VK.release(key-32)
end
_=_+2
end
@@ -149,7 +147,7 @@ function scene.update(dt)
end
touchMoveLastFrame=false
updateVirtualkey()
VK.update()
--Update players
for p=1,#PLAYERS do PLAYERS[p]:update(dt)end
@@ -183,7 +181,7 @@ function scene.draw()
end
--Virtual keys
drawVirtualkeys()
VK.draw()
--Attacking & Being attacked
if GAME.modeEnv.royaleMode then

View File

@@ -22,6 +22,8 @@ function scene.mouseDown(_,_,k)
else
SCN.go(SETTING.simpMode and"main_simple"or"main")
end
else
SCN.swapTo("quit","slowFade")
end
end
function scene.touchDown()
@@ -30,7 +32,7 @@ end
function scene.keyDown(key)
if key=="escape"then
VOC.play("bye")
SCN.back()
SCN.swapTo("quit","slowFade")
else
scene.mouseDown()
end

View File

@@ -32,7 +32,6 @@ function scene.sceneInit()
--Set quick-play-button text
scene.widgetList[2]:setObject(text.WidgetText.main.qplay..": "..text.modes[STAT.lastPlay][1])
quickSure=false
--Create demo player
destroyPlayers()
@@ -184,8 +183,8 @@ scene.widgetList={
WIDGET.newButton{name="dict", x=2480,y=450,w=800,h=100, color="lG",font=40,align="L",edge=30,code=pressKey"l"},
WIDGET.newButton{name="manual", x=2480,y=570,w=800,h=100, color="lC",font=40,align="L",edge=30,code=pressKey","},
WIDGET.newButton{name="music", x=160,y=80,w=200,h=90, color="lO",font=35,code=pressKey"2"},
WIDGET.newButton{name="lang", x=960,y=80,w=90,h=90, color="lY",font=40,code=pressKey"0",fText=DOGC{64,64,
WIDGET.newButton{name="music", x=130,y=80,w=200,h=90, color="lO",font=35,code=pressKey"2"},
WIDGET.newButton{name="lang", x=300,y=80,w=90,h=90, color="lN",font=40,code=pressKey"0",fText=DOGC{64,64,
{"setLW",4},
{"dCirc",32,32,30},
{"dLine",2,31,62,31},
@@ -194,7 +193,7 @@ scene.widgetList={
{"doArc",53,31,40,2.3,3.9},
}},
WIDGET.newButton{name="about", x=-110,y=670,w=600,h=70, color="lB",font=35,align="R",edge=30,code=pressKey"x"},
WIDGET.newButton{name="quit", x=1390,y=670,w=600,h=70, color="lR",font=40,align="L",edge=30,code=function()VOC.play("bye")SCN.swapTo("quit","slowFade")end},
WIDGET.newButton{name="back", x=1390,y=670,w=600,h=70, color="lR",font=40,align="L",edge=30,code=backScene},
}
return scene

View File

@@ -4,10 +4,7 @@ local tc=love.touch
local ins=table.insert
local SCR=SCR
local VK=virtualkey
local onVirtualkey=onVirtualkey
local pressVirtualkey=pressVirtualkey
local updateVirtualkey=updateVirtualkey
local VK=VK
local textBox=WIDGET.newTextBox{name="texts",x=340,y=80,w=600,h=550,hide=false}
@@ -38,16 +35,16 @@ scene.mouseDown=NULL
function scene.touchDown(x,y)
if noTouch or not playing then return end
local t=onVirtualkey(x,y)
local t=VK.on(x,y)
if t then
PLAYERS[1]:pressKey(t)
pressVirtualkey(t,x,y)
VK.touch(t,x,y)
end
end
function scene.touchUp(x,y)
if noTouch or not playing then return end
local t=onVirtualkey(x,y)
local t=VK.on(x,y)
if t then
PLAYERS[1]:releaseKey(t)
end
@@ -60,8 +57,9 @@ function scene.touchMove()
for i=#L,1,-1 do
L[2*i-1],L[2*i]=SCR.xOy:inverseTransformPoint(tc.getPosition(L[i]))
end
for n=1,#VK do
local B=VK[n]
local keys=VK.keys
for n=1,#keys do
local B=keys[n]
if B.ava then
for i=1,#L,2 do
if(L[i]-B.x)^2+(L[i+1]-B.y)^2<=B.r^2 then
@@ -88,8 +86,9 @@ function scene.keyDown(key)
local k=keyMap.keyboard[key]
if k and k>0 then
PLAYERS[1]:pressKey(k)
VK[k].isDown=true
VK[k].pressTime=10
local vk=VK.keys[k]
vk.isDown=true
vk.pressTime=10
end
elseif key=="space"then
NET.signal_ready(not PLY_NET[1].ready)
@@ -100,7 +99,7 @@ function scene.keyUp(key)
local k=keyMap.keyboard[key]
if k and k>0 then
PLAYERS[1]:releaseKey(k)
VK[k].isDown=false
VK.release(k)
end
end
function scene.gamepadDown(key)
@@ -116,8 +115,7 @@ function scene.gamepadDown(key)
local k=keyMap.joystick[key]
if k and k>0 then
PLAYERS[1]:pressKey(k)
VK[k].isDown=true
VK[k].pressTime=10
VK.press(k)
end
end
end
@@ -126,7 +124,7 @@ function scene.gamepadUp(key)
local k=keyMap.joystick[key]
if k and k>0 then
PLAYERS[1]:releaseKey(k)
VK[k].isDown=false
VK.release(k)
return
end
end
@@ -185,7 +183,7 @@ function scene.socketRead(cmd,d)
if P.uid==d.uid then
local res,stream=pcall(love.data.decode,"string","base64",d.stream)
if res then
pumpRecording(stream,P.stream)
DATA.pumpRecording(stream,P.stream)
else
LOG.print("Bad stream from "..P.username.."#"..P.uid)
end
@@ -203,7 +201,7 @@ function scene.update(dt)
local GAME=GAME
touchMoveLastFrame=false
updateVirtualkey()
VK.update()
--Update players
for p=1,#PLAYERS do PLAYERS[p]:update(dt)end
@@ -214,7 +212,7 @@ function scene.update(dt)
--Upload stream
if P1.frameRun-lastUpstreamTime>8 then
local stream
stream,upstreamProgress=dumpRecording(GAME.rep,upstreamProgress)
stream,upstreamProgress=DATA.dumpRecording(GAME.rep,upstreamProgress)
if #stream>0 then
NET.uploadRecStream(stream)
else
@@ -235,7 +233,7 @@ function scene.draw()
end
--Virtual keys
drawVirtualkeys()
VK.draw()
--Warning
drawWarning()
@@ -248,14 +246,17 @@ function scene.draw()
gc.setLineWidth(3)
gc.rectangle("line",40,67+50*i,800,42)
--Username
gc.setColor(1,1,1)
setFont(40)
gc.print(p.username,200,60+50*i)
--UID
setFont(40)
gc.setColor(.5,.5,.5)
gc.print("#"..p.uid,50,60+50*i)
--Avatar
gc.setColor(1,1,1)
gc.draw(USERS.getAvatar(p.uid),200,68+50*i,nil,.3125)
--Username
gc.print(p.username,240,60+50*i)
end
--Profile

View File

@@ -25,6 +25,7 @@ scene.widgetList={
NET.wsclose_play()
NET.wsclose_user()
USER.uid=false
USER.username=false
USER.authToken=false
FILE.save(USER,"conf/user","q")
SCN.back()
@@ -34,7 +35,7 @@ scene.widgetList={
lastLogoutTime=TIME()
end
end},
WIDGET.newButton{name="back", x=1140, y=640,w=170,h=80, font=40,code=backScene},
WIDGET.newButton{name="back", x=1140, y=640,w=170,h=80,font=40,code=backScene},
}
return scene

View File

@@ -143,8 +143,10 @@ function scene.keyDown(key)
SCN.swapTo("game","none")
end
elseif key=="o"then
if(GAME.result or GAME.replaying)and #PLAYERS==1 and not GAME.saved and saveRecording()then
GAME.saved=true
if(GAME.result or GAME.replaying)and #PLAYERS==1 and not GAME.saved then
if DATA.saveRecording()then
GAME.saved=true
end
end
else
WIDGET.keyPressed(key)

View File

@@ -51,8 +51,7 @@ end
function scene.touchUp()
if selected then
local B=VK_org[selected]
local k=snapUnit
B.x,B.y=int(B.x/k+.5)*k,int(B.y/k+.5)*k
B.x,B.y=int(B.x/snapUnit+.5)*snapUnit,int(B.y/snapUnit+.5)*snapUnit
end
end
function scene.touchMove(_,_,dx,dy)
@@ -62,41 +61,19 @@ function scene.touchMove(_,_,dx,dy)
end
end
local function virtualkeyPreview()
if SETTING.VKSwitch then
for i=1,#VK_org do
local B=VK_org[i]
if B.ava then
gc.setColor(1,1,1,SETTING.VKAlpha)
gc.setLineWidth(B.r*.07)
gc.circle("line",B.x,B.y,B.r,10)
if selected==i and TIME()%.26<.13 then
gc.setColor(1,1,1,SETTING.VKAlpha*.62)
gc.circle("fill",B.x,B.y,B.r,10)
end
if SETTING.VKIcon then
local c=B.color
gc.setColor(c[1],c[2],c[3],SETTING.VKAlpha)
gc.draw(TEXTURE.VKIcon[i],B.x,B.y,nil,B.r*.025,nil,18,18)
end
end
end
end
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)
virtualkeyPreview()
local d=snapUnit
if d>=10 then
VK.preview(selected)
if snapUnit>=10 then
gc.setLineWidth(3)
gc.setColor(1,1,1,sin(TIME()*4)*.1+.1)
for i=1,1280/d-1 do
gc.line(d*i,0,d*i,720)
for i=1,1280/snapUnit-1 do
gc.line(snapUnit*i,0,snapUnit*i,720)
end
for i=1,720/d-1 do
gc.line(0,d*i,1280,d*i)
for i=1,720/snapUnit-1 do
gc.line(0,snapUnit*i,1280,snapUnit*i)
end
end
end

View File

@@ -28,12 +28,12 @@ scene.widgetList={
WIDGET.newSwitch{name="b18", x=580, y=500, font=35,disp=VKAdisp(18),code=VKAcode(18)},
WIDGET.newSwitch{name="b19", x=580, y=560, font=35,disp=VKAdisp(19),code=VKAcode(19)},
WIDGET.newSwitch{name="b20", x=580, y=620, font=35,disp=VKAdisp(20),code=VKAcode(20)},
WIDGET.newButton{name="norm", x=840, y=100, w=240,h=80, font=35,code=function()for i=1,20 do VK_org[i].ava=i<11 end end},
WIDGET.newButton{name="pro", x=1120, y=100, w=240,h=80, font=35,code=function()for i=1,20 do VK_org[i].ava=true end end},
WIDGET.newSwitch{name="hide", x=1170, y=200, font=40,disp=SETval("VKSwitch"),code=SETrev("VKSwitch")},
WIDGET.newSwitch{name="track", x=1170, y=300, font=35,disp=SETval("VKTrack"),code=SETrev("VKTrack")},
WIDGET.newSlider{name="sfx", x=800, y=380, w=180, font=35,change=function()SFX.play("virtualKey",SETTING.VKSFX)end,disp=SETval("VKSFX"),code=SETsto("VKSFX")},
WIDGET.newSlider{name="vib", x=800, y=460, w=180,unit=2, font=35,change=function()VIB(SETTING.VKVIB)end,disp=SETval("VKVIB"),code=SETsto("VKVIB")},
WIDGET.newButton{name="norm", x=840, y=100, w=240,h=80, font=35,code=function()for i=1,20 do VK_org[i].ava=i<11 end end},
WIDGET.newButton{name="pro", x=1120, y=100, w=240,h=80, font=35,code=function()for i=1,20 do VK_org[i].ava=true end end},
WIDGET.newSwitch{name="hide", x=1170, y=200, font=40,disp=SETval("VKSwitch"),code=SETrev("VKSwitch")},
WIDGET.newSwitch{name="track", x=1170, y=300, font=35,disp=SETval("VKTrack"),code=SETrev("VKTrack")},
WIDGET.newSlider{name="sfx", x=800, y=380, w=180, font=35,change=function()SFX.play("virtualKey",SETTING.VKSFX)end,disp=SETval("VKSFX"),code=SETsto("VKSFX")},
WIDGET.newSlider{name="vib", x=800, y=460, w=180,unit=2,font=35,change=function()VIB(SETTING.VKVIB)end,disp=SETval("VKVIB"),code=SETsto("VKVIB")},
WIDGET.newSwitch{name="icon", x=850, y=300, font=40,disp=SETval("VKIcon"),code=SETrev("VKIcon")},
WIDGET.newButton{name="tkset", x=1120, y=420, w=240,h=80,
code=function()

View File

@@ -13,10 +13,10 @@ 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=290, y=165, disp=SETval("block"), code=SETrev("block")},
WIDGET.newSwitch{name="smooth", x=290, y=215, disp=SETval("smooth"), code=SETrev("smooth")},
WIDGET.newSwitch{name="upEdge", x=290, y=265, disp=SETval("upEdge"), code=SETrev("upEdge")},
WIDGET.newSwitch{name="bagLine", x=290, y=315, disp=SETval("bagLine"), code=SETrev("bagLine")},
WIDGET.newSwitch{name="block", x=290, y=165,disp=SETval("block"),code=SETrev("block")},
WIDGET.newSwitch{name="smooth", x=290, y=215,disp=SETval("smooth"),code=SETrev("smooth")},
WIDGET.newSwitch{name="upEdge", x=290, y=265,disp=SETval("upEdge"),code=SETrev("upEdge")},
WIDGET.newSwitch{name="bagLine", x=290, y=315,disp=SETval("bagLine"),code=SETrev("bagLine")},
WIDGET.newSlider{name="ghost", x=600, y=180,w=200,unit=.6,disp=SETval("ghost"),show="percent",code=SETsto("ghost")},
WIDGET.newSlider{name="grid", x=600, y=240,w=200,unit=.4,disp=SETval("grid"),show="percent", code=SETsto("grid")},
@@ -37,14 +37,14 @@ scene.widgetList={
SETTING.frameMul=i<5 and 5*i+20 or 10*i
end},
WIDGET.newSwitch{name="text", x=1140, y=160,font=35,disp=SETval("text"), code=SETrev("text")},
WIDGET.newSwitch{name="score", x=1140, y=210,font=35,disp=SETval("score"), code=SETrev("score")},
WIDGET.newSwitch{name="warn", x=1140, y=260,font=35,disp=SETval("warn"), code=SETrev("warn")},
WIDGET.newSwitch{name="highCam", x=1140, y=310,font=35,disp=SETval("highCam"),code=SETrev("highCam")},
WIDGET.newSwitch{name="nextPos", x=1140, y=360,font=35,disp=SETval("nextPos"),code=SETrev("nextPos")},
WIDGET.newSwitch{name="fullscreen", x=1140, y=410,disp=SETval("fullscreen"), code=switchFullscreen},
WIDGET.newSwitch{name="power", x=1140, y=460,font=35,disp=SETval("powerInfo"),code=SETrev("powerInfo")},
WIDGET.newSwitch{name="clickFX", x=1140, y=510,font=35,disp=SETval("clickFX"),code=SETrev("clickFX")},
WIDGET.newSwitch{name="text", x=1140, y=160,font=35,disp=SETval("text"), code=SETrev("text")},
WIDGET.newSwitch{name="score", x=1140, y=210,font=35,disp=SETval("score"), code=SETrev("score")},
WIDGET.newSwitch{name="warn", x=1140, y=260,font=35,disp=SETval("warn"), code=SETrev("warn")},
WIDGET.newSwitch{name="highCam", x=1140, y=310,font=35,disp=SETval("highCam"), code=SETrev("highCam")},
WIDGET.newSwitch{name="nextPos", x=1140, y=360,font=35,disp=SETval("nextPos"), code=SETrev("nextPos")},
WIDGET.newSwitch{name="fullscreen", x=1140, y=410,disp=SETval("fullscreen"), code=switchFullscreen},
WIDGET.newSwitch{name="power", x=1140, y=460,font=35,disp=SETval("powerInfo"), code=SETrev("powerInfo")},
WIDGET.newSwitch{name="clickFX", x=1140, y=510,font=35,disp=SETval("clickFX"), code=SETrev("clickFX")},
WIDGET.newSwitch{name="bg", x=1140, y=560,font=35,disp=SETval("bg"),
code=function()
BG.set("none")

View File

@@ -34,6 +34,7 @@ function SKIN.init(list)
I=gc.newImage("media/image/skin/"..list[1]..".png")
LOG.print("No skin file: "..list[i],"warn")
end
gc.setDefaultFilter("linear","linear")
for y=0,2 do
for x=1,8 do
SKIN.lib[i][8*y+x]=C(30,30)

View File

@@ -1,4 +1,6 @@
local gc=love.graphics
local ins=table.insert
local function NSC(x,y)--New & Set Canvas
local _=gc.newCanvas(x,y)
gc.setCanvas(_)
@@ -84,6 +86,21 @@ gc.setColor(1,1,1)
gc.circle("line",8,8,7)
gc.circle("fill",8,8,3)
TEXTURE.lvIcon=setmetatable({},{__index=function(self,lv)
local img={25,25}
ins(img,{"clear",0,0,0})
ins(img,{"setLW",4})
ins(img,{"setCL",COLOR.lN})
ins(img,{"dRect",2,2,21,21})
--TODO: draw with lv
img=DOGC(img)
rawset(self,lv,img)
return img
end})
gc.setDefaultFilter("linear","linear")

View File

@@ -33,14 +33,13 @@ return STRING.split([=[
改动:
微调TRS中PQT5J5L5的踢墙表
加强消四,增加b2b点数(100→150)
增强hpc攻击力(2→4)
修改pc和hpc对b2b点数的影响
增强hpc攻击力(2→4),修改pc和hpc对b2b点数的影响
自定义游戏设置会自动保存,默认设置为无重力科研
调低竞速模式部分评价要求,科研模式通关条件改为100攻击(原200)
调整master-ph命数奖励
对战背景改为主题默认背景
主菜单语言按钮改为地球图标
修改硬降音效
主菜单语言按钮改为地球图标,移到左上角
词典修改部分词条,调整词条顺序(意见来自群友 库德里尔)
移除词典中两个不必要的个人词条
词典支持左右键翻页,添加触屏可用的翻页按钮
@@ -52,6 +51,7 @@ return STRING.split([=[
新增users模块用来管理网络用户缓存信息
play场景改名game
重构GAME.frame相关内容
大规模整理代码
修复:
登录界面邮箱格式判定错误
调整主菜单点击联网游戏按钮代码的逻辑

View File

@@ -12,26 +12,26 @@ local function loadAvatar(path)
return canvas
end
local texture_noImage=DOGC{120,120,
{"setCL",0,0,0},
{"fRect",0,0,120,120},
local emptyUser={
username="Player",
motto="",
hash="",
new=true,
}
local texture_noImage=DOGC{128,128,
{"setCL",.1,.1,.1},
{"fRect",0,0,128,128},
{"setCL",1,1,1},
{"setLW",6},
{"dLine",9,9,110,110},
{"dLine",9,110,110,9},
{"dLine",9,9,118,118},
{"dLine",9,118,118,9},
}
local db_img={}
local db=setmetatable({},{__index=function(self,k)
if not k then return emptyUser end
local file="cache/user"..k..".dat"
local d=
fs.getInfo(file)and JSON.decode(fs.read(file))or
{
username="[X]",
motto="Techmino haowan",
hash="",
new=false,
}
local d=fs.getInfo(file)and JSON.decode(fs.read(file))or TABLE.copy(emptyUser)
rawset(self,k,d)
if type(d.hash)=="string"and #d.hash>0 and fs.getInfo("cache/"..d.hash)then
db_img[k]=loadAvatar("cache/"..d.hash)
@@ -54,7 +54,6 @@ function USERS.updateUserData(data)
fs.write("cache/"..data.hash,love.data.decode("string","base64",data.avatar:sub(data.avatar:find","+1)))
db_img[uid]=loadAvatar("cache/"..data.hash)
db[uid].hash=type(data.hash)=="string"and #data.hash>0 and data.hash
db[uid].new=true
end
end

174
parts/virtualKey.lua Normal file
View File

@@ -0,0 +1,174 @@
local SETTING=SETTING
local keys={}
for i=1,#VK_org do keys[i]={}end--In-game virtualkey layout
local VK={}
VK.keys=keys
function VK.on(x,y)
local dist,nearest=1e10
for K=1,#keys do
local B=keys[K]
if B.ava then
local d1=(x-B.x)^2+(y-B.y)^2
if d1<B.r^2 then
if d1<dist then
nearest,dist=K,d1
end
end
end
end
return nearest
end
function VK.touch(id,x,y)
local B=keys[id]
B.isDown=true
B.pressTime=10
if SETTING.VKTrack then
--Auto follow
local O=VK_org[id]
local _FW,_CW=SETTING.VKTchW,1-SETTING.VKCurW
local _OW=1-_FW-_CW
--(finger+current+origin)
B.x=x*_FW+B.x*_CW+O.x*_OW
B.y=y*_FW+B.y*_CW+O.y*_OW
--Button collision (not accurate)
if SETTING.VKDodge then
for i=1,#keys do
local b=keys[i]
local d=B.r+b.r-((B.x-b.x)^2+(B.y-b.y)^2)^.5--Hit depth(Neg means distance)
if d>0 then
b.x=b.x+(b.x-B.x)*d*b.r*2.6e-5
b.y=b.y+(b.y-B.y)*d*b.r*2.6e-5
end
end
end
end
SFX.play("virtualKey",SETTING.VKSFX)
VIB(SETTING.VKVIB)
end
function VK.press(id)
keys[id].isDown=true
keys[id].pressTime=10
end
function VK.release(id)
keys[id].isDown=false
end
function VK.switchKey(id,on)
keys[id].ava=on
end
function VK.restore()
for i=1,#VK_org do
local B,O=keys[i],VK_org[i]
B.ava=O.ava
B.x=O.x
B.y=O.y
B.r=O.r
B.color=O.color
B.isDown=false
B.pressTime=0
end
for k,v in next,PLAYERS[1].keyAvailable do
if not v then
keys[k].ava=false
end
end
end
function VK.update()
if SETTING.VKSwitch then
for i=1,#keys do
local _=keys[i]
if _.pressTime>0 then
_.pressTime=_.pressTime-1
end
end
end
end
local gc=love.graphics
local gc_circle,gc_draw,gc_setColor,gc_setLineWidth=gc.circle,gc.draw,gc.setColor,gc.setLineWidth
function VK.draw()
if SETTING.VKSwitch then
local a=SETTING.VKAlpha
local _
if SETTING.VKIcon then
local icons=TEXTURE.VKIcon
for i=1,#keys do
if keys[i].ava then
local B=keys[i]
--Button outline
gc_setColor(1,1,1,a)
gc_setLineWidth(B.r*.07)
gc_circle("line",B.x,B.y,B.r,10)
--Icon
_=keys[i].pressTime
local c=B.color
gc_setColor(c[1],c[2],c[3],a)
gc_draw(icons[i],B.x,B.y,nil,B.r*.026+_*.08,nil,18,18)
--Ripple
if _>0 then
gc_setColor(1,1,1,a*_*.08)
gc_circle("line",B.x,B.y,B.r*(1.4-_*.04),10)
end
--Glow when press
if B.isDown then
gc_setColor(1,1,1,a*.4)
gc_circle("fill",B.x,B.y,B.r*.94,10)
end
end
end
else
for i=1,#keys do
if keys[i].ava then
local B=keys[i]
gc_setColor(1,1,1,a)
gc_setLineWidth(B.r*.07)
gc_circle("line",B.x,B.y,B.r,10)
_=keys[i].pressTime
if _>0 then
gc_setColor(1,1,1,a*_*.08)
gc_circle("fill",B.x,B.y,B.r*.94,10)
gc_circle("line",B.x,B.y,B.r*(1.4-_*.04),10)
end
end
end
end
end
end
function VK.preview(selected)
if SETTING.VKSwitch then
for i=1,#VK_org do
local B=VK_org[i]
if B.ava then
gc_setColor(1,1,1,SETTING.VKAlpha)
gc_setLineWidth(B.r*.07)
gc_circle("line",B.x,B.y,B.r,10)
if selected==i and TIME()%.26<.13 then
gc_setColor(1,1,1,SETTING.VKAlpha*.62)
gc_circle("fill",B.x,B.y,B.r,10)
end
if SETTING.VKIcon then
local c=B.color
gc_setColor(c[1],c[2],c[3],SETTING.VKAlpha)
gc_draw(TEXTURE.VKIcon[i],B.x,B.y,nil,B.r*.025,nil,18,18)
end
end
end
end
end
return VK