代码规范:把所有的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 if arg[1]=="-code"then
print(require"version".apkCode) print(require"version".apkCode)
elseif arg[1]=="-name"then elseif arg[1]=="-name"then
print((require"version".string:gsub("@DEV",""))) print((require"version".string:gsub("@DEV","")))
elseif arg[1]=="-release"then elseif arg[1]=="-release"then
print((require"version".string:gsub("V",""))) print((require"version".string:gsub("V","")))
elseif arg[1]=="-updateTitle"then elseif arg[1]=="-updateTitle"then
local note=require"parts.updateLog" local note=require"parts.updateLog"
local p1=note:find("\n%d")+1 local p1=note:find("\n%d")+1
local p2=note:find("\n",p1)-1 local p2=note:find("\n",p1)-1
note=note:sub(p1,p2) note=note:sub(p1,p2)
print(note) print(note)
elseif arg[1]=="-updateNote"then elseif arg[1]=="-updateNote"then
local note=require"parts.updateLog" local note=require"parts.updateLog"
local p1=note:find("\n",note:find("\n%d")+1)+1 local p1=note:find("\n",note:find("\n%d")+1)+1
local p2=note:find("\n%d",p1+1) local p2=note:find("\n%d",p1+1)
note=note:sub(p1,p2-2) note=note:sub(p1,p2-2)
note=note note=note
:gsub("\t\t\t\t","_") :gsub("\t\t\t\t","_")
:gsub("\t\t","") :gsub("\t\t","")
:gsub("\n([^_])","\n\n%1") :gsub("\n([^_])","\n\n%1")
:gsub("\n_","\n") :gsub("\n_","\n")
:gsub("\n\n","\n",1) :gsub("\n\n","\n",1)
print(note) print(note)
end 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. 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 the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below. 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, and the "GNU GPL" refers to version 3 of the GNU
General Public License. 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. 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. 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 Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library. 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 Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked with which the Combined Work was made is also called the "Linked
Version". 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 Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version. 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 object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work. 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. 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 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 that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified facility is invoked), then you may convey a copy of the modified
version: version:
a) under this License, provided that you make a good faith effort to a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy. 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 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 code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following: (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 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 Library is used in it and that the Library and its use are
covered by this License. covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license b) Accompany the object code with a copy of the GNU GPL and this license
document. 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 taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of engineering for debugging such modifications, if you also do each of
the following: the following:
a) Give prominent notice with each copy of the Combined Work that 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 the Library is used in it and that the Library and its use are
covered by this License. covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license b) Accompany the Combined Work with a copy of the GNU GPL and this license
document. document.
c) For a Combined Work that displays copyright notices during c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document. 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 0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying manner specified by section 6 of the GNU GPL for conveying
Corresponding Source. Corresponding Source.
1) Use a suitable shared library mechanism for linking with the 1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked of the Library that is interface-compatible with the Linked
Version. Version.
e) Provide Installation Information, but only if you would otherwise e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.) 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 Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your License, and convey such a combined library under terms of your
choice, if you do both of the following: choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities, on the Library, uncombined with any other library facilities,
conveyed under the terms of this License. conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it 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 is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work. 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 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 versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns. 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 Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version" of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and 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, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation. 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 whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the permanent authorization for you to choose that version for the

View File

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

View File

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

View File

@@ -1,126 +1,126 @@
local COLOR={ local COLOR={
red= {.92, .12, .12}, red= {.92, .12, .12},
fire= {.92, 0.4, .12}, fire= {.92, 0.4, .12},
orange= {.92, 0.6, .12}, orange= {.92, 0.6, .12},
yellow= {.92, .92, .12}, yellow= {.92, .92, .12},
lime= {0.7, .92, .12}, lime= {0.7, .92, .12},
jade= {0.5, .92, .12}, jade= {0.5, .92, .12},
green= {.12, .92, .12}, green= {.12, .92, .12},
aqua= {.12, .92, 0.6}, aqua= {.12, .92, 0.6},
cyan= {.12, .92, .92}, cyan= {.12, .92, .92},
navy= {.12, 0.7, .92}, navy= {.12, 0.7, .92},
sea= {.12, 0.4, .92}, sea= {.12, 0.4, .92},
blue= {0.2, 0.2, .92}, blue= {0.2, 0.2, .92},
violet= {0.4, .12, .92}, violet= {0.4, .12, .92},
purple= {0.7, .12, .92}, purple= {0.7, .12, .92},
magenta= {.92, .12, .92}, magenta= {.92, .12, .92},
wine= {.92, .12, 0.5}, wine= {.92, .12, 0.5},
lRed= {.95, 0.5, 0.5}, lRed= {.95, 0.5, 0.5},
lFire= {.95, 0.7, 0.5}, lFire= {.95, 0.7, 0.5},
lOrange= {.95, 0.8, 0.3}, lOrange= {.95, 0.8, 0.3},
lYellow= {.95, .95, 0.5}, lYellow= {.95, .95, 0.5},
lLime= {0.8, .95, 0.4}, lLime= {0.8, .95, 0.4},
lJade= {0.6, .95, 0.4}, lJade= {0.6, .95, 0.4},
lGreen= {0.5, .95, 0.5}, lGreen= {0.5, .95, 0.5},
lAqua= {0.4, .95, 0.7}, lAqua= {0.4, .95, 0.7},
lCyan= {0.5, .95, .95}, lCyan= {0.5, .95, .95},
lNavy= {0.4, .85, .95}, lNavy= {0.4, .85, .95},
lSea= {0.5, 0.7, .95}, lSea= {0.5, 0.7, .95},
lBlue= {0.7, 0.7, .95}, lBlue= {0.7, 0.7, .95},
lViolet= {0.7, 0.4, .95}, lViolet= {0.7, 0.4, .95},
lPurple= {0.8, 0.4, .95}, lPurple= {0.8, 0.4, .95},
lMagenta= {.95, 0.5, .95}, lMagenta={.95, 0.5, .95},
lWine= {.95, 0.4, 0.7}, lWine= {.95, 0.4, 0.7},
dRed= {0.6, .08, .08}, dRed= {0.6, .08, .08},
dFire= {0.6, 0.3, .08}, dFire= {0.6, 0.3, .08},
dOrange= {0.6, 0.4, .08}, dOrange= {0.6, 0.4, .08},
dYellow= {0.6, 0.6, .08}, dYellow= {0.6, 0.6, .08},
dLime= {0.5, 0.6, .08}, dLime= {0.5, 0.6, .08},
dJade= {0.3, 0.6, .08}, dJade= {0.3, 0.6, .08},
dGreen= {.08, 0.6, .08}, dGreen= {.08, 0.6, .08},
dAqua= {.08, 0.6, 0.4}, dAqua= {.08, 0.6, 0.4},
dCyan= {.08, 0.6, 0.6}, dCyan= {.08, 0.6, 0.6},
dNavy= {.08, 0.4, 0.6}, dNavy= {.08, 0.4, 0.6},
dSea= {.08, 0.2, 0.6}, dSea= {.08, 0.2, 0.6},
dBlue= {0.1, 0.1, 0.6}, dBlue= {0.1, 0.1, 0.6},
dViolet= {0.2, .08, 0.6}, dViolet= {0.2, .08, 0.6},
dPurple= {0.4, .08, 0.6}, dPurple= {0.4, .08, 0.6},
dMagenta= {0.6, .08, 0.6}, dMagenta={0.6, .08, 0.6},
dWine= {0.6, .08, 0.3}, dWine= {0.6, .08, 0.3},
black= {.05, .05, .05}, black= {.05, .05, .05},
dGray= {0.3, 0.3, 0.3}, dGray= {0.3, 0.3, 0.3},
gray= {0.6, 0.6, 0.6}, gray= {0.6, 0.6, 0.6},
lGray= {0.8, 0.8, 0.8}, lGray= {0.8, 0.8, 0.8},
white= {.97, .97, .97}, white= {.97, .97, .97},
} }
for k,v in next,{ 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', 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', 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', 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', D='black',dH='dGray',H='gray',lH='lGray',Z='white',
--Remain letter: EIKQTUX --Remain letter: EIKQTUX
}do }do
COLOR[k]=COLOR[v] COLOR[k]=COLOR[v]
end end
setmetatable(COLOR,{__index=function(_,k) setmetatable(COLOR,{__index=function(_,k)
error("No color: "..tostring(k)) error("No color: "..tostring(k))
end}) end})
do--Random generators do--Random generators
local rnd=math.random local rnd=math.random
local list_norm={'red','fire','orange','yellow','lime','jade','green','aqua','cyan','navy','sea','blue','violet','purple','magenta','wine'} 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 local len_list_norm=#list_norm
function COLOR.random_norm() function COLOR.random_norm()
return COLOR[list_norm[rnd(len_list_norm)]] return COLOR[list_norm[rnd(len_list_norm)]]
end end
local list_bright={'lRed','lFire','lOrange','lYellow','lLime','lJade','lGreen','lAqua','lCyan','lNavy','lSea','lBlue','lViolet','lPurple','lMagenta','lWine'} 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 local len_list_bright=#list_bright
function COLOR.random_bright() function COLOR.random_bright()
return COLOR[list_bright[rnd(len_list_bright)]] return COLOR[list_bright[rnd(len_list_bright)]]
end end
local list_dark={'dRed','dFire','dOrange','dYellow','dLime','dJade','dGreen','dAqua','dCyan','dNavy','dSea','dBlue','dViolet','dPurple','dMagenta','dWine'} 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 local len_list_dark=#list_dark
function COLOR.random_dark() function COLOR.random_dark()
return COLOR[list_dark[rnd(len_list_dark)]] return COLOR[list_dark[rnd(len_list_dark)]]
end end
end end
do--Rainbow generators do--Rainbow generators
local sin=math.sin local sin=math.sin
function COLOR.rainbow(phase,a) function COLOR.rainbow(phase,a)
return return
sin(phase)*.4+.6, sin(phase)*.4+.6,
sin(phase+2.0944)*.4+.6, sin(phase+2.0944)*.4+.6,
sin(phase-2.0944)*.4+.6, sin(phase-2.0944)*.4+.6,
a a
end end
function COLOR.rainbow_light(phase,a) function COLOR.rainbow_light(phase,a)
return return
sin(phase)*.2+.7, sin(phase)*.2+.7,
sin(phase+2.0944)*.2+.7, sin(phase+2.0944)*.2+.7,
sin(phase-2.0944)*.2+.7, sin(phase-2.0944)*.2+.7,
a a
end end
function COLOR.rainbow_dark(phase,a) function COLOR.rainbow_dark(phase,a)
return return
sin(phase)*.2+.4, sin(phase)*.2+.4,
sin(phase+2.0944)*.2+.4, sin(phase+2.0944)*.2+.4,
sin(phase-2.0944)*.2+.4, sin(phase-2.0944)*.2+.4,
a a
end end
function COLOR.rainbow_gray(phase,a) function COLOR.rainbow_gray(phase,a)
return return
sin(phase)*.16+.5, sin(phase)*.16+.5,
sin(phase+2.0944)*.16+.5, sin(phase+2.0944)*.16+.5,
sin(phase-2.0944)*.16+.5, sin(phase-2.0944)*.16+.5,
a a
end end
end end
return COLOR return COLOR

View File

