Compare commits
56 Commits
pre0.17.0-
...
pre0.17.0-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8b12fc55d | ||
|
|
6d11367ea4 | ||
|
|
eb9e741b4f | ||
|
|
c47546d501 | ||
|
|
11aa178fc1 | ||
|
|
f3a88ef269 | ||
|
|
720dc2131f | ||
|
|
701ef17ae1 | ||
|
|
1a689a5f07 | ||
|
|
ef12ab0cee | ||
|
|
3d26db7a01 | ||
|
|
dd3df9981b | ||
|
|
5d04e83529 | ||
|
|
7ed4626d71 | ||
|
|
ecf5a29a71 | ||
|
|
1a24b346a0 | ||
|
|
72d06c7a02 | ||
|
|
26fde8c694 | ||
|
|
8adeb99be7 | ||
|
|
c92f15156b | ||
|
|
63f69d712b | ||
|
|
55a1bd06f3 | ||
|
|
6a29abf7f0 | ||
|
|
83bdd9f2c4 | ||
|
|
95879827c8 | ||
|
|
2ade518207 | ||
|
|
36c8449e4d | ||
|
|
3c04df69f3 | ||
|
|
1224ee9a67 | ||
|
|
fdd1d4463a | ||
|
|
940ac3736c | ||
|
|
d38897b54d | ||
|
|
90848c6654 | ||
|
|
0220d5aefc | ||
|
|
f42032df07 | ||
|
|
05d7eb60bc | ||
|
|
942416317c | ||
|
|
576de945fb | ||
|
|
8b02084428 | ||
|
|
9f666d69db | ||
|
|
a4c52d9162 | ||
|
|
592b11366e | ||
|
|
07f50b9243 | ||
|
|
ec74d55686 | ||
|
|
4518513e87 | ||
|
|
7df4e2144f | ||
|
|
7f9c9248ce | ||
|
|
9c1db48804 | ||
|
|
0628830f0c | ||
|
|
9436f2f5fb | ||
|
|
c5e1b5617f | ||
|
|
298c417aa3 | ||
|
|
fc74831700 | ||
|
|
d9db55de44 | ||
|
|
3fd205e8c2 | ||
|
|
5cb828fb92 |
@@ -1,4 +1,6 @@
|
||||
local Sources={}
|
||||
local lastLoaded={}
|
||||
local maxLoadedCount=3
|
||||
local SourceObjList={}
|
||||
local volume=1
|
||||
|
||||
local BGM={
|
||||
@@ -37,15 +39,41 @@ end
|
||||
local function check_curFadeOut(task,code,src)
|
||||
return task.code==code and task.args[1]==src
|
||||
end
|
||||
local function _tryReleaseSources()
|
||||
local n=#lastLoaded
|
||||
while #lastLoaded>maxLoadedCount do
|
||||
local name=lastLoaded[n]
|
||||
if SourceObjList[name].source:isPlaying()then
|
||||
n=n-1
|
||||
if n<=0 then return end
|
||||
else
|
||||
SourceObjList[name].source=SourceObjList[name].source:release()and nil
|
||||
table.remove(lastLoaded,n)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
function BGM.setDefault(bgm)
|
||||
BGM.default=bgm
|
||||
end
|
||||
function BGM.setMaxSources(count)
|
||||
maxLoadedCount=count
|
||||
_tryReleaseSources()
|
||||
end
|
||||
function BGM.setChange(func)
|
||||
BGM.onChange=func
|
||||
end
|
||||
function BGM.setVol(v)
|
||||
assert(type(v)=='number'and v>=0 and v<=1)
|
||||
assert(type(v)=='number'and v>=0 and v<=1,'Wrong volume')
|
||||
volume=v
|
||||
if BGM.playing then
|
||||
if volume>0 then
|
||||
BGM.playing:setVolume(volume)
|
||||
BGM.playing:play()
|
||||
elseif BGM.nowPlay then
|
||||
BGM.playing:pause()
|
||||
end
|
||||
end
|
||||
end
|
||||
function BGM.init(list)
|
||||
BGM.init=nil
|
||||
@@ -53,7 +81,7 @@ function BGM.init(list)
|
||||
local simpList={}
|
||||
for _,v in next,list do
|
||||
table.insert(simpList,v.name)
|
||||
Sources[v.name]=v.path
|
||||
SourceObjList[v.name]={path=v.path,source=false}
|
||||
end
|
||||
table.sort(simpList)
|
||||
function BGM.getList()return simpList end
|
||||
@@ -61,58 +89,43 @@ function BGM.init(list)
|
||||
LOG(count.." BGM files added")
|
||||
function BGM.getCount()return count end
|
||||
|
||||
local function _load(name)
|
||||
if type(Sources[name])=='string'then
|
||||
if love.filesystem.getInfo(Sources[name])then
|
||||
Sources[name]=love.audio.newSource(Sources[name],'stream')
|
||||
Sources[name]:setLooping(true)
|
||||
Sources[name]:setVolume(0)
|
||||
local function _tryLoad(name)
|
||||
if SourceObjList[name]then
|
||||
if SourceObjList[name].source then
|
||||
return true
|
||||
elseif love.filesystem.getInfo(SourceObjList[name].path)then
|
||||
SourceObjList[name].source=love.audio.newSource(SourceObjList[name].path,'stream')
|
||||
SourceObjList[name].source:setLooping(true)
|
||||
SourceObjList[name].source:setVolume(0)
|
||||
table.insert(lastLoaded,1,name)
|
||||
_tryReleaseSources()
|
||||
return true
|
||||
else
|
||||
LOG("No BGM: "..Sources[name],5)
|
||||
LOG("No BGM: "..SourceObjList[name],5)
|
||||
end
|
||||
elseif Sources[name]then
|
||||
return true
|
||||
elseif name then
|
||||
LOG("No BGM: "..name,5)
|
||||
end
|
||||
end
|
||||
function BGM.setVol(v)
|
||||
assert(type(v)=='number'and v>=0 and v<=1)
|
||||
volume=v
|
||||
if BGM.playing then
|
||||
if volume>0 then
|
||||
BGM.playing:setVolume(volume)
|
||||
BGM.playing:play()
|
||||
elseif BGM.nowPlay then
|
||||
BGM.playing:pause()
|
||||
end
|
||||
end
|
||||
end
|
||||
function BGM.loadAll()--Not neccessary, unless you want avoid the lag when playing something for the first time
|
||||
for name in next,Sources do
|
||||
_load(name)
|
||||
end
|
||||
end
|
||||
function BGM.play(name)
|
||||
name=name or BGM.default
|
||||
if not _load(name)then return end
|
||||
if not _tryLoad(name)then return end
|
||||
if volume==0 then
|
||||
BGM.nowPlay=name
|
||||
BGM.playing=Sources[name]
|
||||
BGM.playing=SourceObjList[name].source
|
||||
return true
|
||||
end
|
||||
if name and Sources[name]then
|
||||
if name and SourceObjList[name].source then
|
||||
if BGM.nowPlay~=name then
|
||||
if BGM.nowPlay then
|
||||
TASK.new(task_fadeOut,BGM.playing)
|
||||
end
|
||||
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,Sources[name])
|
||||
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,SourceObjList[name].source)
|
||||
TASK.removeTask_code(task_fadeIn)
|
||||
|
||||
TASK.new(task_fadeIn,Sources[name])
|
||||
TASK.new(task_fadeIn,SourceObjList[name].source)
|
||||
BGM.nowPlay=name
|
||||
BGM.playing=Sources[name]
|
||||
BGM.playing=SourceObjList[name].source
|
||||
BGM.lastPlayed=BGM.nowPlay
|
||||
BGM.playing:seek(0)
|
||||
BGM.playing:play()
|
||||
@@ -128,8 +141,8 @@ function BGM.init(list)
|
||||
end
|
||||
function BGM.continue()
|
||||
if BGM.lastPlayed then
|
||||
BGM.nowPlay,BGM.playing=BGM.lastPlayed,Sources[BGM.lastPlayed]
|
||||
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,Sources[BGM.nowPlay])
|
||||
BGM.nowPlay,BGM.playing=BGM.lastPlayed,SourceObjList[BGM.lastPlayed].source
|
||||
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,SourceObjList[BGM.nowPlay].source)
|
||||
TASK.removeTask_code(task_fadeIn)
|
||||
TASK.new(task_fadeIn,BGM.playing)
|
||||
BGM.playing:play()
|
||||
|
||||
@@ -1,66 +1,60 @@
|
||||
local fs=love.filesystem
|
||||
local FILE={}
|
||||
function FILE.load(name,mode)
|
||||
function FILE.load(name,args)
|
||||
if not args then args=''end
|
||||
if fs.getInfo(name)then
|
||||
local F=fs.newFile(name)
|
||||
if F:open'r'then
|
||||
local s=F:read()
|
||||
F:close()
|
||||
if mode=='luaon'or not mode and s:sub(1,6)=="return{"then
|
||||
s=loadstring(s)
|
||||
if s then
|
||||
setfenv(s,{})
|
||||
return s()
|
||||
end
|
||||
elseif mode=='json'or not mode and s:sub(1,1)=="["and s:sub(-1)=="]"or s:sub(1,1)=="{"and s:sub(-1)=="}"then
|
||||
local res=JSON.decode(s)
|
||||
if res then
|
||||
return res
|
||||
end
|
||||
elseif mode=='string'or not mode then
|
||||
return s
|
||||
assert(F:open'r','open error')
|
||||
local s=F:read()F:close()
|
||||
if args:sArg'-luaon'or args==''and s:sub(1,6)=='return{'then
|
||||
local func=loadstring(s)
|
||||
if func then
|
||||
setfenv(func,{})
|
||||
local res=func()
|
||||
return assert(res,'decode error')
|
||||
else
|
||||
MES.new("No file loading mode called "..tostring(mode))
|
||||
error('decode error')
|
||||
end
|
||||
elseif args:sArg'-json'or args==''and s:sub(1,1)=='['and s:sub(-1)==']'or s:sub(1,1)=='{'and s:sub(-1)=='}'then
|
||||
local res=JSON.decode(s)
|
||||
if res then
|
||||
return res
|
||||
end
|
||||
error('decode error')
|
||||
elseif args:sArg'-string'or args==''then
|
||||
return s
|
||||
else
|
||||
MES.new('error',name.." "..text.loadError)
|
||||
error('unknown mode')
|
||||
end
|
||||
else
|
||||
error('no file')
|
||||
end
|
||||
end
|
||||
function FILE.save(data,name,mode)
|
||||
if not mode then mode=""end
|
||||
function FILE.save(data,name,args)
|
||||
if not args then args=''end
|
||||
if args:sArg'-d'and fs.getInfo(name)then
|
||||
error('duplicate')
|
||||
end
|
||||
|
||||
if type(data)=='table'then
|
||||
if mode:find'l'then
|
||||
if args:sArg'-luaon'then
|
||||
data=TABLE.dump(data)
|
||||
if not data then
|
||||
MES.new('error',name.." "..text.saveError.."dump error")
|
||||
return
|
||||
error('encode error')
|
||||
end
|
||||
else
|
||||
data=JSON.encode(data)
|
||||
if not data then
|
||||
MES.new('error',name.." "..text.saveError.."json error")
|
||||
return
|
||||
error('encode error')
|
||||
end
|
||||
end
|
||||
else
|
||||
data=tostring(data)
|
||||
end
|
||||
|
||||
if mode:find'd'and fs.getInfo(name)then
|
||||
MES.new('error',text.saveError_duplicate)
|
||||
return
|
||||
end
|
||||
local F=fs.newFile(name)
|
||||
F:open'w'
|
||||
local success,mes=F:write(data)
|
||||
F:flush()F:close()
|
||||
if success then
|
||||
return true
|
||||
else
|
||||
MES.new('error',text.saveError..(mes or"unknown error"))
|
||||
MES.traceback()
|
||||
end
|
||||
assert(F:open('w'),'open error')
|
||||
F:write(data)F:flush()F:close()
|
||||
end
|
||||
function FILE.clear(path)
|
||||
if fs.getRealDirectory(path)==SAVEDIR and fs.getInfo(path).type=='directory'then
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
NONE={}function NULL()end
|
||||
EDITING=""
|
||||
LOADED=false
|
||||
ERRDATA={}
|
||||
|
||||
--Pure lua modules (basic)
|
||||
MATH= require'Zframework.mathExtend'
|
||||
@@ -74,7 +73,8 @@ local xOy=SCR.xOy
|
||||
local ITP=xOy.inverseTransformPoint
|
||||
|
||||
local mx,my,mouseShow=-20,-20,false
|
||||
joysticks={}
|
||||
local jsState={}--map, joystickID->axisStates: {axisName->axisVal}
|
||||
local errData={}--list, each error create {mes={errMes strings},scene=sceneNameStr}
|
||||
|
||||
local devMode
|
||||
|
||||
@@ -288,18 +288,18 @@ function love.textinput(texts)
|
||||
WIDGET.textinput(texts)
|
||||
end
|
||||
|
||||
function love.joystickadded(JS)
|
||||
table.insert(joysticks,JS)
|
||||
MES.new('info',"Joystick added")
|
||||
end
|
||||
function love.joystickremoved(JS)
|
||||
local i=TABLE.find(joysticks,JS)
|
||||
if i then
|
||||
table.remove(joysticks,i)
|
||||
MES.new('info',"Joystick removed")
|
||||
end
|
||||
end
|
||||
local keyMirror={
|
||||
--analog sticks: -1, 0, 1 for neg, neutral, pos
|
||||
--triggers: 0 for released, 1 for pressed
|
||||
local jsAxisEventName={
|
||||
leftx={'leftstick_left','leftstick_right'},
|
||||
lefty={'leftstick_up','leftstick_down'},
|
||||
rightx={'rightstick_left','rightstick_right'},
|
||||
righty={'rightstick_up','rightstick_down'},
|
||||
triggerleft='triggerleft',
|
||||
triggerright='triggerright'
|
||||
}
|
||||
local gamePadKeys={'a','b','x','y','back','guide','start','leftstick','rightstick','leftshoulder','rightshoulder','dpup','dpdown','dpleft','dpright'}
|
||||
local dPadToKey={
|
||||
dpup='up',
|
||||
dpdown='down',
|
||||
dpleft='left',
|
||||
@@ -307,54 +307,92 @@ local keyMirror={
|
||||
start='return',
|
||||
back='escape',
|
||||
}
|
||||
function love.joystickadded(JS)
|
||||
jsState[JS:getID()]={
|
||||
_loveJSObj=JS,
|
||||
leftx=0,lefty=0,
|
||||
rightx=0,righty=0,
|
||||
triggerleft=0,triggerright=0
|
||||
}
|
||||
MES.new('info',"Joystick added")
|
||||
end
|
||||
function love.joystickremoved(JS)
|
||||
local js=jsState[JS:getID()]
|
||||
if js then
|
||||
for i=1,#gamePadKeys do
|
||||
if JS:isGamepadDown(gamePadKeys[i])then
|
||||
love.gamepadreleased(JS,gamePadKeys[i])
|
||||
end
|
||||
end
|
||||
love.gamepadaxis(JS,'leftx',0)
|
||||
love.gamepadaxis(JS,'lefty',0)
|
||||
love.gamepadaxis(JS,'rightx',0)
|
||||
love.gamepadaxis(JS,'righty',0)
|
||||
love.gamepadaxis(JS,'triggerleft',-1)
|
||||
love.gamepadaxis(JS,'triggerright',-1)
|
||||
jsState[JS:getID()]=nil
|
||||
MES.new('info',"Joystick removed")
|
||||
end
|
||||
end
|
||||
function love.gamepadaxis(JS,axis,val)
|
||||
local js=jsState[JS:getID()]
|
||||
if js then
|
||||
if axis=='leftx'or axis=='lefty'or axis=='rightx'or axis=='righty'then
|
||||
local newVal=--range: [0,1]
|
||||
val>.4 and 1 or
|
||||
val<-.4 and -1 or
|
||||
0
|
||||
if newVal~=js[axis]then
|
||||
if js[axis]==-1 then
|
||||
love.gamepadreleased(JS,jsAxisEventName[axis][1])
|
||||
elseif js[axis]~=0 then
|
||||
love.gamepadreleased(JS,jsAxisEventName[axis][2])
|
||||
end
|
||||
if newVal==-1 then
|
||||
love.gamepadpressed(JS,jsAxisEventName[axis][1])
|
||||
elseif newVal==1 then
|
||||
love.gamepadpressed(JS,jsAxisEventName[axis][2])
|
||||
end
|
||||
js[axis]=newVal
|
||||
end
|
||||
elseif axis=='triggerleft'or axis=='triggerright'then
|
||||
local newVal=val>-.3 and 1 or 0--range: [-1,1]
|
||||
if newVal~=js[axis]then
|
||||
if newVal==1 then
|
||||
love.gamepadpressed(JS,jsAxisEventName[axis])
|
||||
else
|
||||
love.gamepadreleased(JS,jsAxisEventName[axis])
|
||||
end
|
||||
js[axis]=newVal
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function love.gamepadpressed(_,i)
|
||||
mouseShow=false
|
||||
if SCN.swapping then return end
|
||||
if SCN.gamepadDown then SCN.gamepadDown(i)
|
||||
elseif SCN.keyDown then SCN.keyDown(keyMirror[i]or i)
|
||||
elseif SCN.keyDown then SCN.keyDown(dPadToKey[i]or i)
|
||||
elseif i=="back"then SCN.back()
|
||||
else WIDGET.gamepadPressed(keyMirror[i]or i)
|
||||
else WIDGET.gamepadPressed(dPadToKey[i]or i)
|
||||
end
|
||||
end
|
||||
function love.gamepadreleased(_,i)
|
||||
if SCN.swapping then return end
|
||||
if SCN.gamepadUp then SCN.gamepadUp(i)end
|
||||
end
|
||||
--[[
|
||||
function love.joystickpressed(JS,k)
|
||||
mouseShow=false
|
||||
if SCN.swapping then return end
|
||||
if SCN.gamepadDown then SCN.gamepadDown(i)
|
||||
elseif SCN.keyDown then SCN.keyDown(keyMirror[i]or i)
|
||||
elseif i=="back"then SCN.back()
|
||||
else WIDGET.gamepadPressed(i)
|
||||
end
|
||||
end
|
||||
function love.joystickreleased(JS,k)
|
||||
if SCN.swapping then return end
|
||||
if SCN.gamepadUp then SCN.gamepadUp(i)
|
||||
end
|
||||
end
|
||||
function love.joystickaxis(JS,axis,val)
|
||||
|
||||
end
|
||||
function love.joystickhat(JS,hat,dir)
|
||||
|
||||
end
|
||||
function love.sendData(data)end
|
||||
function love.receiveData(id,data)end
|
||||
]]
|
||||
function love.filedropped(file)
|
||||
if SCN.fileDropped then SCN.fileDropped(file)end
|
||||
end
|
||||
function love.directorydropped(dir)
|
||||
if SCN.directoryDropped then SCN.directoryDropped(dir)end
|
||||
end
|
||||
local lastGCtime=0
|
||||
local autoGCcount=0
|
||||
function love.lowmemory()
|
||||
if love.timer.getTime()-lastGCtime>6.26 then
|
||||
collectgarbage()
|
||||
lastGCtime=love.timer.getTime()
|
||||
collectgarbage()
|
||||
if autoGCcount<3 then
|
||||
autoGCcount=autoGCcount+1
|
||||
MES.new('check',"[auto GC] low MEM 设备内存过低")
|
||||
end
|
||||
end
|
||||
@@ -379,7 +417,7 @@ end
|
||||
function love.errorhandler(msg)
|
||||
if type(msg)~='string'then
|
||||
msg="Unknown error"
|
||||
elseif msg:find("Invaild UTF-8")and text then
|
||||
elseif msg:find("Invalid UTF-8")and text then
|
||||
msg=text.tryAnotherBuild
|
||||
end
|
||||
|
||||
@@ -403,20 +441,20 @@ function love.errorhandler(msg)
|
||||
love.audio.stop()
|
||||
gc.reset()
|
||||
|
||||
if LOADED and #ERRDATA<3 then
|
||||
if LOADED and #errData<3 then
|
||||
BG.set('none')
|
||||
local scn=SCN and SCN.cur or"NULL"
|
||||
table.insert(ERRDATA,{mes=err,scene=scn})
|
||||
table.insert(errData,{mes=err,scene=scn})
|
||||
|
||||
--Write messages to log file
|
||||
love.filesystem.append('conf/error.log',
|
||||
os.date("%Y/%m/%d %A %H:%M:%S\n")..
|
||||
#ERRDATA.." crash(es) "..love.system.getOS().."-"..VERSION.string.." scene: "..scn.."\n"..
|
||||
#errData.." crash(es) "..love.system.getOS().."-"..VERSION.string.." scene: "..scn.."\n"..
|
||||
table.concat(err,"\n",1,c-2).."\n\n"
|
||||
)
|
||||
|
||||
--Get screencapture
|
||||
gc.captureScreenshot(function(_)ERRDATA[#ERRDATA].shot=gc.newImage(_)end)
|
||||
gc.captureScreenshot(function(_)errData[#errData].shot=gc.newImage(_)end)
|
||||
gc.present()
|
||||
|
||||
--Create a new mainLoop thread to keep game alive
|
||||
@@ -539,7 +577,7 @@ function love.run()
|
||||
--Scene Launch
|
||||
while #SCN.stack>0 do SCN.pop()end
|
||||
SCN.push('quit','slowFade')
|
||||
SCN.init(#ERRDATA==0 and'load'or'error')
|
||||
SCN.init(#errData==0 and'load'or'error')
|
||||
|
||||
return function()
|
||||
local _
|
||||
@@ -703,6 +741,9 @@ end
|
||||
|
||||
local Z={}
|
||||
|
||||
Z.js=jsState
|
||||
Z.errData=errData
|
||||
|
||||
function Z.setIfPowerInfo(func)showPowerInfo=func end
|
||||
|
||||
--[Warning] Color and line width is uncertain value, set it in the function.
|
||||
|
||||
@@ -72,11 +72,11 @@ function SFX.getCount()
|
||||
return #sfxList
|
||||
end
|
||||
function SFX.setVol(v)
|
||||
assert(type(v)=='number'and v>=0 and v<=1)
|
||||
assert(type(v)=='number'and v>=0 and v<=1,'Wrong volume')
|
||||
volume=v
|
||||
end
|
||||
function SFX.setStereo(v)
|
||||
assert(type(v)=='number'and v>=0 and v<=1)
|
||||
assert(type(v)=='number'and v>=0 and v<=1,'Wrong stereo')
|
||||
stereo=v
|
||||
end
|
||||
|
||||
@@ -112,7 +112,7 @@ function SFX.playSample(pack,...)--vol-1, sampSet1, vol-2, sampSet2
|
||||
end
|
||||
end
|
||||
end
|
||||
function SFX.play(name,vol,pos,pitch)
|
||||
local function _play(name,vol,pos,pitch)
|
||||
if volume==0 or vol==0 then return end
|
||||
local S=Sources[name]--Source list
|
||||
if not S then return end
|
||||
@@ -134,33 +134,13 @@ function SFX.play(name,vol,pos,pitch)
|
||||
S:setPosition(0,0,0)
|
||||
end
|
||||
end
|
||||
S:setVolume(((vol or 1)*volume)^1.626)
|
||||
S:setVolume(vol^1.626)
|
||||
S:setPitch(pitch and 1.0594630943592953^pitch or 1)
|
||||
S:play()
|
||||
end
|
||||
function SFX.fplay(name,vol,pos)
|
||||
local S=Sources[name]--Source list
|
||||
if not S then return end
|
||||
local n=1
|
||||
while S[n]:isPlaying()do
|
||||
n=n+1
|
||||
if not S[n]then
|
||||
S[n]=S[1]:clone()
|
||||
S[n]:seek(0)
|
||||
break
|
||||
end
|
||||
end
|
||||
S=S[n]--AU_SRC
|
||||
if S:getChannelCount()==1 then
|
||||
if pos then
|
||||
pos=pos*stereo
|
||||
S:setPosition(pos,1-pos^2,0)
|
||||
else
|
||||
S:setPosition(0,0,0)
|
||||
end
|
||||
end
|
||||
S:setVolume(vol^1.626)
|
||||
S:play()
|
||||
SFX.fplay=_play--Play sounds without apply module's volume setting
|
||||
function SFX.play(name,vol,pos,pitch)
|
||||
_play(name,(vol or 1)*volume,pos,pitch)
|
||||
end
|
||||
function SFX.reset()
|
||||
for _,L in next,Sources do
|
||||
|
||||
@@ -2,9 +2,25 @@ local data=love.data
|
||||
local STRING={}
|
||||
local assert,tostring,tonumber=assert,tostring,tonumber
|
||||
local int,format=math.floor,string.format
|
||||
local find,sub,upper=string.find,string.sub,string.upper
|
||||
local find,sub,gsub,upper=string.find,string.sub,string.gsub,string.upper
|
||||
local char,byte=string.char,string.byte
|
||||
|
||||
--"Replace dollars", replace all $n with ...
|
||||
function string.repD(str,...)
|
||||
local l={...}
|
||||
for i=#l,1,-1 do
|
||||
str=gsub(str,'$'..i,l[i])
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
--"Scan arg", scan if str has the arg (format of str is like "-json -q", arg is like "-q")
|
||||
function string.sArg(str,switch)
|
||||
if find(str.." ",switch.." ")then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
do--function STRING.shiftChar(c)
|
||||
local shiftMap={
|
||||
['1']='!',['2']='@',['3']='#',['4']='$',['5']='%',
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
local find=string.find
|
||||
local rem=table.remove
|
||||
local next,type=next,type
|
||||
local TABLE={}
|
||||
|
||||
@@ -83,7 +84,7 @@ function TABLE.complete(new,old)
|
||||
end
|
||||
end
|
||||
|
||||
--Remove positive integer index of table
|
||||
--Remove [1~#] of table
|
||||
function TABLE.cut(G)
|
||||
for i=1,#G do
|
||||
G[i]=nil
|
||||
@@ -97,16 +98,53 @@ function TABLE.clear(G)
|
||||
end
|
||||
end
|
||||
|
||||
--Remove duplicated value of [1~#]
|
||||
function TABLE.trimDuplicate(org)
|
||||
local cache={}
|
||||
for i=1,#org,-1 do
|
||||
if cache[org[i]]then
|
||||
rem(org,i)
|
||||
else
|
||||
cache[org[i]]=true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--Discard duplicated value
|
||||
function TABLE.remDuplicate(org)
|
||||
local cache={}
|
||||
for k,v in next,org do
|
||||
if cache[v]then
|
||||
org[k]=nil
|
||||
else
|
||||
cache[v]=true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--Reverse [1~#]
|
||||
function TABLE.reverse(org)
|
||||
local l=#org
|
||||
for i=1,math.floor(l/2)do
|
||||
org[i],org[l+1-i]=org[l+1-i],org[i]
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------
|
||||
|
||||
--Find value in [1~#]
|
||||
function TABLE.find(t,val)
|
||||
for i=1,#t do if t[i]==val then return i end end
|
||||
end
|
||||
|
||||
--Retuen next value of [1~#]
|
||||
--Return next value of [1~#] (by value)
|
||||
function TABLE.next(t,val)
|
||||
for i=1,#t do if t[i]==val then return t[i%#t+1]end end
|
||||
end
|
||||
|
||||
--------------------------
|
||||
|
||||
--Find value in whole table
|
||||
function TABLE.search(t,val)
|
||||
for k,v in next,t do if v==val then return k end end
|
||||
@@ -121,6 +159,8 @@ function TABLE.reIndex(org)
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------
|
||||
|
||||
--Dump a simple lua table
|
||||
do--function TABLE.dump(L,t)
|
||||
local tabs={
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
local rnd=math.random
|
||||
local volume=1
|
||||
local diversion=0
|
||||
local VOC={
|
||||
vol=1,
|
||||
getCount=function()return 0 end,
|
||||
getQueueCount=function()return 0 end,
|
||||
load=function()error("Cannot load before init!")end,
|
||||
@@ -7,13 +9,16 @@ local VOC={
|
||||
play=NULL,
|
||||
update=NULL,
|
||||
}
|
||||
function VOC.setDiversion(n)
|
||||
assert(type(n)=='number'and n>0 and n<12,'Wrong div')
|
||||
diversion=n
|
||||
end
|
||||
function VOC.setVol(v)
|
||||
assert(type(v)=='number'and v>=0 and v<=1)
|
||||
VOC.vol=v
|
||||
assert(type(v)=='number'and v>=0 and v<=1,'Wrong volume')
|
||||
volume=v
|
||||
end
|
||||
function VOC.init(list)
|
||||
VOC.init=nil
|
||||
local rnd=math.random
|
||||
local rem=table.remove
|
||||
local voiceQueue={free=0}
|
||||
local bank={}--{vocName1={SRC1s},vocName2={SRC2s},...}
|
||||
@@ -72,7 +77,7 @@ function VOC.init(list)
|
||||
end
|
||||
|
||||
function VOC.play(s,chn)
|
||||
if VOC.vol>0 then
|
||||
if volume>0 then
|
||||
local _=Source[s]
|
||||
if not _ then return end
|
||||
if chn then
|
||||
@@ -95,13 +100,15 @@ function VOC.init(list)
|
||||
end
|
||||
elseif Q.s==1 then--Waiting load source
|
||||
Q[1]=_getVoice(Q[1])
|
||||
Q[1]:setVolume(VOC.vol)
|
||||
Q[1]:setVolume(volume)
|
||||
Q[1]:setPitch(1.0594630943592953^(diversion*(rnd()*2-1)))
|
||||
Q[1]:play()
|
||||
Q.s=Q[2]and 2 or 4
|
||||
elseif Q.s==2 then--Playing 1,ready 2
|
||||
if Q[1]:getDuration()-Q[1]:tell()<.08 then
|
||||
Q[2]=_getVoice(Q[2])
|
||||
Q[2]:setVolume(VOC.vol)
|
||||
Q[2]:setVolume(volume)
|
||||
Q[1]:setPitch(1.0594630943592953^(diversion*(rnd()*2-1)))
|
||||
Q[2]:play()
|
||||
Q.s=3
|
||||
end
|
||||
|
||||
43
legals.md
43
legals.md
@@ -1,26 +1,23 @@
|
||||
**TECHMINO © 2019-2021 26F Studio. Some rights reserved.**
|
||||
TECHMINO and "26F Studio" are trademarks of 26F Studio.
|
||||
The TECHMINO game and source code are under a GNU Lesser General Public License Version 3.
|
||||
TECHMINO © 2019-2021 26F Studio. Some rights reserved.
|
||||
|
||||
TECHMINO and "26F Studio" are trademarks of 26F Studio. The TECHMINO game and source code are under a GNU Lesser General Public License Version 3.
|
||||
|
||||
|
||||
"Tetris" is the registered trademark of The Tetris Holding, LLC, licensed to The Tetris Company, Inc. TECHMINO is not a fan game of Tetris. TECHMINO and 26F Studio are not affiliated with Tetris Holding, LLC or The Tetris Company, Inc. in any way.
|
||||
|
||||
|
||||
Powered by LÖVE, © 2006-2021 LÖVE Development Team.
|
||||
|
||||
Lua is free software distributed under the terms of the MIT license. Copyright © 1994-2021 by Lua.org, PUC-Rio.
|
||||
|
||||
Lua is free software distributed under the terms of the MIT license. Copyright © 1994~2021 by Lua.org, PUC-Rio.
|
||||
SIMPLE LOVE LIGHTS is under a MIT License. Created by Dylan Hunn.
|
||||
|
||||
json.lua is copyrighted by rxi. © 2021 rxi.
|
||||
|
||||
IBM Plex is copyrighted by the International Business Machines Corporation. IBM and IBM Plex are trademarks of IBM Corp, registered in many jurisdictions worldwide. IBM Plex is licensed under the SIL Open Font License, Version 1.1.
|
||||
|
||||
|
||||
The Apple logo, "Apple Inc.," iOS, iPadOS, macOS, iPhone, and Mac are registered trademarks of Apple Inc. in the United States of America and other countries or regions.
|
||||
|
||||
|
||||
"Windows", the Windows logo, "Xbox", Xbox logo, and "Microsoft" are registered trademarks of Microsoft Corporation in the United States of America and other countries or regions.
|
||||
|
||||
|
||||
Source Han Sans is copyrighted by Adobe Inc. Source Han Sans and Adobe are registered trademarks of Adobe Inc. in United States and other countries or regions. Source Han Sans is licensed under the SIL Open Font License.
|
||||
|
||||
|
||||
IBM Plex is copyrighted by the International Business Machines Corporation. IBM and IBM Plex are trademarks of IBM Corp, registered in many jurisdictions worldwide. IBM Plex is licensed under the SIL Open Font License.
|
||||
Source Han Sans is copyrighted by Adobe Inc. Source Han Sans and Adobe are registered trademarks of Adobe Inc. in United States and other countries or regions. Source Han Sans is licensed under the SIL Open Font License, Version 1.1.
|
||||
|
||||
|
||||
JetBrains Mono is copyrighted by the JetBrains Mono Project authors. JetBrains Mono is a trademark of JetBrains s.r.o. JetBrains Mono is licensed under the SIL Open Font License, Version 1.1.
|
||||
@@ -29,22 +26,26 @@ JetBrains Mono is copyrighted by the JetBrains Mono Project authors. JetBrains M
|
||||
"PlayStation", "PS", "PlayStation Family Mark", "PS logo", "DualSense" and "Play Has No Limits" are registered trademarks or trademarks of Sony Interactive Entertainment Inc. "SONY" is a registered trademark of Sony Corporation. © 2021 Sony Interactive Entertainment LLC.
|
||||
|
||||
|
||||
N3TWORK is a registered trademark of N3TWORK Inc. © 2021 N3TWORK Inc.
|
||||
"Windows", the Windows logo, "Xbox", Xbox logo, and "Microsoft" are registered trademarks of Microsoft Corporation in the United States of America and other countries or regions.
|
||||
|
||||
|
||||
The Apple logo, "Apple Inc.," iOS, iPadOS, macOS, iPhone, and Mac are registered trademarks of Apple Inc. in the United States of America and other countries or regions.
|
||||
|
||||
|
||||
"EA" and "Electronic Arts" are registered trademarks of Electronic Arts Inc. © 2021 Electronic Arts Inc.
|
||||
|
||||
SEGA and the SEGA logo are registered trademarks of Sega Corporation. © 2021 Sega Corporation.
|
||||
|
||||
Oculus Quest is a registered trademark of Facebook Technologies, LLC. © Facebook, Inc.
|
||||
Oculus Quest is a registered trademark of Facebook Technologies, LLC. © Meta Platforms, Inc.
|
||||
|
||||
"Nintendo" is a registered trademarks of Nintendo Co., Ltd. © 2021 Nintendo Co., Ltd.
|
||||
|
||||
N3TWORK is a registered trademark of N3TWORK Inc. © 2021 N3TWORK Inc.
|
||||
|
||||
GoldWave is a registered trademark of GoldWave, Inc.
|
||||
|
||||
|
||||
Linux is a registered trademark of Linus Torvalds.
|
||||
|
||||
Linux is a registered trademark of Linus Torvalds.
|
||||
|
||||
Touhou Project © Team Shanghai Alice 2002-2021.
|
||||
|
||||
All other trademarks are the properties of their respective owners.
|
||||
|
||||
All other trademarks, logos, and copyrights are the properties of their respective owners.
|
||||
|
||||
30
main.lua
30
main.lua
@@ -52,7 +52,9 @@ local _LOADTIME_=TIME()
|
||||
Z=require'Zframework'
|
||||
FONT.load('parts/fonts/proportional.ttf')
|
||||
SCR.setSize(1280,720)--Initialize Screen size
|
||||
BGM.setMaxSources(5)
|
||||
BGM.setChange(function(name)MES.new('music',text.nowPlaying..name,5)end)
|
||||
VOC.setDiversion(1)
|
||||
|
||||
table.insert(_LOADTIMELIST_,("Load Zframework: %.3fs"):format(TIME()-_LOADTIME_))
|
||||
|
||||
@@ -203,15 +205,15 @@ end
|
||||
Z.setOnQuit(destroyPlayers)
|
||||
|
||||
--Load settings and statistics
|
||||
TABLE.cover (FILE.load('conf/user')or{},USER)
|
||||
TABLE.cover (FILE.load('conf/unlock')or{},RANKS)
|
||||
TABLE.update(FILE.load('conf/settings')or{},SETTING)
|
||||
TABLE.coverR(FILE.load('conf/data')or{},STAT)
|
||||
TABLE.cover (FILE.load('conf/key')or{},KEY_MAP)
|
||||
TABLE.cover (FILE.load('conf/virtualkey')or{},VK_ORG)
|
||||
TABLE.cover (loadFile('conf/user')or{},USER)
|
||||
TABLE.cover (loadFile('conf/unlock')or{},RANKS)
|
||||
TABLE.update(loadFile('conf/settings')or{},SETTING)
|
||||
TABLE.coverR(loadFile('conf/data')or{},STAT)
|
||||
TABLE.cover (loadFile('conf/key')or{},KEY_MAP)
|
||||
TABLE.cover (loadFile('conf/virtualkey')or{},VK_ORG)
|
||||
|
||||
--Initialize fields, sequence, missions, gameEnv for cutsom game
|
||||
local fieldData=FILE.load('conf/customBoards','string')
|
||||
local fieldData=loadFile('conf/customBoards','-string')
|
||||
if fieldData then
|
||||
fieldData=STRING.split(fieldData,"!")
|
||||
for i=1,#fieldData do
|
||||
@@ -220,15 +222,15 @@ if fieldData then
|
||||
else
|
||||
FIELD[1]=DATA.newBoard()
|
||||
end
|
||||
local sequenceData=FILE.load('conf/customSequence','string')
|
||||
local sequenceData=loadFile('conf/customSequence','-string')
|
||||
if sequenceData then
|
||||
DATA.pasteSequence(sequenceData)
|
||||
end
|
||||
local missionData=FILE.load('conf/customMissions','string')
|
||||
local missionData=loadFile('conf/customMissions','-string')
|
||||
if missionData then
|
||||
DATA.pasteMission(missionData)
|
||||
end
|
||||
local customData=FILE.load('conf/customEnv')
|
||||
local customData=loadFile('conf/customEnv')
|
||||
if customData and customData['version']==VERSION.code then
|
||||
TABLE.complete(customData,CUSTOMENV)
|
||||
end
|
||||
@@ -475,6 +477,10 @@ do
|
||||
fs.remove('record/rhythm_h.rec')
|
||||
fs.remove('record/rhythm_u.rec')
|
||||
end
|
||||
if RANKS.bigbang then
|
||||
RANKS.clearRush,RANKS.bigbang=RANKS.bigbang
|
||||
fs.remove('record/bigbang.rec')
|
||||
end
|
||||
if STAT.version~=VERSION.code then
|
||||
for k,v in next,MODE_UPDATE_MAP do
|
||||
if RANKS[k]then
|
||||
@@ -627,9 +633,9 @@ if TABLE.find(arg,'--test')then
|
||||
TASK.new(function()
|
||||
while true do
|
||||
YIELD()
|
||||
if ERRDATA[1]then break end
|
||||
if Z.errData[1]then break end
|
||||
end
|
||||
LOG("\27[91m\27[1mAutomatic Test Failed :(\27[0m\nThe error message is:\n"..table.concat(ERRDATA[1].mes,"\n").."\27[91m\nAborting\27[0m")
|
||||
LOG("\27[91m\27[1mAutomatic Test Failed :(\27[0m\nThe error message is:\n"..table.concat(Z.errData[1].mes,"\n").."\27[91m\nAborting\27[0m")
|
||||
TEST.yieldN(60)
|
||||
love.event.quit(1)
|
||||
end)
|
||||
|
||||
BIN
media/music/malate.ogg
Normal file
BIN
media/music/malate.ogg
Normal file
Binary file not shown.
@@ -140,8 +140,8 @@ do
|
||||
},--Z
|
||||
false,--S
|
||||
{
|
||||
[01]={'+0+0','-1+0','-1+1','+0-2','+1+1','+0+1'},
|
||||
[10]={'+0+0','+1+0','+1-1','+0+2','-1-1','+0-1'},
|
||||
[01]={'+0+0','-1+0','-1+1','+0-2','+1+1','+0+1','+0-1'},
|
||||
[10]={'+0+0','+1+0','+1-1','+0+2','-1-1','+0-1','+0+1'},
|
||||
[03]={'+0+0','+1+0','+1+1','+0-2','+1-2','+1-1','+0+1'},
|
||||
[30]={'+0+0','-1+0','-1-1','+0+2','-1+2','+0-1','-1+1'},
|
||||
[12]={'+0+0','+1+0','+1-1','+1+1','-1+0','+0-1','+0+2','+1+2'},
|
||||
|
||||
@@ -61,7 +61,7 @@ function back.draw()
|
||||
|
||||
gc_setLineWidth(6)
|
||||
gc_setColor(.8,.9,1,.3)
|
||||
for i=1,8 do gc_polygon('line',SVG_TITLE_FAN[i])end
|
||||
for i=1,#SVG_TITLE_FAN do gc_polygon('line',SVG_TITLE_FAN[i])end
|
||||
|
||||
gc_setLineWidth(2)
|
||||
gc_setColor(1,.5,.7,.3)
|
||||
|
||||
@@ -12,7 +12,7 @@ local baseBot={
|
||||
function baseBot.update(bot)
|
||||
local P=bot.P
|
||||
local keys=bot.keys
|
||||
if P.control and P.waiting==-1 then
|
||||
if P.control and P.waiting==0 then
|
||||
bot.delay=bot.delay-1
|
||||
if not keys[1]then
|
||||
if bot.runningThread then
|
||||
|
||||
@@ -6,6 +6,8 @@ return{
|
||||
lock=1e99,
|
||||
wait=0,
|
||||
fall=0,
|
||||
hang=5,
|
||||
hurry=1e99,
|
||||
|
||||
--Control
|
||||
nextCount=6,
|
||||
@@ -13,13 +15,13 @@ return{
|
||||
holdCount=1,
|
||||
infHold=true,
|
||||
phyHold=false,
|
||||
hang=0,
|
||||
|
||||
--Visual
|
||||
bone=false,
|
||||
|
||||
--Rule
|
||||
sequence='bag',
|
||||
lockout=false,
|
||||
fieldH=20,
|
||||
heightLimit=1e99,
|
||||
bufferLimit=1e99,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
local function task_newBoard(P,init)
|
||||
local targetLine
|
||||
local F,L={},{1}
|
||||
--TODO
|
||||
P:pushNextList(L)
|
||||
@@ -7,7 +8,7 @@ local function task_newBoard(P,init)
|
||||
if not init then for _=1,26 do YIELD()end end
|
||||
P.control=true
|
||||
|
||||
P.gameEnv.heightLimit=#F
|
||||
P.gameEnv.heightLimit=targetLine or #F
|
||||
P:pushLineList(F)
|
||||
end
|
||||
local function _check(P)
|
||||
@@ -23,7 +24,7 @@ local function _check(P)
|
||||
end
|
||||
return{
|
||||
sequence='none',
|
||||
RS="SRS",
|
||||
RS="TRS",
|
||||
pushSpeed=5,
|
||||
mesDisp=function(P)
|
||||
setFont(60)
|
||||
@@ -1,24 +1,33 @@
|
||||
local gc=love.graphics
|
||||
local warnTime={60,90,105,115,116,117,118,119,120}
|
||||
for i=1,#warnTime do warnTime[i]=warnTime[i]*60 end
|
||||
|
||||
return{
|
||||
mesDisp=function(P)
|
||||
gc.setLineWidth(2)
|
||||
gc.rectangle('line',55,110,32,402)
|
||||
local T=P.stat.frame/60/120
|
||||
gc.setColor(2*T,2-2*T,.2)
|
||||
gc.rectangle('fill',56,511,30,(T-1)*400)
|
||||
gc.setColor(.98,.98,.98,.8)
|
||||
gc.rectangle('line',0,260,126,80,4)
|
||||
gc.setColor(.98,.98,.98,.4)
|
||||
gc.rectangle('fill',0+2,260+2,126-4,80-4,2)
|
||||
setFont(45)
|
||||
local t=P.stat.frame/60
|
||||
local T=("%.1f"):format(120-t)
|
||||
gc.setColor(COLOR.dH)
|
||||
mStr(T,65,270)
|
||||
t=t/120
|
||||
gc.setColor(1.7*t,2.3-2*t,.3)
|
||||
mStr(T,63,268)
|
||||
end,
|
||||
task=function(P)
|
||||
P.modeData.stage=1
|
||||
P.modeData.section=1
|
||||
while true do
|
||||
YIELD()
|
||||
if P.stat.frame/60>=warnTime[P.modeData.stage]then
|
||||
if P.modeData.stage<9 then
|
||||
P.modeData.stage=P.modeData.stage+1
|
||||
playReadySFX(3,.7+P.modeData.stage*.03)
|
||||
while P.stat.frame>=warnTime[P.modeData.section]do
|
||||
if P.modeData.section<9 then
|
||||
P.modeData.section=P.modeData.section+1
|
||||
playReadySFX(3,.7+P.modeData.section*.03)
|
||||
else
|
||||
playReadySFX(0,.7+P.modeData.stage*.03)
|
||||
playReadySFX(0,.7+P.modeData.section*.03)
|
||||
P:win('finish')
|
||||
return
|
||||
end
|
||||
|
||||
@@ -15,6 +15,43 @@ local playSFX=SFX.play
|
||||
|
||||
|
||||
--System
|
||||
function loadFile(name,args)
|
||||
if not args then args=''end
|
||||
local res,mes=pcall(FILE.load,name,args)
|
||||
if res then
|
||||
return mes
|
||||
else
|
||||
if mes:find'open error'then
|
||||
MES.new('error',text.loadError_open:repD(name))
|
||||
elseif mes:find'unknown mode'then
|
||||
MES.new('error',text.loadError_errorMode:repD(name,args))
|
||||
elseif mes:find'no file'then
|
||||
if not args:sArg'-canSkip'then
|
||||
MES.new('error',text.loadError_noFile:repD(name))
|
||||
end
|
||||
elseif mes then
|
||||
MES.new('error',text.loadError_other:repD(name,mes))
|
||||
else
|
||||
MES.new('error',text.loadError_unknown:repD(name))
|
||||
end
|
||||
end
|
||||
end
|
||||
function saveFile(data,name,args)
|
||||
local res,mes=pcall(FILE.save,data,name,args)
|
||||
if res then
|
||||
return mes
|
||||
else
|
||||
MES.new('error',
|
||||
mes:find'duplicate'and
|
||||
text.saveError_duplicate:repD(name)or
|
||||
mes:find'encode error'and
|
||||
text.saveError_encode:repD(name)or
|
||||
mes and
|
||||
text.saveError_other:repD(name,mes)or
|
||||
text.saveError_unknown:repD(name)
|
||||
)
|
||||
end
|
||||
end
|
||||
function isSafeFile(file,mes)
|
||||
if love.filesystem.getRealDirectory(file)~=SAVEDIR then
|
||||
return true
|
||||
@@ -23,13 +60,13 @@ function isSafeFile(file,mes)
|
||||
end
|
||||
end
|
||||
function saveStats()
|
||||
return FILE.save(STAT,'conf/data')
|
||||
return saveFile(STAT,'conf/data')
|
||||
end
|
||||
function saveProgress()
|
||||
return FILE.save(RANKS,'conf/unlock')
|
||||
return saveFile(RANKS,'conf/unlock')
|
||||
end
|
||||
function saveSettings()
|
||||
return FILE.save(SETTING,'conf/settings')
|
||||
return saveFile(SETTING,'conf/settings')
|
||||
end
|
||||
function applyLanguage()
|
||||
text=LANG.get(SETTING.locale)
|
||||
@@ -263,16 +300,16 @@ function setField(P,page)
|
||||
end
|
||||
end
|
||||
end
|
||||
function freshDate(mode)
|
||||
if not mode then
|
||||
mode=""
|
||||
function freshDate(args)
|
||||
if not args then
|
||||
args=""
|
||||
end
|
||||
local date=os.date("%Y/%m/%d")
|
||||
if STAT.date~=date then
|
||||
STAT.date=date
|
||||
STAT.todayTime=0
|
||||
getItem('zTicket',1)
|
||||
if not mode:find'q'then
|
||||
if not args:find'q'then
|
||||
MES.new('info',text.newDay)
|
||||
end
|
||||
saveStats()
|
||||
@@ -297,6 +334,15 @@ function legalGameTime()--Check if today's playtime is legal
|
||||
end
|
||||
return true
|
||||
end
|
||||
do--function trySettingWarn()
|
||||
local lastWarnTime=0
|
||||
function trySettingWarn()
|
||||
if TIME()-lastWarnTime>2.6 then
|
||||
MES.new('warn',text.settingWarn,5)
|
||||
end
|
||||
lastWarnTime=TIME()
|
||||
end
|
||||
end
|
||||
|
||||
function mergeStat(stat,delta)--Merge delta stat. to global stat.
|
||||
for k,v in next,delta do
|
||||
@@ -466,7 +512,7 @@ function gameOver()--Save record
|
||||
D.date=os.date("%Y/%m/%d %H:%M")
|
||||
ins(L,p+1,D)
|
||||
if L[11]then L[11]=nil end
|
||||
FILE.save(L,('record/%s.rec'):format(M.name),'l')
|
||||
saveFile(L,('record/%s.rec'):format(M.name),'-luaon')
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -818,13 +864,17 @@ do--function pressKey(k)
|
||||
end
|
||||
do--CUS/SETXXX(k)
|
||||
local CUSTOMENV=CUSTOMENV
|
||||
local warnList={
|
||||
'ims','RS','FTLock','frameMul','highCam',
|
||||
'VKSwitch','VKIcon','VKTrack','VKDodge',
|
||||
}
|
||||
function CUSval(k)return function()return CUSTOMENV[k]end end
|
||||
function ROOMval(k)return function()return ROOMENV[k]end end
|
||||
function SETval(k)return function()return SETTING[k]end end
|
||||
function CUSrev(k)return function()CUSTOMENV[k]=not CUSTOMENV[k]end end
|
||||
function ROOMrev(k)return function()ROOMENV[k]=not ROOMENV[k]end end
|
||||
function SETrev(k)return function()SETTING[k]=not SETTING[k]end end
|
||||
function SETrev(k)return function()if TABLE.find(warnList,k)then trySettingWarn()end SETTING[k]=not SETTING[k]end end
|
||||
function CUSsto(k)return function(i)CUSTOMENV[k]=i end end
|
||||
function ROOMsto(k)return function(i)ROOMENV[k]=i end end
|
||||
function SETsto(k)return function(i)SETTING[k]=i end end
|
||||
function SETsto(k)return function(i)if TABLE.find(warnList,k)then trySettingWarn()end SETTING[k]=i end end
|
||||
end
|
||||
|
||||
@@ -20,140 +20,129 @@ RANK_COLORS={
|
||||
{1,.5,.4},
|
||||
{.95,.5,.95},
|
||||
}
|
||||
do--SVG_TITLE
|
||||
SVG_TITLE={
|
||||
do--SVG_TITLE_FILL, SVG_TITLE_LINE
|
||||
SVG_TITLE_FILL={
|
||||
{
|
||||
53, 60,
|
||||
1035, 0,
|
||||
964, 218,
|
||||
660, 218,
|
||||
391, 1300,
|
||||
231, 1154,
|
||||
415, 218,
|
||||
0, 218,
|
||||
0,0,
|
||||
0,34,
|
||||
63,34,
|
||||
63,227,
|
||||
97,227,
|
||||
97,34,
|
||||
160,34,
|
||||
160,0,
|
||||
},
|
||||
{
|
||||
716, 290,
|
||||
1429, 290,
|
||||
1312, 462,
|
||||
875, 489,
|
||||
821, 695,
|
||||
1148, 712,
|
||||
1017, 902,
|
||||
761, 924,
|
||||
707, 1127,
|
||||
1106, 1101,
|
||||
1198, 1300,
|
||||
465, 1300,
|
||||
126,60,
|
||||
244,60,
|
||||
244,94,
|
||||
160,94,
|
||||
160,127,
|
||||
230,127,
|
||||
230,161,
|
||||
160,161,
|
||||
160,194,
|
||||
244,194,
|
||||
244,227,
|
||||
126,227,
|
||||
},
|
||||
{
|
||||
1516, 287,
|
||||
2102, 290,
|
||||
2036, 464,
|
||||
1598, 465,
|
||||
1322, 905,
|
||||
1395, 1102,
|
||||
1819, 1064,
|
||||
1743, 1280,
|
||||
1286, 1310,
|
||||
1106, 902,
|
||||
262,82,
|
||||
283,60,
|
||||
385,60,
|
||||
385,94,
|
||||
296,94,
|
||||
296,194,
|
||||
385,194,
|
||||
385,227,
|
||||
283,227,
|
||||
262,206,
|
||||
},
|
||||
{
|
||||
2179, 290,
|
||||
2411, 290,
|
||||
2272, 688,
|
||||
2674, 666,
|
||||
2801, 290,
|
||||
3041, 290,
|
||||
2693, 1280,
|
||||
2464, 1280,
|
||||
2601, 879,
|
||||
2199, 897,
|
||||
2056, 1280,
|
||||
1828, 1280,
|
||||
404,60,
|
||||
437,60,
|
||||
437,127,
|
||||
505,127,
|
||||
505,60,
|
||||
538,60,
|
||||
538,227,
|
||||
505,227,
|
||||
505,161,
|
||||
437,161,
|
||||
437,227,
|
||||
404,227,
|
||||
},
|
||||
{
|
||||
3123, 290,
|
||||
3480, 290,
|
||||
3496, 480,
|
||||
3664, 290,
|
||||
4017, 294,
|
||||
3682, 1280,
|
||||
3453, 1280,
|
||||
3697, 578,
|
||||
3458, 843,
|
||||
3304, 842,
|
||||
3251, 561,
|
||||
3001, 1280,
|
||||
2779, 1280,
|
||||
558,60,
|
||||
604,60,
|
||||
640,153,
|
||||
676,60,
|
||||
722,60,
|
||||
722,227,
|
||||
688,227,
|
||||
688,108,
|
||||
655,194,
|
||||
625,194,
|
||||
591,108,
|
||||
591,227,
|
||||
558,227,
|
||||
},
|
||||
{
|
||||
4088, 290,
|
||||
4677, 290,
|
||||
4599, 501,
|
||||
4426, 502,
|
||||
4219, 1069,
|
||||
4388, 1070,
|
||||
4317, 1280,
|
||||
3753, 1280,
|
||||
3822, 1068,
|
||||
3978, 1068,
|
||||
4194, 504,
|
||||
4016, 504,
|
||||
743,60,
|
||||
777,60,
|
||||
777,227,
|
||||
743,227,
|
||||
},
|
||||
{
|
||||
4747, 290,
|
||||
4978, 295,
|
||||
4921, 464,
|
||||
5186, 850,
|
||||
5366, 290,
|
||||
5599, 295,
|
||||
5288, 1280,
|
||||
5051, 1280,
|
||||
5106, 1102,
|
||||
4836, 709,
|
||||
4641, 1280,
|
||||
4406, 1280,
|
||||
798,60,
|
||||
831,60,
|
||||
899,173,
|
||||
899,60,
|
||||
933,60,
|
||||
933,227,
|
||||
899,227,
|
||||
831,115,
|
||||
831,227,
|
||||
798,227,
|
||||
},
|
||||
{
|
||||
5814, 290,
|
||||
6370, 295,
|
||||
6471, 415,
|
||||
6238, 1156,
|
||||
6058, 1280,
|
||||
5507, 1280,
|
||||
5404, 1154,
|
||||
5635, 416,
|
||||
-- 5814, 290,
|
||||
-- 5878, 463,
|
||||
5770, 542,
|
||||
5617, 1030,
|
||||
5676, 1105,
|
||||
5995, 1106,
|
||||
6100, 1029,
|
||||
6255, 541,
|
||||
6199, 465,
|
||||
5878, 463,
|
||||
950,82,
|
||||
971,60,
|
||||
1064,60,
|
||||
1085,82,
|
||||
1085,206,
|
||||
1064,227,
|
||||
971,227,
|
||||
950,206,
|
||||
950,82,
|
||||
|
||||
984,94,
|
||||
984,194,
|
||||
1051,194,
|
||||
1051,94,
|
||||
984,94,
|
||||
},
|
||||
}
|
||||
for _,C in next,SVG_TITLE do
|
||||
for _,C in next,SVG_TITLE_FILL do
|
||||
for i=1,#C do
|
||||
C[i]=C[i]*.1626
|
||||
C[i]=C[i]*.94
|
||||
end
|
||||
end
|
||||
|
||||
SVG_TITLE_LINE=TABLE.shift(SVG_TITLE_FILL)
|
||||
SVG_TITLE_LINE[8],SVG_TITLE_LINE[9]={},{}
|
||||
for j=1,16 do SVG_TITLE_LINE[8][j]=SVG_TITLE_FILL[8][j]end
|
||||
for j=19,#SVG_TITLE_FILL[8]-2 do SVG_TITLE_LINE[9][j-18]=SVG_TITLE_FILL[8][j]end
|
||||
end
|
||||
do--SVG_TITLE_FAN
|
||||
SVG_TITLE_FAN={}
|
||||
local sin,cos=math.sin,math.cos
|
||||
for i=1,8 do
|
||||
local L={}
|
||||
for i=1,9 do
|
||||
local L=TABLE.copy(SVG_TITLE_LINE[i])
|
||||
SVG_TITLE_FAN[i]=L
|
||||
for j=1,#SVG_TITLE[i]do
|
||||
L[j]=SVG_TITLE[i][j]
|
||||
end
|
||||
for j=1,#L,2 do
|
||||
local x,y=L[j],L[j+1]--0<x<3041, 290<y<1280
|
||||
x,y=-(x+240+y*.3)*.002,(y-580)*.9
|
||||
local x,y=L[j],L[j+1]--0<x<988, 290<y<1280
|
||||
x,y=-(x+280)*.002,(y-580)*.9--X=ang, Y=dist
|
||||
x,y=y*cos(x),-y*sin(x)--Rec-Pol-Rec
|
||||
L[j],L[j+1]=x,y+300
|
||||
end
|
||||
@@ -547,13 +536,12 @@ do--Game data tables
|
||||
ROOMENV={
|
||||
--Room config
|
||||
capacity=10,
|
||||
FTLock=true,
|
||||
|
||||
--Basic
|
||||
drop=30,
|
||||
lock=60,
|
||||
wait=0,
|
||||
fall=0,
|
||||
FTLock=true,
|
||||
drop=30,lock=60,
|
||||
wait=0,fall=0,
|
||||
hang=5,hurry=1e99,
|
||||
|
||||
--Control
|
||||
nextCount=6,
|
||||
|
||||
@@ -16,8 +16,8 @@ return{
|
||||
{"To New Players",
|
||||
"guide newbie noob",
|
||||
"help",
|
||||
"To new players that want to get better at the game:\n\tTwo principles:\n\t1. find a version with good controls (e.g. Techmino, Tetr.io, Tetris Online, Jstris, Tetr.js). Do not use those version used for programming practice.\n\t2. Build foundations in your skills (stable Techrashes using next queue to aid decisions), don't go for fancy T-Spins from the start.\n\n\tTwo main techniques:\n\t1. familiarize yourself with spawn locations of pieces, and the controls to move the piece into each location\n\t2. Plan ahead of where to put the pieces\nHere is a article written by a well-known player in Chinese Tetris community talking about advices to new players. Click the globe if you can read simplified Chinese.",
|
||||
"https://bilibili.com/read/cv2352939",
|
||||
"To new players that want to get better at the game:\n\tTwo principles:\n\t1. find a version with good controls (e.g. Techmino, Tetr.io, Tetris Online, Jstris, Tetr.js). Do not use those version used for programming practice.\n\t2. Build foundations in your skills (stable Techrashes using next queue to aid decisions), don't go for fancy T-Spins from the start.\n\n\tTwo main techniques:\n\t1. familiarize yourself with spawn locations of pieces, and the controls to move the piece into each location\n\t2. Plan ahead of where to put the pieces\nHere is a article written by a well-known player in Chinese Tetris community talking about advices to new players. Click the globe to read the translated article by User670.",
|
||||
"https://github.com/user670/temp/blob/master/tips_to_those_new_to_top.md",
|
||||
},
|
||||
{"Learning T-spins",
|
||||
"tspin learning study guide tips",
|
||||
@@ -167,7 +167,7 @@ return{
|
||||
{"Tetris Gems",
|
||||
"tetris online official gem",
|
||||
"game",
|
||||
"Another Tetris game from tetris.com. It has the gravity mechanism, and each game lasts for 2 minutes. There are three kinds of gem blocks with different abilities.",
|
||||
"Another Tetris game from tetris.com. It has the gravity mechanism, and each game lasts for 1 minute. There are three kinds of gem blocks with different abilities.",
|
||||
},
|
||||
{"Tetris Mind Bender",
|
||||
"tetris online official gem",
|
||||
@@ -259,7 +259,7 @@ return{
|
||||
{"Tetris Blitz",
|
||||
"blitz ea mobile phone",
|
||||
"game",
|
||||
"A mobile Tetris game by Electronic Arts (EA). It has the gravity mechanism, and each game lasts for 2 minutes. A bunch of minoes fall down to the field at the beginning of the game, and you can enter the \"Frenzy\" mode by performing Tetris line clears continuously. There are many different power-ups available.\n\nThis game is no longer available since January 2020.",
|
||||
"A mobile Tetris game by Electronic Arts (EA). It has the gravity mechanism, and each game lasts for 2 minutes. A bunch of minoes fall down to the field at the beginning of the game, and you can enter the \"Frenzy\" mode by performing line clears continuously. There are many different power-ups available. Also, this game has no top-out mechanism. When an incoming block overlaps with existing blocks in the field, the top lines will be cleared automatically. \n\nThis game is no longer available since April 2020.",
|
||||
},
|
||||
{"Tetris (EA)",
|
||||
"tetris ea galaxy universe cosmos mobile phone",
|
||||
@@ -269,7 +269,7 @@ return{
|
||||
{"Tetris (N3TWORK)",
|
||||
"tetris n3twork mobile phone",
|
||||
"game",
|
||||
"The latest mobile Tetris from N3TWORK Inc. It has a 3-minute ultra mode, a marathon mode and a Royale mode. The UI is great but its controls are not so good.",
|
||||
"The latest mobile Tetris from N3TWORK Inc. It has a 3-minute ultra mode, a marathon mode and a 100-player Royale mode. The UI is great but its controls are not so good.",
|
||||
},
|
||||
{"Tetris Beat",
|
||||
"tetris beat n3twork rhythm",
|
||||
@@ -378,7 +378,7 @@ return{
|
||||
{"Tetris",
|
||||
"tetris",
|
||||
"term",
|
||||
"The name of the game (and its trademark). Also the name for clearing 4 lines at one time in official games.\nCoined from Tetra (greek for \"four\") and Tennis (favorite sport of the creator of Tetris).",--Thanks to Alexey Pajitnov!
|
||||
"The name of the game (and its trademark). Also the name for clearing 4 lines at one time in official games.\nCoined from Tetra (greek for \"four\") and Tennis (favorite sport of the creator of Tetris). Also, the Tetris games developed by Nintendo and SEGA was licensed by TTC and these two companies do not have the copyright of Tetris.",--Thanks to Alexey Pajitnov!
|
||||
},
|
||||
{"All Clear",
|
||||
"pc perfectclear ac allclear",
|
||||
@@ -662,10 +662,10 @@ return{
|
||||
"term",
|
||||
"A way of stacking where you have a 6-block-wide stack on the left, and a 3-block-wide stack on the right.\nFor a skilled player, this method of stacking might reduce the keypresses needed for stacking, and is a popular Sprint stacking method. The reason why it works has to do with the fact that pieces spawn with a bias to the left.",
|
||||
},
|
||||
{"20G",
|
||||
"20g",
|
||||
{"Freestyle",
|
||||
"freestyle ziyou",
|
||||
"term",
|
||||
"The fastest falling speed of modern Tetris. In 20G, pieces do not have a falling process and instantly appear on the bottom. This sometimes also limits a piece's sideways movements, as it is not always possible to make a piece climb over a bump or out of a well in 20G.",
|
||||
"This term is usually used in 20TSDs. Freestyle means finishing 20 TSDs without using static stacking modes. Freestyle 20TSDs is more difficult than static tsacking modes such as LST, and the performance can represent the T-spin skills a player has in battles.",
|
||||
},
|
||||
{"Topping out",
|
||||
"die death topout toppingout",
|
||||
@@ -684,9 +684,14 @@ return{
|
||||
"https://youtu.be/z4WtWISkrdU",
|
||||
},
|
||||
{"Falling speed",
|
||||
"fallingspeed",
|
||||
"fallingspeed gravity",
|
||||
"term",
|
||||
"Falling speed is often described in terms of G, i.e. how many lines it falls in one frame (often assuming 60 frames per second).\nG is a large unit. The speed of Lv 1 in a regular Marathon (one second per line) is 1/60 G, and 1G is about Lv 13 speed. G usually caps at 20G, for there are only 20 (visible) blocks in the matrix's height.",
|
||||
"Falling speed is often described in terms of \"G\", i.e. how many lines the blocks fall in one frame (usually assuming 60 fps).\nG is a relatively large unit. The speed of Lv 1 in a regular Marathon (one second per line) is 1/60 G, and 1G is about Lv 13 speed. The highest speed of modern Tetris is 20G because the field height is 20 lines. In fact, the real meaning of 20G is \"Infinite falling speed\", and even when the field height is more than 20 lines, 20G modes force all the blocks to fall down to the bottom instantly. You can learn more about 20G at the \"20G\" entry.",
|
||||
},
|
||||
{"20G",
|
||||
"20g gravity instant",
|
||||
"term",
|
||||
"The fastest falling speed of modern Tetris. In 20G modes, pieces appear instantly on the bottom of the field without the actual process of \"falling down\". This sometimes also limits a piece's sideways movements, as it is not always possible to make a piece climb over a bump or out of a well in 20G. You can learn more at the unit \"G\" at the \"falling speed\" entry. ",
|
||||
},
|
||||
{"Lockdown Delay",
|
||||
"lockdelay lockdowndelay lockdowntimer",
|
||||
@@ -829,7 +834,7 @@ return{
|
||||
"The block skin used by the earliest version of Tetris.\nIn the early times, computers were all using Command Line Interface instead of Graphical User Interface, so at that time a single mino in the game of Tetris is represented using two enclosing square brackets [ ]. It looks kinds of like bones so it is sometimes called the bone blocks.\nIn Techmino, bone blocks are defined as \"A single, fancy block skin that all of the blocks use.\". Different block skins may have different types of bone block styles.",
|
||||
},
|
||||
{"Semi-invisible",
|
||||
"half invisible",
|
||||
"half invisible semi",
|
||||
"term",
|
||||
"Refers to a rule where the tetrominoes will become invisible after a period of time.\nThis time interval is not definite and it is acceptable to describe it as \"disappear after a few seconds\".",
|
||||
},
|
||||
|
||||
@@ -163,7 +163,7 @@ return{
|
||||
{"Tetris Gems",
|
||||
"宝石 tetris online official gems",
|
||||
"game",
|
||||
"tetris.com官网上的俄罗斯方块,限时2分钟挖掘,有重力机制。\n有三种消除后可以获得不同功能的宝石方块。",
|
||||
"tetris.com官网上的俄罗斯方块,限时1分钟挖掘,有重力机制。\n有三种消除后可以获得不同功能的宝石方块。",
|
||||
},
|
||||
{"Tetris Mind Bender",
|
||||
"技能 tetris online official mindbender",
|
||||
@@ -248,7 +248,7 @@ return{
|
||||
{"Tetris Blitz",
|
||||
"闪电战 tetris blitz ea",
|
||||
"game",
|
||||
"简称闪电战,EA代理的一款移动端方块,有重力连锁机制,限时2分钟,游戏开始会掉下一堆小方块;持续消四会进入Frenzy模式(场地下方会不断冒出垃圾行,帮助玩家制造大连锁)。有非常多的道具\n\n已于2020年1月下架。",
|
||||
"简称闪电战,EA代理的一款移动端方块,有重力连锁机制,限时2分钟,游戏开始会掉下一堆小方块;持续消行会进入Frenzy模式(场地下方会不断冒出垃圾行,帮助玩家制造大连锁,如果多次落块没有消行会强制结束Frenzy)。有非常多的道具。\n此外这款游戏似乎没有top-out机制。当新出现的方块与场地现有方块重叠时,场地最上方的几行会被自动清除。\n\n已于2020年4月下架。",
|
||||
},
|
||||
{"Tetris (EA)",
|
||||
"tetris ea",
|
||||
@@ -258,7 +258,7 @@ return{
|
||||
{"Tetris Beat",
|
||||
"节奏 tetris beat n3twork",
|
||||
"game",
|
||||
"N3TWORK代理的一款移动端方块,有按钮、滑动和点击三种操控模式。除了马拉松模式外还有一个“节奏”模式,玩家根据音乐节奏落块可以得到额外分数奖励。特效比较花眼,操控手感不是很好。",
|
||||
"N3TWORK代理的一款移动端方块,有马拉松、3分钟限时打分和Royale(最多100人对战)模式。UI比较好看,但不支持自定义键位;而且默认的按钮很小,手感不好。",
|
||||
},
|
||||
{"Tetris (N3TWORK)",
|
||||
"Tetris n3twork",
|
||||
@@ -266,7 +266,7 @@ return{
|
||||
"N3TWORK代理的一款移动端方块,有马拉松、限时打分和Royale(最多99人对战)模式。UI比较好看,但不支持自定义键位;而且默认的按钮很小,手感不好。"
|
||||
},
|
||||
{"Touhoumino",
|
||||
"东方 车万 touhoumino chewan dongfang touhou th",
|
||||
"东方 车万 偷猴 touhoumino chewan dongfang touhou th",
|
||||
"game",
|
||||
"玩家自制Windows平台方块,东方主题,其实就是一个Nullpomino的自带资源包的改版,将东方Project元素结合到俄罗斯方块的游戏,好玩但是难度较大,适合有方块基础并且各项能力都较强的玩家游玩(不然都不知道自己怎么死的)。",
|
||||
},
|
||||
@@ -578,7 +578,7 @@ return{
|
||||
"term",
|
||||
"交换功能,Hold的另一种表现形式,将手里的方块和Next槽中的第一个交换,一般同样不能连续使用。",
|
||||
},
|
||||
{"Deepdrop",
|
||||
{"深降",
|
||||
"深降 deepdrop shenjiang",
|
||||
"term",
|
||||
"开启后当方块触底时,再次按下软降会让方块尝试向下穿墙寻找放得下的地方,如果有就会直接瞬移到那\n该功能更偏向用于技术研究,对于ai来说有了它可以完全不用再考虑旋转系统,形状能容得下的地方一定都能到达",
|
||||
@@ -686,17 +686,12 @@ return{
|
||||
{"Freestyle",
|
||||
"freestyle ziyou",
|
||||
"term",
|
||||
"自由发挥的意思,常用于freestyle TSD(T2),指不用固定的堆叠方式而是随机应变完成20TSD。比用LST或者垃圾分类完成的20 TSD的含金量高不少",
|
||||
},
|
||||
{"20G",
|
||||
"高重力 20g",
|
||||
"term",
|
||||
"现代方块的最高下落速度,表观就是方块瞬间到底,不存在中间的下落过程,可能会让方块无法跨越壕沟/从山谷爬出。",
|
||||
"自由发挥的意思,常用于freestyle TSD(T2),指不用固定的堆叠方式而是随机应变完成20TSD。比用LST或者垃圾分类完成的20 TSD的难度要大,成绩也更能代表实战水平",
|
||||
},
|
||||
{"死亡判定",
|
||||
"死亡判定 die death siwang",
|
||||
"term",
|
||||
"现代方块普遍使用的死亡判定:\n1. 新出现的方块和场地方块有重叠(窒息,Block Out)(c4w比s4w强的原因,因为被打进18行都不会窒息);\n2. 方块锁定时完全在场地的外面(Lock Out);\n3. 场地内现存方块总高度大于40。(超高,Top Out)\n\n注:本游戏使用的死亡判定不包含上述的第二条和第三条。",
|
||||
"现代方块普遍使用的死亡判定:\n1. 新出现的方块和场地方块有重叠(窒息,Block Out)(c4w比s4w强的原因,因为被打进18行都不会窒息);\n2. 方块锁定时完全在场地的外面(Lock Out);\n3. 场地内现存方块总高度大于40。(超高,Top Out)\n\n注:本游戏使用的死亡判定默认不开启第二、三条。",
|
||||
},
|
||||
{"缓冲区",
|
||||
"缓冲区 buffer zone huanchongqu",
|
||||
@@ -712,7 +707,12 @@ return{
|
||||
{"下落速度",
|
||||
"下落速度 重力 drop speed zhongli gravity",
|
||||
"term",
|
||||
"一般用*G表示方块的下落速度,意思是每一帧方块往下移动多少格子,一秒下落一格就是1/60G(默认60fps),故G是一个很大的单位,20G即为上限(因为场地就20格)。",
|
||||
"一般用*G表示方块的下落速度,意思是每一帧方块往下移动多少格,一秒下落一格就是1/60G(默认60fps),可以看出G是一个很大的单位。因为场地就20格,所以一般认为20G即为上限,详见20G词条。",
|
||||
},
|
||||
{"20G",
|
||||
"高重力 20g",
|
||||
"term",
|
||||
"现代方块的最高下落速度,表观就是方块瞬间到底,不存在中间的下落过程,可能会让方块无法跨越壕沟/从山谷爬出。\n20G一般指的其实是“无限下落速度”,就算场地不止20格,“20G”也会让方块瞬间到底。\n本游戏(和部分其他游戏,推荐这么设计)中20G的优先级比其他玩家操作都高,即使是0arr的水平方向“瞬间移动”中途也会受到20G的影响。",
|
||||
},
|
||||
{"锁定延迟",
|
||||
"锁定延迟 重力 lock delay suoyan zhongli gravity",
|
||||
|
||||
@@ -15,6 +15,7 @@ return{
|
||||
newDay="A new day, a new beginning!",
|
||||
playedLong="You have been playing for a long time. Time to a break!",
|
||||
playedTooMuch="You have been playing for far too long! Techmino is fun, but remember to have some rests!",
|
||||
settingWarn="Modifing uncommon setting, be careful!",
|
||||
|
||||
atkModeName={"Random","Badges","K.O.s","Attackers"},
|
||||
royale_remain="$1 Players Remains",
|
||||
@@ -66,11 +67,19 @@ return{
|
||||
switchSpawnSFX="Please turn on the block spawn SFX!",
|
||||
needRestart="Restart to apply all changes",
|
||||
|
||||
loadError_errorMode="'$1' loading failed: no load mode '$2'",
|
||||
loadError_read="'$1' loading failed: read failed",
|
||||
loadError_noFile="'$1' loading failed no file:",
|
||||
loadError_other="'$1' loading failed: $2",
|
||||
loadError_unknown="'$1' loading failed: unknown reason",
|
||||
|
||||
saveError_duplicate="'$1' saving failed: duplicated filename",
|
||||
saveError_encode="'$1' saving failed: encode failed",
|
||||
saveError_other="'$1' saving failed: $2",
|
||||
saveError_unknown="'$1' saving failed: unknown reason",
|
||||
|
||||
copyDone="Copied!",
|
||||
saveDone="Data saved",
|
||||
saveError="Failed to save:",
|
||||
saveError_duplicate="Duplicated filename",
|
||||
loadError="Failed to load:",
|
||||
exportSuccess="Exported successfully",
|
||||
importSuccess="Imported successfully",
|
||||
dataCorrupted="Data corrupted",
|
||||
@@ -296,6 +305,8 @@ return{
|
||||
lock="Lock Delay",
|
||||
wait="Entry Delay",
|
||||
fall="Line Delay",
|
||||
hang="Death Delay",
|
||||
hurry="ARE Interruption",
|
||||
|
||||
capacity="Capacity",
|
||||
create="Create",
|
||||
@@ -303,6 +314,7 @@ return{
|
||||
ospin="O-spin",
|
||||
fineKill="100% Finesse",
|
||||
b2bKill="No B2B break",
|
||||
lockout="Fail when lock out",
|
||||
easyFresh="Normal Lock Reset",
|
||||
deepDrop="Deep Drop",
|
||||
bone="Bone Blocks",
|
||||
@@ -329,6 +341,7 @@ return{
|
||||
ctrl="Control Settings",
|
||||
key="Key Mappings",
|
||||
touch="Touch Settings",
|
||||
showVK="Show Virtual Keys",
|
||||
reTime="Start Delay",
|
||||
RS="Rotation System",
|
||||
menuPos="Menu Button Pos.",
|
||||
@@ -460,7 +473,6 @@ return{
|
||||
|
||||
norm="Normal",
|
||||
pro="Advanced",
|
||||
hide="Show Virtual Keys",
|
||||
icon="Icon",
|
||||
sfx="SFX",
|
||||
vib="VIB",
|
||||
@@ -479,6 +491,7 @@ return{
|
||||
wait="Entry Delay",
|
||||
fall="Line Delay",
|
||||
hang="Death Delay",
|
||||
hurry="ARE Interruption",
|
||||
|
||||
bg="Background",
|
||||
bgm="Music",
|
||||
@@ -497,6 +510,7 @@ return{
|
||||
|
||||
eventSet="Rule Set",
|
||||
|
||||
holdMode="Hold Mode",
|
||||
nextCount="Next",
|
||||
holdCount="Hold",
|
||||
infHold="Infinite Hold",
|
||||
@@ -515,6 +529,7 @@ return{
|
||||
ospin="O-Spin",
|
||||
fineKill="100% Finesse",
|
||||
b2bKill="No B2B break",
|
||||
lockout="Fail when lock out",
|
||||
easyFresh="Normal Lock Reset",
|
||||
deepDrop="Deep Drop",
|
||||
bone="Bone Blocks",
|
||||
@@ -727,7 +742,7 @@ return{
|
||||
['defender_l']= {"Defender", "LUNATIC", "Practice your defencing skills!"},
|
||||
['dig_h']= {"Driller", "HARD", "Digging practice!"},
|
||||
['dig_u']= {"Driller", "ULTIMATE", "Digging practice!"},
|
||||
['bigbang']= {"Big Bang", "EASY", "All-spin tutorial!\n[Under construction]"},
|
||||
['clearRush']= {"Clear Rush", "NORMAL", "All-spin tutorial!\n[Under construction]"},
|
||||
['c4wtrain_n']= {"C4W Training", "NORMAL", "Infinite combos"},
|
||||
['c4wtrain_l']= {"C4W Training", "LUNATIC", "Infinite combos"},
|
||||
['pctrain_n']= {"PC Training", "NORMAL", "Perfect Clear practice"},
|
||||
|
||||
@@ -5,6 +5,7 @@ return{
|
||||
newDay="[Anti-adicción] ¡Nuevo día, nuevo comienzo!",
|
||||
playedLong="[Anti-adicción] Estuviste jugando un buen rato hoy. Recuerda descansar de vez en cuando.",
|
||||
playedTooMuch="[Anti-adicción] ¡Has jugado mucho por hoy! No puedes jugar más.",
|
||||
-- settingWarn="Modifing uncommon setting, be careful!",
|
||||
|
||||
atkModeName={"Al azar","Medallas","KOs","Atacantes"},
|
||||
royale_remain="$1 Jugadores Restantes",
|
||||
@@ -55,11 +56,19 @@ return{
|
||||
switchSpawnSFX="Habilita los sonidos de aparición de las piezas ;)",
|
||||
needRestart="Reinicia Techmino para que los cambios tengan efecto.",
|
||||
|
||||
-- loadError_errorMode="'$1' loading failed: no load mode '$2'",
|
||||
-- loadError_read="'$1' loading failed: read failed",
|
||||
-- loadError_noFile="'$1' loading failed no file:",
|
||||
-- loadError_other="'$1' loading failed: $2",
|
||||
-- loadError_unknown="'$1' loading failed: unknown reason",
|
||||
|
||||
-- saveError_duplicate="'$1' saving failed: duplicated filename",
|
||||
-- saveError_encode="'$1' saving failed: encode failed",
|
||||
-- saveError_other="'$1' saving failed: $2",
|
||||
-- saveError_unknown="'$1' saving failed: unknown reason",
|
||||
|
||||
-- copyDone="Copied!",
|
||||
saveDone="Datos guardados",
|
||||
saveError="Error al guardar:",
|
||||
saveError_duplicate="Archivo ya existente",
|
||||
loadError="Error al cargar:",
|
||||
exportSuccess="Exportado con éxito",
|
||||
importSuccess="Importado con éxito",
|
||||
dataCorrupted="Los datos están corruptos.",
|
||||
@@ -262,6 +271,8 @@ return{
|
||||
lock="Retraso de Bloqueo",
|
||||
wait="Retraso de Spawneo",
|
||||
fall="Retraso de Línea",
|
||||
-- hang="Death Delay",
|
||||
-- hurry="ARE Interruption",
|
||||
|
||||
capacity="Capacidad",
|
||||
create="Crear",
|
||||
@@ -269,6 +280,7 @@ return{
|
||||
ospin="O-Spin",
|
||||
fineKill="100% Finesse",
|
||||
b2bKill="No Romper B2B ",
|
||||
-- lockout="Fail when lock out",
|
||||
easyFresh="Reinicio de Bloqueo Normal",
|
||||
deepDrop="Deep Drop",
|
||||
bone="Bone Block",
|
||||
@@ -295,6 +307,7 @@ return{
|
||||
ctrl="Sensibilidad",
|
||||
key="Teclas",
|
||||
touch="Controles Táctiles",
|
||||
showVK="Mostrar Tec. Virtual",
|
||||
reTime="Retraso de Inicio",
|
||||
RS="Sistema de Rotación",
|
||||
menuPos="Pos. del Botón de Menú",
|
||||
@@ -425,7 +438,6 @@ return{
|
||||
|
||||
norm="Normal",
|
||||
pro="Profesional",
|
||||
hide="Mostrar Tec. Virtual",
|
||||
icon="Ícono",
|
||||
sfx="SFX",
|
||||
vib="Vibr.",
|
||||
@@ -444,6 +456,7 @@ return{
|
||||
wait="Retraso de Spawneo",
|
||||
fall="Retraso de Línea",
|
||||
-- hang="Death Delay",
|
||||
-- hurry="ARE Interruption",
|
||||
|
||||
bg="Fondo",
|
||||
bgm="Música",
|
||||
@@ -481,6 +494,7 @@ return{
|
||||
ospin="O-Spin",
|
||||
fineKill="100% Finesse",
|
||||
b2bKill="No Romper B2B ",
|
||||
-- lockout="Fail when lock out",
|
||||
easyFresh="Reinicio de Bloqueo Normal",
|
||||
deepDrop="Deep Drop",
|
||||
bone="Bone Block",
|
||||
@@ -609,6 +623,9 @@ return{
|
||||
reset="Reiniciar",
|
||||
invis="A ciegas",
|
||||
},
|
||||
app_arithmetic={
|
||||
reset="Reiniciar",
|
||||
},
|
||||
savedata={
|
||||
export="Exportar al portapapeles",
|
||||
import="Importar de portapapeles",
|
||||
@@ -684,7 +701,7 @@ return{
|
||||
['defender_l']= {"Defensor", "Lunático", "¡Practica la defensa!"},
|
||||
['dig_h']= {"Downstack", "Difícil", "¡Practica el downstackeo!"},
|
||||
['dig_u']= {"Downstack", "Supremo", "¡Practica el downstackeo!"},
|
||||
['bigbang']= {"Big Bang", "Fácil", "¡Tutorial de All-spins!\n[Sin finalizar]"},
|
||||
-- ['clearRush']= {"Clear Rush", "NORMAL", "All-spin tutorial!\n[Under construction]"},
|
||||
['c4wtrain_n']= {"Entrenar C4W", "Normal", "Combos infinitos."},
|
||||
['c4wtrain_l']= {"Entrenar C4W", "Lunático", "Combos infinitos."},
|
||||
['pctrain_n']= {"Entrenar PC", "Normal", "Modo sencillo para practicar Perfect Clears."},
|
||||
|
||||
@@ -5,6 +5,7 @@ return{
|
||||
newDay="[Anti-addiction] Nouveau jour, nouveau commencement !",
|
||||
playedLong="[Anti-addiction] Vous avez joué pendant un bon bout de temps aujourd'hui. Faites des pauses.",
|
||||
playedTooMuch="[Anti-addiction] Vous avez joué trop longtemps ! Vous ne pouvez plus jouer.",
|
||||
-- settingWarn="Modifing uncommon setting, be careful!",
|
||||
|
||||
atkModeName={"Aléatoire","Badges","K.O.s faciles","Attaquants"},
|
||||
royale_remain="$1 Joueurs restants",
|
||||
@@ -56,11 +57,19 @@ return{
|
||||
switchSpawnSFX="Activez les effets sonores d'apparition des pièces pour jouer",
|
||||
needRestart="Fonctionnera dès la prochaine partie",
|
||||
|
||||
-- loadError_errorMode="'$1' loading failed: no load mode '$2'",
|
||||
-- loadError_read="'$1' loading failed: read failed",
|
||||
-- loadError_noFile="'$1' loading failed no file:",
|
||||
-- loadError_other="'$1' loading failed: $2",
|
||||
-- loadError_unknown="'$1' loading failed: unknown reason",
|
||||
|
||||
-- saveError_duplicate="'$1' saving failed: duplicated filename",
|
||||
-- saveError_encode="'$1' saving failed: encode failed",
|
||||
-- saveError_other="'$1' saving failed: $2",
|
||||
-- saveError_unknown="'$1' saving failed: unknown reason",
|
||||
|
||||
-- copyDone="Copied!",
|
||||
saveDone="Données sauvegardées",
|
||||
saveError="Sauvegarde échouée : ",
|
||||
-- saveError_duplicate="Duplicate filename",
|
||||
loadError="Lecture échouée : ",
|
||||
exportSuccess="Exporté avec succès",
|
||||
importSuccess="Importé avec succès",
|
||||
dataCorrupted="Données corrompues",
|
||||
@@ -258,6 +267,8 @@ return{
|
||||
lock="Délai de verrouillage",
|
||||
wait="Délai d'apparition",
|
||||
fall="Délai de ligne",
|
||||
-- hang="Death Delay",
|
||||
-- hurry="ARE Interruption",
|
||||
|
||||
-- capacity="Capacity",
|
||||
-- create="Create",
|
||||
@@ -265,6 +276,7 @@ return{
|
||||
ospin="O-spin",
|
||||
fineKill="100% Finesse",
|
||||
b2bKill="Sans perte de B2B",
|
||||
-- lockout="Fail when lock out",
|
||||
easyFresh="Réinit. de verrouillage normale",
|
||||
-- deepDrop="Deep Drop",
|
||||
bone="Crochets",
|
||||
@@ -292,6 +304,7 @@ return{
|
||||
ctrl="Paramètres de contrôle",
|
||||
key="Touches",
|
||||
touch="Boutons virtuels",
|
||||
showVK="Montrer les touches virtuelles",
|
||||
reTime="Délai de démarrage",
|
||||
RS="Système de rotation",
|
||||
-- menuPos="Menu button pos.",
|
||||
@@ -426,7 +439,6 @@ return{
|
||||
|
||||
norm="Normal",
|
||||
pro="Professionel",
|
||||
hide="Montrer les touches virtuelles",
|
||||
icon="Icône",
|
||||
sfx="Sons",
|
||||
vib="Vib.",
|
||||
@@ -445,6 +457,7 @@ return{
|
||||
wait="Délai d'apparition",
|
||||
fall="Délai de ligne",
|
||||
-- hang="Death Delay",
|
||||
-- hurry="ARE Interruption",
|
||||
|
||||
bg="Arrière-plan",
|
||||
bgm="Musique",
|
||||
@@ -482,6 +495,7 @@ return{
|
||||
ospin="O-spin",
|
||||
fineKill="100% Finesse",
|
||||
b2bKill="Sans perte de B2B",
|
||||
-- lockout="Fail when lock out",
|
||||
easyFresh="Réinit. de verrouillage normale",
|
||||
-- deepDrop="Deep Drop",
|
||||
bone="Crochets",
|
||||
@@ -610,6 +624,9 @@ return{
|
||||
reset="Réinitialiser",
|
||||
invis="Aveugler",
|
||||
},
|
||||
app_arithmetic={
|
||||
reset="Réinitialiser",
|
||||
},
|
||||
savedata={
|
||||
-- export="Export to clipboard",
|
||||
-- import="Import from clipboard",
|
||||
@@ -688,7 +705,7 @@ return{
|
||||
['defender_l']= {"Défendant", "LUNATIQUE", "Soyez défensifs !"},
|
||||
['dig_h']= {"Perceuse", "DIFFICILE", "Essayez de creuser !"},
|
||||
['dig_u']= {"Perceuse", "ULTIME", "Essayez de creuser !"},
|
||||
['bigbang']= {"Big Bang", "FACILE", "Tutoriel All-Spin\nEn construction..."},
|
||||
-- ['clearRush']= {"Clear Rush", "NORMAL", "All-spin tutorial!\n[Under construction]"},
|
||||
['c4wtrain_n']= {"Mode essai C4W", "NORMAL", "Combos infinis."},
|
||||
['c4wtrain_l']= {"Mode essai C4W", "LUNATIQUE", "Combos infinis."},
|
||||
['pctrain_n']= {"Mode essai PC", "NORMAL", "Mode Perfect Clear simple"},
|
||||
|
||||
@@ -6,6 +6,7 @@ return{
|
||||
newDay="[Anti-vício] Novo dia, um começo novo!",
|
||||
playedLong="[Anti-vício] Você andou jogando bastante hoje. Certifique-se de fazer pausas.",
|
||||
playedTooMuch="[Anti-vício] Você esteve jogando demais hoje! Você não pode jogar mais.",
|
||||
-- settingWarn="Modifing uncommon setting, be careful!",
|
||||
|
||||
atkModeName={"Aleatório","Emblemas","K.O.s","Atacantes"},
|
||||
royale_remain="$1 Jogadores restantes",
|
||||
@@ -56,11 +57,19 @@ return{
|
||||
switchSpawnSFX="Switch on spawn SFX to play",
|
||||
needRestart="Funciona após reiniciar",
|
||||
|
||||
-- loadError_errorMode="'$1' loading failed: no load mode '$2'",
|
||||
-- loadError_read="'$1' loading failed: read failed",
|
||||
-- loadError_noFile="'$1' loading failed no file:",
|
||||
-- loadError_other="'$1' loading failed: $2",
|
||||
-- loadError_unknown="'$1' loading failed: unknown reason",
|
||||
|
||||
-- saveError_duplicate="'$1' saving failed: duplicated filename",
|
||||
-- saveError_encode="'$1' saving failed: encode failed",
|
||||
-- saveError_other="'$1' saving failed: $2",
|
||||
-- saveError_unknown="'$1' saving failed: unknown reason",
|
||||
|
||||
-- copyDone="Copied!",
|
||||
saveDone="Data Salva",
|
||||
saveError="Falha ao salvar:",
|
||||
-- saveError_duplicate="Duplicate filename",
|
||||
loadError="Falha ao ler:",
|
||||
exportSuccess="Exportado com sucesso",
|
||||
importSuccess="Importado com sucesso",
|
||||
dataCorrupted="Data corrompida",
|
||||
@@ -284,6 +293,8 @@ return{
|
||||
lock="Delay Trava",
|
||||
wait="Delay Entrada",
|
||||
fall="Delay Linha",
|
||||
-- hang="Death Delay",
|
||||
-- hurry="ARE Interruption",
|
||||
|
||||
-- capacity="Capacity",
|
||||
-- create="Create",
|
||||
@@ -291,6 +302,7 @@ return{
|
||||
ospin="O-Spin",
|
||||
fineKill="100% Finesse",
|
||||
b2bKill="Sem Quebrar B2B",
|
||||
-- lockout="Fail when lock out",
|
||||
easyFresh="Reset De Trava Normal",
|
||||
-- deepDrop="Deep Drop",
|
||||
bone="Bone Blocks",
|
||||
@@ -317,6 +329,7 @@ return{
|
||||
ctrl="Config. controle",
|
||||
key="Map. teclas",
|
||||
touch="Config. toque",
|
||||
showVK="Mostrar tecla virtual",
|
||||
reTime="Demora iniciação",
|
||||
RS="Sistema de rotação",
|
||||
-- menuPos="Menu button pos.",
|
||||
@@ -448,7 +461,6 @@ return{
|
||||
|
||||
norm="Normal",
|
||||
pro="Professional",
|
||||
hide="Mostrar tecla virtual",
|
||||
icon="Icone",
|
||||
sfx="SFX",
|
||||
vib="VIB",
|
||||
@@ -467,6 +479,7 @@ return{
|
||||
wait="Delay Entrada",
|
||||
fall="Delay Linha",
|
||||
-- hang="Death Delay",
|
||||
-- hurry="ARE Interruption",
|
||||
|
||||
bg="Fundo",
|
||||
bgm="Música",
|
||||
@@ -504,6 +517,7 @@ return{
|
||||
ospin="O-Spin",
|
||||
fineKill="100% Finesse",
|
||||
b2bKill="Sem Quebrar B2B",
|
||||
-- lockout="Fail when lock out",
|
||||
easyFresh="Reset De Trava Normal",
|
||||
-- deepDrop="Deep Drop",
|
||||
bone="Bone Blocks",
|
||||
@@ -640,6 +654,9 @@ return{
|
||||
reset="Resetar",
|
||||
invis="Cego",
|
||||
},
|
||||
app_arithmetic={
|
||||
reset="Resetar",
|
||||
},
|
||||
savedata={
|
||||
-- export="Export to clipboard",
|
||||
-- import="Import from clipboard",
|
||||
@@ -718,7 +735,7 @@ return{
|
||||
['defender_l']= {"Defensor", "LUNÁTICO", "Prática de defensiva!"},
|
||||
['dig_h']= {"Cavador", "DIFÍCIL", "Prática de cavar!"},
|
||||
['dig_u']= {"Cavador", "ULTIMATE", "Prática de cavar!"},
|
||||
['bigbang']= {"Big Bang", "FÁCIL", "Tutorial de todos giros!\n[Em construção]"},
|
||||
-- ['clearRush']= {"Clear Rush", "NORMAL", "All-spin tutorial!\n[Under construction]"},
|
||||
['c4wtrain_n']= {"Treinamento C4W", "NORMAL", "Combos infinitos."},
|
||||
['c4wtrain_l']= {"Treinamento C4W", "LUNÁTICO", "Combos infinitos."},
|
||||
['pctrain_n']= {"Treinamento PC", "NORMAL", "Modo simples de limpeza perfeita."},
|
||||
|
||||
@@ -58,11 +58,19 @@ return{
|
||||
ai_mission="X!!!",
|
||||
needRestart="!!*#R#*!!",
|
||||
|
||||
loadError_errorMode="'$1' ↑x!: no load mode '$2'",
|
||||
loadError_read="'$1' ↑x!: read failed",
|
||||
loadError_noFile="'$1' ↑oading failed no file:",
|
||||
loadError_other="'$1' ↑x!: $2",
|
||||
loadError_unknown="'$1' ↑x!: unknown reason",
|
||||
|
||||
saveError_duplicate="'$1' ↓x!: duplicated filename",
|
||||
saveError_encode="'$1' ↓x!: encode failed",
|
||||
saveError_other="'$1' ↓x!: $2",
|
||||
saveError_unknown="'$1' ↓x!: unknown reason",
|
||||
|
||||
-- copyDone="Copied!",
|
||||
saveDone="~~~",
|
||||
saveError="x!:",
|
||||
saveError_duplicate="X←→X ?",
|
||||
loadError="x!:",
|
||||
exportSuccess="~Out~",
|
||||
importSuccess="~In~",
|
||||
dataCorrupted="XXXXX",
|
||||
@@ -190,6 +198,8 @@ return{
|
||||
lock="↓_",
|
||||
wait="→=",
|
||||
fall="↓=",
|
||||
hang=":(=",
|
||||
hurry="_x",
|
||||
|
||||
capacity="<0/?>",
|
||||
create=">",
|
||||
@@ -197,6 +207,7 @@ return{
|
||||
ospin="O→Any",
|
||||
fineKill="12 XX 21",
|
||||
b2bKill="_1 XX",
|
||||
lockout="X ↑_↓_↑",
|
||||
easyFresh="↓_↓_↓_",
|
||||
deepDrop="\\↓↓/",
|
||||
bone="[]",
|
||||
@@ -224,6 +235,7 @@ return{
|
||||
ctrl="=?=",
|
||||
key="=?",
|
||||
touch="_?",
|
||||
showVK="--?",
|
||||
reTime="3-2-1",
|
||||
RS="''?",
|
||||
menuPos="←M→?",
|
||||
@@ -353,7 +365,6 @@ return{
|
||||
|
||||
norm="-",
|
||||
pro="+",
|
||||
hide="--?",
|
||||
icon="@?",
|
||||
sfx="#!#",
|
||||
vib="=~=",
|
||||
@@ -372,6 +383,7 @@ return{
|
||||
wait="→=",
|
||||
fall="↓=",
|
||||
hang=":(=",
|
||||
hurry="_x",
|
||||
|
||||
bg="{~}",
|
||||
bgm="(~)",
|
||||
@@ -409,6 +421,7 @@ return{
|
||||
ospin="O→Any",
|
||||
fineKill="12 XX 21",
|
||||
b2bKill="_1 XX",
|
||||
lockout="X ↑_↓_↑",
|
||||
easyFresh="↓_↓_↓_",
|
||||
deepDrop="\\↓↓/",
|
||||
bone="[]",
|
||||
|
||||
@@ -11,6 +11,7 @@ return{fallback='zh',
|
||||
},
|
||||
playedLong="玩很久了, 给我注意点",
|
||||
playedTooMuch="特么再敢玩眼睛瞎掉, 爬!",
|
||||
settingWarn="别乱动,小心点",
|
||||
|
||||
royale_remain="剩 $1 人",
|
||||
cmb={nil,"1连","2连","3连","4连","5连","6连","7连","8连","9连","10连!","11连!","12连!","13连!","14连!","15连!","16连!","17连!","18连!","19连!","Very 连"},
|
||||
@@ -253,7 +254,7 @@ return{fallback='zh',
|
||||
['defender_l']= {"防守", "疯狂", "防守练习"},
|
||||
['dig_h']= {"挖掘", "困难", "挖掘练习"},
|
||||
['dig_u']= {"挖掘", "极限", "挖掘练习"},
|
||||
['bigbang']= {"大爆炸", "简单", "All-spin入门\n还没做好"},
|
||||
['clearRush']= {"清版竞速", "普通", "舒服"},
|
||||
['c4wtrain_n']= {"C4W练习", "普通", "无 限 连 击"},
|
||||
['c4wtrain_l']= {"C4W练习", "疯狂", "无 限 连 击"},
|
||||
['pctrain_n']= {"全清训练", "普通", "随便打打"},
|
||||
|
||||
@@ -15,6 +15,7 @@ return{
|
||||
newDay="新的一天,新的开始~",
|
||||
playedLong="已经玩很久了!注意休息!",
|
||||
playedTooMuch="今天玩太久啦!打块好玩但也要适可而止哦~",
|
||||
settingWarn="正在修改不常用设置,小心操作!",
|
||||
|
||||
atkModeName={"随机","徽章","击杀","反击"},
|
||||
royale_remain="剩余 $1 名玩家",
|
||||
@@ -66,11 +67,19 @@ return{
|
||||
switchSpawnSFX="请开启方块出生音效",
|
||||
needRestart="重新开始以生效",
|
||||
|
||||
loadError_errorMode="文件 '$1' 读取失败:无加载模式 '$2'",
|
||||
loadError_read="文件 '$1' 读取失败:读取失败",
|
||||
loadError_noFile="文件 '$1' 读取失败:没有文件",
|
||||
loadError_other="文件 '$1' 读取失败:$2",
|
||||
loadError_unknown="文件 '$1' 读取失败:原因未知",
|
||||
|
||||
saveError_duplicate="文件 '$1' 保存失败:文件已存在",
|
||||
saveError_encode="文件 '$1' 保存失败:编码错误",
|
||||
saveError_other="文件 '$1' 保存失败:$2",
|
||||
saveError_unknown="文件 '$1' 保存失败:原因未知",
|
||||
|
||||
copyDone="复制成功!",
|
||||
saveDone="保存成功!",
|
||||
saveError="保存失败:",
|
||||
saveError_duplicate="文件名重复",
|
||||
loadError="读取失败:",
|
||||
exportSuccess="导出成功",
|
||||
importSuccess="导入成功",
|
||||
dataCorrupted="数据损坏",
|
||||
@@ -296,6 +305,8 @@ return{
|
||||
lock="锁定延迟",
|
||||
wait="出块等待",
|
||||
fall="消行延迟",
|
||||
hang="窒息延迟",
|
||||
hurry="ARE打断",
|
||||
|
||||
capacity="房间容量",
|
||||
create="创建",
|
||||
@@ -303,6 +314,7 @@ return{
|
||||
ospin="O-spin",
|
||||
fineKill="强制极简",
|
||||
b2bKill="强制B2B",
|
||||
lockout="锁定在外时失败",
|
||||
easyFresh="普通刷新锁延",
|
||||
deepDrop="深降",
|
||||
bone="骨块",
|
||||
@@ -329,6 +341,7 @@ return{
|
||||
ctrl="控制设置",
|
||||
key="键位设置",
|
||||
touch="触屏设置",
|
||||
showVK="显示虚拟按键",
|
||||
reTime="开局等待时间",
|
||||
RS="旋转系统",
|
||||
menuPos="菜单按钮位置",
|
||||
@@ -459,7 +472,6 @@ return{
|
||||
|
||||
norm="标准",
|
||||
pro="专业",
|
||||
hide="显示虚拟按键",
|
||||
icon="图标",
|
||||
sfx="按键音效",
|
||||
vib="按键振动",
|
||||
@@ -478,6 +490,7 @@ return{
|
||||
wait="出块等待",
|
||||
fall="消行延迟",
|
||||
hang="窒息延迟",
|
||||
hurry="ARE打断",
|
||||
|
||||
bg="背景",
|
||||
bgm="音乐",
|
||||
@@ -515,6 +528,7 @@ return{
|
||||
ospin="O-spin",
|
||||
fineKill="强制极简",
|
||||
b2bKill="强制B2B",
|
||||
lockout="锁定在外时失败",
|
||||
easyFresh="普通刷新锁延",
|
||||
deepDrop="深降",
|
||||
bone="骨块",
|
||||
@@ -654,6 +668,9 @@ return{
|
||||
reset="重置",
|
||||
invis="盲打",
|
||||
},
|
||||
app_arithmetic={
|
||||
reset="重置",
|
||||
},
|
||||
savedata={
|
||||
export="导出到剪切板",
|
||||
import="从剪切板导入",
|
||||
@@ -730,7 +747,7 @@ return{
|
||||
['defender_l']= {"防守", "疯狂", "防守练习"},
|
||||
['dig_h']= {"挖掘", "困难", "挖掘练习"},
|
||||
['dig_u']= {"挖掘", "极限", "挖掘练习"},
|
||||
['bigbang']= {"大爆炸", "简单", "All-spin 入门教程\n施工中"},
|
||||
['clearRush']= {"清版竞速", "普通", "All-spin 入门教程\n施工中"},
|
||||
['c4wtrain_n']= {"C4W练习", "普通", "无 限 连 击"},
|
||||
['c4wtrain_l']= {"C4W练习", "疯狂", "无 限 连 击"},
|
||||
['pctrain_n']= {"全清训练", "普通", "简易PC题库,熟悉全清定式的组合"},
|
||||
@@ -900,7 +917,7 @@ return{
|
||||
"快去打一把100%极简看看会怎样",
|
||||
"锟斤拷锟斤拷锟斤拷",
|
||||
"来学编程,好玩的",
|
||||
"老牌益智游戏了属于是",
|
||||
"老牌益智游戏了",
|
||||
"连续pc有大量知识要背,不过背出来后随手10连pc不是问题",
|
||||
"六连块总共有……?那不重要,不会做的(大概",
|
||||
"论如何正确使用Unicode私用区定制字体",
|
||||
@@ -922,13 +939,13 @@ return{
|
||||
"你们考虑过Z酱的感受吗?没有!你们只考虑你自己。",
|
||||
"你说彩蛋?嗯…算是有,可以找找",
|
||||
"你有一个好",
|
||||
"你知道吗:看主页机器人玩可能比较费电",
|
||||
"你知道吗:全程不使用任何旋转键完成40行模式是有可能的",
|
||||
"你知道吗:全程不使用左右移动键完成40行模式是有可能的",
|
||||
"你知道吗:停留在模式地图界面很费电",
|
||||
"你知道吗:在其他(方块)游戏相关场合提及本游戏是很不礼貌的",
|
||||
"你知道吗:O-Spin是在0.8.20 (Fantastic Global Update II)中诞生的",
|
||||
"你知道吗:TRS旋转系统的最初形态在0.0.091726版本就存在了",
|
||||
"你知道吗[001]看主页机器人玩可能比较费电",
|
||||
"你知道吗[002]全程不使用任何旋转键完成40行模式是有可能的",
|
||||
"你知道吗[003]全程不使用左右移动键完成40行模式是有可能的",
|
||||
"你知道吗[004]停留在模式地图界面很费电",
|
||||
"你知道吗[005]在其他(方块)游戏相关场合提及本游戏是很不礼貌的",
|
||||
"你知道吗[006]O-Spin是在0.8.20 (Fantastic Global Update II)中诞生的",
|
||||
"你知道吗[007]TRS旋转系统的最初形态在0.0.091726版本就存在了",
|
||||
"你准备好了吗?",
|
||||
"其实很多时候“吃键”是玩家对游戏机制不了解或者自己的操作问题导致的",
|
||||
"其实S和Z有四个方向(状态),虽然看起来只有两个",
|
||||
@@ -946,6 +963,25 @@ return{
|
||||
"少女祈祷中",
|
||||
"少玩点游戏,多注意眨眼和休息",
|
||||
"深降了解一下",
|
||||
"时间碎片[000] 2021/11/21开始tip加入这个版块",
|
||||
"时间碎片[001] V0.7.9加入O-spin",
|
||||
"时间碎片[002] V0.7.19加入语音系统",
|
||||
"时间碎片[003] V0.7.22加入平滑下落",
|
||||
"时间碎片[004] V0.8.5加入模式地图",
|
||||
"时间碎片[005] V0.8.19加入五连块",
|
||||
"时间碎片[006] V0.9.0加入自定义序列和模式",
|
||||
"时间碎片[007] V0.10.0加入录像回放",
|
||||
"时间碎片[008] V0.11.1加入小z词典",
|
||||
"时间碎片[009] V0.12.2加入mod系统",
|
||||
"时间碎片[010] V0.13.0联网对战测试",
|
||||
"时间碎片[011] V0.13.2加入任意场地高度",
|
||||
"时间碎片[012] V0.13.3加入控制台",
|
||||
"时间碎片[013] V0.14.4加入第一首不是用Beepbox制作的BGM",
|
||||
"时间碎片[014] V0.14.5加入第一首社区玩家自制BGM",
|
||||
"时间碎片[015] V0.15.5加入录像回放菜单",
|
||||
"时间碎片[016] V0.16.0应该是单次更新内容最多的(起码更新历史最长)",
|
||||
"时间碎片[017] V0.16.2加入打击垫样式的音效室",
|
||||
"时间碎片[018] V0.17.0加入手柄的摇杆和扳机支持",
|
||||
"使用固定堆叠方法达成20TSD难度很低",
|
||||
"试试用跳舞毯打块",
|
||||
"适度游戏益脑,沉迷游戏伤身,合理安排时间,享受健康生活",
|
||||
@@ -1035,18 +1071,18 @@ return{
|
||||
"e^(πi)=-1",
|
||||
"e^(πi/2)=i",
|
||||
"e^(πi/4)=(1+i)/√2",
|
||||
"Farter:“成天被夸赞‘好玩’的”",
|
||||
"Farter:“可以形成方块圈子小中心话题,同作者一起衍生一些概念与梗的”",
|
||||
"Farter:“论方块的软工意义(就算这么小个范围内,各种取舍蒙混翻车现象都总会以很易懂的方式出现(”",
|
||||
"Farter:“民间微创新”",
|
||||
"Farter:“民间音lè与图案”",
|
||||
"Farter:“民间游戏设计”",
|
||||
"Farter:“是方块爱好者研究平台”",
|
||||
"Farter:“是方块萌新入坑接收器”",
|
||||
"Farter:“是居家旅行装逼必备”",
|
||||
"Farter:“是民间UI动效艺术作品”",
|
||||
"Farter:“是一滩散乱的代码组成的蜜汁结构”",
|
||||
"Farter:“它是现在的techmino已发布版本”",
|
||||
"Farter评[01]:“成天被夸赞‘好玩’的”",
|
||||
"Farter评[02]:“可以形成方块圈子小中心话题,同作者一起衍生一些概念与梗的”",
|
||||
"Farter评[03]:“论方块的软工意义(就算这么小个范围内,各种取舍蒙混翻车现象都总会以很易懂的方式出现(”",
|
||||
"Farter评[04]:“民间微创新”",
|
||||
"Farter评[05]:“民间音lè与图案”",
|
||||
"Farter评[06]:“民间游戏设计”",
|
||||
"Farter评[07]:“是方块爱好者研究平台”",
|
||||
"Farter评[08]:“是方块萌新入坑接收器”",
|
||||
"Farter评[09]:“是居家旅行装逼必备”",
|
||||
"Farter评[10]:“是民间UI动效艺术作品”",
|
||||
"Farter评[11]:“是一滩散乱的代码组成的蜜汁结构”",
|
||||
"Farter评[12]:“它是现在的techmino已发布版本”",
|
||||
"fin neo iso 是满足tspin条件的特殊t2的名字",
|
||||
"git commit",
|
||||
"git push -f",
|
||||
|
||||
@@ -142,21 +142,21 @@ return{
|
||||
['defender_l']= {"防守", "疯狂", "防守练习"},
|
||||
['dig_h']= {"挖掘", "困难", "挖掘练习"},
|
||||
['dig_u']= {"挖掘", "极限", "挖掘练习"},
|
||||
['bigbang']= {"大爆炸", "简单", "All-spin 入门教程\n施工中"},
|
||||
['clearRush']= {"清版竞速", "普通", "所有块的回旋入门\n还没做好"},
|
||||
['c4wtrain_n']= {"中四宽练习", "普通", "无 限 连 击"},
|
||||
['c4wtrain_l']= {"中四宽练习", "疯狂", "无 限 连 击"},
|
||||
['pctrain_n']= {"全清训练", "普通", "简易全清题库,熟悉全清定式的组合"},
|
||||
['pctrain_l']= {"全清训练", "疯狂", "困难PC题库,强算力者进"},
|
||||
['pctrain_l']= {"全清训练", "疯狂", "困难全清题库,强算力者进"},
|
||||
['pc_n']= {"全清挑战", "普通", "100行内刷全清"},
|
||||
['pc_h']= {"全清挑战", "困难", "100行内刷全清"},
|
||||
['pc_l']= {"全清挑战", "疯狂", "100行内刷全清"},
|
||||
['pc_inf']= {"无尽全清挑战", "", "你能连续做多少PC?"},
|
||||
['tech_n']= {"科研", "普通", "禁止断B2B"},
|
||||
['pc_inf']= {"无尽全清挑战", "", "你能连续做多少全清?"},
|
||||
['tech_n']= {"科研", "普通", "禁止断满贯"},
|
||||
['tech_n_plus']= {"科研", "普通+", "仅允许回旋与全清"},
|
||||
['tech_h']= {"科研", "困难", "禁止断B2B"},
|
||||
['tech_h']= {"科研", "困难", "禁止断满贯"},
|
||||
['tech_h_plus']= {"科研", "困难+", "仅允许回旋与全清"},
|
||||
['tech_l']= {"科研", "疯狂", "禁止断B2B"},
|
||||
['tech_l_plus']= {"科研", "疯狂+", "仅允许spin与PC"},
|
||||
['tech_l']= {"科研", "疯狂", "禁止断满贯"},
|
||||
['tech_l_plus']= {"科研", "疯狂+", "仅允许回旋与全清"},
|
||||
['tech_finesse']= {"科研", "极简", "强制最简操作"},
|
||||
['tech_finesse_f']= {"科研", "极简+", "禁止普通消除,强制最简操作"},
|
||||
['tsd_e']= {"T2挑战", "简单", "你能连续做几个T旋双清?"},
|
||||
|
||||
@@ -15,6 +15,7 @@ return{
|
||||
newDay="新的一天,新的开始!",
|
||||
playedLong="你已经玩了很长时间了。一定要好好休息!",
|
||||
playedTooMuch="你玩得太久了!玩方块游戏很有趣,但现在是休息的时候了。",
|
||||
settingWarn="修改设置时,请小心!",
|
||||
|
||||
atkModeName={"随机的","徽章","击败","攻击者"},
|
||||
royale_remain="剩余$1球员",
|
||||
@@ -66,11 +67,19 @@ return{
|
||||
switchSpawnSFX="请打开繁殖特技效果",
|
||||
needRestart="请重试以使更改生效",
|
||||
|
||||
loadError_errorMode="'$1' 加载失败:无加载模式 '$2'",
|
||||
loadError_read="'$1' 加载失败:读取失败",
|
||||
loadError_noFile="'$1' 加载失败:没有文件",
|
||||
loadError_other="'$1' 加载失败:$2",
|
||||
loadError_unknown="'$1' 加载失败:原因未知",
|
||||
|
||||
saveError_duplicate="'$1' 保存失败:文件名重复",
|
||||
saveError_encode="'$1' 保存失败:编码失败",
|
||||
saveError_other="'$1' 保存失败:$2",
|
||||
saveError_unknown="'$1' 保存失败:原因未知",
|
||||
|
||||
copyDone="收到了!",
|
||||
saveDone="保存的数据",
|
||||
saveError="未能保存:",
|
||||
saveError_duplicate="重复文件名",
|
||||
loadError="未能加载:",
|
||||
exportSuccess="成功导出",
|
||||
importSuccess="导入成功",
|
||||
dataCorrupted="数据损坏",
|
||||
@@ -294,6 +303,8 @@ return{
|
||||
lock="锁定延迟",
|
||||
wait="进入延迟",
|
||||
fall="线路延迟",
|
||||
hang="毁灭延迟",
|
||||
hurry="是打扰吗",
|
||||
|
||||
capacity="容量",
|
||||
create="创造",
|
||||
@@ -301,6 +312,7 @@ return{
|
||||
ospin="O型自旋",
|
||||
fineKill="100%精巧",
|
||||
b2bKill="没有背靠背中断",
|
||||
lockout="锁定时失败",
|
||||
easyFresh="正常锁复位",
|
||||
deepDrop="深滴",
|
||||
bone="骨块",
|
||||
@@ -327,6 +339,7 @@ return{
|
||||
ctrl="控制设置",
|
||||
key="键映射",
|
||||
touch="触摸设置",
|
||||
showVK="显示虚拟密钥",
|
||||
reTime="启动延迟",
|
||||
RS="轮换制",
|
||||
menuPos="菜单按钮位置",
|
||||
@@ -412,7 +425,6 @@ return{
|
||||
ihs="初始持有",
|
||||
irs="初始旋转",
|
||||
ims="初始运动",
|
||||
reset="重置",
|
||||
},
|
||||
setting_key={
|
||||
a1="向左移动",
|
||||
@@ -458,7 +470,6 @@ return{
|
||||
|
||||
norm="正常",
|
||||
pro="专业的",
|
||||
hide="显示虚拟密钥",
|
||||
icon="偶像",
|
||||
sfx="特技效果",
|
||||
vib="振动",
|
||||
@@ -477,6 +488,7 @@ return{
|
||||
wait="进入延迟",
|
||||
fall="线路延迟",
|
||||
hang="毁灭延迟",
|
||||
hurry="是打扰吗",
|
||||
|
||||
bg="背景",
|
||||
bgm="音乐",
|
||||
@@ -514,6 +526,7 @@ return{
|
||||
ospin="O型自旋",
|
||||
fineKill="100%精巧",
|
||||
b2bKill="没有背靠背中断",
|
||||
lockout="锁定时失败",
|
||||
easyFresh="正常锁复位",
|
||||
deepDrop="深滴",
|
||||
bone="骨块",
|
||||
@@ -612,7 +625,6 @@ return{
|
||||
revKB="逆转",
|
||||
},
|
||||
app_schulteG={
|
||||
reset="重置",
|
||||
rank="大小",
|
||||
invis="英维斯",
|
||||
disappear="隐藏",
|
||||
@@ -624,30 +636,25 @@ return{
|
||||
app_AtoZ={
|
||||
level="水平仪",
|
||||
keyboard="键盘",
|
||||
reset="重置",
|
||||
},
|
||||
app_2048={
|
||||
reset="重置",
|
||||
invis="英维斯",
|
||||
tapControl="抽头控制",
|
||||
|
||||
skip="跳转",
|
||||
},
|
||||
app_ten={
|
||||
reset="重置",
|
||||
next="下一个",
|
||||
invis="英维斯",
|
||||
fast="快速的",
|
||||
},
|
||||
app_dtw={
|
||||
reset="重置",
|
||||
color="颜色",
|
||||
mode="模式",
|
||||
bgm="血糖监测",
|
||||
arcade="游乐中心",
|
||||
},
|
||||
app_link={
|
||||
reset="重置",
|
||||
invis="英维斯",
|
||||
},
|
||||
savedata={
|
||||
@@ -726,7 +733,7 @@ return{
|
||||
['defender_l']= {"防守者", "疯子", "练习你的防守技巧!"},
|
||||
['dig_h']= {"钻机", "硬的", "挖掘练习!"},
|
||||
['dig_u']= {"钻机", "终极", "挖掘练习!"},
|
||||
['bigbang']= {"大爆炸", "容易", "所有旋转教程\n[在建]"},
|
||||
['clearRush']= {"清晰的冲", "普通", "所有旋转教程\n[在建]"},
|
||||
['c4wtrain_n']= {"C4W训练", "正常", "无限组合"},
|
||||
['c4wtrain_l']= {"C4W训练", "疯子", "无限组合"},
|
||||
['pctrain_n']= {"电脑培训", "正常", "完美清晰的实践"},
|
||||
@@ -758,7 +765,7 @@ return{
|
||||
['infinite_dig']= {"无限:挖掘", "", "挖,挖,挖"},
|
||||
['marathon_inf']= {"马拉松", "无尽", "无尽马拉松"},
|
||||
|
||||
['custom_clear']= {"习俗", "正常"} ,
|
||||
['custom_clear']= {"习俗", "正常"},
|
||||
['custom_puzzle']= {"习俗", "令人费解的"},
|
||||
},
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ Gameplay:
|
||||
Play until the end or achieve the level's goal to win.
|
||||
|
||||
Rotation system:
|
||||
Uses Techmino's custom rotation system. Too lazy to write the details
|
||||
Uses TRS (Techmino Rotation System) by default. The game allows players to choose other commonly used rotation systems (generally unnecessary)
|
||||
|
||||
Spin detection:
|
||||
Satisfies "3 corner" rule +2 points
|
||||
@@ -87,4 +87,4 @@ Custom mode:
|
||||
empty cells can be in any state;
|
||||
regular colored cells have to be made of the corresponding block;
|
||||
garbage-colored cells can be any block but not air.
|
||||
Once you make the shape, you will win.
|
||||
Once you make the shape, you will win.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
尝试存活更久,或者完成目标即胜利.
|
||||
|
||||
旋转系统:
|
||||
使用Techmino专属旋转系统,具体太复杂并且随时可能更改所以不写在这里,可以去parts/kicklist.lua看
|
||||
默认使用Techmino专属旋转系统TRS,允许玩家自选其他较常用的旋转系统(一般不必要)
|
||||
|
||||
spin判定:
|
||||
满足三角判定+2分
|
||||
|
||||
@@ -17,8 +17,8 @@ return{
|
||||
{name='dig_100l', x=-600, y=-200, size=40,shape=1,icon="dig_sprint", unlock={'dig_400l'}},
|
||||
{name='dig_400l', x=-800, y=-200, size=40,shape=1,icon="dig_sprint"},
|
||||
|
||||
{name='marathon_n', x=0, y=-600, size=60,shape=1,icon="marathon", unlock={'marathon_h','solo_e','round_e','blind_e','classic_e','survivor_e','bigbang','zen'}},
|
||||
{name='marathon_h', x=0, y=-800, size=50,shape=1,icon="marathon", unlock={'master_n'}},
|
||||
{name='marathon_n', x=0, y=-600, size=60,shape=1,icon="marathon", unlock={'marathon_h','solo_e','round_e','blind_e','classic_e','survivor_e','clearRush','zen'}},
|
||||
{name='marathon_h', x=0, y=-800, size=50,shape=1,icon="marathon", unlock={'master_n','strategy_e'}},
|
||||
|
||||
{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'}},
|
||||
@@ -39,16 +39,16 @@ return{
|
||||
{name='round_l', x=-1200, y=-800, size=40,shape=1,icon="round", unlock={'round_u'}},
|
||||
{name='round_u', x=-1400, y=-800, size=40,shape=1,icon="round"},
|
||||
|
||||
{name='master_n', x=0, y=-1000, size=40,shape=1,icon="master", unlock={'master_h','strategy_e'}},
|
||||
{name='master_h', x=0, y=-1200, size=40,shape=3,icon="master", unlock={'master_final','master_ex','master_ph','master_m'}},
|
||||
{name='master_n', x=0, y=-1000, size=40,shape=1,icon="master", unlock={'master_h','strategy_h'}},
|
||||
{name='master_h', x=0, y=-1200, size=40,shape=3,icon="master", unlock={'master_final','master_ex','master_ph','master_m','strategy_u'}},
|
||||
{name='master_m', x=150, y=-1320, size=30,shape=3,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_ex', x=150, y=-1500, size=40,shape=2,icon="master_ex"},
|
||||
|
||||
{name='strategy_e', x=-150, y=-1100, size=40,shape=3,icon="master", unlock={'strategy_h'}},
|
||||
{name='strategy_h', x=-250, y=-1200, size=35,shape=3,icon="master", unlock={'strategy_u'}},
|
||||
{name='strategy_u', x=-350, y=-1300, size=30,shape=3,icon="master"},
|
||||
{name='strategy_e', x=-150, y=-1030, size=40,shape=3,icon="master"},
|
||||
{name='strategy_h', x=-200, y=-1160, size=35,shape=3,icon="master"},
|
||||
{name='strategy_u', x=-250, y=-1290, size=30,shape=2,icon="master"},
|
||||
|
||||
{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'}},
|
||||
@@ -57,9 +57,9 @@ return{
|
||||
{name='blind_u', x=150, y=-1100, size=30,shape=3,icon="hidden", unlock={'blind_wtf'}},
|
||||
{name='blind_wtf', x=150, y=-1200, size=25,shape=2,icon="hidden"},
|
||||
|
||||
{name='classic_e', x=-150, y=-850, size=40,shape=1,icon="classic", unlock={'classic_h'}},
|
||||
{name='classic_h', x=-300, y=-950, size=35,shape=2,icon="classic", unlock={'classic_u'}},
|
||||
{name='classic_u', x=-450, y=-1050, size=30,shape=2,icon="classic"},
|
||||
{name='classic_e', x=-200, y=-850, size=40,shape=1,icon="classic", unlock={'classic_h'}},
|
||||
{name='classic_h', x=-300, y=-950, size=35,shape=2,icon="classic", unlock={'classic_u'}},
|
||||
{name='classic_u', x=-400, y=-1050, size=30,shape=2,icon="classic"},
|
||||
|
||||
{name='survivor_e', x=300, y=-600, size=40,shape=1,icon="survivor", unlock={'survivor_n'}},
|
||||
{name='survivor_n', x=500, y=-600, size=40,shape=1,icon="survivor", unlock={'survivor_h','attacker_h','defender_n','dig_h'}},
|
||||
@@ -76,7 +76,7 @@ return{
|
||||
{name='dig_h', x=700, y=-800, size=40,shape=1,icon="dig", unlock={'dig_u'}},
|
||||
{name='dig_u', x=700, y=-1000, size=40,shape=1,icon="dig"},
|
||||
|
||||
{name='bigbang', x=400, y=-400, size=50,shape=1,icon="bigbang", unlock={'c4wtrain_n','pctrain_n','sprintAtk'}},
|
||||
{name='clearRush', x=400, y=-400, size=50,shape=1,icon="bigbang", unlock={'c4wtrain_n','pctrain_n','sprintAtk'}},
|
||||
{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"},
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ return{
|
||||
das=8,arr=1,
|
||||
drop=30,lock=30,
|
||||
holdCount=0,
|
||||
eventSet='bigbang',
|
||||
eventSet='clearRush',
|
||||
bg='blockhole',bgm='peak',
|
||||
},
|
||||
score=function(P)return{P.modeData.stage,P.stat.time}end,
|
||||
@@ -240,8 +240,8 @@ function NET.uploadSave()
|
||||
{section=3,data=STRING.packTable(SETTING)},
|
||||
{section=4,data=STRING.packTable(KEY_MAP)},
|
||||
{section=5,data=STRING.packTable(VK_ORG)},
|
||||
{section=6,data=STRING.packTable(FILE.load('conf/vkSave1'))},
|
||||
{section=7,data=STRING.packTable(FILE.load('conf/vkSave2'))},
|
||||
{section=6,data=STRING.packTable(loadFile('conf/vkSave1'))},
|
||||
{section=7,data=STRING.packTable(loadFile('conf/vkSave2'))},
|
||||
}..'}}')
|
||||
MES.new('info',"Uploading")
|
||||
end
|
||||
@@ -282,13 +282,13 @@ function NET.loadSavedData(sections)
|
||||
applyAllSettings()
|
||||
|
||||
TABLE.cover(NET.cloudData.keyMap,KEY_MAP)
|
||||
success=success and FILE.save(KEY_MAP,'conf/key')
|
||||
success=success and saveFile(KEY_MAP,'conf/key')
|
||||
|
||||
TABLE.cover(NET.cloudData.VK_org,VK_ORG)
|
||||
success=success and FILE.save(VK_ORG,'conf/virtualkey')
|
||||
success=success and saveFile(VK_ORG,'conf/virtualkey')
|
||||
|
||||
success=success and FILE.save(NET.cloudData.vkSave1,'conf/vkSave1')
|
||||
success=success and FILE.save(NET.cloudData.vkSave2,'conf/vkSave2')
|
||||
success=success and saveFile(NET.cloudData.vkSave1,'conf/vkSave1')
|
||||
success=success and saveFile(NET.cloudData.vkSave2,'conf/vkSave2')
|
||||
if success then
|
||||
MES.new('check',text.saveDone)
|
||||
end
|
||||
@@ -460,7 +460,7 @@ function NET.updateWS_user()
|
||||
if res.uid then
|
||||
USER.uid=res.uid
|
||||
USER.authToken=res.authToken
|
||||
FILE.save(USER,'conf/user')
|
||||
saveFile(USER,'conf/user')
|
||||
if SCN.cur=='login'then
|
||||
SCN.back()
|
||||
end
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
return{
|
||||
{font=100,name="☆★白羽★☆"},
|
||||
{font=100,name="[*浩]"},
|
||||
|
||||
{font=65,name="那没事了(T6300)"},
|
||||
{font=65,name="加油啊,钉钉动了的大哥哥(T3228)"},
|
||||
@@ -28,6 +29,8 @@ return{
|
||||
{font=65,name="怀沙"},
|
||||
{font=65,name="星街书婉"},
|
||||
{font=65,name="老板来两份薯条"},
|
||||
{font=65,name="[**昆]"},
|
||||
{font=65,name="[**浩]"},
|
||||
|
||||
{font=25,name="八零哥"},
|
||||
{font=25,name="蕴空之灵"},
|
||||
@@ -75,7 +78,7 @@ return{
|
||||
{font=25,name="[*炎]"},
|
||||
{font=25,name="[*Y]"},
|
||||
{font=25,name="aaa222"},
|
||||
{font=25,name="[**城]"},
|
||||
{font=25,name="人偶"},
|
||||
{font=25,name="cnDD"},
|
||||
{font=25,name="红桃老给"},
|
||||
{font=25,name="昭庭玲秋"},
|
||||
@@ -121,4 +124,7 @@ return{
|
||||
{font=25,name="小丘"},
|
||||
{font=25,name="Techtris"},
|
||||
{font=25,name="费尔特林"},
|
||||
{font=25,name="零醇丘卡"},
|
||||
{font=25,name="Hathtiz"},
|
||||
{font=25,name="江江江江17"},
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ local function _drawField(P,showInvis)
|
||||
local V,F=P.visTime,P.field
|
||||
local start=int((P.fieldBeneath+P.fieldUp)/30+1)
|
||||
local texture=P.skinLib
|
||||
if P.falling==-1 then--Blocks only
|
||||
if P.falling==0 then--Blocks only
|
||||
if ENV.upEdge then
|
||||
gc_setShader(shader_lighter)
|
||||
gc_translate(0,-4)
|
||||
@@ -782,7 +782,7 @@ function draw.norm(P,repMode)
|
||||
_drawFXs(P)
|
||||
|
||||
--Draw current block
|
||||
if P.cur and P.waiting==-1 then
|
||||
if P.alive and P.cur then
|
||||
local C=P.cur
|
||||
local curColor=C.color
|
||||
|
||||
@@ -981,7 +981,6 @@ function draw.small(P)
|
||||
end
|
||||
function draw.demo(P)
|
||||
local ENV=P.gameEnv
|
||||
local curColor=P.cur.color
|
||||
|
||||
--Camera
|
||||
gc_push('transform')
|
||||
@@ -997,7 +996,8 @@ function draw.demo(P)
|
||||
gc_translate(0,600)
|
||||
_drawField(P)
|
||||
_drawFXs(P)
|
||||
if P.cur and P.waiting==-1 then
|
||||
if P.alive and P.cur then
|
||||
local curColor=P.cur.color
|
||||
if ENV.ghost then
|
||||
drawGhost[ENV.ghostType](P.cur.bk,P.curX,P.ghoY,ENV.ghost,P.skinLib,curColor)
|
||||
end
|
||||
|
||||
@@ -3,7 +3,6 @@ return{
|
||||
dascut=0,dropcut=0,
|
||||
sddas=2,sdarr=2,
|
||||
ihs=true,irs=true,ims=true,
|
||||
hang=0,FTLock=true,
|
||||
|
||||
ghostType='gray',
|
||||
block=true,ghost=.3,center=1,
|
||||
@@ -30,7 +29,9 @@ return{
|
||||
|
||||
drop=60,lock=60,
|
||||
wait=0,fall=0,
|
||||
hang=5,hurry=1e99,
|
||||
bone=false,
|
||||
lockout=false,
|
||||
fieldH=20,heightLimit=1e99,
|
||||
nextCount=6,nextStartPos=1,
|
||||
holdMode='hold',holdCount=1,
|
||||
@@ -68,4 +69,5 @@ return{
|
||||
|
||||
bg='none',bgm='race',
|
||||
allowMod=true,
|
||||
FTLock=true,
|
||||
}
|
||||
|
||||
@@ -36,54 +36,6 @@ local function _getNewStatTable()
|
||||
end
|
||||
return T
|
||||
end
|
||||
local playerActions={
|
||||
Player.act_moveLeft, --1
|
||||
Player.act_moveRight, --2
|
||||
Player.act_rotRight, --3
|
||||
Player.act_rotLeft, --4
|
||||
Player.act_rot180, --5
|
||||
Player.act_hardDrop, --6
|
||||
Player.act_softDrop, --7
|
||||
Player.act_hold, --8
|
||||
Player.act_func1, --9
|
||||
Player.act_func2, --10
|
||||
Player.act_insLeft, --11
|
||||
Player.act_insRight, --12
|
||||
Player.act_insDown, --13
|
||||
Player.act_down1, --14
|
||||
Player.act_down4, --15
|
||||
Player.act_down10, --16
|
||||
Player.act_dropLeft, --17
|
||||
Player.act_dropRight, --18
|
||||
Player.act_zangiLeft, --19
|
||||
Player.act_zangiRight,--20
|
||||
}
|
||||
local function _pressKey(P,keyID)
|
||||
if P.keyAvailable[keyID]and P.alive then
|
||||
P.keyPressing[keyID]=true
|
||||
playerActions[keyID](P)
|
||||
P.stat.key=P.stat.key+1
|
||||
end
|
||||
end
|
||||
local function _releaseKey(P,keyID)
|
||||
P.keyPressing[keyID]=false
|
||||
end
|
||||
local function _pressKey_Rec(P,keyID)
|
||||
if P.keyAvailable[keyID]and P.alive then
|
||||
local L=GAME.rep
|
||||
ins(L,P.frameRun)
|
||||
ins(L,keyID)
|
||||
P.keyPressing[keyID]=true
|
||||
playerActions[keyID](P)
|
||||
P.stat.key=P.stat.key+1
|
||||
end
|
||||
end
|
||||
local function _releaseKey_Rec(P,keyID)
|
||||
local L=GAME.rep
|
||||
ins(L,P.frameRun)
|
||||
ins(L,32+keyID)
|
||||
P.keyPressing[keyID]=false
|
||||
end
|
||||
local function _newEmptyPlayer(id,mini)
|
||||
local P={id=id}
|
||||
PLAYERS[id]=P
|
||||
@@ -92,15 +44,6 @@ local function _newEmptyPlayer(id,mini)
|
||||
--Inherit functions of Player class
|
||||
for k,v in next,Player do P[k]=v end
|
||||
|
||||
--Set key/timer event
|
||||
if P.id==1 and GAME.recording then
|
||||
P.pressKey=_pressKey_Rec
|
||||
P.releaseKey=_releaseKey_Rec
|
||||
else
|
||||
P.pressKey=_pressKey
|
||||
P.releaseKey=_releaseKey
|
||||
end
|
||||
|
||||
--Field position
|
||||
P.swingOffset={--Shake FX
|
||||
x=0,y=0,
|
||||
@@ -195,7 +138,7 @@ local function _newEmptyPlayer(id,mini)
|
||||
]]
|
||||
P.movDir,P.moving,P.downing=0,0,0--Last move key,DAS charging,downDAS charging
|
||||
P.dropDelay,P.lockDelay=0,0
|
||||
P.waiting,P.falling=-1,-1
|
||||
P.waiting,P.falling=0,0
|
||||
P.freshTime=0
|
||||
P.spinLast=false
|
||||
P.ctrlCount=0--Key press time, for finesse check
|
||||
|
||||
@@ -200,10 +200,321 @@ function Player:createBeam(R,send)
|
||||
end
|
||||
--------------------------</FX>--------------------------
|
||||
|
||||
--------------------------<Action>--------------------------
|
||||
function Player:_deepDrop()
|
||||
local CB=self.cur.bk
|
||||
local y=self.curY-1
|
||||
while self:ifoverlap(CB,self.curX,y)and y>0 do
|
||||
y=y-1
|
||||
end
|
||||
if y>0 then
|
||||
self.ghoY=y
|
||||
self:createDropFX()
|
||||
self.curY=y
|
||||
self:freshBlock('move')
|
||||
SFX.play('swipe')
|
||||
end
|
||||
end
|
||||
function Player:act_moveLeft(auto)
|
||||
if not auto then
|
||||
self.ctrlCount=self.ctrlCount+1
|
||||
end
|
||||
self.movDir=-1
|
||||
if self.control and self.waiting==0 then
|
||||
if self.cur and not self:ifoverlap(self.cur.bk,self.curX-1,self.curY)then
|
||||
self:createMoveFX('left')
|
||||
self.curX=self.curX-1
|
||||
self:freshBlock('move')
|
||||
if not auto then
|
||||
self.moving=0
|
||||
end
|
||||
self.spinLast=false
|
||||
else
|
||||
self.moving=self.gameEnv.das
|
||||
end
|
||||
else
|
||||
self.moving=0
|
||||
end
|
||||
end
|
||||
function Player:act_moveRight(auto)
|
||||
if not auto then
|
||||
self.ctrlCount=self.ctrlCount+1
|
||||
end
|
||||
self.movDir=1
|
||||
if self.control and self.waiting==0 then
|
||||
if self.cur and not self:ifoverlap(self.cur.bk,self.curX+1,self.curY)then
|
||||
self:createMoveFX('right')
|
||||
self.curX=self.curX+1
|
||||
self:freshBlock('move')
|
||||
if not auto then
|
||||
self.moving=0
|
||||
end
|
||||
self.spinLast=false
|
||||
else
|
||||
self.moving=self.gameEnv.das
|
||||
end
|
||||
else
|
||||
self.moving=0
|
||||
end
|
||||
end
|
||||
function Player:act_rotRight()
|
||||
if self.control and self.cur then
|
||||
self.ctrlCount=self.ctrlCount+1
|
||||
self:spin(1)
|
||||
self.keyPressing[3]=false
|
||||
end
|
||||
end
|
||||
function Player:act_rotLeft()
|
||||
if self.control and self.cur then
|
||||
self.ctrlCount=self.ctrlCount+1
|
||||
self:spin(3)
|
||||
self.keyPressing[4]=false
|
||||
end
|
||||
end
|
||||
function Player:act_rot180()
|
||||
if self.control and self.cur then
|
||||
self.ctrlCount=self.ctrlCount+2
|
||||
self:spin(2)
|
||||
self.keyPressing[5]=false
|
||||
end
|
||||
end
|
||||
function Player:act_hardDrop()
|
||||
local ENV=self.gameEnv
|
||||
if self.control and self.cur then
|
||||
if self.lastPiece.autoLock and self.frameRun-self.lastPiece.frame<ENV.dropcut then
|
||||
SFX.play('drop_cancel',.3)
|
||||
else
|
||||
if self.curY>self.ghoY then
|
||||
self:createDropFX()
|
||||
self.curY=self.ghoY
|
||||
self.spinLast=false
|
||||
if self.sound then
|
||||
SFX.play('drop',nil,self:getCenterX()*.15)
|
||||
if SETTING.vib>0 then VIB(SETTING.vib+1)end
|
||||
end
|
||||
end
|
||||
if ENV.shakeFX then
|
||||
self.swingOffset.vy=.6
|
||||
self.swingOffset.va=self.swingOffset.va+self:getCenterX()*6e-4
|
||||
end
|
||||
self.lockDelay=-1
|
||||
self.keyPressing[6]=false
|
||||
self:drop()
|
||||
end
|
||||
end
|
||||
end
|
||||
function Player:act_softDrop()
|
||||
self.downing=1
|
||||
if self.control and self.cur then
|
||||
if self.curY>self.ghoY then
|
||||
self.curY=self.curY-1
|
||||
self:freshBlock('fresh')
|
||||
self.spinLast=false
|
||||
self:checkTouchSound()
|
||||
elseif self.gameEnv.deepdrop then
|
||||
self:_deepdrop()
|
||||
end
|
||||
end
|
||||
end
|
||||
function Player:act_hold()
|
||||
if self.control and self.cur then
|
||||
if self:hold()then
|
||||
self.keyPressing[8]=false
|
||||
end
|
||||
end
|
||||
end
|
||||
function Player:act_func1()
|
||||
self.gameEnv.fkey1(self)
|
||||
end
|
||||
function Player:act_func2()
|
||||
self.gameEnv.fkey2(self)
|
||||
end
|
||||
|
||||
function Player:act_insLeft(auto)
|
||||
if not self.cur then
|
||||
return
|
||||
end
|
||||
local x0=self.curX
|
||||
while not self:ifoverlap(self.cur.bk,self.curX-1,self.curY)do
|
||||
self:createMoveFX('left')
|
||||
self.curX=self.curX-1
|
||||
self:freshBlock('move',true)
|
||||
end
|
||||
if self.curX~=x0 then
|
||||
self.spinLast=false
|
||||
self:checkTouchSound()
|
||||
end
|
||||
if self.gameEnv.shakeFX then
|
||||
self.swingOffset.vx=-1.5
|
||||
end
|
||||
if auto then
|
||||
if self.ctrlCount==0 then
|
||||
self.ctrlCount=1
|
||||
end
|
||||
else
|
||||
self.ctrlCount=self.ctrlCount+1
|
||||
end
|
||||
end
|
||||
function Player:act_insRight(auto)
|
||||
if not self.cur then
|
||||
return
|
||||
end
|
||||
local x0=self.curX
|
||||
while not self:ifoverlap(self.cur.bk,self.curX+1,self.curY)do
|
||||
self:createMoveFX('right')
|
||||
self.curX=self.curX+1
|
||||
self:freshBlock('move',true)
|
||||
end
|
||||
if self.curX~=x0 then
|
||||
self.spinLast=false
|
||||
self:checkTouchSound()
|
||||
end
|
||||
if self.gameEnv.shakeFX then
|
||||
self.swingOffset.vx=1.5
|
||||
end
|
||||
if auto then
|
||||
if self.ctrlCount==0 then
|
||||
self.ctrlCount=1
|
||||
end
|
||||
else
|
||||
self.ctrlCount=self.ctrlCount+1
|
||||
end
|
||||
end
|
||||
function Player:act_insDown()
|
||||
if self.cur and self.curY>self.ghoY then
|
||||
local ENV=self.gameEnv
|
||||
self:createDropFX()
|
||||
if ENV.shakeFX then
|
||||
self.swingOffset.vy=.5
|
||||
end
|
||||
self.curY=self.ghoY
|
||||
self.lockDelay=ENV.lock
|
||||
self.spinLast=false
|
||||
self:freshBlock('fresh')
|
||||
self:checkTouchSound()
|
||||
end
|
||||
end
|
||||
function Player:act_down1()
|
||||
if self.cur then
|
||||
if self.curY>self.ghoY then
|
||||
self:createMoveFX('down')
|
||||
self.curY=self.curY-1
|
||||
self:freshBlock('fresh')
|
||||
self.spinLast=false
|
||||
elseif self.gameEnv.deepdrop then
|
||||
self:_deepdrop()
|
||||
end
|
||||
end
|
||||
end
|
||||
function Player:act_down4()
|
||||
if self.cur then
|
||||
if self.curY>self.ghoY then
|
||||
local ghoY0=self.ghoY
|
||||
self.ghoY=max(self.curY-4,self.ghoY)
|
||||
self:createDropFX()
|
||||
self.curY,self.ghoY=self.ghoY,ghoY0
|
||||
self:freshBlock('fresh')
|
||||
self.spinLast=false
|
||||
elseif self.gameEnv.deepdrop then
|
||||
self:_deepdrop()
|
||||
end
|
||||
end
|
||||
end
|
||||
function Player:act_down10()
|
||||
if self.cur then
|
||||
if self.curY>self.ghoY then
|
||||
local ghoY0=self.ghoY
|
||||
self.ghoY=max(self.curY-0,self.ghoY)
|
||||
self:createDropFX()
|
||||
self.curY,self.ghoY=self.ghoY,ghoY0
|
||||
self:freshBlock('fresh')
|
||||
self.spinLast=false
|
||||
elseif self.gameEnv.deepdrop then
|
||||
self:_deepdrop()
|
||||
end
|
||||
end
|
||||
end
|
||||
function Player:act_dropLeft()
|
||||
if self.cur then
|
||||
self:act_insLeft()
|
||||
self:act_hardDrop()
|
||||
end
|
||||
end
|
||||
function Player:act_dropRight()
|
||||
if self.cur then
|
||||
self:act_insRight()
|
||||
self:act_hardDrop()
|
||||
end
|
||||
end
|
||||
function Player:act_zangiLeft()
|
||||
if self.cur then
|
||||
self:act_insLeft()
|
||||
self:act_insDown()
|
||||
self:act_insRight()
|
||||
self:act_hardDrop()
|
||||
end
|
||||
end
|
||||
function Player:act_zangiRight()
|
||||
if self.cur then
|
||||
self:act_insRight()
|
||||
self:act_insDown()
|
||||
self:act_insLeft()
|
||||
self:act_hardDrop()
|
||||
end
|
||||
end
|
||||
--------------------------</Action>--------------------------
|
||||
|
||||
--------------------------<Method>--------------------------
|
||||
local playerActions={
|
||||
Player.act_moveLeft, --1
|
||||
Player.act_moveRight, --2
|
||||
Player.act_rotRight, --3
|
||||
Player.act_rotLeft, --4
|
||||
Player.act_rot180, --5
|
||||
Player.act_hardDrop, --6
|
||||
Player.act_softDrop, --7
|
||||
Player.act_hold, --8
|
||||
Player.act_func1, --9
|
||||
Player.act_func2, --10
|
||||
Player.act_insLeft, --11
|
||||
Player.act_insRight, --12
|
||||
Player.act_insDown, --13
|
||||
Player.act_down1, --14
|
||||
Player.act_down4, --15
|
||||
Player.act_down10, --16
|
||||
Player.act_dropLeft, --17
|
||||
Player.act_dropRight, --18
|
||||
Player.act_zangiLeft, --19
|
||||
Player.act_zangiRight,--20
|
||||
}function Player:pressKey(keyID)
|
||||
if self.keyAvailable[keyID]and self.alive then
|
||||
if self.waiting>self.gameEnv.hurry then
|
||||
self.waiting=self.gameEnv.hurry
|
||||
if self.waiting==0 and self.falling==0 then
|
||||
self:popNext()
|
||||
end
|
||||
end
|
||||
self.keyPressing[keyID]=true
|
||||
playerActions[keyID](self)
|
||||
self.stat.key=self.stat.key+1
|
||||
if self.id==1 and GAME.recording then
|
||||
local L=GAME.rep
|
||||
ins(L,self.frameRun)
|
||||
ins(L,keyID)
|
||||
end
|
||||
end
|
||||
end
|
||||
function Player:releaseKey(keyID)
|
||||
self.keyPressing[keyID]=false
|
||||
if self.id==1 and GAME.recording then
|
||||
local L=GAME.rep
|
||||
ins(L,self.frameRun)
|
||||
ins(L,32+keyID)
|
||||
end
|
||||
end
|
||||
function Player:newTask(code,...)
|
||||
local thread=coroutine.create(code)
|
||||
resume(thread,self,...)
|
||||
assert(resume(thread,self,...))
|
||||
if status(thread)~='dead'then
|
||||
ins(self.tasks,{
|
||||
thread=thread,
|
||||
@@ -387,16 +698,8 @@ function Player:garbageRise(color,amount,line)--Release n-lines garbage to field
|
||||
#self.field>self.gameEnv.heightLimit
|
||||
)
|
||||
then
|
||||
self:lock()
|
||||
self:lose()
|
||||
end
|
||||
|
||||
if #self.field>self.gameEnv.heightLimit then
|
||||
self:_triggerEvent('hook_die')
|
||||
if #self.field>self.gameEnv.heightLimit then
|
||||
self:lose()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local invList={2,1,4,3,5,6,7}
|
||||
@@ -727,6 +1030,16 @@ function Player:_removeClearedLines()
|
||||
FREEROW.discard(rem(self.visTime,h))
|
||||
end
|
||||
end
|
||||
function Player:_updateFalling(val)
|
||||
self.falling=val
|
||||
if self.falling==0 then
|
||||
local L=#self.clearingRow
|
||||
if self.sound and self.gameEnv.fall>0 and #self.field+L>self.clearingRow[L]then
|
||||
SFX.play('fall')
|
||||
end
|
||||
TABLE.cut(self.clearingRow)
|
||||
end
|
||||
end
|
||||
function Player:removeTopClearingFX()
|
||||
for i=#self.clearingRow,1,-1 do
|
||||
if self.clearingRow[i]>#self.field then
|
||||
@@ -736,7 +1049,7 @@ function Player:removeTopClearingFX()
|
||||
end
|
||||
end
|
||||
if self.clearingRow[1]then
|
||||
self.falling=self.gameEnv.fall
|
||||
self:_updateFalling(self.gameEnv.fall)
|
||||
return false
|
||||
else
|
||||
return true
|
||||
@@ -1012,12 +1325,13 @@ function Player:hold_swap(ifpre)
|
||||
self.stat.hold=self.stat.hold+1
|
||||
end
|
||||
function Player:hold(ifpre)
|
||||
if self.holdTime>0 and(ifpre or self.waiting==-1)then
|
||||
if self.holdTime>0 and(ifpre or self.falling==0 and self.waiting==0)then
|
||||
if self.gameEnv.holdMode=='hold'then
|
||||
self:hold_norm(ifpre)
|
||||
elseif self.gameEnv.holdMode=='swap'then
|
||||
self:hold_swap(ifpre)
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1047,9 +1361,9 @@ function Player:popNext(ifhold)--Pop nextQueue to hand
|
||||
self.spinLast=false
|
||||
self.ctrlCount=0
|
||||
|
||||
self.cur=rem(self.nextQueue,1)
|
||||
self.newNext()
|
||||
if self.cur then
|
||||
if self.nextQueue[1]then
|
||||
self.cur=rem(self.nextQueue,1)
|
||||
self.newNext()
|
||||
self.pieceCount=self.pieceCount+1
|
||||
|
||||
local pressing=self.keyPressing
|
||||
@@ -1259,8 +1573,6 @@ do
|
||||
piece.centX,piece.centY=self.curX+sc[2],self.curY+sc[1]
|
||||
piece.frame,piece.autoLock=self.frameRun,autoLock
|
||||
|
||||
self.waiting=ENV.wait
|
||||
|
||||
--Tri-corner spin check
|
||||
if self.spinLast then
|
||||
if C.id<6 then
|
||||
@@ -1645,7 +1957,10 @@ do
|
||||
end
|
||||
end
|
||||
|
||||
--Prevent sudden death if hang>0
|
||||
--Fresh ARE
|
||||
self.waiting=ENV.wait
|
||||
|
||||
--Prevent sudden death if hang>0
|
||||
if ENV.hang>ENV.wait and self.nextQueue[1]then
|
||||
local B=self.nextQueue[1]
|
||||
if self:ifoverlap(B.bk,int(6-#B.bk[1]*.5),int(ENV.fieldH+1-modf(B.RS.centerPos[B.id][B.dir][1]))+ceil(self.fieldBeneath/30))then
|
||||
@@ -1661,7 +1976,7 @@ do
|
||||
end
|
||||
|
||||
--Check height limit
|
||||
if cc==0 and #self.field>ENV.heightLimit then
|
||||
if cc==0 and(#self.field>ENV.heightLimit or ENV.lockout and CY>ENV.fieldH)then
|
||||
finish='lose'
|
||||
end
|
||||
|
||||
@@ -1707,6 +2022,13 @@ do
|
||||
else
|
||||
self:_triggerEvent('hook_drop')
|
||||
end
|
||||
|
||||
--Remove controling block
|
||||
self.cur=nil
|
||||
|
||||
if self.waiting==0 and self.falling==0 then
|
||||
self:popNext()
|
||||
end
|
||||
end
|
||||
|
||||
function Player:clearFilledLines(start,height)
|
||||
@@ -1716,7 +2038,7 @@ do
|
||||
self:showText(text.clear[min(_cc,21)],0,0,75,'beat',.4)
|
||||
if _cc>6 then self:showText(text.cleared:gsub("$1",_cc),0,55,30,'zoomout',.4)end
|
||||
self:_removeClearedLines()
|
||||
self.falling=self.gameEnv.fall
|
||||
self:_updateFalling(self.gameEnv.fall)
|
||||
self.stat.row=self.stat.row+_cc
|
||||
self.stat.dig=self.stat.dig+_gbcc
|
||||
self.stat.score=self.stat.score+clearSCR[_cc]
|
||||
@@ -2022,7 +2344,7 @@ local function update_alive(P)
|
||||
if P.movDir~=0 then
|
||||
local das,arr=ENV.das,ENV.arr
|
||||
local mov=P.moving
|
||||
if P.waiting==-1 then
|
||||
if P.cur then
|
||||
if P.movDir==1 then
|
||||
if P.keyPressing[2]then
|
||||
if arr>0 then
|
||||
@@ -2106,26 +2428,25 @@ local function update_alive(P)
|
||||
P.downing=0
|
||||
end
|
||||
|
||||
local stopAtFalling
|
||||
|
||||
--Falling animation
|
||||
if P.falling>=0 then
|
||||
P.falling=P.falling-1
|
||||
if P.falling>=0 then
|
||||
if P.falling>0 then
|
||||
stopAtFalling=true
|
||||
P:_updateFalling(P.falling-1)
|
||||
if P.falling>0 then
|
||||
goto THROW_stop
|
||||
else
|
||||
local L=#P.clearingRow
|
||||
if P.sound and ENV.fall>0 and #P.field+L>P.clearingRow[L]then
|
||||
SFX.play('fall')
|
||||
end
|
||||
P.clearingRow={}
|
||||
end
|
||||
end
|
||||
|
||||
--Update block state
|
||||
if P.control then
|
||||
--Try spawn new block
|
||||
if P.waiting>=0 then
|
||||
P.waiting=P.waiting-1
|
||||
if P.waiting<0 then
|
||||
if not P.cur then
|
||||
if not stopAtFalling and P.waiting>0 then
|
||||
P.waiting=P.waiting-1
|
||||
end
|
||||
if P.waiting<=0 then
|
||||
P:popNext()
|
||||
end
|
||||
goto THROW_stop
|
||||
@@ -2246,15 +2567,8 @@ local function update_dead(P)
|
||||
P.swappingAtkMode=min(P.swappingAtkMode+2,30)
|
||||
end
|
||||
|
||||
if P.falling>=0 then
|
||||
P.falling=P.falling-1
|
||||
if P.falling<0 then
|
||||
local L=#P.clearingRow
|
||||
if P.sound and P.gameEnv.fall>0 and #P.field+L>P.clearingRow[L]then
|
||||
SFX.play('fall')
|
||||
end
|
||||
P.clearingRow={}
|
||||
end
|
||||
if P.falling>0 then
|
||||
P:_updateFalling(P.falling-1)
|
||||
end
|
||||
if P.b2b1>0 then
|
||||
P.b2b1=max(0,P.b2b1*.92-1)
|
||||
@@ -2474,254 +2788,4 @@ function Player:lose(force)
|
||||
end
|
||||
--------------------------<\Event>--------------------------
|
||||
|
||||
--------------------------<Action>--------------------------
|
||||
function Player:act_moveLeft(auto)
|
||||
if not auto then
|
||||
self.ctrlCount=self.ctrlCount+1
|
||||
end
|
||||
self.movDir=-1
|
||||
if self.control and self.waiting==-1 then
|
||||
if self.cur and not self:ifoverlap(self.cur.bk,self.curX-1,self.curY)then
|
||||
self:createMoveFX('left')
|
||||
self.curX=self.curX-1
|
||||
self:freshBlock('move')
|
||||
if not auto then
|
||||
self.moving=0
|
||||
end
|
||||
self.spinLast=false
|
||||
else
|
||||
self.moving=self.gameEnv.das
|
||||
end
|
||||
else
|
||||
self.moving=0
|
||||
end
|
||||
end
|
||||
function Player:act_moveRight(auto)
|
||||
if not auto then
|
||||
self.ctrlCount=self.ctrlCount+1
|
||||
end
|
||||
self.movDir=1
|
||||
if self.control and self.waiting==-1 then
|
||||
if self.cur and not self:ifoverlap(self.cur.bk,self.curX+1,self.curY)then
|
||||
self:createMoveFX('right')
|
||||
self.curX=self.curX+1
|
||||
self:freshBlock('move')
|
||||
if not auto then
|
||||
self.moving=0
|
||||
end
|
||||
self.spinLast=false
|
||||
else
|
||||
self.moving=self.gameEnv.das
|
||||
end
|
||||
else
|
||||
self.moving=0
|
||||
end
|
||||
end
|
||||
function Player:act_rotRight()
|
||||
if self.control and self.waiting==-1 and self.cur then
|
||||
self.ctrlCount=self.ctrlCount+1
|
||||
self:spin(1)
|
||||
self.keyPressing[3]=false
|
||||
end
|
||||
end
|
||||
function Player:act_rotLeft()
|
||||
if self.control and self.waiting==-1 and self.cur then
|
||||
self.ctrlCount=self.ctrlCount+1
|
||||
self:spin(3)
|
||||
self.keyPressing[4]=false
|
||||
end
|
||||
end
|
||||
function Player:act_rot180()
|
||||
if self.control and self.waiting==-1 and self.cur then
|
||||
self.ctrlCount=self.ctrlCount+2
|
||||
self:spin(2)
|
||||
self.keyPressing[5]=false
|
||||
end
|
||||
end
|
||||
function Player:act_hardDrop()
|
||||
local ENV=self.gameEnv
|
||||
if self.control and self.waiting==-1 and self.cur then
|
||||
if self.lastPiece.autoLock and self.frameRun-self.lastPiece.frame<ENV.dropcut then
|
||||
SFX.play('drop_cancel',.3)
|
||||
else
|
||||
if self.curY>self.ghoY then
|
||||
self:createDropFX()
|
||||
self.curY=self.ghoY
|
||||
self.spinLast=false
|
||||
if self.sound then
|
||||
SFX.play('drop',nil,self:getCenterX()*.15)
|
||||
if SETTING.vib>0 then VIB(SETTING.vib+1)end
|
||||
end
|
||||
end
|
||||
if ENV.shakeFX then
|
||||
self.swingOffset.vy=.6
|
||||
self.swingOffset.va=self.swingOffset.va+self:getCenterX()*6e-4
|
||||
end
|
||||
self.lockDelay=-1
|
||||
self:drop()
|
||||
self.keyPressing[6]=false
|
||||
end
|
||||
end
|
||||
end
|
||||
function Player:act_softDrop()
|
||||
local ENV=self.gameEnv
|
||||
self.downing=1
|
||||
if self.control and self.waiting==-1 and self.cur then
|
||||
if self.curY>self.ghoY then
|
||||
self.curY=self.curY-1
|
||||
self:freshBlock('fresh')
|
||||
self.spinLast=false
|
||||
self:checkTouchSound()
|
||||
elseif ENV.deepDrop then
|
||||
local CB=self.cur.bk
|
||||
local y=self.curY-1
|
||||
while self:ifoverlap(CB,self.curX,y)and y>0 do
|
||||
y=y-1
|
||||
end
|
||||
if y>0 then
|
||||
self.ghoY=y
|
||||
self:createDropFX()
|
||||
self.curY=y
|
||||
self:freshBlock('move')
|
||||
SFX.play('swipe')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function Player:act_hold()
|
||||
if self.control then
|
||||
if self.waiting==-1 then
|
||||
self:hold()
|
||||
self.keyPressing[8]=false
|
||||
end
|
||||
end
|
||||
end
|
||||
function Player:act_func1()
|
||||
self.gameEnv.fkey1(self)
|
||||
end
|
||||
function Player:act_func2()
|
||||
self.gameEnv.fkey2(self)
|
||||
end
|
||||
|
||||
function Player:act_insLeft(auto)
|
||||
if not self.cur then
|
||||
return
|
||||
end
|
||||
local x0=self.curX
|
||||
while not self:ifoverlap(self.cur.bk,self.curX-1,self.curY)do
|
||||
self:createMoveFX('left')
|
||||
self.curX=self.curX-1
|
||||
self:freshBlock('move',true)
|
||||
end
|
||||
if self.curX~=x0 then
|
||||
self.spinLast=false
|
||||
self:checkTouchSound()
|
||||
end
|
||||
if self.gameEnv.shakeFX then
|
||||
self.swingOffset.vx=-1.5
|
||||
end
|
||||
if auto then
|
||||
if self.ctrlCount==0 then
|
||||
self.ctrlCount=1
|
||||
end
|
||||
else
|
||||
self.ctrlCount=self.ctrlCount+1
|
||||
end
|
||||
end
|
||||
function Player:act_insRight(auto)
|
||||
if not self.cur then
|
||||
return
|
||||
end
|
||||
local x0=self.curX
|
||||
while not self:ifoverlap(self.cur.bk,self.curX+1,self.curY)do
|
||||
self:createMoveFX('right')
|
||||
self.curX=self.curX+1
|
||||
self:freshBlock('move',true)
|
||||
end
|
||||
if self.curX~=x0 then
|
||||
self.spinLast=false
|
||||
self:checkTouchSound()
|
||||
end
|
||||
if self.gameEnv.shakeFX then
|
||||
self.swingOffset.vx=1.5
|
||||
end
|
||||
if auto then
|
||||
if self.ctrlCount==0 then
|
||||
self.ctrlCount=1
|
||||
end
|
||||
else
|
||||
self.ctrlCount=self.ctrlCount+1
|
||||
end
|
||||
end
|
||||
function Player:act_insDown()
|
||||
if self.cur and self.curY>self.ghoY then
|
||||
local ENV=self.gameEnv
|
||||
self:createDropFX()
|
||||
if ENV.shakeFX then
|
||||
self.swingOffset.vy=.5
|
||||
end
|
||||
self.curY=self.ghoY
|
||||
self.lockDelay=ENV.lock
|
||||
self.spinLast=false
|
||||
self:freshBlock('fresh')
|
||||
self:checkTouchSound()
|
||||
end
|
||||
end
|
||||
function Player:act_down1()
|
||||
if self.cur and self.curY>self.ghoY then
|
||||
self:createMoveFX('down')
|
||||
self.curY=self.curY-1
|
||||
self:freshBlock('fresh')
|
||||
self.spinLast=false
|
||||
end
|
||||
end
|
||||
function Player:act_down4()
|
||||
if self.cur and self.curY>self.ghoY then
|
||||
local ghoY0=self.ghoY
|
||||
self.ghoY=max(self.curY-4,self.ghoY)
|
||||
self:createDropFX()
|
||||
self.curY,self.ghoY=self.ghoY,ghoY0
|
||||
self:freshBlock('fresh')
|
||||
self.spinLast=false
|
||||
end
|
||||
end
|
||||
function Player:act_down10()
|
||||
if self.cur and self.curY>self.ghoY then
|
||||
local ghoY0=self.ghoY
|
||||
self.ghoY=max(self.curY-10,self.ghoY)
|
||||
self:createDropFX()
|
||||
self.curY,self.ghoY=self.ghoY,ghoY0
|
||||
self:freshBlock('fresh')
|
||||
self.spinLast=false
|
||||
end
|
||||
end
|
||||
function Player:act_dropLeft()
|
||||
if self.cur then
|
||||
self:act_insLeft()
|
||||
self:act_hardDrop()
|
||||
end
|
||||
end
|
||||
function Player:act_dropRight()
|
||||
if self.cur then
|
||||
self:act_insRight()
|
||||
self:act_hardDrop()
|
||||
end
|
||||
end
|
||||
function Player:act_zangiLeft()
|
||||
if self.cur then
|
||||
self:act_insLeft()
|
||||
self:act_insDown()
|
||||
self:act_insRight()
|
||||
self:act_hardDrop()
|
||||
end
|
||||
end
|
||||
function Player:act_zangiRight()
|
||||
if self.cur then
|
||||
self:act_insRight()
|
||||
self:act_insDown()
|
||||
self:act_insLeft()
|
||||
self:act_hardDrop()
|
||||
end
|
||||
end
|
||||
--------------------------</Action>--------------------------
|
||||
return Player
|
||||
|
||||
@@ -10,7 +10,7 @@ end
|
||||
|
||||
function scene.mouseDown(x,y)
|
||||
if x>55 and y>550 and x<510 and y<670 then
|
||||
loadGame('sprintSym',true)
|
||||
loadGame('stack_e',true)
|
||||
end
|
||||
end
|
||||
scene.touchDown=scene.mouseDown
|
||||
@@ -19,7 +19,7 @@ function scene.keyDown(key)
|
||||
if key=="escape"then
|
||||
SCN.back()
|
||||
elseif key=="space"then
|
||||
loadGame('sprintSym',true)
|
||||
loadGame('stack_e',true)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ local rnd=math.random
|
||||
local int,ceil=math.floor,math.ceil
|
||||
local char=string.char
|
||||
|
||||
local timing,time
|
||||
|
||||
local function b2(i)
|
||||
if i==0 then return 0 end
|
||||
local s=""
|
||||
@@ -114,17 +116,27 @@ local levels={
|
||||
local a=rnd(17,int(s/2))
|
||||
return{COLOR.J,b16(a),COLOR.Z,"+",COLOR.J,b16(s-a)},s
|
||||
end,nil,nil,
|
||||
function()return "Coming S∞n"..(rnd()<.5 and""or" "),1e99 end,
|
||||
function()timing=false return "Coming S∞n"..(rnd()<.5 and""or" "),1e99 end,
|
||||
}setmetatable(levels,{__index=function(self,k)return self[k-1]end})
|
||||
|
||||
local level
|
||||
|
||||
local input,inputTime=0,0
|
||||
local question,answer
|
||||
|
||||
local function newQuestion(lv)
|
||||
return levels[lv]()
|
||||
end
|
||||
|
||||
local function reset()
|
||||
timing=true
|
||||
time=0
|
||||
input=""
|
||||
inputTime=0
|
||||
level=1
|
||||
question,answer=newQuestion(1)
|
||||
end
|
||||
|
||||
local function check(val)
|
||||
if val==answer then
|
||||
level=level+1
|
||||
@@ -142,10 +154,7 @@ end
|
||||
local scene={}
|
||||
|
||||
function scene.sceneInit()
|
||||
input=""
|
||||
inputTime=0
|
||||
level=1
|
||||
question,answer=newQuestion(1)
|
||||
reset()
|
||||
BGM.play('truth')
|
||||
end
|
||||
|
||||
@@ -173,14 +182,15 @@ function scene.keyDown(key,isRep)
|
||||
elseif key=="backspace"then
|
||||
input=""
|
||||
inputTime=0
|
||||
elseif key=="s"then
|
||||
check(answer)
|
||||
elseif key=="r"then
|
||||
reset()
|
||||
elseif key=="escape"then
|
||||
SCN.back()
|
||||
end
|
||||
end
|
||||
|
||||
function scene.update(dt)
|
||||
if timing then time=time+dt end
|
||||
if inputTime>0 then
|
||||
inputTime=inputTime-dt
|
||||
if inputTime<=0 then
|
||||
@@ -189,8 +199,11 @@ function scene.update(dt)
|
||||
end
|
||||
end
|
||||
function scene.draw()
|
||||
FONT.set(35)
|
||||
gc.setColor(COLOR.Z)
|
||||
FONT.set(45)
|
||||
gc.print(("%.3f"):format(time),1026,70)
|
||||
|
||||
FONT.set(35)
|
||||
GC.mStr("["..level.."]",640,30)
|
||||
|
||||
FONT.set(100)
|
||||
@@ -203,6 +216,7 @@ function scene.draw()
|
||||
end
|
||||
|
||||
scene.widgetList={
|
||||
WIDGET.newButton{name='reset',x=155,y=100,w=180,h=100,color='lG',font=40,code=pressKey"r"},
|
||||
WIDGET.newKey{name='X',x=540,y=620,w=90,font=60,fText="X",code=pressKey"backspace"},
|
||||
WIDGET.newKey{name='0',x=640,y=620,w=90,font=60,fText="0",code=pressKey"0"},
|
||||
WIDGET.newKey{name='-',x=740,y=620,w=90,font=60,fText="-",code=pressKey"-"},
|
||||
|
||||
@@ -17,6 +17,7 @@ local sList={
|
||||
wait={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
|
||||
fall={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
|
||||
hang={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
|
||||
hurry={0,1,2,3,4,5,6,7,8,10,1e99},
|
||||
eventSet=EVENTSETS,
|
||||
holdMode={'hold','swap'},
|
||||
}
|
||||
@@ -63,11 +64,11 @@ function scene.keyDown(key,isRep)
|
||||
end
|
||||
if key=="return2"or kb.isDown("lalt","lctrl","lshift")then
|
||||
if #FIELD[1]>0 then
|
||||
FILE.save(CUSTOMENV,'conf/customEnv')
|
||||
saveFile(CUSTOMENV,'conf/customEnv')
|
||||
loadGame('custom_puzzle',true)
|
||||
end
|
||||
else
|
||||
FILE.save(CUSTOMENV,'conf/customEnv')
|
||||
saveFile(CUSTOMENV,'conf/customEnv')
|
||||
loadGame('custom_clear',true)
|
||||
end
|
||||
elseif key=="f"then
|
||||
@@ -83,10 +84,10 @@ function scene.keyDown(key,isRep)
|
||||
TABLE.clear(CUSTOMENV)
|
||||
TABLE.complete(require"parts.customEnv0",CUSTOMENV)
|
||||
for _,W in next,scene.widgetList do W:reset()end
|
||||
FILE.save(DATA.copyMission(),'conf/customMissions')
|
||||
FILE.save(DATA.copyBoards(),'conf/customBoards')
|
||||
FILE.save(DATA.copySequence(),'conf/customSequence')
|
||||
FILE.save(CUSTOMENV,'conf/customEnv')
|
||||
saveFile(DATA.copyMission(),'conf/customMissions')
|
||||
saveFile(DATA.copyBoards(),'conf/customBoards')
|
||||
saveFile(DATA.copySequence(),'conf/customSequence')
|
||||
saveFile(CUSTOMENV,'conf/customEnv')
|
||||
sure=0
|
||||
SFX.play('finesseError',.7)
|
||||
BG.set(CUSTOMENV.bg)
|
||||
@@ -122,7 +123,7 @@ function scene.keyDown(key,isRep)
|
||||
do return end
|
||||
::THROW_fail::MES.new('error',text.dataCorrupted)
|
||||
elseif key=="escape"then
|
||||
FILE.save(CUSTOMENV,'conf/customEnv')
|
||||
saveFile(CUSTOMENV,'conf/customEnv')
|
||||
SCN.back()
|
||||
else
|
||||
WIDGET.keyPressed(key)
|
||||
@@ -181,7 +182,7 @@ function scene.draw()
|
||||
gc.translate(0,WIDGET.scrollPos)
|
||||
end
|
||||
|
||||
scene.widgetScrollHeight=400
|
||||
scene.widgetScrollHeight=450
|
||||
scene.widgetList={
|
||||
WIDGET.newText{name='title', x=520,y=15,font=70,align='R'},
|
||||
|
||||
@@ -212,7 +213,8 @@ scene.widgetList={
|
||||
WIDGET.newSelector{name='lock', x=730,y=410,w=260,color='O',list=sList.lock,disp=CUSval('lock'),code=CUSsto('lock')},
|
||||
WIDGET.newSelector{name='wait', x=730,y=520,w=260,color='G',list=sList.wait,disp=CUSval('wait'),code=CUSsto('wait')},
|
||||
WIDGET.newSelector{name='fall', x=730,y=600,w=260,color='G',list=sList.fall,disp=CUSval('fall'),code=CUSsto('fall')},
|
||||
WIDGET.newSelector{name='hang', x=730,y=680,w=260,color='G',list=sList.hang,disp=CUSval('hang'),code=CUSsto('hang')},
|
||||
WIDGET.newSelector{name='hurry', x=730,y=680,w=260,color='G',list=sList.hurry,disp=CUSval('hurry'),code=CUSsto('hurry')},
|
||||
WIDGET.newSelector{name='hang', x=730,y=760,w=260,color='G',list=sList.hang,disp=CUSval('hang'),code=CUSsto('hang')},
|
||||
|
||||
--Copy / Paste / Start
|
||||
WIDGET.newButton{name='copy', x=1070,y=300,w=310,h=70,color='lR',font=25,code=pressKey"cC"},
|
||||
@@ -222,26 +224,27 @@ scene.widgetList={
|
||||
WIDGET.newButton{name='back', x=1140,y=640,w=170,h=80,font=60,fText=CHAR.icon.back,code=pressKey"escape"},
|
||||
|
||||
--Rule set
|
||||
WIDGET.newSelector{name='eventSet', x=1050,y=740,w=340,color='H',list=sList.eventSet,disp=CUSval('eventSet'),code=CUSsto('eventSet')},
|
||||
WIDGET.newSelector{name='eventSet', x=1050,y=760,w=340,color='H',list=sList.eventSet,disp=CUSval('eventSet'),code=CUSsto('eventSet')},
|
||||
|
||||
--Special rules
|
||||
WIDGET.newSwitch{name='ospin', x=850, y=810,lim=210,disp=CUSval('ospin'), code=CUSrev('ospin')},
|
||||
WIDGET.newSwitch{name='fineKill', x=850, y=870,lim=210,disp=CUSval('fineKill'), code=CUSrev('fineKill')},
|
||||
WIDGET.newSwitch{name='b2bKill', x=850, y=930,lim=210,disp=CUSval('b2bKill'), code=CUSrev('b2bKill')},
|
||||
WIDGET.newSwitch{name='easyFresh', x=1170,y=810,lim=250,disp=CUSval('easyFresh'),code=CUSrev('easyFresh')},
|
||||
WIDGET.newSwitch{name='deepDrop', x=1170,y=870,lim=250,disp=CUSval('deepDrop'), code=CUSrev('deepDrop')},
|
||||
WIDGET.newSwitch{name='bone', x=1170,y=930,lim=250,disp=CUSval('bone'), code=CUSrev('bone')},
|
||||
WIDGET.newSwitch{name='ospin', x=850, y=830, lim=210,disp=CUSval('ospin'), code=CUSrev('ospin')},
|
||||
WIDGET.newSwitch{name='fineKill', x=850, y=890, lim=210,disp=CUSval('fineKill'), code=CUSrev('fineKill')},
|
||||
WIDGET.newSwitch{name='b2bKill', x=850, y=950, lim=210,disp=CUSval('b2bKill'), code=CUSrev('b2bKill')},
|
||||
WIDGET.newSwitch{name='lockout', x=850, y=1010,lim=210,disp=CUSval('lockout'), code=CUSrev('lockout')},
|
||||
WIDGET.newSwitch{name='easyFresh', x=1170,y=830, lim=250,disp=CUSval('easyFresh'),code=CUSrev('easyFresh')},
|
||||
WIDGET.newSwitch{name='deepDrop', x=1170,y=890, lim=250,disp=CUSval('deepDrop'), code=CUSrev('deepDrop')},
|
||||
WIDGET.newSwitch{name='bone', x=1170,y=950, lim=250,disp=CUSval('bone'), code=CUSrev('bone')},
|
||||
|
||||
--Next & Hold
|
||||
WIDGET.newSelector{name='holdMode', x=310, y=890, w=300,color='lY',list=sList.holdMode,disp=CUSval('holdMode'),code=CUSsto('holdMode')},
|
||||
WIDGET.newSelector{name='holdMode', x=310, y=890, w=300,color='lY',list=sList.holdMode,disp=CUSval('holdMode'),code=CUSsto('holdMode'),hideF=function()return CUSTOMENV.holdCount==0 end},
|
||||
WIDGET.newSlider{name='nextCount', x=140, y=960, lim=130,w=180,unit=6,disp=CUSval('nextCount'),code=CUSsto('nextCount')},
|
||||
WIDGET.newSlider{name='holdCount', x=140, y=1030,lim=130,w=180,unit=6,disp=CUSval('holdCount'),code=CUSsto('holdCount')},
|
||||
WIDGET.newSwitch{name='infHold', x=560, y=960, lim=200, disp=CUSval('infHold'),code=CUSrev('infHold'),hideF=function()return CUSTOMENV.holdCount==0 end},
|
||||
WIDGET.newSwitch{name='phyHold', x=560, y=1030,lim=200, disp=CUSval('phyHold'),code=CUSrev('phyHold'),hideF=function()return CUSTOMENV.holdCount==0 end},
|
||||
|
||||
--BG & BGM
|
||||
WIDGET.newSelector{name='bg', x=840, y=1030,w=250,color='Y',list=BG.getList(),disp=CUSval('bg'),code=function(i)CUSTOMENV.bg=i BG.set(i)end},
|
||||
WIDGET.newSelector{name='bgm', x=1120,y=1030,w=250,color='Y',list=BGM.getList(),disp=CUSval('bgm'),code=function(i)CUSTOMENV.bgm=i BGM.play(i)end},
|
||||
WIDGET.newSelector{name='bg', x=840, y=1090,w=250,color='Y',list=BG.getList(),disp=CUSval('bg'),code=function(i)CUSTOMENV.bg=i BG.set(i)end},
|
||||
WIDGET.newSelector{name='bgm', x=1120,y=1090,w=250,color='Y',list=BGM.getList(),disp=CUSval('bgm'),code=function(i)CUSTOMENV.bgm=i BGM.play(i)end},
|
||||
}
|
||||
|
||||
return scene
|
||||
|
||||
@@ -127,7 +127,7 @@ function scene.sceneInit()
|
||||
page=1
|
||||
end
|
||||
function scene.sceneBack()
|
||||
FILE.save(DATA.copyBoards(),'conf/customBoards')
|
||||
saveFile(DATA.copyBoards(),'conf/customBoards')
|
||||
end
|
||||
|
||||
function scene.mouseMove(x,y)
|
||||
|
||||
@@ -16,7 +16,7 @@ function scene.sceneInit()
|
||||
sure=0
|
||||
end
|
||||
function scene.sceneBack()
|
||||
FILE.save(DATA.copyMission(),'conf/customMissions')
|
||||
saveFile(DATA.copyMission(),'conf/customMissions')
|
||||
end
|
||||
|
||||
local ENUM_MISSION=ENUM_MISSION
|
||||
|
||||
@@ -16,7 +16,7 @@ function scene.sceneInit()
|
||||
sure=0
|
||||
end
|
||||
function scene.sceneBack()
|
||||
FILE.save(DATA.copySequence(),'conf/customSequence')
|
||||
saveFile(DATA.copySequence(),'conf/customSequence')
|
||||
end
|
||||
|
||||
local minoKey={
|
||||
|
||||
@@ -12,7 +12,7 @@ local dict--Dict list
|
||||
local result--Result Lable
|
||||
|
||||
local lastTickInput
|
||||
local waiting--Searching animation timer
|
||||
local searchWait--Searching animation timer
|
||||
local selected--Selected option
|
||||
local scrollPos--Scroll down length
|
||||
|
||||
@@ -53,7 +53,7 @@ local function _clearResult()
|
||||
TABLE.cut(result)
|
||||
selected=1
|
||||
scrollPos=0
|
||||
waiting,lastSearch=0,false
|
||||
searchWait,lastSearch=0,false
|
||||
scene.widgetList.copy.hide=false
|
||||
end
|
||||
local function _search()
|
||||
@@ -82,7 +82,7 @@ function scene.sceneInit()
|
||||
inputBox:clear()
|
||||
result={}
|
||||
|
||||
waiting=0
|
||||
searchWait=0
|
||||
selected=1
|
||||
scrollPos=0
|
||||
|
||||
@@ -115,8 +115,9 @@ function scene.keyDown(key)
|
||||
for _=1,12 do scene.keyDown("up")end
|
||||
elseif key=="right"or key=="pagedown"then
|
||||
for _=1,12 do scene.keyDown("down")end
|
||||
elseif key=="link"then
|
||||
love.system.openURL(_getList()[selected].url)
|
||||
elseif key=="application"then
|
||||
local url=_getList()[selected].url
|
||||
if url then love.system.openURL(url)end
|
||||
elseif key=="delete"then
|
||||
if inputBox:hasText()then
|
||||
_clearResult()
|
||||
@@ -152,13 +153,13 @@ function scene.update(dt)
|
||||
if #input==0 then
|
||||
_clearResult()
|
||||
else
|
||||
waiting=.8
|
||||
searchWait=.8
|
||||
end
|
||||
lastTickInput=input
|
||||
end
|
||||
if waiting>0 then
|
||||
waiting=waiting-dt
|
||||
if waiting<=0 then
|
||||
if searchWait>0 then
|
||||
searchWait=searchWait-dt
|
||||
if searchWait<=0 then
|
||||
if #input>0 and input~=lastSearch then
|
||||
_search()
|
||||
end
|
||||
@@ -201,7 +202,7 @@ function scene.draw()
|
||||
gc.rectangle('line',300,180,958,526,5)
|
||||
gc.rectangle('line',20,180,280,526,5)
|
||||
|
||||
if waiting>0 then
|
||||
if searchWait>0 then
|
||||
local r=TIME()*2
|
||||
local R=int(r)%7+1
|
||||
gc.setColor(1,1,1,1-abs(r%1*2-1))
|
||||
@@ -213,7 +214,7 @@ scene.widgetList={
|
||||
WIDGET.newText{name='book', x=20,y=15,font=70,align='L',fText=CHAR.icon.zBook},
|
||||
WIDGET.newText{name='title', x=100,y=15,font=70,align='L'},
|
||||
inputBox,
|
||||
WIDGET.newKey{name='link', x=1120,y=655,w=80,font=55,fText=CHAR.icon.globe, code=pressKey"link",hideF=function()return not _getList()[selected].url end},
|
||||
WIDGET.newKey{name='link', x=1120,y=655,w=80,font=55,fText=CHAR.icon.globe, code=pressKey"application",hideF=function()return not _getList()[selected].url end},
|
||||
WIDGET.newKey{name='copy', x=1210,y=655,w=80,font=50,fText=CHAR.icon.copy, code=pressKey"cC"},
|
||||
WIDGET.newKey{name='up', x=1120,y=475,w=80,font=50,fText=CHAR.key.up, code=pressKey"up",hide=not MOBILE},
|
||||
WIDGET.newKey{name='down', x=1120,y=565,w=80,font=50,fText=CHAR.key.down, code=pressKey"down",hide=not MOBILE},
|
||||
|
||||
@@ -9,9 +9,9 @@ local scene={}
|
||||
|
||||
function scene.sceneInit()
|
||||
BGcolor=rnd()>.026 and{.3,.5,.9}or{.62,.3,.926}
|
||||
stateInfo=SYSTEM.."-"..VERSION.string.." scene:"..ERRDATA[#ERRDATA].scene
|
||||
stateInfo=SYSTEM.."-"..VERSION.string.." scene:"..Z.errData[#Z.errData].scene
|
||||
errorText=LOADED and text.errorMsg or"An error has occurred during loading.\nError info has been created, and you can send it to the author."
|
||||
errorShot,errorInfo=ERRDATA[#ERRDATA].shot,ERRDATA[#ERRDATA].mes
|
||||
errorShot,errorInfo=Z.errData[#Z.errData].shot,Z.errData[#Z.errData].mes
|
||||
NET.wsclose_app()
|
||||
NET.wsclose_user()
|
||||
NET.wsclose_play()
|
||||
|
||||
@@ -11,6 +11,14 @@ local t1,t2,animeType
|
||||
local studioLogo--Studio logo text object
|
||||
local logoColor1,logoColor2
|
||||
|
||||
local titleTransform={
|
||||
function(t)gc.translate(0,max(50-t,0)^2/25)end,
|
||||
function(t)gc.translate(0,-max(50-t,0)^2/25)end,
|
||||
function(t,i)local d=max(50-t,0)gc.translate(sin(TIME()*3+626*i)*d,cos(TIME()*3+626*i)*d)end,
|
||||
function(t,i)local d=max(50-t,0)gc.translate(sin(TIME()*3+626*i)*d,-cos(TIME()*3+626*i)*d)end,
|
||||
function(t)gc.setColor(1,1,1,min(t*.02,1)+rnd()*.2)end,
|
||||
}
|
||||
|
||||
local loadingThread=coroutine.wrap(function()
|
||||
DAILYLAUNCH=freshDate'q'
|
||||
if DAILYLAUNCH then
|
||||
@@ -88,7 +96,7 @@ local loadingThread=coroutine.wrap(function()
|
||||
|
||||
YIELD('loadMode')
|
||||
for _,M in next,MODES do
|
||||
M.records=FILE.load("record/"..M.name..".rec",'luaon')or M.score and{}
|
||||
M.records=loadFile("record/"..M.name..".rec",'-luaon -canSkip')or M.score and{}
|
||||
M.icon=M.icon and(modeIcons[M.icon]or gc.newImage("media/image/modeicon/"..M.icon..".png"))
|
||||
end
|
||||
|
||||
@@ -113,7 +121,7 @@ function scene.sceneInit()
|
||||
progress=0
|
||||
maxProgress=10
|
||||
t1,t2=0,0--Timer
|
||||
animeType={}for i=1,8 do animeType[i]=rnd(5)end--Random animation type
|
||||
animeType={}for i=1,#SVG_TITLE_FILL do animeType[i]=rnd(#titleTransform)end--Random animation type
|
||||
end
|
||||
function scene.sceneBack()
|
||||
love.event.quit()
|
||||
@@ -147,13 +155,6 @@ function scene.update(dt)
|
||||
end
|
||||
end
|
||||
|
||||
local titleTransform={
|
||||
function(t)gc.translate(0,max(50-t,0)^2/25)end,
|
||||
function(t)gc.translate(0,-max(50-t,0)^2/25)end,
|
||||
function(t,i)local d=max(50-t,0)gc.translate(sin(TIME()*3+626*i)*d,cos(TIME()*3+626*i)*d)end,
|
||||
function(t,i)local d=max(50-t,0)gc.translate(sin(TIME()*3+626*i)*d,-cos(TIME()*3+626*i)*d)end,
|
||||
function(t)gc.setColor(1,1,1,min(t*.02,1)+rnd()*.2)end,
|
||||
}
|
||||
local titleColor={COLOR.P,COLOR.F,COLOR.V,COLOR.A,COLOR.M,COLOR.N,COLOR.W,COLOR.Y}
|
||||
function scene.draw()
|
||||
gc.clear(.08,.08,.084)
|
||||
@@ -166,7 +167,8 @@ function scene.draw()
|
||||
end
|
||||
gc.push('transform')
|
||||
gc.translate(126,100)
|
||||
for i=1,8 do
|
||||
for i=1,#SVG_TITLE_FILL do
|
||||
local triangles=love.math.triangulate(SVG_TITLE_FILL[i])
|
||||
local t=t1-i*15
|
||||
if t>0 then
|
||||
gc.push('transform')
|
||||
@@ -176,9 +178,12 @@ function scene.draw()
|
||||
gc.translate(0,math.abs(10-dt)-10)
|
||||
end
|
||||
gc.setColor(titleColor[i][1],titleColor[i][2],titleColor[i][3],min(t*.025,1)*.2)
|
||||
gc.polygon('fill',SVG_TITLE[i])
|
||||
for j=1,#triangles do
|
||||
gc.polygon('fill',triangles[j])
|
||||
end
|
||||
gc.setColor(1,1,1,min(t*.025,1))
|
||||
gc.polygon('line',SVG_TITLE[i])
|
||||
gc.polygon('line',SVG_TITLE_LINE[i])
|
||||
if i==8 then gc.polygon('line',SVG_TITLE_LINE[9])end
|
||||
gc.pop()
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,7 +12,7 @@ local function _login()
|
||||
end
|
||||
NET.wsconn_user_pswd(email,password)
|
||||
if savePW then
|
||||
FILE.save({email,password},'conf/account')
|
||||
saveFile({email,password},'conf/account')
|
||||
else
|
||||
love.filesystem.remove('conf/account')
|
||||
end
|
||||
@@ -21,7 +21,7 @@ end
|
||||
local scene={}
|
||||
|
||||
function scene.sceneInit()
|
||||
local data=FILE.load('conf/account')
|
||||
local data=loadFile('conf/account')
|
||||
if data then
|
||||
savePW=true
|
||||
emailBox:setText(data[1])
|
||||
|
||||
@@ -162,7 +162,7 @@ function scene.update()
|
||||
if kb.isDown("down","s")then dy=dy-10 F=true end
|
||||
if kb.isDown("left","a")then dx=dx+10 F=true end
|
||||
if kb.isDown("right","d")then dx=dx-10 F=true end
|
||||
local js1=joysticks[1]
|
||||
local js1=Z.js[1]
|
||||
if js1 then
|
||||
local dir=js1:getAxis(1)
|
||||
if dir~="c"then
|
||||
|
||||
@@ -22,6 +22,7 @@ local author={
|
||||
["race remix"]="柒栎流星",
|
||||
["sakura"]="ZUN & C₂₉H₂₅N₃O₅",
|
||||
["1980s"]="C₂₉H₂₅N₃O₅",
|
||||
["malate"]="ZUN & C₂₉H₂₅N₃O₅",
|
||||
}
|
||||
|
||||
local scene={}
|
||||
|
||||
@@ -28,7 +28,7 @@ scene.widgetList={
|
||||
NET.wsclose_user()
|
||||
USER.uid=false
|
||||
USER.authToken=false
|
||||
FILE.save(USER,'conf/user')
|
||||
saveFile(USER,'conf/user')
|
||||
SCN.back()
|
||||
end
|
||||
else
|
||||
|
||||
@@ -20,7 +20,10 @@ local sList={
|
||||
lock={0,1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,60,180,1e99},
|
||||
wait={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
|
||||
fall={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
|
||||
hang={0,1,2,3,4,5,6,7,8,10,15,20,30,60},
|
||||
hurry={0,1,2,3,4,5,6,7,8,10,1e99},
|
||||
eventSet=EVENTSETS,
|
||||
holdMode={'hold','swap'},
|
||||
}
|
||||
|
||||
local scene={}
|
||||
@@ -87,6 +90,8 @@ scene.widgetList={
|
||||
WIDGET.newSelector{name='lock', x=730,y=410,w=260,color='O',list=sList.lock,disp=ROOMval('lock'),code=ROOMsto('lock')},
|
||||
WIDGET.newSelector{name='wait', x=730,y=520,w=260,color='G',list=sList.wait,disp=ROOMval('wait'),code=ROOMsto('wait')},
|
||||
WIDGET.newSelector{name='fall', x=730,y=600,w=260,color='G',list=sList.fall,disp=ROOMval('fall'),code=ROOMsto('fall')},
|
||||
WIDGET.newSelector{name='hurry', x=730,y=680,w=260,color='G',list=sList.hurry,disp=ROOMval('hurry'),code=ROOMval('hurry')},
|
||||
WIDGET.newSelector{name='hang', x=730,y=760,w=260,color='G',list=sList.hang,disp=ROOMval('hang'),code=ROOMval('hang')},
|
||||
|
||||
--Capacity & Create & Back
|
||||
WIDGET.newSelector{name='capacity', x=1070,y=330,w=310,color='lY',list={2,3,4,5,7,10,17,31,49,99},disp=ROOMval('capacity'),code=ROOMsto('capacity')},
|
||||
@@ -94,17 +99,19 @@ scene.widgetList={
|
||||
WIDGET.newButton{name='back', x=1140,y=640,w=170,h=80,font=60,fText=CHAR.icon.back,code=backScene},
|
||||
|
||||
--Special rules
|
||||
WIDGET.newSwitch{name='ospin', x=850, y=750,lim=210,disp=ROOMval('ospin'), code=ROOMrev('ospin')},
|
||||
WIDGET.newSwitch{name='fineKill', x=850, y=840,lim=210,disp=ROOMval('fineKill'), code=ROOMrev('fineKill')},
|
||||
WIDGET.newSwitch{name='b2bKill', x=850, y=930,lim=210,disp=ROOMval('b2bKill'), code=ROOMrev('b2bKill')},
|
||||
WIDGET.newSwitch{name='easyFresh', x=1170,y=750,lim=250,disp=ROOMval('easyFresh'),code=ROOMrev('easyFresh')},
|
||||
WIDGET.newSwitch{name='deepDrop', x=1170,y=840,lim=250,disp=ROOMval('deepDrop'), code=ROOMrev('deepDrop')},
|
||||
WIDGET.newSwitch{name='bone', x=1170,y=930,lim=250,disp=ROOMval('bone'), code=ROOMrev('bone')},
|
||||
WIDGET.newSwitch{name='ospin', x=850, y=850, lim=210,disp=ROOMval('ospin'), code=ROOMrev('ospin')},
|
||||
WIDGET.newSwitch{name='fineKill', x=850, y=910, lim=210,disp=ROOMval('fineKill'), code=ROOMrev('fineKill')},
|
||||
WIDGET.newSwitch{name='b2bKill', x=850, y=970, lim=210,disp=ROOMval('b2bKill'), code=ROOMrev('b2bKill')},
|
||||
WIDGET.newSwitch{name='lockout', x=850, y=1030,lim=210,disp=ROOMval('lockout'), code=ROOMrev('lockout')},
|
||||
WIDGET.newSwitch{name='easyFresh', x=1170,y=850, lim=250,disp=ROOMval('easyFresh'),code=ROOMrev('easyFresh')},
|
||||
WIDGET.newSwitch{name='deepDrop', x=1170,y=910, lim=250,disp=ROOMval('deepDrop'), code=ROOMrev('deepDrop')},
|
||||
WIDGET.newSwitch{name='bone', x=1170,y=970, lim=250,disp=ROOMval('bone'), code=ROOMrev('bone')},
|
||||
|
||||
--Rule set
|
||||
WIDGET.newSelector{name='eventSet', x=310,y=880,w=360,color='H',list=sList.eventSet,disp=ROOMval('eventSet'),code=ROOMsto('eventSet')},
|
||||
WIDGET.newSelector{name='eventSet', x=1050,y=760,w=340,color='H',list=sList.eventSet,disp=ROOMval('eventSet'),code=ROOMval('eventSet')},
|
||||
|
||||
--Next & Hold
|
||||
WIDGET.newSelector{name='holdMode', x=310, y=890, w=300,color='lY',list=sList.holdMode,disp=ROOMval('holdMode'),code=ROOMval('holdMode'),hideF=function()return CUSTOMENV.holdCount==0 end},
|
||||
WIDGET.newSlider{name='nextCount', x=140, y=960, lim=130,w=200,unit=6,disp=ROOMval('nextCount'),code=ROOMsto('nextCount')},
|
||||
WIDGET.newSlider{name='holdCount', x=140, y=1030,lim=130,w=200,unit=6,disp=ROOMval('holdCount'),code=ROOMsto('holdCount')},
|
||||
WIDGET.newSwitch{name='infHold', x=560, y=960, lim=200, disp=ROOMval('infHold'),code=ROOMrev('infHold'),hideF=function()return ROOMENV.holdCount==0 end},
|
||||
|
||||
@@ -90,7 +90,7 @@ function scene.keyDown(key)
|
||||
local rep=listBox:getSel()
|
||||
if rep then
|
||||
if rep.available and rep.fileName then
|
||||
local repStr=FILE.load(rep.fileName,'string')
|
||||
local repStr=loadFile(rep.fileName,'-string')
|
||||
if repStr then
|
||||
love.system.setClipboardText(love.data.encode('string','base64',repStr))
|
||||
MES.new('info',text.exportSuccess)
|
||||
@@ -108,7 +108,7 @@ function scene.keyDown(key)
|
||||
local fileName=os.date("replay/%Y_%m_%d_%H%M%S_import.rep")
|
||||
local rep=DATA.parseReplayData(fileName,fileData,false)
|
||||
if rep.available then
|
||||
if FILE.save(fileData,fileName,'d')then
|
||||
if saveFile(fileData,fileName,'-d')then
|
||||
table.insert(REPLAY,1,rep)
|
||||
MES.new('info',text.importSuccess)
|
||||
end
|
||||
|
||||
@@ -71,7 +71,7 @@ scene.widgetList={
|
||||
local D=_parseCB()
|
||||
if D then
|
||||
TABLE.update(D,VK_ORG)
|
||||
FILE.save(VK_ORG,'conf/virtualkey')
|
||||
saveFile(VK_ORG,'conf/virtualkey')
|
||||
MES.new('check',text.importSuccess)
|
||||
else
|
||||
MES.new('error',text.dataCorrupted)
|
||||
|
||||
@@ -31,24 +31,25 @@ function scene.draw()
|
||||
end
|
||||
|
||||
scene.widgetList={
|
||||
WIDGET.newText{name='title', x=640,y=15,font=80},
|
||||
WIDGET.newText{name='title', x=640,y=15,font=80},
|
||||
|
||||
WIDGET.newButton{name='graphic', x=200, y=80, w=240,h=80,color='lC',font=35,code=swapScene('setting_video','swipeR')},
|
||||
WIDGET.newButton{name='sound', x=1080, y=80, w=240,h=80,color='lC',font=35,code=swapScene('setting_sound','swipeL')},
|
||||
WIDGET.newButton{name='graphic', x=200, y=80, w=240,h=80,color='lC',font=35,code=swapScene('setting_video','swipeR')},
|
||||
WIDGET.newButton{name='sound', x=1080, y=80, w=240,h=80,color='lC',font=35,code=swapScene('setting_sound','swipeL')},
|
||||
|
||||
WIDGET.newButton{name='layout', x=250, y=540, w=200,h=70,font=35,code=goScene'setting_skin'},
|
||||
WIDGET.newButton{name='layout', x=250, y=540, w=200,h=70,font=35,code=goScene'setting_skin'},
|
||||
|
||||
WIDGET.newButton{name='ctrl', x=290, y=220, w=320,h=80,font=35,code=goScene'setting_control'},
|
||||
WIDGET.newButton{name='key', x=640, y=220, w=320,h=80,color=MOBILE and'dH',font=35,code=goScene'setting_key'},
|
||||
WIDGET.newButton{name='touch', x=990, y=220, w=320,h=80,color=not MOBILE and'dH',font=35,code=goScene'setting_touch'},
|
||||
WIDGET.newSlider{name='reTime', x=330, y=320, w=300,lim=180,unit=10,disp=SETval('reTime'), code=SETsto('reTime'),show=function(S)return(.5+S.disp()*.25).."s"end},
|
||||
WIDGET.newSelector{name='RS', x=300, y=420, w=300,color='S', disp=SETval('RS'), code=SETsto('RS'),list={'TRS','SRS','SRS_plus','SRS_X','BiRS','ARS_Z','ASC','ASC_plus','C2','C2_sym','Classic','Classic_plus','None','None_plus'}},
|
||||
WIDGET.newSelector{name='menuPos', x=980, y=320, w=300,color='O', disp=SETval('menuPos'), code=SETsto('menuPos'),list={'left','middle','right'}},
|
||||
WIDGET.newSwitch{name='sysCursor' ,x=1060, y=390, lim=580, disp=SETval('sysCursor'),code=function()SETTING.sysCursor=not SETTING.sysCursor applyCursor()end},
|
||||
WIDGET.newSwitch{name='autoPause', x=1060, y=450, lim=580, disp=SETval('autoPause'),code=SETrev('autoPause')},
|
||||
WIDGET.newSwitch{name='autoSave', x=1060, y=500, lim=580, disp=SETval('autoSave'), code=SETrev('autoSave')},
|
||||
WIDGET.newSwitch{name='autoLogin', x=960, y=580, lim=480, disp=SETval('autoLogin'),code=SETrev('autoLogin')},
|
||||
WIDGET.newSwitch{name='simpMode', x=960, y=640, lim=480, disp=SETval('simpMode'),
|
||||
WIDGET.newButton{name='ctrl', x=290, y=220, w=320,h=80,font=35,code=goScene'setting_control'},
|
||||
WIDGET.newButton{name='key', x=640, y=220, w=320,h=80,color=MOBILE and'dH',font=35, code=goScene'setting_key'},
|
||||
WIDGET.newButton{name='touch', x=990, y=220, w=320,h=80,color=not MOBILE and'dH',font=35, code=goScene'setting_touch',hideF=function()return not SETTING.VKSwitch end},
|
||||
WIDGET.newSwitch{name='showVK', x=1100, y=150, lim=400, disp=SETval('VKSwitch'), code=SETrev('VKSwitch')},
|
||||
WIDGET.newSlider{name='reTime', x=330, y=320, w=300,lim=180,unit=10,disp=SETval('reTime'), code=SETsto('reTime'),show=function(S)return(.5+S.disp()*.25).."s"end},
|
||||
WIDGET.newSelector{name='RS', x=300, y=420, w=300,color='S', disp=SETval('RS'), code=SETsto('RS'),list={'TRS','SRS','SRS_plus','SRS_X','BiRS','ARS_Z','ASC','ASC_plus','C2','C2_sym','Classic','Classic_plus','None','None_plus'}},
|
||||
WIDGET.newSelector{name='menuPos',x=980, y=320, w=300,color='O', disp=SETval('menuPos'), code=SETsto('menuPos'),list={'left','middle','right'}},
|
||||
WIDGET.newSwitch{name='sysCursor',x=1060, y=390, lim=580, disp=SETval('sysCursor'),code=function()SETTING.sysCursor=not SETTING.sysCursor applyCursor()end},
|
||||
WIDGET.newSwitch{name='autoPause',x=1060, y=450, lim=580, disp=SETval('autoPause'),code=SETrev('autoPause')},
|
||||
WIDGET.newSwitch{name='autoSave', x=1060, y=500, lim=580, disp=SETval('autoSave'), code=SETrev('autoSave')},
|
||||
WIDGET.newSwitch{name='autoLogin',x=960, y=580, lim=480, disp=SETval('autoLogin'),code=SETrev('autoLogin')},
|
||||
WIDGET.newSwitch{name='simpMode', x=960, y=640, lim=480, disp=SETval('simpMode'),
|
||||
code=function()
|
||||
SETTING.simpMode=not SETTING.simpMode
|
||||
for i=1,#SCN.stack,2 do
|
||||
@@ -58,7 +59,7 @@ scene.widgetList={
|
||||
end
|
||||
end
|
||||
end},
|
||||
WIDGET.newButton{name='back', x=1140, y=640, w=170,h=80,font=60,fText=CHAR.icon.back,code=backScene},
|
||||
WIDGET.newButton{name='back', x=1140, y=640, w=170,h=80,font=60,fText=CHAR.icon.back,code=backScene},
|
||||
}
|
||||
|
||||
return scene
|
||||
|
||||
@@ -23,7 +23,7 @@ function scene.sceneInit()
|
||||
BG.set('none')
|
||||
end
|
||||
function scene.sceneBack()
|
||||
FILE.save(KEY_MAP,'conf/key')
|
||||
saveFile(KEY_MAP,'conf/key')
|
||||
end
|
||||
|
||||
local forbbidenKeys={
|
||||
|
||||
@@ -62,6 +62,7 @@ local function _nextSkin(i)
|
||||
SETTING.skin[i]=SETTING.skin[i]%16+1
|
||||
end
|
||||
local function _nextDir(i)
|
||||
trySettingWarn()
|
||||
SETTING.face[i]=(SETTING.face[i]+1)%4
|
||||
minoRot0[i]=minoRot0[i]+1.5707963
|
||||
if not selEggMode and not GAME.playing then
|
||||
|
||||
@@ -9,10 +9,10 @@ local snapUnit=1
|
||||
local selected--Button selected
|
||||
|
||||
local function _save1()
|
||||
FILE.save(VK_ORG,'conf/vkSave1')
|
||||
saveFile(VK_ORG,'conf/vkSave1')
|
||||
end
|
||||
local function _load1()
|
||||
local D=FILE.load('conf/vkSave1')
|
||||
local D=loadFile('conf/vkSave1')
|
||||
if D then
|
||||
TABLE.update(D,VK_ORG)
|
||||
else
|
||||
@@ -20,10 +20,10 @@ local function _load1()
|
||||
end
|
||||
end
|
||||
local function _save2()
|
||||
FILE.save(VK_ORG,'conf/vkSave2')
|
||||
saveFile(VK_ORG,'conf/vkSave2')
|
||||
end
|
||||
local function _load2()
|
||||
local D=FILE.load('conf/vkSave2')
|
||||
local D=loadFile('conf/vkSave2')
|
||||
if D then
|
||||
TABLE.update(D,VK_ORG)
|
||||
else
|
||||
@@ -37,7 +37,7 @@ function scene.sceneInit()
|
||||
selected=false
|
||||
end
|
||||
function scene.sceneBack()
|
||||
FILE.save(VK_ORG,'conf/virtualkey')
|
||||
saveFile(VK_ORG,'conf/virtualkey')
|
||||
end
|
||||
|
||||
local function _onVK_org(x,y)
|
||||
|
||||
@@ -5,7 +5,7 @@ function scene.sceneInit()
|
||||
end
|
||||
|
||||
function scene.draw()
|
||||
if SETTING.VKSwitch and SETTING.VKTrack then
|
||||
if SETTING.VKTrack then
|
||||
love.graphics.setColor(1,1,1)
|
||||
setFont(30)
|
||||
mStr(text.VKTchW,140+500*SETTING.VKTchW,800-WIDGET.scrollPos)
|
||||
@@ -15,9 +15,17 @@ function scene.draw()
|
||||
end
|
||||
|
||||
local function _VKAdisp(n)return function()return VK_ORG[n].ava end end
|
||||
local function _VKAcode(n)return function()VK_ORG[n].ava=not VK_ORG[n].ava end end
|
||||
local function _notShow()return not SETTING.VKSwitch end
|
||||
local function _notTrack()return not(SETTING.VKSwitch and SETTING.VKTrack)end
|
||||
local function _VKAcode(n)
|
||||
return n<10 and
|
||||
function()
|
||||
VK_ORG[n].ava=not VK_ORG[n].ava
|
||||
trySettingWarn()
|
||||
end or
|
||||
function()
|
||||
VK_ORG[n].ava=not VK_ORG[n].ava
|
||||
end
|
||||
end
|
||||
local function _notTrack()return not SETTING.VKTrack end
|
||||
|
||||
scene.widgetScrollHeight=340
|
||||
scene.widgetList={
|
||||
@@ -44,13 +52,12 @@ scene.widgetList={
|
||||
|
||||
WIDGET.newButton{name='norm', x=840, y=80, w=240,h=80, font=35,code=function()for i=1,20 do VK_ORG[i].ava=i<11 end end},
|
||||
WIDGET.newButton{name='pro', x=1120, y=80, w=240,h=80, font=35,code=function()for i=1,20 do VK_ORG[i].ava=true end end},
|
||||
WIDGET.newSwitch{name='hide', x=1150, y=200, lim=400, font=40,disp=SETval('VKSwitch'),code=SETrev('VKSwitch')},
|
||||
WIDGET.newSwitch{name='icon', x=1150, y=300, lim=400, font=40,disp=SETval('VKIcon'),code=SETrev('VKIcon'),hideF=_notShow},
|
||||
WIDGET.newSlider{name='sfx', x=830, y=380, lim=160,w=400, font=35,change=function()SFX.play('virtualKey',SETTING.VKSFX)end,disp=SETval('VKSFX'),code=SETsto('VKSFX'),hideF=_notShow},
|
||||
WIDGET.newSlider{name='vib', x=830, y=450, lim=160,w=400,unit=6, font=35,change=function()if SETTING.vib>0 then VIB(SETTING.vib+SETTING.VKVIB)end end,disp=SETval('VKVIB'),code=SETsto('VKVIB'),hideF=_notShow},
|
||||
WIDGET.newSlider{name='alpha', x=830, y=520, lim=160,w=400, font=40,disp=SETval('VKAlpha'),code=SETsto('VKAlpha'),hideF=_notShow},
|
||||
WIDGET.newSwitch{name='icon', x=1150, y=240, lim=400, font=35,disp=SETval('VKIcon'),code=SETrev('VKIcon')},
|
||||
WIDGET.newSlider{name='sfx', x=830, y=320, lim=160,w=400, font=35,change=function()SFX.play('virtualKey',SETTING.VKSFX)end,disp=SETval('VKSFX'),code=SETsto('VKSFX')},
|
||||
WIDGET.newSlider{name='vib', x=830, y=390, lim=160,w=400,unit=6, font=35,change=function()if SETTING.vib>0 then VIB(SETTING.vib+SETTING.VKVIB)end end,disp=SETval('VKVIB'),code=SETsto('VKVIB')},
|
||||
WIDGET.newSlider{name='alpha', x=830, y=460, lim=160,w=400, font=35,disp=SETval('VKAlpha'),code=SETsto('VKAlpha')},
|
||||
|
||||
WIDGET.newSwitch{name='track', x=360, y=720, lim=250, font=35,disp=SETval('VKTrack'),code=SETrev('VKTrack'),hideF=_notShow},
|
||||
WIDGET.newSwitch{name='track', x=360, y=720, lim=250, font=35,disp=SETval('VKTrack'),code=SETrev('VKTrack')},
|
||||
WIDGET.newSwitch{name='dodge', x=800, y=720, lim=250, font=35,disp=SETval('VKDodge'),code=SETrev('VKDodge'),hideF=_notTrack},
|
||||
WIDGET.newSlider{name='tchW', x=140, y=860, w=1000, font=35,disp=SETval('VKTchW'),code=function(i)SETTING.VKTchW=i SETTING.VKCurW=math.max(SETTING.VKCurW,i)end,hideF=_notTrack},
|
||||
WIDGET.newSlider{name='curW', x=140, y=930, w=1000, font=35,disp=SETval('VKCurW'),code=function(i)SETTING.VKCurW=i SETTING.VKTchW=math.min(SETTING.VKTchW,i)end,hideF=_notTrack},
|
||||
|
||||
@@ -69,38 +69,37 @@ end
|
||||
gc.setDefaultFilter('linear','linear')
|
||||
|
||||
|
||||
TEXTURE.title=NSC(1160,236)--Title image (Middle: 580,118)
|
||||
TEXTURE.title=NSC(1040,236)--Title image (Middle: 580,118)
|
||||
do
|
||||
for i=1,8 do
|
||||
local triangles=love.math.triangulate(SVG_TITLE[i])
|
||||
gc.setLineWidth(12)
|
||||
gc.translate(10,10)
|
||||
for i=1,#SVG_TITLE_FILL do
|
||||
local triangles=love.math.triangulate(SVG_TITLE_FILL[i])
|
||||
|
||||
gc.translate(12*i,i==1 and 8 or 14)
|
||||
|
||||
gc.setLineWidth(16)
|
||||
gc.setColor(COLOR.Z)
|
||||
gc.polygon('line',SVG_TITLE[i])
|
||||
gc.polygon('line',SVG_TITLE_FILL[i])
|
||||
|
||||
gc.setColor(.2,.2,.2)
|
||||
for j=1,#triangles do
|
||||
gc.polygon('fill',triangles[j])
|
||||
end
|
||||
|
||||
gc.translate(-12*i,i==1 and -8 or -14)
|
||||
end
|
||||
gc.translate(-10,-10)
|
||||
end
|
||||
|
||||
TEXTURE.title_color=NSC(1160,236)--Title image (colored)
|
||||
TEXTURE.title_color=NSC(1040,236)--Title image (colored)
|
||||
do
|
||||
local titleColor={COLOR.P,COLOR.F,COLOR.V,COLOR.A,COLOR.M,COLOR.N,COLOR.W,COLOR.Y}
|
||||
|
||||
gc.translate(10,10)
|
||||
for i=1,8 do
|
||||
local triangles=love.math.triangulate(SVG_TITLE[i])
|
||||
local triangles=love.math.triangulate(SVG_TITLE_FILL[i])
|
||||
|
||||
gc.translate(12*i,i==1 and 8 or 14)
|
||||
|
||||
gc.setLineWidth(16)
|
||||
gc.setLineWidth(12)
|
||||
gc.setColor(COLOR.Z)
|
||||
gc.polygon('line',SVG_TITLE[i])
|
||||
gc.polygon('line',SVG_TITLE_FILL[i])
|
||||
|
||||
gc.setLineWidth(4)
|
||||
gc.setColor(COLOR.D)
|
||||
@@ -109,14 +108,11 @@ do
|
||||
end
|
||||
|
||||
gc.setColor(.2+.8*titleColor[i][1],.2+.8*titleColor[i][2],.2+.8*titleColor[i][3],.3)
|
||||
gc.translate(-4,-4)
|
||||
for j=1,#triangles do
|
||||
gc.polygon('fill',triangles[j])
|
||||
end
|
||||
gc.translate(4,4)
|
||||
|
||||
gc.translate(-12*i,i==1 and -8 or -14)
|
||||
end
|
||||
gc.translate(-10,-10)
|
||||
end
|
||||
|
||||
TEXTURE.multiple=GC.DO{15,15,
|
||||
|
||||
@@ -3,23 +3,40 @@ return[=[
|
||||
Tetro-1010(2C2N, 重力); Tetra-link(桌游)
|
||||
噗哟; 泡泡龙; 求合体; 坦克大战; 扫雷; 接水管; 记忆
|
||||
其他未来内容:
|
||||
组队战; 实时统计数据可视化; 教学关; 从录像继续
|
||||
重做模式选择UI; 重做模组UI; 加速下落; spike相关统计数据
|
||||
实时统计数据可视化; 教学关脚本语言; 从录像继续
|
||||
模式系统重做; 重做模组UI; 加速下落; spike相关统计数据
|
||||
支持更多手柄; 场地格边缘线; 模式数据分析; 高级自定义序列
|
||||
等级系统; 成就系统; 手势操作; C2连击; 特殊控件(虚拟摇杆等)
|
||||
方块位移/旋转动画; 更细节的DAS选项; 拓展主题系统
|
||||
可调攻击系统; 更多消除方式; 可调场地宽度; 新联网游戏场景切换逻辑
|
||||
工程编译到字节码; task-Z(新AI); 自适应UI; 多方块
|
||||
组队战; 方块位移/旋转动画; 更细节的DAS选项; 拓展主题系统
|
||||
更自由的攻击系统; 更多消除方式; 可调场地宽度; 新联网游戏场景切换逻辑
|
||||
task-Z(新AI); 自适应UI; 多方块
|
||||
|
||||
0.17.0: 硬着陆 Hard Landing
|
||||
新增:
|
||||
新模式:大爆炸
|
||||
新模式:策略堆叠(原版设计来自Cambridge游戏, by NOT_A_ROBOT)
|
||||
新模式:清版竞速
|
||||
新模式:策略堆叠(原设计来自游戏Cambridge, by NOT_A_ROBOT)
|
||||
新BGM:malate(暂未使用)
|
||||
新机制:出块延迟打断(ARE打断)(默认关闭) #471
|
||||
添加锁定在外判负(lockout)规则(默认关闭)
|
||||
全局默认使用5帧窒息延迟
|
||||
支持摇杆和扳机(参数暂时不能调整)
|
||||
改动:
|
||||
TRS的S/Z添加四个踢墙防止在一些地方卡死
|
||||
调整游戏大logo为正体字
|
||||
软降n格的键也可以触发深降
|
||||
ultra模式计时器改为秒表,容易看清具体时间
|
||||
出块/消行延迟逻辑修正,现在真的是0延迟,不再有一帧等待了(略微影响手感,更滑)
|
||||
生成位置预览开启后hold的生成位置也可见 #453
|
||||
TRS的S/Z添加四个踢墙防止在一些地方卡死
|
||||
优化pc训练模式体验,添加胜利条件,不再无尽
|
||||
堆积模式添加15帧的窒息延迟 #465
|
||||
小程序arm加入计时器和重置按钮
|
||||
修改部分不常用设置时会显示警告
|
||||
代码:
|
||||
bgm模块可限制最大加载数,不容易达到上限导致没声 #447
|
||||
语音模块支持设置轻微随机音调偏移半径(游戏内固定使用1)
|
||||
较大规模整理玩家相关代码,重构出块延迟和消行延迟逻辑
|
||||
再次封装FILE模块
|
||||
扩展字符串扩展模块
|
||||
修复:
|
||||
机翻语言超级消除无行数显示 #462
|
||||
竞速-效率左侧信息颜色问题
|
||||
@@ -106,7 +123,7 @@ return[=[
|
||||
新语音包:miku(by vocaloidvictory)
|
||||
新BGM:Jazz nihilism(用于节日主题, by Trebor)
|
||||
新BGM:Race remix(用于大师-ph, by 柒栎流星)
|
||||
新BGM:Sakura(用于限时打分, by C₂₉H₂₅N₃O₅)
|
||||
新BGM:Sakura(用于ultra, by C₂₉H₂₅N₃O₅)
|
||||
新BGM:Null(用于节日主题)
|
||||
新音效:单次消5/6行
|
||||
新机制:swap(hold的另一种实现)
|
||||
@@ -1323,7 +1340,7 @@ return[=[
|
||||
0.10.5: 特效更新 FX update
|
||||
新内容:
|
||||
瞬移特效独立为瞬降和移动(旋转)特效,增加移动特效滑条,各特效范围均为0~5
|
||||
增加两个莫名其妙的背景(放在无尽和限时打分)
|
||||
增加两个莫名其妙的背景(放在无尽和ultra)
|
||||
把之前不小心弄丢的自制蓝屏报错界面捡回来了
|
||||
改动:
|
||||
雷达图OPM参数改为ADPM
|
||||
@@ -1443,7 +1460,7 @@ return[=[
|
||||
pc训练方块ghost浮空
|
||||
i平放顶层消1的奇怪行为
|
||||
玩家掉出屏幕过程中绘制场地时剪裁不正确
|
||||
限时打分的时间条和hold重合
|
||||
ultra的时间条和hold重合
|
||||
|
||||
0.9.2: Global Update
|
||||
new:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
return{
|
||||
["apkCode"]=404,
|
||||
["apkCode"]=409,
|
||||
["code"]=1700,
|
||||
["string"]="V0.17.0",
|
||||
["room"]="ver A-0",
|
||||
["room"]="ver A-2",
|
||||
["name"]="硬着陆 Hard Landing",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user