代码规范:把所有的tab换成空格

This commit is contained in:
MrZ626
2021-08-25 04:28:52 +08:00
parent 8f910f95f4
commit 295e79984f
271 changed files with 35384 additions and 35379 deletions

View File

@@ -1,25 +1,25 @@
if arg[1]=="-code"then
print(require"version".apkCode)
print(require"version".apkCode)
elseif arg[1]=="-name"then
print((require"version".string:gsub("@DEV","")))
print((require"version".string:gsub("@DEV","")))
elseif arg[1]=="-release"then
print((require"version".string:gsub("V","")))
print((require"version".string:gsub("V","")))
elseif arg[1]=="-updateTitle"then
local note=require"parts.updateLog"
local p1=note:find("\n%d")+1
local p2=note:find("\n",p1)-1
note=note:sub(p1,p2)
print(note)
local note=require"parts.updateLog"
local p1=note:find("\n%d")+1
local p2=note:find("\n",p1)-1
note=note:sub(p1,p2)
print(note)
elseif arg[1]=="-updateNote"then
local note=require"parts.updateLog"
local p1=note:find("\n",note:find("\n%d")+1)+1
local p2=note:find("\n%d",p1+1)
note=note:sub(p1,p2-2)
note=note
:gsub("\t\t\t\t","_")
:gsub("\t\t","")
:gsub("\n([^_])","\n\n%1")
:gsub("\n_","\n")
:gsub("\n\n","\n",1)
print(note)
local note=require"parts.updateLog"
local p1=note:find("\n",note:find("\n%d")+1)+1
local p2=note:find("\n%d",p1+1)
note=note:sub(p1,p2-2)
note=note
:gsub("\t\t\t\t","_")
:gsub("\t\t","")
:gsub("\n([^_])","\n\n%1")
:gsub("\n_","\n")
:gsub("\n\n","\n",1)
print(note)
end

146
LICENSE
View File

@@ -6,149 +6,149 @@ Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
5. Combined Libraries.
You may place library facilities that are a work based on the
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
@@ -158,7 +158,7 @@ received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the

View File

@@ -1,50 +1,50 @@
local gc_clear=love.graphics.clear
local BGs={
none={draw=function()gc_clear(.08,.08,.084)end}
none={draw=function()gc_clear(.08,.08,.084)end}
}
local BGlist={'none'}
local BG={
cur='none',
default='none',
init=false,
resize=false,
update=NULL,
draw=BGs.none.draw,
event=false,
discard=NULL,
cur='none',
default='none',
init=false,
resize=false,
update=NULL,
draw=BGs.none.draw,
event=false,
discard=NULL,
}
function BG.add(name,bg)
BGs[name]=bg
BGlist[#BGlist+1]=name
BGs[name]=bg
BGlist[#BGlist+1]=name
end
function BG.getList()
return BGlist
return BGlist
end
function BG.send(...)
if BG.event then
BG.event(...)
end
if BG.event then
BG.event(...)
end
end
function BG.setDefault(bg)
BG.default=bg
BG.default=bg
end
function BG.set(background)
if not background then background=BG.default end
if not BGs[background]or not SETTING.bg then return end
if background~=BG.cur then
BG.discard()
BG.cur=background
background=BGs[background]
if not background then background=BG.default end
if not BGs[background]or not SETTING.bg then return end
if background~=BG.cur then
BG.discard()
BG.cur=background
background=BGs[background]
BG.init= background.init or NULL
BG.resize= background.resize or NULL
BG.update= background.update or NULL
BG.draw= background.draw or NULL
BG.event= background.event or NULL
BG.discard= background.discard or NULL
BG.init()
end
return true
BG.init= background.init or NULL
BG.resize= background.resize or NULL
BG.update= background.update or NULL
BG.draw= background.draw or NULL
BG.event= background.event or NULL
BG.discard=background.discard or NULL
BG.init()
end
return true
end
return BG

View File

@@ -1,109 +1,109 @@
local BGM={
default=false,
getList=function()error("Cannot getList before initialize!")end,
getCount=function()return 0 end,
play=NULL,
freshVolume=NULL,
stop=NULL,
--nowPlay=[str:playing ID]
--playing=[src:playing SRC]
default=false,
getList=function()error("Cannot getList before initialize!")end,
getCount=function()return 0 end,
play=NULL,
freshVolume=NULL,
stop=NULL,
--nowPlay=[str:playing ID]
--playing=[src:playing SRC]
}
function BGM.setDefault(bgm)
BGM.default=bgm
BGM.default=bgm
end
function BGM.init(list)
BGM.init=nil
local Sources={}
BGM.init=nil
local Sources={}
local simpList={}
for _,v in next,list do
table.insert(simpList,v.name)
Sources[v.name]=v.path
end
table.sort(simpList)
function BGM.getList()return simpList end
local count=#simpList
function BGM.getCount()return count end
local simpList={}
for _,v in next,list do
table.insert(simpList,v.name)
Sources[v.name]=v.path
end
table.sort(simpList)
function BGM.getList()return simpList end
local count=#simpList
function BGM.getCount()return count end
local function _load(name)
if type(Sources[name])=='string'then
if love.filesystem.getInfo(Sources[name])then
Sources[name]=love.audio.newSource(Sources[name],'stream')
Sources[name]:setLooping(true)
Sources[name]:setVolume(0)
return true
else
MES.new('warn',"No BGM file: "..Sources[name],5)
end
elseif Sources[name]then
return true
elseif name then
MES.new('warn',"No BGM: "..name,5)
end
end
function BGM.loadAll()for name in next,Sources do _load(name)end end
local function task_fadeOut(src)
while true do
coroutine.yield()
local v=src:getVolume()-.025*SETTING.bgm
src:setVolume(v>0 and v or 0)
if v<=0 then
src:stop()
return true
end
end
end
local function task_fadeIn(src)
while true do
coroutine.yield()
local v=SETTING.bgm
v=math.min(v,src:getVolume()+.025*v)
src:setVolume(v)
if v>=SETTING.bgm then
return true
end
end
end
local function check_curFadeOut(task,code,src)
return task.code==code and task.args[1]==src
end
function BGM.play(name)
if not name then name=BGM.default end
if not _load(name)then return end
if SETTING.bgm==0 then
BGM.nowPlay=name
BGM.playing=Sources[name]
return true
end
if name and Sources[name]then
if BGM.nowPlay~=name then
if BGM.nowPlay then TASK.new(task_fadeOut,BGM.playing)end
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,Sources[name])
TASK.removeTask_code(task_fadeIn)
local function _load(name)
if type(Sources[name])=='string'then
if love.filesystem.getInfo(Sources[name])then
Sources[name]=love.audio.newSource(Sources[name],'stream')
Sources[name]:setLooping(true)
Sources[name]:setVolume(0)
return true
else
MES.new('warn',"No BGM file: "..Sources[name],5)
end
elseif Sources[name]then
return true
elseif name then
MES.new('warn',"No BGM: "..name,5)
end
end
function BGM.loadAll()for name in next,Sources do _load(name)end end
local function task_fadeOut(src)
while true do
coroutine.yield()
local v=src:getVolume()-.025*SETTING.bgm
src:setVolume(v>0 and v or 0)
if v<=0 then
src:stop()
return true
end
end
end
local function task_fadeIn(src)
while true do
coroutine.yield()
local v=SETTING.bgm
v=math.min(v,src:getVolume()+.025*v)
src:setVolume(v)
if v>=SETTING.bgm then
return true
end
end
end
local function check_curFadeOut(task,code,src)
return task.code==code and task.args[1]==src
end
function BGM.play(name)
if not name then name=BGM.default end
if not _load(name)then return end
if SETTING.bgm==0 then
BGM.nowPlay=name
BGM.playing=Sources[name]
return true
end
if name and Sources[name]then
if BGM.nowPlay~=name then
if BGM.nowPlay then TASK.new(task_fadeOut,BGM.playing)end
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,Sources[name])
TASK.removeTask_code(task_fadeIn)
TASK.new(task_fadeIn,Sources[name])
BGM.nowPlay=name
BGM.playing=Sources[name]
BGM.playing:play()
end
return true
end
end
function BGM.freshVolume()
if BGM.playing then
local v=SETTING.bgm
if v>0 then
BGM.playing:setVolume(v)
BGM.playing:play()
elseif BGM.nowPlay then
BGM.playing:pause()
end
end
end
function BGM.stop()
TASK.removeTask_code(task_fadeIn)
if BGM.nowPlay then TASK.new(task_fadeOut,BGM.playing)end
BGM.nowPlay,BGM.playing=nil
end
TASK.new(task_fadeIn,Sources[name])
BGM.nowPlay=name
BGM.playing=Sources[name]
BGM.playing:play()
end
return true
end
end
function BGM.freshVolume()
if BGM.playing then
local v=SETTING.bgm
if v>0 then
BGM.playing:setVolume(v)
BGM.playing:play()
elseif BGM.nowPlay then
BGM.playing:pause()
end
end
end
function BGM.stop()
TASK.removeTask_code(task_fadeIn)
if BGM.nowPlay then TASK.new(task_fadeOut,BGM.playing)end
BGM.nowPlay,BGM.playing=nil
end
end
return BGM

View File

@@ -1,126 +1,126 @@
local COLOR={
red= {.92, .12, .12},
fire= {.92, 0.4, .12},
orange= {.92, 0.6, .12},
yellow= {.92, .92, .12},
lime= {0.7, .92, .12},
jade= {0.5, .92, .12},
green= {.12, .92, .12},
aqua= {.12, .92, 0.6},
cyan= {.12, .92, .92},
navy= {.12, 0.7, .92},
sea= {.12, 0.4, .92},
blue= {0.2, 0.2, .92},
violet= {0.4, .12, .92},
purple= {0.7, .12, .92},
magenta= {.92, .12, .92},
wine= {.92, .12, 0.5},
red= {.92, .12, .12},
fire= {.92, 0.4, .12},
orange= {.92, 0.6, .12},
yellow= {.92, .92, .12},
lime= {0.7, .92, .12},
jade= {0.5, .92, .12},
green= {.12, .92, .12},
aqua= {.12, .92, 0.6},
cyan= {.12, .92, .92},
navy= {.12, 0.7, .92},
sea= {.12, 0.4, .92},
blue= {0.2, 0.2, .92},
violet= {0.4, .12, .92},
purple= {0.7, .12, .92},
magenta= {.92, .12, .92},
wine= {.92, .12, 0.5},
lRed= {.95, 0.5, 0.5},
lFire= {.95, 0.7, 0.5},
lOrange= {.95, 0.8, 0.3},
lYellow= {.95, .95, 0.5},
lLime= {0.8, .95, 0.4},
lJade= {0.6, .95, 0.4},
lGreen= {0.5, .95, 0.5},
lAqua= {0.4, .95, 0.7},
lCyan= {0.5, .95, .95},
lNavy= {0.4, .85, .95},
lSea= {0.5, 0.7, .95},
lBlue= {0.7, 0.7, .95},
lViolet= {0.7, 0.4, .95},
lPurple= {0.8, 0.4, .95},
lMagenta= {.95, 0.5, .95},
lWine= {.95, 0.4, 0.7},
lRed= {.95, 0.5, 0.5},
lFire= {.95, 0.7, 0.5},
lOrange= {.95, 0.8, 0.3},
lYellow= {.95, .95, 0.5},
lLime= {0.8, .95, 0.4},
lJade= {0.6, .95, 0.4},
lGreen= {0.5, .95, 0.5},
lAqua= {0.4, .95, 0.7},
lCyan= {0.5, .95, .95},
lNavy= {0.4, .85, .95},
lSea= {0.5, 0.7, .95},
lBlue= {0.7, 0.7, .95},
lViolet= {0.7, 0.4, .95},
lPurple= {0.8, 0.4, .95},
lMagenta={.95, 0.5, .95},
lWine= {.95, 0.4, 0.7},
dRed= {0.6, .08, .08},
dFire= {0.6, 0.3, .08},
dOrange= {0.6, 0.4, .08},
dYellow= {0.6, 0.6, .08},
dLime= {0.5, 0.6, .08},
dJade= {0.3, 0.6, .08},
dGreen= {.08, 0.6, .08},
dAqua= {.08, 0.6, 0.4},
dCyan= {.08, 0.6, 0.6},
dNavy= {.08, 0.4, 0.6},
dSea= {.08, 0.2, 0.6},
dBlue= {0.1, 0.1, 0.6},
dViolet= {0.2, .08, 0.6},
dPurple= {0.4, .08, 0.6},
dMagenta= {0.6, .08, 0.6},
dWine= {0.6, .08, 0.3},
dRed= {0.6, .08, .08},
dFire= {0.6, 0.3, .08},
dOrange= {0.6, 0.4, .08},
dYellow= {0.6, 0.6, .08},
dLime= {0.5, 0.6, .08},
dJade= {0.3, 0.6, .08},
dGreen= {.08, 0.6, .08},
dAqua= {.08, 0.6, 0.4},
dCyan= {.08, 0.6, 0.6},
dNavy= {.08, 0.4, 0.6},
dSea= {.08, 0.2, 0.6},
dBlue= {0.1, 0.1, 0.6},
dViolet= {0.2, .08, 0.6},
dPurple= {0.4, .08, 0.6},
dMagenta={0.6, .08, 0.6},
dWine= {0.6, .08, 0.3},
black= {.05, .05, .05},
dGray= {0.3, 0.3, 0.3},
gray= {0.6, 0.6, 0.6},
lGray= {0.8, 0.8, 0.8},
white= {.97, .97, .97},
black= {.05, .05, .05},
dGray= {0.3, 0.3, 0.3},
gray= {0.6, 0.6, 0.6},
lGray= {0.8, 0.8, 0.8},
white= {.97, .97, .97},
}
for k,v in next,{
R='red',F='fire',O='orange',Y='yellow',L='lime',J='jade',G='green',A='aqua',C='cyan',N='navy',S='sea',B='blue',V='violet',P='purple',M='magenta',W='wine',
lR='lRed',lF='lFire',lO='lOrange',lY='lYellow',lL='lLime',lJ='lJade',lG='lGreen',lA='lAqua',lC='lCyan',lN='lNavy',lS='lSea',lB='lBlue',lV='lViolet',lP='lPurple',lM='lMagenta',lW='lWine',
dR='dRed',dF='dFire',dO='dOrange',dY='dYellow',dL='dLime',dJ='dJade',dG='dGreen',dA='dAqua',dC='dCyan',dN='dNavy',dS='dSea',dB='dBlue',dV='dViolet',dP='dPurple',dM='dMagenta',dW='dWine',
D='black',dH='dGray',H='gray',lH='lGray',Z='white',
--Remain letter: EIKQTUX
R='red', F='fire', O='orange', Y='yellow', L='lime', J='jade', G='green', A='aqua', C='cyan', N='navy', S='sea', B='blue', V='violet', P='purple', M='magenta', W='wine',
lR='lRed',lF='lFire',lO='lOrange',lY='lYellow',lL='lLime',lJ='lJade',lG='lGreen',lA='lAqua',lC='lCyan',lN='lNavy',lS='lSea',lB='lBlue',lV='lViolet',lP='lPurple',lM='lMagenta',lW='lWine',
dR='dRed',dF='dFire',dO='dOrange',dY='dYellow',dL='dLime',dJ='dJade',dG='dGreen',dA='dAqua',dC='dCyan',dN='dNavy',dS='dSea',dB='dBlue',dV='dViolet',dP='dPurple',dM='dMagenta',dW='dWine',
D='black',dH='dGray',H='gray',lH='lGray',Z='white',
--Remain letter: EIKQTUX
}do
COLOR[k]=COLOR[v]
COLOR[k]=COLOR[v]
end
setmetatable(COLOR,{__index=function(_,k)
error("No color: "..tostring(k))
error("No color: "..tostring(k))
end})
do--Random generators
local rnd=math.random
local list_norm={'red','fire','orange','yellow','lime','jade','green','aqua','cyan','navy','sea','blue','violet','purple','magenta','wine'}
local len_list_norm=#list_norm
function COLOR.random_norm()
return COLOR[list_norm[rnd(len_list_norm)]]
end
local rnd=math.random
local list_norm={'red','fire','orange','yellow','lime','jade','green','aqua','cyan','navy','sea','blue','violet','purple','magenta','wine'}
local len_list_norm=#list_norm
function COLOR.random_norm()
return COLOR[list_norm[rnd(len_list_norm)]]
end
local list_bright={'lRed','lFire','lOrange','lYellow','lLime','lJade','lGreen','lAqua','lCyan','lNavy','lSea','lBlue','lViolet','lPurple','lMagenta','lWine'}
local len_list_bright=#list_bright
function COLOR.random_bright()
return COLOR[list_bright[rnd(len_list_bright)]]
end
local list_bright={'lRed','lFire','lOrange','lYellow','lLime','lJade','lGreen','lAqua','lCyan','lNavy','lSea','lBlue','lViolet','lPurple','lMagenta','lWine'}
local len_list_bright=#list_bright
function COLOR.random_bright()
return COLOR[list_bright[rnd(len_list_bright)]]
end
local list_dark={'dRed','dFire','dOrange','dYellow','dLime','dJade','dGreen','dAqua','dCyan','dNavy','dSea','dBlue','dViolet','dPurple','dMagenta','dWine'}
local len_list_dark=#list_dark
function COLOR.random_dark()
return COLOR[list_dark[rnd(len_list_dark)]]
end
local list_dark={'dRed','dFire','dOrange','dYellow','dLime','dJade','dGreen','dAqua','dCyan','dNavy','dSea','dBlue','dViolet','dPurple','dMagenta','dWine'}
local len_list_dark=#list_dark
function COLOR.random_dark()
return COLOR[list_dark[rnd(len_list_dark)]]
end
end
do--Rainbow generators
local sin=math.sin
function COLOR.rainbow(phase,a)
return
sin(phase)*.4+.6,
sin(phase+2.0944)*.4+.6,
sin(phase-2.0944)*.4+.6,
a
end
function COLOR.rainbow_light(phase,a)
return
sin(phase)*.2+.7,
sin(phase+2.0944)*.2+.7,
sin(phase-2.0944)*.2+.7,
a
end
function COLOR.rainbow_dark(phase,a)
return
sin(phase)*.2+.4,
sin(phase+2.0944)*.2+.4,
sin(phase-2.0944)*.2+.4,
a
end
function COLOR.rainbow_gray(phase,a)
return
sin(phase)*.16+.5,
sin(phase+2.0944)*.16+.5,
sin(phase-2.0944)*.16+.5,
a
end
local sin=math.sin
function COLOR.rainbow(phase,a)
return
sin(phase)*.4+.6,
sin(phase+2.0944)*.4+.6,
sin(phase-2.0944)*.4+.6,
a
end
function COLOR.rainbow_light(phase,a)
return
sin(phase)*.2+.7,
sin(phase+2.0944)*.2+.7,
sin(phase-2.0944)*.2+.7,
a
end
function COLOR.rainbow_dark(phase,a)
return
sin(phase)*.2+.4,
sin(phase+2.0944)*.2+.4,
sin(phase-2.0944)*.2+.4,
a
end
function COLOR.rainbow_gray(phase,a)
return
sin(phase)*.16+.5,
sin(phase+2.0944)*.16+.5,
sin(phase-2.0944)*.16+.5,
a
end
end
return COLOR

View File

@@ -1,90 +1,90 @@
local fs=love.filesystem
local FILE={}
function FILE.load(name)
if fs.getInfo(name)then
local F=fs.newFile(name)
if F:open'r'then
local s=F:read()
F:close()
if s:sub(1,6)=="return"then
s=loadstring(s)
if s then
setfenv(s,{})
return s()
end
elseif s:sub(1,1)=="["or s:sub(1,1)=="{"then
local res=JSON.decode(s)
if res then
return res
end
else
return s
end
end
MES.new('error',name.." "..text.loadError)
end
if fs.getInfo(name)then
local F=fs.newFile(name)
if F:open'r'then
local s=F:read()
F:close()
if s:sub(1,6)=="return"then
s=loadstring(s)
if s then
setfenv(s,{})
return s()
end
elseif s:sub(1,1)=="["or s:sub(1,1)=="{"then
local res=JSON.decode(s)
if res then
return res
end
else
return s
end
end
MES.new('error',name.." "..text.loadError)
end
end
function FILE.save(data,name,mode)
if not mode then mode=""end
if type(data)=='table'then
if mode:find'l'then
data=TABLE.dump(data)
if not data then
MES.new('error',name.." "..text.saveError.."dump error")
return
end
else
data=JSON.encode(data)
if not data then
MES.new('error',name.." "..text.saveError.."json error")
return
end
end
else
data=tostring(data)
end
if not mode then mode=""end
if type(data)=='table'then
if mode:find'l'then
data=TABLE.dump(data)
if not data then
MES.new('error',name.." "..text.saveError.."dump error")
return
end
else
data=JSON.encode(data)
if not data then
MES.new('error',name.." "..text.saveError.."json error")
return
end
end
else
data=tostring(data)
end
if mode:find'd'and fs.getInfo(name)then
MES.new('error',text.saveError_duplicate)
return
end
local F=fs.newFile(name)
F:open'w'
local success,mes=F:write(data)
F:flush()F:close()
if success then
return true
else
MES.new('error',text.saveError..(mes or"unknown error"))
MES.traceback()
end
if mode:find'd'and fs.getInfo(name)then
MES.new('error',text.saveError_duplicate)
return
end
local F=fs.newFile(name)
F:open'w'
local success,mes=F:write(data)
F:flush()F:close()
if success then
return true
else
MES.new('error',text.saveError..(mes or"unknown error"))
MES.traceback()
end
end
function FILE.clear(path)
if fs.getRealDirectory(path)~=SAVEDIR or fs.getInfo(path).type~='directory'then return end
for _,name in next,fs.getDirectoryItems(path)do
name=path..'/'..name
if fs.getRealDirectory(name)==SAVEDIR then
local t=fs.getInfo(name).type
if t=='file'then
fs.remove(name)
end
end
end
if fs.getRealDirectory(path)~=SAVEDIR or fs.getInfo(path).type~='directory'then return end
for _,name in next,fs.getDirectoryItems(path)do
name=path..'/'..name
if fs.getRealDirectory(name)==SAVEDIR then
local t=fs.getInfo(name).type
if t=='file'then
fs.remove(name)
end
end
end
end
function FILE.clear_s(path)
if path~=''and(fs.getRealDirectory(path)~=SAVEDIR or fs.getInfo(path).type~='directory')then return end
for _,name in next,fs.getDirectoryItems(path)do
name=path..'/'..name
if fs.getRealDirectory(name)==SAVEDIR then
local t=fs.getInfo(name).type
if t=='file'then
fs.remove(name)
elseif t=='directory'then
FILE.clear_s(name)
fs.remove(name)
end
end
end
fs.remove(path)
if path~=''and(fs.getRealDirectory(path)~=SAVEDIR or fs.getInfo(path).type~='directory')then return end
for _,name in next,fs.getDirectoryItems(path)do
name=path..'/'..name
if fs.getRealDirectory(name)==SAVEDIR then
local t=fs.getInfo(name).type
if t=='file'then
fs.remove(name)
elseif t=='directory'then
FILE.clear_s(name)
fs.remove(name)
end
end
end
fs.remove(path)
end
return FILE

View File

@@ -8,152 +8,152 @@ function GC.X(obj,x,y,a,k)draw(obj,x,y,a,k,nil,obj:getWidth()*.5,0)end
function GC.Y(obj,x,y,a,k)draw(obj,x,y,a,k,nil,0,obj:getHeight()*.5)end
function GC.draw(obj,x,y,a,k)draw(obj,x,y,a,k,nil,obj:getWidth()*.5,obj:getHeight()*.5)end
function GC.outDraw(obj,div,x,y,a,k)
local w,h=obj:getWidth()*.5,obj:getHeight()*.5
draw(obj,x-div,y-div,a,k,nil,w,h)
draw(obj,x-div,y+div,a,k,nil,w,h)
draw(obj,x+div,y-div,a,k,nil,w,h)
draw(obj,x+div,y+div,a,k,nil,w,h)
local w,h=obj:getWidth()*.5,obj:getHeight()*.5
draw(obj,x-div,y-div,a,k,nil,w,h)
draw(obj,x-div,y+div,a,k,nil,w,h)
draw(obj,x+div,y-div,a,k,nil,w,h)
draw(obj,x+div,y+div,a,k,nil,w,h)
end
function GC.shadedPrint(str,x,y,mode,d,clr1,clr2)
local w=1280
if mode=='center'then
x=x-w*.5
elseif mode=='right'then
x=x-w
end
if not d then d=1 end
setColor(clr1 or COLOR.D)
printf(str,x-d,y-d,w,mode)
printf(str,x-d,y+d,w,mode)
printf(str,x+d,y-d,w,mode)
printf(str,x+d,y+d,w,mode)
setColor(clr2 or COLOR.Z)
printf(str,x,y,w,mode)
local w=1280
if mode=='center'then
x=x-w*.5
elseif mode=='right'then
x=x-w
end
if not d then d=1 end
setColor(clr1 or COLOR.D)
printf(str,x-d,y-d,w,mode)
printf(str,x-d,y+d,w,mode)
printf(str,x+d,y-d,w,mode)
printf(str,x+d,y+d,w,mode)
setColor(clr2 or COLOR.Z)
printf(str,x,y,w,mode)
end
function GC.regularPolygon(mode,x,y,R,segments,r,phase)
local X,Y={},{}
local ang=phase or 0
local angStep=6.283185307179586/segments
for i=1,segments do
X[i]=x+R*math.cos(ang)
Y[i]=y+R*math.sin(ang)
ang=ang+angStep
end
X[segments+1]=x+R*math.cos(ang)
Y[segments+1]=y+R*math.sin(ang)
local halfAng=6.283185307179586/segments/2
local erasedLen=r*math.tan(halfAng)
if mode=='line'then
erasedLen=erasedLen+1--Fix 1px cover
for i=1,segments do
--Line
local x1,y1,x2,y2=X[i],Y[i],X[i+1],Y[i+1]
local dir=math.atan2(y2-y1,x2-x1)
gc.line(x1+erasedLen*math.cos(dir),y1+erasedLen*math.sin(dir),x2-erasedLen*math.cos(dir),y2-erasedLen*math.sin(dir))
local X,Y={},{}
local ang=phase or 0
local angStep=6.283185307179586/segments
for i=1,segments do
X[i]=x+R*math.cos(ang)
Y[i]=y+R*math.sin(ang)
ang=ang+angStep
end
X[segments+1]=x+R*math.cos(ang)
Y[segments+1]=y+R*math.sin(ang)
local halfAng=6.283185307179586/segments/2
local erasedLen=r*math.tan(halfAng)
if mode=='line'then
erasedLen=erasedLen+1--Fix 1px cover
for i=1,segments do
--Line
local x1,y1,x2,y2=X[i],Y[i],X[i+1],Y[i+1]
local dir=math.atan2(y2-y1,x2-x1)
gc.line(x1+erasedLen*math.cos(dir),y1+erasedLen*math.sin(dir),x2-erasedLen*math.cos(dir),y2-erasedLen*math.sin(dir))
--Arc
ang=ang+angStep
local R2=R-r/math.cos(halfAng)
local arcCX,arcCY=x+R2*math.cos(ang),y+R2*math.sin(ang)
gc.arc('line','open',arcCX,arcCY,r,ang-halfAng,ang+halfAng)
end
elseif mode=='fill'then
local L={}
for i=1,segments do
--Line
local x1,y1,x2,y2=X[i],Y[i],X[i+1],Y[i+1]
local dir=math.atan2(y2-y1,x2-x1)
table.insert(L,x1+erasedLen*math.cos(dir))
table.insert(L,y1+erasedLen*math.sin(dir))
table.insert(L,x2-erasedLen*math.cos(dir))
table.insert(L,y2-erasedLen*math.sin(dir))
--Arc
ang=ang+angStep
local R2=R-r/math.cos(halfAng)
local arcCX,arcCY=x+R2*math.cos(ang),y+R2*math.sin(ang)
gc.arc('line','open',arcCX,arcCY,r,ang-halfAng,ang+halfAng)
end
elseif mode=='fill'then
local L={}
for i=1,segments do
--Line
local x1,y1,x2,y2=X[i],Y[i],X[i+1],Y[i+1]
local dir=math.atan2(y2-y1,x2-x1)
table.insert(L,x1+erasedLen*math.cos(dir))
table.insert(L,y1+erasedLen*math.sin(dir))
table.insert(L,x2-erasedLen*math.cos(dir))
table.insert(L,y2-erasedLen*math.sin(dir))
--Arc
ang=ang+angStep
local R2=R-r/math.cos(halfAng)
local arcCX,arcCY=x+R2*math.cos(ang),y+R2*math.sin(ang)
gc.arc('fill','open',arcCX,arcCY,r,ang-halfAng,ang+halfAng)
end
gc.polygon('fill',L)
else
error("Draw mode should be 'line' or 'fill'")
end
--Arc
ang=ang+angStep
local R2=R-r/math.cos(halfAng)
local arcCX,arcCY=x+R2*math.cos(ang),y+R2*math.sin(ang)
gc.arc('fill','open',arcCX,arcCY,r,ang-halfAng,ang+halfAng)
end
gc.polygon('fill',L)
else
error("Draw mode should be 'line' or 'fill'")
end
end
do--function GC.DO(L)
local cmds={
origin="origin",
move="translate",
scale="scale",
rotate="rotate",
shear="shear",
clear="clear",
local cmds={
origin="origin",
move="translate",
scale="scale",
rotate="rotate",
shear="shear",
clear="clear",
setCL="setColor",
setCM="setColorMask",
setLW="setLineWidth",
setLS="setLineStyle",
setLJ="setLineJoin",
setCL="setColor",
setCM="setColorMask",
setLW="setLineWidth",
setLS="setLineStyle",
setLJ="setLineJoin",
print="print",
setFT=function(...)setFont(...)end,
mText=GC.str,
mDraw=GC.draw,
mOutDraw=GC.outDraw,
print="print",
setFT=function(...)setFont(...)end,
mText=GC.str,
mDraw=GC.draw,
mOutDraw=GC.outDraw,
draw="draw",
line="line",
fRect=function(...)gc.rectangle('fill',...)end,
dRect=function(...)gc.rectangle('line',...)end,
fCirc=function(...)gc.circle('fill',...)end,
dCirc=function(...)gc.circle('line',...)end,
fElps=function(...)gc.ellipse('fill',...)end,
dElps=function(...)gc.ellipse('line',...)end,
fPoly=function(...)gc.polygon('fill',...)end,
dPoly=function(...)gc.polygon('line',...)end,
draw="draw",
line="line",
fRect=function(...)gc.rectangle('fill',...)end,
dRect=function(...)gc.rectangle('line',...)end,
fCirc=function(...)gc.circle('fill',...)end,
dCirc=function(...)gc.circle('line',...)end,
fElps=function(...)gc.ellipse('fill',...)end,
dElps=function(...)gc.ellipse('line',...)end,
fPoly=function(...)gc.polygon('fill',...)end,
dPoly=function(...)gc.polygon('line',...)end,
dPie=function(...)gc.arc('line',...)end,
dArc=function(...)gc.arc('line','open',...)end,
dBow=function(...)gc.arc('line','closed',...)end,
fPie=function(...)gc.arc('fill',...)end,
fArc=function(...)gc.arc('fill','open',...)end,
fBow=function(...)gc.arc('fill','closed',...)end,
dPie=function(...)gc.arc('line',...)end,
dArc=function(...)gc.arc('line','open',...)end,
dBow=function(...)gc.arc('line','closed',...)end,
fPie=function(...)gc.arc('fill',...)end,
fArc=function(...)gc.arc('fill','open',...)end,
fBow=function(...)gc.arc('fill','closed',...)end,
fRPol=function(...)GC.regularPolygon('fill',...)end,
dRPol=function(...)GC.regularPolygon('line',...)end,
}
local sizeLimit=gc.getSystemLimits().texturesize
function GC.DO(L)
gc.push()
::REPEAT_tryAgain::
local success,canvas=pcall(gc.newCanvas,math.min(L[1],sizeLimit),math.min(L[2],sizeLimit))
if not success then
sizeLimit=math.floor(sizeLimit*.8)
goto REPEAT_tryAgain
end
gc.setCanvas(canvas)
gc.origin()
gc.clear(1,1,1,0)
gc.setColor(1,1,1)
gc.setLineWidth(1)
for i=3,#L do
local cmd=L[i][1]
if type(cmd)=='boolean'and cmd then
table.remove(L[i],1)
cmd=L[i][1]
end
if type(cmd)=='string'then
local func=cmds[cmd]
if type(func)=='string'then func=gc[func]end
if func then
func(unpack(L[i],2))
else
error("No gc command: "..cmd)
end
end
end
gc.setCanvas()
gc.pop()
return canvas
end
fRPol=function(...)GC.regularPolygon('fill',...)end,
dRPol=function(...)GC.regularPolygon('line',...)end,
}
local sizeLimit=gc.getSystemLimits().texturesize
function GC.DO(L)
gc.push()
::REPEAT_tryAgain::
local success,canvas=pcall(gc.newCanvas,math.min(L[1],sizeLimit),math.min(L[2],sizeLimit))
if not success then
sizeLimit=math.floor(sizeLimit*.8)
goto REPEAT_tryAgain
end
gc.setCanvas(canvas)
gc.origin()
gc.clear(1,1,1,0)
gc.setColor(1,1,1)
gc.setLineWidth(1)
for i=3,#L do
local cmd=L[i][1]
if type(cmd)=='boolean'and cmd then
table.remove(L[i],1)
cmd=L[i][1]
end
if type(cmd)=='string'then
local func=cmds[cmd]
if type(func)=='string'then func=gc[func]end
if func then
func(unpack(L[i],2))
else
error("No gc command: "..cmd)
end
end
end
gc.setCanvas()
gc.pop()
return canvas
end
end
return GC

View File

@@ -1,26 +1,26 @@
local IMG={}
function IMG.init(list)
IMG.init=nil
IMG.init=nil
local null=love.graphics.newCanvas(1,1)
setmetatable(IMG,{__index=function(self,name)
if type(list[name])=='table'then
self[name]={}
for i=1,#list[name]do
self[name][i]=love.graphics.newImage(list[name][i])
end
elseif type(list[name])=='string'then
self[name]=love.graphics.newImage(list[name])
else
MES.new('warn',"No IMG: "..name,5)
self[name]=null
end
return self[name]
end})
local null=love.graphics.newCanvas(1,1)
setmetatable(IMG,{__index=function(self,name)
if type(list[name])=='table'then
self[name]={}
for i=1,#list[name]do
self[name][i]=love.graphics.newImage(list[name][i])
end
elseif type(list[name])=='string'then
self[name]=love.graphics.newImage(list[name])
else
MES.new('warn',"No IMG: "..name,5)
self[name]=null
end
return self[name]
end})
function IMG.loadAll()
for k in next,list do local _=IMG[k]end
IMG.loadAll=nil
end
function IMG.loadAll()
for k in next,list do local _=IMG[k]end
IMG.loadAll=nil
end
end
return IMG

File diff suppressed because it is too large Load Diff

View File

@@ -32,86 +32,86 @@ local json = {}
local _encode
local escape_char_map = {
["\\"] = "\\",
["\""] = "\"",
["\b"] = "b",
["\f"] = "f",
["\n"] = "n",
["\r"] = "r",
["\t"] = "t"
["\\"] = "\\",
["\""] = "\"",
["\b"] = "b",
["\f"] = "f",
["\n"] = "n",
["\r"] = "r",
["\t"] = "t"
}
local escape_char_map_inv = {["/"] = "/"}
for k, v in pairs(escape_char_map) do escape_char_map_inv[v] = k end
local function escape_char(c)
return "\\" .. (escape_char_map[c] or string.format("u%04x", c:byte()))
return "\\" .. (escape_char_map[c] or string.format("u%04x", c:byte()))
end
local function encode_nil() return "null" end
local function encode_table(val, stack)
local res = {}
stack = stack or {}
local res = {}
stack = stack or {}
-- Circular reference?
if stack[val] then error("circular reference") end
-- Circular reference?
if stack[val] then error("circular reference") end
stack[val] = true
stack[val] = true
if rawget(val, 1) ~= nil or next(val) == nil then
-- Treat as array -- check keys are valid and it is not sparse
local n = 0
for k in pairs(val) do
if type(k) ~= 'number' then
error("invalid table: mixed or invalid key types")
end
n = n + 1
end
if n ~= #val then error("invalid table: sparse array") end
-- Encode
for _, v in ipairs(val) do ins(res, _encode(v, stack)) end
stack[val] = nil
return "[" .. table.concat(res, ",") .. "]"
if rawget(val, 1) ~= nil or next(val) == nil then
-- Treat as array -- check keys are valid and it is not sparse
local n = 0
for k in pairs(val) do
if type(k) ~= 'number' then
error("invalid table: mixed or invalid key types")
end
n = n + 1
end
if n ~= #val then error("invalid table: sparse array") end
-- Encode
for _, v in ipairs(val) do ins(res, _encode(v, stack)) end
stack[val] = nil
return "[" .. table.concat(res, ",") .. "]"
else
-- Treat as an object
for k, v in pairs(val) do
if type(k) ~= 'string' then
error("invalid table: mixed or invalid key types")
end
ins(res, _encode(k, stack) .. ":" .. _encode(v, stack))
end
stack[val] = nil
return "{" .. table.concat(res, ",") .. "}"
end
else
-- Treat as an object
for k, v in pairs(val) do
if type(k) ~= 'string' then
error("invalid table: mixed or invalid key types")
end
ins(res, _encode(k, stack) .. ":" .. _encode(v, stack))
end
stack[val] = nil
return "{" .. table.concat(res, ",") .. "}"
end
end
local function encode_string(val)
return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"'
return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"'
end
local function encode_number(val)
-- Check for NaN, -inf and inf
if val ~= val or val <= -math.huge or val >= math.huge then
error("unexpected number value '" .. tostring(val) .. "'")
end
return string.format("%.14g", val)
-- Check for NaN, -inf and inf
if val ~= val or val <= -math.huge or val >= math.huge then
error("unexpected number value '" .. tostring(val) .. "'")
end
return string.format("%.14g", val)
end
local type_func_map = {
['nil'] = encode_nil,
['table'] = encode_table,
['string'] = encode_string,
['number'] = encode_number,
['boolean'] = tostring
['nil'] = encode_nil,
['table'] = encode_table,
['string'] = encode_string,
['number'] = encode_number,
['boolean'] = tostring
}
_encode = function(val, stack)
local t = type(val)
local f = type_func_map[t]
if f then return f(val, stack) end
error("unexpected type '" .. t .. "'")
local t = type(val)
local f = type_func_map[t]
if f then return f(val, stack) end
error("unexpected type '" .. t .. "'")
end
json.encode=_encode
@@ -123,9 +123,9 @@ json.encode=_encode
local parse
local function create_set(...)
local res = {}
for i = 1, select("#", ...) do res[select(i, ...)] = true end
return res
local res = {}
for i = 1, select("#", ...) do res[select(i, ...)] = true end
return res
end
local space_chars = create_set(" ", "\t", "\r", "\n")
@@ -136,205 +136,205 @@ local literals = create_set("true", "false", "null")
local literal_map = {["true"] = true, ["false"] = false, ["null"] = nil}
local function next_char(str, idx, set, negate)
for i = idx, #str do if set[str:sub(i, i)] ~= negate then return i end end
return #str + 1
for i = idx, #str do if set[str:sub(i, i)] ~= negate then return i end end
return #str + 1
end
local function decode_error(str, idx, msg)
local line_count = 1
local col_count = 1
for i = 1, idx - 1 do
col_count = col_count + 1
if str:sub(i, i) == "\n" then
line_count = line_count + 1
col_count = 1
end
end
error(string.format("%s at line %d col %d", msg, line_count, col_count))
local line_count = 1
local col_count = 1
for i = 1, idx - 1 do
col_count = col_count + 1
if str:sub(i, i) == "\n" then
line_count = line_count + 1
col_count = 1
end
end
error(string.format("%s at line %d col %d", msg, line_count, col_count))
end
local function codepoint_to_utf8(n)
-- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa
local f = bit.rshift
if n <= 0x7f then
return char(n)
elseif n <= 0x7ff then
return char(f(n, 6) + 192, n % 64 + 128)
elseif n <= 0xffff then
return char(f(n, 12) + 224, f(n % 4096, 6) + 128, n % 64 + 128)
elseif n <= 0x10ffff then
return char(f(n, 18) + 240, f(n % 262144, 12) + 128, f(n % 4096, 6) + 128, n % 64 + 128)
end
error(string.format("invalid unicode codepoint '%x'", n))
-- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa
local f = bit.rshift
if n <= 0x7f then
return char(n)
elseif n <= 0x7ff then
return char(f(n, 6) + 192, n % 64 + 128)
elseif n <= 0xffff then
return char(f(n, 12) + 224, f(n % 4096, 6) + 128, n % 64 + 128)
elseif n <= 0x10ffff then
return char(f(n, 18) + 240, f(n % 262144, 12) + 128, f(n % 4096, 6) + 128, n % 64 + 128)
end
error(string.format("invalid unicode codepoint '%x'", n))
end
local function parse_unicode_escape(s)
local n1 = tonumber(s:sub(1, 4), 16)
local n2 = tonumber(s:sub(7, 10), 16)
-- Surrogate pair?
if n2 then
return
codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000)
else
return codepoint_to_utf8(n1)
end
local n1 = tonumber(s:sub(1, 4), 16)
local n2 = tonumber(s:sub(7, 10), 16)
-- Surrogate pair?
if n2 then
return
codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000)
else
return codepoint_to_utf8(n1)
end
end
local function parse_string(str, i)
local res = ""
local j = i + 1
local k = j
local res = ""
local j = i + 1
local k = j
while j <= #str do
local x = str:byte(j)
while j <= #str do
local x = str:byte(j)
if x < 32 then
decode_error(str, j, "control character in string")
if x < 32 then
decode_error(str, j, "control character in string")
elseif x == 92 then -- `\`: Escape
res = res .. str:sub(k, j - 1)
j = j + 1
local c = str:sub(j, j)
if c == "u" then
local hex = str:match("^[dD][89aAbB]%x%x\\u%x%x%x%x", j + 1) or
str:match("^%x%x%x%x", j + 1) or
decode_error(str, j - 1,
"invalid unicode escape in string")
res = res .. parse_unicode_escape(hex)
j = j + #hex
else
if not escape_chars[c] then
decode_error(str, j - 1,
"invalid escape char '" .. c .. "' in string")
end
res = res .. escape_char_map_inv[c]
end
k = j + 1
elseif x == 92 then -- `\`: Escape
res = res .. str:sub(k, j - 1)
j = j + 1
local c = str:sub(j, j)
if c == "u" then
local hex = str:match("^[dD][89aAbB]%x%x\\u%x%x%x%x", j + 1) or
str:match("^%x%x%x%x", j + 1) or
decode_error(str, j - 1,
"invalid unicode escape in string")
res = res .. parse_unicode_escape(hex)
j = j + #hex
else
if not escape_chars[c] then
decode_error(str, j - 1,
"invalid escape char '" .. c .. "' in string")
end
res = res .. escape_char_map_inv[c]
end
k = j + 1
elseif x == 34 then -- `"`: End of string
res = res .. str:sub(k, j - 1)
return res, j + 1
end
elseif x == 34 then -- `"`: End of string
res = res .. str:sub(k, j - 1)
return res, j + 1
end
j = j + 1
end
j = j + 1
end
decode_error(str, i, "expected closing quote for string")
decode_error(str, i, "expected closing quote for string")
end
local function parse_number(str, i)
local x = next_char(str, i, delim_chars)
local s = str:sub(i, x - 1)
local n = tonumber(s)
if not n then decode_error(str, i, "invalid number '" .. s .. "'") end
return n, x
local x = next_char(str, i, delim_chars)
local s = str:sub(i, x - 1)
local n = tonumber(s)
if not n then decode_error(str, i, "invalid number '" .. s .. "'") end
return n, x
end
local function parse_literal(str, i)
local x = next_char(str, i, delim_chars)
local word = str:sub(i, x - 1)
if not literals[word] then
decode_error(str, i, "invalid literal '" .. word .. "'")
end
return literal_map[word], x
local x = next_char(str, i, delim_chars)
local word = str:sub(i, x - 1)
if not literals[word] then
decode_error(str, i, "invalid literal '" .. word .. "'")
end
return literal_map[word], x
end
local function parse_array(str, i)
local res = {}
local n = 1
i = i + 1
while 1 do
local x
i = next_char(str, i, space_chars, true)
-- Empty / end of array?
if str:sub(i, i) == "]" then
i = i + 1
break
end
-- Read token
x, i = parse(str, i)
res[n] = x
n = n + 1
-- Next token
i = next_char(str, i, space_chars, true)
local chr = str:sub(i, i)
i = i + 1
if chr == "]" then break end
if chr ~= "," then decode_error(str, i, "expected ']' or ','") end
end
return res, i
local res = {}
local n = 1
i = i + 1
while 1 do
local x
i = next_char(str, i, space_chars, true)
-- Empty / end of array?
if str:sub(i, i) == "]" then
i = i + 1
break
end
-- Read token
x, i = parse(str, i)
res[n] = x
n = n + 1
-- Next token
i = next_char(str, i, space_chars, true)
local chr = str:sub(i, i)
i = i + 1
if chr == "]" then break end
if chr ~= "," then decode_error(str, i, "expected ']' or ','") end
end
return res, i
end
local function parse_object(str, i)
local res = {}
i = i + 1
while 1 do
local key, val
i = next_char(str, i, space_chars, true)
-- Empty / end of object?
if str:sub(i, i) == "}" then
i = i + 1
break
end
-- Read key
if str:sub(i, i) ~= '"' then
decode_error(str, i, "expected string for key")
end
key, i = parse(str, i)
-- Read ':' delimiter
i = next_char(str, i, space_chars, true)
if str:sub(i, i) ~= ":" then
decode_error(str, i, "expected ':' after key")
end
i = next_char(str, i + 1, space_chars, true)
-- Read value
val, i = parse(str, i)
-- Set
res[key] = val
-- Next token
i = next_char(str, i, space_chars, true)
local chr = str:sub(i, i)
i = i + 1
if chr == "}" then break end
if chr ~= "," then decode_error(str, i, "expected '}' or ','") end
end
return res, i
local res = {}
i = i + 1
while 1 do
local key, val
i = next_char(str, i, space_chars, true)
-- Empty / end of object?
if str:sub(i, i) == "}" then
i = i + 1
break
end
-- Read key
if str:sub(i, i) ~= '"' then
decode_error(str, i, "expected string for key")
end
key, i = parse(str, i)
-- Read ':' delimiter
i = next_char(str, i, space_chars, true)
if str:sub(i, i) ~= ":" then
decode_error(str, i, "expected ':' after key")
end
i = next_char(str, i + 1, space_chars, true)
-- Read value
val, i = parse(str, i)
-- Set
res[key] = val
-- Next token
i = next_char(str, i, space_chars, true)
local chr = str:sub(i, i)
i = i + 1
if chr == "}" then break end
if chr ~= "," then decode_error(str, i, "expected '}' or ','") end
end
return res, i
end
local char_func_map = {
['"'] = parse_string,
["0"] = parse_number,
["1"] = parse_number,
["2"] = parse_number,
["3"] = parse_number,
["4"] = parse_number,
["5"] = parse_number,
["6"] = parse_number,
["7"] = parse_number,
["8"] = parse_number,
["9"] = parse_number,
["-"] = parse_number,
["t"] = parse_literal,
["f"] = parse_literal,
["n"] = parse_literal,
["["] = parse_array,
["{"] = parse_object
['"'] = parse_string,
["0"] = parse_number,
["1"] = parse_number,
["2"] = parse_number,
["3"] = parse_number,
["4"] = parse_number,
["5"] = parse_number,
["6"] = parse_number,
["7"] = parse_number,
["8"] = parse_number,
["9"] = parse_number,
["-"] = parse_number,
["t"] = parse_literal,
["f"] = parse_literal,
["n"] = parse_literal,
["["] = parse_array,
["{"] = parse_object
}
function parse(str, idx)
local chr = str:sub(idx, idx)
local f = char_func_map[chr]
if f then return f(str, idx) end
decode_error(str, idx, "unexpected character '" .. chr .. "'")
local chr = str:sub(idx, idx)
local f = char_func_map[chr]
if f then return f(str, idx) end
decode_error(str, idx, "unexpected character '" .. chr .. "'")
end
function json.decode(str)
if type(str) ~= 'string' then
error("expected argument of type string, got " .. type(str))
end
local res, idx = parse(str, next_char(str, 1, space_chars, true))
idx = next_char(str, idx, space_chars, true)
if idx <= #str then decode_error(str, idx, "trailing garbage") end
return res
if type(str) ~= 'string' then
error("expected argument of type string, got " .. type(str))
end
local res, idx = parse(str, next_char(str, 1, space_chars, true))
idx = next_char(str, idx, space_chars, true)
if idx <= #str then decode_error(str, idx, "trailing garbage") end
return res
end
return json

View File

@@ -1,56 +1,56 @@
local LANG={}
function LANG.init(langList,publicText)--Attention, calling this will destory all initializing methods, create a LANG.set()!
local function _langFallback(T0,T)
for k,v in next,T0 do
if type(v)=='table'and not v.refuseCopy then--refuseCopy: just copy pointer, not contents
if not T[k]then T[k]={}end
if type(T[k])=='table'then _langFallback(v,T[k])end
elseif not T[k]then
T[k]=v
end
end
end
local tipMeta={__call=function(L)return L[math.random(#L)]end}
local function _langFallback(T0,T)
for k,v in next,T0 do
if type(v)=='table'and not v.refuseCopy then--refuseCopy: just copy pointer, not contents
if not T[k]then T[k]={}end
if type(T[k])=='table'then _langFallback(v,T[k])end
elseif not T[k]then
T[k]=v
end
end
end
local tipMeta={__call=function(L)return L[math.random(#L)]end}
for i=1,#langList do
local L=langList[i]
for i=1,#langList do
local L=langList[i]
--Set public text
for key,list in next,publicText do
L[key]=list
end
--Set public text
for key,list in next,publicText do
L[key]=list
end
--Fallback to other language, default zh
if i>1 then
_langFallback(langList[L.fallback or 1],L)
end
--Fallback to other language, default zh
if i>1 then
_langFallback(langList[L.fallback or 1],L)
end
--Metatable:__call for table:getTip
if type(rawget(L,'getTip'))=='table'then
setmetatable(L.getTip,tipMeta)
end
end
--Metatable:__call for table:getTip
if type(rawget(L,'getTip'))=='table'then
setmetatable(L.getTip,tipMeta)
end
end
LANG.init,LANG.setLangList,LANG.setPublicText=nil
LANG.init,LANG.setLangList,LANG.setPublicText=nil
function LANG.set(l)
if text~=langList[l]then
text=langList[l]
WIDGET.setLang(text.WidgetText)
for k,v in next,drawableText do
if text[k]then
v:set(text[k])
end
end
end
end
function LANG.set(l)
if text~=langList[l]then
text=langList[l]
WIDGET.setLang(text.WidgetText)
for k,v in next,drawableText do
if text[k]then
v:set(text[k])
end
end
end
end
function LANG.addScene(name)
for i=1,#langList do
if langList[i].WidgetText and not langList[i].WidgetText[name]then
langList[i].WidgetText[name]={back=langList[i].back}
end
end
end
function LANG.addScene(name)
for i=1,#langList do
if langList[i].WidgetText and not langList[i].WidgetText[name]then
langList[i].WidgetText[name]={back=langList[i].back}
end
end
end
end
return LANG

View File

@@ -10,77 +10,77 @@ local shadowMapShader=gc.newShader('Zframework/light/shadowMap.glsl')--Shader fo
local lightRenderShader=gc.newShader('Zframework/light/lightRender.glsl')--Shader for rendering blurred lights and shadows.
local Lights={}--Lightsource objects
local function move(L,x,y)
L.x,L.y=x,y
L.x,L.y=x,y
end
local function setPow(L,pow)
L.size=pow
L.size=pow
end
local function drawLight(L)
local s=L.size
local s=L.size
--Initialization
gc_setCanvas(L.blackCanvas)clear()
gc_setCanvas(L.shadowCanvas)clear()
gc_setCanvas(L.renderCanvas)clear()
lightRenderShader:send('xresolution',s)
shadowMapShader:send('yresolution',s)
--Initialization
gc_setCanvas(L.blackCanvas)clear()
gc_setCanvas(L.shadowCanvas)clear()
gc_setCanvas(L.renderCanvas)clear()
lightRenderShader:send('xresolution',s)
shadowMapShader:send('yresolution',s)
--Get up-left of light
local X=L.x-s*.5
local Y=L.y-s*.5
--Get up-left of light
local X=L.x-s*.5
local Y=L.y-s*.5
--Render solid
gc_translate(-X,-Y)
L.blackCanvas:renderTo(L.blackFn)
gc_translate(X,Y)
--Render solid
gc_translate(-X,-Y)
L.blackCanvas:renderTo(L.blackFn)
gc_translate(X,Y)
--Render shade canvas by solid
gc_setShader(shadowMapShader)
gc_setCanvas(L.shadowCanvas)
gc_draw(L.blackCanvas)
--Render shade canvas by solid
gc_setShader(shadowMapShader)
gc_setCanvas(L.shadowCanvas)
gc_draw(L.blackCanvas)
--Render light canvas by shade
gc_setShader(lightRenderShader)
gc_setCanvas(L.renderCanvas)
gc_draw(L.shadowCanvas,0,0,0,1,s)
--Render light canvas by shade
gc_setShader(lightRenderShader)
gc_setCanvas(L.renderCanvas)
gc_draw(L.shadowCanvas,0,0,0,1,s)
--Ready to final render
gc_setShader()gc_setCanvas()gc.setBlendMode('add')
--Ready to final render
gc_setShader()gc_setCanvas()gc.setBlendMode('add')
--Render to screen
gc_draw(L.renderCanvas,X,Y+s,0,1,-1)
--Render to screen
gc_draw(L.renderCanvas,X,Y+s,0,1,-1)
--Reset
gc.setBlendMode('alpha')
--Reset
gc.setBlendMode('alpha')
end
local LIGHT={}
function LIGHT.draw()
gc_setColor(1,1,1)
for i=1,#Lights do
drawLight(Lights[i])
end
gc_setColor(1,1,1)
for i=1,#Lights do
drawLight(Lights[i])
end
end
function LIGHT.clear()
for i=1,#Lights do
Lights[i].blackCanvas:release()
Lights[i].shadowCanvas:release()
Lights[i].renderCanvas:release()
Lights[i]=nil
end
for i=1,#Lights do
Lights[i].blackCanvas:release()
Lights[i].shadowCanvas:release()
Lights[i].renderCanvas:release()
Lights[i]=nil
end
end
function LIGHT.add(x,y,radius,solidFunc)
local id=#Lights+1
Lights[id]={
id=id,
x=x,y=y,size=radius,
blackCanvas=gc.newCanvas(radius,radius),--Solid canvas
shadowCanvas=gc.newCanvas(radius,1),--1D vis-depth canvas
renderCanvas=gc.newCanvas(radius,radius),--Light canvas
blackFn=solidFunc,--Solid draw function
local id=#Lights+1
Lights[id]={
id=id,
x=x,y=y,size=radius,
blackCanvas=gc.newCanvas(radius,radius),--Solid canvas
shadowCanvas=gc.newCanvas(radius,1),--1D vis-depth canvas
renderCanvas=gc.newCanvas(radius,radius),--Light canvas
blackFn=solidFunc,--Solid draw function
move=move,
setPow=setPow,
}
move=move,
setPow=setPow,
}
end
return LIGHT

View File

@@ -2,28 +2,28 @@
extern float xresolution;
// Sample from 1D vis-depth map
float samp(vec2 coord,float r,Image u_texture){
return step(r,Texel(u_texture,coord).r);
return step(r,Texel(u_texture,coord).r);
}
vec4 effect(vec4 color,Image tex,vec2 tex_coords,vec2 screen_coords){
// Cartesian to polar, y of 1D sample is always 0
vec2 norm=tex_coords.st*2.-1.;
vec2 tc=vec2((atan(norm.y,norm.x)+PI)/(2.*PI),0.);
float r=length(norm);
// Cartesian to polar, y of 1D sample is always 0
vec2 norm=tex_coords.st*2.-1.;
vec2 tc=vec2((atan(norm.y,norm.x)+PI)/(2.*PI),0.);
float r=length(norm);
// Enlarge blur parameter by distance, light scattering simulation
float blur=(1./xresolution)*smoothstep(0.3,1.,r);
// Enlarge blur parameter by distance, light scattering simulation
float blur=(1./xresolution)*smoothstep(0.3,1.,r);
// Simple Gaussian blur
float sum=// Brightness(0~1)
samp(vec2(tc.x-3.*blur,tc.y),r,tex)*0.1
+samp(vec2(tc.x-2.*blur,tc.y),r,tex)*0.13
+samp(vec2(tc.x-1.*blur,tc.y),r,tex)*0.17
// Simple Gaussian blur
float sum=// Brightness(0~1)
samp(vec2(tc.x-3.*blur,tc.y),r,tex)*0.1
+samp(vec2(tc.x-2.*blur,tc.y),r,tex)*0.13
+samp(vec2(tc.x-1.*blur,tc.y),r,tex)*0.17
+samp(tc,r,tex)*0.2// The center tex coord, which gives us hard shadows.
+samp(vec2(tc.x+1.*blur,tc.y),r,tex)*0.17
+samp(vec2(tc.x+2.*blur,tc.y),r,tex)*0.13
+samp(vec2(tc.x+3.*blur,tc.y),r,tex)*0.1;
+samp(tc,r,tex)*0.2// The center tex coord, which gives us hard shadows.
+samp(vec2(tc.x+1.*blur,tc.y),r,tex)*0.17
+samp(vec2(tc.x+2.*blur,tc.y),r,tex)*0.13
+samp(vec2(tc.x+3.*blur,tc.y),r,tex)*0.1;
// Multiply the distance to get a soft fading
return vec4(vec3(1.),sum*smoothstep(1.,0.,r));
// Multiply the distance to get a soft fading
return vec4(vec3(1.),sum*smoothstep(1.,0.,r));
}

View File

@@ -1,20 +1,20 @@
#define PI 3.14
extern float yresolution;
vec4 effect(vec4 color,Image tex,vec2 tex_coords,vec2 screen_coords){
// Iterate through the occluder map's y-axis.
for(float y=0.;y<yresolution;y++){
// Cartesian to polar
// y/yresolution=distance to light source(0~1)
vec2 norm=vec2(tex_coords.s,y/yresolution)*2.-1.;
float theta=PI*1.5+norm.x*PI;
float r=(1.+norm.y)*0.5;
// Iterate through the occluder map's y-axis.
for(float y=0.;y<yresolution;y++){
// Cartesian to polar
// y/yresolution=distance to light source(0~1)
vec2 norm=vec2(tex_coords.s,y/yresolution)*2.-1.;
float theta=PI*1.5+norm.x*PI;
float r=(1.+norm.y)*0.5;
//sample from solid
if(
Texel(tex,(
vec2(-r*sin(theta),-r*cos(theta))*0.5+0.5// Coord of solid sampling
)).a>0.1
)return vec4(vec3(y/yresolution),1.);// Collision check, alpha>0.1 means transparent
}
return vec4(1.);// Return max distance 1
//sample from solid
if(
Texel(tex,(
vec2(-r*sin(theta),-r*cos(theta))*0.5+0.5// Coord of solid sampling
)).a>0.1
)return vec4(vec3(y/yresolution),1.);// Collision check, alpha>0.1 means transparent
}
return vec4(1.);// Return max distance 1
}

View File

@@ -1,23 +1,23 @@
package.cpath=package.cpath..';'..SAVEDIR..'/lib/lib?.so;'..'?.dylib'
return function(libName)
if SYSTEM=='Android'then
local platform=(function()
local p=io.popen('uname -m')
local arch=p:read('*a'):lower()
p:close()
return
arch=='aarch64'or arch=='arm64'and'arm64-v8a'or
'armeabi-v7a'
end)()
love.filesystem.write(
'lib/libCCloader.so',
love.filesystem.read('data','libAndroid/'..platform..'/libCCloader.so')
)
end
local r1,r2,r3=pcall(require,libName)
if r1 and r2 then
return r2
else
MES.new('error',"Cannot load "..libName..": "..(r2 or r3))
end
if SYSTEM=='Android'then
local platform=(function()
local p=io.popen('uname -m')
local arch=p:read('*a'):lower()
p:close()
return
arch=='aarch64'or arch=='arm64'and'arm64-v8a'or
'armeabi-v7a'
end)()
love.filesystem.write(
'lib/libCCloader.so',
love.filesystem.read('data','libAndroid/'..platform..'/libCCloader.so')
)
end
local r1,r2,r3=pcall(require,libName)
if r1 and r2 then
return r2
else
MES.new('error',"Cannot load "..libName..": "..(r2 or r3))
end
end

View File

@@ -7,137 +7,137 @@ local max=math.max
local mesList={}
local mesIcon={
check=GC.DO{40,40,
{'setLW',10},
{'setCL',0,0,0},
{'line',4,19,15,30,36,9},
{'setLW',6},
{'setCL',.7,1,.6},
{'line',5,20,15,30,35,10},
},
info=GC.DO{40,40,
{'setCL',.2,.25,.85},
{'fCirc',20,20,15},
{'setCL',1,1,1},
{'setLW',2},
{'dCirc',20,20,15},
{'fRect',18,11,4,4},
{'fRect',18,17,4,12},
},
broadcast=GC.DO{40,40,
{'setCL',1,1,1},
{'fRect',2,4,36,26,3},
{'fPoly',2,27,2,37,14,25},
{'setCL',.5,.5,.5},
{'fRect',6,11,4,4},{'fRect',14,11,19,4},
{'fRect',6,19,4,4},{'fRect',14,19,19,4},
},
warn=GC.DO{40,40,
{'setCL',.95,.83,.4},
{'fPoly',20.5,1,0,38,40,38},
{'setCL',0,0,0},
{'dPoly',20.5,1,0,38,40,38},
{'fRect',17,10,7,18},
{'fRect',17,29,7,7},
{'setCL',1,1,1},
{'fRect',18,11,5,16},
{'fRect',18,30,5,5},
},
error=GC.DO{40,40,
{'setCL',.95,.3,.3},
{'fCirc',20,20,19},
{'setCL',0,0,0},
{'dCirc',20,20,19},
{'setLW',6},
{'line',10.2,10.2,29.8,29.8},
{'line',10.2,29.8,29.8,10.2},
{'setLW',4},
{'setCL',1,1,1},
{'line',11,11,29,29},
{'line',11,29,29,11},
},
check=GC.DO{40,40,
{'setLW',10},
{'setCL',0,0,0},
{'line',4,19,15,30,36,9},
{'setLW',6},
{'setCL',.7,1,.6},
{'line',5,20,15,30,35,10},
},
info=GC.DO{40,40,
{'setCL',.2,.25,.85},
{'fCirc',20,20,15},
{'setCL',1,1,1},
{'setLW',2},
{'dCirc',20,20,15},
{'fRect',18,11,4,4},
{'fRect',18,17,4,12},
},
broadcast=GC.DO{40,40,
{'setCL',1,1,1},
{'fRect',2,4,36,26,3},
{'fPoly',2,27,2,37,14,25},
{'setCL',.5,.5,.5},
{'fRect',6,11,4,4},{'fRect',14,11,19,4},
{'fRect',6,19,4,4},{'fRect',14,19,19,4},
},
warn=GC.DO{40,40,
{'setCL',.95,.83,.4},
{'fPoly',20.5,1,0,38,40,38},
{'setCL',0,0,0},
{'dPoly',20.5,1,0,38,40,38},
{'fRect',17,10,7,18},
{'fRect',17,29,7,7},
{'setCL',1,1,1},
{'fRect',18,11,5,16},
{'fRect',18,30,5,5},
},
error=GC.DO{40,40,
{'setCL',.95,.3,.3},
{'fCirc',20,20,19},
{'setCL',0,0,0},
{'dCirc',20,20,19},
{'setLW',6},
{'line',10.2,10.2,29.8,29.8},
{'line',10.2,29.8,29.8,10.2},
{'setLW',4},
{'setCL',1,1,1},
{'line',11,11,29,29},
{'line',11,29,29,11},
},
}
local MES={}
function MES.new(icon,str,time)
local backColor={.5,.5,.5,.7}
if type(icon)=='string'then
if icon=='check'then
backColor={.3,.6,.3,.7}
elseif icon=='broadcast'then
backColor={.3,.3,.6,.8}
elseif icon=='warn'then
backColor={.4,.4,.2,.9}
elseif icon=='error'then
backColor={.4,.2,.2,.9}
end
icon=mesIcon[icon]
end
local t=gc.newText(getFont(30),str)
local w=math.max(t:getWidth()+(icon and 45 or 5),200)+20
local h=math.max(t:getHeight(),46)+3
local L={w,h,
{'clear',backColor},
{'setCL',.7,.7,.7},
{'setLW',2},
{'dRect',1,1,w-2,h-2},
{'setCL',1,1,1},
}
if icon then
ins(L,{'draw',icon,4,4,nil,40/icon:getWidth(),40/icon:getHeight()})
end
ins(L,{'draw',t,icon and 50 or 10,2})
local backColor={.5,.5,.5,.7}
if type(icon)=='string'then
if icon=='check'then
backColor={.3,.6,.3,.7}
elseif icon=='broadcast'then
backColor={.3,.3,.6,.8}
elseif icon=='warn'then
backColor={.4,.4,.2,.9}
elseif icon=='error'then
backColor={.4,.2,.2,.9}
end
icon=mesIcon[icon]
end
local t=gc.newText(getFont(30),str)
local w=math.max(t:getWidth()+(icon and 45 or 5),200)+20
local h=math.max(t:getHeight(),46)+3
local L={w,h,
{'clear',backColor},
{'setCL',.7,.7,.7},
{'setLW',2},
{'dRect',1,1,w-2,h-2},
{'setCL',1,1,1},
}
if icon then
ins(L,{'draw',icon,4,4,nil,40/icon:getWidth(),40/icon:getHeight()})
end
ins(L,{'draw',t,icon and 50 or 10,2})
ins(mesList,{
startTime=.5,
endTime=.5,
time=time or 3,
canvas=GC.DO(L),
width=w,height=h,
scale=h>400 and 1/math.min(h/400,2.6)or 1
})
ins(mesList,{
startTime=.5,
endTime=.5,
time=time or 3,
canvas=GC.DO(L),
width=w,height=h,
scale=h>400 and 1/math.min(h/400,2.6)or 1
})
end
function MES.update(dt)
for i=#mesList,1,-1 do
local m=mesList[i]
if m.startTime>0 then
m.startTime=max(m.startTime-dt,0)
elseif m.time>0 then
m.time=max(m.time-dt,0)
elseif m.endTime>0 then
m.endTime=m.endTime-dt
else
rem(mesList,i)
end
end
for i=#mesList,1,-1 do
local m=mesList[i]
if m.startTime>0 then
m.startTime=max(m.startTime-dt,0)
elseif m.time>0 then
m.time=max(m.time-dt,0)
elseif m.endTime>0 then
m.endTime=m.endTime-dt
else
rem(mesList,i)
end
end
end
function MES.draw()
gc_push('transform')
if #mesList>0 then
gc_translate(SCR.safeX,30)
for i=1,#mesList do
local m=mesList[i]
gc_setColor(1,1,1,2*(m.endTime-m.startTime))
gc_draw(m.canvas,40-80*(m.endTime+m.startTime),0,nil,m.scale)
gc_translate(0,m.height*m.scale+4)
end
end
gc_pop()
gc_push('transform')
if #mesList>0 then
gc_translate(SCR.safeX,30)
for i=1,#mesList do
local m=mesList[i]
gc_setColor(1,1,1,2*(m.endTime-m.startTime))
gc_draw(m.canvas,40-80*(m.endTime+m.startTime),0,nil,m.scale)
gc_translate(0,m.height*m.scale+4)
end
end
gc_pop()
end
function MES.traceback()
local mes=
debug.traceback('',1)
:gsub(': in function',', in')
:gsub(':',' ')
:gsub('\t','')
MES.new('error',mes:sub(
mes:find("\n",2)+1,
mes:find("\n%[C%], in 'xpcall'")
),5)
local mes=
debug.traceback('',1)
:gsub(': in function',', in')
:gsub(':',' ')
:gsub('\t','')
MES.new('error',mes:sub(
mes:find("\n",2)+1,
mes:find("\n%[C%], in 'xpcall'")
),5)
end
return MES

View File

@@ -2,156 +2,156 @@ local clock=os.clock
local profile={}
local _labeled={} -- function labels
local _defined={} -- function definitions
local _tcalled={} -- time of last call
local _labeled={} -- function labels
local _defined={} -- function definitions
local _tcalled={} -- time of last call
local _telapsed={}-- total execution time
local _ncalls={} -- number of calls
local _ncalls={} -- number of calls
local _internal={}-- list of internal profiler functions
local getInfo=debug.getinfo
function profile.hooker(event,line,info)
info=info or getInfo(2,'fnS')
local f=info.func
if _internal[f]then return end-- ignore the profiler itself
if info.name then _labeled[f]=info.name end-- get the function name if available
-- find the line definition
if not _defined[f]then
_defined[f]=info.short_src..":"..info.linedefined
_ncalls[f]=0
_telapsed[f]=0
end
if _tcalled[f]then
local dt=clock()-_tcalled[f]
_telapsed[f]=_telapsed[f]+dt
_tcalled[f]=nil
end
if event=='tail call'then
local prev=getInfo(3,'fnS')
profile.hooker('return',line,prev)
profile.hooker('call',line,info)
elseif event=='call'then
_tcalled[f]=clock()
else
_ncalls[f]=_ncalls[f]+1
end
info=info or getInfo(2,'fnS')
local f=info.func
if _internal[f]then return end-- ignore the profiler itself
if info.name then _labeled[f]=info.name end-- get the function name if available
-- find the line definition
if not _defined[f]then
_defined[f]=info.short_src..":"..info.linedefined
_ncalls[f]=0
_telapsed[f]=0
end
if _tcalled[f]then
local dt=clock()-_tcalled[f]
_telapsed[f]=_telapsed[f]+dt
_tcalled[f]=nil
end
if event=='tail call'then
local prev=getInfo(3,'fnS')
profile.hooker('return',line,prev)
profile.hooker('call',line,info)
elseif event=='call'then
_tcalled[f]=clock()
else
_ncalls[f]=_ncalls[f]+1
end
end
--- Starts collecting data.
function profile.start()
if jit then
jit.off()
jit.flush()
end
debug.sethook(profile.hooker,'cr')
if jit then
jit.off()
jit.flush()
end
debug.sethook(profile.hooker,'cr')
end
--- Stops collecting data.
function profile.stop()
debug.sethook()
for f in next,_tcalled do
local dt=clock()-_tcalled[f]
_telapsed[f]=_telapsed[f]+dt
_tcalled[f]=nil
end
-- merge closures
local lookup={}
for f,d in next,_defined do
local id=(_labeled[f]or"?")..d
local f2=lookup[id]
if f2 then
_ncalls[f2]=_ncalls[f2]+(_ncalls[f]or 0)
_telapsed[f2]=_telapsed[f2]+(_telapsed[f]or 0)
_defined[f],_labeled[f]=nil,nil
_ncalls[f],_telapsed[f]=nil,nil
else
lookup[id]=f
end
end
collectgarbage()
debug.sethook()
for f in next,_tcalled do
local dt=clock()-_tcalled[f]
_telapsed[f]=_telapsed[f]+dt
_tcalled[f]=nil
end
-- merge closures
local lookup={}
for f,d in next,_defined do
local id=(_labeled[f]or"?")..d
local f2=lookup[id]
if f2 then
_ncalls[f2]=_ncalls[f2]+(_ncalls[f]or 0)
_telapsed[f2]=_telapsed[f2]+(_telapsed[f]or 0)
_defined[f],_labeled[f]=nil,nil
_ncalls[f],_telapsed[f]=nil,nil
else
lookup[id]=f
end
end
collectgarbage()
end
--- Resets all collected data.
function profile.reset()
for f in next,_ncalls do
_ncalls[f]=0
_telapsed[f]=0
_tcalled[f]=nil
end
collectgarbage()
for f in next,_ncalls do
_ncalls[f]=0
_telapsed[f]=0
_tcalled[f]=nil
end
collectgarbage()
end
local function _comp(a,b)
local dt=_telapsed[b]-_telapsed[a]
return dt==0 and _ncalls[b]<_ncalls[a]or dt<0
local dt=_telapsed[b]-_telapsed[a]
return dt==0 and _ncalls[b]<_ncalls[a]or dt<0
end
--- Iterates all functions that have been called since the profile was started.
function profile.query(limit)
local t={}
for f,n in next,_ncalls do
if n>0 then
t[#t+1]=f
end
end
table.sort(t,_comp)
local t={}
for f,n in next,_ncalls do
if n>0 then
t[#t+1]=f
end
end
table.sort(t,_comp)
if limit then while #t>limit do table.remove(t)end end
if limit then while #t>limit do table.remove(t)end end
for i,f in ipairs(t)do
local dt=0
if _tcalled[f]then
dt=clock()-_tcalled[f]
end
t[i]={i,_labeled[f]or"?",math.floor((_telapsed[f]+dt)*1e6)/1e6,_ncalls[f],_defined[f]}
end
return t
for i,f in ipairs(t)do
local dt=0
if _tcalled[f]then
dt=clock()-_tcalled[f]
end
t[i]={i,_labeled[f]or"?",math.floor((_telapsed[f]+dt)*1e6)/1e6,_ncalls[f],_defined[f]}
end
return t
end
local cols={3,20,8,6,32}
function profile.report(n)
local out={}
local report=profile.query(n)
for i,row in ipairs(report)do
for j=1,5 do
local s=tostring(row[j])
local l1,l2=#s,cols[j]
if l1<l2 then
s=s..(" "):rep(l2-l1)
elseif l1>l2 then
s=s:sub(l1-l2+1,l1)
end
row[j]=s
end
out[i]=table.concat(row," | ")
end
local out={}
local report=profile.query(n)
for i,row in ipairs(report)do
for j=1,5 do
local s=tostring(row[j])
local l1,l2=#s,cols[j]
if l1<l2 then
s=s..(" "):rep(l2-l1)
elseif l1>l2 then
s=s:sub(l1-l2+1,l1)
end
row[j]=s
end
out[i]=table.concat(row," | ")
end
local row=" +-----+----------------------+----------+--------+----------------------------------+ \n"
local col=" | # | Function | Time | Calls | Code | \n"
local sz=row..col..row
if #out>0 then
sz=sz.." | "..table.concat(out," | \n | ").." | \n"
end
return "\n"..sz..row
local row=" +-----+----------------------+----------+--------+----------------------------------+ \n"
local col=" | # | Function | Time | Calls | Code | \n"
local sz=row..col..row
if #out>0 then
sz=sz.." | "..table.concat(out," | \n | ").." | \n"
end
return "\n"..sz..row
end
local switch=false
function profile.switch()
switch=not switch
if not switch then
profile.stop()
love.system.setClipboardText(PROFILE.report())
PROFILE.reset()
return false
else
PROFILE.start()
return true
end
switch=not switch
if not switch then
profile.stop()
love.system.setClipboardText(PROFILE.report())
PROFILE.reset()
return false
else
PROFILE.start()
return true
end
end
-- store all internal profiler functions
for _,v in next,profile do
_internal[v]=type(v)=='function'
_internal[v]=type(v)=='function'
end
return profile

View File

@@ -4,173 +4,173 @@ local abs=math.abs
local scenes={}
local SCN={
cur='NULL',--Current scene name
swapping=false,--If Swapping
stat={
tar=false, --Swapping target
style=false,--Swapping style
changeTime=false, --Loading point
time=false, --Full swap time
draw=false, --Swap draw func
},
stack={},--Scene stack
cur='NULL', --Current scene name
swapping=false, --If Swapping
stat={
tar=false, --Swapping target
style=false, --Swapping style
changeTime=false,--Loading point
time=false, --Full swap time
draw=false, --Swap draw func
},
stack={},--Scene stack
scenes=scenes,
scenes=scenes,
--Events
update=false,
draw=false,
mouseClick=false,
touchClick=false,
mouseDown=false,
mouseMove=false,
mouseUp=false,
wheelMoved=false,
touchDown=false,
touchUp=false,
touchMove=false,
keyDown=false,
keyUp=false,
gamepadDown=false,
gamepadUp=false,
fileDropped=false,
directoryDropped=false,
resize=false,
socketRead=false,
--Events
update=false,
draw=false,
mouseClick=false,
touchClick=false,
mouseDown=false,
mouseMove=false,
mouseUp=false,
wheelMoved=false,
touchDown=false,
touchUp=false,
touchMove=false,
keyDown=false,
keyUp=false,
gamepadDown=false,
gamepadUp=false,
fileDropped=false,
directoryDropped=false,
resize=false,
socketRead=false,
}--Scene datas, returned
function SCN.add(name,scene)
scenes[name]=scene
if scene.widgetList then
setmetatable(scene.widgetList,WIDGET.indexMeta)
end
scenes[name]=scene
if scene.widgetList then
setmetatable(scene.widgetList,WIDGET.indexMeta)
end
end
function SCN.swapUpdate()
local S=SCN.stat
S.time=S.time-1
if S.time==S.changeTime then
--Scene swapped this moment
SCN.init(S.tar,SCN.cur)
end
if S.time==0 then
SCN.swapping=false
end
local S=SCN.stat
S.time=S.time-1
if S.time==S.changeTime then
--Scene swapped this moment
SCN.init(S.tar,SCN.cur)
end
if S.time==0 then
SCN.swapping=false
end
end
function SCN.init(s,org)
love.keyboard.setTextInput(false)
love.keyboard.setTextInput(false)
local S=scenes[s]
SCN.cur=s
local S=scenes[s]
SCN.cur=s
WIDGET.setScrollHeight(S.widgetScrollHeight)
WIDGET.setWidgetList(S.widgetList)
SCN.sceneInit=S.sceneInit
SCN.sceneBack=S.sceneBack
SCN.mouseDown=S.mouseDown
SCN.mouseMove=S.mouseMove
SCN.mouseUp=S.mouseUp
SCN.mouseClick=S.mouseClick
SCN.wheelMoved=S.wheelMoved
SCN.touchDown=S.touchDown
SCN.touchUp=S.touchUp
SCN.touchMove=S.touchMove
SCN.touchClick=S.touchClick
SCN.keyDown=S.keyDown
SCN.keyUp=S.keyUp
SCN.gamepadDown=S.gamepadDown
SCN.gamepadUp=S.gamepadUp
SCN.fileDropped=S.fileDropped
SCN.directoryDropped=S.directoryDropped
SCN.resize=S.resize
SCN.socketRead=S.socketRead
SCN.update=S.update
SCN.draw=S.draw
if S.sceneInit then S.sceneInit(org)end
WIDGET.setScrollHeight(S.widgetScrollHeight)
WIDGET.setWidgetList(S.widgetList)
SCN.sceneInit=S.sceneInit
SCN.sceneBack=S.sceneBack
SCN.mouseDown=S.mouseDown
SCN.mouseMove=S.mouseMove
SCN.mouseUp=S.mouseUp
SCN.mouseClick=S.mouseClick
SCN.wheelMoved=S.wheelMoved
SCN.touchDown=S.touchDown
SCN.touchUp=S.touchUp
SCN.touchMove=S.touchMove
SCN.touchClick=S.touchClick
SCN.keyDown=S.keyDown
SCN.keyUp=S.keyUp
SCN.gamepadDown=S.gamepadDown
SCN.gamepadUp=S.gamepadUp
SCN.fileDropped=S.fileDropped
SCN.directoryDropped=S.directoryDropped
SCN.resize=S.resize
SCN.socketRead=S.socketRead
SCN.update=S.update
SCN.draw=S.draw
if S.sceneInit then S.sceneInit(org)end
end
function SCN.push(tar,style)
if not SCN.swapping then
local m=#SCN.stack
SCN.stack[m+1]=tar or SCN.cur
SCN.stack[m+2]=style or'fade'
end
if not SCN.swapping then
local m=#SCN.stack
SCN.stack[m+1]=tar or SCN.cur
SCN.stack[m+2]=style or'fade'
end
end
function SCN.pop()
local s=SCN.stack
s[#s],s[#s-1]=nil
local s=SCN.stack
s[#s],s[#s-1]=nil
end
local swap={
none={duration=1,changeTime=0,draw=function()end},
flash={duration=8,changeTime=1,draw=function()gc.clear(1,1,1)end},
fade={duration=30,changeTime=15,draw=function(t)
t=t>15 and 2-t/15 or t/15
gc.setColor(0,0,0,t)
gc.rectangle('fill',0,0,SCR.w,SCR.h)
end},
fade_togame={duration=120,changeTime=20,draw=function(t)
t=t>20 and(120-t)/100 or t/20
gc.setColor(0,0,0,t)
gc.rectangle('fill',0,0,SCR.w,SCR.h)
end},
slowFade={duration=180,changeTime=90,draw=function(t)
t=t>90 and 2-t/90 or t/90
gc.setColor(0,0,0,t)
gc.rectangle('fill',0,0,SCR.w,SCR.h)
end},
swipeL={duration=30,changeTime=15,draw=function(t)
t=t/30
gc.setColor(.1,.1,.1,1-abs(t-.5))
t=t*t*(3-2*t)*2-1
gc.rectangle('fill',t*SCR.w,0,SCR.w,SCR.h)
end},
swipeR={duration=30,changeTime=15,draw=function(t)
t=t/30
gc.setColor(.1,.1,.1,1-abs(t-.5))
t=t*t*(2*t-3)*2+1
gc.rectangle('fill',t*SCR.w,0,SCR.w,SCR.h)
end},
swipeD={duration=30,changeTime=15,draw=function(t)
t=t/30
gc.setColor(.1,.1,.1,1-abs(t-.5))
t=t*t*(2*t-3)*2+1
gc.rectangle('fill',0,t*SCR.h,SCR.w,SCR.h)
end},
none={duration=1,changeTime=0,draw=function()end},
flash={duration=8,changeTime=1,draw=function()gc.clear(1,1,1)end},
fade={duration=30,changeTime=15,draw=function(t)
t=t>15 and 2-t/15 or t/15
gc.setColor(0,0,0,t)
gc.rectangle('fill',0,0,SCR.w,SCR.h)
end},
fade_togame={duration=120,changeTime=20,draw=function(t)
t=t>20 and(120-t)/100 or t/20
gc.setColor(0,0,0,t)
gc.rectangle('fill',0,0,SCR.w,SCR.h)
end},
slowFade={duration=180,changeTime=90,draw=function(t)
t=t>90 and 2-t/90 or t/90
gc.setColor(0,0,0,t)
gc.rectangle('fill',0,0,SCR.w,SCR.h)
end},
swipeL={duration=30,changeTime=15,draw=function(t)
t=t/30
gc.setColor(.1,.1,.1,1-abs(t-.5))
t=t*t*(3-2*t)*2-1
gc.rectangle('fill',t*SCR.w,0,SCR.w,SCR.h)
end},
swipeR={duration=30,changeTime=15,draw=function(t)
t=t/30
gc.setColor(.1,.1,.1,1-abs(t-.5))
t=t*t*(2*t-3)*2+1
gc.rectangle('fill',t*SCR.w,0,SCR.w,SCR.h)
end},
swipeD={duration=30,changeTime=15,draw=function(t)
t=t/30
gc.setColor(.1,.1,.1,1-abs(t-.5))
t=t*t*(2*t-3)*2+1
gc.rectangle('fill',0,t*SCR.h,SCR.w,SCR.h)
end},
}--Scene swapping animations
function SCN.swapTo(tar,style)--Parallel scene swapping, cannot back
if scenes[tar]then
if not SCN.swapping and tar~=SCN.cur then
if not style then style='fade'end
SCN.swapping=true
local S=SCN.stat
S.tar,S.style=tar,style
S.time=swap[style].duration
S.changeTime=swap[style].changeTime
S.draw=swap[style].draw
end
else
MES.new('warn',"No Scene: "..tar)
end
if scenes[tar]then
if not SCN.swapping and tar~=SCN.cur then
if not style then style='fade'end
SCN.swapping=true
local S=SCN.stat
S.tar,S.style=tar,style
S.time=swap[style].duration
S.changeTime=swap[style].changeTime
S.draw=swap[style].draw
end
else
MES.new('warn',"No Scene: "..tar)
end
end
function SCN.go(tar,style)--Normal scene swapping, can back
if scenes[tar]then
SCN.push()
SCN.swapTo(tar,style)
else
MES.new('warn',"No Scene: "..tar)
end
if scenes[tar]then
SCN.push()
SCN.swapTo(tar,style)
else
MES.new('warn',"No Scene: "..tar)
end
end
function SCN.back()
if SCN.swapping then return end
if SCN.swapping then return end
--Leave scene
if SCN.sceneBack then SCN.sceneBack()end
--Leave scene
if SCN.sceneBack then SCN.sceneBack()end
--Poll&Back to previous Scene
local m=#SCN.stack
if m>0 then
SCN.swapTo(SCN.stack[m-1],SCN.stack[m])
SCN.stack[m],SCN.stack[m-1]=nil
end
--Poll&Back to previous Scene
local m=#SCN.stack
if m>0 then
SCN.swapTo(SCN.stack[m-1],SCN.stack[m])
SCN.stack[m],SCN.stack[m-1]=nil
end
end
return SCN

View File

@@ -1,73 +1,73 @@
local SCR={
w0=1280,h0=720, --Default Screen Size
x=0,y=0, --Up-left Coord on screen
cx=0,cy=0, --Center Coord on screen (Center X/Y)
ex=0,ey=0, --Down-right Coord on screen (End X/Y)
w=0,h=0, --Fullscreen w/h for graphic functions
W=0,H=0, --Fullscreen w/h for shader
safeX=0,safeY=0,--Safe area
safeW=0,safeH=0,--Safe area
rad=0, --Radius
k=1, --Scale size
dpi=1, --DPI from gc.getDPIScale()
w0=1280,h0=720, --Default Screen Size
x=0,y=0, --Up-left Coord on screen
cx=0,cy=0, --Center Coord on screen (Center X/Y)
ex=0,ey=0, --Down-right Coord on screen (End X/Y)
w=0,h=0, --Fullscreen w/h for graphic functions
W=0,H=0, --Fullscreen w/h for shader
safeX=0,safeY=0,--Safe area
safeW=0,safeH=0,--Safe area
rad=0, --Radius
k=1, --Scale size
dpi=1, --DPI from gc.getDPIScale()
--Screen transformation objects
origin=love.math.newTransform(),
xOy=love.math.newTransform(),
xOy_m=love.math.newTransform(),
xOy_ul=love.math.newTransform(),
xOy_u=love.math.newTransform(),
xOy_ur=love.math.newTransform(),
xOy_l=love.math.newTransform(),
xOy_r=love.math.newTransform(),
xOy_dl=love.math.newTransform(),
xOy_d=love.math.newTransform(),
xOy_dr=love.math.newTransform(),
--Screen transformation objects
origin=love.math.newTransform(),
xOy=love.math.newTransform(),
xOy_m=love.math.newTransform(),
xOy_ul=love.math.newTransform(),
xOy_u=love.math.newTransform(),
xOy_ur=love.math.newTransform(),
xOy_l=love.math.newTransform(),
xOy_r=love.math.newTransform(),
xOy_dl=love.math.newTransform(),
xOy_d=love.math.newTransform(),
xOy_dr=love.math.newTransform(),
}
function SCR.setSize(w,h)
SCR.w0,SCR.h0=w,h
SCR.w0,SCR.h0=w,h
end
function SCR.resize(w,h)
SCR.w,SCR.h,SCR.dpi=w,h,love.graphics.getDPIScale()
SCR.W,SCR.H=SCR.w*SCR.dpi,SCR.h*SCR.dpi
SCR.r=h/w
SCR.rad=(w^2+h^2)^.5
SCR.w,SCR.h,SCR.dpi=w,h,love.graphics.getDPIScale()
SCR.W,SCR.H=SCR.w*SCR.dpi,SCR.h*SCR.dpi
SCR.r=h/w
SCR.rad=(w^2+h^2)^.5
SCR.x,SCR.y=0,0
if SCR.r>=SCR.h0/SCR.w0 then
SCR.k=w/SCR.w0
SCR.y=(h-SCR.h0*SCR.k)/2
else
SCR.k=h/SCR.h0
SCR.x=(w-SCR.w0*SCR.k)/2
end
SCR.cx,SCR.cy=SCR.w/2,SCR.h/2
SCR.ex,SCR.ey=SCR.w-SCR.x,SCR.h-SCR.y
SCR.safeX,SCR.safeY,SCR.safeW,SCR.safeH=love.window.getSafeArea()
SCR.x,SCR.y=0,0
if SCR.r>=SCR.h0/SCR.w0 then
SCR.k=w/SCR.w0
SCR.y=(h-SCR.h0*SCR.k)/2
else
SCR.k=h/SCR.h0
SCR.x=(w-SCR.w0*SCR.k)/2
end
SCR.cx,SCR.cy=SCR.w/2,SCR.h/2
SCR.ex,SCR.ey=SCR.w-SCR.x,SCR.h-SCR.y
SCR.safeX,SCR.safeY,SCR.safeW,SCR.safeH=love.window.getSafeArea()
SCR.origin:setTransformation(0,0)
SCR.xOy:setTransformation(SCR.x,SCR.y,0,SCR.k)
SCR.xOy_m:setTransformation(w/2,h/2,0,SCR.k)
SCR.xOy_ul:setTransformation(0,0,0,SCR.k)
SCR.xOy_u:setTransformation(w/2,0,0,SCR.k)
SCR.xOy_ur:setTransformation(w,0,0,SCR.k)
SCR.xOy_l:setTransformation(0,h/2,0,SCR.k)
SCR.xOy_r:setTransformation(w,h/2,0,SCR.k)
SCR.xOy_dl:setTransformation(0,h,0,SCR.k)
SCR.xOy_d:setTransformation(w/2,h,0,SCR.k)
SCR.xOy_dr:setTransformation(w,h,0,SCR.k)
SCR.origin:setTransformation(0,0)
SCR.xOy:setTransformation(SCR.x,SCR.y,0,SCR.k)
SCR.xOy_m:setTransformation(w/2,h/2,0,SCR.k)
SCR.xOy_ul:setTransformation(0,0,0,SCR.k)
SCR.xOy_u:setTransformation(w/2,0,0,SCR.k)
SCR.xOy_ur:setTransformation(w,0,0,SCR.k)
SCR.xOy_l:setTransformation(0,h/2,0,SCR.k)
SCR.xOy_r:setTransformation(w,h/2,0,SCR.k)
SCR.xOy_dl:setTransformation(0,h,0,SCR.k)
SCR.xOy_d:setTransformation(w/2,h,0,SCR.k)
SCR.xOy_dr:setTransformation(w,h,0,SCR.k)
end
function SCR.info()
return{
("w0,h0 : %d, %d"):format(SCR.w0,SCR.h0),
("x,y : %d, %d"):format(SCR.x,SCR.y),
("cx,cy : %d, %d"):format(SCR.cx,SCR.cy),
("ex,ey : %d, %d"):format(SCR.ex,SCR.ey),
("w,h : %d, %d"):format(SCR.w,SCR.h),
("W,H : %d, %d"):format(SCR.W,SCR.H),
("safeX,safeY : %d, %d"):format(SCR.safeX,SCR.safeY),
("safeW,safeH : %d, %d"):format(SCR.safeW,SCR.safeH),
("k,dpi,rad : %.2f, %d, %.2f"):format(SCR.k,SCR.dpi,SCR.rad),
}
return{
("w0,h0 : %d, %d"):format(SCR.w0,SCR.h0),
("x,y : %d, %d"):format(SCR.x,SCR.y),
("cx,cy : %d, %d"):format(SCR.cx,SCR.cy),
("ex,ey : %d, %d"):format(SCR.ex,SCR.ey),
("w,h : %d, %d"):format(SCR.w,SCR.h),
("W,H : %d, %d"):format(SCR.W,SCR.H),
("safeX,safeY : %d, %d"):format(SCR.safeX,SCR.safeY),
("safeW,safeH : %d, %d"):format(SCR.safeW,SCR.safeH),
("k,dpi,rad : %.2f, %d, %.2f"):format(SCR.k,SCR.dpi,SCR.rad),
}
end
return SCR

View File

@@ -3,36 +3,36 @@ local newFont=gc.setNewFont
local setNewFont=gc.setFont
local fontCache,currentFontSize={}
if love.filesystem.getInfo('font.ttf')then
local fontData=love.filesystem.newFile('font.ttf')
function setFont(s)
if s~=currentFontSize then
if not fontCache[s]then
fontCache[s]=newFont(fontData,s)
end
setNewFont(fontCache[s])
currentFontSize=s
end
end
function getFont(s)
if not fontCache[s]then
fontCache[s]=newFont(fontData,s)
end
return fontCache[s]
end
local fontData=love.filesystem.newFile('font.ttf')
function setFont(s)
if s~=currentFontSize then
if not fontCache[s]then
fontCache[s]=newFont(fontData,s)
end
setNewFont(fontCache[s])
currentFontSize=s
end
end
function getFont(s)
if not fontCache[s]then
fontCache[s]=newFont(fontData,s)
end
return fontCache[s]
end
else
function setFont(s)
if s~=currentFontSize then
if not fontCache[s]then
fontCache[s]=newFont(s)
end
setNewFont(fontCache[s])
currentFontSize=s
end
end
function getFont(s)
if not fontCache[s]then
fontCache[s]=newFont(s)
end
return fontCache[s]
end
function setFont(s)
if s~=currentFontSize then
if not fontCache[s]then
fontCache[s]=newFont(s)
end
setNewFont(fontCache[s])
currentFontSize=s
end
end
function getFont(s)
if not fontCache[s]then
fontCache[s]=newFont(s)
end
return fontCache[s]
end
end

View File

@@ -1,87 +1,87 @@
local SFX={
getCount=function()return 0 end,
loadAll=function()error("Cannot load before init!")end,
fieldPlay=NULL,
play=NULL,
fplay=NULL,
reset=NULL,
getCount=function()return 0 end,
loadAll=function()error("Cannot load before init!")end,
fieldPlay=NULL,
play=NULL,
fplay=NULL,
reset=NULL,
}
function SFX.init(list)
SFX.init=nil
local rem=table.remove
local Sources={}
SFX.init=nil
local rem=table.remove
local Sources={}
local count=#list function SFX.getCount()return count end
function SFX.loadAll()
for i=1,count do
local N='media/SFX/'..list[i]..'.ogg'
if love.filesystem.getInfo(N)then
Sources[list[i]]={love.audio.newSource(N,'static')}
else
MES.new('warn',"No SFX file: "..N,.1)
end
end
local count=#list function SFX.getCount()return count end
function SFX.loadAll()
for i=1,count do
local N='media/SFX/'..list[i]..'.ogg'
if love.filesystem.getInfo(N)then
Sources[list[i]]={love.audio.newSource(N,'static')}
else
MES.new('warn',"No SFX file: "..N,.1)
end
end
function SFX.play(s,vol,pos)
if SETTING.sfx==0 or vol==0 then return end
local S=Sources[s]--Source list
if not S then return end
local n=1
while S[n]:isPlaying()do
n=n+1
if not S[n]then
S[n]=S[1]:clone()
S[n]:seek(0)
break
end
end
S=S[n]--AU_SRC
if S:getChannelCount()==1 then
if pos then
pos=pos*SETTING.stereo
S:setPosition(pos,1-pos^2,0)
else
S:setPosition(0,0,0)
end
end
S:setVolume(((vol or 1)*SETTING.sfx)^1.626)
S:play()
end
function SFX.fplay(s,vol,pos)
local S=Sources[s]--Source list
if not S then return end
local n=1
while S[n]:isPlaying()do
n=n+1
if not S[n]then
S[n]=S[1]:clone()
S[n]:seek(0)
break
end
end
S=S[n]--AU_SRC
if S:getChannelCount()==1 then
if pos then
pos=pos*SETTING.stereo
S:setPosition(pos,1-pos^2,0)
else
S:setPosition(0,0,0)
end
end
S:setVolume(vol^1.626)
S:play()
end
function SFX.reset()
for _,L in next,Sources do
if type(L)=='table'then
for i=#L,1,-1 do
if not L[i]:isPlaying()then
rem(L,i)
end
end
end
end
end
end
function SFX.play(s,vol,pos)
if SETTING.sfx==0 or vol==0 then return end
local S=Sources[s]--Source list
if not S then return end
local n=1
while S[n]:isPlaying()do
n=n+1
if not S[n]then
S[n]=S[1]:clone()
S[n]:seek(0)
break
end
end
S=S[n]--AU_SRC
if S:getChannelCount()==1 then
if pos then
pos=pos*SETTING.stereo
S:setPosition(pos,1-pos^2,0)
else
S:setPosition(0,0,0)
end
end
S:setVolume(((vol or 1)*SETTING.sfx)^1.626)
S:play()
end
function SFX.fplay(s,vol,pos)
local S=Sources[s]--Source list
if not S then return end
local n=1
while S[n]:isPlaying()do
n=n+1
if not S[n]then
S[n]=S[1]:clone()
S[n]:seek(0)
break
end
end
S=S[n]--AU_SRC
if S:getChannelCount()==1 then
if pos then
pos=pos*SETTING.stereo
S:setPosition(pos,1-pos^2,0)
else
S:setPosition(0,0,0)
end
end
S:setVolume(vol^1.626)
S:play()
end
function SFX.reset()
for _,L in next,Sources do
if type(L)=='table'then
for i=#L,1,-1 do
if not L[i]:isPlaying()then
rem(L,i)
end
end
end
end
end
end
end
return SFX

View File

@@ -5,144 +5,144 @@ local find,sub,upper=string.find,string.sub,string.upper
local char,byte=string.char,string.byte
do--function STRING.shiftChar(c)
local shiftMap={
['1']='!',['2']='@',['3']='#',['4']='$',['5']='%',
['6']='^',['7']='&',['8']='*',['9']='(',['0']=')',
['`']='~',['-']='_',['=']='+',
['[']='{',[']']='}',['\\']='|',
[';']=':',['\'']='"',
[',']='<',['.']='>',['/']='?',
}
function STRING.shiftChar(c)
return shiftMap[c]or upper(c)
end
local shiftMap={
['1']='!',['2']='@',['3']='#',['4']='$',['5']='%',
['6']='^',['7']='&',['8']='*',['9']='(',['0']=')',
['`']='~',['-']='_',['=']='+',
['[']='{',[']']='}',['\\']='|',
[';']=':',['\'']='"',
[',']='<',['.']='>',['/']='?',
}
function STRING.shiftChar(c)
return shiftMap[c]or upper(c)
end
end
function STRING.trim(s)
if not s:find("%S")then return""end
s=s:sub((s:find("%S"))):reverse()
return s:sub((s:find("%S"))):reverse()
if not s:find("%S")then return""end
s=s:sub((s:find("%S"))):reverse()
return s:sub((s:find("%S"))):reverse()
end
function STRING.split(s,sep,regex)
local L={}
local p1,p2=1--start,target
if regex then
while p1<=#s do
p2=find(s,sep,p1)or #s+1
L[#L+1]=sub(s,p1,p2-1)
p1=p2+#sep
end
else
while p1<=#s do
p2=find(s,sep,p1,true)or #s+1
L[#L+1]=sub(s,p1,p2-1)
p1=p2+#sep
end
end
return L
local L={}
local p1,p2=1--start,target
if regex then
while p1<=#s do
p2=find(s,sep,p1)or #s+1
L[#L+1]=sub(s,p1,p2-1)
p1=p2+#sep
end
else
while p1<=#s do
p2=find(s,sep,p1,true)or #s+1
L[#L+1]=sub(s,p1,p2-1)
p1=p2+#sep
end
end
return L
end
function STRING.simpEmailCheck(e)
e=STRING.split(e,"@")
if #e~=2 then return false end
if e[1]:sub(-1)=="."or e[2]:sub(-1)=="."then return false end
local e1,e2=STRING.split(e[1],"."),STRING.split(e[2],".")
if #e1*#e2==0 then return false end
for _,v in next,e1 do if #v==0 then return false end end
for _,v in next,e2 do if #v==0 then return false end end
return true
e=STRING.split(e,"@")
if #e~=2 then return false end
if e[1]:sub(-1)=="."or e[2]:sub(-1)=="."then return false end
local e1,e2=STRING.split(e[1],"."),STRING.split(e[2],".")
if #e1*#e2==0 then return false end
for _,v in next,e1 do if #v==0 then return false end end
for _,v in next,e2 do if #v==0 then return false end end
return true
end
function STRING.time(s)
if s<60 then
return format("%.3f\"",s)
elseif s<3600 then
return format("%d'%05.2f\"",int(s/60),s%60)
else
local h=int(s/3600)
return format("%d:%.2d'%05.2f\"",h,int(s/60%60),s%60)
end
if s<60 then
return format("%.3f\"",s)
elseif s<3600 then
return format("%d'%05.2f\"",int(s/60),s%60)
else
local h=int(s/3600)
return format("%d:%.2d'%05.2f\"",h,int(s/60%60),s%60)
end
end
do--function STRING.urlEncode(s)
local rshift=bit.rshift
local b16={[0]='0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}
function STRING.urlEncode(s)
local out=""
for i=1,#s do
if s:sub(i,i):match("[a-zA-Z0-9]")then
out=out..s:sub(i,i)
else
local b=s:byte(i)
out=out.."%"..b16[rshift(b,4)]..b16[b%16]
end
end
return out
end
local rshift=bit.rshift
local b16={[0]='0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}
function STRING.urlEncode(s)
local out=""
for i=1,#s do
if s:sub(i,i):match("[a-zA-Z0-9]")then
out=out..s:sub(i,i)
else
local b=s:byte(i)
out=out.."%"..b16[rshift(b,4)]..b16[b%16]
end
end
return out
end
end
function STRING.vcsEncrypt(text,key)
local keyLen=#key
local result=""
local buffer=""
for i=0,#text-1 do
buffer=buffer..char((byte(text,i+1)-32+byte(key,i%keyLen+1))%95+32)
if #buffer==26 then
result=result..buffer
buffer=""
end
end
return result..buffer
local keyLen=#key
local result=""
local buffer=""
for i=0,#text-1 do
buffer=buffer..char((byte(text,i+1)-32+byte(key,i%keyLen+1))%95+32)
if #buffer==26 then
result=result..buffer
buffer=""
end
end
return result..buffer
end
function STRING.vcsDecrypt(text,key)
local keyLen=#key
local result=""
local buffer=""
for i=0,#text-1 do
buffer=buffer..char((byte(text,i+1)-32-byte(key,i%keyLen+1))%95+32)
if #buffer==26 then
result=result..buffer
buffer=""
end
end
return result..buffer
local keyLen=#key
local result=""
local buffer=""
for i=0,#text-1 do
buffer=buffer..char((byte(text,i+1)-32-byte(key,i%keyLen+1))%95+32)
if #buffer==26 then
result=result..buffer
buffer=""
end
end
return result..buffer
end
function STRING.readLine(str)
local p=str:find("\n")
if p then
return str:sub(1,p-1),str:sub(p+1)
else
return str,""
end
local p=str:find("\n")
if p then
return str:sub(1,p-1),str:sub(p+1)
else
return str,""
end
end
function STRING.packBin(s)
return data.encode('string','base64',data.compress('string','zlib',s))
return data.encode('string','base64',data.compress('string','zlib',s))
end
function STRING.unpackBin(str)
local res
res,str=pcall(data.decode,'string','base64',str)
if not res then return end
res,str=pcall(data.decompress,'string','zlib',str)
if res then return str end
local res
res,str=pcall(data.decode,'string','base64',str)
if not res then return end
res,str=pcall(data.decompress,'string','zlib',str)
if res then return str end
end
function STRING.packText(s)
return data.encode('string','base64',data.compress('string','gzip',s))
return data.encode('string','base64',data.compress('string','gzip',s))
end
function STRING.unpackText(str)
local res
res,str=pcall(data.decode,'string','base64',str)
if not res then return end
res,str=pcall(data.decompress,'string','gzip',str)
if res then return str end
local res
res,str=pcall(data.decode,'string','base64',str)
if not res then return end
res,str=pcall(data.decompress,'string','gzip',str)
if res then return str end
end
function STRING.packTable(t)
return STRING.packText(JSON.encode(t))
return STRING.packText(JSON.encode(t))
end
function STRING.unpackTable(t)
return JSON.decode(STRING.unpackText(t))
return JSON.decode(STRING.unpackText(t))
end
return STRING

View File

@@ -10,23 +10,23 @@ local ins,rem=table.insert,table.remove
local fx={}
local function _normUpdate(S,dt)
S.t=S.t+dt*S.rate
return S.t>1
S.t=S.t+dt*S.rate
return S.t>1
end
local FXupdate={}
function FXupdate.badge(S,dt)
S.t=S.t+dt
if S.t<.2 then
S.x,S.y=S.x1-14,S.y1-14
elseif S.t<.8 then
local t=((S.t-.2)*1.6667)
t=(3-2*t)*t*t
S.x,S.y=S.x1*(1-t)+S.x2*t-14,S.y1*(1-t)+S.y2*t-14
else
S.x,S.y=S.x2-14,S.y2-14
end
return S.t>=1
S.t=S.t+dt
if S.t<.2 then
S.x,S.y=S.x1-14,S.y1-14
elseif S.t<.8 then
local t=((S.t-.2)*1.6667)
t=(3-2*t)*t*t
S.x,S.y=S.x1*(1-t)+S.x2*t-14,S.y1*(1-t)+S.y2*t-14
else
S.x,S.y=S.x2-14,S.y2-14
end
return S.t>=1
end
FXupdate.attack=_normUpdate
FXupdate.tap=_normUpdate
@@ -34,172 +34,172 @@ FXupdate.ripple=_normUpdate
FXupdate.rectRipple=_normUpdate
FXupdate.shade=_normUpdate
function FXupdate.cell(S,dt)
if S.vx then
S.x=S.x+S.vx*S.rate
S.y=S.y+S.vy*S.rate
if S.ax then
S.vx=S.vx+S.ax*S.rate
S.vy=S.vy+S.ay*S.rate
end
end
S.t=S.t+dt*S.rate
return S.t>1
if S.vx then
S.x=S.x+S.vx*S.rate
S.y=S.y+S.vy*S.rate
if S.ax then
S.vx=S.vx+S.ax*S.rate
S.vy=S.vy+S.ay*S.rate
end
end
S.t=S.t+dt*S.rate
return S.t>1
end
FXupdate.line=_normUpdate
local FXdraw={}
function FXdraw.badge(S)
gc_setColor(1,1,1,S.t<.2 and S.t*.6 or S.t<.8 and 1 or(1-S.t)*.6)
gc_draw(IMG.badgeIcon,S.x,S.y)
gc_setColor(1,1,1,S.t<.2 and S.t*.6 or S.t<.8 and 1 or(1-S.t)*.6)
gc_draw(IMG.badgeIcon,S.x,S.y)
end
function FXdraw.attack(S)
gc_setColor(S.r*2,S.g*2,S.b*2,S.a*min(4-S.t*4,1))
gc_setColor(S.r*2,S.g*2,S.b*2,S.a*min(4-S.t*4,1))
gc_setLineWidth(S.wid)
local t1,t2=max(5*S.t-4,0),min(S.t*4,1)
gc_line(
S.x1*(1-t1)+S.x2*t1,
S.y1*(1-t1)+S.y2*t1,
S.x1*(1-t2)+S.x2*t2,
S.y1*(1-t2)+S.y2*t2
)
gc_setLineWidth(S.wid)
local t1,t2=max(5*S.t-4,0),min(S.t*4,1)
gc_line(
S.x1*(1-t1)+S.x2*t1,
S.y1*(1-t1)+S.y2*t1,
S.x1*(1-t2)+S.x2*t2,
S.y1*(1-t2)+S.y2*t2
)
gc_setLineWidth(S.wid*.6)
t1,t2=max(4*S.t-3,0),min(S.t*5,1)
gc_line(
S.x1*(1-t1)+S.x2*t1,
S.y1*(1-t1)+S.y2*t1,
S.x1*(1-t2)+S.x2*t2,
S.y1*(1-t2)+S.y2*t2
)
gc_setLineWidth(S.wid*.6)
t1,t2=max(4*S.t-3,0),min(S.t*5,1)
gc_line(
S.x1*(1-t1)+S.x2*t1,
S.y1*(1-t1)+S.y2*t1,
S.x1*(1-t2)+S.x2*t2,
S.y1*(1-t2)+S.y2*t2
)
end
function FXdraw.tap(S)
local t=S.t
gc_setColor(1,1,1,(1-t)*.4)
gc_circle('fill',S.x,S.y,30*(1-t)^.5)
local t=S.t
gc_setColor(1,1,1,(1-t)*.4)
gc_circle('fill',S.x,S.y,30*(1-t)^.5)
end
function FXdraw.ripple(S)
local t=S.t
gc_setLineWidth(2)
gc_setColor(1,1,1,1-t)
gc_circle('line',S.x,S.y,t*(2-t)*S.r)
local t=S.t
gc_setLineWidth(2)
gc_setColor(1,1,1,1-t)
gc_circle('line',S.x,S.y,t*(2-t)*S.r)
end
function FXdraw.rectRipple(S)
gc_setLineWidth(6)
gc_setColor(1,1,1,1-S.t)
local r=(10*S.t)^1.2
gc_rectangle('line',S.x-r,S.y-r,S.w+2*r,S.h+2*r)
gc_setLineWidth(6)
gc_setColor(1,1,1,1-S.t)
local r=(10*S.t)^1.2
gc_rectangle('line',S.x-r,S.y-r,S.w+2*r,S.h+2*r)
end
function FXdraw.shade(S)
gc_setColor(S.r,S.g,S.b,1-S.t)
gc_rectangle('fill',S.x,S.y,S.w,S.h,2)
gc_setColor(S.r,S.g,S.b,1-S.t)
gc_rectangle('fill',S.x,S.y,S.w,S.h,2)
end
function FXdraw.cell(S)
gc_setColor(1,1,1,1-S.t)
gc_draw(S.image,S.x,S.y,nil,S.size,nil,S.cx,S.cy)
gc_setColor(1,1,1,1-S.t)
gc_draw(S.image,S.x,S.y,nil,S.size,nil,S.cx,S.cy)
end
function FXdraw.line(S)
gc_setColor(1,1,1,S.a*(1-S.t))
gc_line(S.x1,S.y1,S.x2,S.y2)
gc_setColor(1,1,1,S.a*(1-S.t))
gc_line(S.x1,S.y1,S.x2,S.y2)
end
local SYSFX={}
function SYSFX.update(dt)
for i=#fx,1,-1 do
if fx[i]:update(dt)then
rem(fx,i)
end
end
for i=#fx,1,-1 do
if fx[i]:update(dt)then
rem(fx,i)
end
end
end
function SYSFX.draw()
for i=1,#fx do
fx[i]:draw()
end
for i=1,#fx do
fx[i]:draw()
end
end
function SYSFX.newBadge(x1,y1,x2,y2)
ins(fx,{
update=FXupdate.badge,
draw=FXdraw.badge,
t=0,
x=x1,y=y1,
x1=x1,y1=y1,
x2=x2,y2=y2,
})
ins(fx,{
update=FXupdate.badge,
draw=FXdraw.badge,
t=0,
x=x1,y=y1,
x1=x1,y1=y1,
x2=x2,y2=y2,
})
end
function SYSFX.newAttack(rate,x1,y1,x2,y2,wid,r,g,b,a)
ins(fx,{
update=FXupdate.attack,
draw=FXdraw.attack,
t=0,
rate=rate,
x1=x1,y1=y1,--Start pos
x2=x2,y2=y2,--End pos
wid=wid,--Line width
r=r,g=g,b=b,a=a,
})
ins(fx,{
update=FXupdate.attack,
draw=FXdraw.attack,
t=0,
rate=rate,
x1=x1,y1=y1,--Start pos
x2=x2,y2=y2,--End pos
wid=wid,--Line width
r=r,g=g,b=b,a=a,
})
end
function SYSFX.newTap(rate,x,y)
local T=
{
update=FXupdate.tap,
draw=FXdraw.tap,
t=0,
rate=rate,
x=x,y=y,
}
ins(fx,T)
local T=
{
update=FXupdate.tap,
draw=FXdraw.tap,
t=0,
rate=rate,
x=x,y=y,
}
ins(fx,T)
end
function SYSFX.newRipple(rate,x,y,r)
ins(fx,{
update=FXupdate.ripple,
draw=FXdraw.ripple,
t=0,
rate=rate,
x=x,y=y,r=r,
})
ins(fx,{
update=FXupdate.ripple,
draw=FXdraw.ripple,
t=0,
rate=rate,
x=x,y=y,r=r,
})
end
function SYSFX.newRectRipple(rate,x,y,w,h)
ins(fx,{
update=FXupdate.rectRipple,
draw=FXdraw.rectRipple,
t=0,
rate=rate,
x=x,y=y,w=w,h=h,
})
ins(fx,{
update=FXupdate.rectRipple,
draw=FXdraw.rectRipple,
t=0,
rate=rate,
x=x,y=y,w=w,h=h,
})
end
function SYSFX.newShade(rate,x,y,w,h,r,g,b)
ins(fx,{
update=FXupdate.shade,
draw=FXdraw.shade,
t=0,
rate=rate,
x=x,y=y,w=w,h=h,
r=r or 1,g=g or 1,b=b or 1,
})
ins(fx,{
update=FXupdate.shade,
draw=FXdraw.shade,
t=0,
rate=rate,
x=x,y=y,w=w,h=h,
r=r or 1,g=g or 1,b=b or 1,
})
end
function SYSFX.newCell(rate,image,size,x,y,vx,vy,ax,ay)
ins(fx,{
update=FXupdate.cell,
draw=FXdraw.cell,
t=0,
rate=rate*(.9+rnd()*.2),
image=image,size=size,
cx=image:getWidth()*.5,cy=image:getHeight()*.5,
x=x,y=y,
vx=vx,vy=vy,
ax=ax,ay=ay,
})
ins(fx,{
update=FXupdate.cell,
draw=FXdraw.cell,
t=0,
rate=rate*(.9+rnd()*.2),
image=image,size=size,
cx=image:getWidth()*.5,cy=image:getHeight()*.5,
x=x,y=y,
vx=vx,vy=vy,
ax=ax,ay=ay,
})
end
function SYSFX.newLine(rate,x1,y1,x2,y2,r,g,b,a)
ins(fx,{
update=FXupdate.line,
draw=FXdraw.line,
t=0,
rate=rate,
x1=x1 or 0,y1=y1 or 0,
x2=x2 or x1 or 1280,y2=y2 or y1 or 720,
r=r or 1,g=g or 1,b=b or 1,a=a or 1,
})
ins(fx,{
update=FXupdate.line,
draw=FXdraw.line,
t=0,
rate=rate,
x1=x1 or 0,y1=y1 or 0,
x2=x2 or x1 or 1280,y2=y2 or y1 or 720,
r=r or 1,g=g or 1,b=b or 1,a=a or 1,
})
end
return SYSFX

View File

@@ -4,195 +4,195 @@ local TABLE={}
--Get a new filled table
function TABLE.new(val,count)
local L={}
for i=1,count do
L[i]=val
end
return L
local L={}
for i=1,count do
L[i]=val
end
return L
end
--Get a copy of [1~#] elements
function TABLE.shift(org,depth)
if not depth then depth=1e99 end
local L={}
for i=1,#org do
if type(org[i])=='table'and depth>0 then
L[i]=TABLE.shift(org[i],depth-1)
else
L[i]=org[i]
end
end
return L
if not depth then depth=1e99 end
local L={}
for i=1,#org do
if type(org[i])=='table'and depth>0 then
L[i]=TABLE.shift(org[i],depth-1)
else
L[i]=org[i]
end
end
return L
end
--Get a full copy of a table, depth = how many layers will be recreate, default to inf
function TABLE.copy(org,depth)
if not depth then depth=1e99 end
local L={}
for k,v in next,org do
if type(v)=='table'and depth>0 then
L[k]=TABLE.copy(v,depth-1)
else
L[k]=v
end
end
return L
if not depth then depth=1e99 end
local L={}
for k,v in next,org do
if type(v)=='table'and depth>0 then
L[k]=TABLE.copy(v,depth-1)
else
L[k]=v
end
end
return L
end
--For all things in new, push to old
function TABLE.cover(new,old)
for k,v in next,new do
old[k]=v
end
for k,v in next,new do
old[k]=v
end
end
--For all things in new if same type in old, push to old
function TABLE.update(new,old)
for k,v in next,new do
if type(v)==type(old[k])then
if type(v)=='table'then
TABLE.update(v,old[k])
else
old[k]=v
end
end
end
for k,v in next,new do
if type(v)==type(old[k])then
if type(v)=='table'then
TABLE.update(v,old[k])
else
old[k]=v
end
end
end
end
--For all things in new if no val in old, push to old
function TABLE.complete(new,old)
for k,v in next,new do
if type(v)=='table'then
if old[k]==nil then old[k]={}end
TABLE.complete(v,old[k])
elseif old[k]==nil then
old[k]=v
end
end
for k,v in next,new do
if type(v)=='table'then
if old[k]==nil then old[k]={}end
TABLE.complete(v,old[k])
elseif old[k]==nil then
old[k]=v
end
end
end
--Remove positive integer index of table
function TABLE.cut(G)
for i=1,#G do
G[i]=nil
end
for i=1,#G do
G[i]=nil
end
end
--Clear table
function TABLE.clear(G)
for k in next,G do
G[k]=nil
end
for k in next,G do
G[k]=nil
end
end
--Find value in [1~#]
function TABLE.find(t,val)
for i=1,#t do if t[i]==val then return i end end
for i=1,#t do if t[i]==val then return i end end
end
--Find value in whole table
function TABLE.search(t,val)
for k,v in next,t do if v==val then return k end end
for k,v in next,t do if v==val then return k end end
end
--Re-index string value of a table
function TABLE.reIndex(org)
for k,v in next,org do
if type(v)=='string'then
org[k]=org[v]
end
end
for k,v in next,org do
if type(v)=='string'then
org[k]=org[v]
end
end
end
--Dump a simple lua table
do--function TABLE.dump(L,t)
local tabs={
[0]="",
"\t",
"\t\t",
"\t\t\t",
"\t\t\t\t",
"\t\t\t\t\t",
}
local function dump(L,t)
local s
if t then
s="{\n"
else
s="return{\n"
t=1
if type(L)~='table'then
return
end
end
local count=1
for k,v in next,L do
local T=type(k)
if T=='number'then
if k==count then
k=""
count=count+1
else
k="["..k.."]="
end
elseif T=='string'then
if find(k,"[^0-9a-zA-Z_]")then
k="[\""..k.."\"]="
else
k=k.."="
end
elseif T=='boolean'then k="["..k.."]="
else error("Error key type!")
end
T=type(v)
if T=='number'then v=tostring(v)
elseif T=='string'then v="\""..v.."\""
elseif T=='table'then v=dump(v,t+1)
elseif T=='boolean'then v=tostring(v)
else error("Error data type!")
end
s=s..tabs[t]..k..v..",\n"
end
return s..tabs[t-1].."}"
end
TABLE.dump=dump
local tabs={
[0]="",
"\t",
"\t\t",
"\t\t\t",
"\t\t\t\t",
"\t\t\t\t\t",
}
local function dump(L,t)
local s
if t then
s="{\n"
else
s="return{\n"
t=1
if type(L)~='table'then
return
end
end
local count=1
for k,v in next,L do
local T=type(k)
if T=='number'then
if k==count then
k=""
count=count+1
else
k="["..k.."]="
end
elseif T=='string'then
if find(k,"[^0-9a-zA-Z_]")then
k="[\""..k.."\"]="
else
k=k.."="
end
elseif T=='boolean'then k="["..k.."]="
else error("Error key type!")
end
T=type(v)
if T=='number'then v=tostring(v)
elseif T=='string'then v="\""..v.."\""
elseif T=='table'then v=dump(v,t+1)
elseif T=='boolean'then v=tostring(v)
else error("Error data type!")
end
s=s..tabs[t]..k..v..",\n"
end
return s..tabs[t-1].."}"
end
TABLE.dump=dump
end
--Dump a simple lua table (no whitespaces)
do--function TABLE.dumpDeflate(L,t)
local function dump(L)
local s="return{"
if type(L)~='table'then return end
local count=1
for k,v in next,L do
local T=type(k)
if T=='number'then
if k==count then
k=""
count=count+1
else
k="["..k.."]="
end
elseif T=='string'then
if find(k,"[^0-9a-zA-Z_]")then
k="[\""..k.."\"]="
else
k=k.."="
end
elseif T=='boolean'then k="["..k.."]="
else error("Error key type!")
end
T=type(v)
if T=='number'then v=tostring(v)
elseif T=='string'then v="\""..v.."\""
elseif T=='table'then v=dump(v)
elseif T=='boolean'then v=tostring(v)
else error("Error data type!")
end
end
return s.."}"
end
TABLE.dumpDeflate=dump
local function dump(L)
local s="return{"
if type(L)~='table'then return end
local count=1
for k,v in next,L do
local T=type(k)
if T=='number'then
if k==count then
k=""
count=count+1
else
k="["..k.."]="
end
elseif T=='string'then
if find(k,"[^0-9a-zA-Z_]")then
k="[\""..k.."\"]="
else
k=k.."="
end
elseif T=='boolean'then k="["..k.."]="
else error("Error key type!")
end
T=type(v)
if T=='number'then v=tostring(v)
elseif T=='string'then v="\""..v.."\""
elseif T=='table'then v=dump(v)
elseif T=='boolean'then v=tostring(v)
else error("Error data type!")
end
end
return s.."}"
end
TABLE.dumpDeflate=dump
end
return TABLE

View File

@@ -4,48 +4,48 @@ local tasks={}
local TASK={}
function TASK.getCount()
return #tasks
return #tasks
end
function TASK.update()
for i=#tasks,1,-1 do
local T=tasks[i]
if status(T.thread)=='dead'then
rem(tasks,i)
else
assert(resume(T.thread))
end
end
for i=#tasks,1,-1 do
local T=tasks[i]
if status(T.thread)=='dead'then
rem(tasks,i)
else
assert(resume(T.thread))
end
end
end
function TASK.new(code,...)
local thread=coroutine.create(code)
resume(thread,...)
if status(thread)~='dead'then
tasks[#tasks+1]={
thread=thread,
code=code,
args={...},
}
end
local thread=coroutine.create(code)
resume(thread,...)
if status(thread)~='dead'then
tasks[#tasks+1]={
thread=thread,
code=code,
args={...},
}
end
end
function TASK.removeTask_code(code)
for i=#tasks,1,-1 do
if tasks[i].code==code then
rem(tasks,i)
end
end
for i=#tasks,1,-1 do
if tasks[i].code==code then
rem(tasks,i)
end
end
end
function TASK.removeTask_iterate(func,...)
for i=#tasks,1,-1 do
if func(tasks[i],...)then
rem(tasks,i)
end
end
for i=#tasks,1,-1 do
if func(tasks[i],...)then
rem(tasks,i)
end
end
end
function TASK.clear()
local i=#tasks
while i>0 do
tasks[i]=nil
i=i-1
end
local i=#tasks
while i>0 do
tasks[i]=nil
i=i-1
end
end
return TASK

View File

@@ -10,120 +10,120 @@ local texts={}
local textFX={}
function textFX.appear(t)
mStr(t.text,t.x,t.y-t.font*.7)
mStr(t.text,t.x,t.y-t.font*.7)
end
function textFX.sudden(t)
gc_setColor(1,1,1,1-t.c)
mStr(t.text,t.x,t.y-t.font*.7)
gc_setColor(1,1,1,1-t.c)
mStr(t.text,t.x,t.y-t.font*.7)
end
function textFX.fly(t)
mStr(t.text,t.x+(t.c-.5)^3*300,t.y-t.font*.7)
mStr(t.text,t.x+(t.c-.5)^3*300,t.y-t.font*.7)
end
function textFX.stretch(t)
gc_push('transform')
gc_translate(t.x,t.y)
if t.c<.3 then gc_scale((.3-t.c)*1.6+1,1)end
mStr(t.text,0,-t.font*.7)
gc_pop()
gc_push('transform')
gc_translate(t.x,t.y)
if t.c<.3 then gc_scale((.3-t.c)*1.6+1,1)end
mStr(t.text,0,-t.font*.7)
gc_pop()
end
function textFX.drive(t)
gc_push('transform')
gc_translate(t.x,t.y)
if t.c<.3 then gc_shear((.3-t.c)*2,0)end
mStr(t.text,0,-t.font*.7)
gc_pop()
gc_push('transform')
gc_translate(t.x,t.y)
if t.c<.3 then gc_shear((.3-t.c)*2,0)end
mStr(t.text,0,-t.font*.7)
gc_pop()
end
function textFX.spin(t)
gc_push('transform')
gc_translate(t.x,t.y)
if t.c<.3 then
gc_rotate((.3-t.c)^2*4)
elseif t.c>.8 then
gc_rotate((t.c-.8)^2*-4)
end
mStr(t.text,0,-t.font*.7)
gc_pop()
gc_push('transform')
gc_translate(t.x,t.y)
if t.c<.3 then
gc_rotate((.3-t.c)^2*4)
elseif t.c>.8 then
gc_rotate((t.c-.8)^2*-4)
end
mStr(t.text,0,-t.font*.7)
gc_pop()
end
function textFX.flicker(t)
local _,_,_,T=gc_getColor()
gc_setColor(1,1,1,T*(rnd()+.5))
mStr(t.text,t.x,t.y-t.font*.7)
local _,_,_,T=gc_getColor()
gc_setColor(1,1,1,T*(rnd()+.5))
mStr(t.text,t.x,t.y-t.font*.7)
end
function textFX.zoomout(t)
gc_push('transform')
local k=t.c^.5*.1+1
gc_translate(t.x,t.y)
gc_scale(k,k)
mStr(t.text,0,-t.font*.7)
gc_pop()
gc_push('transform')
local k=t.c^.5*.1+1
gc_translate(t.x,t.y)
gc_scale(k,k)
mStr(t.text,0,-t.font*.7)
gc_pop()
end
function textFX.beat(t)
gc_push('transform')
gc_translate(t.x,t.y)
if t.c<.3 then
local k=1.3-t.c^2/.3
gc_scale(k,k)
end
mStr(t.text,0,-t.font*.7)
gc_pop()
gc_push('transform')
gc_translate(t.x,t.y)
if t.c<.3 then
local k=1.3-t.c^2/.3
gc_scale(k,k)
end
mStr(t.text,0,-t.font*.7)
gc_pop()
end
function textFX.score(t)
local _,_,_,T=gc_getColor()
gc_setColor(1,1,1,T*.5)
mStr(t.text,t.x,t.y-t.font*.7-t.c^.2*50)
local _,_,_,T=gc_getColor()
gc_setColor(1,1,1,T*.5)
mStr(t.text,t.x,t.y-t.font*.7-t.c^.2*50)
end
local TEXT={}
function TEXT.clear()
texts={}
texts={}
end
function TEXT.show(text,x,y,font,style,spd,stop)
ins(texts,{
c=0, --Timer
text=text, --String
x=x or 0, --X
y=y or 0, --Y
font=int(font/5)*5 or 40, --Font
spd=(spd or 1)/60, --Timing speed(1=last 1 sec)
stop=stop, --Stop time(sustained text)
draw=textFX[style or'appear']or error("unavailable type:"..style), --Draw method
})
ins(texts,{
c=0, --Timer
text=text, --String
x=x or 0, --X
y=y or 0, --Y
font=int(font/5)*5 or 40,--Font
spd=(spd or 1)/60, --Timing speed(1=last 1 sec)
stop=stop, --Stop time(sustained text)
draw=assert(textFX[style or'appear'],"no text type:"..style),--Draw method
})
end
function TEXT.getText(text,x,y,font,style,spd,stop)--Another version of TEXT.show(), but only return text object, need manual management
return{
c=0,
text=text,
x=x or 0,
y=y or 0,
font=int(font/5)*5 or 40,
spd=(spd or 1)/60,
stop=stop,
draw=textFX[style or'appear']or error("unavailable type:"..style),
}
return{
c=0,
text=text,
x=x or 0,
y=y or 0,
font=int(font/5)*5 or 40,
spd=(spd or 1)/60,
stop=stop,
draw=textFX[style or'appear']or error("unavailable type:"..style),
}
end
function TEXT.update(list)
if not list then list=texts end
for i=#list,1,-1 do
local t=list[i]
t.c=t.c+t.spd
if t.stop then
if t.c>t.stop then
t.c=t.stop
end
end
if t.c>1 then
rem(list,i)
end
end
if not list then list=texts end
for i=#list,1,-1 do
local t=list[i]
t.c=t.c+t.spd
if t.stop then
if t.c>t.stop then
t.c=t.stop
end
end
if t.c>1 then
rem(list,i)
end
end
end
function TEXT.draw(list)
if not list then list=texts end
for i=1,#list do
local t=list[i]
local p=t.c
gc_setColor(1,1,1,p<.2 and p*5 or p<.8 and 1 or 5-p*5)
setFont(t.font)
t:draw()
end
if not list then list=texts end
for i=1,#list do
local t=list[i]
local p=t.c
gc_setColor(1,1,1,p<.2 and p*5 or p<.8 and 1 or 5-p*5)
setFont(t.font)
t:draw()
end
end
return TEXT

View File

@@ -1,97 +1,97 @@
local THEME={
cur=false,--Current theme
cur=false,--Current theme
}
local themeColor={
xmas={COLOR.R,COLOR.Z,COLOR.G},
sprfes={COLOR.R,COLOR.O,COLOR.Y},
xmas={COLOR.R,COLOR.Z,COLOR.G},
sprfes={COLOR.R,COLOR.O,COLOR.Y},
}
function THEME.calculate(Y,M,D)
if not Y then Y,M,D=os.date('%Y'),os.date('%m'),os.date('%d')end
--Festival calculate within one statement
return
--Christmas
M=='12'and math.abs(D-25)<4 and
'xmas'or
if not Y then Y,M,D=os.date('%Y'),os.date('%m'),os.date('%d')end
--Festival calculate within one statement
return
--Christmas
M=='12'and math.abs(D-25)<4 and
'xmas'or
--Birthday
M=='06'and D=='06'and
'birth'or
--Birthday
M=='06'and D=='06'and
'birth'or
--Spring festival
M<'03'and math.abs((({
--Festival days. Jan 26=26, Feb 1=32, etc.
24,43,32,22,40,29,49,38,26,45,
34,23,41,31,50,39,28,47,36,25,
43,32,22,41,29,48,37,26,44,34,
23,42,31,50,39,28,46,35,24,43,
32,22,41,30,48,37,26,45,33,23,
42,32,50,39,28,46,35,24,43,33,
21,40,
})[Y-2000]or -26)-((M-1)*31+D))<6 and
'sprfes'or
--Spring festival
M<'03'and math.abs((({
--Festival days. Jan 26=26, Feb 1=32, etc.
24,43,32,22,40,29,49,38,26,45,
34,23,41,31,50,39,28,47,36,25,
43,32,22,41,29,48,37,26,44,34,
23,42,31,50,39,28,46,35,24,43,
32,22,41,30,48,37,26,45,33,23,
42,32,50,39,28,46,35,24,43,33,
21,40,
})[Y-2000]or -26)-((M-1)*31+D))<6 and
'sprfes'or
--April fool's day
M=='04'and D=='01'and
'fool'or
--April fool's day
M=='04'and D=='01'and
'fool'or
--Z day
D=='26'and(
(M=='01'or M=='02'or M=='03')and'zday1'or
(M=='04'or M=='05'or M=='06')and'zday2'or
(M=='07'or M=='08'or M=='09')and'zday3'or
(M=='10'or M=='11'or M=='12')and'zday4'
)or
--Z day
D=='26'and(
(M=='01'or M=='02'or M=='03')and'zday1'or
(M=='04'or M=='05'or M=='06')and'zday2'or
(M=='07'or M=='08'or M=='09')and'zday3'or
(M=='10'or M=='11'or M=='12')and'zday4'
)or
'classic'
'classic'
end
function THEME.set(theme)
if theme=='classic'then
BG.setDefault('space')
BGM.setDefault('nil')
elseif theme=='xmas'then
BG.setDefault('snow')
BGM.setDefault('xmas')
MES.new('info',"==Merry Christmas==")
elseif theme=='birth'then
BG.setDefault('firework')
BGM.setDefault('magicblock')
elseif theme=='sprfes'then
BG.setDefault('firework')
BGM.setDefault('spring festival')
MES.new('info',"★☆新年快乐☆★")
elseif theme=='zday1'then
BG.setDefault('lanterns')
BGM.setDefault('overzero')
elseif theme=='zday2'then
BG.setDefault('lanterns')
BGM.setDefault('vacuum')
elseif theme=='zday3'then
BG.setDefault('lanterns')
BGM.setDefault('empty')
elseif theme=='zday4'then
BG.setDefault('lanterns')
BGM.setDefault('space')
elseif theme=='fool'then
BG.setDefault('blockrain')
BGM.setDefault('how feeling')
else
return
end
THEME.cur=theme
BG.set()
BGM.play()
return true
if theme=='classic'then
BG.setDefault('space')
BGM.setDefault('nil')
elseif theme=='xmas'then
BG.setDefault('snow')
BGM.setDefault('xmas')
MES.new('info',"==Merry Christmas==")
elseif theme=='birth'then
BG.setDefault('firework')
BGM.setDefault('magicblock')
elseif theme=='sprfes'then
BG.setDefault('firework')
BGM.setDefault('spring festival')
MES.new('info',"★☆新年快乐☆★")
elseif theme=='zday1'then
BG.setDefault('lanterns')
BGM.setDefault('overzero')
elseif theme=='zday2'then
BG.setDefault('lanterns')
BGM.setDefault('vacuum')
elseif theme=='zday3'then
BG.setDefault('lanterns')
BGM.setDefault('empty')
elseif theme=='zday4'then
BG.setDefault('lanterns')
BGM.setDefault('space')
elseif theme=='fool'then
BG.setDefault('blockrain')
BGM.setDefault('how feeling')
else
return
end
THEME.cur=theme
BG.set()
BGM.play()
return true
end
function THEME.getThemeColor(theme)
if not theme then theme=THEME.cur end
return themeColor[theme]
if not theme then theme=THEME.cur end
return themeColor[theme]
end
function THEME.fresh()
THEME.set(THEME.calculate(os.date('%Y'),os.date('%m'),os.date('%d')))
THEME.set(THEME.calculate(os.date('%Y'),os.date('%m'),os.date('%d')))
end
return THEME

View File

@@ -1,8 +1,8 @@
local level={0,0,.01,.016,.023,.03,.04,.05,.06,.07,.08,.09,.12,.15}
local vib=love.system.vibrate
return function(t)
local L=SETTING.vib
if L>0 then
vib(level[L+t])
end
local L=SETTING.vib
if L>0 then
vib(level[L+t])
end
end

View File

@@ -1,118 +1,118 @@
local VOC={
getCount=function()return 0 end,
getQueueCount=function()return 0 end,
loadAll=function()error("Cannot load before init!")end,
getFreeChannel=NULL,
play=NULL,
update=NULL,
getCount=function()return 0 end,
getQueueCount=function()return 0 end,
loadAll=function()error("Cannot load before init!")end,
getFreeChannel=NULL,
play=NULL,
update=NULL,
}
function VOC.init(list)
VOC.init=nil
local rnd=math.random
local rem=table.remove
local voiceQueue={free=0}
local bank={}--{vocName1={SRC1s},vocName2={SRC2s},...}
local Source={}
VOC.init=nil
local rnd=math.random
local rem=table.remove
local voiceQueue={free=0}
local bank={}--{vocName1={SRC1s},vocName2={SRC2s},...}
local Source={}
local count=#list function VOC.getCount()return count end
local function _loadVoiceFile(N,vocName)
local fileName='media/VOICE/'..SETTING.cv..'/'..vocName..'.ogg'
if love.filesystem.getInfo(fileName)then
bank[vocName]={love.audio.newSource(fileName,'stream')}
table.insert(Source[N],vocName)
return true
end
end
local function _getVoice(str)
local L=bank[str]
local n=1
while L[n]:isPlaying()do
n=n+1
if not L[n]then
L[n]=L[1]:clone()
L[n]:seek(0)
break
end
end
return L[n]
--Load voice with string
end
function VOC.loadAll()
for i=1,count do
Source[list[i]]={}
local count=#list function VOC.getCount()return count end
local function _loadVoiceFile(N,vocName)
local fileName='media/VOICE/'..SETTING.cv..'/'..vocName..'.ogg'
if love.filesystem.getInfo(fileName)then
bank[vocName]={love.audio.newSource(fileName,'stream')}
table.insert(Source[N],vocName)
return true
end
end
local function _getVoice(str)
local L=bank[str]
local n=1
while L[n]:isPlaying()do
n=n+1
if not L[n]then
L[n]=L[1]:clone()
L[n]:seek(0)
break
end
end
return L[n]
--Load voice with string
end
function VOC.loadAll()
for i=1,count do
Source[list[i]]={}
local n=0
repeat n=n+1 until not _loadVoiceFile(list[i],list[i]..'_'..n)
local n=0
repeat n=n+1 until not _loadVoiceFile(list[i],list[i]..'_'..n)
if n==1 then
if not _loadVoiceFile(list[i],list[i])then
MES.new('warn',"No VOICE file: "..list[i],.1)
end
end
if not Source[list[i]][1]then Source[list[i]]=nil end
end
if n==1 then
if not _loadVoiceFile(list[i],list[i])then
MES.new('warn',"No VOICE file: "..list[i],.1)
end
end
if not Source[list[i]][1]then Source[list[i]]=nil end
end
function VOC.getQueueCount()
return #voiceQueue
end
function VOC.getFreeChannel()
local l=#voiceQueue
for i=1,l do
if #voiceQueue[i]==0 then return i end
end
voiceQueue[l+1]={s=0}
return l+1
end
function VOC.getQueueCount()
return #voiceQueue
end
function VOC.getFreeChannel()
local l=#voiceQueue
for i=1,l do
if #voiceQueue[i]==0 then return i end
end
voiceQueue[l+1]={s=0}
return l+1
end
function VOC.play(s,chn)
if SETTING.voc>0 then
local _=Source[s]
if not _ then return end
if chn then
local L=voiceQueue[chn]
L[#L+1]=_[rnd(#_)]
L.s=1
--Add to queue[chn]
else
voiceQueue[VOC.getFreeChannel()]={s=1,_[rnd(#_)]}
--Create new channel & play
end
end
end
function VOC.update()
for i=#voiceQueue,1,-1 do
local Q=voiceQueue[i]
if Q.s==0 then--Free channel, auto delete when >3
if i>3 then
rem(voiceQueue,i)
end
elseif Q.s==1 then--Waiting load source
Q[1]=_getVoice(Q[1])
Q[1]:setVolume(SETTING.voc)
Q[1]:play()
Q.s=Q[2]and 2 or 4
elseif Q.s==2 then--Playing 1,ready 2
if Q[1]:getDuration()-Q[1]:tell()<.08 then
Q[2]=_getVoice(Q[2])
Q[2]:setVolume(SETTING.voc)
Q[2]:play()
Q.s=3
end
elseif Q.s==3 then--Playing 12 same time
if not Q[1]:isPlaying()then
for j=1,#Q do
Q[j]=Q[j+1]
end
Q.s=Q[2]and 2 or 4
end
elseif Q.s==4 then--Playing last
if not Q[1].isPlaying(Q[1])then
Q[1]=nil
Q.s=0
end
end
end
end
end
function VOC.play(s,chn)
if SETTING.voc>0 then
local _=Source[s]
if not _ then return end
if chn then
local L=voiceQueue[chn]
L[#L+1]=_[rnd(#_)]
L.s=1
--Add to queue[chn]
else
voiceQueue[VOC.getFreeChannel()]={s=1,_[rnd(#_)]}
--Create new channel & play
end
end
end
function VOC.update()
for i=#voiceQueue,1,-1 do
local Q=voiceQueue[i]
if Q.s==0 then--Free channel, auto delete when >3
if i>3 then
rem(voiceQueue,i)
end
elseif Q.s==1 then--Waiting load source
Q[1]=_getVoice(Q[1])
Q[1]:setVolume(SETTING.voc)
Q[1]:play()
Q.s=Q[2]and 2 or 4
elseif Q.s==2 then--Playing 1,ready 2
if Q[1]:getDuration()-Q[1]:tell()<.08 then
Q[2]=_getVoice(Q[2])
Q[2]:setVolume(SETTING.voc)
Q[2]:play()
Q.s=3
end
elseif Q.s==3 then--Playing 12 same time
if not Q[1]:isPlaying()then
for j=1,#Q do
Q[j]=Q[j+1]
end
Q.s=Q[2]and 2 or 4
end
elseif Q.s==4 then--Playing last
if not Q[1].isPlaying(Q[1])then
Q[1]=nil
Q.s=0
end
end
end
end
end
end
return VOC

View File

@@ -1,7 +1,7 @@
local host=
-- '127.0.0.1'
-- '192.168.114.102'
'game.techmino.org'
-- '127.0.0.1'
-- '192.168.114.102'
'game.techmino.org'
local port='10026'
local path='/tech/socket/v1'
@@ -18,174 +18,174 @@ local TRD_isRunning=TRD.isRunning
local WS={}
local wsList=setmetatable({},{
__index=function(l,k)
local ws={
real=false,
status='dead',
lastPongTime=timer(),
sendTimer=0,
alertTimer=0,
pongTimer=0,
}
l[k]=ws
return ws
end
__index=function(l,k)
local ws={
real=false,
status='dead',
lastPongTime=timer(),
sendTimer=0,
alertTimer=0,
pongTimer=0,
}
l[k]=ws
return ws
end
})
function WS.switchHost(_1,_2,_3)
for k in next,wsList do
WS.close(k)
end
host=_1
port=_2 or port
path=_3 or path
for k in next,wsList do
WS.close(k)
end
host=_1
port=_2 or port
path=_3 or path
end
function WS.connect(name,subPath,body,timeout)
if wsList[name]and wsList[name].thread then
wsList[name].thread:release()
end
local ws={
real=true,
thread=love.thread.newThread('Zframework/websocket_thread.lua'),
triggerCHN=love.thread.newChannel(),
sendCHN=love.thread.newChannel(),
readCHN=love.thread.newChannel(),
lastPingTime=0,
lastPongTime=timer(),
pingInterval=6,
status='connecting',--'connecting', 'running', 'dead'
sendTimer=0,
alertTimer=0,
pongTimer=0,
}
wsList[name]=ws
ws.thread:start(ws.triggerCHN,ws.sendCHN,ws.readCHN)
CHN_push(ws.sendCHN,host)
CHN_push(ws.sendCHN,port)
CHN_push(ws.sendCHN,path..subPath)
CHN_push(ws.sendCHN,body or"")
CHN_push(ws.sendCHN,timeout or 2.6)
if wsList[name]and wsList[name].thread then
wsList[name].thread:release()
end
local ws={
real=true,
thread=love.thread.newThread('Zframework/websocket_thread.lua'),
triggerCHN=love.thread.newChannel(),
sendCHN=love.thread.newChannel(),
readCHN=love.thread.newChannel(),
lastPingTime=0,
lastPongTime=timer(),
pingInterval=6,
status='connecting',--'connecting', 'running', 'dead'
sendTimer=0,
alertTimer=0,
pongTimer=0,
}
wsList[name]=ws
ws.thread:start(ws.triggerCHN,ws.sendCHN,ws.readCHN)
CHN_push(ws.sendCHN,host)
CHN_push(ws.sendCHN,port)
CHN_push(ws.sendCHN,path..subPath)
CHN_push(ws.sendCHN,body or"")
CHN_push(ws.sendCHN,timeout or 2.6)
end
function WS.status(name)
local ws=wsList[name]
return ws.status or'dead'
local ws=wsList[name]
return ws.status or'dead'
end
function WS.getTimers(name)
local ws=wsList[name]
return ws.pongTimer,ws.sendTimer,ws.alertTimer
local ws=wsList[name]
return ws.pongTimer,ws.sendTimer,ws.alertTimer
end
function WS.setPingInterval(name,time)
local ws=wsList[name]
ws.pingInterval=math.max(time or 2.6,2.6)
local ws=wsList[name]
ws.pingInterval=math.max(time or 2.6,2.6)
end
function WS.alert(name)
local ws=wsList[name]
ws.alertTimer=2.6
local ws=wsList[name]
ws.alertTimer=2.6
end
local OPcode={
continue=0,
text=1,
binary=2,
close=8,
ping=9,
pong=10,
continue=0,
text=1,
binary=2,
close=8,
ping=9,
pong=10,
}
local OPname={
[0]='continue',
[1]='text',
[2]='binary',
[8]='close',
[9]='ping',
[10]='pong',
[0]='continue',
[1]='text',
[2]='binary',
[8]='close',
[9]='ping',
[10]='pong',
}
function WS.send(name,message,op)
if type(message)=='string'then
local ws=wsList[name]
if ws.real and ws.status=='running'then
CHN_push(ws.sendCHN,op and OPcode[op]or 2)--2=binary
CHN_push(ws.sendCHN,message)
ws.lastPingTime=timer()
ws.sendTimer=1
end
else
MES.new('error',"Attempt to send non-string value!")
MES.traceback()
end
if type(message)=='string'then
local ws=wsList[name]
if ws.real and ws.status=='running'then
CHN_push(ws.sendCHN,op and OPcode[op]or 2)--2=binary
CHN_push(ws.sendCHN,message)
ws.lastPingTime=timer()
ws.sendTimer=1
end
else
MES.new('error',"Attempt to send non-string value!")
MES.traceback()
end
end
function WS.read(name)
local ws=wsList[name]
if ws.real and ws.status~='connecting'and CHN_getCount(ws.readCHN)>=2 then
local op,message=CHN_pop(ws.readCHN),CHN_pop(ws.readCHN)
if op==8 then--8=close
ws.status='dead'
elseif op==9 then--9=ping
WS.send(name,message or"",'pong')
end
ws.lastPongTime=timer()
ws.pongTimer=1
return message,OPname[op]or op
end
local ws=wsList[name]
if ws.real and ws.status~='connecting'and CHN_getCount(ws.readCHN)>=2 then
local op,message=CHN_pop(ws.readCHN),CHN_pop(ws.readCHN)
if op==8 then--8=close
ws.status='dead'
elseif op==9 then--9=ping
WS.send(name,message or"",'pong')
end
ws.lastPongTime=timer()
ws.pongTimer=1
return message,OPname[op]or op
end
end
function WS.close(name)
local ws=wsList[name]
if ws.real then
CHN_push(ws.sendCHN,8)--close
CHN_push(ws.sendCHN,"")
ws.status='dead'
end
local ws=wsList[name]
if ws.real then
CHN_push(ws.sendCHN,8)--close
CHN_push(ws.sendCHN,"")
ws.status='dead'
end
end
function WS.update(dt)
local time=timer()
for name,ws in next,wsList do
if ws.real and ws.status~='dead'then
if TRD_isRunning(ws.thread)then
if CHN_getCount(ws.triggerCHN)==0 then
CHN_push(ws.triggerCHN,0)
end
if ws.status=='connecting'then
local mes=CHN_pop(ws.readCHN)
if mes then
if mes=='success'then
ws.status='running'
ws.lastPingTime=time
ws.lastPongTime=time
ws.pongTimer=1
else
ws.status='dead'
MES.new('warn',text.wsFailed..": "..(mes=="timeout"and text.netTimeout or mes))
end
end
elseif ws.status=='running'then
if time-ws.lastPingTime>ws.pingInterval then
WS.send(name,"",'pong')
end
if time-ws.lastPongTime>6+2*ws.pingInterval then
WS.close(name)
end
end
if ws.sendTimer>0 then ws.sendTimer=ws.sendTimer-dt end
if ws.pongTimer>0 then ws.pongTimer=ws.pongTimer-dt end
if ws.alertTimer>0 then ws.alertTimer=ws.alertTimer-dt end
else
ws.status='dead'
local err=ws.thread:getError()
if err then
err=err:sub((err:find(":",(err:find(":")or 0)+1)or 0)+1,(err:find("\n")or 0)-1)
MES.new('warn',text.wsClose..err)
WS.alert(name)
end
end
end
end
local time=timer()
for name,ws in next,wsList do
if ws.real and ws.status~='dead'then
if TRD_isRunning(ws.thread)then
if CHN_getCount(ws.triggerCHN)==0 then
CHN_push(ws.triggerCHN,0)
end
if ws.status=='connecting'then
local mes=CHN_pop(ws.readCHN)
if mes then
if mes=='success'then
ws.status='running'
ws.lastPingTime=time
ws.lastPongTime=time
ws.pongTimer=1
else
ws.status='dead'
MES.new('warn',text.wsFailed..": "..(mes=="timeout"and text.netTimeout or mes))
end
end
elseif ws.status=='running'then
if time-ws.lastPingTime>ws.pingInterval then
WS.send(name,"",'pong')
end
if time-ws.lastPongTime>6+2*ws.pingInterval then
WS.close(name)
end
end
if ws.sendTimer>0 then ws.sendTimer=ws.sendTimer-dt end
if ws.pongTimer>0 then ws.pongTimer=ws.pongTimer-dt end
if ws.alertTimer>0 then ws.alertTimer=ws.alertTimer-dt end
else
ws.status='dead'
local err=ws.thread:getError()
if err then
err=err:sub((err:find(":",(err:find(":")or 0)+1)or 0)+1,(err:find("\n")or 0)-1)
MES.new('warn',text.wsClose..err)
WS.alert(name)
end
end
end
end
end
return WS

View File

@@ -7,57 +7,57 @@ local SOCK=require'socket'.tcp()
local JSON=require'Zframework.json'
do--Connect
local host=CHN_demand(sendCHN)
local port=CHN_demand(sendCHN)
local path=CHN_demand(sendCHN)
local body=CHN_demand(sendCHN)
local timeout=CHN_demand(sendCHN)
local host=CHN_demand(sendCHN)
local port=CHN_demand(sendCHN)
local path=CHN_demand(sendCHN)
local body=CHN_demand(sendCHN)
local timeout=CHN_demand(sendCHN)
SOCK:settimeout(timeout)
local res,err=SOCK:connect(host,port)
assert(res,err)
SOCK:settimeout(timeout)
local res,err=SOCK:connect(host,port)
assert(res,err)
--WebSocket handshake
if not body then body=''end
SOCK:send(
'GET '..path..' HTTP/1.1\r\n'..
'Host: '..host..':'..port..'\r\n'..
'Connection: Upgrade\r\n'..
'Upgrade: websocket\r\n'..
'Content-Type: application/json\r\n'..
'Content-Length: '..#body..'\r\n'..
'Sec-WebSocket-Version: 13\r\n'..
'Sec-WebSocket-Key: osT3F7mvlojIvf3/8uIsJQ==\r\n\r\n'..--secKey
body
)
--WebSocket handshake
if not body then body=''end
SOCK:send(
'GET '..path..' HTTP/1.1\r\n'..
'Host: '..host..':'..port..'\r\n'..
'Connection: Upgrade\r\n'..
'Upgrade: websocket\r\n'..
'Content-Type: application/json\r\n'..
'Content-Length: '..#body..'\r\n'..
'Sec-WebSocket-Version: 13\r\n'..
'Sec-WebSocket-Key: osT3F7mvlojIvf3/8uIsJQ==\r\n\r\n'..--secKey
body
)
--First line of HTTP
res,err=SOCK:receive('*l')
assert(res,err)
local code,ctLen
code=res:find(' ')
code=res:sub(code+1,code+3)
--First line of HTTP
res,err=SOCK:receive('*l')
assert(res,err)
local code,ctLen
code=res:find(' ')
code=res:sub(code+1,code+3)
--Get body length from headers and remove headers
repeat
res,err=SOCK:receive('*l')
assert(res,err)
if not ctLen and res:find('length')then
ctLen=tonumber(res:match('%d+'))
end
until res==''
--Get body length from headers and remove headers
repeat
res,err=SOCK:receive('*l')
assert(res,err)
if not ctLen and res:find('length')then
ctLen=tonumber(res:match('%d+'))
end
until res==''
--Result
if ctLen then
if code=='101'then
CHN_push(readCHN,'success')
else
res,err=SOCK:receive(ctLen)
res=JSON.decode(assert(res,err))
error((code or"XXX")..":"..(res and res.reason or"Server Error"))
end
end
SOCK:settimeout(0)
--Result
if ctLen then
if code=='101'then
CHN_push(readCHN,'success')
else
res,err=SOCK:receive(ctLen)
res=JSON.decode(assert(res,err))
error((code or"XXX")..":"..(res and res.reason or"Server Error"))
end
end
SOCK:settimeout(0)
end
local YIELD=coroutine.yield
@@ -68,121 +68,121 @@ local shl,shr=bit.lshift,bit.rshift
local mask_key={1,14,5,14}
local mask_str=char(unpack(mask_key))
local function _send(op,message)
--Message type
SOCK:send(char(bor(op,0x80)))
--Message type
SOCK:send(char(bor(op,0x80)))
if message then
--Length
local length=#message
if length>65535 then
SOCK:send(char(bor(127,0x80),0,0,0,0,band(shr(length,24),0xff),band(shr(length,16),0xff),band(shr(length,8),0xff),band(length,0xff)))
elseif length>125 then
SOCK:send(char(bor(126,0x80),band(shr(length,8),0xff),band(length,0xff)))
else
SOCK:send(char(bor(length,0x80)))
end
local msgbyte={byte(message,1,length)}
for i=1,length do
msgbyte[i]=bxor(msgbyte[i],mask_key[(i-1)%4+1])
end
return SOCK:send(mask_str..char(unpack(msgbyte)))
else
SOCK:send('\128'..mask_str)
return 0
end
if message then
--Length
local length=#message
if length>65535 then
SOCK:send(char(bor(127,0x80),0,0,0,0,band(shr(length,24),0xff),band(shr(length,16),0xff),band(shr(length,8),0xff),band(length,0xff)))
elseif length>125 then
SOCK:send(char(bor(126,0x80),band(shr(length,8),0xff),band(length,0xff)))
else
SOCK:send(char(bor(length,0x80)))
end
local msgbyte={byte(message,1,length)}
for i=1,length do
msgbyte[i]=bxor(msgbyte[i],mask_key[(i-1)%4+1])
end
return SOCK:send(mask_str..char(unpack(msgbyte)))
else
SOCK:send('\128'..mask_str)
return 0
end
end
local sendThread=coroutine.wrap(function()
while true do
while CHN_getCount(sendCHN)>=2 do
_send(CHN_pop(sendCHN),CHN_pop(sendCHN))
end
YIELD()
end
while true do
while CHN_getCount(sendCHN)>=2 do
_send(CHN_pop(sendCHN),CHN_pop(sendCHN))
end
YIELD()
end
end)
local function _receive(sock,len)
local buffer=""
while true do
local r,e,p=sock:receive(len)
if r then
buffer=buffer..r
len=len-#r
elseif p then
buffer=buffer..p
len=len-#p
elseif e then
return nil,e
end
if len==0 then
return buffer
end
YIELD()
end
local buffer=""
while true do
local r,e,p=sock:receive(len)
if r then
buffer=buffer..r
len=len-#r
elseif p then
buffer=buffer..p
len=len-#p
elseif e then
return nil,e
end
if len==0 then
return buffer
end
YIELD()
end
end
local readThread=coroutine.wrap(function()
local res,err
local op,fin
local lBuffer=""--Long multi-pack buffer
while true do
--Byte 0-1
res,err=_receive(SOCK,2)
assert(res,err)
local res,err
local op,fin
local lBuffer=""--Long multi-pack buffer
while true do
--Byte 0-1
res,err=_receive(SOCK,2)
assert(res,err)
op=band(byte(res,1),0x0f)
fin=band(byte(res,1),0x80)==0x80
op=band(byte(res,1),0x0f)
fin=band(byte(res,1),0x80)==0x80
--Calculating data length
local length=band(byte(res,2),0x7f)
if length==126 then
res,err=_receive(SOCK,2)
assert(res,err)
length=shl(byte(res,1),8)+byte(res,2)
elseif length==127 then
local lenData
lenData,err=_receive(SOCK,8)
assert(res,err)
local _,_,_,_,_5,_6,_7,_8=byte(lenData,1,8)
length=shl(_5,24)+shl(_6,16)+shl(_7,8)+_8
end
res,err=_receive(SOCK,length)
assert(res,err)
--Calculating data length
local length=band(byte(res,2),0x7f)
if length==126 then
res,err=_receive(SOCK,2)
assert(res,err)
length=shl(byte(res,1),8)+byte(res,2)
elseif length==127 then
local lenData
lenData,err=_receive(SOCK,8)
assert(res,err)
local _,_,_,_,_5,_6,_7,_8=byte(lenData,1,8)
length=shl(_5,24)+shl(_6,16)+shl(_7,8)+_8
end
res,err=_receive(SOCK,length)
assert(res,err)
--React
if op==8 then--8=close
CHN_push(readCHN,8)--close
if type(res)=='string'then
CHN_push(readCHN,res:sub(3))--Warning: 2 bytes close code at start so :sub(3)
else
CHN_push(readCHN,"WS closed")
end
return
elseif op==0 then--0=continue
lBuffer=lBuffer..res
if fin then
CHN_push(readCHN,lBuffer)
lBuffer=""
end
else
CHN_push(readCHN,op)
if fin then
CHN_push(readCHN,res)
lBuffer=""
else
lBuffer=res
end
end
YIELD()
end
--React
if op==8 then--8=close
CHN_push(readCHN,8)--close
if type(res)=='string'then
CHN_push(readCHN,res:sub(3))--Warning: 2 bytes close code at start so :sub(3)
else
CHN_push(readCHN,"WS closed")
end
return
elseif op==0 then--0=continue
lBuffer=lBuffer..res
if fin then
CHN_push(readCHN,lBuffer)
lBuffer=""
end
else
CHN_push(readCHN,op)
if fin then
CHN_push(readCHN,res)
lBuffer=""
else
lBuffer=res
end
end
YIELD()
end
end)
local success,err
while true do--Running
CHN_demand(triggerCHN)
success,err=pcall(sendThread)
if not success or err then break end
success,err=pcall(readThread)
if not success or err then break end
CHN_demand(triggerCHN)
success,err=pcall(sendThread)
if not success or err then break end
success,err=pcall(readThread)
if not success or err then break end
end
SOCK:close()

View File

@@ -2,18 +2,18 @@ local love=love
local max,min=math.max,math.min
local float=0
return function(y,key1,key2)
if y>0 then
float=max(float,0)+y^1.2
elseif y<0 then
if float>0 then float=0 end
float=min(float,0)-(-y)^1.2
end
while float>=1 do
love.keypressed(key1 or"up")
float=float-1
end
while float<=-1 do
love.keypressed(key2 or"down")
float=float+1
end
if y>0 then
float=max(float,0)+y^1.2
elseif y<0 then
if float>0 then float=0 end
float=min(float,0)-(-y)^1.2
end
while float>=1 do
love.keypressed(key1 or"up")
float=float-1
end
while float<=-1 do
love.keypressed(key2 or"down")
float=float+1
end
end

File diff suppressed because it is too large Load Diff

View File

@@ -6,18 +6,18 @@ FILETYPE 0x1
{
BLOCK "StringFileInfo"
{
BLOCK "040904B0"
{
VALUE "FileDescription", "Techmino Alpha"
VALUE "CompanyName", "26F Studio"
VALUE "LegalCopyright", "Copyright @ 26F Studio"
VALUE "ProductName", "Techmino"
VALUE "ProductVersion", "@Version"
}
BLOCK "040904B0"
{
VALUE "FileDescription", "Techmino Alpha"
VALUE "CompanyName", "26F Studio"
VALUE "LegalCopyright", "Copyright @ 26F Studio"
VALUE "ProductName", "Techmino"
VALUE "ProductVersion", "@Version"
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x0409 0x04E4
VALUE "Translation", 0x0409 0x04E4
}
}

View File

@@ -2,55 +2,55 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>19B88</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>love</string>
<key>CFBundleIconFile</key>
<string>iconfile</string>
<key>CFBundleIdentifier</key>
<string>org.love2d.MrZ.Techmino</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Techmino</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>@versionName</string>
<key>CFBundleSignature</key>
<string>LoVe</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>11C504</string>
<key>DTPlatformVersion</key>
<string>GM</string>
<key>DTSDKBuild</key>
<string>19B90</string>
<key>DTSDKName</key>
<string>macosx10.15</string>
<key>DTXcode</key>
<string>1130</string>
<key>DTXcodeBuild</key>
<string>11C504</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.games</string>
<key>LSMinimumSystemVersion</key>
<string>10.7</string>
<key>NSHighResolutionCapable</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>©2020-@thisYear 26F Studio, GNU LGPLv3.0</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<false/>
<key>BuildMachineOSBuild</key>
<string>19B88</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>love</string>
<key>CFBundleIconFile</key>
<string>iconfile</string>
<key>CFBundleIdentifier</key>
<string>org.love2d.MrZ.Techmino</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Techmino</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>@versionName</string>
<key>CFBundleSignature</key>
<string>LoVe</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>11C504</string>
<key>DTPlatformVersion</key>
<string>GM</string>
<key>DTSDKBuild</key>
<string>19B90</string>
<key>DTSDKName</key>
<string>macosx10.15</string>
<key>DTXcode</key>
<string>1130</string>
<key>DTXcodeBuild</key>
<string>11C504</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.games</string>
<key>LSMinimumSystemVersion</key>
<string>10.7</string>
<key>NSHighResolutionCapable</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>©2020-@thisYear 26F Studio, GNU LGPLv3.0</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<false/>
</dict>
</plist>

View File

@@ -1,35 +1,35 @@
function love.conf(t)
t.identity='Techmino'--Saving folder
t.version="11.1"
t.gammacorrect=false
t.appendidentity=true--Search files in source then in save directory
t.accelerometerjoystick=false--Accelerometer=joystick on ios/android
if t.audio then
t.audio.mic=false
t.audio.mixwithsystem=true
end
t.identity='Techmino'--Saving folder
t.version="11.1"
t.gammacorrect=false
t.appendidentity=true--Search files in source then in save directory
t.accelerometerjoystick=false--Accelerometer=joystick on ios/android
if t.audio then
t.audio.mic=false
t.audio.mixwithsystem=true
end
local W=t.window
W.title="Techmino "..require"version".string
W.icon="media/image/icon.png"
W.width,W.height=1280,720
W.minwidth,W.minheight=640,360
W.borderless=false
W.resizable=true
W.fullscreen=false
W.vsync=0--Unlimited FPS
W.msaa=0--Multi-sampled antialiasing
W.depth=0--Bits/samp of depth buffer
W.stencil=1--Bits/samp of stencil buffer
W.display=1--Monitor ID
W.highdpi=true--High-dpi mode for the window on a Retina display
W.x,W.y=nil
local W=t.window
W.title="Techmino "..require"version".string
W.icon="media/image/icon.png"
W.width,W.height=1280,720
W.minwidth,W.minheight=640,360
W.borderless=false
W.resizable=true
W.fullscreen=false
W.vsync=0--Unlimited FPS
W.msaa=0--Multi-sampled antialiasing
W.depth=0--Bits/samp of depth buffer
W.stencil=1--Bits/samp of stencil buffer
W.display=1--Monitor ID
W.highdpi=true--High-dpi mode for the window on a Retina display
W.x,W.y=nil
local M=t.modules
M.window,M.system,M.event,M.thread=true,true,true,true
M.timer,M.math,M.data=true,true,true
M.video,M.audio,M.sound=true,true,true
M.graphics,M.font,M.image=true,true,true
M.mouse,M.touch,M.keyboard,M.joystick=true,true,true,true
M.physics=false
local M=t.modules
M.window,M.system,M.event,M.thread=true,true,true,true
M.timer,M.math,M.data=true,true,true
M.video,M.audio,M.sound=true,true,true
M.graphics,M.font,M.image=true,true,true
M.mouse,M.touch,M.keyboard,M.joystick=true,true,true,true
M.physics=false
end

View File

@@ -1,158 +1,158 @@
模式文件应当是一个合(语)法的lua程序文件其必须返回一个table里面的内容包括
color:
必选
模式的颜色,用于点击地图图标后显示的提示文本
env:
必选
模式环境变量,决定了关卡的各项属性
*属性名* *默认值* *说明*
drop 60 下落延迟(帧支持自然数和2的整数次幂)
lock 60 锁定延迟(帧)
wait 0 出块延迟(帧)
fall 0 消行延迟(帧)
bone false 是否开启骨块模式
fieldH 20 场地高度
heightLimit 1e99 允许的最大场地高度
nextCount 6 显示next个数
nextStartPos 1 next从第几个开始显示
holdCount 1 hold个数
infHold false 是否能无限hold
phyHold false 是否开启物理hold
ospin true 是否能O-spin
deepDrop false 是否开启深降
RS 'TRS' 旋转系统名
color:
必选
模式的颜色,用于点击地图图标后显示的提示文本
env:
必选
模式环境变量,决定了关卡的各项属性
*属性名* *默认值* *说明*
drop 60 下落延迟(帧支持自然数和2的整数次幂)
lock 60 锁定延迟(帧)
wait 0 出块延迟(帧)
fall 0 消行延迟(帧)
bone false 是否开启骨块模式
fieldH 20 场地高度
heightLimit 1e99 允许的最大场地高度
nextCount 6 显示next个数
nextStartPos 1 next从第几个开始显示
holdCount 1 hold个数
infHold false 是否能无限hold
phyHold false 是否开启物理hold
ospin true 是否能O-spin
deepDrop false 是否开启深降
RS 'TRS' 旋转系统名
das 10 DAS
arr 2 ARR
sddas 2 软降DAS
sdarr 2 软降ARR
mindas 0 允许的最小DAS
minarr 0 允许的最小ARR
minsdarr 0 允许的最小软降ARR
ihs true 提前Hold
irs true 提前旋转
ims true 提前移动
das 10 DAS
arr 2 ARR
sddas 2 软降DAS
sdarr 2 软降ARR
mindas 0 允许的最小DAS
minarr 0 允许的最小ARR
minsdarr 0 允许的最小软降ARR
ihs true 提前Hold
irs true 提前旋转
ims true 提前移动
skinSet [设置] 方块贴图,只能填写内置皮肤的名字
skin [设置] 方块颜色包含25个整数(1~16)的table
face [设置] 方块朝向包含25个整数(0~3)的table
skinSet [设置] 方块贴图,只能填写内置皮肤的名字
skin [设置] 方块颜色包含25个整数(1~16)的table
face [设置] 方块朝向包含25个整数(0~3)的table
block true 是否显示方块
ghost 0.3 影子透明度(0~1)
center 1 旋转中心透明度(0~1)
smooth false 是否平滑下落
grid 0.16 网格透明度(0~1)
bagLine true 是否显示包分界线(如果存在)
lockFX 2 锁定特效等级(0~5整数)
dropFX 2 瞬间下落特效等级(0~5整数)
moveFX 2 移动特效等级(0~5整数)
clearFX 2 消除特效等级(0~5整数)
splashFX 2 溅射特效等级(0~5整数)
shakeFX 2 晃动特效等级(0~5整数)
atkFX 2 攻击特效等级(0~5整数)
block true 是否显示方块
ghost 0.3 影子透明度(0~1)
center 1 旋转中心透明度(0~1)
smooth false 是否平滑下落
grid 0.16 网格透明度(0~1)
bagLine true 是否显示包分界线(如果存在)
lockFX 2 锁定特效等级(0~5整数)
dropFX 2 瞬间下落特效等级(0~5整数)
moveFX 2 移动特效等级(0~5整数)
clearFX 2 消除特效等级(0~5整数)
splashFX 2 溅射特效等级(0~5整数)
shakeFX 2 晃动特效等级(0~5整数)
atkFX 2 攻击特效等级(0~5整数)
text true 是否显示消行文本
score true 是否显示落块分数
highCam false 是否开启超屏视野
nextPos false 是否开启生成预览
showSpike false 是否开启spike计数器
text true 是否显示消行文本
score true 是否显示落块分数
highCam false 是否开启超屏视野
nextPos false 是否开启生成预览
showSpike false 是否开启spike计数器
hideBoard false 场地隐藏模式("down"|"up"|"all")
flipBoard false 场地翻转模式("U-D"|"L-R"|"180")
hideBoard false 场地隐藏模式("down"|"up"|"all")
flipBoard false 场地翻转模式("U-D"|"L-R"|"180")
sequence 'bag' 序列模式是放一块后对next序列的刷新函数可以使用默认的几个函数用字符串表示。也可以自己写一个注意使用协程技术
seqData {1,2,3,4,5,6,7}序列模式使用的"包"数据(本质是生成序列用的数据会作为参数传进上面那个叫sequence的序列生成函数不一定是包)
mission false 包含任务的table说明暂时略
sequence bag' 序列模式是放一块后对next序列的刷新函数可以使用默认的几个函数用字符串表示。也可以自己写一个注意使用协程技术
seqData {1,2,3,4,5,6,7}序列模式使用的"包"数据(本质是生成序列用的数据会作为参数传进上面那个叫sequence的序列生成函数不一定是包)
mission false 包含任务的table说明暂时略
life 0 生命数(复活次数)
garbageSpeed 1 垃圾行释放速度
pushSpeed 3 垃圾行上涨速度
noTele false 是否禁止10个高级按键
visible 'show' 方块可见性,填写固定的几个字符串
freshLimit 1e99 锁延刷新次数限制
easyFresh true 是否使用简单锁延刷新规则
bufferLimit 1e99 攻击缓冲行数上限
life 0 生命数(复活次数)
garbageSpeed 1 垃圾行释放速度
pushSpeed 3 垃圾行上涨速度
noTele false 是否禁止10个高级按键
visible 'show' 方块可见性,填写固定的几个字符串
freshLimit 1e99 锁延刷新次数限制
easyFresh true 是否使用简单锁延刷新规则
bufferLimit 1e99 攻击缓冲行数上限
fkey1 false 按下功能键1后执行的函数
fkey2 false 按下功能键2后执行的函数
keyCancel {} 包含禁止使用的按键的id例如{1,2}就是禁止左移和右移
fine [设置] 是否开启非极简提示音
fineKill false 是否开启非极简即死
b2bKill false 是否开启断b2b即死
missionKill false 是否开启强制任务
dropPiece NULL 放一块后要执行的函数,输入玩家对象
task NULL 每帧会*继续执行*的函数,输入玩家对象,注意:使用协程技术
noInitSZO false 是否禁止SZO块开局如果禁止开局序列会自动跳过最多连续五个SZO
fkey1 false 按下功能键1后执行的函数
fkey2 false 按下功能键2后执行的函数
keyCancel {} 包含禁止使用的按键的id例如{1,2}就是禁止左移和右移
fine [设置] 是否开启非极简提示音
fineKill false 是否开启非极简即死
b2bKill false 是否开启断b2b即死
missionKill false 是否开启强制任务
dropPiece NULL 放一块后要执行的函数,输入玩家对象
task NULL 每帧会*继续执行*的函数,输入玩家对象,注意:使用协程技术
noInitSZO false 是否禁止SZO块开局如果禁止开局序列会自动跳过最多连续五个SZO
bg 'none' 背景,只能填写内置背景的名字
bgm 'race' 背景音乐名(或者列表随机,例如{'race','push'}),只能用内置音乐库的音乐名
allowMod true 是否允许mod
load:
必选
模式初始化函数,一般创建一个玩家即可
无输入
无输出
mesDisp:
必选
模式显示信息,是一个绘图函数,坐标系原点是玩家对象最左上角
输入玩家对象
无输出
bg 'none' 背景,只能填写内置背景的名字
bgm 'race' 背景音乐名(或者列表随机,例如{'race','push'}),只能用内置音乐库的音乐名
allowMod true 是否允许mod
load:
必选
模式初始化函数,一般创建一个玩家即可
无输入
无输出
mesDisp:
必选
模式显示信息,是一个绘图函数,坐标系原点是玩家对象最左上角
输入玩家对象
无输出
score:
可选(不填就没有分数保存和计算)
一局打完后要存储的数据
输入玩家对象
输出游戏结束瞬间返回一个包含直接决定该模式成绩的数据table(会被强制加上date标签)
score:
可选(不填就没有分数保存和计算)
一局打完后要存储的数据
输入玩家对象
输出游戏结束瞬间返回一个包含直接决定该模式成绩的数据table(会被强制加上date标签)
scoreDisp:
可选(模式不出现在地图上的时候不用写)
是把score()存起来的table转换为字符串显示出来的函数
输入一个成绩table
输出一个字符串
scoreDisp:
可选(模式不出现在地图上的时候不用写)
是把score()存起来的table转换为字符串显示出来的函数
输入一个成绩table
输出一个字符串
comp:
可选(没有score函数的时候不用写)
是成绩table之间对比并排序的规则
输入两个成绩table
输出[第一个是不是排在第二个前面]的布尔值(可以类比"小于"运算)
comp:
可选(没有score函数的时候不用写)
是成绩table之间对比并排序的规则
输入两个成绩table
输出[第一个是不是排在第二个前面]的布尔值(可以类比"小于"运算)
getRank:
可选,模式评级函数
是用于评价玩家表现的函数
输入玩家对象
输出0~50表示除了记录到排行榜外什么都不做1/2/3/4/5表示D/C/B/A/S级能解锁连接的模式还会让模式图标在地图上显示不同的颜色
getRank:
可选,模式评级函数
是用于评价玩家表现的函数
输入玩家对象
输出0~50表示除了记录到排行榜外什么都不做1/2/3/4/5表示D/C/B/A/S级能解锁连接的模式还会让模式图标在地图上显示不同的颜色
以下是40行的模式文件内容:
//sprint_40l.lua
return{--返回一个table你也可以在之前定义一些常量或者函数什么的
color=COLOR.green,--颜色
env={--模式环境变量
drop=60,lock=60,
dropPiece=function(P)if P.stat.row>=40 then P win('finish')end end,
bg='bg2',bgm='race',
},
load=function()--模式加载函数,这里只生成了一个玩家,常用的单人模式可以不写,默认使用这个函数
PLY.newPlayer(1)--1是玩家编号默认用户控制1号玩家
end,
mesDisp=function(P)--40行模式需要显示的信息
setFont(55)
local r=40-P.stat.row
if r<0 then r=0 end
mStr(r,63,265)--把计算出来的剩余行数r显示出来
PLY.draw.drawTargetLine(P,r)--使用自带的境界高度线绘制函数
end,
score=function(P)return{P.stat.time,P.stat.piece}end,--游戏结束时需要保存的本局关键信息
scoreDisp=function(D)return STRING.time(D[1]).." "..D[2].." Pieces"end,--把score返回的数据显示出来的方法
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]<b[2]end,--按照时间排序,时间一样就看块数
getRank=function(P)--计算评级
if P.stat.row<40 then return end--你总得打完40行对吧否则直接return空掉成绩都不记录
local T=P.stat.time
return
T<=26 and 5 or--时间小于等于26秒就是S级要求
T<=32.6 and 4 or--A级要求
T<=52.6 and 3 or--B级要求
T<=92.9 and 2 or--C级要求
T<=183 and 1 or--D级要求解锁别的模式的最低标准
0--记录成绩的最低标准
end,
color=COLOR.green,--颜色
env={--模式环境变量
drop=60,lock=60,
dropPiece=function(P)if P.stat.row>=40 then P:win('finish')end end,
bg='bg2',bgm='race',
},
load=function()--模式加载函数,这里只生成了一个玩家,常用的单人模式可以不写,默认使用这个函数
PLY.newPlayer(1)--1是玩家编号默认用户控制1号玩家
end,
mesDisp=function(P)--40行模式需要显示的信息
setFont(55)
local r=40-P.stat.row
if r<0 then r=0 end
mStr(r,63,265)--把计算出来的剩余行数r显示出来
PLY.draw.drawTargetLine(P,r)--使用自带的境界高度线绘制函数
end,
score=function(P)return{P.stat.time,P.stat.piece}end,--游戏结束时需要保存的本局关键信息
scoreDisp=function(D)return STRING.time(D[1]).." "..D[2].." Pieces"end,--把score返回的数据显示出来的方法
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]<b[2]end,--按照时间排序,时间一样就看块数
getRank=function(P)--计算评级
if P.stat.row<40 then return end--你总得打完40行对吧否则直接return空掉成绩都不记录
local T=P.stat.time
return
T<=26 and 5 or--时间小于等于26秒就是S级要求
T<=32.6 and 4 or--A级要求
T<=52.6 and 3 or--B级要求
T<=92.9 and 2 or--C级要求
T<=183 and 1 or--D级要求解锁别的模式的最低标准
0--记录成绩的最低标准
end,
}

View File

@@ -8,43 +8,43 @@
如果打算自己导入游戏的话需要降噪+裁剪+调整音量后再转为ogg格式 (不支持别的, 因为ogg音质好体积小)
目前游戏内正在使用, 必须录制的音频文件名们:
single, double, triple, techrash (读作\'tekrʌʃ\)
以上直接念就可以,用于普通直接消行
single, double, triple, techrash (读作\'tekrʌʃ\)
以上直接念就可以,用于普通直接消行
mini, b2b, b2b2b
以上直接念就可以,用于组合进spin消除
注: b2b读作back to back
mini, b2b, b2b2b
以上直接念就可以,用于组合进spin消除
注: b2b读作back to back
[各种spin消除]
以上的每一个都要衍生出数条语音,例如zpin的是这五条:
z-spin (用于不消行)
z-spin single
z-spin double
z-spin triple
(z-spin techrash)
(z-spin pentacrash)
(z-spin hexacrash)
对于 S L J T O I 每一个都是这样至少四条语音
加括号一般不用所以可以不录(消5和消6),
对于P, Q, F, E, U, V, W, X, R, Y, N, H
这些方块也可以有上面那些语音,但由于仅在五连块使用还会显著增加语音包体积, 所以不录也可以
[各种spin消除]
以上的每一个都要衍生出数条语音,例如zpin的是这五条:
z-spin (用于不消行)
z-spin single
z-spin double
z-spin triple
(z-spin techrash)
(z-spin pentacrash)
(z-spin hexacrash)
对于 S L J T O I 每一个都是这样至少四条语音
加括号一般不用所以可以不录(消5和消6),
对于P, Q, F, E, U, V, W, X, R, Y, N, H
这些方块也可以有上面那些语音,但由于仅在五连块使用还会显著增加语音包体积, 所以不录也可以
perfect_clear, half_clear
这俩可以直接念也可以略做修改
perfect_clear, half_clear
这俩可以直接念也可以略做修改
win, lose, bye
这几个可以自由发挥, 能用在三个场合就行,尽量不要太长
win, lose, bye
这几个可以自由发挥, 能用在三个场合就行,尽量不要太长
test, happy, doubt, sad, egg
这几个是特殊音效,具体使用情况不定
第一个是测试音量用的音效,尽量短一点,长度在半秒内
其他是彩蛋音效(不录也行, 反正一般不会触发)
test, happy, doubt, sad, egg
这几个是特殊音效,具体使用情况不定
第一个是测试音量用的音效,尽量短一点,长度在半秒内
其他是彩蛋音效(不录也行, 反正一般不会触发)
welcome_voc
进入游戏播放的欢迎语音(类似osu)
welcome_voc
进入游戏播放的欢迎语音(类似osu)
目前没有用到但是将要加入的:
split
split
未来可能加入的:
暂无
暂无

592
main.lua
View File

@@ -1,17 +1,17 @@
--[[
# ______ __ _ #
# /_ __/___ _____ / /_ ____ ___ (_)____ ____ #
# / / / _ \ / ___// __ \ / __ `__ \ / // __ \ / __ \ #
# / / / __// /__ / / / // / / / / // // / / // /_/ / #
# /_/ \___/ \___//_/ /_//_/ /_/ /_//_//_/ /_/ \____/ #
Techmino is my first "huge project"
optimization is welcomed if you also love tetromino stacking game
# ______ __ _ #
# /_ __/___ _____ / /_ ____ ___ (_)____ ____ #
# / / / _ \ / ___// __ \ / __ `__ \ / // __ \ / __ \ #
# / / / __// /__ / / / // / / / / // // / / // /_/ / #
# /_/ \___/ \___//_/ /_//_/ /_/ /_//_//_/ /_/ \____/ #
Techmino is my first "huge project"
optimization is welcomed if you also love tetromino stacking game
Instructions:
1. I made a framework called Zframework, *most* code in Zframework are not directly relevant to game;
2. "xxx" are texts for reading by player, 'xxx' are string values just used in program;
3. Some goto statement are used for better performance. All goto-labes have detailed names so don't be afraid;
4. Except "gcinfo" function of lua itself, other "gc" are short for "graphics";
Instructions:
1. I made a framework called Zframework, *most* code in Zframework are not directly relevant to game;
2. "xxx" are texts for reading by player, 'xxx' are string values just used in program;
3. Some goto statement are used for better performance. All goto-labes have detailed names so don't be afraid;
4. Except "gcinfo" function of lua itself, other "gc" are short for "graphics";
]]--
@@ -38,9 +38,9 @@ love.keyboard.setKeyRepeat(true)
love.keyboard.setTextInput(false)
love.mouse.setVisible(false)
if SYSTEM=='Android'or SYSTEM=='iOS'then
local w,h,f=love.window.getMode()
f.resizable=false
love.window.setMode(w,h,f)
local w,h,f=love.window.getMode()
f.resizable=false
love.window.setMode(w,h,f)
end
--Load modules
@@ -52,41 +52,41 @@ FILE.clear('')
--Create directories
for _,v in next,{'conf','record','replay','cache','lib'}do
local info=fs.getInfo(v)
if not info then
fs.createDirectory(v)
elseif info.type~='directory'then
fs.remove(v)
fs.createDirectory(v)
end
local info=fs.getInfo(v)
if not info then
fs.createDirectory(v)
elseif info.type~='directory'then
fs.remove(v)
fs.createDirectory(v)
end
end
--Load shader files from SOURCE ONLY
SHADER={}
for _,v in next,fs.getDirectoryItems('parts/shaders')do
if fs.getRealDirectory('parts/shaders/'..v)~=SAVEDIR then
local name=v:sub(1,-6)
SHADER[name]=love.graphics.newShader('parts/shaders/'..name..'.glsl')
end
if fs.getRealDirectory('parts/shaders/'..v)~=SAVEDIR then
local name=v:sub(1,-6)
SHADER[name]=love.graphics.newShader('parts/shaders/'..name..'.glsl')
end
end
require'parts.list'
require'parts.globalTables'
require'parts.gametoolfunc'
FREEROW= require'parts.freeRow'
DATA= require'parts.data'
FREEROW= require'parts.freeRow'
DATA= require'parts.data'
TEXTURE= require'parts.texture'
SKIN= require'parts.skin'
USERS= require'parts.users'
NET= require'parts.net'
VK= require'parts.virtualKey'
BOT= require'parts.bot'
RSlist= require'parts.RSlist'DSCP=RSlist.TRS.centerPos
PLY= require'parts.player'
netPLY= require'parts.netPlayer'
MODES= require'parts.modes'
TEXTURE= require'parts.texture'
SKIN= require'parts.skin'
USERS= require'parts.users'
NET= require'parts.net'
VK= require'parts.virtualKey'
BOT= require'parts.bot'
RSlist= require'parts.RSlist'DSCP=RSlist.TRS.centerPos
PLY= require'parts.player'
netPLY= require'parts.netPlayer'
MODES= require'parts.modes'
--Load settings and statistics
TABLE.cover(FILE.load('conf/user')or{},USER)
@@ -99,12 +99,12 @@ TABLE.cover(FILE.load('conf/virtualkey')or{},VK_org)
--Initialize fields, sequence, missions, gameEnv for cutsom game
local fieldData=FILE.load('conf/customBoards')
if fieldData then
fieldData=STRING.split(fieldData,"!")
for i=1,#fieldData do
DATA.pasteBoard(fieldData[i],i)
end
fieldData=STRING.split(fieldData,"!")
for i=1,#fieldData do
DATA.pasteBoard(fieldData[i],i)
end
else
FIELD[1]=DATA.newBoard()
FIELD[1]=DATA.newBoard()
end
local sequenceData=FILE.load('conf/customSequence')
if sequenceData then DATA.pasteSequence(sequenceData)end
@@ -117,255 +117,255 @@ TABLE.complete(require"parts.customEnv0",CUSTOMENV)
--Initialize image libs
IMG.init{
lock='media/image/mess/lock.png',
dialCircle='media/image/mess/dialCircle.png',
dialNeedle='media/image/mess/dialNeedle.png',
lifeIcon='media/image/mess/life.png',
badgeIcon='media/image/mess/badge.png',
ctrlSpeedLimit='media/image/mess/ctrlSpeedLimit.png',
speedLimit='media/image/mess/speedLimit.png',--Not used, for future C2-mode
pay1='media/image/mess/pay1.png',
pay2='media/image/mess/pay2.png',
lock='media/image/mess/lock.png',
dialCircle='media/image/mess/dialCircle.png',
dialNeedle='media/image/mess/dialNeedle.png',
lifeIcon='media/image/mess/life.png',
badgeIcon='media/image/mess/badge.png',
ctrlSpeedLimit='media/image/mess/ctrlSpeedLimit.png',
speedLimit='media/image/mess/speedLimit.png',--Not used, for future C2-mode
pay1='media/image/mess/pay1.png',
pay2='media/image/mess/pay2.png',
miyaCH='media/image/characters/miya.png',
miyaF1='media/image/characters/miya_f1.png',
miyaF2='media/image/characters/miya_f2.png',
miyaF3='media/image/characters/miya_f3.png',
miyaF4='media/image/characters/miya_f4.png',
nakiCH='media/image/characters/nakiharu.png',
xiaoyaCH='media/image/characters/xiaoya.png',
electric='media/image/characters/electric.png',
hbm='media/image/characters/hbm.png',
miyaCH='media/image/characters/miya.png',
miyaF1='media/image/characters/miya_f1.png',
miyaF2='media/image/characters/miya_f2.png',
miyaF3='media/image/characters/miya_f3.png',
miyaF4='media/image/characters/miya_f4.png',
nakiCH='media/image/characters/nakiharu.png',
xiaoyaCH='media/image/characters/xiaoya.png',
electric='media/image/characters/electric.png',
hbm='media/image/characters/hbm.png',
lanterns={
'media/image/lanterns/1.png',
'media/image/lanterns/2.png',
'media/image/lanterns/3.png',
'media/image/lanterns/4.png',
'media/image/lanterns/5.png',
'media/image/lanterns/6.png',
},
lanterns={
'media/image/lanterns/1.png',
'media/image/lanterns/2.png',
'media/image/lanterns/3.png',
'media/image/lanterns/4.png',
'media/image/lanterns/5.png',
'media/image/lanterns/6.png',
},
}
SKIN.init{
{name="crystal_scf",path='media/image/skin/crystal_scf.png'},
{name="matte_mrz",path='media/image/skin/matte_mrz.png'},
{name="contrast_mrz",path='media/image/skin/contrast_mrz.png'},
{name="polkadots_scf",path='media/image/skin/polkadots_scf.png'},
{name="toy_scf",path='media/image/skin/toy_scf.png'},
{name="smooth_mrz",path='media/image/skin/smooth_mrz.png'},
{name="simple_scf",path='media/image/skin/simple_scf.png'},
{name="glass_scf",path='media/image/skin/glass_scf.png'},
{name="penta_scf",path='media/image/skin/penta_scf.png'},
{name="bubble_scf",path='media/image/skin/bubble_scf.png'},
{name="minoes_scf",path='media/image/skin/minoes_scf.png'},
{name="pure_mrz",path='media/image/skin/pure_mrz.png'},
{name="bright_scf",path='media/image/skin/bright_scf.png'},
{name="glow_mrz",path='media/image/skin/glow_mrz.png'},
{name="plastic_mrz",path='media/image/skin/plastic_mrz.png'},
{name="paper_mrz",path='media/image/skin/paper_mrz.png'},
{name="yinyang_scf",path='media/image/skin/yinyang_scf.png'},
{name="cartooncup_earety",path='media/image/skin/cartooncup_earety.png'},
{name="jelly_miya",path='media/image/skin/jelly_miya.png'},
{name="brick_notypey",path='media/image/skin/brick_notypey.png'},
{name="gem_notypey",path='media/image/skin/gem_notypey.png'},
{name="classic",path='media/image/skin/classic_unknown.png'},
{name="ball_shaw",path='media/image/skin/ball_shaw.png'},
{name="retro_notypey",path='media/image/skin/retro_notypey.png'},
{name="textbone_mrz",path='media/image/skin/textbone_mrz.png'},
{name="coloredbone_mrz",path='media/image/skin/coloredbone_mrz.png'},
{name="wtf",path='media/image/skin/wtf_mrz.png'},
{name="crystal_scf",path='media/image/skin/crystal_scf.png'},
{name="matte_mrz",path='media/image/skin/matte_mrz.png'},
{name="contrast_mrz",path='media/image/skin/contrast_mrz.png'},
{name="polkadots_scf",path='media/image/skin/polkadots_scf.png'},
{name="toy_scf",path='media/image/skin/toy_scf.png'},
{name="smooth_mrz",path='media/image/skin/smooth_mrz.png'},
{name="simple_scf",path='media/image/skin/simple_scf.png'},
{name="glass_scf",path='media/image/skin/glass_scf.png'},
{name="penta_scf",path='media/image/skin/penta_scf.png'},
{name="bubble_scf",path='media/image/skin/bubble_scf.png'},
{name="minoes_scf",path='media/image/skin/minoes_scf.png'},
{name="pure_mrz",path='media/image/skin/pure_mrz.png'},
{name="bright_scf",path='media/image/skin/bright_scf.png'},
{name="glow_mrz",path='media/image/skin/glow_mrz.png'},
{name="plastic_mrz",path='media/image/skin/plastic_mrz.png'},
{name="paper_mrz",path='media/image/skin/paper_mrz.png'},
{name="yinyang_scf",path='media/image/skin/yinyang_scf.png'},
{name="cartooncup_earety",path='media/image/skin/cartooncup_earety.png'},
{name="jelly_miya",path='media/image/skin/jelly_miya.png'},
{name="brick_notypey",path='media/image/skin/brick_notypey.png'},
{name="gem_notypey",path='media/image/skin/gem_notypey.png'},
{name="classic",path='media/image/skin/classic_unknown.png'},
{name="ball_shaw",path='media/image/skin/ball_shaw.png'},
{name="retro_notypey",path='media/image/skin/retro_notypey.png'},
{name="textbone_mrz",path='media/image/skin/textbone_mrz.png'},
{name="coloredbone_mrz",path='media/image/skin/coloredbone_mrz.png'},
{name="wtf",path='media/image/skin/wtf_mrz.png'},
}
--Initialize sound libs
SFX.init((function()
local L={}
for _,v in next,fs.getDirectoryItems('media/SFX')do
if fs.getRealDirectory('media/SFX/'..v)~=SAVEDIR then
table.insert(L,v:sub(1,-5))
else
MES.new('warn',"Dangerous file : %SAVE%/media/SFX/"..v)
end
end
return L
local L={}
for _,v in next,fs.getDirectoryItems('media/SFX')do
if fs.getRealDirectory('media/SFX/'..v)~=SAVEDIR then
table.insert(L,v:sub(1,-5))
else
MES.new('warn',"Dangerous file : %SAVE%/media/SFX/"..v)
end
end
return L
end)())
BGM.init((function()
local L={}
for _,v in next,fs.getDirectoryItems('media/BGM')do
if fs.getRealDirectory('media/BGM/'..v)~=SAVEDIR then
table.insert(L,{name=v:sub(1,-5),path='media/BGM/'..v})
else
MES.new('warn',"Dangerous file : %SAVE%/media/BGM/"..v)
end
end
return L
local L={}
for _,v in next,fs.getDirectoryItems('media/BGM')do
if fs.getRealDirectory('media/BGM/'..v)~=SAVEDIR then
table.insert(L,{name=v:sub(1,-5),path='media/BGM/'..v})
else
MES.new('warn',"Dangerous file : %SAVE%/media/BGM/"..v)
end
end
return L
end)())
VOC.init{
'zspin','sspin','lspin','jspin','tspin','ospin','ispin',
'single','double','triple','techrash',
'mini','b2b','b3b',
'perfect_clear','half_clear',
'win','lose','bye',
'test','happy','doubt','sad','egg',
'welcome_voc',
'zspin','sspin','lspin','jspin','tspin','ospin','ispin',
'single','double','triple','techrash',
'mini','b2b','b3b',
'perfect_clear','half_clear',
'win','lose','bye',
'test','happy','doubt','sad','egg',
'welcome_voc',
}
--Initialize language lib
LANG.init(
{
require'parts.language.lang_zh',
require'parts.language.lang_zh2',
require'parts.language.lang_yygq',
require'parts.language.lang_en',
require'parts.language.lang_fr',
require'parts.language.lang_es',
require'parts.language.lang_pt',
require'parts.language.lang_symbol',
--1. Add language file to LANG folder;
--2. Require it;
--3. Add a button in parts/scenes/setting_lang.lua;
},
{
block={
"Z","S","J","L","T","O","I",
"Z5","S5","Q","P","F","E",
"T5","U","V","W","X",
"J5","L5","R","Y","N","H","I5",
"I3","C","I2","O1"
},
}
{
require'parts.language.lang_zh',
require'parts.language.lang_zh2',
require'parts.language.lang_yygq',
require'parts.language.lang_en',
require'parts.language.lang_fr',
require'parts.language.lang_es',
require'parts.language.lang_pt',
require'parts.language.lang_symbol',
--1. Add language file to LANG folder;
--2. Require it;
--3. Add a button in parts/scenes/setting_lang.lua;
},
{
block={
"Z","S","J","L","T","O","I",
"Z5","S5","Q","P","F","E",
"T5","U","V","W","X",
"J5","L5","R","Y","N","H","I5",
"I3","C","I2","O1"
},
}
)
--Load background files from SOURCE ONLY
for _,v in next,fs.getDirectoryItems('parts/backgrounds')do
if fs.getRealDirectory('parts/backgrounds/'..v)~=SAVEDIR then
if v:sub(-3)=='lua'then
local name=v:sub(1,-5)
BG.add(name,require('parts.backgrounds.'..name))
end
end
if fs.getRealDirectory('parts/backgrounds/'..v)~=SAVEDIR then
if v:sub(-3)=='lua'then
local name=v:sub(1,-5)
BG.add(name,require('parts.backgrounds.'..name))
end
end
end
--Load scene files from SOURCE ONLY
for _,v in next,fs.getDirectoryItems('parts/scenes')do
if fs.getRealDirectory('parts/scenes/'..v)~=SAVEDIR then
local sceneName=v:sub(1,-5)
SCN.add(sceneName,require('parts.scenes.'..sceneName))
LANG.addScene(sceneName)
end
if fs.getRealDirectory('parts/scenes/'..v)~=SAVEDIR then
local sceneName=v:sub(1,-5)
SCN.add(sceneName,require('parts.scenes.'..sceneName))
LANG.addScene(sceneName)
end
end
--Load mode files
for i=1,#MODES do
local m=MODES[i]--Mode template
local M=require('parts.modes.'..m.name)--Mode file
for k,v in next,m do M[k]=v end
MODES[m.name],MODES[i]=M
local m=MODES[i]--Mode template
local M=require('parts.modes.'..m.name)--Mode file
for k,v in next,m do M[k]=v end
MODES[m.name],MODES[i]=M
end
--Update data
do
local needSave
local needSave
if not fs.getInfo('conf/data')then
FIRSTLAUNCH=true
needSave=true
end
if type(STAT.version)~='number'then
STAT.version=0
needSave=true
end
if STAT.version<1500 then
FILE.clear_s('')
end
if STAT.version<1505 then
fs.remove('record/bigbang.rec')
fs.remove('conf/replay')
end
if STAT.version==1506 then
local temp1,temp2
if fs.getInfo('record/master_l.rec')then temp1=fs.read('record/master_l.rec')end
if fs.getInfo('record/master_u.rec')then temp2=fs.read('record/master_u.rec')end
if temp1 then fs.write('record/master_u.rec',temp1)end
if temp2 then fs.write('record/master_l.rec',temp2)end
RANKS.master_l,RANKS.master_u=RANKS.master_u,RANKS.master_l
if RANKS.tsd_u then RANKS.tsd_u=0 end
needSave=true
end
if STAT.version==1601 then
RANKS.round_e=nil
RANKS.round_n=nil
RANKS.round_h=nil
RANKS.round_l=nil
RANKS.round_u=nil
fs.remove('record/round_e.rec')
fs.remove('record/round_n.rec')
fs.remove('record/round_h.rec')
fs.remove('record/round_l.rec')
fs.remove('record/round_u.rec')
end
if RANKS.stack_20l then
RANKS.stack_20l=nil
RANKS.stack_40l=nil
RANKS.stack_100l=nil
fs.remove('record/stack_20l.rec')
fs.remove('record/stack_40l.rec')
fs.remove('record/stack_100l.rec')
end
if STAT.version~=VERSION.code then
STAT.version=VERSION.code
needSave=true
love.event.quit('restart')
end
SETTING.appLock=nil
SETTING.dataSaving=nil
if not SETTING.VKSkin then SETTING.VKSkin=1 end
for _,v in next,SETTING.skin do if v<1 or v>17 then v=17 end end
if
SETTING.RS=='ZRS'or SETTING.RS=='BRS'or
SETTING.RS=='ASCplus'or SETTING.RS=='C2sym'
then SETTING.RS='TRS'end
if SETTING.ghostType=='greyCell'then SETTING.ghostType='grayCell'end
if type(SETTING.skinSet)=='number'then SETTING.skinSet='crystal_scf'end
if not TABLE.find({8,10,13,17,22,29,37,47,62,80,100},SETTING.frameMul)then SETTING.frameMul=100 end
if not fs.getInfo('conf/data')then
FIRSTLAUNCH=true
needSave=true
end
if type(STAT.version)~='number'then
STAT.version=0
needSave=true
end
if STAT.version<1500 then
FILE.clear_s('')
end
if STAT.version<1505 then
fs.remove('record/bigbang.rec')
fs.remove('conf/replay')
end
if STAT.version==1506 then
local temp1,temp2
if fs.getInfo('record/master_l.rec')then temp1=fs.read('record/master_l.rec')end
if fs.getInfo('record/master_u.rec')then temp2=fs.read('record/master_u.rec')end
if temp1 then fs.write('record/master_u.rec',temp1)end
if temp2 then fs.write('record/master_l.rec',temp2)end
RANKS.master_l,RANKS.master_u=RANKS.master_u,RANKS.master_l
if RANKS.tsd_u then RANKS.tsd_u=0 end
needSave=true
end
if STAT.version==1601 then
RANKS.round_e=nil
RANKS.round_n=nil
RANKS.round_h=nil
RANKS.round_l=nil
RANKS.round_u=nil
fs.remove('record/round_e.rec')
fs.remove('record/round_n.rec')
fs.remove('record/round_h.rec')
fs.remove('record/round_l.rec')
fs.remove('record/round_u.rec')
end
if RANKS.stack_20l then
RANKS.stack_20l=nil
RANKS.stack_40l=nil
RANKS.stack_100l=nil
fs.remove('record/stack_20l.rec')
fs.remove('record/stack_40l.rec')
fs.remove('record/stack_100l.rec')
end
if STAT.version~=VERSION.code then
STAT.version=VERSION.code
needSave=true
love.event.quit('restart')
end
SETTING.appLock=nil
SETTING.dataSaving=nil
if not SETTING.VKSkin then SETTING.VKSkin=1 end
for _,v in next,SETTING.skin do if v<1 or v>17 then v=17 end end
if
SETTING.RS=='ZRS'or SETTING.RS=='BRS'or
SETTING.RS=='ASCplus'or SETTING.RS=='C2sym'
then SETTING.RS='TRS'end
if SETTING.ghostType=='greyCell'then SETTING.ghostType='grayCell'end
if type(SETTING.skinSet)=='number'then SETTING.skinSet='crystal_scf'end
if not TABLE.find({8,10,13,17,22,29,37,47,62,80,100},SETTING.frameMul)then SETTING.frameMul=100 end
for _,v in next,VK_org do v.color=nil end
if RANKS.infinite then RANKS.infinite=0 end
if RANKS.infinite_dig then RANKS.infinite_dig=0 end
if not RANKS.sprint_10l then RANKS.sprint_10l=0 end
if RANKS.master_l then RANKS.master_n,RANKS.master_l=RANKS.master_l needSave=true end
if RANKS.master_u then RANKS.master_h,RANKS.master_u=RANKS.master_u needSave=true end
for k in next,RANKS do
if type(k)=='number'then
RANKS[k]=nil
needSave=true
end
end
for k,v in next,oldModeNameTable do
if RANKS[k]then
RANKS[v]=RANKS[k]
RANKS[k]=nil
end
k='record/'..k
if fs.getInfo(k..'.dat')then
fs.write('record/'..v..'.rec',fs.read(k..'.dat'))
fs.remove(k..'.dat')
end
if fs.getInfo(k..'.rec')then
fs.write('record/'..v..'.rec',fs.read(k..'.rec'))
fs.remove(k..'.rec')
end
end
for _,v in next,VK_org do v.color=nil end
if RANKS.infinite then RANKS.infinite=0 end
if RANKS.infinite_dig then RANKS.infinite_dig=0 end
if not RANKS.sprint_10l then RANKS.sprint_10l=0 end
if RANKS.master_l then RANKS.master_n,RANKS.master_l=RANKS.master_l needSave=true end
if RANKS.master_u then RANKS.master_h,RANKS.master_u=RANKS.master_u needSave=true end
for k in next,RANKS do
if type(k)=='number'then
RANKS[k]=nil
needSave=true
end
end
for k,v in next,oldModeNameTable do
if RANKS[k]then
RANKS[v]=RANKS[k]
RANKS[k]=nil
end
k='record/'..k
if fs.getInfo(k..'.dat')then
fs.write('record/'..v..'.rec',fs.read(k..'.dat'))
fs.remove(k..'.dat')
end
if fs.getInfo(k..'.rec')then
fs.write('record/'..v..'.rec',fs.read(k..'.rec'))
fs.remove(k..'.rec')
end
end
if needSave then
saveStats()
saveProgress()
saveSettings()
end
if needSave then
saveStats()
saveProgress()
saveSettings()
end
end
--First start for phones
if FIRSTLAUNCH and MOBILE then
SETTING.VKSwitch=true
SETTING.swap=false
SETTING.powerInfo=true
SETTING.cleanCanvas=true
SETTING.VKSwitch=true
SETTING.swap=false
SETTING.powerInfo=true
SETTING.cleanCanvas=true
end
--Apply system setting
@@ -373,46 +373,46 @@ applySettings()
--Load replays
for _,fileName in next,fs.getDirectoryItems('replay')do
if fileName:sub(12,12):match("[a-zA-Z]")then
local date,mode,version,player,seed,setting,mod
local fileData=fs.read('replay/'..fileName)
date, fileData=STRING.readLine(fileData)date=date:gsub("[a-zA-Z]","")
mode, fileData=STRING.readLine(fileData)mode=oldModeNameTable[mode]or mode
version,fileData=STRING.readLine(fileData)
player, fileData=STRING.readLine(fileData)if player=="Local Player"then player="Stacker"end
local success
success,fileData=pcall(love.data.decompress,'string','zlib',fileData)
if not success then goto BREAK_cannotParse end
seed, fileData=STRING.readLine(fileData)
setting,fileData=STRING.readLine(fileData)setting=JSON.decode(setting)
mod, fileData=STRING.readLine(fileData)mod=JSON.decode(mod)
if
not setting or
not mod or
not mode or
#mode==0
then goto BREAK_cannotParse end
if fileName:sub(12,12):match("[a-zA-Z]")then
local date,mode,version,player,seed,setting,mod
local fileData=fs.read('replay/'..fileName)
date, fileData=STRING.readLine(fileData)date=date:gsub("[a-zA-Z]","")
mode, fileData=STRING.readLine(fileData)mode=oldModeNameTable[mode]or mode
version,fileData=STRING.readLine(fileData)
player, fileData=STRING.readLine(fileData)if player=="Local Player"then player="Stacker"end
local success
success,fileData=pcall(love.data.decompress,'string','zlib',fileData)
if not success then goto BREAK_cannotParse end
seed, fileData=STRING.readLine(fileData)
setting,fileData=STRING.readLine(fileData)setting=JSON.decode(setting)
mod, fileData=STRING.readLine(fileData)mod=JSON.decode(mod)
if
not setting or
not mod or
not mode or
#mode==0
then goto BREAK_cannotParse end
fs.remove('replay/'..fileName)
local newName=fileName:sub(1,10)..fileName:sub(15)
fs.write('replay/'..newName,
love.data.compress('string','zlib',
JSON.encode{
date=date,
mode=mode,
version=version,
player=player,
seed=seed,
setting=setting,
mod=mod,
}.."\n"..
fileData
)
)
fileName=newName
end
::BREAK_cannotParse::
local rep=DATA.parseReplay('replay/'..fileName)
table.insert(REPLAY,rep)
fs.remove('replay/'..fileName)
local newName=fileName:sub(1,10)..fileName:sub(15)
fs.write('replay/'..newName,
love.data.compress('string','zlib',
JSON.encode{
date=date,
mode=mode,
version=version,
player=player,
seed=seed,
setting=setting,
mod=mod,
}.."\n"..
fileData
)
)
fileName=newName
end
::BREAK_cannotParse::
local rep=DATA.parseReplay('replay/'..fileName)
table.insert(REPLAY,rep)
end
table.sort(REPLAY,function(a,b)return a.fileName>b.fileName end)

File diff suppressed because it is too large Load Diff

View File

@@ -5,21 +5,21 @@ local shader=SHADER.aura
local t
function back.init()
t=math.random()*2600
BG.resize(SCR.w,SCR.h)
t=math.random()*2600
BG.resize(SCR.w,SCR.h)
end
function back.resize(_,h)
shader:send('w',SCR.W)
shader:send('h',h*SCR.dpi)
shader:send('w',SCR.W)
shader:send('h',h*SCR.dpi)
end
function back.update(dt)
t=t+dt
t=t+dt
end
function back.draw()
gc.clear(.08,.08,.084)
shader:send('t',t)
gc.setShader(shader)
gc.rectangle('fill',0,0,SCR.w,SCR.h)
gc.setShader()
gc.clear(.08,.08,.084)
shader:send('t',t)
gc.setShader(shader)
gc.rectangle('fill',0,0,SCR.w,SCR.h)
gc.setShader()
end
return back

View File

@@ -5,20 +5,20 @@ local shader=SHADER.grad1
local t
function back.init()
t=math.random()*2600
back.resize()
t=math.random()*2600
back.resize()
end
function back.resize()
shader:send('w',SCR.W)
shader:send('w',SCR.W)
end
function back.update(dt)
t=t+dt
t=t+dt
end
function back.draw()
gc.clear(.08,.08,.084)
shader:send('t',t)
gc.setShader(shader)
gc.rectangle('fill',0,0,SCR.w,SCR.h)
gc.setShader()
gc.clear(.08,.08,.084)
shader:send('t',t)
gc.setShader(shader)
gc.rectangle('fill',0,0,SCR.w,SCR.h)
gc.setShader()
end
return back

View File

@@ -5,20 +5,20 @@ local shader=SHADER.grad2
local t
function back.init()
t=math.random()*2600
BG.resize(nil,SCR.h)
t=math.random()*2600
BG.resize(nil,SCR.h)
end
function back.resize(_,h)
shader:send('h',h*SCR.dpi)
shader:send('h',h*SCR.dpi)
end
function back.update(dt)
t=t+dt
t=t+dt
end
function back.draw()
gc.clear(.08,.08,.084)
shader:send('t',t)
gc.setShader(shader)
gc.rectangle('fill',0,0,SCR.w,SCR.h)
gc.setShader()
gc.clear(.08,.08,.084)
shader:send('t',t)
gc.setShader(shader)
gc.rectangle('fill',0,0,SCR.w,SCR.h)
gc.setShader()
end
return back

View File

@@ -12,55 +12,55 @@ local back={}
local t
local squares
function back.init()
t=26
squares={}
t=26
squares={}
end
function back.update()
t=t-1
if t==0 then
local S={
ang=6.2832*rnd(),
d=SCR.rad*1.05/2,
rotate=6.2832*rnd(),
va=.05-rnd()*.1,
size=SCR.rad*(2+rnd()*3)/100,
texture=SKIN.lib[SETTING.skinSet][rnd(16)],
}
ins(squares,S)
t=rnd(6,12)
end
for i=#squares,1,-1 do
local S=squares[i]
S.d=S.d-SCR.rad/(S.d+60)
if S.d>0 then
S.ang=S.ang+.008
S.rotate=S.rotate+S.va
else
rem(squares,i)
end
end
t=t-1
if t==0 then
local S={
ang=6.2832*rnd(),
d=SCR.rad*1.05/2,
rotate=6.2832*rnd(),
va=.05-rnd()*.1,
size=SCR.rad*(2+rnd()*3)/100,
texture=SKIN.lib[SETTING.skinSet][rnd(16)],
}
ins(squares,S)
t=rnd(6,12)
end
for i=#squares,1,-1 do
local S=squares[i]
S.d=S.d-SCR.rad/(S.d+60)
if S.d>0 then
S.ang=S.ang+.008
S.rotate=S.rotate+S.va
else
rem(squares,i)
end
end
end
function back.draw()
gc_clear(.1,.1,.1)
gc_replaceTransform(SCR.xOy_m)
gc_clear(.1,.1,.1)
gc_replaceTransform(SCR.xOy_m)
--Squares
gc_setColor(1,1,1,.2)
for i=1,#squares do
local S=squares[i]
gc_draw(S.texture,S.d*cos(S.ang),S.d*sin(S.ang),S.rotate,S.size*.026,nil,15,15)
end
--Squares
gc_setColor(1,1,1,.2)
for i=1,#squares do
local S=squares[i]
gc_draw(S.texture,S.d*cos(S.ang),S.d*sin(S.ang),S.rotate,S.size*.026,nil,15,15)
end
--Blackhole
gc_setColor(.07,.07,.07)
gc_circle('fill',0,0,157)
gc_setLineWidth(6)
for i=0,15 do
gc_setColor(.07,.07,.07,1-i*.0666)
gc_circle('line',0,0,160+6*i)
end
--Blackhole
gc_setColor(.07,.07,.07)
gc_circle('fill',0,0,157)
gc_setLineWidth(6)
for i=0,15 do
gc_setColor(.07,.07,.07,1-i*.0666)
gc_circle('line',0,0,160+6*i)
end
end
function back.discard()
squares=nil
squares=nil
end
return back

View File

@@ -10,46 +10,46 @@ local back={}
local t
local mino
function back.init()
t=0
mino={}
t=0
mino={}
end
function back.update()
t=t+1
if t%26==0 then
local r=rnd(7)
local B=BLOCKS[r][rnd(0,3)]
local k=(1+rnd()*2)*SCR.rad/1000
ins(mino,{
x=(SCR.w)*rnd()-15*#B[1],
y=0,
k=k,
vy=k*2,
block=B,
texture=SKIN.lib[SETTING.skinSet][SETTING.skin[r]],
})
end
for i=#mino,1,-1 do
local M=mino[i]
M.y=M.y+M.vy
if M.y-M.k*#M.block*30>SCR.h then rem(mino,i)end
end
t=t+1
if t%26==0 then
local r=rnd(7)
local B=BLOCKS[r][rnd(0,3)]
local k=(1+rnd()*2)*SCR.rad/1000
ins(mino,{
x=(SCR.w)*rnd()-15*#B[1],
y=0,
k=k,
vy=k*2,
block=B,
texture=SKIN.lib[SETTING.skinSet][SETTING.skin[r]],
})
end
for i=#mino,1,-1 do
local M=mino[i]
M.y=M.y+M.vy
if M.y-M.k*#M.block*30>SCR.h then rem(mino,i)end
end
end
function back.draw()
gc_clear(.1,.1,.1)
gc_setColor(1,1,1,.2)
for i=1,#mino do
local M=mino[i]
local b=M.block
for y=1,#b do
for x=1,#b[1]do
if b[y][x]then
gc_draw(M.texture,M.x+(x-1)*30*M.k,M.y-y*30*M.k,nil,M.k)
end
end
end
end
gc_clear(.1,.1,.1)
gc_setColor(1,1,1,.2)
for i=1,#mino do
local M=mino[i]
local b=M.block
for y=1,#b do
for x=1,#b[1]do
if b[y][x]then
gc_draw(M.texture,M.x+(x-1)*30*M.k,M.y-y*30*M.k,nil,M.k)
end
end
end
end
end
function back.discard()
mino=nil
mino=nil
end
return back

View File

@@ -7,48 +7,48 @@ local back={}
local t
local mino
function back.init()
t=0
mino={}
t=0
mino={}
end
function back.update()
t=t+1
if t%10==0 then
local r=rnd(29)
ins(mino,{
bid=r,
block=TEXTURE.miniBlock[r],
color=minoColor[SETTING.skin[r]],
x=SCR.w*rnd(),
y=SCR.h*-.05,
k=SCR.rad/100,
ang=rnd()*6.2832,
vy=.5+rnd()*.4,
vx=rnd()*.4-.2,
va=rnd()*.04-.02,
})
end
for i=#mino,1,-1 do
local P=mino[i]
P.y=P.y+P.vy
if P.y>SCR.h+25 then
rem(mino,i)
else
P.x=P.x+P.vx
P.ang=P.ang+P.va
P.vx=P.vx-.01+rnd()*.02
end
end
t=t+1
if t%10==0 then
local r=rnd(29)
ins(mino,{
bid=r,
block=TEXTURE.miniBlock[r],
color=minoColor[SETTING.skin[r]],
x=SCR.w*rnd(),
y=SCR.h*-.05,
k=SCR.rad/100,
ang=rnd()*6.2832,
vy=.5+rnd()*.4,
vx=rnd()*.4-.2,
va=rnd()*.04-.02,
})
end
for i=#mino,1,-1 do
local P=mino[i]
P.y=P.y+P.vy
if P.y>SCR.h+25 then
rem(mino,i)
else
P.x=P.x+P.vx
P.ang=P.ang+P.va
P.vx=P.vx-.01+rnd()*.02
end
end
end
function back.draw()
gc.clear(.08,.08,.084)
for i=1,#mino do
local C=mino[i]
local c=C.color
gc.setColor(c[1],c[2],c[3],.2)
gc.draw(C.block,C.x,C.y,C.ang,C.k,C.k,C.block:getWidth()/2,C.block:getHeight()/2)
end
gc.clear(.08,.08,.084)
for i=1,#mino do
local C=mino[i]
local c=C.color
gc.setColor(c[1],c[2],c[3],.2)
gc.draw(C.block,C.x,C.y,C.ang,C.k,C.k,C.block:getWidth()/2,C.block:getHeight()/2)
end
end
function back.discard()
mino=nil
mino=nil
end
return back

View File

@@ -11,47 +11,47 @@ local back={}
local t
local mino
function back.init()
t=0
mino={}
t=0
mino={}
end
function back.update()
t=t+1
if t%3==0 then
local r=rnd(29)
ins(mino,{
block=TEXTURE.miniBlock[r],
color=minoColor[SETTING.skin[r]],
ang=6.2832*rnd(),
rotate=6.2832*rnd(),
vr=.05-rnd()*.1,
d=0,
v=.5+rnd(),
})
end
local rad=SCR.rad
for i=#mino,1,-1 do
local M=mino[i]
M.d=M.d+M.v
if M.d>rad*1.05 then
rem(mino,i)
else
M.rotate=M.rotate+M.vr
M.v=M.v*(1+M.d/rad*.05)
end
end
t=t+1
if t%3==0 then
local r=rnd(29)
ins(mino,{
block=TEXTURE.miniBlock[r],
color=minoColor[SETTING.skin[r]],
ang=6.2832*rnd(),
rotate=6.2832*rnd(),
vr=.05-rnd()*.1,
d=0,
v=.5+rnd(),
})
end
local rad=SCR.rad
for i=#mino,1,-1 do
local M=mino[i]
M.d=M.d+M.v
if M.d>rad*1.05 then
rem(mino,i)
else
M.rotate=M.rotate+M.vr
M.v=M.v*(1+M.d/rad*.05)
end
end
end
function back.draw()
gc_clear(.1,.1,.1)
gc_translate(SCR.cx,SCR.cy)
for i=1,#mino do
local M=mino[i]
local c=M.color
gc_setColor(c[1],c[2],c[3],.2)
gc_draw(M.block,M.d*cos(M.ang),M.d*sin(M.ang),M.rotate,(18*M.d/SCR.rad)^1.6,nil,M.block:getWidth()/2,M.block:getHeight()/2)
end
gc_translate(-SCR.cx,-SCR.cy)
gc_clear(.1,.1,.1)
gc_translate(SCR.cx,SCR.cy)
for i=1,#mino do
local M=mino[i]
local c=M.color
gc_setColor(c[1],c[2],c[3],.2)
gc_draw(M.block,M.d*cos(M.ang),M.d*sin(M.ang),M.rotate,(18*M.d/SCR.rad)^1.6,nil,M.block:getWidth()/2,M.block:getHeight()/2)
end
gc_translate(-SCR.cx,-SCR.cy)
end
function back.discard()
mino=nil
mino=nil
end
return back

View File

@@ -11,71 +11,71 @@ local back={}
local t
local squares
function back.init()
t=26
squares={}
t=26
squares={}
end
function back.update(dt)
t=t-1
if t==0 then
local size=SCR.rad*(2+rnd()*3)/100
local S={
x=(SCR.w-size)*rnd(),
y=(SCR.h-size)*rnd(),
vx=0,vy=0,
size=size,
color=COLOR.random_dark(),
}
local speed=SCR.rad*(1+rnd()*2)/6
if rnd()<.5 then
S.vy=26*(.5-rnd())
S.vx=speed
if rnd()<.5 then
S.x=-S.size
else
S.x=SCR.w
S.vx=-S.vx
end
else
S.vx=26*(.5-rnd())
S.vy=speed
if rnd()<.5 then
S.y=-S.size
else
S.y=SCR.h
S.vy=-S.vy
end
end
ins(squares,S)
t=rnd(6,16)
end
for i=#squares,1,-1 do
local S=squares[i]
if
S.vx>0 and S.x>SCR.w or
S.vx<0 and S.x+S.size<0 or
S.vy>0 and S.y>SCR.h or
S.vy<0 and S.y+S.size<0
then
rem(squares,i)
else
S.x=S.x+S.vx*dt
S.y=S.y+S.vy*dt
end
end
t=t-1
if t==0 then
local size=SCR.rad*(2+rnd()*3)/100
local S={
x=(SCR.w-size)*rnd(),
y=(SCR.h-size)*rnd(),
vx=0,vy=0,
size=size,
color=COLOR.random_dark(),
}
local speed=SCR.rad*(1+rnd()*2)/6
if rnd()<.5 then
S.vy=26*(.5-rnd())
S.vx=speed
if rnd()<.5 then
S.x=-S.size
else
S.x=SCR.w
S.vx=-S.vx
end
else
S.vx=26*(.5-rnd())
S.vy=speed
if rnd()<.5 then
S.y=-S.size
else
S.y=SCR.h
S.vy=-S.vy
end
end
ins(squares,S)
t=rnd(6,16)
end
for i=#squares,1,-1 do
local S=squares[i]
if
S.vx>0 and S.x>SCR.w or
S.vx<0 and S.x+S.size<0 or
S.vy>0 and S.y>SCR.h or
S.vy<0 and S.y+S.size<0
then
rem(squares,i)
else
S.x=S.x+S.vx*dt
S.y=S.y+S.vy*dt
end
end
end
function back.draw()
gc_clear(.1,.1,.1)
gc_setLineWidth(6)
for i=1,#squares do
local S=squares[i]
local c=S.color
gc_setColor(c[1],c[2],c[3],.2)
gc_rectangle('line',S.x,S.y,S.size,S.size)
gc_setColor(c[1],c[2],c[3],.3)
gc_rectangle('fill',S.x,S.y,S.size,S.size)
end
gc_clear(.1,.1,.1)
gc_setLineWidth(6)
for i=1,#squares do
local S=squares[i]
local c=S.color
gc_setColor(c[1],c[2],c[3],.2)
gc_rectangle('line',S.x,S.y,S.size,S.size)
gc_setColor(c[1],c[2],c[3],.3)
gc_rectangle('fill',S.x,S.y,S.size,S.size)
end
end
function back.discard()
squares=nil
squares=nil
end
return back

View File

@@ -14,66 +14,66 @@ local back={}
local t
local fan,petal
function back.init()
t=0
fan=title_fan
petal={}
t=0
fan=title_fan
petal={}
end
function back.update()
t=t+1
if t%10==0 then
ins(petal,{
x=SCR.w*rnd(),
y=0,
vy=2+rnd()*2,
vx=rnd()*2-.5,
rx=4+rnd()*4,
ry=4+rnd()*4,
})
end
for i=#petal,1,-1 do
local P=petal[i]
P.y=P.y+P.vy
if P.y>SCR.h then
rem(petal,i)
else
P.x=P.x+P.vx
P.vx=P.vx+rnd()*.01
P.rx=max(min(P.rx+rnd()-.5,10),2)
P.ry=max(min(P.ry+rnd()-.5,10),2)
end
end
t=t+1
if t%10==0 then
ins(petal,{
x=SCR.w*rnd(),
y=0,
vy=2+rnd()*2,
vx=rnd()*2-.5,
rx=4+rnd()*4,
ry=4+rnd()*4,
})
end
for i=#petal,1,-1 do
local P=petal[i]
P.y=P.y+P.vy
if P.y>SCR.h then
rem(petal,i)
else
P.x=P.x+P.vx
P.vx=P.vx+rnd()*.01
P.rx=max(min(P.rx+rnd()-.5,10),2)
P.ry=max(min(P.ry+rnd()-.5,10),2)
end
end
end
function back.draw()
gc_clear(.1,.1,.1)
gc_clear(.1,.1,.1)
gc_replaceTransform(SCR.xOy_m)
gc_translate(0,20*sin(t*.02))
gc_replaceTransform(SCR.xOy_m)
gc_translate(0,20*sin(t*.02))
gc_setLineWidth(320)
gc_setColor(.9,.6,.9,.1)
gc_arc('line','open',0,420,500,-.8*3.1416,-.2*3.1416)
gc_setLineWidth(320)
gc_setColor(.9,.6,.9,.1)
gc_arc('line','open',0,420,500,-.8*3.1416,-.2*3.1416)
gc_setLineWidth(4)
gc_setColor(1,.7,.9,.2)
gc_arc('line','open',0,420,660,-.799*3.1416,-.201*3.1416)
gc_arc('line','open',0,420,340,-.808*3.1416,-.192*3.1416)
gc_line(-281,224,-530,30.5)
gc_line(281,224,530,30.5)
gc_setLineWidth(4)
gc_setColor(1,.7,.9,.2)
gc_arc('line','open',0,420,660,-.799*3.1416,-.201*3.1416)
gc_arc('line','open',0,420,340,-.808*3.1416,-.192*3.1416)
gc_line(-281,224,-530,30.5)
gc_line(281,224,530,30.5)
gc_setLineWidth(6)
gc_setColor(.8,.9,1,.3)
for i=1,8 do gc_polygon('line',fan[i])end
gc_setLineWidth(6)
gc_setColor(.8,.9,1,.3)
for i=1,8 do gc_polygon('line',fan[i])end
gc_setLineWidth(2)
gc_setColor(1,.5,.7,.3)
gc_setLineWidth(2)
gc_setColor(1,.5,.7,.3)
gc_origin()
for i=1,#petal do
local P=petal[i]
gc_ellipse('fill',P.x,P.y,P.rx,P.ry)
end
gc_origin()
for i=1,#petal do
local P=petal[i]
gc_ellipse('fill',P.x,P.y,P.rx,P.ry)
end
end
function back.discard()
petal=nil
petal=nil
end
return back

View File

@@ -11,88 +11,88 @@ local back={}
local t
local firework,particle
function back.init()
t=26
firework,particle={},{}
t=26
firework,particle={},{}
end
function back.update(dt)
t=t-1
if t==0 then
ins(firework,{
x=nil,y=nil,
x0=SCR.w*(rnd()*1.2-.1),
y0=SCR.h*1.5,
x1=SCR.w*(.15+rnd()*.7),
y1=SCR.h*(.15+rnd()*.4),
t=0,
v=.5+rnd(),
color=COLOR.random_dark(),
big=rnd()<.1,
})
t=rnd(26,62)
end
for i=#firework,1,-1 do
local F=firework[i]
local time=F.t^.5
if time>1 then
local x,y,color=F.x,F.y,F.color
if F.big then
SFX.play('fall',.5)
for _=1,rnd(62,126)do
ins(particle,{
x=x,y=y,
color=color,
vx=rnd()*16-8,
vy=rnd()*16-8,
t=1,
})
end
else
SFX.play('clear_1',.4)
for _=1,rnd(16,26)do
ins(particle,{
x=x,y=y,
color=color,
vx=rnd()*8-4,
vy=rnd()*8-4,
t=1,
})
end
end
rem(firework,i)
else
F.t=F.t+dt*F.v
F.x=F.x0*(1-time)+F.x1*time
F.y=F.y0*(1-time)+F.y1*time
end
end
for i=#particle,1,-1 do
local P=particle[i]
if P.t<0 then
rem(particle,i)
else
P.x=P.x+P.vx
P.y=P.y+P.vy
P.vy=P.vy+.04
P.t=P.t-dt*.6
end
end
t=t-1
if t==0 then
ins(firework,{
x=nil,y=nil,
x0=SCR.w*(rnd()*1.2-.1),
y0=SCR.h*1.5,
x1=SCR.w*(.15+rnd()*.7),
y1=SCR.h*(.15+rnd()*.4),
t=0,
v=.5+rnd(),
color=COLOR.random_dark(),
big=rnd()<.1,
})
t=rnd(26,62)
end
for i=#firework,1,-1 do
local F=firework[i]
local time=F.t^.5
if time>1 then
local x,y,color=F.x,F.y,F.color
if F.big then
SFX.play('fall',.5)
for _=1,rnd(62,126)do
ins(particle,{
x=x,y=y,
color=color,
vx=rnd()*16-8,
vy=rnd()*16-8,
t=1,
})
end
else
SFX.play('clear_1',.4)
for _=1,rnd(16,26)do
ins(particle,{
x=x,y=y,
color=color,
vx=rnd()*8-4,
vy=rnd()*8-4,
t=1,
})
end
end
rem(firework,i)
else
F.t=F.t+dt*F.v
F.x=F.x0*(1-time)+F.x1*time
F.y=F.y0*(1-time)+F.y1*time
end
end
for i=#particle,1,-1 do
local P=particle[i]
if P.t<0 then
rem(particle,i)
else
P.x=P.x+P.vx
P.y=P.y+P.vy
P.vy=P.vy+.04
P.t=P.t-dt*.6
end
end
end
function back.draw()
gc_clear(.1,.1,.1)
for i=1,#firework do
local F=firework[i]
gc_setColor(F.color)
gc_circle('fill',F.x,F.y,F.big and 8 or 4)
end
gc_setLineWidth(3)
for i=1,#particle do
local P=particle[i]
local c=P.color
gc_setColor(c[1],c[2],c[3],P.t*.4)
gc_line(P.x,P.y,P.x-P.vx*4,P.y-P.vy*4)
end
gc_clear(.1,.1,.1)
for i=1,#firework do
local F=firework[i]
gc_setColor(F.color)
gc_circle('fill',F.x,F.y,F.big and 8 or 4)
end
gc_setLineWidth(3)
for i=1,#particle do
local P=particle[i]
local c=P.color
gc_setColor(c[1],c[2],c[3],P.t*.4)
gc_line(P.x,P.y,P.x-P.vx*4,P.y-P.vy*4)
end
end
function back.discard()
firework=nil
firework=nil
end
return back

View File

@@ -4,15 +4,15 @@ local back={}
local t
function back.init()
t=math.random()*2600
t=math.random()*2600
end
function back.update(dt)
t=t+dt
t=t+dt
end
function back.draw()
local t1=.13-t%3%1.9
if t1<.2 then gc.clear(t1,t1,t1)
else gc.clear(0,0,0)
end
local t1=.13-t%3%1.9
if t1<.2 then gc.clear(t1,t1,t1)
else gc.clear(0,0,0)
end
end
return back

View File

@@ -5,13 +5,13 @@ local back={}
local t
function back.init()
t=math.random()*2600
t=math.random()*2600
end
function back.update(dt)
t=t+dt
t=t+dt
end
function back.draw()
local t1=(sin(t*.5)+sin(t*.7)+sin(t*.9+1)+sin(t*1.5)+sin(t*2+10))*.08
gc.clear(t1,t1,t1)
local t1=(sin(t*.5)+sin(t*.7)+sin(t*.9+1)+sin(t*1.5)+sin(t*2+10))*.08
gc.clear(t1,t1,t1)
end
return back

View File

@@ -8,41 +8,41 @@ local back={}
local lanterns
local t
function back.init()
lanterns={}
t=0
lanterns={}
t=0
end
function back.update(dt)
t=t-dt
local H=SCR.h
if t<=0 then
local size=SCR.rad*(2+rnd()*3)/5/2000
local L={
x=SCR.w*rnd(),
y=H*1.1,
vy=size*2,
size=size,
phase=rnd(),
vp=(.02+.02*rnd())*(rnd(2)*2-3),
}
ins(lanterns,L)
t=rnd(.626,1.626)
end
for i=#lanterns,1,-1 do
local L=lanterns[i]
L.y=L.y-L.vy*dt*60
L.phase=(L.phase+L.vp*dt*60)%1
if L.y<-.1*H then
rem(lanterns,i)
end
end
t=t-dt
local H=SCR.h
if t<=0 then
local size=SCR.rad*(2+rnd()*3)/5/2000
local L={
x=SCR.w*rnd(),
y=H*1.1,
vy=size*2,
size=size,
phase=rnd(),
vp=(.02+.02*rnd())*(rnd(2)*2-3),
}
ins(lanterns,L)
t=rnd(.626,1.626)
end
for i=#lanterns,1,-1 do
local L=lanterns[i]
L.y=L.y-L.vy*dt*60
L.phase=(L.phase+L.vp*dt*60)%1
if L.y<-.1*H then
rem(lanterns,i)
end
end
end
function back.draw()
gc.clear(.08,.08,.084)
gc.setColor(1,1,1,.2)
local img=IMG.lanterns
for i=1,#lanterns do
local L=lanterns[i]
mDraw(img[int(L.phase*6)+1],L.x,L.y,nil,L.size)
end
gc.clear(.08,.08,.084)
gc.setColor(1,1,1,.2)
local img=IMG.lanterns
for i=1,#lanterns do
local L=lanterns[i]
mDraw(img[int(L.phase*6)+1],L.x,L.y,nil,L.size)
end
end
return back

View File

@@ -3,34 +3,34 @@ local gc=love.graphics
local back={}
local upCover do
local L={1,64}
for i=0,63 do
table.insert(L,{'setCL',.6,1,1,i*.01})
table.insert(L,{'fRect',0,63-i,1,1})
end
upCover=GC.DO(L)
local L={1,64}
for i=0,63 do
table.insert(L,{'setCL',.6,1,1,i*.01})
table.insert(L,{'fRect',0,63-i,1,1})
end
upCover=GC.DO(L)
end
local downCover do
local L={1,64}
for i=0,63 do
table.insert(L,{'setCL',1,.5,.8,i*.01})
table.insert(L,{'fRect',0,i,1,1})
end
downCover=GC.DO(L)
local L={1,64}
for i=0,63 do
table.insert(L,{'setCL',1,.5,.8,i*.01})
table.insert(L,{'fRect',0,i,1,1})
end
downCover=GC.DO(L)
end
local W,H
function back.init()
BG.resize(SCR.w,SCR.h)
BG.resize(SCR.w,SCR.h)
end
function back.resize(w,h)
W,H=w,h
W,H=w,h
end
function back.update()
end
function back.draw()
gc.clear(.08,.08,.084)
gc.draw(upCover,0,0,0,W,H*.3/64)
gc.draw(downCover,0,H*.7,0,W,H*.3/64)
gc.clear(.08,.08,.084)
gc.draw(upCover,0,0,0,W,H*.3/64)
gc.draw(downCover,0,H*.7,0,W,H*.3/64)
end
return back

View File

@@ -4,15 +4,15 @@ local back={}
local t
function back.init()
t=math.random()*2600
t=math.random()*2600
end
function back.update(dt)
t=t+dt
t=t+dt
end
function back.draw()
local t1=2.5-t%20%6%2.5
if t1<.3 then gc.clear(t1,t1,t1)
else gc.clear(0,0,0)
end
local t1=2.5-t%20%6%2.5
if t1<.3 then gc.clear(t1,t1,t1)
else gc.clear(0,0,0)
end
end
return back

View File

@@ -8,19 +8,19 @@ local colorLib=minoColor
local blocks=BLOCKS
local scs=RSlist.TRS.centerPos
function back.init()
t=rnd()*2600
t=rnd()*2600
end
function back.update(dt)
t=t+dt
t=t+dt
end
function back.draw()
local R=7-int(t*.5%7)
local T=1.2-t%15%6%1.8
if T<.26 then gc.clear(T,T,T)
else gc.clear(0,0,0)
end
local _=colorLib[SETTING.skin[R]]
gc.setColor(_[1],_[2],_[3],.12)
gc.draw(TEXTURE.miniBlock[R],SCR.cx,SCR.cy,t%3.1416*6,400*SCR.k,nil,scs[R][0][2]+.5,#blocks[R][0]-scs[R][0][1]-.5)
local R=7-int(t*.5%7)
local T=1.2-t%15%6%1.8
if T<.26 then gc.clear(T,T,T)
else gc.clear(0,0,0)
end
local _=colorLib[SETTING.skin[R]]
gc.setColor(_[1],_[2],_[3],.12)
gc.draw(TEXTURE.miniBlock[R],SCR.cx,SCR.cy,t%3.1416*6,400*SCR.k,nil,scs[R][0][2]+.5,#blocks[R][0]-scs[R][0][1]-.5)
end
return back

View File

@@ -11,21 +11,21 @@ local back={}
local t
local matrixT={}for i=1,50 do matrixT[i]={}for j=1,50 do matrixT[i][j]=love.math.noise(i,j)+2 end end
function back.init()
t=math.random()*2600
t=math.random()*2600
end
function back.update(dt)
t=t+dt
t=t+dt
end
function back.draw()
gc_clear(.1,.1,.1)
local k=SCR.k
gc_scale(k)
local Y=ceil(SCR.h/80/k)
for x=1,ceil(SCR.w/80/k)do
for y=1,Y do
gc_setColor(1,1,1,sin(x+matrixT[x][y]*t)*.04+.04)
gc_rectangle('fill',80*x,80*y,-80,-80)
end
end
gc_clear(.1,.1,.1)
local k=SCR.k
gc_scale(k)
local Y=ceil(SCR.h/80/k)
for x=1,ceil(SCR.w/80/k)do
for y=1,Y do
gc_setColor(1,1,1,sin(x+matrixT[x][y]*t)*.04+.04)
gc_rectangle('fill',80*x,80*y,-80,-80)
end
end
end
return back

View File

@@ -5,21 +5,21 @@ local shader=SHADER.rgb1
local t
function back.init()
t=math.random()*2600
BG.resize(SCR.w,SCR.h)
t=math.random()*2600
BG.resize(SCR.w,SCR.h)
end
function back.resize(_,h)
shader:send('w',SCR.W)
shader:send('h',h*SCR.dpi)
shader:send('w',SCR.W)
shader:send('h',h*SCR.dpi)
end
function back.update(dt)
t=t+dt
t=t+dt
end
function back.draw()
gc.clear(.08,.08,.084)
shader:send('t',t)
gc.setShader(shader)
gc.rectangle('fill',0,0,SCR.w,SCR.h)
gc.setShader()
gc.clear(.08,.08,.084)
shader:send('t',t)
gc.setShader(shader)
gc.rectangle('fill',0,0,SCR.w,SCR.h)
gc.setShader()
end
return back

View File

@@ -5,21 +5,21 @@ local shader=SHADER.rgb2
local t
function back.init()
t=math.random()*2600
BG.resize(SCR.w,SCR.h)
t=math.random()*2600
BG.resize(SCR.w,SCR.h)
end
function back.resize(_,h)
shader:send('w',SCR.W)
shader:send('h',h*SCR.dpi)
shader:send('w',SCR.W)
shader:send('h',h*SCR.dpi)
end
function back.update(dt)
t=t+dt
t=t+dt
end
function back.draw()
gc.clear(.08,.08,.084)
shader:send('t',t)
gc.setShader(shader)
gc.rectangle('fill',0,0,SCR.w,SCR.h)
gc.setShader()
gc.clear(.08,.08,.084)
shader:send('t',t)
gc.setShader(shader)
gc.rectangle('fill',0,0,SCR.w,SCR.h)
gc.setShader()
end
return back

View File

@@ -5,16 +5,16 @@ local back={}
local t
function back.init()
t=math.random()*2600
t=math.random()*2600
end
function back.update(dt)
t=t+dt
t=t+dt
end
function back.draw()
gc.clear(
sin(t*1.2)*.06+.08,
sin(t*1.5)*.06+.08,
sin(t*1.9)*.06+.08
)
gc.clear(
sin(t*1.2)*.06+.08,
sin(t*1.5)*.06+.08,
sin(t*1.9)*.06+.08
)
end
return back

View File

@@ -9,43 +9,43 @@ local back={}
local t
local snow
function back.init()
t=0
snow={}
t=0
snow={}
end
function back.update()
t=t+1
if t%(t%626>260 and 3 or 6)==0 then
ins(snow,{
x=SCR.w*rnd(),
y=0,
vy=1+rnd()*.6,
vx=rnd()*2-.5,
rx=2+rnd()*2,
ry=2+rnd()*2,
})
end
for i=#snow,1,-1 do
local P=snow[i]
P.y=P.y+P.vy
if P.y>SCR.h then
rem(snow,i)
else
P.x=P.x+P.vx
P.vx=P.vx-.02+rnd()*.04
P.rx=max(min(P.rx+rnd()-.5,4),2)
P.ry=max(min(P.ry+rnd()-.5,5),3)
end
end
t=t+1
if t%(t%626>260 and 3 or 6)==0 then
ins(snow,{
x=SCR.w*rnd(),
y=0,
vy=1+rnd()*.6,
vx=rnd()*2-.5,
rx=2+rnd()*2,
ry=2+rnd()*2,
})
end
for i=#snow,1,-1 do
local P=snow[i]
P.y=P.y+P.vy
if P.y>SCR.h then
rem(snow,i)
else
P.x=P.x+P.vx
P.vx=P.vx-.02+rnd()*.04
P.rx=max(min(P.rx+rnd()-.5,4),2)
P.ry=max(min(P.ry+rnd()-.5,5),3)
end
end
end
function back.draw()
gc.clear(.08,.08,.084)
gc.setColor(.7,.7,.7)
for i=1,#snow do
local P=snow[i]
ellipse('fill',P.x,P.y,P.rx,P.ry)
end
gc.clear(.08,.08,.084)
gc.setColor(.7,.7,.7)
for i=1,#snow do
local P=snow[i]
ellipse('fill',P.x,P.y,P.rx,P.ry)
end
end
function back.discard()
snow=nil
snow=nil
end
return back

View File

@@ -7,40 +7,40 @@ local back={}
local stars
local W,H
function back.init()
stars={}
BG.resize(SCR.w,SCR.h)
stars={}
BG.resize(SCR.w,SCR.h)
end
function back.resize(w,h)
W,H=w+20,h+20
local S=stars
for i=1,1260,5 do
local s=rnd(26,40)*.1
S[i]=s*SCR.k --Size
S[i+1]=rnd(W)-10 --X
S[i+2]=rnd(H)-10 --Y
S[i+3]=(rnd()-.5)*.01*s --Vx
S[i+4]=(rnd()-.5)*.01*s --Vy
end
W,H=w+20,h+20
local S=stars
for i=1,1260,5 do
local s=rnd(26,40)*.1
S[i]=s*SCR.k --Size
S[i+1]=rnd(W)-10 --X
S[i+2]=rnd(H)-10 --Y
S[i+3]=(rnd()-.5)*.01*s--Vx
S[i+4]=(rnd()-.5)*.01*s--Vy
end
end
function back.update()
local S=stars
--Star moving
for i=1,1260,5 do
S[i+1]=(S[i+1]+S[i+3])%W
S[i+2]=(S[i+2]+S[i+4])%H
end
local S=stars
--Star moving
for i=1,1260,5 do
S[i+1]=(S[i+1]+S[i+3])%W
S[i+2]=(S[i+2]+S[i+4])%H
end
end
function back.draw()
gc.clear(.08,.08,.084)
if not stars[1]then return end
gc.translate(-10,-10)
gc.setColor(1,1,1,.6)
for i=1,1260,5 do
rectangle('fill',stars[i+1],stars[i+2],stars[i],stars[i])
end
gc.translate(10,10)
gc.clear(.08,.08,.084)
if not stars[1]then return end
gc.translate(-10,-10)
gc.setColor(1,1,1,.6)
for i=1,1260,5 do
rectangle('fill',stars[i+1],stars[i+2],stars[i],stars[i])
end
gc.translate(10,10)
end
function back.discard()
stars=nil
stars=nil
end
return back

View File

@@ -8,36 +8,36 @@ local ring
local t
local W,H
function back.init()
ring={}
t=26
back.resize(SCR.w,SCR.h)
ring={}
t=26
back.resize(SCR.w,SCR.h)
end
function back.resize(w,h)
W,H=w,h
W,H=w,h
end
function back.update(dt)
t=t-1
if t==0 then
t=rnd(26,62)
ins(ring,0)
end
for i=#ring,1,-1 do
ring[i]=ring[i]+dt
if ring[i]>3.55 then
rem(ring,i)
end
end
t=t-1
if t==0 then
t=rnd(26,62)
ins(ring,0)
end
for i=#ring,1,-1 do
ring[i]=ring[i]+dt
if ring[i]>3.55 then
rem(ring,i)
end
end
end
function back.draw()
gc.clear(.08,.08,.084)
gc.setColor(1,1,1,.1)
for i=1,#ring do
local r=ring[i]^2/12
gc.setLineWidth(30-15/(r+.5))
gc.rectangle('line',W*.5-W*r/2,H*.5-H*r/2,W*r,H*r)
end
gc.clear(.08,.08,.084)
gc.setColor(1,1,1,.1)
for i=1,#ring do
local r=ring[i]^2/12
gc.setLineWidth(30-15/(r+.5))
gc.rectangle('line',W*.5-W*r/2,H*.5-H*r/2,W*r,H*r)
end
end
function back.discard()
ring=nil
ring=nil
end
return back

View File

@@ -6,34 +6,34 @@ local back={}
local t
local txt
function back.init()
t=math.random()*2600
txt=gc.newText(getFont(80),"Welcome To Techmino")
t=math.random()*2600
txt=gc.newText(getFont(80),"Welcome To Techmino")
end
function back.update(dt)
t=t+dt
t=t+dt
end
function back.draw()
if -t%13.55<.1283 then
gc.clear(.2+.1*sin(t),.2+.1*sin(1.26*t),.2+.1*sin(1.626*t))
else
gc.clear(.08,.08,.084)
end
gc.push('transform')
gc.translate(SCR.cx,SCR.cy+20*sin(t*.02))
gc.scale(SCR.k)
gc.scale(1.1626,1.26)
if -t%6.26<.1355 then
gc.translate(60*sin(t*.26),100*sin(t*.626))
end
if -t%12.6<.1626 then
gc.rotate(t+5*sin(.26*t)+5*sin(.626*t))
end
gc.setColor(.4,.6,1,.3)
gc.draw(txt,-883*.5+4*sin(t*.7942),-110*.5+4*sin(t*.7355))
gc.setColor(.5,.7,1,.4)
gc.draw(txt,-883*.5+2*sin(t*.77023),-110*.5+2*sin(t*.7026))
gc.setColor(1,1,1,.5)
gc.draw(txt,-883*.5+3*sin(t*.7283),-110*.5+3*sin(t*.7626))
gc.pop()
if -t%13.55<.1283 then
gc.clear(.2+.1*sin(t),.2+.1*sin(1.26*t),.2+.1*sin(1.626*t))
else
gc.clear(.08,.08,.084)
end
gc.push('transform')
gc.translate(SCR.cx,SCR.cy+20*sin(t*.02))
gc.scale(SCR.k)
gc.scale(1.1626,1.26)
if -t%6.26<.1355 then
gc.translate(60*sin(t*.26),100*sin(t*.626))
end
if -t%12.6<.1626 then
gc.rotate(t+5*sin(.26*t)+5*sin(.626*t))
end
gc.setColor(.4,.6,1,.3)
gc.draw(txt,-883*.5+4*sin(t*.7942),-110*.5+4*sin(t*.7355))
gc.setColor(.5,.7,1,.4)
gc.draw(txt,-883*.5+2*sin(t*.77023),-110*.5+2*sin(t*.7026))
gc.setColor(1,1,1,.5)
gc.draw(txt,-883*.5+3*sin(t*.7283),-110*.5+3*sin(t*.7626))
gc.pop()
end
return back

View File

@@ -3,71 +3,71 @@ local gc=love.graphics
local rnd=math.random
local back={}
local wingColor={
{.3,.9,.9,.2},
{.5,1.,.5,.2},
{.9,.9,.3,.2},
{1.,.7,.3,.2},
{1.,.5,.5,.2},
{.7,.3,1.,.2},
{.5,.5,1.,.2},
{.3,.9,.9,.2},
{.3,.9,.9,.2},
{.5,1.,.5,.2},
{.9,.9,.3,.2},
{1.,.7,.3,.2},
{1.,.5,.5,.2},
{.7,.3,1.,.2},
{.5,.5,1.,.2},
{.3,.9,.9,.2},
}
local bar,crystal
local W,H
function back.init()
bar=gc.newCanvas(41,1)
gc.setCanvas(bar)
gc.push('transform')
gc.origin()
for x=0,20 do
gc.setColor(1,1,1,x/5)
gc.rectangle('fill',x,0,1,1)
gc.rectangle('fill',41-x,0,1,1)
end
gc.pop()
gc.setCanvas()
back.resize()
bar=gc.newCanvas(41,1)
gc.setCanvas(bar)
gc.push('transform')
gc.origin()
for x=0,20 do
gc.setColor(1,1,1,x/5)
gc.rectangle('fill',x,0,1,1)
gc.rectangle('fill',41-x,0,1,1)
end
gc.pop()
gc.setCanvas()
back.resize()
end
function back.resize()
crystal={}
W,H=SCR.w,SCR.h
for i=1,16 do
crystal[i]={
x=i<9 and W*.05*i or W*.05*(28-i),
y=H*.1,
a=0,
va=0,
f=i<9 and .012-i*.0005 or .012-(17-i)*.0005
}
end
crystal={}
W,H=SCR.w,SCR.h
for i=1,16 do
crystal[i]={
x=i<9 and W*.05*i or W*.05*(28-i),
y=H*.1,
a=0,
va=0,
f=i<9 and .012-i*.0005 or .012-(17-i)*.0005
}
end
end
function back.update()
for i=1,16 do
local B=crystal[i]
B.a=B.a+B.va
B.va=B.va*.986-B.a*B.f
end
for i=1,16 do
local B=crystal[i]
B.a=B.a+B.va
B.va=B.va*.986-B.a*B.f
end
end
function back.draw()
gc.clear(.06,.06,.06)
local sk,sy=SCR.k,H*.8
for i=1,8 do
gc.setColor(wingColor[i])
local B=crystal[i]
gc.draw(bar,B.x,B.y,B.a,sk,sy,20,0)
B=crystal[17-i]
gc.draw(bar,B.x,B.y,B.a,sk,sy,20,0)
end
gc.clear(.06,.06,.06)
local sk,sy=SCR.k,H*.8
for i=1,8 do
gc.setColor(wingColor[i])
local B=crystal[i]
gc.draw(bar,B.x,B.y,B.a,sk,sy,20,0)
B=crystal[17-i]
gc.draw(bar,B.x,B.y,B.a,sk,sy,20,0)
end
end
function back.event(level)
for i=1,8 do
local B=crystal[i]
B.va=B.va+.001*level*(1+rnd())
B=crystal[17-i]
B.va=B.va-.001*level*(1+rnd())
end
for i=1,8 do
local B=crystal[i]
B.va=B.va+.001*level*(1+rnd())
B=crystal[17-i]
B.va=B.va-.001*level*(1+rnd())
end
end
function back.discard()
bar,crystal=nil
bar,crystal=nil
end
return back

View File

@@ -1,15 +1,15 @@
--[[ControlID:
1~5:mL,mR,rR,rL,rF,
6~10:hD,sD,H,A,R,
11~13:LL,RR,DD
1~5:mL,mR,rR,rL,rF,
6~10:hD,sD,H,A,R,
11~13:LL,RR,DD
]]
--[[Future:
HighestBlock
BlockedCells
Wells
FilledLines
4deepShape
BlockedWells
HighestBlock
BlockedCells
Wells
FilledLines
4deepShape
BlockedWells
]]
local min,abs=math.min,math.abs
local ins,rem=table.insert,table.remove
@@ -17,184 +17,184 @@ local yield=coroutine.yield
local dirCount={1,1,3,3,3,0,1}
local FCL={
[1]={
{{11},{11,2},{1},{},{2},{2,2},{12,1},{12}},
{{11,4},{11,3},{1,4},{4},{3},{2,3},{2,2,3},{12,4},{12,3}},
},
[3]={
{{11},{11,2},{1},{},{2},{2,2},{12,1},{12}},
{{3,11},{11,3},{11,2,3},{1,3},{3},{2,3},{2,2,3},{12,1,3},{12,3}},
{{11,5},{11,2,5},{1,5},{5},{2,5},{2,2,5},{12,1,5},{12,5}},
{{11,4},{11,2,4},{1,4},{4},{2,4},{2,2,4},{12,1,4},{12,4},{4,12}},
},
[6]={
{{11},{11,2},{1,1},{1},{},{2},{2,2},{12,1},{12}},
},
[7]={
{{11},{11,2},{1},{},{2},{12,1},{12}},
{{4,11},{11,4},{11,3},{1,4},{4},{3},{2,3},{12,4},{12,3},{3,12}},
},
[1]={
{{11},{11,2},{1},{},{2},{2,2},{12,1},{12}},
{{11,4},{11,3},{1,4},{4},{3},{2,3},{2,2,3},{12,4},{12,3}},
},
[3]={
{{11},{11,2},{1},{},{2},{2,2},{12,1},{12}},
{{3,11},{11,3},{11,2,3},{1,3},{3},{2,3},{2,2,3},{12,1,3},{12,3}},
{{11,5},{11,2,5},{1,5},{5},{2,5},{2,2,5},{12,1,5},{12,5}},
{{11,4},{11,2,4},{1,4},{4},{2,4},{2,2,4},{12,1,4},{12,4},{4,12}},
},
[6]={
{{11},{11,2},{1,1},{1},{},{2},{2,2},{12,1},{12}},
},
[7]={
{{11},{11,2},{1},{},{2},{12,1},{12}},
{{4,11},{11,4},{11,3},{1,4},{4},{3},{2,3},{12,4},{12,3},{3,12}},
},
}FCL[2],FCL[4],FCL[5]=FCL[1],FCL[3],FCL[3]
local LclearScore={[0]=0,-200,-150,-100,200}
local HclearScore={[0]=0,100,140,200,500}
local function _ifoverlapAI(f,bk,x,y)
for i=1,#bk do for j=1,#bk[1]do
if f[y+i-1]and bk[i][j]and f[y+i-1][x+j-1]>0 then return true end
end end
for i=1,#bk do for j=1,#bk[1]do
if f[y+i-1]and bk[i][j]and f[y+i-1][x+j-1]>0 then return true end
end end
end
local discardRow=FREEROW.discard
local getRow=FREEROW.get
local function _resetField(f0,f,start)
for _=#f,start,-1 do
discardRow(f[_])
f[_]=nil
end
for i=start,#f0 do
f[i]=getRow(0)
for j=1,10 do
f[i][j]=f0[i][j]
end
end
for _=#f,start,-1 do
discardRow(f[_])
f[_]=nil
end
for i=start,#f0 do
f[i]=getRow(0)
for j=1,10 do
f[i][j]=f0[i][j]
end
end
end
local function _getScore(field,cb,cy)
local score=0
local highest=0
local height=getRow(0)
local clear=0
local hole=0
local score=0
local highest=0
local height=getRow(0)
local clear=0
local hole=0
for i=cy+#cb-1,cy,-1 do
for j=1,10 do
if field[i][j]==0 then goto CONTINUE_notFull end
end
discardRow(rem(field,i))
clear=clear+1
::CONTINUE_notFull::
end
if #field==0 then return 1e99 end--PC
for x=1,10 do
local h=#field
while field[h][x]==0 and h>1 do
h=h-1
end
height[x]=h
if x>3 and x<8 and h>highest then highest=h end
if h>1 then
for h1=h-1,1,-1 do
if field[h1][x]==0 then
hole=hole+1
if hole==5 then break end
end
end
end
end
local sdh=0
local h1,mh1=0,0
for x=1,9 do
local dh=abs(height[x]-height[x+1])
if dh==1 then
h1=h1+1
if h1>mh1 then mh1=h1 end
else
h1=0
end
sdh=sdh+min(dh^1.6,20)
end
discardRow(height)
score=
-#field*30
-#cb*15
+(#field>10 and
HclearScore[clear]--Clearing
-hole*70--Hole
-cy*50--Height
-sdh--Sum of DeltaH
or
LclearScore[clear]
-hole*100
-cy*40
-sdh*3
)
if #field>6 then score=score-highest*5+20 end
if mh1>3 then score=score-20-mh1*30 end
return score
for i=cy+#cb-1,cy,-1 do
for j=1,10 do
if field[i][j]==0 then goto CONTINUE_notFull end
end
discardRow(rem(field,i))
clear=clear+1
::CONTINUE_notFull::
end
if #field==0 then return 1e99 end--PC
for x=1,10 do
local h=#field
while field[h][x]==0 and h>1 do
h=h-1
end
height[x]=h
if x>3 and x<8 and h>highest then highest=h end
if h>1 then
for h1=h-1,1,-1 do
if field[h1][x]==0 then
hole=hole+1
if hole==5 then break end
end
end
end
end
local sdh=0
local h1,mh1=0,0
for x=1,9 do
local dh=abs(height[x]-height[x+1])
if dh==1 then
h1=h1+1
if h1>mh1 then mh1=h1 end
else
h1=0
end
sdh=sdh+min(dh^1.6,20)
end
discardRow(height)
score=
-#field*30
-#cb*15
+(#field>10 and
HclearScore[clear]--Clearing
-hole*70--Hole
-cy*50--Height
-sdh--Sum of DeltaH
or
LclearScore[clear]
-hole*100
-cy*40
-sdh*3
)
if #field>6 then score=score-highest*5+20 end
if mh1>3 then score=score-20-mh1*30 end
return score
end
local bot_9s={}
function bot_9s.thread(bot)
local P,data,keys=bot.P,bot.data,bot.keys
while true do
--Thinking
yield()
local Tfield={}--Test field
local best={x=1,dir=0,hold=false,score=-1e99}--Best method
local field_org=P.field
for i=1,#field_org do
Tfield[i]=getRow(0)
for j=1,10 do
Tfield[i][j]=field_org[i][j]
end
end
local P,data,keys=bot.P,bot.data,bot.keys
while true do
--Thinking
yield()
local Tfield={}--Test field
local best={x=1,dir=0,hold=false,score=-1e99}--Best method
local field_org=P.field
for i=1,#field_org do
Tfield[i]=getRow(0)
for j=1,10 do
Tfield[i][j]=field_org[i][j]
end
end
for ifhold=0,data.hold and P.gameEnv.holdCount>0 and 1 or 0 do
--Get block id
local bn
if ifhold==0 then
bn=P.cur and P.cur.id
else
bn=P.holdQueue[1]and P.holdQueue[1].id or P.nextQueue[1]and P.nextQueue[1].id
end
if bn then
for dir=0,dirCount[bn]do--Each dir
local cb=BLOCKS[bn][dir]
for cx=1,11-#cb[1]do--Each pos
local cy=#Tfield+1
for ifhold=0,data.hold and P.gameEnv.holdCount>0 and 1 or 0 do
--Get block id
local bn
if ifhold==0 then
bn=P.cur and P.cur.id
else
bn=P.holdQueue[1]and P.holdQueue[1].id or P.nextQueue[1]and P.nextQueue[1].id
end
if bn then
for dir=0,dirCount[bn]do--Each dir
local cb=BLOCKS[bn][dir]
for cx=1,11-#cb[1]do--Each pos
local cy=#Tfield+1
--Move to bottom
while cy>1 and not _ifoverlapAI(Tfield,cb,cx,cy-1)do
cy=cy-1
end
--Move to bottom
while cy>1 and not _ifoverlapAI(Tfield,cb,cx,cy-1)do
cy=cy-1
end
--Simulate lock
for i=1,#cb do
local y=cy+i-1
if not Tfield[y]then Tfield[y]=getRow(0)end
local L=Tfield[y]
for j=1,#cb[1]do
if cb[i][j]then
L[cx+j-1]=1
end
end
end
local score=_getScore(Tfield,cb,cy)
if score>best.score then
best={bn=bn,x=cx,dir=dir,hold=ifhold==1,score=score}
end
_resetField(field_org,Tfield,cy)
end
end
end
end
if not best.bn then return 1 end
--Simulate lock
for i=1,#cb do
local y=cy+i-1
if not Tfield[y]then Tfield[y]=getRow(0)end
local L=Tfield[y]
for j=1,#cb[1]do
if cb[i][j]then
L[cx+j-1]=1
end
end
end
local score=_getScore(Tfield,cb,cy)
if score>best.score then
best={bn=bn,x=cx,dir=dir,hold=ifhold==1,score=score}
end
_resetField(field_org,Tfield,cy)
end
end
end
end
if not best.bn then return 1 end
--Release cache
while #Tfield>0 do
discardRow(rem(Tfield,1))
end
if best.hold then
ins(keys,8)
end
local l=FCL[best.bn][best.dir+1][best.x]
for i=1,#l do
ins(keys,l[i])
end
ins(keys,6)
--Release cache
while #Tfield>0 do
discardRow(rem(Tfield,1))
end
if best.hold then
ins(keys,8)
end
local l=FCL[best.bn][best.dir+1][best.x]
for i=1,#l do
ins(keys,l[i])
end
ins(keys,6)
--Check if time to change target
yield()
if P.aiRND:random()<.00126 then
P:changeAtkMode(P.aiRND:random()<.85 and 1 or #P.atker>3 and 4 or P.aiRND:random()<.3 and 2 or 3)
end
end
--Check if time to change target
yield()
if P.aiRND:random()<.00126 then
P:changeAtkMode(P.aiRND:random()<.85 and 1 or #P.atker>3 and 4 or P.aiRND:random()<.3 and 2 or 3)
end
end
end
return bot_9s

View File

@@ -1,55 +1,55 @@
--[[ControlID:
1~5:mL,mR,rR,rL,rF,
6~10:hD,sD,H,A,R,
11~13:LL,RR,DD
1~5:mL,mR,rR,rL,rF,
6~10:hD,sD,H,A,R,
11~13:LL,RR,DD
]]
local ins,rem=table.insert,table.remove
local yield=coroutine.yield
local bot_cc={}
function bot_cc:pushNewNext(id)
self.bot:addNext(rem(self.nexts,1))
ins(self.nexts,id)
self.bot:addNext(rem(self.nexts,1))
ins(self.nexts,id)
end
function bot_cc:thread()
local P,keys=self.P,self.keys
local ccBot=self.ccBot
while true do
--Start thinking
yield()
ccBot:think()
local P,keys=self.P,self.keys
local ccBot=self.ccBot
while true do
--Start thinking
yield()
ccBot:think()
--Poll keys
local success,result,dest,hold,move
repeat
yield()
success,result,dest,hold,move=ccBot:getMove()
until not success or result==0 or result==2
if not success then break end
if result==2 then
break
elseif result==0 then
dest[5],dest[6]=dest[1][1],dest[1][2]
dest[7],dest[8]=dest[2][1],dest[2][2]
dest[1],dest[2]=dest[3][1],dest[3][2]
dest[3],dest[4]=dest[4][1],dest[4][2]
P.AI_dest=dest
if hold then keys[1]=8 end--Hold
while move[1]do
local m=rem(move,1)
if m<4 then
ins(keys,m+1)
elseif not P.AIdata._20G then
ins(keys,13)
end
end
ins(keys,6)
end
--Poll keys
local success,result,dest,hold,move
repeat
yield()
success,result,dest,hold,move=ccBot:getMove()
until not success or result==0 or result==2
if not success then break end
if result==2 then
break
elseif result==0 then
dest[5],dest[6]=dest[1][1],dest[1][2]
dest[7],dest[8]=dest[2][1],dest[2][2]
dest[1],dest[2]=dest[3][1],dest[3][2]
dest[3],dest[4]=dest[4][1],dest[4][2]
P.AI_dest=dest
if hold then keys[1]=8 end--Hold
while move[1]do
local m=rem(move,1)
if m<4 then
ins(keys,m+1)
elseif not P.AIdata._20G then
ins(keys,13)
end
end
ins(keys,6)
end
--Check if time to change target
yield()
if P.aiRND:random()<.00126 then
P:changeAtkMode(P.aiRND:random()<.85 and 1 or #P.atker>3 and 4 or P.aiRND:random()<.3 and 2 or 3)
end
end
--Check if time to change target
yield()
if P.aiRND:random()<.00126 then
P:changeAtkMode(P.aiRND:random()<.85 and 1 or #P.atker>3 and 4 or P.aiRND:random()<.3 and 2 or 3)
end
end
end
return bot_cc

View File

@@ -1,35 +1,35 @@
local ins,rem=table.insert,table.remove
local baseBot={
pushNewNext=NULL,
updateField=NULL,
lockWrongPlace=NULL,
switch20G=NULL,
revive=NULL,
pushNewNext=NULL,
updateField=NULL,
lockWrongPlace=NULL,
switch20G=NULL,
revive=NULL,
}
function baseBot.update(bot)
local P=bot.P
local keys=bot.keys
if P.control and P.waiting==-1 then
bot.delay=bot.delay-1
if not keys[1]then
if bot.runningThread then
pcall(bot.runningThread)
else
P:act_hardDrop()
end
elseif bot.delay<=0 then
bot.delay=bot.delay0*.5
P:pressKey(keys[1])P:releaseKey(keys[1])
rem(keys,1)
end
end
local P=bot.P
local keys=bot.keys
if P.control and P.waiting==-1 then
bot.delay=bot.delay-1
if not keys[1]then
if bot.runningThread then
pcall(bot.runningThread)
else
P:act_hardDrop()
end
elseif bot.delay<=0 then
bot.delay=bot.delay0*.5
P:pressKey(keys[1])P:releaseKey(keys[1])
rem(keys,1)
end
end
end
local function _undefMethod(self,k)
print("Undefined method: "..k)
self[k]=NULL
return NULL
print("Undefined method: "..k)
self[k]=NULL
return NULL
end
local botMeta={__index=_undefMethod}
@@ -37,75 +37,75 @@ local BOT={}
local AISpeed={60,50,40,30,20,14,10,6,4,3}
function BOT.template(arg)
if arg.type=='CC'then
if not arg.hold then arg.hold=false else arg.hold=true end
return{
type='CC',
next=arg.next,
hold=arg.hold,
delay=AISpeed[arg.speedLV],
["args.node"]=arg.node,
}
elseif arg.type=='9S'then
return{
type='9S',
delay=math.floor(AISpeed[arg.speedLV]),
hold=arg.hold,
}
end
if arg.type=='CC'then
if not arg.hold then arg.hold=false else arg.hold=true end
return{
type='CC',
next=arg.next,
hold=arg.hold,
delay=AISpeed[arg.speedLV],
["args.node"]=arg.node,
}
elseif arg.type=='9S'then
return{
type='9S',
delay=math.floor(AISpeed[arg.speedLV]),
hold=arg.hold,
}
end
end
function BOT.new(P,data)
local bot={P=P,data=data}
if data.type=="CC"then
-- P:setRS('SRS')
-- bot.keys={}
-- bot.nexts={}
-- bot.delay=data.delay
-- bot.delay0=data.delay
-- if P.gameEnv.holdCount and P.gameEnv.holdCount>1 then P:setHold(1)end
local bot={P=P,data=data}
if data.type=="CC"then
-- P:setRS('SRS')
-- bot.keys={}
-- bot.nexts={}
-- bot.delay=data.delay
-- bot.delay0=data.delay
-- if P.gameEnv.holdCount and P.gameEnv.holdCount>1 then P:setHold(1)end
-- local cc=require"parts.bot.cc_wrapper"
-- local opt,wei=cc.getConf()
-- wei:fastWeights()
-- opt:setHold(P.AIdata.hold)
-- opt:set20G(P.AIdata._20G)
-- opt:setBag(P.AIdata.bag=='bag')
-- opt:setNode(P.AIdata.node)
-- bot.ccBot=cc.new(opt,wei)
-- local cc_lua=require"parts.bot.bot_cc"
-- setmetatable(bot,{__index=function(self,k)
-- if self.ccBot[k]then
-- self.ccBot[k](self.ccBot)
-- elseif cc_lua[k]then
-- cc_lua[k](self)
-- elseif baseBot[k]then
-- baseBot[k](self)
-- end
-- end})
-- local cc=require"parts.bot.cc_wrapper"
-- local opt,wei=cc.getConf()
-- wei:fastWeights()
-- opt:setHold(P.AIdata.hold)
-- opt:set20G(P.AIdata._20G)
-- opt:setBag(P.AIdata.bag=='bag')
-- opt:setNode(P.AIdata.node)
-- bot.ccBot=cc.new(opt,wei)
-- local cc_lua=require"parts.bot.bot_cc"
-- setmetatable(bot,{__index=function(self,k)
-- if self.ccBot[k]then
-- self.ccBot[k](self.ccBot)
-- elseif cc_lua[k]then
-- cc_lua[k](self)
-- elseif baseBot[k]then
-- baseBot[k](self)
-- end
-- end})
-- for i,B in next,P.gameEnv.nextQueue do
-- if i<=data.next then
-- bot:addNext(B.id)
-- else
-- ins(bot.nexts,B.id)
-- end
-- end
-- bot.runningThread=coroutine.wrap(cc_lua.thread)
-- bot.runningThread(bot)
setmetatable(bot,botMeta)
elseif data.type=="9S"or true then--9s or else
TABLE.cover(baseBot,bot)
TABLE.cover(require"parts.bot.bot_9s",bot)
P:setRS('TRS')
bot.keys={}
bot.delay=data.delay
bot.delay0=data.delay
bot.runningThread=coroutine.wrap(bot.thread)
bot.runningThread(bot)
setmetatable(bot,botMeta)
end
return bot
-- for i,B in next,P.gameEnv.nextQueue do
-- if i<=data.next then
-- bot:addNext(B.id)
-- else
-- ins(bot.nexts,B.id)
-- end
-- end
-- bot.runningThread=coroutine.wrap(cc_lua.thread)
-- bot.runningThread(bot)
setmetatable(bot,botMeta)
elseif data.type=="9S"or true then--9s or else
TABLE.cover(baseBot,bot)
TABLE.cover(require"parts.bot.bot_9s",bot)
P:setRS('TRS')
bot.keys={}
bot.delay=data.delay
bot.delay0=data.delay
bot.runningThread=coroutine.wrap(bot.thread)
bot.runningThread(bot)
setmetatable(bot,botMeta)
end
return bot
end
return BOT

View File

@@ -1,43 +1,43 @@
return{
version=VERSION.code,
version=VERSION.code,
--Basic
drop=1e99,
lock=1e99,
wait=0,
fall=0,
--Basic
drop=1e99,
lock=1e99,
wait=0,
fall=0,
--Control
nextCount=6,
holdCount=1,
infHold=true,
phyHold=false,
--Control
nextCount=6,
holdCount=1,
infHold=true,
phyHold=false,
--Visual
bone=false,
--Visual
bone=false,
--Rule
sequence='bag',
fieldH=20,
heightLimit=1e99,
bufferLimit=1e99,
--Rule
sequence='bag',
fieldH=20,
heightLimit=1e99,
bufferLimit=1e99,
ospin=true,
fineKill=false,
b2bKill=false,
easyFresh=true,
deepDrop=false,
visible='show',
freshLimit=1e99,
ospin=true,
fineKill=false,
b2bKill=false,
easyFresh=true,
deepDrop=false,
visible='show',
freshLimit=1e99,
opponent="X",
life=0,
pushSpeed=3,
garbageSpeed=1,
missionKill=false,
opponent="X",
life=0,
pushSpeed=3,
garbageSpeed=1,
missionKill=false,
--Else
bg='blockrain',
bgm='hang out',
--Else
bg='blockrain',
bgm='hang out',
}

View File

@@ -8,423 +8,423 @@ 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]
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 str=""
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
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
return str
end
function DATA.pasteSequence(str)
TABLE.cut(BAG)
local b,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
return true
TABLE.cut(BAG)
local b,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
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
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
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::
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 STRING.packBin(str)
--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 STRING.packBin(str)
end
function DATA.copyBoards()
local out={}
for i=1,#FIELD do
out[i]=DATA.copyBoard(i)
end
return table.concat(out,"!")
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]
if not page then page=1 end
if not FIELD[page]then FIELD[page]=DATA.newBoard()end
local F=FIELD[page]
--Decode
str=STRING.unpackBin(str)
if not str then return end
--Decode
str=STRING.unpackBin(str)
if not str then return end
local fX,fY=1,1--*ptr for Field(r*10+(c-1))
local p=1
while true do
local b=byte(str,p)--1byte
local fX,fY=1,1--*ptr for Field(r*10+(c-1))
local p=1
while true do
local b=byte(str,p)--1byte
--Str end
if not b then
if fX~=1 then
return
else
break
end
end
--Str end
if not b then
if fX~=1 then
return
else
break
end
end
local id=b%32-1--Block id
if id>26 then return end--Illegal blockid
b=int(b/32)--Mode id
local id=b%32-1--Block id
if id>26 then return end--Illegal blockid
b=int(b/32)--Mode id
F[fY][fX]=id
if fX<10 then
fX=fX+1
else
fY=fY+1
if fY>20 then break end
fX=1
end
p=p+1
end
F[fY][fX]=id
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
for y=fY,20 do
for x=1,10 do
F[y][x]=0
end
end
return true
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.
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,
_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 str=""
local _
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
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
return str
end
function DATA.pasteMission(str)
local b
TABLE.cut(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
TABLE.cut(MISSION)
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
return true
local b
TABLE.cut(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
TABLE.cut(MISSION)
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
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
local ENV=CUSTOMENV
local str=""..
ENV.holdCount..
(ENV.ospin and"O"or"Z")..
(ENV.missionKill and"M"or"Z")..
ENV.sequence
return str
end
function DATA.pasteQuestArgs(str)
if #str<4 then return end
local ENV=CUSTOMENV
ENV.holdCount= str:byte(1)-48
ENV.ospin= str:byte(2)~=90
ENV.missionKill= str:byte(3)~=90
ENV.sequence= str:sub(4)
return true
if #str<4 then return end
local ENV=CUSTOMENV
ENV.holdCount= str:byte(1)-48
ENV.ospin= str:byte(2)~=90
ENV.missionKill=str:byte(3)~=90
ENV.sequence= str:sub(4)
return true
end
--[[
Replay file:
a zlib-compressed json table
Replay file:
a zlib-compressed json table
Replay data format (table):
{frame,event, frame,event, ...}
Replay data format (table):
{frame,event, frame,event, ...}
Replay data format (byte): (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)
Replay data format (byte): (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)
...
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
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 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
--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
--Step
ptr=ptr+2
end
return out..buffer,ptr
end
function DATA.pumpRecording(str,L)
local len=#str
local p=1
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 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
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.saveReplay()
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.saveReplay()
--Filtering modes that cannot be saved
for _,v in next,noRecList do
if GAME.curModeName:find(v)then
MES.new('error',"Cannot save recording of this mode now!")
return
end
end
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.saveReplay()
--Filtering modes that cannot be saved
for _,v in next,noRecList do
if GAME.curModeName:find(v)then
MES.new('error',"Cannot save recording of this mode now!")
return
end
end
--Write file
local fileName=os.date("replay/%Y_%m_%d_%H%M%S.rep")
if not love.filesystem.getInfo(fileName)then
love.filesystem.write(fileName,
love.data.compress('string','zlib',
JSON.encode{
date=os.date("%Y/%m/%d %H:%M:%S"),
mode=GAME.curModeName,
version=VERSION.string,
player=USERS.getUsername(USER.uid),
seed=GAME.seed,
setting=GAME.setting,
mod=_getModList(),
tasUsed=GAME.tasUsed,
}.."\n"..
DATA.dumpRecording(GAME.rep)
)
)
ins(REPLAY,1,DATA.parseReplay(fileName))
return true
else
MES.new('error',"Save failed: File already exists")
end
end
--Write file
local fileName=os.date("replay/%Y_%m_%d_%H%M%S.rep")
if not love.filesystem.getInfo(fileName)then
love.filesystem.write(fileName,
love.data.compress('string','zlib',
JSON.encode{
date=os.date("%Y/%m/%d %H:%M:%S"),
mode=GAME.curModeName,
version=VERSION.string,
player=USERS.getUsername(USER.uid),
seed=GAME.seed,
setting=GAME.setting,
mod=_getModList(),
tasUsed=GAME.tasUsed,
}.."\n"..
DATA.dumpRecording(GAME.rep)
)
)
ins(REPLAY,1,DATA.parseReplay(fileName))
return true
else
MES.new('error',"Save failed: File already exists")
end
end
end
function DATA.parseReplay(fileName,ifFull)
local fileData
--Read file
fileData=love.filesystem.read(fileName)
return DATA.parseReplayData(fileName,fileData,ifFull)
local fileData
--Read file
fileData=love.filesystem.read(fileName)
return DATA.parseReplayData(fileName,fileData,ifFull)
end
function DATA.parseReplayData(fileName,fileData,ifFull)
local success,metaData,rep
local success,metaData,rep
if not(fileData and #fileData>0)then goto BREAK_cannotParse end
if not(fileData and #fileData>0)then goto BREAK_cannotParse end
--Decompress file
success,fileData=pcall(love.data.decompress,'string','zlib',fileData)
if not success then goto BREAK_cannotParse end
--Decompress file
success,fileData=pcall(love.data.decompress,'string','zlib',fileData)
if not success then goto BREAK_cannotParse end
--Load metadata
metaData,fileData=STRING.readLine(fileData)
metaData=JSON.decode(metaData)
if not metaData then goto BREAK_cannotParse end
--Load metadata
metaData,fileData=STRING.readLine(fileData)
metaData=JSON.decode(metaData)
if not metaData then goto BREAK_cannotParse end
--Convert ancient replays
metaData.mode=oldModeNameTable[metaData.mode]or metaData.mode
if not MODES[metaData.mode]then goto BREAK_cannotParse end
--Convert ancient replays
metaData.mode=oldModeNameTable[metaData.mode]or metaData.mode
if not MODES[metaData.mode]then goto BREAK_cannotParse end
--Create replay object
rep={
fileName=fileName,
available=true,
--Create replay object
rep={
fileName=fileName,
available=true,
date=metaData.date,
mode=metaData.mode,
version=metaData.version,
player=metaData.player,
date=metaData.date,
mode=metaData.mode,
version=metaData.version,
player=metaData.player,
seed=metaData.seed,
setting=metaData.setting,
mod=metaData.mod,
tasUsed=metaData.tasUsed,
}
if ifFull then rep.data=fileData end
do return rep end
seed=metaData.seed,
setting=metaData.setting,
mod=metaData.mod,
tasUsed=metaData.tasUsed,
}
if ifFull then rep.data=fileData end
do return rep end
--Create unavailable replay object
::BREAK_cannotParse::
return{
fileName=fileName,
available=false,
}
--Create unavailable replay object
::BREAK_cannotParse::
return{
fileName=fileName,
available=false,
}
end
return DATA

View File

@@ -2,36 +2,36 @@ local FREEROW={}
local L={}--Storage
local len=0--Length
function FREEROW.reset(num)
if num<len then
for i=len,num+1,-1 do
L[i]=nil
end
elseif num>len then
for i=len+1,num do
L[i]={0,0,0,0,0,0,0,0,0,0,garbage=false}
end
end
len=num
if num<len then
for i=len,num+1,-1 do
L[i]=nil
end
elseif num>len then
for i=len+1,num do
L[i]={0,0,0,0,0,0,0,0,0,0,garbage=false}
end
end
len=num
end
function FREEROW.get(val,ifGarbage)
if len==0 then
for i=1,10 do
L[i]={0,0,0,0,0,0,0,0,0,0,garbage=false}
end
len=len+10
end
local t=L[len]
for i=1,10 do t[i]=val end
t.garbage=ifGarbage==true
L[len]=nil
len=len-1
return t
if len==0 then
for i=1,10 do
L[i]={0,0,0,0,0,0,0,0,0,0,garbage=false}
end
len=len+10
end
local t=L[len]
for i=1,10 do t[i]=val end
t.garbage=ifGarbage==true
L[len]=nil
len=len-1
return t
end
function FREEROW.discard(t)
len=len+1
L[len]=t
len=len+1
L[len]=t
end
function FREEROW.getCount()
return len
return len
end
return FREEROW

File diff suppressed because it is too large Load Diff

View File

@@ -1,151 +1,151 @@
--Complex tables
local function _disableKey(P,key)
table.insert(P.gameEnv.keyCancel,key)
table.insert(P.gameEnv.keyCancel,key)
end
MODOPT={--Mod options
{no=0,id="NX",name="next",
key="q",x=80,y=230,color='lO',
list={0,1,2,3,4,5,6},
func=function(P,O)P.gameEnv.nextCount=O end,
unranked=true,
},
{no=1,id="HL",name="hold",
key="w",x=200,y=230,color='lO',
list={0,1,2,3,4,5,6},
func=function(P,O)P.gameEnv.holdCount=O end,
unranked=true,
},
{no=2,id="FL",name="hideNext",
key="e",x=320,y=230,color='lA',
list={1,2,3,4,5},
func=function(P,O)P.gameEnv.nextStartPos=O+1 end,
unranked=true,
},
{no=3,id="IH",name="infHold",
key="r",x=440,y=230,color='lA',
func=function(P)P.gameEnv.infHold=true end,
unranked=true,
},
{no=4,id="HB",name="hideBlock",
key="y",x=680,y=230,color='lV',
func=function(P)P.gameEnv.block=false end,
unranked=true,
},
{no=5,id="HG",name="hideGhost",
key="u",x=800,y=230,color='lV',
func=function(P)P.gameEnv.ghost=false end,
unranked=true,
},
{no=6,id="HD",name="hidden",
key="i",x=920,y=230,color='lP',
list={'easy','slow','medium','fast','none'},
func=function(P,O)P.gameEnv.visible=O end,
unranked=true,
},
{no=7,id="HB",name="hideBoard",
key="o",x=1040,y=230,color='lP',
list={'down','up','all'},
func=function(P,O)P.gameEnv.hideBoard=O end,
unranked=true,
},
{no=8,id="FB",name="flipBoard",
key="p",x=1160,y=230,color='lJ',
list={'U-D','L-R','180'},
func=function(P,O)P.gameEnv.flipBoard=O end,
unranked=true,
},
{no=0,id="NX",name="next",
key="q",x=80,y=230,color='lO',
list={0,1,2,3,4,5,6},
func=function(P,O)P.gameEnv.nextCount=O end,
unranked=true,
},
{no=1,id="HL",name="hold",
key="w",x=200,y=230,color='lO',
list={0,1,2,3,4,5,6},
func=function(P,O)P.gameEnv.holdCount=O end,
unranked=true,
},
{no=2,id="FL",name="hideNext",
key="e",x=320,y=230,color='lA',
list={1,2,3,4,5},
func=function(P,O)P.gameEnv.nextStartPos=O+1 end,
unranked=true,
},
{no=3,id="IH",name="infHold",
key="r",x=440,y=230,color='lA',
func=function(P)P.gameEnv.infHold=true end,
unranked=true,
},
{no=4,id="HB",name="hideBlock",
key="y",x=680,y=230,color='lV',
func=function(P)P.gameEnv.block=false end,
unranked=true,
},
{no=5,id="HG",name="hideGhost",
key="u",x=800,y=230,color='lV',
func=function(P)P.gameEnv.ghost=false end,
unranked=true,
},
{no=6,id="HD",name="hidden",
key="i",x=920,y=230,color='lP',
list={'easy','slow','medium','fast','none'},
func=function(P,O)P.gameEnv.visible=O end,
unranked=true,
},
{no=7,id="HB",name="hideBoard",
key="o",x=1040,y=230,color='lP',
list={'down','up','all'},
func=function(P,O)P.gameEnv.hideBoard=O end,
unranked=true,
},
{no=8,id="FB",name="flipBoard",
key="p",x=1160,y=230,color='lJ',
list={'U-D','L-R','180'},
func=function(P,O)P.gameEnv.flipBoard=O end,
unranked=true,
},
{no=9,id="DT",name="dropDelay",
key="a",x=140,y=350,color='lR',
list={0,.125,.25,.5,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,1e99},
func=function(P,O)P.gameEnv.drop=O end,
unranked=true,
},
{no=10,id="LT",name="lockDelay",
key="s",x=260,y=350,color='lR',
list={0,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,1e99},
func=function(P,O)P.gameEnv.lock=O end,
unranked=true,
},
{no=11,id="ST",name="waitDelay",
key="d",x=380,y=350,color='lR',
list={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
func=function(P,O)P.gameEnv.wait=O end,
unranked=true,
},
{no=12,id="CT",name="fallDelay",
key="f",x=500,y=350,color='lR',
list={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
func=function(P,O)P.gameEnv.fall=O end,
unranked=true,
},
{no=13,id="LF",name="life",
key="j",x=860,y=350,color='lY',
list={0,1,2,3,5,10,15,26,42,87,500},
func=function(P,O)P.gameEnv.life=O end,
unranked=true,
},
{no=14,id="FB",name="forceB2B",
key="k",x=980,y=350,color='lY',
func=function(P)P.gameEnv.b2bKill=true end,
unranked=true,
},
{no=15,id="PF",name="forceFinesse",
key="l",x=1100,y=350,color='lY',
func=function(P)P.gameEnv.fineKill=true end,
unranked=true,
},
{no=9,id="DT",name="dropDelay",
key="a",x=140,y=350,color='lR',
list={0,.125,.25,.5,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,1e99},
func=function(P,O)P.gameEnv.drop=O end,
unranked=true,
},
{no=10,id="LT",name="lockDelay",
key="s",x=260,y=350,color='lR',
list={0,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,1e99},
func=function(P,O)P.gameEnv.lock=O end,
unranked=true,
},
{no=11,id="ST",name="waitDelay",
key="d",x=380,y=350,color='lR',
list={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
func=function(P,O)P.gameEnv.wait=O end,
unranked=true,
},
{no=12,id="CT",name="fallDelay",
key="f",x=500,y=350,color='lR',
list={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
func=function(P,O)P.gameEnv.fall=O end,
unranked=true,
},
{no=13,id="LF",name="life",
key="j",x=860,y=350,color='lY',
list={0,1,2,3,5,10,15,26,42,87,500},
func=function(P,O)P.gameEnv.life=O end,
unranked=true,
},
{no=14,id="FB",name="forceB2B",
key="k",x=980,y=350,color='lY',
func=function(P)P.gameEnv.b2bKill=true end,
unranked=true,
},
{no=15,id="PF",name="forceFinesse",
key="l",x=1100,y=350,color='lY',
func=function(P)P.gameEnv.fineKill=true end,
unranked=true,
},
{no=16,id="TL",name="tele",
key="z",x=200,y=470,color='lH',
func=function(P)
P.gameEnv.das,P.gameEnv.arr=0,0
P.gameEnv.sddas,P.gameEnv.sdarr=0,0
end,
unranked=true,
},
{no=17,id="FX",name="noRotation",
key="x",x=320,y=470,color='lH',
func=function(P)
_disableKey(P,3)
_disableKey(P,4)
_disableKey(P,5)
end,
unranked=true,
},
{no=18,id="GL",name="noMove",
key="c",x=440,y=470,color='lH',
func=function(P)
_disableKey(P,1)_disableKey(P,2)
_disableKey(P,11)_disableKey(P,12)
_disableKey(P,17)_disableKey(P,18)
_disableKey(P,19)_disableKey(P,20)
end,
unranked=true,
},
{no=19,id="CS",name="customSeq",
key="b",x=680,y=470,color='lB',
list={'bag','his','hisPool','c2','rnd','mess','reverb'},
func=function(P,O)P.gameEnv.sequence=O end,
unranked=true,
},
{no=20,id="PS",name="pushSpeed",
key="n",x=800,y=470,color='lB',
list={.5,1,2,3,5,15,1e99},
func=function(P,O)P.gameEnv.pushSpeed=O end,
unranked=true,
},
{no=21,id="BN",name="boneBlock",
key="m",x=920,y=470,color='lB',
list={'on','off'},
func=function(P,O)P.gameEnv.bone=O=='on'end,
unranked=true,
},
{no=16,id="TL",name="tele",
key="z",x=200,y=470,color='lH',
func=function(P)
P.gameEnv.das,P.gameEnv.arr=0,0
P.gameEnv.sddas,P.gameEnv.sdarr=0,0
end,
unranked=true,
},
{no=17,id="FX",name="noRotation",
key="x",x=320,y=470,color='lH',
func=function(P)
_disableKey(P,3)
_disableKey(P,4)
_disableKey(P,5)
end,
unranked=true,
},
{no=18,id="GL",name="noMove",
key="c",x=440,y=470,color='lH',
func=function(P)
_disableKey(P,1)_disableKey(P,2)
_disableKey(P,11)_disableKey(P,12)
_disableKey(P,17)_disableKey(P,18)
_disableKey(P,19)_disableKey(P,20)
end,
unranked=true,
},
{no=19,id="CS",name="customSeq",
key="b",x=680,y=470,color='lB',
list={'bag','his','hisPool','c2','rnd','mess','reverb'},
func=function(P,O)P.gameEnv.sequence=O end,
unranked=true,
},
{no=20,id="PS",name="pushSpeed",
key="n",x=800,y=470,color='lB',
list={.5,1,2,3,5,15,1e99},
func=function(P,O)P.gameEnv.pushSpeed=O end,
unranked=true,
},
{no=21,id="BN",name="boneBlock",
key="m",x=920,y=470,color='lB',
list={'on','off'},
func=function(P,O)P.gameEnv.bone=O=='on'end,
unranked=true,
},
}
for i=1,#MODOPT do
local M=MODOPT[i]
M.sel,M.time=0,0
M.color=COLOR[M.color]
local M=MODOPT[i]
M.sel,M.time=0,0
M.color=COLOR[M.color]
end
--Game tables
@@ -155,216 +155,216 @@ FIELD={}--Field(s) for custom game
BAG={}--Sequence for custom game
MISSION={}--Clearing mission for custom game
GAME={--Global game data
playing=false, --If in-game
init=false, --If need initializing game when enter scene-play
net=false, --If play net game
playing=false, --If in-game
init=false, --If need initializing game when enter scene-play
net=false, --If play net game
result=false, --Game result (string)
rank=0, --Rank reached
pauseTime=0, --Time paused
pauseCount=0, --Pausing count
warnLVL0=0, --Warning level
warnLVL=0, --Warning level (show)
result=false, --Game result (string)
rank=0, --Rank reached
pauseTime=0, --Time paused
pauseCount=0, --Pausing count
warnLVL0=0, --Warning level
warnLVL=0, --Warning level (show)
seed=1046101471, --Game seed
curMode=false, --Current gamemode object
mod={}, --List of loaded mods
modeEnv=false, --Current gamemode environment
setting={}, --Game settings
rep={}, --Recording list, key,time,key,time...
statSaved=true, --If recording saved
recording=false, --If recording
replaying=false, --If replaying
saved=false, --If recording saved
tasUsed=false, --If tasMode used
seed=1046101471, --Game seed
curMode=false, --Current gamemode object
mod={}, --List of loaded mods
modeEnv=false, --Current gamemode environment
setting={}, --Game settings
rep={}, --Recording list, key,time,key,time...
statSaved=true, --If recording saved
recording=false, --If recording
replaying=false, --If replaying
saved=false, --If recording saved
tasUsed=false, --If tasMode used
prevBG=false, --Previous background, for restore BG when quit setting page
prevBG=false, --Previous background, for restore BG when quit setting page
--Data for royale mode
stage=false, --Game stage
mostBadge=false, --Most badge owner
secBadge=false, --Second badge owner
mostDangerous=false,--Most dangerous player
secDangerous=false, --Second dangerous player
--Data for royale mode
stage=false, --Game stage
mostBadge=false, --Most badge owner
secBadge=false, --Second badge owner
mostDangerous=false,--Most dangerous player
secDangerous=false, --Second dangerous player
}
ROYALEDATA={
powerUp=false,
stage=false,
powerUp=false,
stage=false,
}
CUSTOMENV={}
ROOMENV={
--Room config
capacity=10,
--Room config
capacity=10,
--Basic
drop=30,
lock=60,
wait=0,
fall=0,
--Basic
drop=30,
lock=60,
wait=0,
fall=0,
--Control
nextCount=6,
holdCount=1,
infHold=false,
phyHold=false,
--Control
nextCount=6,
holdCount=1,
infHold=false,
phyHold=false,
--Visual
bone=false,
--Visual
bone=false,
--Rule
life=0,
pushSpeed=5,
garbageSpeed=2,
visible='show',
freshLimit=15,
--Rule
life=0,
pushSpeed=5,
garbageSpeed=2,
visible='show',
freshLimit=15,
fieldH=20,
heightLimit=1e99,
bufferLimit=1e99,
fieldH=20,
heightLimit=1e99,
bufferLimit=1e99,
ospin=true,
fineKill=false,
b2bKill=false,
easyFresh=true,
deepDrop=false,
ospin=true,
fineKill=false,
b2bKill=false,
easyFresh=true,
deepDrop=false,
}
REPLAY={}--Replay objects (not include stream data)
--Userdata tables
USER={--User infomation
--Network infos
uid=false,
authToken=false,
--Network infos
uid=false,
authToken=false,
--Local data
xp=0,lv=1,
--Local data
xp=0,lv=1,
}
SETTING={--Settings
--Tuning
das=10,arr=2,
dascut=0,dropcut=0,
sddas=0,sdarr=2,
ihs=true,irs=true,ims=true,
RS='TRS',
swap=true,
--Tuning
das=10,arr=2,
dascut=0,dropcut=0,
sddas=0,sdarr=2,
ihs=true,irs=true,ims=true,
RS='TRS',
swap=true,
--System
reTime=4,
allowTAS=false,
autoPause=true,
menuPos='middle',
fine=false,
autoSave=false,
simpMode=false,
lang=1,
skinSet='crystal_scf',
skin={
1,7,11,3,14,4,9,
1,7,2,6,10,2,13,5,9,15,10,11,3,12,2,16,8,4,
10,13,2,8
},
face={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
--System
reTime=4,
allowTAS=false,
autoPause=true,
menuPos='middle',
fine=false,
autoSave=false,
simpMode=false,
lang=1,
skinSet='crystal_scf',
skin={
1,7,11,3,14,4,9,
1,7,2,6,10,2,13,5,9,15,10,11,3,12,2,16,8,4,
10,13,2,8
},
face={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
--Graphic
ghostType='gray',
block=true,ghost=.3,center=1,
smooth=true,grid=.16,lineNum=.5,
upEdge=true,
bagLine=false,
lockFX=2,
dropFX=2,
moveFX=2,
clearFX=2,
splashFX=2,
shakeFX=2,
atkFX=2,
frameMul=100,
cleanCanvas=false,
blockSatur='normal',
fieldSatur='normal',
--Graphic
ghostType='gray',
block=true,ghost=.3,center=1,
smooth=true,grid=.16,lineNum=.5,
upEdge=true,
bagLine=false,
lockFX=2,
dropFX=2,
moveFX=2,
clearFX=2,
splashFX=2,
shakeFX=2,
atkFX=2,
frameMul=100,
cleanCanvas=false,
blockSatur='normal',
fieldSatur='normal',
text=true,
score=true,
bufferWarn=true,
showSpike=true,
highCam=true,
nextPos=true,
fullscreen=true,
bg=true,
powerInfo=false,
clickFX=true,
warn=true,
text=true,
score=true,
bufferWarn=true,
showSpike=true,
highCam=true,
nextPos=true,
fullscreen=true,
bg=true,
powerInfo=false,
clickFX=true,
warn=true,
--Sound
sfx=1,
sfx_spawn=0,
sfx_warn=.4,
bgm=.7,
stereo=.7,
vib=0,
voc=0,
cv='miya',
--Sound
sfx=1,
sfx_spawn=0,
sfx_warn=.4,
bgm=.7,
stereo=.7,
vib=0,
voc=0,
cv='miya',
--Virtualkey
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
VKCurW=.4,--Cur-Pos Weight
VKIcon=true,--If disp icon
VKAlpha=.3,
--Virtualkey
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
VKCurW=.4,--Cur-Pos Weight
VKIcon=true,--If disp icon
VKAlpha=.3,
}
keyMap={--Key setting
keyboard={
left=1,right=2,x=3,z=4,c=5,
up=6,down=7,space=8,a=9,s=10,
r=0,
},
joystick={
dpleft=1,dpright=2,a=3,b=4,y=5,
dpup=6,dpdown=7,rightshoulder=8,x=9,
leftshoulder=0,
},
keyboard={
left=1,right=2,x=3,z=4,c=5,
up=6,down=7,space=8,a=9,s=10,
r=0,
},
joystick={
dpleft=1,dpright=2,a=3,b=4,y=5,
dpup=6,dpdown=7,rightshoulder=8,x=9,
leftshoulder=0,
},
}
VK_org={--Virtualkey layout, refresh all VKs' position with this before each game
{ava=true, x=80, y=720-200, r=80},--moveLeft
{ava=true, x=320, y=720-200, r=80},--moveRight
{ava=true, x=1280-80, y=720-200, r=80},--rotRight
{ava=true, x=1280-200, y=720-80, r=80},--rotLeft
{ava=true, x=1280-200, y=720-320, r=80},--rot180
{ava=true, x=200, y=720-320, r=80},--hardDrop
{ava=true, x=200, y=720-80, r=80},--softDrop
{ava=true, x=1280-320, y=720-200, r=80},--hold
{ava=true, x=80, y=280, r=80},--func1
{ava=true, x=1280-80, y=280, r=80},--func2
{ava=false, x=670, y=50, r=30},--insLeft
{ava=false, x=730, y=50, r=30},--insRight
{ava=false, x=790, y=50, r=30},--insDown
{ava=false, x=850, y=50, r=30},--down1
{ava=false, x=910, y=50, r=30},--down4
{ava=false, x=970, y=50, r=30},--down10
{ava=false, x=1030, y=50, r=30},--dropLeft
{ava=false, x=1090, y=50, r=30},--dropRight
{ava=false, x=1150, y=50, r=30},--zangiLeft
{ava=false, x=1210, y=50, r=30},--zangiRight
{ava=true, x=80, y=720-200,r=80},--moveLeft
{ava=true, x=320, y=720-200,r=80},--moveRight
{ava=true, x=1280-80, y=720-200,r=80},--rotRight
{ava=true, x=1280-200,y=720-80, r=80},--rotLeft
{ava=true, x=1280-200,y=720-320,r=80},--rot180
{ava=true, x=200, y=720-320,r=80},--hardDrop
{ava=true, x=200, y=720-80, r=80},--softDrop
{ava=true, x=1280-320,y=720-200,r=80},--hold
{ava=true, x=80, y=280, r=80},--func1
{ava=true, x=1280-80, y=280, r=80},--func2
{ava=false, x=670, y=50, r=30},--insLeft
{ava=false, x=730, y=50, r=30},--insRight
{ava=false, x=790, y=50, r=30},--insDown
{ava=false, x=850, y=50, r=30},--down1
{ava=false, x=910, y=50, r=30},--down4
{ava=false, x=970, y=50, r=30},--down10
{ava=false, x=1030, y=50, r=30},--dropLeft
{ava=false, x=1090, y=50, r=30},--dropRight
{ava=false, x=1150, y=50, r=30},--zangiLeft
{ava=false, x=1210, y=50, r=30},--zangiRight
}
RANKS={sprint_10l=0}--Ranks of modes
STAT={
version=VERSION.code,
run=0,game=0,time=0,frame=0,
key=0,rotate=0,hold=0,
extraPiece=0,finesseRate=0,
piece=0,row=0,dig=0,
atk=0,digatk=0,
send=0,recv=0,pend=0,off=0,
clear=(function()local L={}for i=1,29 do L[i]={0,0,0,0,0,0}end return L end)(),
spin=(function()local L={}for i=1,29 do L[i]={0,0,0,0,0,0,0}end return L end)(),
pc=0,hpc=0,b2b=0,b3b=0,score=0,
lastPlay='sprint_10l',--Last played mode ID
date=false,
todayTime=0,
version=VERSION.code,
run=0,game=0,time=0,frame=0,
key=0,rotate=0,hold=0,
extraPiece=0,finesseRate=0,
piece=0,row=0,dig=0,
atk=0,digatk=0,
send=0,recv=0,pend=0,off=0,
clear=(function()local L={}for i=1,29 do L[i]={0,0,0,0,0,0}end return L end)(),
spin=(function()local L={}for i=1,29 do L[i]={0,0,0,0,0,0,0}end return L end)(),
pc=0,hpc=0,b2b=0,b3b=0,score=0,
lastPlay='sprint_10l',--Last played mode ID
date=false,
todayTime=0,
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,314 +1,314 @@
return{
loadText={
loadSFX="音效",
loadVoice="语音",
loadFont="字体",
loadModeIcon="模式图标",
loadMode="模式",
loadOther="其他",
finish="走你",
},
playedLong="今天玩很久了,给我注意点",
playedTooMuch="特么再玩小心眼睛瞎掉,爬",
loadText={
loadSFX="音效",
loadVoice="语音",
loadFont="字体",
loadModeIcon="模式图标",
loadMode="模式",
loadOther="其他",
finish="走你",
},
playedLong="今天玩很久了,给我注意点",
playedTooMuch="特么再玩小心眼睛瞎掉,爬",
royale_remain="剩 $1 人",
cmb={nil,"1连","2连","3连","4连","5连","6连","7连","8连","9连","10连!","11连!","12连!","13连!","14连!","15连!","16连!","17连!","18连!","19连!","MEGACMB"},
spin="",
clear={"消一","消二","消三","消四","卧槽","离谱"},
mini="",b2b="牛逼",b3b="很牛逼",
PC="消干净了",HPC="消挺干净",
royale_remain="剩 $1 人",
cmb={nil,"1连","2连","3连","4连","5连","6连","7连","8连","9连","10连!","11连!","12连!","13连!","14连!","15连!","16连!","17连!","18连!","19连!","MEGACMB"},
spin="",
clear={"消一","消二","消三","消四","卧槽","离谱"},
mini="",b2b="牛逼",b3b="很牛逼",
PC="消干净了",HPC="消挺干净",
great="不错的",
awesome="您很强",
almost="太舒服了",
continue="您继续",
maxspeed="速度封顶",
great="不错的",
awesome="您很强",
almost="太舒服了",
continue="您继续",
maxspeed="速度封顶",
speedLV="速度等级",
piece="块数",line="行数",atk="",eff="",
rpm="收每分",tsd="T2",
grade="段位",techrash="消四",
wave="波数",nextWave="下一波",
combo="连击",maxcmb="最大连",
pc="消干净了",ko="淘汰",
speedLV="速度等级",
piece="块数",line="行数",atk="",eff="",
rpm="收每分",tsd="T2",
grade="段位",techrash="消四",
wave="波数",nextWave="下一波",
combo="连击",maxcmb="最大连",
pc="消干净了",ko="淘汰",
win="好了",
lose="挂了",
win="好了",
lose="挂了",
finish="好厉害呀 真帅气呢",
gamewin="成了",
gameover="没了",
finish="好厉害呀 真帅气呢",
gamewin="成了",
gameover="没了",
pause="歇会",
pauseCount="歇多久了",
finesse_ap="",
finesse_fc="全连",
pause="歇会",
pauseCount="歇多久了",
finesse_ap="",
finesse_fc="全连",
noUsername="别闹。",
wrongEmail="别乱输。",
noPassword="注册会不会?",
diffPassword="字不认识?",
noUsername="别闹。",
wrongEmail="别乱输。",
noPassword="注册会不会?",
diffPassword="字不认识?",
ranks={"","","","",""},
ranks={"","","","",""},
createRoomSuccessed="创好了",
started="开了",
spectating="看戏中",
createRoomSuccessed="创好了",
started="开了",
spectating="看戏中",
stat={
"开了几次:",
"玩了几把:",
"玩了多久:",
"按键/旋转/暂存:",
"方块/消行/攻击:",
"接收/抵消/上涨:",
"挖掘/挖掘攻击:",
"效率/挖掘效率:",
"牛逼/很牛逼:",
"消光/消半截:",
"多余操作/极简率:",
},
WidgetText={
setting_game={
title="游戏设置",
stat={
"开了几次:",
"玩了几把:",
"玩了多久:",
"按键/旋转/暂存:",
"方块/消行/攻击:",
"接收/抵消/上涨:",
"挖掘/挖掘攻击:",
"效率/挖掘效率:",
"牛逼/很牛逼:",
"消光/消半截:",
"多余操作/极简率:",
},
WidgetText={
setting_game={
title="游戏设置",
graphic="←改画面",
sound="改声音→",
graphic="←改画面",
sound="改声音→",
ctrl="改控制",
key="改键位",
touch="改触屏",
},
setting_video={
title="改画面",
sound="←改声音",
game="游戏设置→",
ctrl="改控制",
key="改键位",
touch="改触屏",
},
setting_video={
title="改画面",
sound="←改声音",
game="游戏设置→",
block="方块可见",
ghost="阴影",
center="中心",
lineNum="行号",
block="方块可见",
ghost="阴影",
center="中心",
lineNum="行号",
text="招式名",
score="跳分",
warn="要死",
highCam="拉镜",
},
setting_sound={
title="改声音",
text="招式名",
score="跳分",
warn="要死",
highCam="拉镜",
},
setting_sound={
title="改声音",
game="←游戏设置",
graphic="改画面→",
game="←游戏设置",
graphic="改画面→",
bgm="",
spawn="出块",
warn="警告",
vib="嗡嗡",
cv="",
},
setting_control={
title="改控制",
reset="重设",
},
setting_skin={
skinSet="皮肤",
title="改外观",
},
setting_touchSwitch={
basic="阳间",
pro="阴间",
},
about={
staff="游戏谁写的",
his="黑历史",
qq="QQ对线",
},
register={
password2="你懂的",
registering="",
},
sound={
title="音效室",
sfx="音效",
voc="语音",
bgm="",
spawn="出块",
warn="警告",
vib="嗡嗡",
cv="",
},
setting_control={
title="改控制",
reset="重设",
},
setting_skin={
skinSet="皮肤",
title="改外观",
},
setting_touchSwitch={
basic="阳间",
pro="阴间",
},
about={
staff="游戏谁写的",
his="黑历史",
qq="QQ对线",
},
register={
password2="你懂的",
registering="",
},
sound={
title="音效室",
sfx="音效",
voc="语音",
hold="暂存",
prehold="提前暂存",
_pc="消干净了",
hold="暂存",
prehold="提前暂存",
_pc="消干净了",
spin0="空旋转",
spin1="旋转消一",
spin2="旋转消二",
spin3="旋转消三",
spin0="空旋转",
spin1="旋转消一",
spin2="旋转消二",
spin3="旋转消三",
z0="Z旋",
z1="Z旋消一",
z2="Z旋消二",
z3="Z旋消三",
s0="S旋",
s1="S旋消一",
s2="S旋消二",
s3="S旋消三",
z0="Z旋",
z1="Z旋消一",
z2="Z旋消二",
z3="Z旋消三",
s0="S旋",
s1="S旋消一",
s2="S旋消二",
s3="S旋消三",
j0="J旋",
j1="J旋消一",
j2="J旋消二",
j3="J旋消三",
l0="L旋",
l1="L旋消一",
l2="L旋消二",
l3="L旋消三",
j0="J旋",
j1="J旋消一",
j2="J旋消二",
j3="J旋消三",
l0="L旋",
l1="L旋消一",
l2="L旋消二",
l3="L旋消三",
t0="T旋",
t1="T旋消一",
t2="T旋消二",
t3="T旋消三",
o0="O旋",
o1="O旋消一",
o2="O旋消二",
o3="O旋消三",
t0="T旋",
t1="T旋消一",
t2="T旋消二",
t3="T旋消三",
o0="O旋",
o1="O旋消一",
o2="O旋消二",
o3="O旋消三",
i0="I旋",
i1="I旋消一",
i2="I旋消二",
i3="I旋消三",
i0="I旋",
i1="I旋消一",
i2="I旋消二",
i3="I旋消三",
mini="",
b2b="牛逼",
b3b="很牛逼",
pc="消干净了",
},
app_15p={
reset="打乱",
color="",
blind="",
slide="滑动",
pathVis="路径显示",
revKB="键盘反向",
},
app_schulteG={
reset="重开",
rank="尺寸",
blind="",
disappear="消失",
tapFX="动画",
},
savedata={
export="复制走",
import="粘贴到",
unlock="地图",
data="统计",
setting="设置",
vk="虚拟按键",
mini="",
b2b="牛逼",
b3b="很牛逼",
pc="消干净了",
},
app_15p={
reset="打乱",
color="",
blind="",
slide="滑动",
pathVis="路径显示",
revKB="键盘反向",
},
app_schulteG={
reset="重开",
rank="尺寸",
blind="",
disappear="消失",
tapFX="动画",
},
savedata={
export="复制走",
import="粘贴到",
unlock="地图",
data="统计",
setting="设置",
vk="虚拟按键",
couldSave="云存档(测试,炸了别怪我)",
notLogin="[不登录存个锤子]",
upload="上传",
download="下载",
},
},
modes={
['sprint_10l']= {"竞速", "10L", "消10行"},
['sprint_20l']= {"竞速", "20L", "消20行"},
['sprint_40l']= {"竞速", "40L", "消40行"},
['sprint_100l']= {"竞速", "100L", "消100行"},
['sprint_400l']= {"竞速", "400L", "消400行"},
['sprint_1000l']= {"竞速", "1000L", "消1000行"},
['sprintPenta']= {"竞速", "五连块", "离谱"},
['sprintMPH']= {"竞速", "纯净", "听说你反应很快?"},
['dig_10l']= {"挖掘", "10L", "挖10行"},
['dig_40l']= {"挖掘", "40L", "挖40行"},
['dig_100l']= {"挖掘", "100L", "挖100行"},
['dig_400l']= {"挖掘", "400L", "挖400行"},
['dig_1000l']= {"挖掘", "1000L", "挖1000行"},
['drought_n']= {"干旱", "100L", "放轻松,简单得很"},
['drought_l']= {"干旱+", "100L", "有趣的要来了"},
['stack_e']= {"堆叠", "简单", "智力启蒙玩具(确信"},
['stack_h']= {"堆叠", "困难", "智力启蒙玩具(确信"},
['stack_u']= {"堆叠", "极限", "智力启蒙玩具(确信"},
['marathon_n']= {"马拉松", "普通", "休闲模式"},
['marathon_h']= {"马拉松", "困难", "休闲模式"},
['solo_e']= {"单挑", "简单", "鲨AI"},
['solo_n']= {"单挑", "普通", "鲨AI"},
['solo_h']= {"单挑", "困难", "鲨AI"},
['solo_l']= {"单挑", "疯狂", "鲨AI"},
['solo_u']= {"单挑", "极限", "鲨AI"},
['techmino49_e']= {"49人混战", "简单", "这我岂不是乱鲨"},
['techmino49_h']= {"49人混战", "困难", "这我岂不是乱鲨"},
['techmino49_u']= {"49人混战", "极限", "你吃鸡率多少?"},
['techmino99_e']= {"99人混战", "简单", "这我岂不是乱鲨"},
['techmino99_h']= {"99人混战", "困难", "这我岂不是乱鲨"},
['techmino99_u']= {"99人混战", "极限", "你吃鸡率多少?"},
['round_e']= {"回合制", "简单", "下棋"},
['round_n']= {"回合制", "普通", "下棋"},
['round_h']= {"回合制", "困难", "下棋"},
['round_l']= {"回合制", "疯狂", "下棋"},
['round_u']= {"回合制", "极限", "下棋"},
['master_n']= {"大师", "普通", "无脑20G"},
['master_h']= {"大师", "困难", "简单20G"},
['master_final']= {"大师", "终点", "究极20G:真正的游戏"},
['master_ph']= {"大师", "虚幻", "虚幻20G:好玩"},
['master_ex']= {"宗师", "EX", "你行你上"},
['rhythm_e']= {"节奏", "简单", "很无聊的"},
['rhythm_h']= {"节奏", "困难", "好玩么?"},
['rhythm_u']= {"节奏", "极限", "真男人不玩低难度"},
['blind_e']= {"隐形", "半隐", "谁都能玩"},
['blind_n']= {"隐形", "全隐", "稍加练习即可"},
['blind_h']= {"隐形", "瞬隐", "和上一个一样"},
['blind_l']= {"隐形", "瞬隐+", "这个确实挺难的"},
['blind_u']= {"隐形", "啊这", "你准备好了吗"},
['blind_wtf']= {"隐形", "不会吧", "还没准备好"},
['classic_fast']= {"高速经典", "CTWC", "就这?简单"},
['survivor_e']= {"生存", "简单", "这都玩不下去?不会吧"},
['survivor_n']= {"生存", "普通", "呵,这都玩不过?"},
['survivor_h']= {"生存", "困难", "所以呢?"},
['survivor_l']= {"生存", "疯狂", "然后呢?"},
['survivor_u']= {"生存", "极限", "舒服了"},
['attacker_h']= {"进攻", "困难", "进攻练习"},
['attacker_u']= {"进攻", "极限", "进攻练习"},
['defender_n']= {"防守", "普通", "防守练习"},
['defender_l']= {"防守", "疯狂", "防守练习"},
['dig_h']= {"挖掘", "困难", "挖掘练习"},
['dig_u']= {"挖掘", "极限", "挖掘练习"},
['bigbang']= {"大爆炸", "简单", "All-spin 入门教程\n施工中"},
['c4wtrain_n']= {"C4W练习", "普通", "无 限 连 击"},
['c4wtrain_l']= {"C4W练习", "疯狂", "无 限 连 击"},
['pctrain_n']= {"全清训练", "普通", "随便打打"},
['pctrain_l']= {"全清训练", "疯狂", "建议不打"},
['pc_n']= {"全清挑战", "普通", "100行内刷PC"},
['pc_h']= {"全清挑战", "困难", "100行内刷PC"},
['pc_l']= {"全清挑战", "疯狂", "100行内刷PC"},
['pc_inf']= {"无尽全清挑战", "", "你这水平还是先别玩了"},
['tech_n']= {"科研", "普通", "禁止断B2B"},
['tech_n_plus']= {"科研", "普通+", "仅允许spin与PC"},
['tech_h']= {"科研", "困难", "禁止断B2B"},
['tech_h_plus']= {"科研", "困难+", "仅允许spin与PC"},
['tech_l']= {"科研", "疯狂", "禁止断B2B"},
['tech_l_plus']= {"科研", "疯狂+", "仅允许spin与PC"},
['tech_finesse']= {"科研", "极简", "强制最简操作"},
['tech_finesse_f']= {"科研", "极简+", "禁止普通消除,强制最简操作"},
['tsd_e']= {"TSD挑战", "简单", "刷T2"},
['tsd_h']= {"TSD挑战", "困难", "刷T2"},
['tsd_u']= {"TSD挑战", "极限", "刷T2"},
['backfire_n']= {"自攻自受", "普通", "100攻击很少的,冲冲冲"},
['backfire_h']= {"自攻自受", "困难", "你在害怕什么"},
['backfire_l']= {"自攻自受", "疯狂", "别怂啊,打攻击呀"},
['backfire_u']= {"自攻自受", "极限", "能把自己玩死,不会吧"},
['sprintAtk']= {"竞速", "100攻击", "送100行"},
['zen']= {"", "200", "不限时200行"},
['ultra']= {"限时打分", "挑战", "2分钟刷分"},
['infinite']= {"无尽", "", "真的有人会玩这个?"},
['infinite_dig']= {"无尽:挖掘", "", "闲得慌就来挖"},
couldSave="云存档(测试,炸了别怪我)",
notLogin="[不登录存个锤子]",
upload="上传",
download="下载",
},
},
modes={
['sprint_10l']= {"竞速", "10L", "消10行"},
['sprint_20l']= {"竞速", "20L", "消20行"},
['sprint_40l']= {"竞速", "40L", "消40行"},
['sprint_100l']= {"竞速", "100L", "消100行"},
['sprint_400l']= {"竞速", "400L", "消400行"},
['sprint_1000l']= {"竞速", "1000L", "消1000行"},
['sprintPenta']= {"竞速", "五连块", "离谱"},
['sprintMPH']= {"竞速", "纯净", "听说你反应很快?"},
['dig_10l']= {"挖掘", "10L", "挖10行"},
['dig_40l']= {"挖掘", "40L", "挖40行"},
['dig_100l']= {"挖掘", "100L", "挖100行"},
['dig_400l']= {"挖掘", "400L", "挖400行"},
['dig_1000l']= {"挖掘", "1000L", "挖1000行"},
['drought_n']= {"干旱", "100L", "放轻松,简单得很"},
['drought_l']= {"干旱+", "100L", "有趣的要来了"},
['stack_e']= {"堆叠", "简单", "智力启蒙玩具(确信"},
['stack_h']= {"堆叠", "困难", "智力启蒙玩具(确信"},
['stack_u']= {"堆叠", "极限", "智力启蒙玩具(确信"},
['marathon_n']= {"马拉松", "普通", "休闲模式"},
['marathon_h']= {"马拉松", "困难", "休闲模式"},
['solo_e']= {"单挑", "简单", "鲨AI"},
['solo_n']= {"单挑", "普通", "鲨AI"},
['solo_h']= {"单挑", "困难", "鲨AI"},
['solo_l']= {"单挑", "疯狂", "鲨AI"},
['solo_u']= {"单挑", "极限", "鲨AI"},
['techmino49_e']= {"49人混战", "简单", "这我岂不是乱鲨"},
['techmino49_h']= {"49人混战", "困难", "这我岂不是乱鲨"},
['techmino49_u']= {"49人混战", "极限", "你吃鸡率多少?"},
['techmino99_e']= {"99人混战", "简单", "这我岂不是乱鲨"},
['techmino99_h']= {"99人混战", "困难", "这我岂不是乱鲨"},
['techmino99_u']= {"99人混战", "极限", "你吃鸡率多少?"},
['round_e']= {"回合制", "简单", "下棋"},
['round_n']= {"回合制", "普通", "下棋"},
['round_h']= {"回合制", "困难", "下棋"},
['round_l']= {"回合制", "疯狂", "下棋"},
['round_u']= {"回合制", "极限", "下棋"},
['master_n']= {"大师", "普通", "无脑20G"},
['master_h']= {"大师", "困难", "简单20G"},
['master_final']= {"大师", "终点", "究极20G:真正的游戏"},
['master_ph']= {"大师", "虚幻", "虚幻20G:好玩"},
['master_ex']= {"宗师", "EX", "你行你上"},
['rhythm_e']= {"节奏", "简单", "很无聊的"},
['rhythm_h']= {"节奏", "困难", "好玩么?"},
['rhythm_u']= {"节奏", "极限", "真男人不玩低难度"},
['blind_e']= {"隐形", "半隐", "谁都能玩"},
['blind_n']= {"隐形", "全隐", "稍加练习即可"},
['blind_h']= {"隐形", "瞬隐", "和上一个一样"},
['blind_l']= {"隐形", "瞬隐+", "这个确实挺难的"},
['blind_u']= {"隐形", "啊这", "你准备好了吗"},
['blind_wtf']= {"隐形", "不会吧", "还没准备好"},
['classic_fast']= {"高速经典", "CTWC", "就这?简单"},
['survivor_e']= {"生存", "简单", "这都玩不下去?不会吧"},
['survivor_n']= {"生存", "普通", "呵,这都玩不过?"},
['survivor_h']= {"生存", "困难", "所以呢?"},
['survivor_l']= {"生存", "疯狂", "然后呢?"},
['survivor_u']= {"生存", "极限", "舒服了"},
['attacker_h']= {"进攻", "困难", "进攻练习"},
['attacker_u']= {"进攻", "极限", "进攻练习"},
['defender_n']= {"防守", "普通", "防守练习"},
['defender_l']= {"防守", "疯狂", "防守练习"},
['dig_h']= {"挖掘", "困难", "挖掘练习"},
['dig_u']= {"挖掘", "极限", "挖掘练习"},
['bigbang']= {"大爆炸", "简单", "All-spin 入门教程\n施工中"},
['c4wtrain_n']= {"C4W练习", "普通", "无 限 连 击"},
['c4wtrain_l']= {"C4W练习", "疯狂", "无 限 连 击"},
['pctrain_n']= {"全清训练", "普通", "随便打打"},
['pctrain_l']= {"全清训练", "疯狂", "建议不打"},
['pc_n']= {"全清挑战", "普通", "100行内刷PC"},
['pc_h']= {"全清挑战", "困难", "100行内刷PC"},
['pc_l']= {"全清挑战", "疯狂", "100行内刷PC"},
['pc_inf']= {"无尽全清挑战", "", "你这水平还是先别玩了"},
['tech_n']= {"科研", "普通", "禁止断B2B"},
['tech_n_plus']= {"科研", "普通+", "仅允许spin与PC"},
['tech_h']= {"科研", "困难", "禁止断B2B"},
['tech_h_plus']= {"科研", "困难+", "仅允许spin与PC"},
['tech_l']= {"科研", "疯狂", "禁止断B2B"},
['tech_l_plus']= {"科研", "疯狂+", "仅允许spin与PC"},
['tech_finesse']= {"科研", "极简", "强制最简操作"},
['tech_finesse_f']= {"科研", "极简+", "禁止普通消除,强制最简操作"},
['tsd_e']= {"TSD挑战", "简单", "刷T2"},
['tsd_h']= {"TSD挑战", "困难", "刷T2"},
['tsd_u']= {"TSD挑战", "极限", "刷T2"},
['backfire_n']= {"自攻自受", "普通", "100攻击很少的,冲冲冲"},
['backfire_h']= {"自攻自受", "困难", "你在害怕什么"},
['backfire_l']= {"自攻自受", "疯狂", "别怂啊,打攻击呀"},
['backfire_u']= {"自攻自受", "极限", "能把自己玩死,不会吧"},
['sprintAtk']= {"竞速", "100攻击", "送100行"},
['zen']= {"", "200", "不限时200行"},
['ultra']= {"限时打分", "挑战", "2分钟刷分"},
['infinite']= {"无尽", "", "真的有人会玩这个?"},
['infinite_dig']= {"无尽:挖掘", "", "闲得慌就来挖"},
['sprintFix']= {"竞速", "无移动"},
['sprintLock']= {"竞速", "无旋转"},
['sprintSmooth']= {"竞速", "无摩擦"},
['marathon_bfmax']= {"马拉松", "极限"},
['sprintFix']= {"竞速", "无移动"},
['sprintLock']= {"竞速", "无旋转"},
['sprintSmooth']= {"竞速", "无摩擦"},
['marathon_bfmax']= {"马拉松", "极限"},
['master_l']= {"大师", "疯狂"},
['master_u']= {"大师", "极限"},
['master_l']= {"大师", "疯狂"},
['master_u']= {"大师", "极限"},
['custom_clear']= {"自定义", "普通"},
['custom_puzzle']= {"自定义", "拼图"},
},
['custom_clear']= {"自定义", "普通"},
['custom_puzzle']= {"自定义", "拼图"},
},
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,230 +1,230 @@
return{
cmb={nil,"1连击","2连击","3连击","4连击","5连击","6连击","7连击","8连击","9连击","10连击!","11连击!","12连击!","13连击!","14连击!","15连击!","16连击!","17连击!","18连击!","19连击!","巨型连击"},
spin="型回旋",
clear={"单清","双清","三清","四清","五清","六清"},
mini="迷你",b2b="满贯",b3b="大满贯",
PC="场地全清",HPC="场地半清",
cmb={nil,"1连击","2连击","3连击","4连击","5连击","6连击","7连击","8连击","9连击","10连击!","11连击!","12连击!","13连击!","14连击!","15连击!","16连击!","17连击!","18连击!","19连击!","巨型连击"},
spin="型回旋",
clear={"单清","双清","三清","四清","五清","六清"},
mini="迷你",b2b="满贯",b3b="大满贯",
PC="场地全清",HPC="场地半清",
great="不错!",
awesome="精彩。",
almost="差一点!",
continue="继续。",
great="不错!",
awesome="精彩。",
almost="差一点!",
continue="继续。",
speedLV="速度等级",
piece="块数",line="行数",atk="攻击",eff="效率",
rpm="收每分",tsd="T2",
grade="段位",techrash="消四",
wave="波数",nextWave="下一波",
combo="连击",maxcmb="最大连击",
pc="全清",ko="淘汰",
speedLV="速度等级",
piece="块数",line="行数",atk="攻击",eff="效率",
rpm="收每分",tsd="T2",
grade="段位",techrash="消四",
wave="波数",nextWave="下一波",
combo="连击",maxcmb="最大连击",
pc="全清",ko="淘汰",
finesse_ap="完美极简",
finesse_fc="全连击",
finesse_ap="完美极简",
finesse_fc="全连击",
ai_fixed="不能同时开启电脑玩家和固定序列",
ai_prebag="不能同时开启电脑玩家和含有非四连块的自定义序列",
ai_mission="不能同时开启电脑玩家和自定义任务",
ai_fixed="不能同时开启电脑玩家和固定序列",
ai_prebag="不能同时开启电脑玩家和含有非四连块的自定义序列",
ai_mission="不能同时开启电脑玩家和自定义任务",
ranks={"","","","",""},
ranks={"","","","",""},
modInstruction="选择你要使用的模组!\n不同的模组会用不同的方式改变游戏规则,来开发新玩法挑战自我吧!\n提醒:开启一些模组会让成绩无效 你可以用键盘开关模组,按tab重置",
modInfo={
next="预览数量:\n强制使用预览的个数",
hold="暂存数量:\n强制使用暂存的个数",
hideNext="隐藏预览:\n隐藏前几个预览",
infHold="无限暂存:\n可以无限制使用暂存",
forceB2B="强制满贯:\n满贯点数条掉到启动线以下就会结束游戏",
},
pauseStat={
"时间:",
"按键/旋转/暂存:",
"落块:",
"消行/挖掘:",
"攻击/挖掘攻击:",
"上涨/接收/抵消:",
"消除:",
"回旋:",
"(大)满贯/全(半)清:",
"非极简操作:",
},
radar={"","","","","",""},
radarData={"防/分","守/分","攻/分","送/分","行/分","挖/分"},
WidgetText={
mode={
mod="模组(F1)",
},
mod={
title="模组",
},
setting_control={
das="首次移动延迟",arr="移动重复延迟",
sddas="首次软降延迟",sdarr="软降重复延迟",
ihs="提前暂存",
},
setting_skin={
spin1="",spin2="",spin3="",spin4="",spin5="",spin6="",spin7="",
},
customGame={
mod="模组(F1)",
modInstruction="选择你要使用的模组!\n不同的模组会用不同的方式改变游戏规则,来开发新玩法挑战自我吧!\n提醒:开启一些模组会让成绩无效 你可以用键盘开关模组,按tab重置",
modInfo={
next="预览数量:\n强制使用预览的个数",
hold="暂存数量:\n强制使用暂存的个数",
hideNext="隐藏预览:\n隐藏前几个预览",
infHold="无限暂存:\n可以无限制使用暂存",
forceB2B="强制满贯:\n满贯点数条掉到启动线以下就会结束游戏",
},
pauseStat={
"时间:",
"按键/旋转/暂存:",
"落块:",
"消行/挖掘:",
"攻击/挖掘攻击:",
"上涨/接收/抵消:",
"消除:",
"回旋:",
"(大)满贯/全(半)清:",
"非极简操作:",
},
radar={"","","","","",""},
radarData={"防/分","守/分","攻/分","送/分","行/分","挖/分"},
WidgetText={
mode={
mod="模组(F1)",
},
mod={
title="模组",
},
setting_control={
das="首次移动延迟",arr="移动重复延迟",
sddas="首次软降延迟",sdarr="软降重复延迟",
ihs="提前暂存",
},
setting_skin={
spin1="",spin2="",spin3="",spin4="",spin5="",spin6="",spin7="",
},
customGame={
mod="模组(F1)",
nextCount="预览个数",
holdCount="暂存个数",
infHold="无限暂存",
phyHold="物理暂存",
},
sound={
clear1="消一",
clear2="消二",
clear3="消三",
clear4="消四",
spin0="空旋转",
spin1="旋转消一",
spin2="旋转消二",
spin3="旋转消三",
nextCount="预览个数",
holdCount="暂存个数",
infHold="无限暂存",
phyHold="物理暂存",
},
sound={
clear1="消一",
clear2="消二",
clear3="消三",
clear4="消四",
spin0="空旋转",
spin1="旋转消一",
spin2="旋转消二",
spin3="旋转消三",
_1="消一",
_2="消二",
_3="消三",
_4="消四",
z0="Z旋",
z1="Z旋消一",
z2="Z旋消二",
z3="Z旋消三",
s0="S旋",
s1="S旋消一",
s2="S旋消二",
s3="S旋消三",
_1="消一",
_2="消二",
_3="消三",
_4="消四",
z0="Z旋",
z1="Z旋消一",
z2="Z旋消二",
z3="Z旋消三",
s0="S旋",
s1="S旋消一",
s2="S旋消二",
s3="S旋消三",
j0="J旋",
j1="J旋消一",
j2="J旋消二",
j3="J旋消三",
l0="L旋",
l1="L旋消一",
l2="L旋消二",
l3="L旋消三",
j0="J旋",
j1="J旋消一",
j2="J旋消二",
j3="J旋消三",
l0="L旋",
l1="L旋消一",
l2="L旋消二",
l3="L旋消三",
t0="T旋",
t1="T旋消一",
t2="T旋消二",
t3="T旋消三",
o0="O旋",
o1="O旋消一",
o2="O旋消二",
o3="O旋消三",
t0="T旋",
t1="T旋消一",
t2="T旋消二",
t3="T旋消三",
o0="O旋",
o1="O旋消一",
o2="O旋消二",
o3="O旋消三",
i0="I旋",
i1="I旋消一",
i2="I旋消二",
i3="I旋消三",
i0="I旋",
i1="I旋消一",
i2="I旋消二",
i3="I旋消三",
mini="迷你",
b2b="满贯",
b3b="大满贯",
pc="全清",
},
},
modes={
['sprint_10l']= {"竞速", "10行", "消除10行"},
['sprint_20l']= {"竞速", "20行", "消除20行"},
['sprint_40l']= {"竞速", "40行", "消除40行"},
['sprint_100l']= {"竞速", "100行", "消除100行"},
['sprint_400l']= {"竞速", "400行", "消除400行"},
['sprint_1000l']= {"竞速", "1000行", "消除1000行"},
['sprintPenta']= {"竞速", "五连块", "伤脑筋十八块"},
['sprintMPH']= {"竞速", "纯净", "纯随机\n无预览\n无暂存"},
['dig_10l']= {"挖掘", "10L", "挖掘10行"},
['dig_40l']= {"挖掘", "40L", "挖掘40行"},
['dig_100l']= {"挖掘", "100L", "挖掘100行"},
['dig_400l']= {"挖掘", "400L", "挖掘400行"},
['dig_1000l']= {"挖掘", "1000L", "挖掘1000行"},
['drought_n']= {"干旱", "100行", "你I没了"},
['drought_l']= {"干旱+", "100行", "后 妈 发 牌"},
['stack_e']= {"堆积", "简单", "搭积木"},
['stack_h']= {"堆积", "困难", "搭积木"},
['stack_u']= {"堆积", "极限", "搭积木"},
['marathon_n']= {"马拉松", "普通", "200行加速马拉松"},
['marathon_h']= {"马拉松", "困难", "200行高速马拉松"},
['solo_e']= {"单挑", "简单", "打败机器人"},
['solo_n']= {"单挑", "普通", "打败机器人"},
['solo_h']= {"单挑", "困难", "打败机器人"},
['solo_l']= {"单挑", "疯狂", "打败机器人"},
['solo_u']= {"单挑", "极限", "打败机器人"},
['techmino49_e']= {"49人混战", "简单", "49人混战,活到最后"},
['techmino49_h']= {"49人混战", "困难", "49人混战,活到最后"},
['techmino49_u']= {"49人混战", "极限", "49人混战,活到最后"},
['techmino99_e']= {"99人混战", "简单", "99人混战,活到最后"},
['techmino99_h']= {"99人混战", "困难", "99人混战,活到最后"},
['techmino99_u']= {"99人混战", "极限", "99人混战,活到最后"},
['round_e']= {"回合制", "简单", "下棋模式"},
['round_n']= {"回合制", "普通", "下棋模式"},
['round_h']= {"回合制", "困难", "下棋模式"},
['round_l']= {"回合制", "疯狂", "下棋模式"},
['round_u']= {"回合制", "极限", "下棋模式"},
['master_n']= {"大师", "普通", "20G初心者练习"},
['master_h']= {"大师", "困难", "上级者20G挑战"},
['master_final']= {"大师", "终点", "究极20G:无法触及的终点"},
['master_ph']= {"大师", "虚幻", "虚幻20G:???"},
['master_ex']= {"宗师", "EX", "成为方块大师"},
['rhythm_e']= {"节奏", "简单", "200行低速节奏马拉松"},
['rhythm_h']= {"节奏", "困难", "200行中速节奏马拉松"},
['rhythm_u']= {"节奏", "极限", "200行高速节奏马拉松"},
['blind_e']= {"隐形", "半隐", "不强大脑"},
['blind_n']= {"隐形", "全隐", "挺强大脑"},
['blind_h']= {"隐形", "瞬隐", "很强大脑"},
['blind_l']= {"隐形", "瞬隐+", "超强大脑"},
['blind_u']= {"隐形", "啊这", "你准备好了吗"},
['blind_wtf']= {"隐形", "不会吧", "还没准备好"},
['classic_fast']= {"高速经典", "CTWC", "高速经典"},
['survivor_e']= {"生存", "简单", "你能存活多久?"},
['survivor_n']= {"生存", "普通", "你能存活多久?"},
['survivor_h']= {"生存", "困难", "你能存活多久?"},
['survivor_l']= {"生存", "疯狂", "你能存活多久?"},
['survivor_u']= {"生存", "极限", "你能存活多久?"},
['attacker_h']= {"进攻", "困难", "进攻练习"},
['attacker_u']= {"进攻", "极限", "进攻练习"},
['defender_n']= {"防守", "普通", "防守练习"},
['defender_l']= {"防守", "疯狂", "防守练习"},
['dig_h']= {"挖掘", "困难", "挖掘练习"},
['dig_u']= {"挖掘", "极限", "挖掘练习"},
['bigbang']= {"大爆炸", "简单", "All-spin 入门教程\n施工中"},
['c4wtrain_n']= {"中四宽练习", "普通", "无 限 连 击"},
['c4wtrain_l']= {"中四宽练习", "疯狂", "无 限 连 击"},
['pctrain_n']= {"全清训练", "普通", "简易全清题库,熟悉全清定式的组合"},
['pctrain_l']= {"全清训练", "疯狂", "困难PC题库,强算力者进"},
['pc_n']= {"全清挑战", "普通", "100行内刷全清"},
['pc_h']= {"全清挑战", "困难", "100行内刷全清"},
['pc_l']= {"全清挑战", "疯狂", "100行内刷全清"},
['pc_inf']= {"无尽全清挑战", "", "你能连续做多少PC?"},
['tech_n']= {"科研", "普通", "禁止断B2B"},
['tech_n_plus']= {"科研", "普通+", "仅允许回旋与全清"},
['tech_h']= {"科研", "困难", "禁止断B2B"},
['tech_h_plus']= {"科研", "困难+", "仅允许回旋与全清"},
['tech_l']= {"科研", "疯狂", "禁止断B2B"},
['tech_l_plus']= {"科研", "疯狂+", "仅允许spin与PC"},
['tech_finesse']= {"科研", "极简", "强制最简操作"},
['tech_finesse_f']= {"科研", "极简+", "禁止普通消除,强制最简操作"},
['tsd_e']= {"T2挑战", "简单", "你能连续做几个T旋双清?"},
['tsd_h']= {"T2挑战", "困难", "你能连续做几个T旋双清?"},
['tsd_u']= {"T2挑战", "极限", "你能连续做几个T旋双清?"},
['backfire_n']= {"自攻自防", "普通", "打出100攻击"},
['backfire_h']= {"自攻自防", "困难", "打出100攻击"},
['backfire_l']= {"自攻自防", "疯狂", "打出100攻击"},
['backfire_u']= {"自攻自防", "极限", "打出100攻击"},
['sprintAtk']= {"竞速", "100攻击", "打出100攻击"},
['zen']= {"", "200", "不限时200行"},
['ultra']= {"限时打分", "挑战", "在两分钟内尽可能拿到最多的分数"},
['infinite']= {"无尽", "", "沙盒"},
['infinite_dig']= {"无尽:挖掘", "", "挖呀挖呀挖"},
mini="迷你",
b2b="满贯",
b3b="大满贯",
pc="全清",
},
},
modes={
['sprint_10l']= {"竞速", "10行", "消除10行"},
['sprint_20l']= {"竞速", "20行", "消除20行"},
['sprint_40l']= {"竞速", "40行", "消除40行"},
['sprint_100l']= {"竞速", "100行", "消除100行"},
['sprint_400l']= {"竞速", "400行", "消除400行"},
['sprint_1000l']= {"竞速", "1000行", "消除1000行"},
['sprintPenta']= {"竞速", "五连块", "伤脑筋十八块"},
['sprintMPH']= {"竞速", "纯净", "纯随机\n无预览\n无暂存"},
['dig_10l']= {"挖掘", "10L", "挖掘10行"},
['dig_40l']= {"挖掘", "40L", "挖掘40行"},
['dig_100l']= {"挖掘", "100L", "挖掘100行"},
['dig_400l']= {"挖掘", "400L", "挖掘400行"},
['dig_1000l']= {"挖掘", "1000L", "挖掘1000行"},
['drought_n']= {"干旱", "100行", "你I没了"},
['drought_l']= {"干旱+", "100行", "后 妈 发 牌"},
['stack_e']= {"堆积", "简单", "搭积木"},
['stack_h']= {"堆积", "困难", "搭积木"},
['stack_u']= {"堆积", "极限", "搭积木"},
['marathon_n']= {"马拉松", "普通", "200行加速马拉松"},
['marathon_h']= {"马拉松", "困难", "200行高速马拉松"},
['solo_e']= {"单挑", "简单", "打败机器人"},
['solo_n']= {"单挑", "普通", "打败机器人"},
['solo_h']= {"单挑", "困难", "打败机器人"},
['solo_l']= {"单挑", "疯狂", "打败机器人"},
['solo_u']= {"单挑", "极限", "打败机器人"},
['techmino49_e']= {"49人混战", "简单", "49人混战,活到最后"},
['techmino49_h']= {"49人混战", "困难", "49人混战,活到最后"},
['techmino49_u']= {"49人混战", "极限", "49人混战,活到最后"},
['techmino99_e']= {"99人混战", "简单", "99人混战,活到最后"},
['techmino99_h']= {"99人混战", "困难", "99人混战,活到最后"},
['techmino99_u']= {"99人混战", "极限", "99人混战,活到最后"},
['round_e']= {"回合制", "简单", "下棋模式"},
['round_n']= {"回合制", "普通", "下棋模式"},
['round_h']= {"回合制", "困难", "下棋模式"},
['round_l']= {"回合制", "疯狂", "下棋模式"},
['round_u']= {"回合制", "极限", "下棋模式"},
['master_n']= {"大师", "普通", "20G初心者练习"},
['master_h']= {"大师", "困难", "上级者20G挑战"},
['master_final']= {"大师", "终点", "究极20G:无法触及的终点"},
['master_ph']= {"大师", "虚幻", "虚幻20G:???"},
['master_ex']= {"宗师", "EX", "成为方块大师"},
['rhythm_e']= {"节奏", "简单", "200行低速节奏马拉松"},
['rhythm_h']= {"节奏", "困难", "200行中速节奏马拉松"},
['rhythm_u']= {"节奏", "极限", "200行高速节奏马拉松"},
['blind_e']= {"隐形", "半隐", "不强大脑"},
['blind_n']= {"隐形", "全隐", "挺强大脑"},
['blind_h']= {"隐形", "瞬隐", "很强大脑"},
['blind_l']= {"隐形", "瞬隐+", "超强大脑"},
['blind_u']= {"隐形", "啊这", "你准备好了吗"},
['blind_wtf']= {"隐形", "不会吧", "还没准备好"},
['classic_fast']= {"高速经典", "CTWC", "高速经典"},
['survivor_e']= {"生存", "简单", "你能存活多久?"},
['survivor_n']= {"生存", "普通", "你能存活多久?"},
['survivor_h']= {"生存", "困难", "你能存活多久?"},
['survivor_l']= {"生存", "疯狂", "你能存活多久?"},
['survivor_u']= {"生存", "极限", "你能存活多久?"},
['attacker_h']= {"进攻", "困难", "进攻练习"},
['attacker_u']= {"进攻", "极限", "进攻练习"},
['defender_n']= {"防守", "普通", "防守练习"},
['defender_l']= {"防守", "疯狂", "防守练习"},
['dig_h']= {"挖掘", "困难", "挖掘练习"},
['dig_u']= {"挖掘", "极限", "挖掘练习"},
['bigbang']= {"大爆炸", "简单", "All-spin 入门教程\n施工中"},
['c4wtrain_n']= {"中四宽练习", "普通", "无 限 连 击"},
['c4wtrain_l']= {"中四宽练习", "疯狂", "无 限 连 击"},
['pctrain_n']= {"全清训练", "普通", "简易全清题库,熟悉全清定式的组合"},
['pctrain_l']= {"全清训练", "疯狂", "困难PC题库,强算力者进"},
['pc_n']= {"全清挑战", "普通", "100行内刷全清"},
['pc_h']= {"全清挑战", "困难", "100行内刷全清"},
['pc_l']= {"全清挑战", "疯狂", "100行内刷全清"},
['pc_inf']= {"无尽全清挑战", "", "你能连续做多少PC?"},
['tech_n']= {"科研", "普通", "禁止断B2B"},
['tech_n_plus']= {"科研", "普通+", "仅允许回旋与全清"},
['tech_h']= {"科研", "困难", "禁止断B2B"},
['tech_h_plus']= {"科研", "困难+", "仅允许回旋与全清"},
['tech_l']= {"科研", "疯狂", "禁止断B2B"},
['tech_l_plus']= {"科研", "疯狂+", "仅允许spin与PC"},
['tech_finesse']= {"科研", "极简", "强制最简操作"},
['tech_finesse_f']= {"科研", "极简+", "禁止普通消除,强制最简操作"},
['tsd_e']= {"T2挑战", "简单", "你能连续做几个T旋双清?"},
['tsd_h']= {"T2挑战", "困难", "你能连续做几个T旋双清?"},
['tsd_u']= {"T2挑战", "极限", "你能连续做几个T旋双清?"},
['backfire_n']= {"自攻自防", "普通", "打出100攻击"},
['backfire_h']= {"自攻自防", "困难", "打出100攻击"},
['backfire_l']= {"自攻自防", "疯狂", "打出100攻击"},
['backfire_u']= {"自攻自防", "极限", "打出100攻击"},
['sprintAtk']= {"竞速", "100攻击", "打出100攻击"},
['zen']= {"", "200", "不限时200行"},
['ultra']= {"限时打分", "挑战", "在两分钟内尽可能拿到最多的分数"},
['infinite']= {"无尽", "", "沙盒"},
['infinite_dig']= {"无尽:挖掘", "", "挖呀挖呀挖"},
['sprintFix']= {"竞速", "无移动"},
['sprintLock']= {"竞速", "无旋转"},
['sprintSmooth']= {"竞速", "无摩擦"},
['marathon_bfmax']= {"马拉松", "极限"},
['sprintFix']= {"竞速", "无移动"},
['sprintLock']= {"竞速", "无旋转"},
['sprintSmooth']= {"竞速", "无摩擦"},
['marathon_bfmax']= {"马拉松", "极限"},
['master_l']= {"大师", "疯狂"},
['master_u']= {"大师", "极限"},
['custom_clear']= {"自定义", "普通"},
['custom_puzzle']= {"自定义", "拼图"},
},
['master_l']= {"大师", "疯狂"},
['master_u']= {"大师", "极限"},
['custom_clear']= {"自定义", "普通"},
['custom_puzzle']= {"自定义", "拼图"},
},
}

View File

@@ -1,92 +1,92 @@
return STRING.split([=[
Gameplay:
The system will provide you with tetrominoes (4-block pieces),
with a total of 7 types, and the player needs to control them
(move left and right, rotate 90, 180 or 270 degrees).
each row filled with the field will be cleared.
If there is an opponent, an attack will be sent depending on the line clear type
Play until the end or achieve the level's goal to win.
The system will provide you with tetrominoes (4-block pieces),
with a total of 7 types, and the player needs to control them
(move left and right, rotate 90, 180 or 270 degrees).
each row filled with the field will be cleared.
If there is an opponent, an attack will be sent depending on the line clear type
Play until the end or achieve the level's goal to win.
Rotation system:
Uses Techmino's custom rotation system. Too lazy to write the details
Uses Techmino's custom rotation system. Too lazy to write the details
Spin detection:
Satisfies "3 corner" rule +2 points
Satisfies "immobile" rule +2 points
- As long as one of the above is true, it is a Spin
Satisfies "3 corner" rule +2 points
Satisfies "immobile" rule +2 points
- As long as one of the above is true, it is a Spin
If the rotation was not using the second check in the kick table, +1 point
- The Spin is a Mini if it only has 2 points; the piece is one of S, Z, J, L, T; AND the line clear did not clear the entire piece.
If the rotation was not using the second check in the kick table, +1 point
- The Spin is a Mini if it only has 2 points; the piece is one of S, Z, J, L, T; AND the line clear did not clear the entire piece.
Attack system:
Normal line clears (1 to 3 lines):
Sends (lines cleared -0.5) attack
Special line clears:
Spin sends (lines cleared x2) attack,
- B2B sends extra 1/1/2/4/8 for Spin Single/Double/Triple/Techrash/Techrash+
- B2B2B sends (lines cleared x0.5), and +1 extra blocking
- Minis reduces the attack to 25% (x0.25 multiplier)
Non-Spin Techrash/Techrash+ sends (lines cleared) attack,
- B2B sends 1 additional line
- B2B2B will have an attack boost of 50% and +1 extra blocking
Normal line clears (1 to 3 lines):
Sends (lines cleared -0.5) attack
Special line clears:
Spin sends (lines cleared x2) attack,
- B2B sends extra 1/1/2/4/8 for Spin Single/Double/Triple/Techrash/Techrash+
- B2B2B sends (lines cleared x0.5), and +1 extra blocking
- Minis reduces the attack to 25% (x0.25 multiplier)
Non-Spin Techrash/Techrash+ sends (lines cleared) attack,
- B2B sends 1 additional line
- B2B2B will have an attack boost of 50% and +1 extra blocking
Special line clears will the increase B2B gauge, making later special line clears have either a B2B or B2B2B bonus (see below)
Special line clears will the increase B2B gauge, making later special line clears have either a B2B or B2B2B bonus (see below)
Hemi Perfect Clear (a P.C. "with blocks left below". If it's an I clearing 1 line, the remaining blocks must not be player-placed):
Attack +4, Extra Blocking +2
Hemi Perfect Clear (a P.C. "with blocks left below". If it's an I clearing 1 line, the remaining blocks must not be player-placed):
Attack +4, Extra Blocking +2
Perfect Clear (aka All Clear):
Sends 8 to 16 (increments within a game by 2 for every PC) OR every other damage above, whichever is higher,
and +2 extra blocking.
Perfect Clear (aka All Clear):
Sends 8 to 16 (increments within a game by 2 for every PC) OR every other damage above, whichever is higher,
and +2 extra blocking.
Combos: All damage above will be given a (combo x25%) bonus, or (combo x15%) for Single clear (capped at 12 combo),
+1 more attack for 3 Combo or more.
After calculating all above, the damage value will be rounded down then sent
Combos: All damage above will be given a (combo x25%) bonus, or (combo x15%) for Single clear (capped at 12 combo),
+1 more attack for 3 Combo or more.
After calculating all above, the damage value will be rounded down then sent
Score system:
The better you play, the higher the score.
The better you play, the higher the score.
Attack delay:
Attacks from Doubles/Triples take effect the fastest;
Followed by Techrash, Spins, which send slower attacks;
High combos are the slowest;
For B2B or B2B2B, they also increase the attack delay while they increase lines sent;
Minis will greatly increase the delay.
Attacks from Doubles/Triples take effect the fastest;
Followed by Techrash, Spins, which send slower attacks;
High combos are the slowest;
For B2B or B2B2B, they also increase the attack delay while they increase lines sent;
Minis will greatly increase the delay.
Countering:
When you send attacks, if there is garbage in queue,
extra blocking will be used first, then attack, countering the earliest attack at a 1:1 ratio.
Any extra blocking you didn't use will be discarded, and finally the remaining attack power will be sent to your opponent.
When you send attacks, if there is garbage in queue,
extra blocking will be used first, then attack, countering the earliest attack at a 1:1 ratio.
Any extra blocking you didn't use will be discarded, and finally the remaining attack power will be sent to your opponent.
Back to Back (B2B) gauge:
The B2B gauge ranges from 0 to 1,000. Special line clears are B2B if the gauge is >=50, B2B2B if >800.
A regular line clear -250
Spin Single/Double/Triple/Techrash/Techrash+ + 50/100/180/800/1000 (x50% if Mini)
Techrash/Techrash+ + 150/200/...
PC when lines cleared in this round >4, +800
Hemi-PC, +100
Spin (0 lines) +20. Do note that the B2B gauge cannot exceed 800 using this method.
When gauge is above 800, a drop without clearing lines decreases it by 40, but cannot drop below 800
The B2B gauge ranges from 0 to 1,000. Special line clears are B2B if the gauge is >=50, B2B2B if >800.
A regular line clear -250
Spin Single/Double/Triple/Techrash/Techrash+ + 50/100/180/800/1000 (x50% if Mini)
Techrash/Techrash+ + 150/200/...
PC when lines cleared in this round >4, +800
Hemi-PC, +100
Spin (0 lines) +20. Do note that the B2B gauge cannot exceed 800 using this method.
When gauge is above 800, a drop without clearing lines decreases it by 40, but cannot drop below 800
Battle Royale modes:
Many players play a game at the same time (against AI bots, not real players).
As players get eliminated, blocks fall faster, and garbage take effect faster, as well as rise faster.
Eliminate other players to gain a badge and the player's badge to increase your attack power.
Players can choose between four attack modes:
1. Random: Every time you attack, 10% chance to lock onto a random player.
2. Badges: After you attack or when your target dies, lock onto the player with the most badges.
3. KOs: After you attack or when your target dies, lock onto the player with the highest field. (Refreshes every second)
4. Attackers: attack all players locking onto yourself.
Your attack will be sent to all of them. If you are not targetted, you attack a random player (not locking).
When all opponents have been eliminated, the last player in the match is the winner.
Many players play a game at the same time (against AI bots, not real players).
As players get eliminated, blocks fall faster, and garbage take effect faster, as well as rise faster.
Eliminate other players to gain a badge and the player's badge to increase your attack power.
Players can choose between four attack modes:
1. Random: Every time you attack, 10% chance to lock onto a random player.
2. Badges: After you attack or when your target dies, lock onto the player with the most badges.
3. KOs: After you attack or when your target dies, lock onto the player with the highest field. (Refreshes every second)
4. Attackers: attack all players locking onto yourself.
Your attack will be sent to all of them. If you are not targetted, you attack a random player (not locking).
When all opponents have been eliminated, the last player in the match is the winner.
Custom mode:
You can freely adjust most parameters (not including special effects of other game modes).
You can also draw a field to clear or make a template to build.
In build (puzzle) mode, you can toggle template display with Function key:
Cells with a X cannot have blocks;
empty cells can be in any state;
regular colored cells have to be made of the corresponding block;
garbage-colored cells can be any block but not air.
Once you make the shape, you will win.
You can freely adjust most parameters (not including special effects of other game modes).
You can also draw a field to clear or make a template to build.
In build (puzzle) mode, you can toggle template display with Function key:
Cells with a X cannot have blocks;
empty cells can be in any state;
regular colored cells have to be made of the corresponding block;
garbage-colored cells can be any block but not air.
Once you make the shape, you will win.
]=],"\n")

View File

@@ -1,76 +1,76 @@
return STRING.split([=[
游戏方法:
系统会提供的一个个四连骨牌("方块",总共7种)
玩家需要控制(左右移动和旋转90,180,270度)这些骨牌直到下落到场地底部,锁定
每填满场地的一行就会将其消除(如果有对手的话根据消除方式会给对手攻击)
尝试存活更久,或者完成目标即胜利.
系统会提供的一个个四连骨牌("方块",总共7种)
玩家需要控制(左右移动和旋转90,180,270度)这些骨牌直到下落到场地底部,锁定
每填满场地的一行就会将其消除(如果有对手的话根据消除方式会给对手攻击)
尝试存活更久,或者完成目标即胜利.
旋转系统:
使用Techmino专属旋转系统,具体太复杂并且随时可能更改所以不写在这里,可以去parts/kicklist.lua看
使用Techmino专属旋转系统,具体太复杂并且随时可能更改所以不写在这里,可以去parts/kicklist.lua看
spin判定:
满足三角判定+2分
满足不可移动判定+2分
--满足以上之一就算是spin
满足非第二个test+1分
--如果分数只有2,方块是SZJLT之一,并且没有把当前方块整个消除那么就是mini
满足三角判定+2分
满足不可移动判定+2分
--满足以上之一就算是spin
满足非第二个test+1分
--如果分数只有2,方块是SZJLT之一,并且没有把当前方块整个消除那么就是mini
攻击系统:
普通消除:
消<4行打出[消行数-0.5]攻击
特殊消除:
如果是spin,打出[2*消行数]攻击,
B2B攻击+[1/1/2/4/8(spin1~5)]
B3B攻击在B2B基础上+消行数*0.5,+1额外抵挡
mini减至25%
不是spin但是单次消>=4行,打出[消行数]攻击,
B2B攻击+1
B3B攻击+50%,+1额外抵挡
特殊消除会增加B2B点数,让之后的特殊消除获得B2B(B3B)增益(详细说明见下文)
半全消("下方有剩余方块"的全消,如果是I消1行则必须不剩余玩家放置的方块):伤害+4,额外抵挡+2
全消:全消伤害为8~16(本局内递增2),和上述其他伤害取大,然后+2额外抵挡
连击:每次连击给予上述攻击[连击数*25%(上限12连)(如果只消一行就是15%)]的加成,>=3次时再额外加1攻击
根据上述规则计算后,向下取整,攻击打出
普通消除:
消<4行打出[消行数-0.5]攻击
特殊消除:
如果是spin,打出[2*消行数]攻击,
B2B攻击+[1/1/2/4/8(spin1~5)]
B3B攻击在B2B基础上+消行数*0.5,+1额外抵挡
mini减至25%
不是spin但是单次消>=4行,打出[消行数]攻击,
B2B攻击+1
B3B攻击+50%,+1额外抵挡
特殊消除会增加B2B点数,让之后的特殊消除获得B2B(B3B)增益(详细说明见下文)
半全消("下方有剩余方块"的全消,如果是I消1行则必须不剩余玩家放置的方块):伤害+4,额外抵挡+2
全消:全消伤害为8~16(本局内递增2),和上述其他伤害取大,然后+2额外抵挡
连击:每次连击给予上述攻击[连击数*25%(上限12连)(如果只消一行就是15%)]的加成,>=3次时再额外加1攻击
根据上述规则计算后,向下取整,攻击打出
分数系统:
分数计算系统非常复杂,而且随时可能更改所以不写在这里,并且计算只跟消除方式等信息有关,和模式设定无关
分数计算系统非常复杂,而且随时可能更改所以不写在这里,并且计算只跟消除方式等信息有关,和模式设定无关
攻击延迟:
消2/3的攻击生效最快,消四其次,spin攻击生效较慢,高连击生效最慢
B2B或者B3B增加攻击力的同时也会减缓一点生效速度,mini大幅减缓生效速度
消2/3的攻击生效最快,消四其次,spin攻击生效较慢,高连击生效最慢
B2B或者B3B增加攻击力的同时也会减缓一点生效速度,mini大幅减缓生效速度
抵消逻辑:
发动攻击时,若缓冲条有攻击则先用额外抵挡再用攻击力1:1抵消最先受到的攻击
没有用上的额外抵挡会被丢弃,最后剩下的攻击力会发送给对手
发动攻击时,若缓冲条有攻击则先用额外抵挡再用攻击力1:1抵消最先受到的攻击
没有用上的额外抵挡会被丢弃,最后剩下的攻击力会发送给对手
back to back(B2B)点数说明:
B2B点数的范围在0~1000,在点数>=50时进行特殊消除为B2B,>800时特殊消除为B3B
普通消除:-250
spin1~5:+[50/100/180/800/1000](mini变为原来50%)
消四/五/六:+[150/200/...]
本局内消行数>4时全消:+800
半全消:+100
空spin:+20,此法得到的点数不能超过800
当点数在800以上时空放一块-40(不低于800)
B2B点数的范围在0~1000,在点数>=50时进行特殊消除为B2B,>800时特殊消除为B3B
普通消除:-250
spin1~5:+[50/100/180/800/1000](mini变为原来50%)
消四/五/六:+[150/200/...]
本局内消行数>4时全消:+800
半全消:+100
空spin:+20,此法得到的点数不能超过800
当点数在800以上时空放一块-40(不低于800)
混战模式说明:
许多玩家同时进行一局游戏(对手都是AI,不是真人).
随着玩家数量的减少,方块下落/垃圾生效速度/垃圾升起速度都会增加.
淘汰其它玩家后可以获得一个徽章和该玩家持有的徽章,增强自己的攻击力.
玩家可选四个攻击模式:
1.随机:每次攻击后10%随机挑选一个玩家锁定
2.最多徽章:攻击后或者锁定玩家死亡时锁定徽章最多的玩家
3.最高:攻击后或者锁定玩家死亡时锁定场地最高的玩家(每秒刷新)
4.反击:攻击所有锁定自己的玩家(攻击AOE),若未被任何人锁定则攻击随机玩家(不锁定)
坚持到最后的玩家就是胜利者.
许多玩家同时进行一局游戏(对手都是AI,不是真人).
随着玩家数量的减少,方块下落/垃圾生效速度/垃圾升起速度都会增加.
淘汰其它玩家后可以获得一个徽章和该玩家持有的徽章,增强自己的攻击力.
玩家可选四个攻击模式:
1.随机:每次攻击后10%随机挑选一个玩家锁定
2.最多徽章:攻击后或者锁定玩家死亡时锁定徽章最多的玩家
3.最高:攻击后或者锁定玩家死亡时锁定场地最高的玩家(每秒刷新)
4.反击:攻击所有锁定自己的玩家(攻击AOE),若未被任何人锁定则攻击随机玩家(不锁定)
坚持到最后的玩家就是胜利者.
自定义模式说明:
玩家可以自由调整大多数参数(不包括上述各种游戏模式的特殊效果),
也可以画一个场地去消除或者是作为提示模板来进行拼图模式.
在拼图模式下可以按功能键切换是否展示提示,其中:
打"X"的格子不允许有方块;
空的格子可以是任何状态;
普通的七种彩色方块必须颜色对应;
垃圾行方块的位置只要有方块就可以,但是不能是空气.
玩家拼出画的图后就会判定胜利.
玩家可以自由调整大多数参数(不包括上述各种游戏模式的特殊效果),
也可以画一个场地去消除或者是作为提示模板来进行拼图模式.
在拼图模式下可以按功能键切换是否展示提示,其中:
打"X"的格子不允许有方块;
空的格子可以是任何状态;
普通的七种彩色方块必须颜色对应;
垃圾行方块的位置只要有方块就可以,但是不能是空气.
玩家拼出画的图后就会判定胜利.
]=],"\n")

View File

@@ -1,324 +1,324 @@
do--title
title={
{
53, 60,
1035, 0,
964, 218,
660, 218,
391, 1300,
231, 1154,
415, 218,
0, 218,
},
{
716, 290,
1429, 290,
1312, 462,
875, 489,
821, 695,
1148, 712,
1017, 902,
761, 924,
707, 1127,
1106, 1101,
1198, 1300,
465, 1300,
},
{
1516, 287,
2102, 290,
2036, 464,
1598, 465,
1322, 905,
1395, 1102,
1819, 1064,
1743, 1280,
1286, 1310,
1106, 902,
},
{
2179, 290,
2411, 290,
2272, 688,
2674, 666,
2801, 290,
3041, 290,
2693, 1280,
2464, 1280,
2601, 879,
2199, 897,
2056, 1280,
1828, 1280,
},
{
3123, 290,
3480, 290,
3496, 480,
3664, 290,
4017, 294,
3682, 1280,
3453, 1280,
3697, 578,
3458, 843,
3304, 842,
3251, 561,
3001, 1280,
2779, 1280,
},
{
4088, 290,
4677, 290,
4599, 501,
4426, 502,
4219, 1069,
4388, 1070,
4317, 1280,
3753, 1280,
3822, 1068,
3978, 1068,
4194, 504,
4016, 504,
},
{
4747, 290,
4978, 295,
4921, 464,
5186, 850,
5366, 290,
5599, 295,
5288, 1280,
5051, 1280,
5106, 1102,
4836, 709,
4641, 1280,
4406, 1280,
},
{
5814, 290,
6370, 295,
6471, 415,
6238, 1156,
6058, 1280,
5507, 1280,
5404, 1154,
5635, 416,
-- 5814, 290,
-- 5878, 463,
5770, 542,
5617, 1030,
5676, 1105,
5995, 1106,
6100, 1029,
6255, 541,
6199, 465,
5878, 463,
},
}
for _,C in next,title do
for i=1,#C do
C[i]=C[i]*.1626
end
end
title={
{
53, 60,
1035, 0,
964, 218,
660, 218,
391, 1300,
231, 1154,
415, 218,
0, 218,
},
{
716, 290,
1429, 290,
1312, 462,
875, 489,
821, 695,
1148, 712,
1017, 902,
761, 924,
707, 1127,
1106, 1101,
1198, 1300,
465, 1300,
},
{
1516, 287,
2102, 290,
2036, 464,
1598, 465,
1322, 905,
1395, 1102,
1819, 1064,
1743, 1280,
1286, 1310,
1106, 902,
},
{
2179, 290,
2411, 290,
2272, 688,
2674, 666,
2801, 290,
3041, 290,
2693, 1280,
2464, 1280,
2601, 879,
2199, 897,
2056, 1280,
1828, 1280,
},
{
3123, 290,
3480, 290,
3496, 480,
3664, 290,
4017, 294,
3682, 1280,
3453, 1280,
3697, 578,
3458, 843,
3304, 842,
3251, 561,
3001, 1280,
2779, 1280,
},
{
4088, 290,
4677, 290,
4599, 501,
4426, 502,
4219, 1069,
4388, 1070,
4317, 1280,
3753, 1280,
3822, 1068,
3978, 1068,
4194, 504,
4016, 504,
},
{
4747, 290,
4978, 295,
4921, 464,
5186, 850,
5366, 290,
5599, 295,
5288, 1280,
5051, 1280,
5106, 1102,
4836, 709,
4641, 1280,
4406, 1280,
},
{
5814, 290,
6370, 295,
6471, 415,
6238, 1156,
6058, 1280,
5507, 1280,
5404, 1154,
5635, 416,
-- 5814, 290,
-- 5878, 463,
5770, 542,
5617, 1030,
5676, 1105,
5995, 1106,
6100, 1029,
6255, 541,
6199, 465,
5878, 463,
},
}
for _,C in next,title do
for i=1,#C do
C[i]=C[i]*.1626
end
end
end
do--title_fan
title_fan={}
local sin,cos=math.sin,math.cos
for i=1,8 do
local L={}
title_fan[i]=L
for j=1,#title[i]do
L[j]=title[i][j]
end
for j=1,#L,2 do
local x,y=L[j],L[j+1]--0<x<3041, 290<y<1280
x,y=-(x+240+y*.3)*.002,(y-580)*.9
x,y=y*cos(x),-y*sin(x)--Rec-Pol-Rec
L[j],L[j+1]=x,y+300
end
end
title_fan={}
local sin,cos=math.sin,math.cos
for i=1,8 do
local L={}
title_fan[i]=L
for j=1,#title[i]do
L[j]=title[i][j]
end
for j=1,#L,2 do
local x,y=L[j],L[j+1]--0<x<3041, 290<y<1280
x,y=-(x+240+y*.3)*.002,(y-580)*.9
x,y=y*cos(x),-y*sin(x)--Rec-Pol-Rec
L[j],L[j+1]=x,y+300
end
end
end
do--missionEnum
missionEnum={
_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,
}
local L={}
for k,v in next,missionEnum do L[v]=k end
for k,v in next,L do missionEnum[k]=v end
missionEnum={
_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,
}
local L={}
for k,v in next,missionEnum do L[v]=k end
for k,v in next,L do missionEnum[k]=v end
end
do--drawableText
local function T(s,t)return love.graphics.newText(getFont(s),t)end
drawableText={
modeName=T(30),
local function T(s,t)return love.graphics.newText(getFont(s),t)end
drawableText={
modeName=T(30),
win=T(120),
lose=T(120),
win=T(120),
lose=T(120),
finish=T(90),
gamewin=T(90),
gameover=T(90),
pause=T(90),
finish=T(90),
gamewin=T(90),
gameover=T(90),
pause=T(90),
speedLV=T(20),
piece=T(25),line=T(25),atk=T(20),eff=T(20),
rpm=T(35),tsd=T(35),
grade=T(25),techrash=T(25),
wave=T(30),nextWave=T(30),
combo=T(20),maxcmb=T(20),
pc=T(20),ko=T(25),
speedLV=T(20),
piece=T(25),line=T(25),atk=T(20),eff=T(20),
rpm=T(35),tsd=T(35),
grade=T(25),techrash=T(25),
wave=T(30),nextWave=T(30),
combo=T(20),maxcmb=T(20),
pc=T(20),ko=T(25),
noScore=T(45),highScore=T(30),modeLocked=T(45),
}
noScore=T(45),highScore=T(30),modeLocked=T(45),
}
end
do--BLOCKS
local O,_=true,false
BLOCKS={
--Tetromino
{{_,O,O},{O,O,_}}, --Z
{{O,O,_},{_,O,O}}, --S
{{O,O,O},{O,_,_}}, --J
{{O,O,O},{_,_,O}}, --L
{{O,O,O},{_,O,_}}, --T
{{O,O},{O,O}}, --O
{{O,O,O,O}}, --I
local O,_=true,false
BLOCKS={
--Tetromino
{{_,O,O},{O,O,_}},--Z
{{O,O,_},{_,O,O}},--S
{{O,O,O},{O,_,_}},--J
{{O,O,O},{_,_,O}},--L
{{O,O,O},{_,O,_}},--T
{{O,O},{O,O}}, --O
{{O,O,O,O}}, --I
--Pentomino
{{_,O,O},{_,O,_},{O,O,_}}, --Z5
{{O,O,_},{_,O,_},{_,O,O}}, --S5
{{O,O,O},{O,O,_}}, --P
{{O,O,O},{_,O,O}}, --Q
{{_,O,_},{O,O,O},{O,_,_}}, --F
{{_,O,_},{O,O,O},{_,_,O}}, --E
{{O,O,O},{_,O,_},{_,O,_}}, --T5
{{O,O,O},{O,_,O}}, --U
{{O,O,O},{_,_,O},{_,_,O}}, --V
{{_,O,O},{O,O,_},{O,_,_}}, --W
{{_,O,_},{O,O,O},{_,O,_}}, --X
{{O,O,O,O},{O,_,_,_}}, --J5
{{O,O,O,O},{_,_,_,O}}, --L5
{{O,O,O,O},{_,O,_,_}}, --R
{{O,O,O,O},{_,_,O,_}}, --Y
{{_,O,O,O},{O,O,_,_}}, --N
{{O,O,O,_},{_,_,O,O}}, --H
{{O,O,O,O,O}}, --I5
--Pentomino
{{_,O,O},{_,O,_},{O,O,_}},--Z5
{{O,O,_},{_,O,_},{_,O,O}},--S5
{{O,O,O},{O,O,_}}, --P
{{O,O,O},{_,O,O}}, --Q
{{_,O,_},{O,O,O},{O,_,_}},--F
{{_,O,_},{O,O,O},{_,_,O}},--E
{{O,O,O},{_,O,_},{_,O,_}},--T5
{{O,O,O},{O,_,O}}, --U
{{O,O,O},{_,_,O},{_,_,O}},--V
{{_,O,O},{O,O,_},{O,_,_}},--W
{{_,O,_},{O,O,O},{_,O,_}},--X
{{O,O,O,O},{O,_,_,_}}, --J5
{{O,O,O,O},{_,_,_,O}}, --L5
{{O,O,O,O},{_,O,_,_}}, --R
{{O,O,O,O},{_,_,O,_}}, --Y
{{_,O,O,O},{O,O,_,_}}, --N
{{O,O,O,_},{_,_,O,O}}, --H
{{O,O,O,O,O}}, --I5
--Trimino
{{O,O,O}}, --I3
{{O,O},{_,O}}, --C
--Trimino
{{O,O,O}}, --I3
{{O,O},{_,O}},--C
--Domino
{{O,O}}, --I2
--Domino
{{O,O}},--I2
--Dot
{{O}}, --O1
}
local function _RotCW(B)
local N={}
local r,c=#B,#B[1]--row,col
for x=1,c do
N[x]={}
for y=1,r do
N[x][y]=B[y][c-x+1]
end
end
return N
end
for i=1,#BLOCKS do
local B=BLOCKS[i]
BLOCKS[i]={[0]=B}
for j=1,3 do
B=_RotCW(B)
BLOCKS[i][j]=B
end
end
--Dot
{{O}},--O1
}
local function _RotCW(B)
local N={}
local r,c=#B,#B[1]--row,col
for x=1,c do
N[x]={}
for y=1,r do
N[x][y]=B[y][c-x+1]
end
end
return N
end
for i=1,#BLOCKS do
local B=BLOCKS[i]
BLOCKS[i]={[0]=B}
for j=1,3 do
B=_RotCW(B)
BLOCKS[i][j]=B
end
end
end
oldModeNameTable={
attacker_hard="attacker_h",
attacker_ultimate="attacker_u",
blind_easy="blind_e",
blind_hard="blind_h",
blind_lunatic="blind_l",
blind_normal="blind_n",
blind_ultimate="blind_u",
c4wtrain_lunatic="c4wtrain_l",
c4wtrain_normal="c4wtrain_n",
defender_lunatic="defender_l",
defender_normal="defender_n",
dig_100="dig_100l",
dig_10="dig_10l",
dig_400="dig_400l",
dig_40="dig_40l",
dig_hard="dig_h",
dig_ultimate="dig_u",
drought_lunatic="drought_l",
drought_normal="drought_n",
marathon_hard="marathon_h",
marathon_normal="marathon_n",
pcchallenge_hard="pc_h",
pcchallenge_lunatic="pc_l",
pcchallenge_normal="pc_n",
pctrain_lunatic="pctrain_l",
pctrain_normal="pctrain_n",
round_1="round_e",
round_2="round_h",
round_3="round_l",
round_4="round_n",
round_5="round_u",
solo_1="solo_e",
solo_2="solo_h",
solo_3="solo_l",
solo_4="solo_n",
solo_5="solo_u",
sprint_10="sprint_10l",
sprint_20="sprint_20l",
sprint_40="sprint_40l",
sprint_400="sprint_400l",
sprint_100="sprint_100l",
sprint_1000="sprint_1000l",
survivor_easy="survivor_e",
survivor_hard="survivor_h",
survivor_lunatic="survivor_l",
survivor_normal="survivor_n",
survivor_ultimate="survivor_u",
tech_finesse2="tech_finesse_f",
tech_hard2="tech_h_plus",
tech_hard="tech_h",
tech_lunatic2="tech_l_plus",
tech_lunatic="tech_l",
tech_normal2="tech_n_plus",
tech_normal="tech_n",
techmino49_easy="techmino49_e",
techmino49_hard="techmino49_h",
techmino49_ultimate="techmino49_u",
techmino99_easy="techmino99_e",
techmino99_hard="techmino99_h",
techmino99_ultimate="techmino99_u",
tsd_easy="tsd_e",
tsd_hard="tsd_h",
tsd_ultimate="tsd_u",
GM="master_ex",
master_beginner="master_l",
master_advance="master_u",
master_phantasm="master_ph",
master_extra="master_ex",
attacker_hard="attacker_h",
attacker_ultimate="attacker_u",
blind_easy="blind_e",
blind_hard="blind_h",
blind_lunatic="blind_l",
blind_normal="blind_n",
blind_ultimate="blind_u",
c4wtrain_lunatic="c4wtrain_l",
c4wtrain_normal="c4wtrain_n",
defender_lunatic="defender_l",
defender_normal="defender_n",
dig_100="dig_100l",
dig_10="dig_10l",
dig_400="dig_400l",
dig_40="dig_40l",
dig_hard="dig_h",
dig_ultimate="dig_u",
drought_lunatic="drought_l",
drought_normal="drought_n",
marathon_hard="marathon_h",
marathon_normal="marathon_n",
pcchallenge_hard="pc_h",
pcchallenge_lunatic="pc_l",
pcchallenge_normal="pc_n",
pctrain_lunatic="pctrain_l",
pctrain_normal="pctrain_n",
round_1="round_e",
round_2="round_h",
round_3="round_l",
round_4="round_n",
round_5="round_u",
solo_1="solo_e",
solo_2="solo_h",
solo_3="solo_l",
solo_4="solo_n",
solo_5="solo_u",
sprint_10="sprint_10l",
sprint_20="sprint_20l",
sprint_40="sprint_40l",
sprint_400="sprint_400l",
sprint_100="sprint_100l",
sprint_1000="sprint_1000l",
survivor_easy="survivor_e",
survivor_hard="survivor_h",
survivor_lunatic="survivor_l",
survivor_normal="survivor_n",
survivor_ultimate="survivor_u",
tech_finesse2="tech_finesse_f",
tech_hard2="tech_h_plus",
tech_hard="tech_h",
tech_lunatic2="tech_l_plus",
tech_lunatic="tech_l",
tech_normal2="tech_n_plus",
tech_normal="tech_n",
techmino49_easy="techmino49_e",
techmino49_hard="techmino49_h",
techmino49_ultimate="techmino49_u",
techmino99_easy="techmino99_e",
techmino99_hard="techmino99_h",
techmino99_ultimate="techmino99_u",
tsd_easy="tsd_e",
tsd_hard="tsd_h",
tsd_ultimate="tsd_u",
GM="master_ex",
master_beginner="master_l",
master_advance="master_u",
master_phantasm="master_ph",
master_extra="master_ex",
}
rankColor={
{.6,.3,.3},
{.7,.5,.3},
{.9,.7,.5},
{.6,.9,1},
{.95,.95,.5},
{.6,.3,.3},
{.7,.5,.3},
{.9,.7,.5},
{.6,.9,1},
{.95,.95,.5},
}
minoColor={
COLOR.R,COLOR.F,COLOR.O,COLOR.Y,COLOR.L,COLOR.J,COLOR.G,COLOR.A,
COLOR.C,COLOR.N,COLOR.S,COLOR.B,COLOR.V,COLOR.P,COLOR.M,COLOR.W,
COLOR.dH,COLOR.D,COLOR.lY,COLOR.H,COLOR.lH,COLOR.dV,COLOR.dR,COLOR.dG,
COLOR.R,COLOR.F,COLOR.O,COLOR.Y,COLOR.L,COLOR.J,COLOR.G,COLOR.A,
COLOR.C,COLOR.N,COLOR.S,COLOR.B,COLOR.V,COLOR.P,COLOR.M,COLOR.W,
COLOR.dH,COLOR.D,COLOR.lY,COLOR.H,COLOR.lH,COLOR.dV,COLOR.dR,COLOR.dG,
}

View File

@@ -1,132 +1,132 @@
return{
{name='sprint_10l', x=0, y=0, size=40,shape=1,icon="sprint1", unlock={'sprint_20l','sprint_40l'}},
{name='sprint_20l', x=-200, y=200, size=50,shape=1,icon="sprint1"},
{name='sprint_40l', x=0, y=-300, size=40,shape=1,icon="sprint2", unlock={'dig_10l','sprint_100l','marathon_n','sprintPenta','sprintMPH','stack_e'}},
{name='sprint_100l', x=-200, y=0, size=50,shape=1,icon="sprint2", unlock={'sprint_400l','drought_n'}},
{name='sprint_400l', x=-400, y=0, size=40,shape=1,icon="sprint3", unlock={'sprint_1000l'}},
{name='sprint_1000l', x=-600, y=0, size=40,shape=1,icon="sprint3"},
{name='sprint_10l', x=0, y=0, size=40,shape=1,icon="sprint1", unlock={'sprint_20l','sprint_40l'}},
{name='sprint_20l', x=-200, y=200, size=50,shape=1,icon="sprint1"},
{name='sprint_40l', x=0, y=-300, size=40,shape=1,icon="sprint2", unlock={'dig_10l','sprint_100l','marathon_n','sprintPenta','sprintMPH','stack_e'}},
{name='sprint_100l', x=-200, y=0, size=50,shape=1,icon="sprint2", unlock={'sprint_400l','drought_n'}},
{name='sprint_400l', x=-400, y=0, size=40,shape=1,icon="sprint3", unlock={'sprint_1000l'}},
{name='sprint_1000l', x=-600, y=0, size=40,shape=1,icon="sprint3"},
{name='sprintPenta', x=210, y=-370, size=40,shape=3,icon="tech"},
{name='sprintMPH', x=210, y=-230, size=40,shape=3,icon="tech"},
{name='sprintPenta', x=210, y=-370, size=40,shape=3,icon="tech"},
{name='sprintMPH', x=210, y=-230, size=40,shape=3,icon="tech"},
{name='drought_n', x=-400, y=200, size=40,shape=1,icon="drought", unlock={'drought_l'}},
{name='drought_l', x=-600, y=200, size=40,shape=1,icon="drought"},
{name='drought_n', x=-400, y=200, size=40,shape=1,icon="drought", unlock={'drought_l'}},
{name='drought_l', x=-600, y=200, size=40,shape=1,icon="drought"},
{name='stack_e', x=-200, y=-400, size=40,shape=1,icon="mess", unlock={'stack_h'}},
{name='stack_h', x=-400, y=-400, size=40,shape=1,icon="mess", unlock={'stack_u'}},
{name='stack_u', x=-600, y=-400, size=40,shape=1,icon="mess"},
{name='stack_e', x=-200, y=-400, size=40,shape=1,icon="mess", unlock={'stack_h'}},
{name='stack_h', x=-400, y=-400, size=40,shape=1,icon="mess", unlock={'stack_u'}},
{name='stack_u', x=-600, y=-400, size=40,shape=1,icon="mess"},
{name='dig_10l', x=-200, y=-200, size=40,shape=1,icon="dig_sprint",unlock={'dig_40l'}},
{name='dig_40l', x=-400, y=-200, size=40,shape=1,icon="dig_sprint",unlock={'dig_100l'}},
{name='dig_100l', x=-600, y=-200, size=40,shape=1,icon="dig_sprint",unlock={'dig_400l'}},
{name='dig_400l', x=-800, y=-200, size=40,shape=1,icon="dig_sprint"},
{name='dig_10l', x=-200, y=-200, size=40,shape=1,icon="dig_sprint", unlock={'dig_40l'}},
{name='dig_40l', x=-400, y=-200, size=40,shape=1,icon="dig_sprint", unlock={'dig_100l'}},
{name='dig_100l', x=-600, y=-200, size=40,shape=1,icon="dig_sprint", unlock={'dig_400l'}},
{name='dig_400l', x=-800, y=-200, size=40,shape=1,icon="dig_sprint"},
{name='marathon_n', x=0, y=-600, size=60,shape=1,icon="marathon",unlock={'marathon_h','rhythm_e','solo_e','round_e','blind_e','classic_fast','survivor_e','bigbang','zen'}},
{name='marathon_h', x=0, y=-800, size=50,shape=1,icon="marathon",unlock={'master_n'}},
{name='marathon_n', x=0, y=-600, size=60,shape=1,icon="marathon", unlock={'marathon_h','rhythm_e','solo_e','round_e','blind_e','classic_fast','survivor_e','bigbang','zen'}},
{name='marathon_h', x=0, y=-800, size=50,shape=1,icon="marathon", unlock={'master_n'}},
{name='solo_e', x=-600, y=-1000,size=40,shape=1,icon="solo", unlock={'solo_n'}},
{name='solo_n', x=-800, y=-1000,size=40,shape=1,icon="solo", unlock={'solo_h'}},
{name='solo_h', x=-1000,y=-1000,size=40,shape=1,icon="solo", unlock={'solo_l','techmino49_e'}},
{name='solo_l', x=-1200,y=-1000,size=40,shape=1,icon="solo", unlock={'solo_u'}},
{name='solo_u', x=-1400,y=-1000,size=40,shape=1,icon="solo"},
{name='solo_e', x=-600, y=-1000, size=40,shape=1,icon="solo", unlock={'solo_n'}},
{name='solo_n', x=-800, y=-1000, size=40,shape=1,icon="solo", unlock={'solo_h'}},
{name='solo_h', x=-1000, y=-1000, size=40,shape=1,icon="solo", unlock={'solo_l','techmino49_e'}},
{name='solo_l', x=-1200, y=-1000, size=40,shape=1,icon="solo", unlock={'solo_u'}},
{name='solo_u', x=-1400, y=-1000, size=40,shape=1,icon="solo"},
{name='techmino49_e', x=-1100,y=-1200,size=40,shape=1,icon="t49", unlock={'techmino49_h','techmino99_e'}},
{name='techmino49_h', x=-1100,y=-1400,size=40,shape=1,icon="t49", unlock={'techmino49_u'}},
{name='techmino49_u', x=-1100,y=-1600,size=40,shape=1,icon="t49"},
{name='techmino99_e', x=-1300,y=-1400,size=40,shape=1,icon="t99", unlock={'techmino99_h'}},
{name='techmino99_h', x=-1300,y=-1600,size=40,shape=1,icon="t99", unlock={'techmino99_u'}},
{name='techmino99_u', x=-1300,y=-1800,size=40,shape=1,icon="t99"},
{name='techmino49_e', x=-1100, y=-1200, size=40,shape=1,icon="t49", unlock={'techmino49_h','techmino99_e'}},
{name='techmino49_h', x=-1100, y=-1400, size=40,shape=1,icon="t49", unlock={'techmino49_u'}},
{name='techmino49_u', x=-1100, y=-1600, size=40,shape=1,icon="t49"},
{name='techmino99_e', x=-1300, y=-1400, size=40,shape=1,icon="t99", unlock={'techmino99_h'}},
{name='techmino99_h', x=-1300, y=-1600, size=40,shape=1,icon="t99", unlock={'techmino99_u'}},
{name='techmino99_u', x=-1300, y=-1800, size=40,shape=1,icon="t99"},
{name='round_e', x=-600, y=-800, size=40,shape=1,icon="round", unlock={'round_n'}},
{name='round_n', x=-800, y=-800, size=40,shape=1,icon="round", unlock={'round_h'}},
{name='round_h', x=-1000,y=-800, size=40,shape=1,icon="round", unlock={'round_l'}},
{name='round_l', x=-1200,y=-800, size=40,shape=1,icon="round", unlock={'round_u'}},
{name='round_u', x=-1400,y=-800, size=40,shape=1,icon="round"},
{name='round_e', x=-600, y=-800, size=40,shape=1,icon="round", unlock={'round_n'}},
{name='round_n', x=-800, y=-800, size=40,shape=1,icon="round", unlock={'round_h'}},
{name='round_h', x=-1000, y=-800, size=40,shape=1,icon="round", unlock={'round_l'}},
{name='round_l', x=-1200, y=-800, size=40,shape=1,icon="round", unlock={'round_u'}},
{name='round_u', x=-1400, y=-800, size=40,shape=1,icon="round"},
{name='master_n', x=0, y=-1000,size=40,shape=1,icon="master", unlock={'master_h'}},
{name='master_h', x=0, y=-1200,size=40,shape=3,icon="master", unlock={'master_final','master_ex','master_ph'}},
{name='master_final', x=0, y=-1600,size=40,shape=2,icon="master"},
{name='master_ph', x=-150, y=-1500,size=40,shape=2,icon="master"},
{name='master_ex', x=150, y=-1500,size=40,shape=2,icon="master_ex"},
{name='master_n', x=0, y=-1000, size=40,shape=1,icon="master", unlock={'master_h'}},
{name='master_h', x=0, y=-1200, size=40,shape=3,icon="master", unlock={'master_final','master_ex','master_ph'}},
{name='master_final', x=0, y=-1600, size=40,shape=2,icon="master"},
{name='master_ph', x=-150, y=-1500, size=40,shape=2,icon="master"},
{name='master_ex', x=150, y=-1500, size=40,shape=2,icon="master_ex"},
{name='rhythm_e', x=-350, y=-1000,size=40,shape=1,icon="rhythm", unlock={'rhythm_h'}},
{name='rhythm_h', x=-350, y=-1200,size=40,shape=3,icon="rhythm", unlock={'rhythm_u'}},
{name='rhythm_u', x=-350, y=-1400,size=40,shape=2,icon="rhythm"},
{name='rhythm_e', x=-350, y=-1000, size=40,shape=1,icon="rhythm", unlock={'rhythm_h'}},
{name='rhythm_h', x=-350, y=-1200, size=40,shape=3,icon="rhythm", unlock={'rhythm_u'}},
{name='rhythm_u', x=-350, y=-1400, size=40,shape=2,icon="rhythm"},
{name='blind_e', x=150, y=-700, size=40,shape=1,icon="hidden", unlock={'blind_n'}},
{name='blind_n', x=150, y=-800, size=40,shape=1,icon="hidden", unlock={'blind_h'}},
{name='blind_h', x=150, y=-900, size=35,shape=1,icon="hidden", unlock={'blind_l'}},
{name='blind_l', x=150, y=-1000,size=35,shape=3,icon="hidden", unlock={'blind_u'}},
{name='blind_u', x=150, y=-1100,size=30,shape=3,icon="hidden", unlock={'blind_wtf'}},
{name='blind_wtf', x=150, y=-1200,size=25,shape=2,icon="hidden"},
{name='blind_e', x=150, y=-700, size=40,shape=1,icon="hidden", unlock={'blind_n'}},
{name='blind_n', x=150, y=-800, size=40,shape=1,icon="hidden", unlock={'blind_h'}},
{name='blind_h', x=150, y=-900, size=35,shape=1,icon="hidden", unlock={'blind_l'}},
{name='blind_l', x=150, y=-1000, size=35,shape=3,icon="hidden", unlock={'blind_u'}},
{name='blind_u', x=150, y=-1100, size=30,shape=3,icon="hidden", unlock={'blind_wtf'}},
{name='blind_wtf', x=150, y=-1200, size=25,shape=2,icon="hidden"},
{name='classic_fast', x=-150, y=-950, size=40,shape=2,icon="classic"},
{name='classic_fast', x=-150, y=-950, size=40,shape=2,icon="classic"},
{name='survivor_e', x=300, y=-600, size=40,shape=1,icon="survivor",unlock={'survivor_n'}},
{name='survivor_n', x=500, y=-600, size=40,shape=1,icon="survivor",unlock={'survivor_h','attacker_h','defender_n','dig_h'}},
{name='survivor_h', x=700, y=-600, size=40,shape=1,icon="survivor",unlock={'survivor_l'}},
{name='survivor_l', x=900, y=-600, size=40,shape=3,icon="survivor",unlock={'survivor_u'}},
{name='survivor_u', x=1100, y=-600, size=40,shape=2,icon="survivor"},
{name='survivor_e', x=300, y=-600, size=40,shape=1,icon="survivor", unlock={'survivor_n'}},
{name='survivor_n', x=500, y=-600, size=40,shape=1,icon="survivor", unlock={'survivor_h','attacker_h','defender_n','dig_h'}},
{name='survivor_h', x=700, y=-600, size=40,shape=1,icon="survivor", unlock={'survivor_l'}},
{name='survivor_l', x=900, y=-600, size=40,shape=3,icon="survivor", unlock={'survivor_u'}},
{name='survivor_u', x=1100, y=-600, size=40,shape=2,icon="survivor"},
{name='attacker_h', x=300, y=-800, size=40,shape=1,icon="attack", unlock={'attacker_u'}},
{name='attacker_u', x=300, y=-1000,size=40,shape=1,icon="attack"},
{name='attacker_h', x=300, y=-800, size=40,shape=1,icon="attack", unlock={'attacker_u'}},
{name='attacker_u', x=300, y=-1000, size=40,shape=1,icon="attack"},
{name='defender_n', x=500, y=-800, size=40,shape=1,icon="defend", unlock={'defender_l'}},
{name='defender_l', x=500, y=-1000,size=40,shape=1,icon="defend"},
{name='defender_n', x=500, y=-800, size=40,shape=1,icon="defend", unlock={'defender_l'}},
{name='defender_l', x=500, y=-1000, size=40,shape=1,icon="defend"},
{name='dig_h', x=700, y=-800, size=40,shape=1,icon="dig", unlock={'dig_u'}},
{name='dig_u', x=700, y=-1000,size=40,shape=1,icon="dig"},
{name='dig_h', x=700, y=-800, size=40,shape=1,icon="dig", unlock={'dig_u'}},
{name='dig_u', x=700, y=-1000, size=40,shape=1,icon="dig"},
{name='bigbang', x=400, y=-400, size=50,shape=1,icon="bigbang", unlock={'c4wtrain_n','pctrain_n','tech_n'}},
{name='c4wtrain_n', x=700, y=-400, size=40,shape=1,icon="pc", unlock={'c4wtrain_l'}},
{name='c4wtrain_l', x=900, y=-400, size=40,shape=1,icon="pc"},
{name='bigbang', x=400, y=-400, size=50,shape=1,icon="bigbang", unlock={'c4wtrain_n','pctrain_n','tech_n'}},
{name='c4wtrain_n', x=700, y=-400, size=40,shape=1,icon="pc", unlock={'c4wtrain_l'}},
{name='c4wtrain_l', x=900, y=-400, size=40,shape=1,icon="pc"},
{name='pctrain_n', x=700, y=-250, size=40,shape=1,icon="pc", unlock={'pctrain_l','pc_n'}},
{name='pctrain_l', x=900, y=-250, size=40,shape=1,icon="pc"},
{name='pctrain_n', x=700, y=-250, size=40,shape=1,icon="pc", unlock={'pctrain_l','pc_n'}},
{name='pctrain_l', x=900, y=-250, size=40,shape=1,icon="pc"},
{name='pc_n', x=800, y=-110, size=40,shape=1,icon="pc", unlock={'pc_h'}},
{name='pc_h', x=950, y=-110, size=40,shape=3,icon="pc", unlock={'pc_l','pc_inf'}},
{name='pc_l', x=1100, y=-110, size=40,shape=3,icon="pc"},
{name='pc_inf', x=1100, y=-250, size=40,shape=2,icon="pc"},
{name='pc_n', x=800, y=-110, size=40,shape=1,icon="pc", unlock={'pc_h'}},
{name='pc_h', x=950, y=-110, size=40,shape=3,icon="pc", unlock={'pc_l','pc_inf'}},
{name='pc_l', x=1100, y=-110, size=40,shape=3,icon="pc"},
{name='pc_inf', x=1100, y=-250, size=40,shape=2,icon="pc"},
{name='tech_n', x=400, y=-110, size=40,shape=1,icon="tech", unlock={'tech_n_plus','tech_h','tech_finesse','sprintAtk'}},
{name='tech_n_plus', x=600, y=160, size=40,shape=3,icon="tech", unlock={'tsd_e','backfire_n'}},
{name='tech_h', x=220, y=120, size=40,shape=1,icon="tech", unlock={'tech_h_plus','tech_l'}},
{name='tech_h_plus', x=20, y=150, size=35,shape=3,icon="tech"},
{name='tech_l', x=220, y=280, size=40,shape=1,icon="tech", unlock={'tech_l_plus'}},
{name='tech_l_plus', x=20, y=310, size=35,shape=3,icon="tech"},
{name='tech_n', x=400, y=-110, size=40,shape=1,icon="tech", unlock={'tech_n_plus','tech_h','tech_finesse','sprintAtk'}},
{name='tech_n_plus', x=600, y=160, size=40,shape=3,icon="tech", unlock={'tsd_e','backfire_n'}},
{name='tech_h', x=220, y=120, size=40,shape=1,icon="tech", unlock={'tech_h_plus','tech_l'}},
{name='tech_h_plus', x=20, y=150, size=35,shape=3,icon="tech"},
{name='tech_l', x=220, y=280, size=40,shape=1,icon="tech", unlock={'tech_l_plus'}},
{name='tech_l_plus', x=20, y=310, size=35,shape=3,icon="tech"},
{name='tech_finesse', x=800, y=50, size=40,shape=1,icon="tech", unlock={'tech_finesse_f'}},
{name='tech_finesse_f', x=1000, y=50, size=40,shape=1,icon="tech"},
{name='tech_finesse', x=800, y=50, size=40,shape=1,icon="tech", unlock={'tech_finesse_f'}},
{name='tech_finesse_f',x=1000, y=50, size=40,shape=1,icon="tech"},
{name='tsd_e', x=800, y=200, size=40,shape=1,icon="tsd", unlock={'tsd_h'}},
{name='tsd_h', x=1000, y=200, size=40,shape=1,icon="tsd", unlock={'tsd_u'}},
{name='tsd_u', x=1200, y=200, size=40,shape=1,icon="tsd"},
{name='tsd_e', x=800, y=200, size=40,shape=1,icon="tsd", unlock={'tsd_h'}},
{name='tsd_h', x=1000, y=200, size=40,shape=1,icon="tsd", unlock={'tsd_u'}},
{name='tsd_u', x=1200, y=200, size=40,shape=1,icon="tsd"},
{name='backfire_n', x=800, y=350, size=40,shape=1,icon="backfire",unlock={'backfire_h'}},
{name='backfire_h', x=950, y=350, size=40,shape=1,icon="backfire",unlock={'backfire_l'}},
{name='backfire_l', x=1100, y=350, size=40,shape=3,icon="backfire",unlock={'backfire_u'}},
{name='backfire_u', x=1250, y=350, size=35,shape=2,icon="backfire"},
{name='backfire_n', x=800, y=350, size=40,shape=1,icon="backfire", unlock={'backfire_h'}},
{name='backfire_h', x=950, y=350, size=40,shape=1,icon="backfire", unlock={'backfire_l'}},
{name='backfire_l', x=1100, y=350, size=40,shape=3,icon="backfire", unlock={'backfire_u'}},
{name='backfire_u', x=1250, y=350, size=35,shape=2,icon="backfire"},
{name='sprintAtk', x=400, y=200, size=40,shape=1,icon="sprint2"},
{name='sprintAtk', x=400, y=200, size=40,shape=1,icon="sprint2"},
{name='zen', x=-800, y=-600, size=40,shape=1,icon="zen", unlock={'ultra','infinite','infinite_dig'}},
{name='ultra', x=-1000,y=-600, size=40,shape=1,icon="ultra"},
{name='infinite', x=-1000,y=-400, size=40,shape=1,icon='infinite'},
{name='infinite_dig', x=-800, y=-400, size=40,shape=1,icon="dig"},
{name='zen', x=-800, y=-600, size=40,shape=1,icon="zen", unlock={'ultra','infinite','infinite_dig'}},
{name='ultra', x=-1000, y=-600, size=40,shape=1,icon="ultra"},
{name='infinite', x=-1000, y=-400, size=40,shape=1,icon='infinite'},
{name='infinite_dig', x=-800, y=-400, size=40,shape=1,icon="dig"},
--Secret
{name='sprintFix'},
{name='sprintLock'},
{name='sprintSmooth'},
{name='marathon_bfmax'},
--Secret
{name='sprintFix'},
{name='sprintLock'},
{name='sprintSmooth'},
{name='marathon_bfmax'},
--Old
{name='master_l'},
{name='master_u'},
--Old
{name='master_l'},
{name='master_u'},
--Special
{name='custom_puzzle'},
{name='custom_clear'},
{name="netBattle"},
--Special
{name='custom_puzzle'},
{name='custom_clear'},
{name="netBattle"},
}

View File

@@ -1,108 +1,108 @@
return{
{
{
{4,4,4,3,3,3,7,0,0,0},
{4,1,6,6,2,3,7,0,0,0},
{1,1,6,6,2,2,7,0,0,0},
{1,7,7,7,7,2,7,0,0,0},
},
{
{4,4,4,3,3,3,0,0,0,7},
{4,1,6,6,2,3,0,0,0,7},
{1,1,6,6,2,2,0,0,0,7},
{1,7,7,7,7,2,0,0,0,7},
},
{
{2,7,7,7,7,1,7,0,0,0},
{2,2,6,6,1,1,7,0,0,0},
{3,2,6,6,1,4,7,0,0,0},
{3,3,3,4,4,4,7,0,0,0},
},
{
{2,7,7,7,7,1,0,0,0,7},
{2,2,6,6,1,1,0,0,0,7},
{3,2,6,6,1,4,0,0,0,7},
{3,3,3,4,4,4,0,0,0,7},
},
},--3*4 shape
{
{
{1,1,0,0,0,0,0,3,3,3},
{5,1,1,0,0,0,0,6,6,3},
{5,5,2,2,0,0,0,6,6,4},
{5,2,2,0,0,0,0,4,4,4},
},
{
{1,1,0,0,0,0,0,4,4,4},
{5,1,1,0,0,0,0,4,6,6},
{5,5,2,2,0,0,0,3,6,6},
{5,2,2,0,0,0,0,3,3,3},
},
{
{3,3,3,1,1,0,0,0,0,0},
{6,6,3,5,1,1,0,0,0,0},
{6,6,4,5,5,2,2,0,0,0},
{4,4,4,5,2,2,0,0,0,0},
},
{
{4,4,4,1,1,0,0,0,0,0},
{4,6,6,5,1,1,0,0,0,0},
{3,6,6,5,5,2,2,0,0,0},
{3,3,3,5,2,2,0,0,0,0},
},
},--7 piece opener(right>)(without i)
{
{
{4,4,4,3,3,3,0,0,0,0},
{4,1,6,6,2,3,0,0,0,0},
{1,1,6,6,2,2,0,0,0,0},
{1,7,7,7,7,2,0,0,0,0},
},
{
{2,7,7,7,7,1,0,0,0,0},
{2,2,6,6,1,1,0,0,0,0},
{3,2,6,6,1,4,0,0,0,0},
{3,3,3,4,4,4,0,0,0,0},
},
},--6 piece opener
{
{
{0,0,0,0,0,1,3,5,6,7},
{0,0,0,0,0,1,3,5,6,7},
{0,0,0,0,0,1,3,5,6,7},
{0,0,0,0,0,1,3,5,6,7},
},
{
{1,0,0,0,0,0,3,5,6,7},
{1,0,0,0,0,0,3,5,6,7},
{1,0,0,0,0,0,3,5,6,7},
{1,0,0,0,0,0,3,5,6,7},
},
{
{1,3,0,0,0,0,0,5,6,7},
{1,3,0,0,0,0,0,5,6,7},
{1,3,0,0,0,0,0,5,6,7},
{1,3,0,0,0,0,0,5,6,7},
},
},--4*5
{
{
{0,0,0,0,0,0,1,3,5,7},
{0,0,0,0,0,0,7,1,3,5},
{0,0,0,0,0,0,5,7,1,3},
{0,0,0,0,0,0,3,5,7,1},
},
{
{7,0,0,0,0,0,0,5,3,1},
{7,0,0,0,0,0,0,5,3,1},
{7,0,0,0,0,0,0,5,3,1},
{7,0,0,0,0,0,0,5,3,1},
},
{
{1,3,0,0,0,0,0,0,6,5},
{5,6,0,0,0,0,0,0,3,1},
{5,7,0,0,0,0,0,0,3,1},
{1,3,0,0,0,0,0,0,7,5},
},
},--4*6
{
{
{4,4,4,3,3,3,7,0,0,0},
{4,1,6,6,2,3,7,0,0,0},
{1,1,6,6,2,2,7,0,0,0},
{1,7,7,7,7,2,7,0,0,0},
},
{
{4,4,4,3,3,3,0,0,0,7},
{4,1,6,6,2,3,0,0,0,7},
{1,1,6,6,2,2,0,0,0,7},
{1,7,7,7,7,2,0,0,0,7},
},
{
{2,7,7,7,7,1,7,0,0,0},
{2,2,6,6,1,1,7,0,0,0},
{3,2,6,6,1,4,7,0,0,0},
{3,3,3,4,4,4,7,0,0,0},
},
{
{2,7,7,7,7,1,0,0,0,7},
{2,2,6,6,1,1,0,0,0,7},
{3,2,6,6,1,4,0,0,0,7},
{3,3,3,4,4,4,0,0,0,7},
},
},--3*4 shape
{
{
{1,1,0,0,0,0,0,3,3,3},
{5,1,1,0,0,0,0,6,6,3},
{5,5,2,2,0,0,0,6,6,4},
{5,2,2,0,0,0,0,4,4,4},
},
{
{1,1,0,0,0,0,0,4,4,4},
{5,1,1,0,0,0,0,4,6,6},
{5,5,2,2,0,0,0,3,6,6},
{5,2,2,0,0,0,0,3,3,3},
},
{
{3,3,3,1,1,0,0,0,0,0},
{6,6,3,5,1,1,0,0,0,0},
{6,6,4,5,5,2,2,0,0,0},
{4,4,4,5,2,2,0,0,0,0},
},
{
{4,4,4,1,1,0,0,0,0,0},
{4,6,6,5,1,1,0,0,0,0},
{3,6,6,5,5,2,2,0,0,0},
{3,3,3,5,2,2,0,0,0,0},
},
},--7 piece opener(right>)(without i)
{
{
{4,4,4,3,3,3,0,0,0,0},
{4,1,6,6,2,3,0,0,0,0},
{1,1,6,6,2,2,0,0,0,0},
{1,7,7,7,7,2,0,0,0,0},
},
{
{2,7,7,7,7,1,0,0,0,0},
{2,2,6,6,1,1,0,0,0,0},
{3,2,6,6,1,4,0,0,0,0},
{3,3,3,4,4,4,0,0,0,0},
},
},--6 piece opener
{
{
{0,0,0,0,0,1,3,5,6,7},
{0,0,0,0,0,1,3,5,6,7},
{0,0,0,0,0,1,3,5,6,7},
{0,0,0,0,0,1,3,5,6,7},
},
{
{1,0,0,0,0,0,3,5,6,7},
{1,0,0,0,0,0,3,5,6,7},
{1,0,0,0,0,0,3,5,6,7},
{1,0,0,0,0,0,3,5,6,7},
},
{
{1,3,0,0,0,0,0,5,6,7},
{1,3,0,0,0,0,0,5,6,7},
{1,3,0,0,0,0,0,5,6,7},
{1,3,0,0,0,0,0,5,6,7},
},
},--4*5
{
{
{0,0,0,0,0,0,1,3,5,7},
{0,0,0,0,0,0,7,1,3,5},
{0,0,0,0,0,0,5,7,1,3},
{0,0,0,0,0,0,3,5,7,1},
},
{
{7,0,0,0,0,0,0,5,3,1},
{7,0,0,0,0,0,0,5,3,1},
{7,0,0,0,0,0,0,5,3,1},
{7,0,0,0,0,0,0,5,3,1},
},
{
{1,3,0,0,0,0,0,0,6,5},
{5,6,0,0,0,0,0,0,3,1},
{5,7,0,0,0,0,0,0,3,1},
{1,3,0,0,0,0,0,0,7,5},
},
},--4*6
}

File diff suppressed because one or more lines are too long

View File

@@ -1,58 +1,58 @@
return{
color=COLOR.magenta,
env={
drop=30,lock=60,
fall=12,
freshLimit=15,
pushSpeed=2,
task=function(P)
while true do
YIELD()
if P.control and P.atkBufferSum==0 then
local D=P.modeData
if D.wave<20 then
local t=1500-30*D.wave--1500~900
table.insert(P.atkBuffer,{line=generateLine(P.holeRND:random(4,7)),amount=12,countdown=t,cd0=t,time=0,sent=false,lv=3})
table.insert(P.atkBuffer,{line=generateLine(P.holeRND:random(3,8)),amount=10,countdown=t,cd0=t,time=0,sent=false,lv=4})
else
local t=900-10*(D.wave-20)--900~600
table.insert(P.atkBuffer,{line=generateLine(P.holeRND:random(10)),amount=14,countdown=t,cd0=t,time=0,sent=false,lv=4})
table.insert(P.atkBuffer,{line=generateLine(P.holeRND:random(4,7)),amount=8,countdown=t,cd0=t,time=0,sent=false,lv=5})
end
P.atkBufferSum=P.atkBufferSum+22
P.stat.recv=P.stat.recv+22
D.wave=D.wave+1
if D.wave%10==0 then
if D.wave==20 then
P:showTextF(text.great,0,-140,100,'appear',.6)
P.gameEnv.pushSpeed=3
elseif D.wave==50 then
P:showTextF(text.maxspeed,0,-140,100,'appear',.6)
end
end
end
end
end,
bg='rainbow2',bgm='shining terminal',
},
mesDisp=function(P)
setFont(55)
mStr(P.modeData.wave,63,200)
mStr("22",63,320)
mText(drawableText.wave,63,260)
mText(drawableText.nextWave,63,380)
end,
score=function(P)return{P.modeData.wave,P.stat.time}end,
scoreDisp=function(D)return D[1].." Waves "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local W=P.modeData.wave
return
W>=50 and 5 or
W>=40 and 4 or
W>=30 and 3 or
W>=20 and 2 or
W>=10 and 1 or
W>=5 and 0
end,
color=COLOR.magenta,
env={
drop=30,lock=60,
fall=12,
freshLimit=15,
pushSpeed=2,
task=function(P)
while true do
YIELD()
if P.control and P.atkBufferSum==0 then
local D=P.modeData
if D.wave<20 then
local t=1500-30*D.wave--1500~900
table.insert(P.atkBuffer,{line=generateLine(P.holeRND:random(4,7)),amount=12,countdown=t,cd0=t,time=0,sent=false,lv=3})
table.insert(P.atkBuffer,{line=generateLine(P.holeRND:random(3,8)),amount=10,countdown=t,cd0=t,time=0,sent=false,lv=4})
else
local t=900-10*(D.wave-20)--900~600
table.insert(P.atkBuffer,{line=generateLine(P.holeRND:random(10)),amount=14,countdown=t,cd0=t,time=0,sent=false,lv=4})
table.insert(P.atkBuffer,{line=generateLine(P.holeRND:random(4,7)),amount=8,countdown=t,cd0=t,time=0,sent=false,lv=5})
end
P.atkBufferSum=P.atkBufferSum+22
P.stat.recv=P.stat.recv+22
D.wave=D.wave+1
if D.wave%10==0 then
if D.wave==20 then
P:showTextF(text.great,0,-140,100,'appear',.6)
P.gameEnv.pushSpeed=3
elseif D.wave==50 then
P:showTextF(text.maxspeed,0,-140,100,'appear',.6)
end
end
end
end
end,
bg='rainbow2',bgm='shining terminal',
},
mesDisp=function(P)
setFont(55)
mStr(P.modeData.wave,63,200)
mStr("22",63,320)
mText(drawableText.wave,63,260)
mText(drawableText.nextWave,63,380)
end,
score=function(P)return{P.modeData.wave,P.stat.time}end,
scoreDisp=function(D)return D[1].." Waves "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local W=P.modeData.wave
return
W>=50 and 5 or
W>=40 and 4 or
W>=30 and 3 or
W>=20 and 2 or
W>=10 and 1 or
W>=5 and 0
end,
}

View File

@@ -1,66 +1,66 @@
return{
color=COLOR.lYellow,
env={
drop=5,lock=60,
fall=8,
freshLimit=15,
task=function(P)
while true do
YIELD()
if P.control and P.atkBufferSum<4 then
local D=P.modeData
local s
local t=800-10*D.wave--800~700~600~500
if D.wave<10 then
table.insert(P.atkBuffer,{line=generateLine(P.holeRND:random(5,6)),amount=9,countdown=t,cd0=t,time=0,sent=false,lv=3})
table.insert(P.atkBuffer,{line=generateLine(P.holeRND:random(4,7)),amount=11,countdown=t,cd0=t+62,time=0,sent=false,lv=4})
s=20
elseif D.wave<20 then
table.insert(P.atkBuffer,{line=generateLine(P.holeRND:random(3,8)),amount=11,countdown=t,cd0=t,time=0,sent=false,lv=4})
table.insert(P.atkBuffer,{line=generateLine(P.holeRND:random(4,7)),amount=13,countdown=t,cd0=t+62,time=0,sent=false,lv=5})
s=24
else
table.insert(P.atkBuffer,{line=generateLine(P.holeRND:random(2)*9-8),amount=14,countdown=t,cd0=t,time=0,sent=false,lv=5})
table.insert(P.atkBuffer,{line=generateLine(P.holeRND:random(3,8)),amount=14,countdown=t+62,cd0=t,time=0,sent=false,lv=5})
s=28
end
P.atkBufferSum=P.atkBufferSum+s
P.stat.recv=P.stat.recv+s
D.wave=D.wave+1
if D.wave%10==0 then
if D.wave==10 then
P:showTextF(text.great,0,-140,100,'appear',.6)
P.gameEnv.pushSpeed=4
elseif D.wave==20 then
P:showTextF(text.awesome,0,-140,100,'appear',.6)
P.gameEnv.pushSpeed=5
elseif D.wave==30 then
P:showTextF(text.maxspeed,0,-140,100,'appear',.6)
end
end
end
end
end,
bg='rainbow2',bgm='shining terminal',
},
mesDisp=function(P)
setFont(55)
mStr(P.modeData.wave,63,200)
mStr(20+4*math.min(math.floor(P.modeData.wave/10),2),63,320)
mText(drawableText.wave,63,260)
mText(drawableText.nextWave,63,380)
end,
score=function(P)return{P.modeData.wave,P.stat.time}end,
scoreDisp=function(D)return D[1].." Waves "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local W=P.modeData.wave
return
W>=50 and 5 or
W>=40 and 4 or
W>=30 and 3 or
W>=20 and 2 or
W>=10 and 1 or
W>=5 and 0
end,
color=COLOR.lYellow,
env={
drop=5,lock=60,
fall=8,
freshLimit=15,
task=function(P)
while true do
YIELD()
if P.control and P.atkBufferSum<4 then
local D=P.modeData
local s
local t=800-10*D.wave--800~700~600~500
if D.wave<10 then
table.insert(P.atkBuffer,{line=generateLine(P.holeRND:random(5,6)),amount=9,countdown=t,cd0=t,time=0,sent=false,lv=3})
table.insert(P.atkBuffer,{line=generateLine(P.holeRND:random(4,7)),amount=11,countdown=t,cd0=t+62,time=0,sent=false,lv=4})
s=20
elseif D.wave<20 then
table.insert(P.atkBuffer,{line=generateLine(P.holeRND:random(3,8)),amount=11,countdown=t,cd0=t,time=0,sent=false,lv=4})
table.insert(P.atkBuffer,{line=generateLine(P.holeRND:random(4,7)),amount=13,countdown=t,cd0=t+62,time=0,sent=false,lv=5})
s=24
else
table.insert(P.atkBuffer,{line=generateLine(P.holeRND:random(2)*9-8),amount=14,countdown=t,cd0=t,time=0,sent=false,lv=5})
table.insert(P.atkBuffer,{line=generateLine(P.holeRND:random(3,8)),amount=14,countdown=t+62,cd0=t,time=0,sent=false,lv=5})
s=28
end
P.atkBufferSum=P.atkBufferSum+s
P.stat.recv=P.stat.recv+s
D.wave=D.wave+1
if D.wave%10==0 then
if D.wave==10 then
P:showTextF(text.great,0,-140,100,'appear',.6)
P.gameEnv.pushSpeed=4
elseif D.wave==20 then
P:showTextF(text.awesome,0,-140,100,'appear',.6)
P.gameEnv.pushSpeed=5
elseif D.wave==30 then
P:showTextF(text.maxspeed,0,-140,100,'appear',.6)
end
end
end
end
end,
bg='rainbow2',bgm='shining terminal',
},
mesDisp=function(P)
setFont(55)
mStr(P.modeData.wave,63,200)
mStr(20+4*math.min(math.floor(P.modeData.wave/10),2),63,320)
mText(drawableText.wave,63,260)
mText(drawableText.nextWave,63,380)
end,
score=function(P)return{P.modeData.wave,P.stat.time}end,
scoreDisp=function(D)return D[1].." Waves "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local W=P.modeData.wave
return
W>=50 and 5 or
W>=40 and 4 or
W>=30 and 3 or
W>=20 and 2 or
W>=10 and 1 or
W>=5 and 0
end,
}

View File

@@ -1,39 +1,39 @@
return{
color=COLOR.magenta,
env={
drop=10,lock=60,
freshLimit=15,
dropPiece=function(P)
if P.lastPiece.atk>0 then
P:receive(nil,P.lastPiece.atk,60,generateLine(P.holeRND:random(10)))
end
if P.stat.atk>=100 then
P:win('finish')
end
end,
bg='tunnel',bgm='echo',
},
mesDisp=function(P)
setFont(60)
mStr(P.stat.atk,63,280)
mText(drawableText.atk,63,350)
end,
score=function(P)return{math.min(math.floor(P.stat.atk),100),P.stat.time}end,
scoreDisp=function(D)return D[1].." Attack "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.atk
if L>=100 then
local T=P.stat.time
return
T<50 and 5 or
T<65 and 4 or
T<100 and 3 or
T<130 and 2 or
1
else
return
L>=50 and 0
end
end,
color=COLOR.magenta,
env={
drop=10,lock=60,
freshLimit=15,
dropPiece=function(P)
if P.lastPiece.atk>0 then
P:receive(nil,P.lastPiece.atk,60,generateLine(P.holeRND:random(10)))
end
if P.stat.atk>=100 then
P:win('finish')
end
end,
bg='tunnel',bgm='echo',
},
mesDisp=function(P)
setFont(60)
mStr(P.stat.atk,63,280)
mText(drawableText.atk,63,350)
end,
score=function(P)return{math.min(math.floor(P.stat.atk),100),P.stat.time}end,
scoreDisp=function(D)return D[1].." Attack "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.atk
if L>=100 then
local T=P.stat.time
return
T<50 and 5 or
T<65 and 4 or
T<100 and 3 or
T<130 and 2 or
1
else
return
L>=50 and 0
end
end,
}

View File

@@ -1,39 +1,39 @@
return{
color=COLOR.red,
env={
drop=5,lock=45,
freshLimit=15,
dropPiece=function(P)
if P.lastPiece.atk>0 then
P:receive(nil,P.lastPiece.atk,30,generateLine(P.holeRND:random(10)))
end
if P.stat.atk>=100 then
P:win('finish')
end
end,
bg='blackhole',bgm='echo',
},
mesDisp=function(P)
setFont(60)
mStr(P.stat.atk,63,280)
mText(drawableText.atk,63,350)
end,
score=function(P)return{math.min(math.floor(P.stat.atk),100),P.stat.time}end,
scoreDisp=function(D)return D[1].." Attack "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.atk
if L>=100 then
local T=P.stat.time
return
T<55 and 5 or
T<70 and 4 or
T<110 and 3 or
T<150 and 2 or
1
else
return
L>=50 and 0
end
end,
color=COLOR.red,
env={
drop=5,lock=45,
freshLimit=15,
dropPiece=function(P)
if P.lastPiece.atk>0 then
P:receive(nil,P.lastPiece.atk,30,generateLine(P.holeRND:random(10)))
end
if P.stat.atk>=100 then
P:win('finish')
end
end,
bg='blackhole',bgm='echo',
},
mesDisp=function(P)
setFont(60)
mStr(P.stat.atk,63,280)
mText(drawableText.atk,63,350)
end,
score=function(P)return{math.min(math.floor(P.stat.atk),100),P.stat.time}end,
scoreDisp=function(D)return D[1].." Attack "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.atk
if L>=100 then
local T=P.stat.time
return
T<55 and 5 or
T<70 and 4 or
T<110 and 3 or
T<150 and 2 or
1
else
return
L>=50 and 0
end
end,
}

View File

@@ -1,38 +1,38 @@
return{
color=COLOR.green,
env={
drop=30,lock=60,
dropPiece=function(P)
if P.lastPiece.atk>0 then
P:receive(nil,P.lastPiece.atk,120,generateLine(P.holeRND:random(10)))
end
if P.stat.atk>=100 then
P:win('finish')
end
end,
bg='tunnel',bgm='echo',
},
mesDisp=function(P)
setFont(60)
mStr(P.stat.atk,63,280)
mText(drawableText.atk,63,350)
end,
score=function(P)return{math.min(math.floor(P.stat.atk),100),P.stat.time}end,
scoreDisp=function(D)return D[1].." Attack "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.atk
if L>=100 then
local T=P.stat.time
return
T<45 and 5 or
T<60 and 4 or
T<90 and 3 or
T<120 and 2 or
1
else
return
L>=50 and 0
end
end,
color=COLOR.green,
env={
drop=30,lock=60,
dropPiece=function(P)
if P.lastPiece.atk>0 then
P:receive(nil,P.lastPiece.atk,120,generateLine(P.holeRND:random(10)))
end
if P.stat.atk>=100 then
P:win('finish')
end
end,
bg='tunnel',bgm='echo',
},
mesDisp=function(P)
setFont(60)
mStr(P.stat.atk,63,280)
mText(drawableText.atk,63,350)
end,
score=function(P)return{math.min(math.floor(P.stat.atk),100),P.stat.time}end,
scoreDisp=function(D)return D[1].." Attack "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.atk
if L>=100 then
local T=P.stat.time
return
T<45 and 5 or
T<60 and 4 or
T<90 and 3 or
T<120 and 2 or
1
else
return
L>=50 and 0
end
end,
}

View File

@@ -1,39 +1,39 @@
return{
color=COLOR.lYellow,
env={
drop=2,lock=30,
freshLimit=10,
dropPiece=function(P)
if P.lastPiece.atk>0 then
P:receive(nil,P.lastPiece.atk,0,generateLine(P.holeRND:random(10)))
end
if P.stat.atk>=100 then
P:win('finish')
end
end,
bg='blackhole',bgm='echo',
},
mesDisp=function(P)
setFont(60)
mStr(P.stat.atk,63,280)
mText(drawableText.atk,63,350)
end,
score=function(P)return{math.min(math.floor(P.stat.atk),100),P.stat.time}end,
scoreDisp=function(D)return D[1].." Attack "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.atk
if L>=100 then
local T=P.stat.time
return
T<60 and 5 or
T<80 and 4 or
T<120 and 3 or
T<180 and 2 or
1
else
return
L>=50 and 0
end
end,
color=COLOR.lYellow,
env={
drop=2,lock=30,
freshLimit=10,
dropPiece=function(P)
if P.lastPiece.atk>0 then
P:receive(nil,P.lastPiece.atk,0,generateLine(P.holeRND:random(10)))
end
if P.stat.atk>=100 then
P:win('finish')
end
end,
bg='blackhole',bgm='echo',
},
mesDisp=function(P)
setFont(60)
mStr(P.stat.atk,63,280)
mText(drawableText.atk,63,350)
end,
score=function(P)return{math.min(math.floor(P.stat.atk),100),P.stat.time}end,
scoreDisp=function(D)return D[1].." Attack "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.atk
if L>=100 then
local T=P.stat.time
return
T<60 and 5 or
T<80 and 4 or
T<120 and 3 or
T<180 and 2 or
1
else
return
L>=50 and 0
end
end,
}

View File

@@ -1,19 +1,19 @@
return{
color=COLOR.lGray,
env={
drop=1e99,lock=1e99,
holdCount=0,
task=function(P)
while not P.control do YIELD()end
P:pressKey(6)
P:lose()
end,
bg='bg1',bgm='new era',
},
score=function(P)return{P.modeData.event,P.stat.finesseRate*.2/P.stat.piece}end,
scoreDisp=function(D)return("%d Stage %.2f%%"):format(D[1],D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]>b[2]end,
getRank=function()
return 1
end,
color=COLOR.lGray,
env={
drop=1e99,lock=1e99,
holdCount=0,
task=function(P)
while not P.control do YIELD()end
P:pressKey(6)
P:lose()
end,
bg='bg1',bgm='new era',
},
score=function(P)return{P.modeData.event,P.stat.finesseRate*.2/P.stat.piece}end,
scoreDisp=function(D)return("%d Stage %.2f%%"):format(D[1],D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]>b[2]end,
getRank=function()
return 1
end,
}

View File

@@ -1,37 +1,37 @@
local min=math.min
return{
color=COLOR.cyan,
env={
drop=30,lock=45,
visible='easy',
dropPiece=function(P)if P.stat.row>=200 then P:win('finish')end end,
freshLimit=10,
bg='glow',bgm='push',
},
mesDisp=function(P)
mText(drawableText.line,63,300)
mText(drawableText.techrash,63,420)
setFont(75)
mStr(P.stat.row,63,220)
mStr(P.stat.clears[4],63,340)
end,
score=function(P)return{min(P.stat.row,200),P.stat.time}end,
scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
if L>=200 then
local T=P.stat.time
return
T<=140 and 5 or
T<=200 and 4 or
3
else
return
L>=150 and 3 or
L>=100 and 2 or
L>=40 and 1 or
L>=1 and 0
end
end,
color=COLOR.cyan,
env={
drop=30,lock=45,
visible='easy',
dropPiece=function(P)if P.stat.row>=200 then P:win('finish')end end,
freshLimit=10,
bg='glow',bgm='push',
},
mesDisp=function(P)
mText(drawableText.line,63,300)
mText(drawableText.techrash,63,420)
setFont(75)
mStr(P.stat.row,63,220)
mStr(P.stat.clears[4],63,340)
end,
score=function(P)return{min(P.stat.row,200),P.stat.time}end,
scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
if L>=200 then
local T=P.stat.time
return
T<=140 and 5 or
T<=200 and 4 or
3
else
return
L>=150 and 3 or
L>=100 and 2 or
L>=40 and 1 or
L>=1 and 0
end
end,
}

View File

@@ -1,45 +1,45 @@
local gc=love.graphics
local min=math.min
return{
color=COLOR.magenta,
env={
drop=15,lock=45,
fall=10,
dropFX=0,lockFX=0,
visible='none',
score=false,
dropPiece=function(P)if P.stat.row>=200 then P:win('finish')end end,
freshLimit=15,
bg='rgb',bgm='push',
},
mesDisp=function(P)
mText(drawableText.line,63,300)
mText(drawableText.techrash,63,420)
setFont(75)
mStr(P.stat.row,63,220)
mStr(P.stat.clears[4],63,340)
PLY.draw.applyField(P)
gc.setColor(1,1,1,.1)
gc.draw(IMG.electric,0,106,0,2.6)
PLY.draw.cancelField(P)
end,
score=function(P)return{min(P.stat.row,200),P.stat.time}end,
scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
if L>=200 then
local T=P.stat.time
return
T<=180 and 5 or
T<=240 and 4 or
3
else
return
L>=150 and 3 or
L>=90 and 2 or
L>=40 and 1 or
L>=1 and 0
end
end,
color=COLOR.magenta,
env={
drop=15,lock=45,
fall=10,
dropFX=0,lockFX=0,
visible='none',
score=false,
dropPiece=function(P)if P.stat.row>=200 then P:win('finish')end end,
freshLimit=15,
bg='rgb',bgm='push',
},
mesDisp=function(P)
mText(drawableText.line,63,300)
mText(drawableText.techrash,63,420)
setFont(75)
mStr(P.stat.row,63,220)
mStr(P.stat.clears[4],63,340)
PLY.draw.applyField(P)
gc.setColor(1,1,1,.1)
gc.draw(IMG.electric,0,106,0,2.6)
PLY.draw.cancelField(P)
end,
score=function(P)return{min(P.stat.row,200),P.stat.time}end,
scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
if L>=200 then
local T=P.stat.time
return
T<=180 and 5 or
T<=240 and 4 or
3
else
return
L>=150 and 3 or
L>=90 and 2 or
L>=40 and 1 or
L>=1 and 0
end
end,
}

View File

@@ -1,46 +1,46 @@
local gc=love.graphics
local min=math.min
return{
color=COLOR.red,
env={
drop=10,lock=60,
fall=5,
ghost=0,
dropFX=0,lockFX=0,
visible='none',
score=false,
dropPiece=function(P)if P.stat.row>=200 then P:win('finish')end end,
freshLimit=15,
bg='rgb',bgm='push',
},
mesDisp=function(P)
mText(drawableText.line,63,300)
mText(drawableText.techrash,63,420)
setFont(75)
mStr(P.stat.row,63,220)
mStr(P.stat.clears[4],63,340)
PLY.draw.applyField(P)
gc.setColor(1,1,1,.1)
gc.draw(IMG.electric,0,106,0,2.6)
PLY.draw.cancelField(P)
end,
score=function(P)return{min(P.stat.row,200),P.stat.time}end,
scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
if L>=200 then
local T=P.stat.time
return
T<=200 and 5 or
T<=250 and 4 or
3
else
return
L>=150 and 3 or
L>=100 and 2 or
L>=40 and 1 or
L>=1 and 0
end
end,
color=COLOR.red,
env={
drop=10,lock=60,
fall=5,
ghost=0,
dropFX=0,lockFX=0,
visible='none',
score=false,
dropPiece=function(P)if P.stat.row>=200 then P:win('finish')end end,
freshLimit=15,
bg='rgb',bgm='push',
},
mesDisp=function(P)
mText(drawableText.line,63,300)
mText(drawableText.techrash,63,420)
setFont(75)
mStr(P.stat.row,63,220)
mStr(P.stat.clears[4],63,340)
PLY.draw.applyField(P)
gc.setColor(1,1,1,.1)
gc.draw(IMG.electric,0,106,0,2.6)
PLY.draw.cancelField(P)
end,
score=function(P)return{min(P.stat.row,200),P.stat.time}end,
scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
if L>=200 then
local T=P.stat.time
return
T<=200 and 5 or
T<=250 and 4 or
3
else
return
L>=150 and 3 or
L>=100 and 2 or
L>=40 and 1 or
L>=1 and 0
end
end,
}

View File

@@ -1,42 +1,42 @@
local gc=love.graphics
local min=math.min
return{
color=COLOR.green,
env={
drop=15,lock=45,
freshLimit=10,
visible='fast',
dropPiece=function(P)if P.stat.row>=200 then P:win('finish')end end,
bg='glow',bgm='push',
},
mesDisp=function(P)
mText(drawableText.line,63,300)
mText(drawableText.techrash,63,420)
setFont(75)
mStr(P.stat.row,63,220)
mStr(P.stat.clears[4],63,340)
PLY.draw.applyField(P)
gc.setColor(1,1,1,.1)
gc.draw(IMG.electric,0,106,0,2.6)
PLY.draw.cancelField(P)
end,
score=function(P)return{min(P.stat.row,200),P.stat.time}end,
scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
if L>=200 then
local T=P.stat.time
return
T<=180 and 5 or
T<=220 and 4 or
3
else
return
L>=126 and 3 or
L>=80 and 2 or
L>=40 and 1 or
L>=1 and 0
end
end,
color=COLOR.green,
env={
drop=15,lock=45,
freshLimit=10,
visible='fast',
dropPiece=function(P)if P.stat.row>=200 then P:win('finish')end end,
bg='glow',bgm='push',
},
mesDisp=function(P)
mText(drawableText.line,63,300)
mText(drawableText.techrash,63,420)
setFont(75)
mStr(P.stat.row,63,220)
mStr(P.stat.clears[4],63,340)
PLY.draw.applyField(P)
gc.setColor(1,1,1,.1)
gc.draw(IMG.electric,0,106,0,2.6)
PLY.draw.cancelField(P)
end,
score=function(P)return{min(P.stat.row,200),P.stat.time}end,
scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local L=P.stat.row
if L>=200 then
local T=P.stat.time
return
T<=180 and 5 or
T<=220 and 4 or
3
else
return
L>=126 and 3 or
L>=80 and 2 or
L>=40 and 1 or
L>=1 and 0
end
end,
}

Some files were not shown because too many files have changed in this diff Show More