@@ -1,90 +1,90 @@
local fs=love.filesystem local fs=love.filesystem
local FILE={} local FILE={}
function FILE.load(name) function FILE.load(name)
if fs.getInfo(name)then if fs.getInfo(name)then
local F=fs.newFile(name) local F=fs.newFile(name)
if F:open'r'then if F:open'r'then
local s=F:read() local s=F:read()
F:close() F:close()
if s:sub(1,6)=="return"then if s:sub(1,6)=="return"then
s=loadstring(s) s=loadstring(s)
if s then if s then
setfenv(s,{}) setfenv(s,{})
return s() return s()
end end
elseif s:sub(1,1)=="["or s:sub(1,1)=="{"then elseif s:sub(1,1)=="["or s:sub(1,1)=="{"then
local res=JSON.decode(s) local res=JSON.decode(s)
if res then if res then
return res return res
end end
else else
return s return s
end end
end end
MES.new('error',name.." "..text.loadError) MES.new('error',name.." "..text.loadError)
end end
end end
function FILE.save(data,name,mode) function FILE.save(data,name,mode)
if not mode then mode=""end if not mode then mode=""end
if type(data)=='table'then if type(data)=='table'then
if mode:find'l'then if mode:find'l'then
data=TABLE.dump(data) data=TABLE.dump(data)
if not data then if not data then
MES.new('error',name.." "..text.saveError.."dump error") MES.new('error',name.." "..text.saveError.."dump error")
return return
end end
else else
data=JSON.encode(data) data=JSON.encode(data)
if not data then if not data then
MES.new('error',name.." "..text.saveError.."json error") MES.new('error',name.." "..text.saveError.."json error")
return return
end end
end end
else else
data=tostring(data) data=tostring(data)
end end
if mode:find'd'and fs.getInfo(name)then if mode:find'd'and fs.getInfo(name)then
MES.new('error',text.saveError_duplicate) MES.new('error',text.saveError_duplicate)
return return
end end
local F=fs.newFile(name) local F=fs.newFile(name)
F:open'w' F:open'w'
local success,mes=F:write(data) local success,mes=F:write(data)
F:flush()F:close() F:flush()F:close()
if success then if success then
return true return true
else else
MES.new('error',text.saveError..(mes or"unknown error")) MES.new('error',text.saveError..(mes or"unknown error"))
MES.traceback() MES.traceback()
end end
end end
function FILE.clear(path) function FILE.clear(path)
if fs.getRealDirectory(path)~=SAVEDIR or fs.getInfo(path).type~='directory'then return end if fs.getRealDirectory(path)~=SAVEDIR or fs.getInfo(path).type~='directory'then return end
for _,name in next,fs.getDirectoryItems(path)do for _,name in next,fs.getDirectoryItems(path)do
name=path..'/'..name name=path..'/'..name
if fs.getRealDirectory(name)==SAVEDIR then if fs.getRealDirectory(name)==SAVEDIR then
local t=fs.getInfo(name).type local t=fs.getInfo(name).type
if t=='file'then if t=='file'then
fs.remove(name) fs.remove(name)
end end
end end
end end
end end
function FILE.clear_s(path) function FILE.clear_s(path)
if path~=''and(fs.getRealDirectory(path)~=SAVEDIR or fs.getInfo(path).type~='directory')then return end if path~=''and(fs.getRealDirectory(path)~=SAVEDIR or fs.getInfo(path).type~='directory')then return end
for _,name in next,fs.getDirectoryItems(path)do for _,name in next,fs.getDirectoryItems(path)do
name=path..'/'..name name=path..'/'..name
if fs.getRealDirectory(name)==SAVEDIR then if fs.getRealDirectory(name)==SAVEDIR then
local t=fs.getInfo(name).type local t=fs.getInfo(name).type
if t=='file'then if t=='file'then
fs.remove(name) fs.remove(name)
elseif t=='directory'then elseif t=='directory'then
FILE.clear_s(name) FILE.clear_s(name)
fs.remove(name) fs.remove(name)
end end
end end
end end
fs.remove(path) fs.remove(path)
end end
return FILE 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.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.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) function GC.outDraw(obj,div,x,y,a,k)
local w,h=obj:getWidth()*.5,obj:getHeight()*.5 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)
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 end
function GC.shadedPrint(str,x,y,mode,d,clr1,clr2) function GC.shadedPrint(str,x,y,mode,d,clr1,clr2)
local w=1280 local w=1280
if mode=='center'then if mode=='center'then
x=x-w*.5 x=x-w*.5
elseif mode=='right'then elseif mode=='right'then
x=x-w x=x-w
end end
if not d then d=1 end if not d then d=1 end
setColor(clr1 or COLOR.D) 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)
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) setColor(clr2 or COLOR.Z)
printf(str,x,y,w,mode) printf(str,x,y,w,mode)
end end
function GC.regularPolygon(mode,x,y,R,segments,r,phase) function GC.regularPolygon(mode,x,y,R,segments,r,phase)
local X,Y={},{} local X,Y={},{}
local ang=phase or 0 local ang=phase or 0
local angStep=6.283185307179586/segments local angStep=6.283185307179586/segments
for i=1,segments do for i=1,segments do
X[i]=x+R*math.cos(ang) X[i]=x+R*math.cos(ang)
Y[i]=y+R*math.sin(ang) Y[i]=y+R*math.sin(ang)
ang=ang+angStep ang=ang+angStep
end end
X[segments+1]=x+R*math.cos(ang) X[segments+1]=x+R*math.cos(ang)
Y[segments+1]=y+R*math.sin(ang) Y[segments+1]=y+R*math.sin(ang)
local halfAng=6.283185307179586/segments/2 local halfAng=6.283185307179586/segments/2
local erasedLen=r*math.tan(halfAng) local erasedLen=r*math.tan(halfAng)
if mode=='line'then if mode=='line'then
erasedLen=erasedLen+1--Fix 1px cover erasedLen=erasedLen+1--Fix 1px cover
for i=1,segments do for i=1,segments do
--Line --Line
local x1,y1,x2,y2=X[i],Y[i],X[i+1],Y[i+1] local x1,y1,x2,y2=X[i],Y[i],X[i+1],Y[i+1]
local dir=math.atan2(y2-y1,x2-x1) 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)) gc.line(x1+erasedLen*math.cos(dir),y1+erasedLen*math.sin(dir),x2-erasedLen*math.cos(dir),y2-erasedLen*math.sin(dir))
--Arc --Arc
ang=ang+angStep ang=ang+angStep
local R2=R-r/math.cos(halfAng) local R2=R-r/math.cos(halfAng)
local arcCX,arcCY=x+R2*math.cos(ang),y+R2*math.sin(ang) local arcCX,arcCY=x+R2*math.cos(ang),y+R2*math.sin(ang)
gc.arc('line','open',arcCX,arcCY,r,ang-halfAng,ang+halfAng) gc.arc('line','open',arcCX,arcCY,r,ang-halfAng,ang+halfAng)
end end
elseif mode=='fill'then elseif mode=='fill'then
local L={} local L={}
for i=1,segments do for i=1,segments do
--Line --Line
local x1,y1,x2,y2=X[i],Y[i],X[i+1],Y[i+1] local x1,y1,x2,y2=X[i],Y[i],X[i+1],Y[i+1]
local dir=math.atan2(y2-y1,x2-x1) local dir=math.atan2(y2-y1,x2-x1)
table.insert(L,x1+erasedLen*math.cos(dir)) table.insert(L,x1+erasedLen*math.cos(dir))
table.insert(L,y1+erasedLen*math.sin(dir)) table.insert(L,y1+erasedLen*math.sin(dir))
table.insert(L,x2-erasedLen*math.cos(dir)) table.insert(L,x2-erasedLen*math.cos(dir))
table.insert(L,y2-erasedLen*math.sin(dir)) table.insert(L,y2-erasedLen*math.sin(dir))
--Arc --Arc
ang=ang+angStep ang=ang+angStep
local R2=R-r/math.cos(halfAng) local R2=R-r/math.cos(halfAng)
local arcCX,arcCY=x+R2*math.cos(ang),y+R2*math.sin(ang) local arcCX,arcCY=x+R2*math.cos(ang),y+R2*math.sin(ang)
gc.arc('fill','open',arcCX,arcCY,r,ang-halfAng,ang+halfAng) gc.arc('fill','open',arcCX,arcCY,r,ang-halfAng,ang+halfAng)
end end
gc.polygon('fill',L) gc.polygon('fill',L)
else else
error("Draw mode should be 'line' or 'fill'") error("Draw mode should be 'line' or 'fill'")
end end
end end
do--function GC.DO(L) do--function GC.DO(L)
local cmds={ local cmds={
origin="origin", origin="origin",
move="translate", move="translate",
scale="scale", scale="scale",
rotate="rotate", rotate="rotate",
shear="shear", shear="shear",
clear="clear", clear="clear",
setCL="setColor", setCL="setColor",
setCM="setColorMask", setCM="setColorMask",
setLW="setLineWidth", setLW="setLineWidth",
setLS="setLineStyle", setLS="setLineStyle",
setLJ="setLineJoin", setLJ="setLineJoin",
print="print", print="print",
setFT=function(...)setFont(...)end, setFT=function(...)setFont(...)end,
mText=GC.str, mText=GC.str,
mDraw=GC.draw, mDraw=GC.draw,
mOutDraw=GC.outDraw, mOutDraw=GC.outDraw,
draw="draw", draw="draw",
line="line", line="line",
fRect=function(...)gc.rectangle('fill',...)end, fRect=function(...)gc.rectangle('fill',...)end,
dRect=function(...)gc.rectangle('line',...)end, dRect=function(...)gc.rectangle('line',...)end,
fCirc=function(...)gc.circle('fill',...)end, fCirc=function(...)gc.circle('fill',...)end,
dCirc=function(...)gc.circle('line',...)end, dCirc=function(...)gc.circle('line',...)end,
fElps=function(...)gc.ellipse('fill',...)end, fElps=function(...)gc.ellipse('fill',...)end,
dElps=function(...)gc.ellipse('line',...)end, dElps=function(...)gc.ellipse('line',...)end,
fPoly=function(...)gc.polygon('fill',...)end, fPoly=function(...)gc.polygon('fill',...)end,
dPoly=function(...)gc.polygon('line',...)end, dPoly=function(...)gc.polygon('line',...)end,
dPie=function(...)gc.arc('line',...)end, dPie=function(...)gc.arc('line',...)end,
dArc=function(...)gc.arc('line','open',...)end, dArc=function(...)gc.arc('line','open',...)end,
dBow=function(...)gc.arc('line','closed',...)end, dBow=function(...)gc.arc('line','closed',...)end,
fPie=function(...)gc.arc('fill',...)end, fPie=function(...)gc.arc('fill',...)end,
fArc=function(...)gc.arc('fill','open',...)end, fArc=function(...)gc.arc('fill','open',...)end,
fBow=function(...)gc.arc('fill','closed',...)end, fBow=function(...)gc.arc('fill','closed',...)end,
fRPol=function(...)GC.regularPolygon('fill',...)end, fRPol=function(...)GC.regularPolygon('fill',...)end,
dRPol=function(...)GC.regularPolygon('line',...)end, dRPol=function(...)GC.regularPolygon('line',...)end,
} }
local sizeLimit=gc.getSystemLimits().texturesize local sizeLimit=gc.getSystemLimits().texturesize
function GC.DO(L) function GC.DO(L)
gc.push() gc.push()
::REPEAT_tryAgain:: ::REPEAT_tryAgain::
local success,canvas=pcall(gc.newCanvas,math.min(L[1],sizeLimit),math.min(L[2],sizeLimit)) local success,canvas=pcall(gc.newCanvas,math.min(L[1],sizeLimit),math.min(L[2],sizeLimit))
if not success then if not success then
sizeLimit=math.floor(sizeLimit*.8) sizeLimit=math.floor(sizeLimit*.8)
goto REPEAT_tryAgain goto REPEAT_tryAgain
end end
gc.setCanvas(canvas) gc.setCanvas(canvas)
gc.origin() gc.origin()
gc.clear(1,1,1,0) gc.clear(1,1,1,0)
gc.setColor(1,1,1) gc.setColor(1,1,1)
gc.setLineWidth(1) gc.setLineWidth(1)
for i=3,#L do for i=3,#L do
local cmd=L[i][1] local cmd=L[i][1]
if type(cmd)=='boolean'and cmd then if type(cmd)=='boolean'and cmd then
table.remove(L[i],1) table.remove(L[i],1)
cmd=L[i][1] cmd=L[i][1]
end end
if type(cmd)=='string'then if type(cmd)=='string'then
local func=cmds[cmd] local func=cmds[cmd]
if type(func)=='string'then func=gc[func]end if type(func)=='string'then func=gc[func]end
if func then if func then
func(unpack(L[i],2)) func(unpack(L[i],2))
else else
error("No gc command: "..cmd) error("No gc command: "..cmd)
end end
end end
end end
gc.setCanvas() gc.setCanvas()
gc.pop() gc.pop()
return canvas return canvas
end end
end end
return GC return GC

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -1,56 +1,56 @@
local LANG={} local LANG={}
function LANG.init(langList,publicText)--Attention, calling this will destory all initializing methods, create a LANG.set()! function LANG.init(langList,publicText)--Attention, calling this will destory all initializing methods, create a LANG.set()!
local function _langFallback(T0,T) local function _langFallback(T0,T)
for k,v in next,T0 do for k,v in next,T0 do
if type(v)=='table'and not v.refuseCopy then--refuseCopy: just copy pointer, not contents if type(v)=='table'and not v.refuseCopy then--refuseCopy: just copy pointer, not contents
if not T[k]then T[k]={}end if not T[k]then T[k]={}end
if type(T[k])=='table'then _langFallback(v,T[k])end if type(T[k])=='table'then _langFallback(v,T[k])end
elseif not T[k]then elseif not T[k]then
T[k]=v T[k]=v
end end
end end
end end
local tipMeta={__call=function(L)return L[math.random(#L)]end} local tipMeta={__call=function(L)return L[math.random(#L)]end}
for i=1,#langList do for i=1,#langList do
local L=langList[i] local L=langList[i]
--Set public text --Set public text
for key,list in next,publicText do for key,list in next,publicText do
L[key]=list L[key]=list
end end
--Fallback to other language, default zh --Fallback to other language, default zh
if i>1 then if i>1 then
_langFallback(langList[L.fallback or 1],L) _langFallback(langList[L.fallback or 1],L)
end end
--Metatable:__call for table:getTip --Metatable:__call for table:getTip
if type(rawget(L,'getTip'))=='table'then if type(rawget(L,'getTip'))=='table'then
setmetatable(L.getTip,tipMeta) setmetatable(L.getTip,tipMeta)
end end
end end
LANG.init,LANG.setLangList,LANG.setPublicText=nil LANG.init,LANG.setLangList,LANG.setPublicText=nil
function LANG.set(l) function LANG.set(l)
if text~=langList[l]then if text~=langList[l]then
text=langList[l] text=langList[l]
WIDGET.setLang(text.WidgetText) WIDGET.setLang(text.WidgetText)
for k,v in next,drawableText do for k,v in next,drawableText do
if text[k]then if text[k]then
v:set(text[k]) v:set(text[k])
end end
end end
end end
end end
function LANG.addScene(name) function LANG.addScene(name)
for i=1,#langList do for i=1,#langList do
if langList[i].WidgetText and not langList[i].WidgetText[name]then if langList[i].WidgetText and not langList[i].WidgetText[name]then
langList[i].WidgetText[name]={back=langList[i].back} langList[i].WidgetText[name]={back=langList[i].back}
end end
end end
end end
end end
return LANG 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 lightRenderShader=gc.newShader('Zframework/light/lightRender.glsl')--Shader for rendering blurred lights and shadows.
local Lights={}--Lightsource objects local Lights={}--Lightsource objects
local function move(L,x,y) local function move(L,x,y)
L.x,L.y=x,y L.x,L.y=x,y
end end
local function setPow(L,pow) local function setPow(L,pow)
L.size=pow L.size=pow
end end
local function drawLight(L) local function drawLight(L)
local s=L.size local s=L.size
--Initialization --Initialization
gc_setCanvas(L.blackCanvas)clear() gc_setCanvas(L.blackCanvas)clear()
gc_setCanvas(L.shadowCanvas)clear() gc_setCanvas(L.shadowCanvas)clear()
gc_setCanvas(L.renderCanvas)clear() gc_setCanvas(L.renderCanvas)clear()
lightRenderShader:send('xresolution',s) lightRenderShader:send('xresolution',s)
shadowMapShader:send('yresolution',s) shadowMapShader:send('yresolution',s)
--Get up-left of light --Get up-left of light
local X=L.x-s*.5 local X=L.x-s*.5
local Y=L.y-s*.5 local Y=L.y-s*.5
--Render solid --Render solid
gc_translate(-X,-Y) gc_translate(-X,-Y)
L.blackCanvas:renderTo(L.blackFn) L.blackCanvas:renderTo(L.blackFn)
gc_translate(X,Y) gc_translate(X,Y)
--Render shade canvas by solid --Render shade canvas by solid
gc_setShader(shadowMapShader) gc_setShader(shadowMapShader)
gc_setCanvas(L.shadowCanvas) gc_setCanvas(L.shadowCanvas)
gc_draw(L.blackCanvas) gc_draw(L.blackCanvas)
--Render light canvas by shade --Render light canvas by shade
gc_setShader(lightRenderShader) gc_setShader(lightRenderShader)
gc_setCanvas(L.renderCanvas) gc_setCanvas(L.renderCanvas)
gc_draw(L.shadowCanvas,0,0,0,1,s) gc_draw(L.shadowCanvas,0,0,0,1,s)
--Ready to final render --Ready to final render
gc_setShader()gc_setCanvas()gc.setBlendMode('add') gc_setShader()gc_setCanvas()gc.setBlendMode('add')
--Render to screen --Render to screen
gc_draw(L.renderCanvas,X,Y+s,0,1,-1) gc_draw(L.renderCanvas,X,Y+s,0,1,-1)
--Reset --Reset
gc.setBlendMode('alpha') gc.setBlendMode('alpha')
end end
local LIGHT={} local LIGHT={}
function LIGHT.draw() function LIGHT.draw()
gc_setColor(1,1,1) gc_setColor(1,1,1)
for i=1,#Lights do for i=1,#Lights do
drawLight(Lights[i]) drawLight(Lights[i])
end end
end end
function LIGHT.clear() function LIGHT.clear()
for i=1,#Lights do for i=1,#Lights do
Lights[i].blackCanvas:release() Lights[i].blackCanvas:release()
Lights[i].shadowCanvas:release() Lights[i].shadowCanvas:release()
Lights[i].renderCanvas:release() Lights[i].renderCanvas:release()
Lights[i]=nil Lights[i]=nil
end end
end end
function LIGHT.add(x,y,radius,solidFunc) function LIGHT.add(x,y,radius,solidFunc)
local id=#Lights+1 local id=#Lights+1
Lights[id]={ Lights[id]={
id=id, id=id,
x=x,y=y,size=radius, x=x,y=y,size=radius,
blackCanvas=gc.newCanvas(radius,radius),--Solid canvas blackCanvas=gc.newCanvas(radius,radius),--Solid canvas
shadowCanvas=gc.newCanvas(radius,1),--1D vis-depth canvas shadowCanvas=gc.newCanvas(radius,1),--1D vis-depth canvas
renderCanvas=gc.newCanvas(radius,radius),--Light canvas renderCanvas=gc.newCanvas(radius,radius),--Light canvas
blackFn=solidFunc,--Solid draw function blackFn=solidFunc,--Solid draw function
move=move, move=move,
setPow=setPow, setPow=setPow,
} }
end end
return LIGHT return LIGHT

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,87 +1,87 @@
local SFX={ local SFX={
getCount=function()return 0 end, getCount=function()return 0 end,
loadAll=function()error("Cannot load before init!")end, loadAll=function()error("Cannot load before init!")end,
fieldPlay=NULL, fieldPlay=NULL,
play=NULL, play=NULL,
fplay=NULL, fplay=NULL,
reset=NULL, reset=NULL,
} }
function SFX.init(list) function SFX.init(list)
SFX.init=nil SFX.init=nil
local rem=table.remove local rem=table.remove
local Sources={} local Sources={}
local count=#list function SFX.getCount()return count end local count=#list function SFX.getCount()return count end
function SFX.loadAll() function SFX.loadAll()
for i=1,count do for i=1,count do
local N='media/SFX/'..list[i]..'.ogg' local N='media/SFX/'..list[i]..'.ogg'
if love.filesystem.getInfo(N)then if love.filesystem.getInfo(N)then
Sources[list[i]]={love.audio.newSource(N,'static')} Sources[list[i]]={love.audio.newSource(N,'static')}
else else
MES.new('warn',"No SFX file: "..N,.1) MES.new('warn',"No SFX file: "..N,.1)
end end
end end
function SFX.play(s,vol,pos) function SFX.play(s,vol,pos)
if SETTING.sfx==0 or vol==0 then return end if SETTING.sfx==0 or vol==0 then return end
local S=Sources[s]--Source list local S=Sources[s]--Source list
if not S then return end if not S then return end
local n=1 local n=1
while S[n]:isPlaying()do while S[n]:isPlaying()do
n=n+1 n=n+1
if not S[n]then if not S[n]then
S[n]=S[1]:clone() S[n]=S[1]:clone()
S[n]:seek(0) S[n]:seek(0)
break break
end end
end end
S=S[n]--AU_SRC S=S[n]--AU_SRC
if S:getChannelCount()==1 then if S:getChannelCount()==1 then
if pos then if pos then
pos=pos*SETTING.stereo pos=pos*SETTING.stereo
S:setPosition(pos,1-pos^2,0) S:setPosition(pos,1-pos^2,0)
else else
S:setPosition(0,0,0) S:setPosition(0,0,0)
end end
end end
S:setVolume(((vol or 1)*SETTING.sfx)^1.626) S:setVolume(((vol or 1)*SETTING.sfx)^1.626)
S:play() S:play()
end end
function SFX.fplay(s,vol,pos) function SFX.fplay(s,vol,pos)
local S=Sources[s]--Source list local S=Sources[s]--Source list
if not S then return end if not S then return end
local n=1 local n=1
while S[n]:isPlaying()do while S[n]:isPlaying()do
n=n+1 n=n+1
if not S[n]then if not S[n]then
S[n]=S[1]:clone() S[n]=S[1]:clone()
S[n]:seek(0) S[n]:seek(0)
break break
end end
end end
S=S[n]--AU_SRC S=S[n]--AU_SRC
if S:getChannelCount()==1 then if S:getChannelCount()==1 then
if pos then if pos then
pos=pos*SETTING.stereo pos=pos*SETTING.stereo
S:setPosition(pos,1-pos^2,0) S:setPosition(pos,1-pos^2,0)
else else
S:setPosition(0,0,0) S:setPosition(0,0,0)
end end
end end
S:setVolume(vol^1.626) S:setVolume(vol^1.626)
S:play() S:play()
end end
function SFX.reset() function SFX.reset()
for _,L in next,Sources do for _,L in next,Sources do
if type(L)=='table'then if type(L)=='table'then
for i=#L,1,-1 do for i=#L,1,-1 do
if not L[i]:isPlaying()then if not L[i]:isPlaying()then
rem(L,i) rem(L,i)
end end
end end
end end
end end
end end
end end
end end
return SFX 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 local char,byte=string.char,string.byte
do--function STRING.shiftChar(c) do--function STRING.shiftChar(c)
local shiftMap={ local shiftMap={
['1']='!',['2']='@',['3']='#',['4']='$',['5']='%', ['1']='!',['2']='@',['3']='#',['4']='$',['5']='%',
['6']='^',['7']='&',['8']='*',['9']='(',['0']=')', ['6']='^',['7']='&',['8']='*',['9']='(',['0']=')',
['`']='~',['-']='_',['=']='+', ['`']='~',['-']='_',['=']='+',
['[']='{',[']']='}',['\\']='|', ['[']='{',[']']='}',['\\']='|',
[';']=':',['\'']='"', [';']=':',['\'']='"',
[',']='<',['.']='>',['/']='?', [',']='<',['.']='>',['/']='?',
} }
function STRING.shiftChar(c) function STRING.shiftChar(c)
return shiftMap[c]or upper(c) return shiftMap[c]or upper(c)
end end
end end
function STRING.trim(s) function STRING.trim(s)
if not s:find("%S")then return""end if not s:find("%S")then return""end
s=s:sub((s:find("%S"))):reverse() s=s:sub((s:find("%S"))):reverse()
return s:sub((s:find("%S"))):reverse() return s:sub((s:find("%S"))):reverse()
end end
function STRING.split(s,sep,regex) function STRING.split(s,sep,regex)
local L={} local L={}
local p1,p2=1--start,target local p1,p2=1--start,target
if regex then if regex then
while p1<=#s do while p1<=#s do
p2=find(s,sep,p1)or #s+1 p2=find(s,sep,p1)or #s+1
L[#L+1]=sub(s,p1,p2-1) L[#L+1]=sub(s,p1,p2-1)
p1=p2+#sep p1=p2+#sep
end end
else else
while p1<=#s do while p1<=#s do
p2=find(s,sep,p1,true)or #s+1 p2=find(s,sep,p1,true)or #s+1
L[#L+1]=sub(s,p1,p2-1) L[#L+1]=sub(s,p1,p2-1)
p1=p2+#sep p1=p2+#sep
end end
end end
return L return L
end end
function STRING.simpEmailCheck(e) function STRING.simpEmailCheck(e)
e=STRING.split(e,"@") e=STRING.split(e,"@")
if #e~=2 then return false end if #e~=2 then return false end
if e[1]:sub(-1)=="."or e[2]:sub(-1)=="."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],".") local e1,e2=STRING.split(e[1],"."),STRING.split(e[2],".")
if #e1*#e2==0 then return false end 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,e1 do if #v==0 then return false end end
for _,v in next,e2 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 return true
end end
function STRING.time(s) function STRING.time(s)
if s<60 then if s<60 then
return format("%.3f\"",s) return format("%.3f\"",s)
elseif s<3600 then elseif s<3600 then
return format("%d'%05.2f\"",int(s/60),s%60) return format("%d'%05.2f\"",int(s/60),s%60)
else else
local h=int(s/3600) local h=int(s/3600)
return format("%d:%.2d'%05.2f\"",h,int(s/60%60),s%60) return format("%d:%.2d'%05.2f\"",h,int(s/60%60),s%60)
end end
end end
do--function STRING.urlEncode(s) do--function STRING.urlEncode(s)
local rshift=bit.rshift local rshift=bit.rshift
local b16={[0]='0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'} local b16={[0]='0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}
function STRING.urlEncode(s) function STRING.urlEncode(s)
local out="" local out=""
for i=1,#s do for i=1,#s do
if s:sub(i,i):match("[a-zA-Z0-9]")then if s:sub(i,i):match("[a-zA-Z0-9]")then
out=out..s:sub(i,i) out=out..s:sub(i,i)
else else
local b=s:byte(i) local b=s:byte(i)
out=out.."%"..b16[rshift(b,4)]..b16[b%16] out=out.."%"..b16[rshift(b,4)]..b16[b%16]
end end
end end
return out return out
end end
end end
function STRING.vcsEncrypt(text,key) function STRING.vcsEncrypt(text,key)
local keyLen=#key local keyLen=#key
local result="" local result=""
local buffer="" local buffer=""
for i=0,#text-1 do for i=0,#text-1 do
buffer=buffer..char((byte(text,i+1)-32+byte(key,i%keyLen+1))%95+32) buffer=buffer..char((byte(text,i+1)-32+byte(key,i%keyLen+1))%95+32)
if #buffer==26 then if #buffer==26 then
result=result..buffer result=result..buffer
buffer="" buffer=""
end end
end end
return result..buffer return result..buffer
end end
function STRING.vcsDecrypt(text,key) function STRING.vcsDecrypt(text,key)
local keyLen=#key local keyLen=#key
local result="" local result=""
local buffer="" local buffer=""
for i=0,#text-1 do for i=0,#text-1 do
buffer=buffer..char((byte(text,i+1)-32-byte(key,i%keyLen+1))%95+32) buffer=buffer..char((byte(text,i+1)-32-byte(key,i%keyLen+1))%95+32)
if #buffer==26 then if #buffer==26 then
result=result..buffer result=result..buffer
buffer="" buffer=""
end end
end end
return result..buffer return result..buffer
end end
function STRING.readLine(str) function STRING.readLine(str)
local p=str:find("\n") local p=str:find("\n")
if p then if p then
return str:sub(1,p-1),str:sub(p+1) return str:sub(1,p-1),str:sub(p+1)
else else
return str,"" return str,""
end end
end end
function STRING.packBin(s) 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 end
function STRING.unpackBin(str) function STRING.unpackBin(str)
local res local res
res,str=pcall(data.decode,'string','base64',str) res,str=pcall(data.decode,'string','base64',str)
if not res then return end if not res then return end
res,str=pcall(data.decompress,'string','zlib',str) res,str=pcall(data.decompress,'string','zlib',str)
if res then return str end if res then return str end
end end
function STRING.packText(s) 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 end
function STRING.unpackText(str) function STRING.unpackText(str)
local res local res
res,str=pcall(data.decode,'string','base64',str) res,str=pcall(data.decode,'string','base64',str)
if not res then return end if not res then return end
res,str=pcall(data.decompress,'string','gzip',str) res,str=pcall(data.decompress,'string','gzip',str)
if res then return str end if res then return str end
end end
function STRING.packTable(t) function STRING.packTable(t)
return STRING.packText(JSON.encode(t)) return STRING.packText(JSON.encode(t))
end end
function STRING.unpackTable(t) function STRING.unpackTable(t)
return JSON.decode(STRING.unpackText(t)) return JSON.decode(STRING.unpackText(t))
end end
return STRING return STRING

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -6,18 +6,18 @@ FILETYPE 0x1
{ {
BLOCK "StringFileInfo" BLOCK "StringFileInfo"
{ {
BLOCK "040904B0" BLOCK "040904B0"
{ {
VALUE "FileDescription", "Techmino Alpha" VALUE "FileDescription", "Techmino Alpha"
VALUE "CompanyName", "26F Studio" VALUE "CompanyName", "26F Studio"
VALUE "LegalCopyright", "Copyright @ 26F Studio" VALUE "LegalCopyright", "Copyright @ 26F Studio"
VALUE "ProductName", "Techmino" VALUE "ProductName", "Techmino"
VALUE "ProductVersion", "@Version" VALUE "ProductVersion", "@Version"
} }
} }
BLOCK "VarFileInfo" 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"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>BuildMachineOSBuild</key> <key>BuildMachineOSBuild</key>
<string>19B88</string> <string>19B88</string>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>English</string> <string>English</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>love</string> <string>love</string>
<key>CFBundleIconFile</key> <key>CFBundleIconFile</key>
<string>iconfile</string> <string>iconfile</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
<string>org.love2d.MrZ.Techmino</string> <string>org.love2d.MrZ.Techmino</string>
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleName</key> <key>CFBundleName</key>
<string>Techmino</string> <string>Techmino</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>@versionName</string> <string>@versionName</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>LoVe</string> <string>LoVe</string>
<key>CFBundleSupportedPlatforms</key> <key>CFBundleSupportedPlatforms</key>
<array> <array>
<string>MacOSX</string> <string>MacOSX</string>
</array> </array>
<key>DTCompiler</key> <key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string> <string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key> <key>DTPlatformBuild</key>
<string>11C504</string> <string>11C504</string>
<key>DTPlatformVersion</key> <key>DTPlatformVersion</key>
<string>GM</string> <string>GM</string>
<key>DTSDKBuild</key> <key>DTSDKBuild</key>
<string>19B90</string> <string>19B90</string>
<key>DTSDKName</key> <key>DTSDKName</key>
<string>macosx10.15</string> <string>macosx10.15</string>
<key>DTXcode</key> <key>DTXcode</key>
<string>1130</string> <string>1130</string>
<key>DTXcodeBuild</key> <key>DTXcodeBuild</key>
<string>11C504</string> <string>11C504</string>
<key>LSApplicationCategoryType</key> <key>LSApplicationCategoryType</key>
<string>public.app-category.games</string> <string>public.app-category.games</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>
<string>10.7</string> <string>10.7</string>
<key>NSHighResolutionCapable</key> <key>NSHighResolutionCapable</key>
<true/> <true/>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string>©2020-@thisYear 26F Studio, GNU LGPLv3.0</string> <string>©2020-@thisYear 26F Studio, GNU LGPLv3.0</string>
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>
<string>NSApplication</string> <string>NSApplication</string>
<key>NSSupportsAutomaticGraphicsSwitching</key> <key>NSSupportsAutomaticGraphicsSwitching</key>
<false/> <false/>
</dict> </dict>
</plist> </plist>

View File

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

View File

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

View File

@@ -8,43 +8,43 @@
如果打算自己导入游戏的话需要降噪+裁剪+调整音量后再转为ogg格式 (不支持别的, 因为ogg音质好体积小) 如果打算自己导入游戏的话需要降噪+裁剪+调整音量后再转为ogg格式 (不支持别的, 因为ogg音质好体积小)
目前游戏内正在使用, 必须录制的音频文件名们: 目前游戏内正在使用, 必须录制的音频文件名们:
single, double, triple, techrash (读作\'tekrʌʃ\) single, double, triple, techrash (读作\'tekrʌʃ\)
以上直接念就可以,用于普通直接消行 以上直接念就可以,用于普通直接消行
mini, b2b, b2b2b mini, b2b, b2b2b
以上直接念就可以,用于组合进spin消除 以上直接念就可以,用于组合进spin消除
注: b2b读作back to back 注: b2b读作back to back
[各种spin消除] [各种spin消除]
以上的每一个都要衍生出数条语音,例如zpin的是这五条: 以上的每一个都要衍生出数条语音,例如zpin的是这五条:
z-spin (用于不消行) z-spin (用于不消行)
z-spin single z-spin single
z-spin double z-spin double
z-spin triple z-spin triple
(z-spin techrash) (z-spin techrash)
(z-spin pentacrash) (z-spin pentacrash)
(z-spin hexacrash) (z-spin hexacrash)
对于 S L J T O I 每一个都是这样至少四条语音 对于 S L J T O I 每一个都是这样至少四条语音
加括号一般不用所以可以不录(消5和消6), 加括号一般不用所以可以不录(消5和消6),
对于P, Q, F, E, U, V, W, X, R, Y, N, H 对于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 welcome_voc
进入游戏播放的欢迎语音(类似osu) 进入游戏播放的欢迎语音(类似osu)
目前没有用到但是将要加入的: 目前没有用到但是将要加入的:
split split
未来可能加入的: 未来可能加入的:
暂无 暂无

592
main.lua
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -8,19 +8,19 @@ local colorLib=minoColor
local blocks=BLOCKS local blocks=BLOCKS
local scs=RSlist.TRS.centerPos local scs=RSlist.TRS.centerPos
function back.init() function back.init()
t=rnd()*2600 t=rnd()*2600
end end
function back.update(dt) function back.update(dt)
t=t+dt t=t+dt
end end
function back.draw() function back.draw()
local R=7-int(t*.5%7) local R=7-int(t*.5%7)
local T=1.2-t%15%6%1.8 local T=1.2-t%15%6%1.8
if T<.26 then gc.clear(T,T,T) if T<.26 then gc.clear(T,T,T)
else gc.clear(0,0,0) else gc.clear(0,0,0)
end end
local _=colorLib[SETTING.skin[R]] local _=colorLib[SETTING.skin[R]]
gc.setColor(_[1],_[2],_[3],.12) 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) 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 end
return back return back

View File

@@ -11,21 +11,21 @@ local back={}
local t 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 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() function back.init()
t=math.random()*2600 t=math.random()*2600
end end
function back.update(dt) function back.update(dt)
t=t+dt t=t+dt
end end
function back.draw() function back.draw()
gc_clear(.1,.1,.1) gc_clear(.1,.1,.1)
local k=SCR.k local k=SCR.k
gc_scale(k) gc_scale(k)
local Y=ceil(SCR.h/80/k) local Y=ceil(SCR.h/80/k)
for x=1,ceil(SCR.w/80/k)do for x=1,ceil(SCR.w/80/k)do
for y=1,Y do for y=1,Y do
gc_setColor(1,1,1,sin(x+matrixT[x][y]*t)*.04+.04) gc_setColor(1,1,1,sin(x+matrixT[x][y]*t)*.04+.04)
gc_rectangle('fill',80*x,80*y,-80,-80) gc_rectangle('fill',80*x,80*y,-80,-80)
end end
end end
end end
return back return back

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,151 +1,151 @@
--Complex tables --Complex tables
local function _disableKey(P,key) local function _disableKey(P,key)
table.insert(P.gameEnv.keyCancel,key) table.insert(P.gameEnv.keyCancel,key)
end end
MODOPT={--Mod options MODOPT={--Mod options
{no=0,id="NX",name="next", {no=0,id="NX",name="next",
key="q",x=80,y=230,color='lO', key="q",x=80,y=230,color='lO',
list={0,1,2,3,4,5,6}, list={0,1,2,3,4,5,6},
func=function(P,O)P.gameEnv.nextCount=O end, func=function(P,O)P.gameEnv.nextCount=O end,
unranked=true, unranked=true,
}, },
{no=1,id="HL",name="hold", {no=1,id="HL",name="hold",
key="w",x=200,y=230,color='lO', key="w",x=200,y=230,color='lO',
list={0,1,2,3,4,5,6}, list={0,1,2,3,4,5,6},
func=function(P,O)P.gameEnv.holdCount=O end, func=function(P,O)P.gameEnv.holdCount=O end,
unranked=true, unranked=true,
}, },
{no=2,id="FL",name="hideNext", {no=2,id="FL",name="hideNext",
key="e",x=320,y=230,color='lA', key="e",x=320,y=230,color='lA',
list={1,2,3,4,5}, list={1,2,3,4,5},
func=function(P,O)P.gameEnv.nextStartPos=O+1 end, func=function(P,O)P.gameEnv.nextStartPos=O+1 end,
unranked=true, unranked=true,
}, },
{no=3,id="IH",name="infHold", {no=3,id="IH",name="infHold",
key="r",x=440,y=230,color='lA', key="r",x=440,y=230,color='lA',
func=function(P)P.gameEnv.infHold=true end, func=function(P)P.gameEnv.infHold=true end,
unranked=true, unranked=true,
}, },
{no=4,id="HB",name="hideBlock", {no=4,id="HB",name="hideBlock",
key="y",x=680,y=230,color='lV', key="y",x=680,y=230,color='lV',
func=function(P)P.gameEnv.block=false end, func=function(P)P.gameEnv.block=false end,
unranked=true, unranked=true,
}, },
{no=5,id="HG",name="hideGhost", {no=5,id="HG",name="hideGhost",
key="u",x=800,y=230,color='lV', key="u",x=800,y=230,color='lV',
func=function(P)P.gameEnv.ghost=false end, func=function(P)P.gameEnv.ghost=false end,
unranked=true, unranked=true,
}, },
{no=6,id="HD",name="hidden", {no=6,id="HD",name="hidden",
key="i",x=920,y=230,color='lP', key="i",x=920,y=230,color='lP',
list={'easy','slow','medium','fast','none'}, list={'easy','slow','medium','fast','none'},
func=function(P,O)P.gameEnv.visible=O end, func=function(P,O)P.gameEnv.visible=O end,
unranked=true, unranked=true,
}, },
{no=7,id="HB",name="hideBoard", {no=7,id="HB",name="hideBoard",
key="o",x=1040,y=230,color='lP', key="o",x=1040,y=230,color='lP',
list={'down','up','all'}, list={'down','up','all'},
func=function(P,O)P.gameEnv.hideBoard=O end, func=function(P,O)P.gameEnv.hideBoard=O end,
unranked=true, unranked=true,
}, },
{no=8,id="FB",name="flipBoard", {no=8,id="FB",name="flipBoard",
key="p",x=1160,y=230,color='lJ', key="p",x=1160,y=230,color='lJ',
list={'U-D','L-R','180'}, list={'U-D','L-R','180'},
func=function(P,O)P.gameEnv.flipBoard=O end, func=function(P,O)P.gameEnv.flipBoard=O end,
unranked=true, unranked=true,
}, },
{no=9,id="DT",name="dropDelay", {no=9,id="DT",name="dropDelay",
key="a",x=140,y=350,color='lR', 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}, 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, func=function(P,O)P.gameEnv.drop=O end,
unranked=true, unranked=true,
}, },
{no=10,id="LT",name="lockDelay", {no=10,id="LT",name="lockDelay",
key="s",x=260,y=350,color='lR', 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}, 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, func=function(P,O)P.gameEnv.lock=O end,
unranked=true, unranked=true,
}, },
{no=11,id="ST",name="waitDelay", {no=11,id="ST",name="waitDelay",
key="d",x=380,y=350,color='lR', key="d",x=380,y=350,color='lR',
list={0,1,2,3,4,5,6,7,8,10,15,20,30,60}, list={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
func=function(P,O)P.gameEnv.wait=O end, func=function(P,O)P.gameEnv.wait=O end,
unranked=true, unranked=true,
}, },
{no=12,id="CT",name="fallDelay", {no=12,id="CT",name="fallDelay",
key="f",x=500,y=350,color='lR', key="f",x=500,y=350,color='lR',
list={0,1,2,3,4,5,6,7,8,10,15,20,30,60}, list={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
func=function(P,O)P.gameEnv.fall=O end, func=function(P,O)P.gameEnv.fall=O end,
unranked=true, unranked=true,
}, },
{no=13,id="LF",name="life", {no=13,id="LF",name="life",
key="j",x=860,y=350,color='lY', key="j",x=860,y=350,color='lY',
list={0,1,2,3,5,10,15,26,42,87,500}, list={0,1,2,3,5,10,15,26,42,87,500},
func=function(P,O)P.gameEnv.life=O end, func=function(P,O)P.gameEnv.life=O end,
unranked=true, unranked=true,
}, },
{no=14,id="FB",name="forceB2B", {no=14,id="FB",name="forceB2B",
key="k",x=980,y=350,color='lY', key="k",x=980,y=350,color='lY',
func=function(P)P.gameEnv.b2bKill=true end, func=function(P)P.gameEnv.b2bKill=true end,
unranked=true, unranked=true,
}, },
{no=15,id="PF",name="forceFinesse", {no=15,id="PF",name="forceFinesse",
key="l",x=1100,y=350,color='lY', key="l",x=1100,y=350,color='lY',
func=function(P)P.gameEnv.fineKill=true end, func=function(P)P.gameEnv.fineKill=true end,
unranked=true, unranked=true,
}, },
{no=16,id="TL",name="tele", {no=16,id="TL",name="tele",
key="z",x=200,y=470,color='lH', key="z",x=200,y=470,color='lH',
func=function(P) func=function(P)
P.gameEnv.das,P.gameEnv.arr=0,0 P.gameEnv.das,P.gameEnv.arr=0,0
P.gameEnv.sddas,P.gameEnv.sdarr=0,0 P.gameEnv.sddas,P.gameEnv.sdarr=0,0
end, end,
unranked=true, unranked=true,
}, },
{no=17,id="FX",name="noRotation", {no=17,id="FX",name="noRotation",
key="x",x=320,y=470,color='lH', key="x",x=320,y=470,color='lH',
func=function(P) func=function(P)
_disableKey(P,3) _disableKey(P,3)
_disableKey(P,4) _disableKey(P,4)
_disableKey(P,5) _disableKey(P,5)
end, end,
unranked=true, unranked=true,
}, },
{no=18,id="GL",name="noMove", {no=18,id="GL",name="noMove",
key="c",x=440,y=470,color='lH', key="c",x=440,y=470,color='lH',
func=function(P) func=function(P)
_disableKey(P,1)_disableKey(P,2) _disableKey(P,1)_disableKey(P,2)
_disableKey(P,11)_disableKey(P,12) _disableKey(P,11)_disableKey(P,12)
_disableKey(P,17)_disableKey(P,18) _disableKey(P,17)_disableKey(P,18)
_disableKey(P,19)_disableKey(P,20) _disableKey(P,19)_disableKey(P,20)
end, end,
unranked=true, unranked=true,
}, },
{no=19,id="CS",name="customSeq", {no=19,id="CS",name="customSeq",
key="b",x=680,y=470,color='lB', key="b",x=680,y=470,color='lB',
list={'bag','his','hisPool','c2','rnd','mess','reverb'}, list={'bag','his','hisPool','c2','rnd','mess','reverb'},
func=function(P,O)P.gameEnv.sequence=O end, func=function(P,O)P.gameEnv.sequence=O end,
unranked=true, unranked=true,
}, },
{no=20,id="PS",name="pushSpeed", {no=20,id="PS",name="pushSpeed",
key="n",x=800,y=470,color='lB', key="n",x=800,y=470,color='lB',
list={.5,1,2,3,5,15,1e99}, list={.5,1,2,3,5,15,1e99},
func=function(P,O)P.gameEnv.pushSpeed=O end, func=function(P,O)P.gameEnv.pushSpeed=O end,
unranked=true, unranked=true,
}, },
{no=21,id="BN",name="boneBlock", {no=21,id="BN",name="boneBlock",
key="m",x=920,y=470,color='lB', key="m",x=920,y=470,color='lB',
list={'on','off'}, list={'on','off'},
func=function(P,O)P.gameEnv.bone=O=='on'end, func=function(P,O)P.gameEnv.bone=O=='on'end,
unranked=true, unranked=true,
}, },
} }
for i=1,#MODOPT do for i=1,#MODOPT do
local M=MODOPT[i] local M=MODOPT[i]
M.sel,M.time=0,0 M.sel,M.time=0,0
M.color=COLOR[M.color] M.color=COLOR[M.color]
end end
--Game tables --Game tables
@@ -155,216 +155,216 @@ FIELD={}--Field(s) for custom game
BAG={}--Sequence for custom game BAG={}--Sequence for custom game
MISSION={}--Clearing mission for custom game MISSION={}--Clearing mission for custom game
GAME={--Global game data GAME={--Global game data
playing=false, --If in-game playing=false, --If in-game
init=false, --If need initializing game when enter scene-play init=false, --If need initializing game when enter scene-play
net=false, --If play net game net=false, --If play net game
result=false, --Game result (string) result=false, --Game result (string)
rank=0, --Rank reached rank=0, --Rank reached
pauseTime=0, --Time paused pauseTime=0, --Time paused
pauseCount=0, --Pausing count pauseCount=0, --Pausing count
warnLVL0=0, --Warning level warnLVL0=0, --Warning level
warnLVL=0, --Warning level (show) warnLVL=0, --Warning level (show)
seed=1046101471, --Game seed seed=1046101471, --Game seed
curMode=false, --Current gamemode object curMode=false, --Current gamemode object
mod={}, --List of loaded mods mod={}, --List of loaded mods
modeEnv=false, --Current gamemode environment modeEnv=false, --Current gamemode environment
setting={}, --Game settings setting={}, --Game settings
rep={}, --Recording list, key,time,key,time... rep={}, --Recording list, key,time,key,time...
statSaved=true, --If recording saved statSaved=true, --If recording saved
recording=false, --If recording recording=false, --If recording
replaying=false, --If replaying replaying=false, --If replaying
saved=false, --If recording saved saved=false, --If recording saved
tasUsed=false, --If tasMode used 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 --Data for royale mode
stage=false, --Game stage stage=false, --Game stage
mostBadge=false, --Most badge owner mostBadge=false, --Most badge owner
secBadge=false, --Second badge owner secBadge=false, --Second badge owner
mostDangerous=false,--Most dangerous player mostDangerous=false,--Most dangerous player
secDangerous=false, --Second dangerous player secDangerous=false, --Second dangerous player
} }
ROYALEDATA={ ROYALEDATA={
powerUp=false, powerUp=false,
stage=false, stage=false,
} }
CUSTOMENV={} CUSTOMENV={}
ROOMENV={ ROOMENV={
--Room config --Room config
capacity=10, capacity=10,
--Basic --Basic
drop=30, drop=30,
lock=60, lock=60,
wait=0, wait=0,
fall=0, fall=0,
--Control --Control
nextCount=6, nextCount=6,
holdCount=1, holdCount=1,
infHold=false, infHold=false,
phyHold=false, phyHold=false,
--Visual --Visual
bone=false, bone=false,
--Rule --Rule
life=0, life=0,
pushSpeed=5, pushSpeed=5,
garbageSpeed=2, garbageSpeed=2,
visible='show', visible='show',
freshLimit=15, freshLimit=15,
fieldH=20, fieldH=20,
heightLimit=1e99, heightLimit=1e99,
bufferLimit=1e99, bufferLimit=1e99,
ospin=true, ospin=true,
fineKill=false, fineKill=false,
b2bKill=false, b2bKill=false,
easyFresh=true, easyFresh=true,
deepDrop=false, deepDrop=false,
} }
REPLAY={}--Replay objects (not include stream data) REPLAY={}--Replay objects (not include stream data)
--Userdata tables --Userdata tables
USER={--User infomation USER={--User infomation
--Network infos --Network infos
uid=false, uid=false,
authToken=false, authToken=false,
--Local data --Local data
xp=0,lv=1, xp=0,lv=1,
} }
SETTING={--Settings SETTING={--Settings
--Tuning --Tuning
das=10,arr=2, das=10,arr=2,
dascut=0,dropcut=0, dascut=0,dropcut=0,
sddas=0,sdarr=2, sddas=0,sdarr=2,
ihs=true,irs=true,ims=true, ihs=true,irs=true,ims=true,
RS='TRS', RS='TRS',
swap=true, swap=true,
--System --System
reTime=4, reTime=4,
allowTAS=false, allowTAS=false,
autoPause=true, autoPause=true,
menuPos='middle', menuPos='middle',
fine=false, fine=false,
autoSave=false, autoSave=false,
simpMode=false, simpMode=false,
lang=1, lang=1,
skinSet='crystal_scf', skinSet='crystal_scf',
skin={ skin={
1,7,11,3,14,4,9, 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, 1,7,2,6,10,2,13,5,9,15,10,11,3,12,2,16,8,4,
10,13,2,8 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}, 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 --Graphic
ghostType='gray', ghostType='gray',
block=true,ghost=.3,center=1, block=true,ghost=.3,center=1,
smooth=true,grid=.16,lineNum=.5, smooth=true,grid=.16,lineNum=.5,
upEdge=true, upEdge=true,
bagLine=false, bagLine=false,
lockFX=2, lockFX=2,
dropFX=2, dropFX=2,
moveFX=2, moveFX=2,
clearFX=2, clearFX=2,
splashFX=2, splashFX=2,
shakeFX=2, shakeFX=2,
atkFX=2, atkFX=2,
frameMul=100, frameMul=100,
cleanCanvas=false, cleanCanvas=false,
blockSatur='normal', blockSatur='normal',
fieldSatur='normal', fieldSatur='normal',
text=true, text=true,
score=true, score=true,
bufferWarn=true, bufferWarn=true,
showSpike=true, showSpike=true,
highCam=true, highCam=true,
nextPos=true, nextPos=true,
fullscreen=true, fullscreen=true,
bg=true, bg=true,
powerInfo=false, powerInfo=false,
clickFX=true, clickFX=true,
warn=true, warn=true,
--Sound --Sound
sfx=1, sfx=1,
sfx_spawn=0, sfx_spawn=0,
sfx_warn=.4, sfx_warn=.4,
bgm=.7, bgm=.7,
stereo=.7, stereo=.7,
vib=0, vib=0,
voc=0, voc=0,
cv='miya', cv='miya',
--Virtualkey --Virtualkey
VKSFX=.2,--SFX volume VKSFX=.2,--SFX volume
VKVIB=0,--VIB VKVIB=0,--VIB
VKSwitch=false,--If disp VKSwitch=false,--If disp
VKSkin=1,--If disp VKSkin=1,--If disp
VKTrack=false,--If tracked VKTrack=false,--If tracked
VKDodge=false,--If dodge VKDodge=false,--If dodge
VKTchW=.3,--Touch-Pos Weight VKTchW=.3,--Touch-Pos Weight
VKCurW=.4,--Cur-Pos Weight VKCurW=.4,--Cur-Pos Weight
VKIcon=true,--If disp icon VKIcon=true,--If disp icon
VKAlpha=.3, VKAlpha=.3,
} }
keyMap={--Key setting keyMap={--Key setting
keyboard={ keyboard={
left=1,right=2,x=3,z=4,c=5, left=1,right=2,x=3,z=4,c=5,
up=6,down=7,space=8,a=9,s=10, up=6,down=7,space=8,a=9,s=10,
r=0, r=0,
}, },
joystick={ joystick={
dpleft=1,dpright=2,a=3,b=4,y=5, dpleft=1,dpright=2,a=3,b=4,y=5,
dpup=6,dpdown=7,rightshoulder=8,x=9, dpup=6,dpdown=7,rightshoulder=8,x=9,
leftshoulder=0, leftshoulder=0,
}, },
} }
VK_org={--Virtualkey layout, refresh all VKs' position with this before each game 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=80, y=720-200,r=80},--moveLeft
{ava=true, x=320, y=720-200, r=80},--moveRight {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-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-80, r=80},--rotLeft
{ava=true, x=1280-200, y=720-320, r=80},--rot180 {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-320,r=80},--hardDrop
{ava=true, x=200, y=720-80, r=80},--softDrop {ava=true, x=200, y=720-80, r=80},--softDrop
{ava=true, x=1280-320, y=720-200, r=80},--hold {ava=true, x=1280-320,y=720-200,r=80},--hold
{ava=true, x=80, y=280, r=80},--func1 {ava=true, x=80, y=280, r=80},--func1
{ava=true, x=1280-80, y=280, r=80},--func2 {ava=true, x=1280-80, y=280, r=80},--func2
{ava=false, x=670, y=50, r=30},--insLeft {ava=false, x=670, y=50, r=30},--insLeft
{ava=false, x=730, y=50, r=30},--insRight {ava=false, x=730, y=50, r=30},--insRight
{ava=false, x=790, y=50, r=30},--insDown {ava=false, x=790, y=50, r=30},--insDown
{ava=false, x=850, y=50, r=30},--down1 {ava=false, x=850, y=50, r=30},--down1
{ava=false, x=910, y=50, r=30},--down4 {ava=false, x=910, y=50, r=30},--down4
{ava=false, x=970, y=50, r=30},--down10 {ava=false, x=970, y=50, r=30},--down10
{ava=false, x=1030, y=50, r=30},--dropLeft {ava=false, x=1030, y=50, r=30},--dropLeft
{ava=false, x=1090, y=50, r=30},--dropRight {ava=false, x=1090, y=50, r=30},--dropRight
{ava=false, x=1150, y=50, r=30},--zangiLeft {ava=false, x=1150, y=50, r=30},--zangiLeft
{ava=false, x=1210, y=50, r=30},--zangiRight {ava=false, x=1210, y=50, r=30},--zangiRight
} }
RANKS={sprint_10l=0}--Ranks of modes RANKS={sprint_10l=0}--Ranks of modes
STAT={ STAT={
version=VERSION.code, version=VERSION.code,
run=0,game=0,time=0,frame=0, run=0,game=0,time=0,frame=0,
key=0,rotate=0,hold=0, key=0,rotate=0,hold=0,
extraPiece=0,finesseRate=0, extraPiece=0,finesseRate=0,
piece=0,row=0,dig=0, piece=0,row=0,dig=0,
atk=0,digatk=0, atk=0,digatk=0,
send=0,recv=0,pend=0,off=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)(), 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)(), 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, pc=0,hpc=0,b2b=0,b3b=0,score=0,
lastPlay='sprint_10l',--Last played mode ID lastPlay='sprint_10l',--Last played mode ID
date=false, date=false,
todayTime=0, 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{ return{
loadText={ loadText={
loadSFX="音效", loadSFX="音效",
loadVoice="语音", loadVoice="语音",
loadFont="字体", loadFont="字体",
loadModeIcon="模式图标", loadModeIcon="模式图标",
loadMode="模式", loadMode="模式",
loadOther="其他", loadOther="其他",
finish="走你", finish="走你",
}, },
playedLong="今天玩很久了,给我注意点", playedLong="今天玩很久了,给我注意点",
playedTooMuch="特么再玩小心眼睛瞎掉,爬", playedTooMuch="特么再玩小心眼睛瞎掉,爬",
royale_remain="剩 $1 人", 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"}, cmb={nil,"1连","2连","3连","4连","5连","6连","7连","8连","9连","10连!","11连!","12连!","13连!","14连!","15连!","16连!","17连!","18连!","19连!","MEGACMB"},
spin="", spin="",
clear={"消一","消二","消三","消四","卧槽","离谱"}, clear={"消一","消二","消三","消四","卧槽","离谱"},
mini="",b2b="牛逼",b3b="很牛逼", mini="",b2b="牛逼",b3b="很牛逼",
PC="消干净了",HPC="消挺干净", PC="消干净了",HPC="消挺干净",
great="不错的", great="不错的",
awesome="您很强", awesome="您很强",
almost="太舒服了", almost="太舒服了",
continue="您继续", continue="您继续",
maxspeed="速度封顶", maxspeed="速度封顶",
speedLV="速度等级", speedLV="速度等级",
piece="块数",line="行数",atk="",eff="", piece="块数",line="行数",atk="",eff="",
rpm="收每分",tsd="T2", rpm="收每分",tsd="T2",
grade="段位",techrash="消四", grade="段位",techrash="消四",
wave="波数",nextWave="下一波", wave="波数",nextWave="下一波",
combo="连击",maxcmb="最大连", combo="连击",maxcmb="最大连",
pc="消干净了",ko="淘汰", pc="消干净了",ko="淘汰",
win="好了", win="好了",
lose="挂了", lose="挂了",
finish="好厉害呀 真帅气呢", finish="好厉害呀 真帅气呢",
gamewin="成了", gamewin="成了",
gameover="没了", gameover="没了",
pause="歇会", pause="歇会",
pauseCount="歇多久了", pauseCount="歇多久了",
finesse_ap="", finesse_ap="",
finesse_fc="全连", finesse_fc="全连",
noUsername="别闹。", noUsername="别闹。",
wrongEmail="别乱输。", wrongEmail="别乱输。",
noPassword="注册会不会?", noPassword="注册会不会?",
diffPassword="字不认识?", diffPassword="字不认识?",
ranks={"","","","",""}, ranks={"","","","",""},
createRoomSuccessed="创好了", createRoomSuccessed="创好了",
started="开了", started="开了",
spectating="看戏中", spectating="看戏中",
stat={ stat={
"开了几次:", "开了几次:",
"玩了几把:", "玩了几把:",
"玩了多久:", "玩了多久:",
"按键/旋转/暂存:", "按键/旋转/暂存:",
"方块/消行/攻击:", "方块/消行/攻击:",
"接收/抵消/上涨:", "接收/抵消/上涨:",
"挖掘/挖掘攻击:", "挖掘/挖掘攻击:",
"效率/挖掘效率:", "效率/挖掘效率:",
"牛逼/很牛逼:", "牛逼/很牛逼:",
"消光/消半截:", "消光/消半截:",
"多余操作/极简率:", "多余操作/极简率:",
}, },
WidgetText={ WidgetText={
setting_game={ setting_game={
title="游戏设置", title="游戏设置",
graphic="←改画面", graphic="←改画面",
sound="改声音→", sound="改声音→",
ctrl="改控制", ctrl="改控制",
key="改键位", key="改键位",
touch="改触屏", touch="改触屏",
}, },
setting_video={ setting_video={
title="改画面", title="改画面",
sound="←改声音", sound="←改声音",
game="游戏设置→", game="游戏设置→",
block="方块可见", block="方块可见",
ghost="阴影", ghost="阴影",
center="中心", center="中心",
lineNum="行号", lineNum="行号",
text="招式名", text="招式名",
score="跳分", score="跳分",
warn="要死", warn="要死",
highCam="拉镜", highCam="拉镜",
}, },
setting_sound={ setting_sound={
title="改声音", title="改声音",
game="←游戏设置", game="←游戏设置",
graphic="改画面→", graphic="改画面→",
bgm="", bgm="",
spawn="出块", spawn="出块",
warn="警告", warn="警告",
vib="嗡嗡", vib="嗡嗡",
cv="", cv="",
}, },
setting_control={ setting_control={
title="改控制", title="改控制",
reset="重设", reset="重设",
}, },
setting_skin={ setting_skin={
skinSet="皮肤", skinSet="皮肤",
title="改外观", title="改外观",
}, },
setting_touchSwitch={ setting_touchSwitch={
basic="阳间", basic="阳间",
pro="阴间", pro="阴间",
}, },
about={ about={
staff="游戏谁写的", staff="游戏谁写的",
his="黑历史", his="黑历史",
qq="QQ对线", qq="QQ对线",
}, },
register={ register={
password2="你懂的", password2="你懂的",
registering="", registering="",
}, },
sound={ sound={
title="音效室", title="音效室",
sfx="音效", sfx="音效",
voc="语音", voc="语音",
hold="暂存", hold="暂存",
prehold="提前暂存", prehold="提前暂存",
_pc="消干净了", _pc="消干净了",
spin0="空旋转", spin0="空旋转",
spin1="旋转消一", spin1="旋转消一",
spin2="旋转消二", spin2="旋转消二",
spin3="旋转消三", spin3="旋转消三",
z0="Z旋", z0="Z旋",
z1="Z旋消一", z1="Z旋消一",
z2="Z旋消二", z2="Z旋消二",
z3="Z旋消三", z3="Z旋消三",
s0="S旋", s0="S旋",
s1="S旋消一", s1="S旋消一",
s2="S旋消二", s2="S旋消二",
s3="S旋消三", s3="S旋消三",
j0="J旋", j0="J旋",
j1="J旋消一", j1="J旋消一",
j2="J旋消二", j2="J旋消二",
j3="J旋消三", j3="J旋消三",
l0="L旋", l0="L旋",
l1="L旋消一", l1="L旋消一",
l2="L旋消二", l2="L旋消二",
l3="L旋消三", l3="L旋消三",
t0="T旋", t0="T旋",
t1="T旋消一", t1="T旋消一",
t2="T旋消二", t2="T旋消二",
t3="T旋消三", t3="T旋消三",
o0="O旋", o0="O旋",
o1="O旋消一", o1="O旋消一",
o2="O旋消二", o2="O旋消二",
o3="O旋消三", o3="O旋消三",
i0="I旋", i0="I旋",
i1="I旋消一", i1="I旋消一",
i2="I旋消二", i2="I旋消二",
i3="I旋消三", i3="I旋消三",
mini="", mini="",
b2b="牛逼", b2b="牛逼",
b3b="很牛逼", b3b="很牛逼",
pc="消干净了", pc="消干净了",
}, },
app_15p={ app_15p={
reset="打乱", reset="打乱",
color="", color="",
blind="", blind="",
slide="滑动", slide="滑动",
pathVis="路径显示", pathVis="路径显示",
revKB="键盘反向", revKB="键盘反向",
}, },
app_schulteG={ app_schulteG={
reset="重开", reset="重开",
rank="尺寸", rank="尺寸",
blind="", blind="",
disappear="消失", disappear="消失",
tapFX="动画", tapFX="动画",
}, },
savedata={ savedata={
export="复制走", export="复制走",
import="粘贴到", import="粘贴到",
unlock="地图", unlock="地图",
data="统计", data="统计",
setting="设置", setting="设置",
vk="虚拟按键", vk="虚拟按键",
couldSave="云存档(测试,炸了别怪我)", couldSave="云存档(测试,炸了别怪我)",
notLogin="[不登录存个锤子]", notLogin="[不登录存个锤子]",
upload="上传", upload="上传",
download="下载", download="下载",
}, },
}, },
modes={ modes={
['sprint_10l']= {"竞速", "10L", "消10行"}, ['sprint_10l']= {"竞速", "10L", "消10行"},
['sprint_20l']= {"竞速", "20L", "消20行"}, ['sprint_20l']= {"竞速", "20L", "消20行"},
['sprint_40l']= {"竞速", "40L", "消40行"}, ['sprint_40l']= {"竞速", "40L", "消40行"},
['sprint_100l']= {"竞速", "100L", "消100行"}, ['sprint_100l']= {"竞速", "100L", "消100行"},
['sprint_400l']= {"竞速", "400L", "消400行"}, ['sprint_400l']= {"竞速", "400L", "消400行"},
['sprint_1000l']= {"竞速", "1000L", "消1000行"}, ['sprint_1000l']= {"竞速", "1000L", "消1000行"},
['sprintPenta']= {"竞速", "五连块", "离谱"}, ['sprintPenta']= {"竞速", "五连块", "离谱"},
['sprintMPH']= {"竞速", "纯净", "听说你反应很快?"}, ['sprintMPH']= {"竞速", "纯净", "听说你反应很快?"},
['dig_10l']= {"挖掘", "10L", "挖10行"}, ['dig_10l']= {"挖掘", "10L", "挖10行"},
['dig_40l']= {"挖掘", "40L", "挖40行"}, ['dig_40l']= {"挖掘", "40L", "挖40行"},
['dig_100l']= {"挖掘", "100L", "挖100行"}, ['dig_100l']= {"挖掘", "100L", "挖100行"},
['dig_400l']= {"挖掘", "400L", "挖400行"}, ['dig_400l']= {"挖掘", "400L", "挖400行"},
['dig_1000l']= {"挖掘", "1000L", "挖1000行"}, ['dig_1000l']= {"挖掘", "1000L", "挖1000行"},
['drought_n']= {"干旱", "100L", "放轻松,简单得很"}, ['drought_n']= {"干旱", "100L", "放轻松,简单得很"},
['drought_l']= {"干旱+", "100L", "有趣的要来了"}, ['drought_l']= {"干旱+", "100L", "有趣的要来了"},
['stack_e']= {"堆叠", "简单", "智力启蒙玩具(确信"}, ['stack_e']= {"堆叠", "简单", "智力启蒙玩具(确信"},
['stack_h']= {"堆叠", "困难", "智力启蒙玩具(确信"}, ['stack_h']= {"堆叠", "困难", "智力启蒙玩具(确信"},
['stack_u']= {"堆叠", "极限", "智力启蒙玩具(确信"}, ['stack_u']= {"堆叠", "极限", "智力启蒙玩具(确信"},
['marathon_n']= {"马拉松", "普通", "休闲模式"}, ['marathon_n']= {"马拉松", "普通", "休闲模式"},
['marathon_h']= {"马拉松", "困难", "休闲模式"}, ['marathon_h']= {"马拉松", "困难", "休闲模式"},
['solo_e']= {"单挑", "简单", "鲨AI"}, ['solo_e']= {"单挑", "简单", "鲨AI"},
['solo_n']= {"单挑", "普通", "鲨AI"}, ['solo_n']= {"单挑", "普通", "鲨AI"},
['solo_h']= {"单挑", "困难", "鲨AI"}, ['solo_h']= {"单挑", "困难", "鲨AI"},
['solo_l']= {"单挑", "疯狂", "鲨AI"}, ['solo_l']= {"单挑", "疯狂", "鲨AI"},
['solo_u']= {"单挑", "极限", "鲨AI"}, ['solo_u']= {"单挑", "极限", "鲨AI"},
['techmino49_e']= {"49人混战", "简单", "这我岂不是乱鲨"}, ['techmino49_e']= {"49人混战", "简单", "这我岂不是乱鲨"},
['techmino49_h']= {"49人混战", "困难", "这我岂不是乱鲨"}, ['techmino49_h']= {"49人混战", "困难", "这我岂不是乱鲨"},
['techmino49_u']= {"49人混战", "极限", "你吃鸡率多少?"}, ['techmino49_u']= {"49人混战", "极限", "你吃鸡率多少?"},
['techmino99_e']= {"99人混战", "简单", "这我岂不是乱鲨"}, ['techmino99_e']= {"99人混战", "简单", "这我岂不是乱鲨"},
['techmino99_h']= {"99人混战", "困难", "这我岂不是乱鲨"}, ['techmino99_h']= {"99人混战", "困难", "这我岂不是乱鲨"},
['techmino99_u']= {"99人混战", "极限", "你吃鸡率多少?"}, ['techmino99_u']= {"99人混战", "极限", "你吃鸡率多少?"},
['round_e']= {"回合制", "简单", "下棋"}, ['round_e']= {"回合制", "简单", "下棋"},
['round_n']= {"回合制", "普通", "下棋"}, ['round_n']= {"回合制", "普通", "下棋"},
['round_h']= {"回合制", "困难", "下棋"}, ['round_h']= {"回合制", "困难", "下棋"},
['round_l']= {"回合制", "疯狂", "下棋"}, ['round_l']= {"回合制", "疯狂", "下棋"},
['round_u']= {"回合制", "极限", "下棋"}, ['round_u']= {"回合制", "极限", "下棋"},
['master_n']= {"大师", "普通", "无脑20G"}, ['master_n']= {"大师", "普通", "无脑20G"},
['master_h']= {"大师", "困难", "简单20G"}, ['master_h']= {"大师", "困难", "简单20G"},
['master_final']= {"大师", "终点", "究极20G:真正的游戏"}, ['master_final']= {"大师", "终点", "究极20G:真正的游戏"},
['master_ph']= {"大师", "虚幻", "虚幻20G:好玩"}, ['master_ph']= {"大师", "虚幻", "虚幻20G:好玩"},
['master_ex']= {"宗师", "EX", "你行你上"}, ['master_ex']= {"宗师", "EX", "你行你上"},
['rhythm_e']= {"节奏", "简单", "很无聊的"}, ['rhythm_e']= {"节奏", "简单", "很无聊的"},
['rhythm_h']= {"节奏", "困难", "好玩么?"}, ['rhythm_h']= {"节奏", "困难", "好玩么?"},
['rhythm_u']= {"节奏", "极限", "真男人不玩低难度"}, ['rhythm_u']= {"节奏", "极限", "真男人不玩低难度"},
['blind_e']= {"隐形", "半隐", "谁都能玩"}, ['blind_e']= {"隐形", "半隐", "谁都能玩"},
['blind_n']= {"隐形", "全隐", "稍加练习即可"}, ['blind_n']= {"隐形", "全隐", "稍加练习即可"},
['blind_h']= {"隐形", "瞬隐", "和上一个一样"}, ['blind_h']= {"隐形", "瞬隐", "和上一个一样"},
['blind_l']= {"隐形", "瞬隐+", "这个确实挺难的"}, ['blind_l']= {"隐形", "瞬隐+", "这个确实挺难的"},
['blind_u']= {"隐形", "啊这", "你准备好了吗"}, ['blind_u']= {"隐形", "啊这", "你准备好了吗"},
['blind_wtf']= {"隐形", "不会吧", "还没准备好"}, ['blind_wtf']= {"隐形", "不会吧", "还没准备好"},
['classic_fast']= {"高速经典", "CTWC", "就这?简单"}, ['classic_fast']= {"高速经典", "CTWC", "就这?简单"},
['survivor_e']= {"生存", "简单", "这都玩不下去?不会吧"}, ['survivor_e']= {"生存", "简单", "这都玩不下去?不会吧"},
['survivor_n']= {"生存", "普通", "呵,这都玩不过?"}, ['survivor_n']= {"生存", "普通", "呵,这都玩不过?"},
['survivor_h']= {"生存", "困难", "所以呢?"}, ['survivor_h']= {"生存", "困难", "所以呢?"},
['survivor_l']= {"生存", "疯狂", "然后呢?"}, ['survivor_l']= {"生存", "疯狂", "然后呢?"},
['survivor_u']= {"生存", "极限", "舒服了"}, ['survivor_u']= {"生存", "极限", "舒服了"},
['attacker_h']= {"进攻", "困难", "进攻练习"}, ['attacker_h']= {"进攻", "困难", "进攻练习"},
['attacker_u']= {"进攻", "极限", "进攻练习"}, ['attacker_u']= {"进攻", "极限", "进攻练习"},
['defender_n']= {"防守", "普通", "防守练习"}, ['defender_n']= {"防守", "普通", "防守练习"},
['defender_l']= {"防守", "疯狂", "防守练习"}, ['defender_l']= {"防守", "疯狂", "防守练习"},
['dig_h']= {"挖掘", "困难", "挖掘练习"}, ['dig_h']= {"挖掘", "困难", "挖掘练习"},
['dig_u']= {"挖掘", "极限", "挖掘练习"}, ['dig_u']= {"挖掘", "极限", "挖掘练习"},
['bigbang']= {"大爆炸", "简单", "All-spin 入门教程\n施工中"}, ['bigbang']= {"大爆炸", "简单", "All-spin 入门教程\n施工中"},
['c4wtrain_n']= {"C4W练习", "普通", "无 限 连 击"}, ['c4wtrain_n']= {"C4W练习", "普通", "无 限 连 击"},
['c4wtrain_l']= {"C4W练习", "疯狂", "无 限 连 击"}, ['c4wtrain_l']= {"C4W练习", "疯狂", "无 限 连 击"},
['pctrain_n']= {"全清训练", "普通", "随便打打"}, ['pctrain_n']= {"全清训练", "普通", "随便打打"},
['pctrain_l']= {"全清训练", "疯狂", "建议不打"}, ['pctrain_l']= {"全清训练", "疯狂", "建议不打"},
['pc_n']= {"全清挑战", "普通", "100行内刷PC"}, ['pc_n']= {"全清挑战", "普通", "100行内刷PC"},
['pc_h']= {"全清挑战", "困难", "100行内刷PC"}, ['pc_h']= {"全清挑战", "困难", "100行内刷PC"},
['pc_l']= {"全清挑战", "疯狂", "100行内刷PC"}, ['pc_l']= {"全清挑战", "疯狂", "100行内刷PC"},
['pc_inf']= {"无尽全清挑战", "", "你这水平还是先别玩了"}, ['pc_inf']= {"无尽全清挑战", "", "你这水平还是先别玩了"},
['tech_n']= {"科研", "普通", "禁止断B2B"}, ['tech_n']= {"科研", "普通", "禁止断B2B"},
['tech_n_plus']= {"科研", "普通+", "仅允许spin与PC"}, ['tech_n_plus']= {"科研", "普通+", "仅允许spin与PC"},
['tech_h']= {"科研", "困难", "禁止断B2B"}, ['tech_h']= {"科研", "困难", "禁止断B2B"},
['tech_h_plus']= {"科研", "困难+", "仅允许spin与PC"}, ['tech_h_plus']= {"科研", "困难+", "仅允许spin与PC"},
['tech_l']= {"科研", "疯狂", "禁止断B2B"}, ['tech_l']= {"科研", "疯狂", "禁止断B2B"},
['tech_l_plus']= {"科研", "疯狂+", "仅允许spin与PC"}, ['tech_l_plus']= {"科研", "疯狂+", "仅允许spin与PC"},
['tech_finesse']= {"科研", "极简", "强制最简操作"}, ['tech_finesse']= {"科研", "极简", "强制最简操作"},
['tech_finesse_f']= {"科研", "极简+", "禁止普通消除,强制最简操作"}, ['tech_finesse_f']= {"科研", "极简+", "禁止普通消除,强制最简操作"},
['tsd_e']= {"TSD挑战", "简单", "刷T2"}, ['tsd_e']= {"TSD挑战", "简单", "刷T2"},
['tsd_h']= {"TSD挑战", "困难", "刷T2"}, ['tsd_h']= {"TSD挑战", "困难", "刷T2"},
['tsd_u']= {"TSD挑战", "极限", "刷T2"}, ['tsd_u']= {"TSD挑战", "极限", "刷T2"},
['backfire_n']= {"自攻自受", "普通", "100攻击很少的,冲冲冲"}, ['backfire_n']= {"自攻自受", "普通", "100攻击很少的,冲冲冲"},
['backfire_h']= {"自攻自受", "困难", "你在害怕什么"}, ['backfire_h']= {"自攻自受", "困难", "你在害怕什么"},
['backfire_l']= {"自攻自受", "疯狂", "别怂啊,打攻击呀"}, ['backfire_l']= {"自攻自受", "疯狂", "别怂啊,打攻击呀"},
['backfire_u']= {"自攻自受", "极限", "能把自己玩死,不会吧"}, ['backfire_u']= {"自攻自受", "极限", "能把自己玩死,不会吧"},
['sprintAtk']= {"竞速", "100攻击", "送100行"}, ['sprintAtk']= {"竞速", "100攻击", "送100行"},
['zen']= {"", "200", "不限时200行"}, ['zen']= {"", "200", "不限时200行"},
['ultra']= {"限时打分", "挑战", "2分钟刷分"}, ['ultra']= {"限时打分", "挑战", "2分钟刷分"},
['infinite']= {"无尽", "", "真的有人会玩这个?"}, ['infinite']= {"无尽", "", "真的有人会玩这个?"},
['infinite_dig']= {"无尽:挖掘", "", "闲得慌就来挖"}, ['infinite_dig']= {"无尽:挖掘", "", "闲得慌就来挖"},
['sprintFix']= {"竞速", "无移动"}, ['sprintFix']= {"竞速", "无移动"},
['sprintLock']= {"竞速", "无旋转"}, ['sprintLock']= {"竞速", "无旋转"},
['sprintSmooth']= {"竞速", "无摩擦"}, ['sprintSmooth']= {"竞速", "无摩擦"},
['marathon_bfmax']= {"马拉松", "极限"}, ['marathon_bfmax']= {"马拉松", "极限"},
['master_l']= {"大师", "疯狂"}, ['master_l']= {"大师", "疯狂"},
['master_u']= {"大师", "极限"}, ['master_u']= {"大师", "极限"},
['custom_clear']= {"自定义", "普通"}, ['custom_clear']= {"自定义", "普通"},
['custom_puzzle']= {"自定义", "拼图"}, ['custom_puzzle']= {"自定义", "拼图"},
}, },
} }

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -1,92 +1,92 @@
return STRING.split([=[ return STRING.split([=[
Gameplay: Gameplay:
The system will provide you with tetrominoes (4-block pieces), The system will provide you with tetrominoes (4-block pieces),
with a total of 7 types, and the player needs to control them with a total of 7 types, and the player needs to control them
(move left and right, rotate 90, 180 or 270 degrees). (move left and right, rotate 90, 180 or 270 degrees).
each row filled with the field will be cleared. 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 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. Play until the end or achieve the level's goal to win.
Rotation system: 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: Spin detection:
Satisfies "3 corner" rule +2 points Satisfies "3 corner" rule +2 points
Satisfies "immobile" rule +2 points Satisfies "immobile" rule +2 points
- As long as one of the above is true, it is a Spin - 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 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. - 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: Attack system:
Normal line clears (1 to 3 lines): Normal line clears (1 to 3 lines):
Sends (lines cleared -0.5) attack Sends (lines cleared -0.5) attack
Special line clears: Special line clears:
Spin sends (lines cleared x2) attack, Spin sends (lines cleared x2) attack,
- B2B sends extra 1/1/2/4/8 for Spin Single/Double/Triple/Techrash/Techrash+ - 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 - B2B2B sends (lines cleared x0.5), and +1 extra blocking
- Minis reduces the attack to 25% (x0.25 multiplier) - Minis reduces the attack to 25% (x0.25 multiplier)
Non-Spin Techrash/Techrash+ sends (lines cleared) attack, Non-Spin Techrash/Techrash+ sends (lines cleared) attack,
- B2B sends 1 additional line - B2B sends 1 additional line
- B2B2B will have an attack boost of 50% and +1 extra blocking - 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): 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 Attack +4, Extra Blocking +2
Perfect Clear (aka All Clear): 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, 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. 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), 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. +1 more attack for 3 Combo or more.
After calculating all above, the damage value will be rounded down then sent After calculating all above, the damage value will be rounded down then sent
Score system: Score system:
The better you play, the higher the score. The better you play, the higher the score.
Attack delay: Attack delay:
Attacks from Doubles/Triples take effect the fastest; Attacks from Doubles/Triples take effect the fastest;
Followed by Techrash, Spins, which send slower attacks; Followed by Techrash, Spins, which send slower attacks;
High combos are the slowest; High combos are the slowest;
For B2B or B2B2B, they also increase the attack delay while they increase lines sent; For B2B or B2B2B, they also increase the attack delay while they increase lines sent;
Minis will greatly increase the delay. Minis will greatly increase the delay.
Countering: Countering:
When you send attacks, if there is garbage in queue, 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. 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. 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: 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. 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 A regular line clear -250
Spin Single/Double/Triple/Techrash/Techrash+ + 50/100/180/800/1000 (x50% if Mini) Spin Single/Double/Triple/Techrash/Techrash+ + 50/100/180/800/1000 (x50% if Mini)
Techrash/Techrash+ + 150/200/... Techrash/Techrash+ + 150/200/...
PC when lines cleared in this round >4, +800 PC when lines cleared in this round >4, +800
Hemi-PC, +100 Hemi-PC, +100
Spin (0 lines) +20. Do note that the B2B gauge cannot exceed 800 using this method. 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 When gauge is above 800, a drop without clearing lines decreases it by 40, but cannot drop below 800
Battle Royale modes: Battle Royale modes:
Many players play a game at the same time (against AI bots, not real players). 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. 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. Eliminate other players to gain a badge and the player's badge to increase your attack power.
Players can choose between four attack modes: Players can choose between four attack modes:
1. Random: Every time you attack, 10% chance to lock onto a random player. 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. 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) 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. 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). 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. When all opponents have been eliminated, the last player in the match is the winner.
Custom mode: Custom mode:
You can freely adjust most parameters (not including special effects of other game modes). 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. 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: In build (puzzle) mode, you can toggle template display with Function key:
Cells with a X cannot have blocks; Cells with a X cannot have blocks;
empty cells can be in any state; empty cells can be in any state;
regular colored cells have to be made of the corresponding block; regular colored cells have to be made of the corresponding block;
garbage-colored cells can be any block but not air. garbage-colored cells can be any block but not air.
Once you make the shape, you will win. Once you make the shape, you will win.
]=],"\n") ]=],"\n")

View File

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

View File

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

View File

@@ -1,132 +1,132 @@
return{ return{
{name='sprint_10l', x=0, y=0, size=40,shape=1,icon="sprint1", unlock={'sprint_20l','sprint_40l'}}, {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_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_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_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_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_1000l', x=-600, y=0, size=40,shape=1,icon="sprint3"},
{name='sprintPenta', x=210, y=-370, 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='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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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='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_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_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='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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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='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_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='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_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_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_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_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_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_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', 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_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', 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_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', 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_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', 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_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_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_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_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_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_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_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_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='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='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', x=-1000, y=-400, size=40,shape=1,icon='infinite'},
{name='infinite_dig', x=-800, y=-400, size=40,shape=1,icon="dig"}, {name='infinite_dig', x=-800, y=-400, size=40,shape=1,icon="dig"},
--Secret --Secret
{name='sprintFix'}, {name='sprintFix'},
{name='sprintLock'}, {name='sprintLock'},
{name='sprintSmooth'}, {name='sprintSmooth'},
{name='marathon_bfmax'}, {name='marathon_bfmax'},
--Old --Old
{name='master_l'}, {name='master_l'},
{name='master_u'}, {name='master_u'},
--Special --Special
{name='custom_puzzle'}, {name='custom_puzzle'},
{name='custom_clear'}, {name='custom_clear'},
{name="netBattle"}, {name="netBattle"},
} }

View File

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

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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