Compare commits

..

83 Commits

Author SHA1 Message Date
MrZ626
707bcca368 Merge commit 'f8f115de10b4ef7818cf58bc03c9d75700e425b0' into test-new-mode-system 2021-12-27 14:26:32 +08:00
MrZ626
f8f115de10 更新字体 2021-12-27 14:19:39 +08:00
MrZ626
b07c4dc53a 优化滑条控件和列表框控件 2021-12-26 02:57:57 +08:00
NOT_A_ROBOT
6eeddba773 Remove dictionary and legal page conflict (#563)
Dictionary: "A 🤔 game developed using LÖVE."
Legal page: "TECHMINO is not a fan game of Tetris."

This commit edits the dictionary to follow the legal page into:
"A block stacker game developed using LÖVE."
2021-12-25 19:24:51 +08:00
MrZ626
0cfe4df468 新BGM:lounge(暂未使用, by Hailey (cudsys) & MrZ) 2021-12-24 18:50:30 +08:00
MrZ626
eb5c3c3be5 版本推进 2021-12-24 00:08:46 +08:00
MrZ626
a5b9206694 修正联网对战结算的l'pm公式算的其实是lpm 2021-12-24 00:06:43 +08:00
MrZ626
375e67bdc4 微调框架坐标系相关细节 2021-12-24 00:06:40 +08:00
MrZ626
724a576aa3 跟进框架更新 2021-12-23 21:03:11 +08:00
MrZ626
ed47dcb90c 框架新增onResize 2021-12-23 21:03:05 +08:00
MrZ626
64b08a5a4d 修复录像界面导入导出按钮隐藏状态错误 2021-12-23 14:00:30 +08:00
MrZ626
baed0153a2 两个节日主题颜色浅一些 2021-12-23 13:48:39 +08:00
MrZ626
46d95b33e4 播放立体声音效限制输入值范围 2021-12-23 13:19:01 +08:00
MrZ626
200d270fee 框架会给场景提供触摸id 2021-12-22 21:22:19 +08:00
MrZ626
a8628275a0 大量指数接近动画改为基于时间而不是帧 2021-12-22 02:19:42 +08:00
MrZ626
20a1d2bcc1 修正框架主循环刷新率控制 2021-12-21 23:35:32 +08:00
MrZ626
b887a1f096 版本推进 2021-12-21 23:24:01 +08:00
MrZ626
9bf0e9f28d 调整一行hpc判定为“消除后最高行是垃圾行”,避免自定义场地的空气行争议 2021-12-21 23:18:49 +08:00
MrZ626
dfc724767b 调整帧率控制算法 2021-12-21 10:23:16 +08:00
MrZ626
f0e66e9dc5 框架添加设置最大帧率的入口 2021-12-21 00:16:29 +08:00
MrZ626
0932335f0b 微调游戏设置菜单 2021-12-20 23:21:02 +08:00
MrZ626
a9b39e396a BGM.play新增预加载参数 2021-12-20 16:01:19 +08:00
MrZ626
2e0ceaae72 math扩展库新增interval方法 2021-12-20 16:01:19 +08:00
MrZ626
04f38d2eb6 微调新模式pr的小问题 2021-12-20 14:55:42 +08:00
MrZ626
fc1ed4dff6 修正英文词典小问题 2021-12-20 14:52:40 +08:00
NOT_A_ROBOT
f8935d3dd7 Add Master Instinct mode (#545)
* Add Inverse Invisible mode

A mode where the locked pieces doesn't become invisible, but your active piece does.

[NOTE: I haven't added the mode to the map yet because the mode selection screen is changing]

* Renamed to Master Instinct
2021-12-20 14:51:30 +08:00
user670
a86228677f Update dict_en.lua (#556)
- Un-confused the support entries. Patreon processing fee assumes your account uses the 5% tier.
- TGM games are arcade games, NOT Windows games, despite their now most common versions found in China are Windows ports.
2021-12-20 14:47:45 +08:00
MrZ626
79df9f7876 前两个tsd模式有很小的重力 2021-12-19 20:22:02 +08:00
MrZ626
12ea2d76be 修正profile模块小问题 2021-12-19 17:06:44 +08:00
MrZ626
485bd72241 重构bgm模块 2021-12-19 16:29:50 +08:00
MrZ626
7240275075 修复一个bgm模块小问题 2021-12-19 15:26:16 +08:00
MrZ626
29ef9b8d15 ai种子会根据id变化 2021-12-19 00:59:01 +08:00
MrZ626
97f4795d4e 修正一处框架修改没改完导致地图报错 2021-12-19 00:50:42 +08:00
MrZ626
226e45b24d 整理代码 2021-12-18 16:08:45 +08:00
MrZ626
d6ab7e72b2 调整某个无关紧要的小东西 2021-12-18 01:15:04 +08:00
MrZ626
168f44b8b3 修正一处框架方法名修改没改完 2021-12-18 00:37:32 +08:00
MrZ626
b73f646a4c 作者要求mono语音包暂时消失一段时间 2021-12-18 00:25:05 +08:00
MrZ626
36cefcc000 太空背景支持任意帧率 2021-12-17 21:57:33 +08:00
MrZ626
f901c25c87 修正一些地方move音效没改touch 2021-12-17 21:12:50 +08:00
MrZ626
6d8478b029 string扩展模块新增一个按字符数读+截取的方法 2021-12-17 13:54:27 +08:00
MrZ626
9bcb040019 bgm模块新增isPlaying方法 2021-12-16 17:47:57 +08:00
MrZ626
d977087fc0 调整上一个pr的小问题 2021-12-16 14:35:57 +08:00
C₂₉H₂₅N₃O₅
1a330771d7 大改词典 (#553)
* 大修中文词典

`dict_zh`:
* 术语和专有名词大小写修正
* 日期格式标准化
* 增加评论注释
* 增加更多关键词索引
* 删除重复内容
* 英文使用半角标点
* 修改一些写错的名词
* 修改一个链接

* Updated `dict_en`

`dict_en`
* Added more search indexes
* Added many contents from `dict_zh`, especially the games
* Changed some URL links (from the teatube version to the original websites, if possible)
* Corrected the names of the wrongly-spelled proper nouns
* Rearranged the order of some entries
2021-12-16 13:48:02 +08:00
MrZ626
9c8c9f2106 涉及框架的设置项统一应用,不再细分时机
修改errData的获得方式
WIDGET新增setOnChange方法,不再依赖THEME
2021-12-16 12:39:42 +08:00
MrZ626
0498beecdf 特化新的模式选择场景名 2021-12-16 03:04:35 +08:00
MrZ626
8e075adf8f 新增一个简易秒表小程序 2021-12-16 02:58:36 +08:00
MrZ626
60f2a0e647 更新ios无法自动退出的界面细节 2021-12-16 02:37:25 +08:00
MrZ626
b642f2b5c4 Merge branch 'main' into test-new-mode-system 2021-12-16 02:32:51 +08:00
MrZ626
2b80f72c6b 移除框架内几处对SETTING的依赖 2021-12-16 02:31:53 +08:00
MrZ626
462720881a 支持鼠标滚动模式列表 2021-12-16 02:07:49 +08:00
MrZ626
3dda0254a8 调整中文词典的游戏介绍词条及顺序
Co-authored-by: C₂₉H₂₅N₃O₅ <cgu52@wisc.edu>
2021-12-16 00:22:32 +08:00
MrZ626
054a52a445 版本推进 2021-12-15 14:28:44 +08:00
MrZ626
85242d808b 修复语言文件小问题 2021-12-15 14:28:05 +08:00
MrZ626
57241677a9 修复混战 2021-12-15 14:26:40 +08:00
MrZ626
6ccdee2a53 bgm模块新增瞬间开/关功能
字符串扩展模块不再直接修改全局的string,需要外部自己补充
2021-12-15 11:28:25 +08:00
MrFaq2018
a3d2b7b7f3 Update lang_es.lua (#552) 2021-12-14 12:41:45 +08:00
MrZ626
b7b28b4ae3 修复经典模式h和u难度没有干旱计数器 close #546 2021-12-13 03:52:19 +08:00
MrZ626
30748200dd 修复自定义场地界面按超过第三个的鼠标键会报错 2021-12-11 19:38:24 +08:00
MrZ626
c9f8240234 添加模式搜索的帮助文本 2021-12-10 13:22:42 +08:00
MrZ626
5c7082e886 修复不能deepdrop 2021-12-10 12:50:57 +08:00
MrZ626
9a3c889a9d 修改词典和tip 2021-12-10 09:31:07 +08:00
MrZ626
f41f58e13f 模式文件夹可以显示作者 2021-12-10 01:49:05 +08:00
MrZ626
e81f25c216 修正段位更新条件
模式列表显示获得的段位
2021-12-10 01:37:14 +08:00
MrZ626
36fc681fbf 项目名太长会压缩显示 2021-12-09 20:10:46 +08:00
MrZ626
87e5e29129 彩蛋模式补充进模式树 2021-12-09 20:10:17 +08:00
MrZ626
b432fdf90a 部分语言的模式说明添加换行 2021-12-09 19:43:36 +08:00
MrZ626
6e78a3fedd 选择模式后右侧显示排行榜等信息 2021-12-09 19:41:42 +08:00
MrZ626
24760801af 增加模式图标显示,等待添加素材 2021-12-09 17:26:37 +08:00
MrZ626
f5e8e0f7a5 Merge commit 'df089a2f04fc44774e8dc722cc5d9948f94e5de5' into HEAD 2021-12-09 17:26:31 +08:00
MrZ626
df089a2f04 框架新增1*1空白画布变量PAPER 2021-12-09 17:26:02 +08:00
user670
6600713f4b Update lang_en.lua (#540) 2021-12-09 16:04:24 +08:00
NOT_A_ROBOT
96dad762b2 Update lang_en.lua (#544)
BiRS now allows you to spin the O1 piece.
2021-12-09 16:03:57 +08:00
MrZ626
5470387685 优化滚动
增加触摸控制
2021-12-09 15:55:09 +08:00
MrZ626
fa64c868b9 调整一些tip 2021-12-09 15:21:51 +08:00
MrZ626
2f4a416353 整理代码
调整模式排列顺序
2021-12-09 15:13:09 +08:00
MrZ626
3dbafb042c 进一步优化 2021-12-09 15:04:17 +08:00
MrZ626
97e7b019dd TRS的N/H块补充一个踢墙 2021-12-09 03:21:28 +08:00
MrZ626
28103ad952 新模式选择菜单原型
删除模式图标
动态加载所有模式
2021-12-09 03:20:57 +08:00
MrZ626
1826ca6f2f fix 2021-12-09 01:03:27 +08:00
MrZ626
db490a6c6c FILE.load新增-lua方式(直接运行,无环境限制) 2021-12-09 01:01:24 +08:00
MrZ626
421fdef4f9 调整两个群友词条的关键词 2021-12-09 01:00:40 +08:00
MrZ626
d717ce842d 调整tip 2021-12-08 09:19:58 +08:00
MrZ626
f13c9792af 调整把按键添加到录像的时机
修复触发了自动保存的最后一个按键本身不会保存到录像里
2021-12-08 08:40:24 +08:00
126 changed files with 1890 additions and 1519 deletions

View File

@@ -1,44 +1,37 @@
local lastLoaded={} local lastLoaded={}
local maxLoadedCount=3 local maxLoadedCount=3
local nameList={}
local SourceObjList={} local SourceObjList={}
local volume=1 local volume=1
local BGM={ local BGM={
default=false, default=false,
getList=function()error("Cannot getList before initialize!")end,
getCount=function()return 0 end,
play=NULL,
stop=NULL,
onChange=NULL, onChange=NULL,
--nowPlay=[str:playing ID] --nowPlay=[str:playing ID]
--playing=[src:playing SRC] --playing=[src:playing SRC]
--lastPlayed=[str:lastPlayed ID] --lastPlayed=[str:lastPlayed ID]
} }
local function task_fadeOut(src)
while true do function BGM.getList()return nameList end
coroutine.yield() function BGM.getCount()return #nameList end
local v=src:getVolume()-.025*volume local function _addFile(name,path)
src:setVolume(v>0 and v or 0) if not SourceObjList[name]then
if v<=0 then table.insert(nameList,name)
src:pause() SourceObjList[name]={path=path,source=false}
return true
end
end end
end end
local function task_fadeIn(src) function BGM.load(name,path)
while true do if type(name)=='table'then
coroutine.yield() for k,v in next,name do
local v=volume _addFile(k,v)
v=math.min(v,src:getVolume()+.025*v)
src:setVolume(v)
if v>=volume then
return true
end end
else
_addFile(name,path)
end end
table.sort(nameList)
LOG(BGM.getCount().." BGM files added")
end end
local function check_curFadeOut(task,code,src)
return task.code==code and task.args[1]==src
end
local function _tryReleaseSources() local function _tryReleaseSources()
local n=#lastLoaded local n=#lastLoaded
while #lastLoaded>maxLoadedCount do while #lastLoaded>maxLoadedCount do
@@ -75,85 +68,115 @@ function BGM.setVol(v)
end end
end end
end end
function BGM.init(list)
BGM.init=nil
local simpList={} local function task_fadeOut(src)
for _,v in next,list do while true do
table.insert(simpList,v.name) coroutine.yield()
SourceObjList[v.name]={path=v.path,source=false} local v=src:getVolume()-.025*volume
end src:setVolume(v>0 and v or 0)
table.sort(simpList) if v<=0 then
function BGM.getList()return simpList end src:pause()
local count=#simpList return true
LOG(count.." BGM files added")
function BGM.getCount()return count end
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: "..SourceObjList[name],5)
end
elseif name then
LOG("No BGM: "..name,5)
end end
end end
function BGM.play(name) end
name=name or BGM.default local function task_fadeIn(src)
if not _tryLoad(name)then return end while true do
if volume==0 then coroutine.yield()
local v=volume
v=math.min(v,src:getVolume()+.025*v)
src:setVolume(v)
if v>=volume then
return true
end
end
end
local function check_curFadeOut(task,code,src)
return task.code==code and task.args[1]==src
end
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:setVolume(0)
table.insert(lastLoaded,1,name)
_tryReleaseSources()
return true
else
LOG("No BGM: "..SourceObjList[name],5)
end
elseif name then
LOG("No BGM: "..name,5)
end
end
function BGM.play(name,args)
name=name or BGM.default
args=args or""
if not _tryLoad(name)or args:sArg('-preLoad')then return end
if volume==0 then
BGM.nowPlay=name
BGM.playing=SourceObjList[name].source
return true
end
if name and SourceObjList[name].source then
if BGM.nowPlay~=name then
if BGM.nowPlay then
if not args:sArg('-sdout')then
TASK.new(task_fadeOut,BGM.playing)
else
BGM.playing:pause()
end
end
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,SourceObjList[name].source)
TASK.removeTask_code(task_fadeIn)
BGM.nowPlay=name BGM.nowPlay=name
BGM.playing=SourceObjList[name].source BGM.playing=SourceObjList[name].source
return true if not args:sArg('-sdin')then
end BGM.playing:setVolume(0)
if name and SourceObjList[name].source then TASK.new(task_fadeIn,BGM.playing)
if BGM.nowPlay~=name then else
if BGM.nowPlay then BGM.playing:setVolume(volume)
TASK.new(task_fadeOut,BGM.playing)
end
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,SourceObjList[name].source)
TASK.removeTask_code(task_fadeIn)
TASK.new(task_fadeIn,SourceObjList[name].source)
BGM.nowPlay=name
BGM.playing=SourceObjList[name].source
BGM.lastPlayed=BGM.nowPlay
BGM.playing:seek(0)
BGM.playing:play() BGM.playing:play()
BGM.onChange(name)
end end
return true SourceObjList[name].source:setLooping(not args:sArg('-noloop'))
end BGM.lastPlayed=BGM.nowPlay
end BGM.playing:seek(0)
function BGM.seek(t)
if BGM.playing then
BGM.playing:seek(t)
end
end
function BGM.continue()
if BGM.lastPlayed then
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() BGM.playing:play()
BGM.onChange(name)
end end
return true
end end
function BGM.stop() end
function BGM.seek(t)
if BGM.playing then
BGM.playing:seek(t)
end
end
function BGM.isPlaying()
return BGM.playing and BGM.playing:isPlaying()
end
function BGM.continue()
if BGM.lastPlayed then
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.removeTask_code(task_fadeIn)
TASK.new(task_fadeIn,BGM.playing)
BGM.playing:play()
end
end
function BGM.stop(args)
args=args or""
TASK.removeTask_code(task_fadeIn)
if not args:sArg('-s')then
if BGM.nowPlay then if BGM.nowPlay then
TASK.new(task_fadeOut,BGM.playing) TASK.new(task_fadeOut,BGM.playing)
end end
BGM.nowPlay,BGM.playing=nil elseif BGM.playing then
BGM.playing:pause()
end end
BGM.nowPlay,BGM.playing=nil
end end
return BGM return BGM

View File

@@ -7,20 +7,29 @@ function FILE.load(name,args)
assert(F:open'r','open error') assert(F:open'r','open error')
local s=F:read()F:close() local s=F:read()F:close()
local mode= local mode=
args:sArg'-luaon'and'luaon'or STRING.sArg(args,'-luaon')and'luaon'or
args:sArg'-json'and'json'or STRING.sArg(args,'-lua')and'lua'or
args:sArg'-string'and'string'or STRING.sArg(args,'-json')and'json'or
STRING.sArg(args,'-string')and'string'or
s:sub(1,6)=='return{'and'luaon'or s:sub(1,6)=='return{'and'luaon'or
(s:sub(1,1)=='['and s:sub(-1)==']'or s:sub(1,1)=='{'and s:sub(-1)=='}')and'json'or (s:sub(1,1)=='['and s:sub(-1)==']'or s:sub(1,1)=='{'and s:sub(-1)=='}')and'json'or
'string' 'string'
if mode=='luaon'then if mode=='luaon'then
local func=loadstring(s) local func,err_mes=loadstring(s)
if func then if func then
setfenv(func,{}) setfenv(func,{})
local res=func() local res=func()
return assert(res,'decode error') return assert(res,'decode error')
else else
error('decode error') error('decode error: '..err_mes)
end
elseif mode=='lua'then
local func,err_mes=loadstring(s)
if func then
local res=func()
return assert(res,'run error')
else
error('compile error: '..err_mes)
end end
elseif mode=='json'then elseif mode=='json'then
local res=JSON.decode(s) local res=JSON.decode(s)
@@ -39,12 +48,12 @@ function FILE.load(name,args)
end end
function FILE.save(data,name,args) function FILE.save(data,name,args)
if not args then args=''end if not args then args=''end
if args:sArg'-d'and fs.getInfo(name)then if STRING.sArg(args,'-d')and fs.getInfo(name)then
error('duplicate') error('duplicate')
end end
if type(data)=='table'then if type(data)=='table'then
if args:sArg'-luaon'then if STRING.sArg(args,'-luaon')then
data=TABLE.dump(data) data=TABLE.dump(data)
if not data then if not data then
error('encode error') error('encode error')

View File

@@ -18,7 +18,7 @@ function FONT.rawset(s)
end end
function FONT.load(fonts) function FONT.load(fonts)
for name,path in next,fonts do for name,path in next,fonts do
assert(love.filesystem.getInfo(path),("Font file $1($2) not exist!"):repD(name,path)) assert(love.filesystem.getInfo(path),STRING.repD("Font file $1($2) not exist!",name,path))
fontFiles[name]=love.filesystem.newFile(path) fontFiles[name]=love.filesystem.newFile(path)
fontCache[name]={} fontCache[name]={}
end end

View File

@@ -2,7 +2,6 @@ local IMG={}
function IMG.init(list) function IMG.init(list)
IMG.init=nil IMG.init=nil
local null=love.graphics.newCanvas(1,1)
setmetatable(IMG,{__index=function(self,name) setmetatable(IMG,{__index=function(self,name)
if type(list[name])=='table'then if type(list[name])=='table'then
self[name]={} self[name]={}
@@ -13,7 +12,7 @@ function IMG.init(list)
self[name]=love.graphics.newImage(list[name]) self[name]=love.graphics.newImage(list[name])
else else
LOG("No IMG: "..name) LOG("No IMG: "..name)
self[name]=null self[name]=PAPER
end end
return self[name] return self[name]
end}) end})

View File

@@ -1,4 +1,4 @@
NONE={}function NULL()end NONE={}function NULL()end PAPER=love.graphics.newCanvas(1,1)
EDITING="" EDITING=""
LOADED=false LOADED=false
@@ -70,15 +70,26 @@ local gc_draw,gc_line,gc_circle,gc_print=gc.draw,gc.line,gc.circle,gc.print
local WIDGET,SCR,SCN=WIDGET,SCR,SCN local WIDGET,SCR,SCN=WIDGET,SCR,SCN
local xOy=SCR.xOy local xOy=SCR.xOy
local ITP=xOy.inverseTransformPoint local ITP=xOy.inverseTransformPoint
local max,min=math.max,math.min local max,min=math.max,math.min
local devMode
local mx,my,mouseShow,cursorSpd=640,360,false,0 local mx,my,mouseShow,cursorSpd=640,360,false,0
local jsState={}--map, joystickID->axisStates: {axisName->axisVal} local jsState={}--map, joystickID->axisStates: {axisName->axisVal}
local errData={}--list, each error create {mes={errMes strings},scene=sceneNameStr} local errData={}--list, each error create {mes={errMes strings},scene=sceneNameStr}
local devMode local function drawCursor(_,x,y)
gc_setColor(1,1,1)
gc_setLineWidth(2)
gc_circle(ms.isDown(1)and'fill'or'line',x,y,6)
end
local showPowerInfo=true
local showClickFX=true
local discardCanvas=false
local frameMul=100
local sleepInterval=1/60
local onQuit=NULL
local batteryImg=GC.DO{31,20, local batteryImg=GC.DO{31,20,
{'fRect',1,0,26,2}, {'fRect',1,0,26,2},
@@ -96,17 +107,16 @@ local function updatePowerInfo()
gc_clear(0,0,0,.25) gc_clear(0,0,0,.25)
if state~='unknown'then if state~='unknown'then
gc_setLineWidth(4) gc_setLineWidth(4)
local charging=state=='charging'
if state=='nobattery'then if state=='nobattery'then
gc_setColor(1,1,1) gc_setColor(1,1,1)
gc_setLineWidth(2) gc_setLineWidth(2)
gc_line(74,SCR.safeX+5,100,22) gc_line(74,5,100,22)
elseif pow then elseif pow then
if charging then gc_setColor(0,1,0) if state=='charging'then gc_setColor(0,1,0)
elseif pow>50 then gc_setColor(1,1,1) elseif pow>50 then gc_setColor(1,1,1)
elseif pow>26 then gc_setColor(1,1,0) elseif pow>26 then gc_setColor(1,1,0)
elseif pow==26 then gc_setColor(.5,0,1) elseif pow==26 then gc_setColor(.5,0,1)
else gc_setColor(1,0,0) else gc_setColor(1,0,0)
end end
gc.rectangle('fill',76,6,pow*.22,14) gc.rectangle('fill',76,6,pow*.22,14)
if pow<100 then if pow<100 then
@@ -152,7 +162,7 @@ local function _triggerMouseDown(x,y,k)
if SCN.mouseDown then SCN.mouseDown(x,y,k)end if SCN.mouseDown then SCN.mouseDown(x,y,k)end
WIDGET.press(x,y,k) WIDGET.press(x,y,k)
lastX,lastY=x,y lastX,lastY=x,y
if SETTING.clickFX then SYSFX.newTap(3,x,y)end if showClickFX then SYSFX.newTap(3,x,y)end
end end
local function mouse_update(dt) local function mouse_update(dt)
if not KBisDown('lctrl','rctrl')and KBisDown('up','down','left','right')then if not KBisDown('lctrl','rctrl')and KBisDown('up','down','left','right')then
@@ -238,13 +248,13 @@ function love.touchpressed(id,x,y)
x,y=ITP(xOy,x,y) x,y=ITP(xOy,x,y)
lastX,lastY=x,y lastX,lastY=x,y
WIDGET.cursorMove(x,y) WIDGET.cursorMove(x,y)
if SCN.touchDown then SCN.touchDown(x,y)end if SCN.touchDown then SCN.touchDown(x,y,id)end
if kb.hasTextInput()then kb.setTextInput(false)end if kb.hasTextInput()then kb.setTextInput(false)end
end end
function love.touchmoved(_,x,y,dx,dy) function love.touchmoved(id,x,y,dx,dy)
if SCN.swapping then return end if SCN.swapping then return end
x,y=ITP(xOy,x,y) x,y=ITP(xOy,x,y)
if SCN.touchMove then SCN.touchMove(x,y,dx/SCR.k,dy/SCR.k)end if SCN.touchMove then SCN.touchMove(x,y,dx/SCR.k,dy/SCR.k,id)end
WIDGET.drag(x,y,dx/SCR.k,dy/SCR.k) WIDGET.drag(x,y,dx/SCR.k,dy/SCR.k)
end end
function love.touchreleased(id,x,y) function love.touchreleased(id,x,y)
@@ -257,10 +267,10 @@ function love.touchreleased(id,x,y)
WIDGET.unFocus() WIDGET.unFocus()
SCN.mainTouchID=false SCN.mainTouchID=false
end end
if SCN.touchUp then SCN.touchUp(x,y)end if SCN.touchUp then SCN.touchUp(x,y,id)end
if(x-lastX)^2+(y-lastY)^2<62 then if(x-lastX)^2+(y-lastY)^2<62 then
if SCN.touchClick then SCN.touchClick(x,y)end if SCN.touchClick then SCN.touchClick(x,y)end
if SETTING.clickFX then SYSFX.newTap(3,x,y)end if showClickFX then SYSFX.newTap(3,x,y)end
end end
end end
@@ -309,7 +319,7 @@ function love.keypressed(key,_,isRep)
MES.new('info',"DEBUG ON",.2) MES.new('info',"DEBUG ON",.2)
elseif key=='f11'then elseif key=='f11'then
SETTING.fullscreen=not SETTING.fullscreen SETTING.fullscreen=not SETTING.fullscreen
applyFullscreen() applySettings()
saveSettings() saveSettings()
elseif not SCN.swapping then elseif not SCN.swapping then
if EDITING==""and(not SCN.keyDown or SCN.keyDown(key,isRep))then if EDITING==""and(not SCN.keyDown or SCN.keyDown(key,isRep))then
@@ -324,7 +334,7 @@ function love.keypressed(key,_,isRep)
elseif key=='space'or key=='return'then elseif key=='space'or key=='return'then
mouseShow=true mouseShow=true
if not isRep then if not isRep then
if SETTING.clickFX then SYSFX.newTap(3,mx,my)end if showClickFX then SYSFX.newTap(3,mx,my)end
_triggerMouseDown(mx,my,1) _triggerMouseDown(mx,my,1)
end end
else else
@@ -452,7 +462,7 @@ function love.gamepadpressed(_,key)
if W and W.arrowKey then W:arrowKey(key)end if W and W.arrowKey then W:arrowKey(key)end
elseif key=='return'then elseif key=='return'then
mouseShow=true mouseShow=true
if SETTING.clickFX then SYSFX.newTap(3,mx,my)end if showClickFX then SYSFX.newTap(3,mx,my)end
_triggerMouseDown(mx,my,1) _triggerMouseDown(mx,my,1)
else else
if W and W.keypress then if W and W.keypress then
@@ -481,14 +491,16 @@ function love.lowmemory()
MES.new('check',"[auto GC] low MEM 设备内存过低") MES.new('check',"[auto GC] low MEM 设备内存过低")
end end
end end
local onResize=NULL
function love.resize(w,h) function love.resize(w,h)
if SCR.w==w and SCR.h==h then return end
SCR.resize(w,h) SCR.resize(w,h)
if BG.resize then BG.resize(w,h)end if BG.resize then BG.resize(w,h)end
if SCN.resize then SCN.resize(w,h)end if SCN.resize then SCN.resize(w,h)end
WIDGET.resize(w,h) WIDGET.resize(w,h)
FONT.reset() FONT.reset()
onResize(w,h)
SHADER.warning:send('w',w*SCR.dpi)
end end
local onFocus=NULL local onFocus=NULL
@@ -627,14 +639,6 @@ local wsImg={}do
} }
end end
local function drawCursor(_,x,y)
gc_setColor(1,1,1)
gc_setLineWidth(2)
gc_circle(ms.isDown(1)and'fill'or'line',x,y,6)
end
local function showPowerInfo()return true end
local onQuit=NULL
function love.run() function love.run()
local love=love local love=love
@@ -649,7 +653,7 @@ function love.run()
local FPS,MINI=love.timer.getFPS,love.window.isMinimized local FPS,MINI=love.timer.getFPS,love.window.isMinimized
local PUMP,POLL=love.event.pump,love.event.poll local PUMP,POLL=love.event.pump,love.event.poll
local timer,SETTING,VERSION=love.timer.getTime,SETTING,VERSION local timer,VERSION=love.timer.getTime,VERSION
local frameTimeList={} local frameTimeList={}
local lastFrame=timer() local lastFrame=timer()
@@ -698,11 +702,10 @@ function love.run()
--DRAW --DRAW
if not MINI()then if not MINI()then
FCT=FCT+SETTING.frameMul FCT=FCT+frameMul
if FCT>=100 then if FCT>=100 then
FCT=FCT-100 FCT=FCT-100
local safeX=SCR.safeX
gc_replaceTransform(SCR.origin) gc_replaceTransform(SCR.origin)
gc_setColor(1,1,1) gc_setColor(1,1,1)
BG.draw() BG.draw()
@@ -713,16 +716,14 @@ function love.run()
TEXT_draw() TEXT_draw()
--Draw cursor --Draw cursor
if mouseShow then if mouseShow then drawCursor(time,mx,my)end
drawCursor(time,mx,my)
end
gc_replaceTransform(SCR.xOy_ul)
MES_draw()
gc_replaceTransform(SCR.origin) gc_replaceTransform(SCR.origin)
MES_draw()
--Draw power info. --Draw power info.
if showPowerInfo()then if showPowerInfo then
gc_setColor(1,1,1) gc_setColor(1,1,1)
gc_draw(infoCanvas,safeX,0,0,SCR.k) gc_draw(infoCanvas,SCR.safeX,0,0,SCR.k)
end end
--Draw scene swapping animation --Draw scene swapping animation
@@ -737,6 +738,8 @@ function love.run()
FONT.set(20) FONT.set(20)
mStr(VERSION.string,0,-30) mStr(VERSION.string,0,-30)
gc_replaceTransform(SCR.xOy_dl) gc_replaceTransform(SCR.xOy_dl)
local safeX=SCR.safeX/SCR.k
--Draw FPS --Draw FPS
FONT.set(15) FONT.set(15)
gc_setColor(1,1,1) gc_setColor(1,1,1)
@@ -794,13 +797,13 @@ function love.run()
gc_present() gc_present()
--SPEED UPUPUP! --SPEED UPUPUP!
if SETTING.cleanCanvas then gc_discard()end if discardCanvas then gc_discard()end
end end
end end
--Fresh power info. --Fresh power info.
if time-lastFreshPow>2.6 then if time-lastFreshPow>2.6 then
if showPowerInfo()then if showPowerInfo then
updatePowerInfo() updatePowerInfo()
lastFreshPow=time lastFreshPow=time
end end
@@ -818,31 +821,44 @@ function love.run()
end end
end end
--Keep 60fps
_=timer()-lastFrame _=timer()-lastFrame
if _<.0162 then WAIT(.0162-_)end if _<sleepInterval*.9626 then WAIT(sleepInterval*.9626-_)end
while timer()-lastFrame<1/60 do end while timer()-lastFrame<sleepInterval do end
end end
end end
local Z={} local Z={}
Z.js=jsState function Z.getJsState()return jsState end
Z.errData=errData function Z.getErr(i)
if i=='#'then
return errData[#errData]
elseif i then
return errData[i]
else
return errData
end
end
function Z.setIfPowerInfo(func)showPowerInfo=func end function Z.setPowerInfo(bool)showPowerInfo=bool end
function Z.setCleanCanvas(bool)discardCanvas=bool end
function Z.setFrameMul(n)frameMul=n end
function Z.setMaxFPS(fps)sleepInterval=1/fps end
function Z.setClickFX(bool)showClickFX=bool end
--[Warning] Color and line width is uncertain value, set it in the function. --[Warning] Color and line width is uncertain value, set it in the function.
function Z.setCursor(func)drawCursor=func end function Z.setCursor(func)drawCursor=func end
--Change F1~F7 events of devmode (F8 mode) --Change F1~F7 events of devmode (F8 mode)
function Z.setOnFnKeys(list) function Z.setOnFnKeys(list)
assert(type(list)=='table') assert(type(list)=='table',"Z.setOnFnKeys(list): list must be a table.")
for i=1,7 do fnKey[i]=type(list[i])=='function'and list[i]or NULL end for i=1,7 do fnKey[i]=type(list[i])=='function'and list[i]or NULL end
end end
function Z.setOnFocus(func)onFocus=type(func)=='function'and func or NULL end function Z.setOnFocus(func)onFocus=assert(type(func)=='function'and func,"Z.setOnFocus(func): func must be a function")end
function Z.setOnQuit(func)onQuit=type(func)=='function'and func or NULL end function Z.setOnResize(func)onResize=assert(type(func)=='function'and func,"Z.setOnResize(func): func must be a function")end
function Z.setOnQuit(func)onQuit=assert(type(func)=='function'and func,"Z.setOnQuit(func): func must be a function")end
return Z return Z

View File

@@ -20,4 +20,18 @@ function MATH.coin(a,b)
end end
end end
function MATH.interval(v,low,high)
if v<=low then
return low
elseif v>=high then
return high
else
return v
end
end
function MATH.expApproach(a,b,k)
return b+(a-b)*2.718281828459045^-k
end
return MATH return MATH

View File

@@ -140,11 +140,11 @@ function profile.switch()
switch=not switch switch=not switch
if not switch then if not switch then
profile.stop() profile.stop()
love.system.setClipboardText(PROFILE.report()) love.system.setClipboardText(profile.report())
PROFILE.reset() profile.reset()
return false return false
else else
PROFILE.start() profile.start()
return true return true
end end
end end

View File

@@ -1,5 +1,6 @@
local type,rem=type,table.remove local type,rem=type,table.remove
local int,rnd=math.floor,math.random local int,rnd=math.floor,math.random
local interval=MATH.interval
local sfxList={} local sfxList={}
local packSetting={} local packSetting={}
@@ -140,7 +141,7 @@ local function _play(name,vol,pos,pitch)
S=S[n]--AU_SRC S=S[n]--AU_SRC
if S:getChannelCount()==1 then if S:getChannelCount()==1 then
if pos then if pos then
pos=pos*stereo pos=interval(pos,-1,1)*stereo
S:setPosition(pos,1-pos^2,0) S:setPosition(pos,1-pos^2,0)
else else
S:setPosition(0,0,0) S:setPosition(0,0,0)

View File

@@ -6,7 +6,7 @@ local find,sub,gsub,upper=string.find,string.sub,string.gsub,string.upper
local char,byte=string.char,string.byte local char,byte=string.char,string.byte
--"Replace dollars", replace all $n with ... --"Replace dollars", replace all $n with ...
function string.repD(str,...) function STRING.repD(str,...)
local l={...} local l={...}
for i=#l,1,-1 do for i=#l,1,-1 do
str=gsub(str,'$'..i,l[i]) str=gsub(str,'$'..i,l[i])
@@ -15,7 +15,7 @@ function string.repD(str,...)
end end
--"Scan arg", scan if str has the arg (format of str is like "-json -q", arg is like "-q") --"Scan arg", scan if str has the arg (format of str is like "-json -q", arg is like "-q")
function string.sArg(str,switch) function STRING.sArg(str,switch)
if find(str.." ",switch.." ")then if find(str.." ",switch.." ")then
return true return true
end end
@@ -197,6 +197,9 @@ function STRING.readLine(str)
return str,"" return str,""
end end
end end
function STRING.readChars(str,n)
return sub(str,1,n),sub(str,n+1)
end
function STRING.packBin(s) function STRING.packBin(s)
return data.encode('string','base64',data.compress('string','zlib',s)) return data.encode('string','base64',data.compress('string','zlib',s))

View File

@@ -19,6 +19,7 @@ local sub,ins,rem=string.sub,table.insert,table.remove
local xOy=SCR.xOy local xOy=SCR.xOy
local FONT=FONT local FONT=FONT
local mStr=GC.mStr local mStr=GC.mStr
local approach=MATH.expApproach
local downArrowIcon=GC.DO{40,25,{'fPoly',0,0,20,25,40,0}} local downArrowIcon=GC.DO{40,25,{'fPoly',0,0,20,25,40,0}}
local upArrowIcon=GC.DO{40,25,{'fPoly',0,25,20,0,40,25}} local upArrowIcon=GC.DO{40,25,{'fPoly',0,25,20,0,40,25}}
@@ -45,7 +46,12 @@ local function _rectangleStencil()
gc.rectangle('fill',1,1,STW-2,STH-2) gc.rectangle('fill',1,1,STW-2,STH-2)
end end
local onChange=NULL
local WIDGET={} local WIDGET={}
function WIDGET.setOnChange(func)onChange=assert(type(func)=='function'and func,"WIDGET.setOnChange(func): func must be a function")end
local widgetMetatable={ local widgetMetatable={
__tostring=function(self) __tostring=function(self)
return self:getInfo() return self:getInfo()
@@ -523,7 +529,7 @@ function slider:isAbove(x,y)
return x>self.x-10 and x<self.x+self.w+10 and y>self.y-25 and y<self.y+25 return x>self.x-10 and x<self.x+self.w+10 and y>self.y-25 and y<self.y+25
end end
function slider:getCenter() function slider:getCenter()
return self.x+self.w*(self.pos/self.unit),self.y return self.x+self.w*((self.pos-self.rangeL)/(self.rangeR-self.rangeL)),self.y
end end
function slider:update(dt) function slider:update(dt)
local ATV=self.ATV local ATV=self.ATV
@@ -537,7 +543,7 @@ function slider:update(dt)
if ATV>0 then self.ATV=max(ATV-dt*30,0)end if ATV>0 then self.ATV=max(ATV-dt*30,0)end
end end
if not self.hide then if not self.hide then
self.pos=self.pos*.7+self.disp()*.3 self.pos=approach(self.pos,self.disp(),dt*26)
end end
end end
function slider:draw() function slider:draw()
@@ -550,8 +556,8 @@ function slider:draw()
--Units --Units
if not self.smooth then if not self.smooth then
gc_setLineWidth(2) gc_setLineWidth(2)
for p=0,self.unit do for p=self.rangeL,self.rangeR,self.unit do
local X=x+(x2-x)*p/self.unit local X=x+(x2-x)*(p-self.rangeL)/(self.rangeR-self.rangeL)
gc_line(X,y+7,X,y-7) gc_line(X,y+7,X,y-7)
end end
end end
@@ -561,7 +567,7 @@ function slider:draw()
gc_line(x,y,x2,y) gc_line(x,y,x2,y)
--Block --Block
local cx=x+(x2-x)*self.pos/self.unit local cx=x+(x2-x)*(self.pos-self.rangeL)/(self.rangeR-self.rangeL)
local bx,by,bw,bh=cx-10-ATV*.5,y-16-ATV,20+ATV,32+2*ATV local bx,by,bw,bh=cx-10-ATV*.5,y-16-ATV,20+ATV,32+2*ATV
gc_setColor(.8,.8,.8) gc_setColor(.8,.8,.8)
gc_rectangle('fill',bx,by,bw,bh,3) gc_rectangle('fill',bx,by,bw,bh,3)
@@ -596,13 +602,16 @@ end
function slider:drag(x) function slider:drag(x)
if not x then return end if not x then return end
x=x-self.x x=x-self.x
local p=self.disp() local newPos=MATH.interval(x/self.w,0,1)
local P=x<0 and 0 or x>self.w and self.unit or x/self.w*self.unit local newVal
if not self.smooth then if not self.unit then
P=int(P+.5) newVal=(1-newPos)*self.rangeL+newPos*self.rangeR
else
newVal=newPos*(self.rangeR-self.rangeL)
newVal=self.rangeL+newVal-newVal%self.unit
end end
if p~=P then if newVal~=self.disp()then
self.code(P) self.code(newVal)
end end
if self.change and timer()-self.lastTime>.5 then if self.change and timer()-self.lastTime>.5 then
self.lastTime=timer() self.lastTime=timer()
@@ -615,8 +624,8 @@ function slider:release(x)
end end
function slider:scroll(n) function slider:scroll(n)
local p=self.disp() local p=self.disp()
local u=self.smooth and .01 or 1 local u=self.unit or .01
local P=n==-1 and max(p-u,0)or min(p+u,self.unit) local P=MATH.interval(p+u*n,self.rangeL,self.rangeR)
if p==P or not P then return end if p==P or not P then return end
self.code(P) self.code(P)
if self.change and timer()-self.lastTime>.18 then if self.change and timer()-self.lastTime>.18 then
@@ -627,7 +636,13 @@ end
function slider:arrowKey(k) function slider:arrowKey(k)
self:scroll((k=='left'or k=='up')and -1 or 1) self:scroll((k=='left'or k=='up')and -1 or 1)
end end
function WIDGET.newSlider(D)--name,x,y,w[,lim][,fText][,color][,unit][,smooth][,font=30][,fType][,change],disp[,show][,code],hide function WIDGET.newSlider(D)--name,x,y,w[,lim][,fText][,color][,axis][,smooth][,font=30][,fType][,change],disp[,show][,code],hide
if not D.axis then
D.axis={0,1,false}
D.smooth=true
elseif not D.axis[3]then
D.smooth=true
end
local _={ local _={
name= D.name or"_", name= D.name or"_",
@@ -646,8 +661,10 @@ function WIDGET.newSlider(D)--name,x,y,w[,lim][,fText][,color][,unit][,smooth][,
fText= D.fText, fText= D.fText,
color= D.color and(COLOR[D.color]or D.color)or COLOR.Z, color= D.color and(COLOR[D.color]or D.color)or COLOR.Z,
unit= D.unit or 1, rangeL=D.axis[1],
smooth=false, rangeR=D.axis[2],
unit= D.axis[3],
smooth=D.smooth,
font= D.font or 30, font= D.font or 30,
fType= D.fType, fType= D.fType,
change=D.change, change=D.change,
@@ -657,22 +674,17 @@ function WIDGET.newSlider(D)--name,x,y,w[,lim][,fText][,color][,unit][,smooth][,
hide= D.hide, hide= D.hide,
show= false, show= false,
} }
if D.smooth~=nil then
_.smooth=D.smooth
else
_.smooth=_.unit<=1
end
if D.show then if D.show then
if type(D.show)=='function'then if type(D.show)=='function'then
_.show=D.show _.show=D.show
else else
_.show=sliderShowFunc[D.show] _.show=sliderShowFunc[D.show]
end end
elseif D.show~=false then elseif D.show~=false then--Use default if nil
if _.unit<=1 then if _.unit and _.unit%1==0 then
_.show=sliderShowFunc.percent
else
_.show=sliderShowFunc.int _.show=sliderShowFunc.int
else
_.show=sliderShowFunc.percent
end end
end end
for k,v in next,slider do _[k]=v end for k,v in next,slider do _[k]=v end
@@ -1221,6 +1233,14 @@ function listBox:arrowKey(dir)
end end
end end
end end
function listBox:select(i)
self.selected=i
if self.selected<int(self.scrollPos/self.lineH)+2 then
self:drag(nil,nil,nil,1e99)
elseif self.selected>int(self.scrollPos/self.lineH)+self.capacity-1 then
self:drag(nil,nil,nil,-1e99)
end
end
function listBox:draw() function listBox:draw()
local x,y,w,h=self.x,self.y,self.w,self.h local x,y,w,h=self.x,self.y,self.w,self.h
local list=self.list local list=self.list
@@ -1263,7 +1283,7 @@ end
function listBox:getInfo() function listBox:getInfo()
return("x=%d,y=%d,w=%d,h=%d"):format(self.x+self.w*.5,self.y+self.h*.5,self.w,self.h) return("x=%d,y=%d,w=%d,h=%d"):format(self.x+self.w*.5,self.y+self.h*.5,self.w,self.h)
end end
function WIDGET.newListBox(D)--name,x,y,w,h,lineH[,hideF][,hide][,drawF] function WIDGET.newListBox(D)--name,x,y,w,h,lineH,drawF[,hideF][,hide]
local _={ local _={
name= D.name or"_", name= D.name or"_",
@@ -1320,16 +1340,7 @@ function WIDGET.setWidgetList(list)
for i=1,#list do for i=1,#list do
list[i]:reset() list[i]:reset()
end end
if SCN.cur~='custom_field'then onChange()
local colorList=THEME.getThemeColor()
if not colorList then return end
local rnd=math.random
for _,W in next,list do
if W.color and not W.fText then
W.color=colorList[rnd(#colorList)]
end
end
end
end end
end end
function WIDGET.setScrollHeight(height) function WIDGET.setScrollHeight(height)

View File

@@ -24,13 +24,13 @@ VERSION=require"version"
TIME=love.timer.getTime TIME=love.timer.getTime
YIELD=coroutine.yield YIELD=coroutine.yield
SYSTEM=love.system.getOS()if SYSTEM=='OS X'then SYSTEM='macOS'end SYSTEM=love.system.getOS()if SYSTEM=='OS X'then SYSTEM='macOS'end
FNNS=true or SYSTEM:find'\79\83'--What does FNSF stand for? IDK so don't ask me lol FNNS=SYSTEM:find'\79\83'--What does FNSF stand for? IDK so don't ask me lol
MOBILE=SYSTEM=='Android'or SYSTEM=='iOS' MOBILE=SYSTEM=='Android'or SYSTEM=='iOS'
SAVEDIR=fs.getSaveDirectory() SAVEDIR=fs.getSaveDirectory()
--Global Vars & Settings --Global Vars & Settings
SFXPACKS={'chiptune'} SFXPACKS={'chiptune'}
VOCPACKS={'miya','mono','xiaoya','miku'} VOCPACKS={'miya',--[['mono',]]'xiaoya','miku'}
FIRSTLAUNCH=false FIRSTLAUNCH=false
DAILYLAUNCH=false DAILYLAUNCH=false
@@ -62,6 +62,19 @@ BGM.setMaxSources(5)
BGM.setChange(function(name)MES.new('music',text.nowPlaying..name,5)end) BGM.setChange(function(name)MES.new('music',text.nowPlaying..name,5)end)
VOC.setDiversion(.62) VOC.setDiversion(.62)
WIDGET.setOnChange(function()
if SCN.cur~='custom_field'then
local colorList=THEME.getThemeColor()
if not colorList then return end
local rnd=math.random
for _,W in next,SCN.scenes[SCN.cur].widgetList do
if W.color then
W.color=colorList[rnd(#colorList)]
end
end
end
end)
table.insert(_LOADTIMELIST_,("Load Zframework: %.3fs"):format(TIME()-_LOADTIME_)) table.insert(_LOADTIMELIST_,("Load Zframework: %.3fs"):format(TIME()-_LOADTIME_))
--Create shortcuts --Create shortcuts
@@ -71,6 +84,9 @@ mStr=GC.mStr
mText=GC.simpX mText=GC.simpX
mDraw=GC.draw mDraw=GC.draw
Snd=SFX.playSample Snd=SFX.playSample
string.repD=STRING.repD
string.sArg=STRING.sArg
string.split=STRING.split
--Delete all naked files (from too old version) --Delete all naked files (from too old version)
FILE.clear('') FILE.clear('')
@@ -112,20 +128,17 @@ BOT= require'parts.bot'
RSlist= require'parts.RSlist'DSCP=RSlist.TRS.centerPos RSlist= require'parts.RSlist'DSCP=RSlist.TRS.centerPos
PLY= require'parts.player' PLY= require'parts.player'
NETPLY= require'parts.netPlayer' NETPLY= require'parts.netPlayer'
MODES= require'parts.modes' MODETREE= require'parts.modeTree'
setmetatable(TEXTURE,{__index=function(self,k) setmetatable(TEXTURE,{__index=function(self,k)
MES.new('warn',"No texture called: "..k) MES.new('warn',"No texture called: "..k)
self[k]=love.graphics.newCanvas(1,1) self[k]=PAPER
return self[k] return self[k]
end}) end})
table.insert(_LOADTIMELIST_,("Load Parts: %.3fs"):format(TIME()-_LOADTIME_)) table.insert(_LOADTIMELIST_,("Load Parts: %.3fs"):format(TIME()-_LOADTIME_))
--Init Zframework --Init Zframework
Z.setIfPowerInfo(function()
return SETTING.powerInfo and LOADED
end)
do--Z.setCursor do--Z.setCursor
local normImg=GC.DO{16,16, local normImg=GC.DO{16,16,
{'fCirc',8,8,4}, {'fCirc',8,8,4},
@@ -171,6 +184,9 @@ Z.setOnFnKeys({
function()for k,v in next,_G do print(k,v)end end, function()for k,v in next,_G do print(k,v)end end,
function()if love['_openConsole']then love['_openConsole']()end end, function()if love['_openConsole']then love['_openConsole']()end end,
}) })
Z.setOnResize(function(w,_)
SHADER.warning:send('w',w*SCR.dpi)
end)
do--Z.setOnFocus do--Z.setOnFocus
local function task_autoSoundOff() local function task_autoSoundOff()
while true do while true do
@@ -255,6 +271,7 @@ IMG.init{
speedLimit='media/image/mess/speedLimit.png',--Not used, for future C2-mode speedLimit='media/image/mess/speedLimit.png',--Not used, for future C2-mode
pay1='media/image/mess/pay1.png', pay1='media/image/mess/pay1.png',
pay2='media/image/mess/pay2.png', pay2='media/image/mess/pay2.png',
drought='media/image/mess/drought.png',
miyaCH1='media/image/characters/miya1.png', miyaCH1='media/image/characters/miya1.png',
miyaCH2='media/image/characters/miya2.png', miyaCH2='media/image/characters/miya2.png',
@@ -320,11 +337,11 @@ SFX.init((function()--[Warning] Not loading files here, just get the list of sou
end end
return L return L
end)()) end)())
BGM.init((function() BGM.load((function()
local L={} local L={}
for _,v in next,fs.getDirectoryItems('media/music')do for _,v in next,fs.getDirectoryItems('media/music')do
if isSafeFile('media/music/'..v,"Dangerous file : %SAVE%/media/music/"..v)then if isSafeFile('media/music/'..v,"Dangerous file : %SAVE%/media/music/"..v)then
table.insert(L,{name=v:sub(1,-5),path='media/music/'..v}) L[v:sub(1,-5)]='media/music/'..v
end end
end end
return L return L
@@ -393,24 +410,6 @@ for _,v in next,fs.getDirectoryItems('parts/scenes')do
LANG.addScene(sceneName) LANG.addScene(sceneName)
end end
end end
--Load mode files
for i=1,#MODES do
local m=MODES[i]--Mode template
if isSafeFile('parts/modes/'..m.name)then
TABLE.complete(require('parts.modes.'..m.name),MODES[i])
MODES[m.name],MODES[i]=MODES[i]
end
end
for _,v in next,fs.getDirectoryItems('parts/modes')do
if isSafeFile('parts/modes/'..v)and not MODES[v:sub(1,-5)]then
local M={name=v:sub(1,-5)}
local modeData=require('parts.modes.'..M.name)
if modeData.env then
TABLE.complete(modeData,M)
MODES[M.name]=M
end
end
end
table.insert(_LOADTIMELIST_,("Load Files: %.3fs"):format(TIME()-_LOADTIME_)) table.insert(_LOADTIMELIST_,("Load Files: %.3fs"):format(TIME()-_LOADTIME_))
@@ -467,6 +466,9 @@ do
SETTING.dascut=SETTING.dascut+1 SETTING.dascut=SETTING.dascut+1
needSave=true needSave=true
end end
if SETTING.vocPack=='mono'then
SETTING.vocPack='miya'
end
if RANKS.stack_e then if RANKS.stack_e then
RANKS.stack_e=nil RANKS.stack_e=nil
RANKS.stack_h=nil RANKS.stack_h=nil
@@ -524,6 +526,7 @@ do
if SETTING.cv then SETTING.vocPack,SETTING.cv=SETTING.cv end if SETTING.cv then SETTING.vocPack,SETTING.cv=SETTING.cv end
if type(SETTING.bg)~='string'then SETTING.bg='on'end if type(SETTING.bg)~='string'then SETTING.bg='on'end
if SETTING.skin[18]==10 then SETTING.skin[18]=4 end if SETTING.skin[18]==10 then SETTING.skin[18]=4 end
if SETTING.reTime>3 or SETTING.reTime<.5 then SETTING.reTime=2 end
if RANKS.infinite then RANKS.infinite=0 end if RANKS.infinite then RANKS.infinite=0 end
if RANKS.infinite_dig then RANKS.infinite_dig=0 end if RANKS.infinite_dig then RANKS.infinite_dig=0 end
if not RANKS.sprint_10l then RANKS.sprint_10l=0 end if not RANKS.sprint_10l then RANKS.sprint_10l=0 end
@@ -534,26 +537,8 @@ do
if type(name)=='number'or type(rank)~='number'then if type(name)=='number'or type(rank)~='number'then
RANKS[name]=nil RANKS[name]=nil
needSave=true needSave=true
else
local M=MODES[name]
if M and M.unlock and rank>0 then
for _,unlockName in next,M.unlock do
if not RANKS[unlockName]then
RANKS[unlockName]=0
needSave=true
end
end
end
if not(M and M.x)then
RANKS[name]=nil
needSave=true
end
end end
end end
if not MODES[STAT.lastPlay]then
STAT.lastPlay='sprint_10l'
needSave=true
end
if needSave then if needSave then
saveStats() saveStats()
@@ -572,7 +557,7 @@ if FIRSTLAUNCH and MOBILE then
end end
--Apply system setting --Apply system setting
applyAllSettings() applySettings()
--Load replays --Load replays
for _,fileName in next,fs.getDirectoryItems('replay')do for _,fileName in next,fs.getDirectoryItems('replay')do
@@ -650,9 +635,9 @@ if TABLE.find(arg,'--test')then
TASK.new(function() TASK.new(function()
while true do while true do
YIELD() YIELD()
if Z.errData[1]then break end if Z.getErr(1)then break end
end end
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") LOG("\27[91m\27[1mAutomatic Test Failed :(\27[0m\nThe error message is:\n"..table.concat(Z.getErr(1).mes,"\n").."\27[91m\nAborting\27[0m")
TEST.yieldN(60) TEST.yieldN(60)
love.event.quit(1) love.event.quit(1)
end) end)

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 552 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 534 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 603 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 483 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 489 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 403 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 347 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 395 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

BIN
media/music/lounge.ogg Normal file

Binary file not shown.

View File

@@ -376,8 +376,8 @@ do
},--R },--R
false,--Y false,--Y
{ {
[01]={'+0+0','-1+0','-1+1','+0+1','+1+0','-1+2','-2+0','+0-2'}, [01]={'+0+0','-1+0','-1+1','+0+1','+1+0','+1+1','-1+2','-2+0','+0-2'},
[10]={'+0+0','+1+0','-1+0','+0-1','+1-1','+1-2','+2+0','+0+2'}, [10]={'+0+0','+1+0','-1+0','+0-1','-1-1','+1-1','+1-2','+2+0','+0+2'},
[03]={'+0+0','-1+0','+1-1','+0-2','+0-3','+1+0','+1-2','+1-3','+0+1','-1+1'}, [03]={'+0+0','-1+0','+1-1','+0-2','+0-3','+1+0','+1-2','+1-3','+0+1','-1+1'},
[30]={'+0+0','-1+0','+1-1','+1-2','+1+0','+0-2','+1-3','-1+2','+0+3','-1+3'}, [30]={'+0+0','-1+0','+1-1','+1-2','+1+0','+0-2','+1-3','-1+2','+0+3','-1+3'},
[12]={'+0+0','-1+0','+1-1','-1-1','+1-2','+1+0','+0-2','+1-3','-1+2','+0+3','-1+3'}, [12]={'+0+0','-1+0','+1-1','-1-1','+1-2','+1+0','+0-2','+1-3','-1+2','+0+3','-1+3'},

View File

@@ -22,12 +22,12 @@ function back.resize(w,h)
S[i+4]=(rnd()-.5)*.01*s--Vy S[i+4]=(rnd()-.5)*.01*s--Vy
end end
end end
function back.update() function back.update(dt)
local S=stars local S=stars
--Star moving --Star moving
for i=1,1260,5 do for i=1,1260,5 do
S[i+1]=(S[i+1]+S[i+3])%W S[i+1]=(S[i+1]+S[i+3]*dt*60)%W
S[i+2]=(S[i+2]+S[i+4])%H S[i+2]=(S[i+2]+S[i+4]*dt*60)%H
end end
end end
function back.draw() function back.draw()

View File

@@ -28,7 +28,7 @@ return{
end end
setFont(50) setFont(50)
mStr(P.modeData.drought,63,130) mStr(P.modeData.drought,63,130)
mDraw(MODES.drought_l.icon,63,200,nil,.5) mDraw(IMG.drought,63,200,nil,.5)
end end
end, end,
task=function(P) task=function(P)

View File

@@ -28,7 +28,7 @@ return{
end end
setFont(50) setFont(50)
mStr(P.modeData.drought,63,130) mStr(P.modeData.drought,63,130)
mDraw(MODES.drought_l.icon,63,200,nil,.5) mDraw(IMG.drought,63,200,nil,.5)
end end
end, end,
task=function(P) task=function(P)
@@ -36,6 +36,7 @@ return{
end, end,
hook_drop=function(P) hook_drop=function(P)
local D=P.modeData local D=P.modeData
D.drought=P.lastPiece.id==7 and 0 or D.drought+1
if P.stat.row>=D.target then if P.stat.row>=D.target then
if D.target==110 then if D.target==110 then
P.gameEnv.drop,P.gameEnv.lock=2,2 P.gameEnv.drop,P.gameEnv.lock=2,2

View File

@@ -28,7 +28,7 @@ return{
end end
setFont(50) setFont(50)
mStr(P.modeData.drought,63,130) mStr(P.modeData.drought,63,130)
mDraw(MODES.drought_l.icon,63,200,nil,.5) mDraw(IMG.drought,63,200,nil,.5)
end end
end, end,
task=function(P) task=function(P)
@@ -36,6 +36,7 @@ return{
end, end,
hook_drop=function(P) hook_drop=function(P)
local D=P.modeData local D=P.modeData
D.drought=P.lastPiece.id==7 and 0 or D.drought+1
if P.stat.row>=D.target then if P.stat.row>=D.target then
if D.target==100 then if D.target==100 then
P:win('finish') P:win('finish')

View File

@@ -0,0 +1,80 @@
local inv_lock={60,50,45,40,37, 34,32,30,28,26}
local inv_wait={12,11,11,10,10, 10,10, 9, 9, 9}
local inv_fall={18,16,14,13,12, 12,11,11,10,10}
local inv_hide={20,17,14,11, 8, 5, 3, 2, 1, 0}
local hidetimer=0
local held=false
return{
drop=0,
lock=inv_lock[1],
wait=inv_wait[1],
fall=inv_fall[1],
ghost=false,
noTele=true,
das=10,arr=1,
mesDisp=function(P)
PLY.draw.drawProgress(P.modeData.pt,P.modeData.target)
end,
hook_drop=function(P)
local D=P.modeData
local c=#P.clearedRow
if c==0 and D.pt%100==99 then return end
local s=c<3 and c+1 or c==3 and 5 or 7
if P.combo>7 then s=s+2
elseif P.combo>3 then s=s+1
end
D.pt=D.pt+s
held=false
if D.pt<1000 then
hidetimer=0-inv_wait[(P.modeData.pt/100-(P.modeData.pt%100)/100)+1]
if c>0 then hidetimer=hidetimer-inv_fall[(P.modeData.pt/100-(P.modeData.pt%100)/100)+1]end
end
if D.pt%100==99 then
SFX.play('warn_1')
elseif D.pt>=D.target then--Level up!
s=D.target/100
local E=P.gameEnv
E.lock=inv_lock[s]
E.wait=inv_wait[s]
E.fall=inv_fall[s]
if s==2 then
E.das=8
elseif s==4 then
BG.set('rgb')
elseif s==5 then
E.das=7
elseif s==7 then
E.das=6
BGM.play('far')
elseif s==10 then
D.pt=1000
P:win('finish')
return
end
D.target=D.target+100
P:stageComplete(s)
SFX.play('reach')
end
end,
task=function(P)
P.modeData.pt=0
P.modeData.target=100
while true do
YIELD()
if P.holdTime==0 and P.waiting<=0 and not held then
hidetimer=0
held=true
end
hidetimer=hidetimer+1
if hidetimer>inv_hide[(P.modeData.pt/100-(P.modeData.pt%100)/100)+1]then
P.gameEnv.block=false
else
P.gameEnv.block=true
end
end
end,
}

Binary file not shown.

View File

@@ -7,6 +7,7 @@ local gc_draw,gc_rectangle,gc_line,gc_printf=gc.draw,gc.rectangle,gc.line,gc.pri
local ins,rem=table.insert,table.remove local ins,rem=table.insert,table.remove
local int,rnd=math.floor,math.random local int,rnd=math.floor,math.random
local approach=MATH.expApproach
local SETTING,GAME,SCR=SETTING,GAME,SCR local SETTING,GAME,SCR=SETTING,GAME,SCR
local PLAYERS=PLAYERS local PLAYERS=PLAYERS
@@ -94,7 +95,8 @@ do--function loadFile(name,args), function saveFile(data,name,args)
end end
end end
function isSafeFile(file,mes) function isSafeFile(file,mes)
if love.filesystem.getRealDirectory(file)~=SAVEDIR then local path=love.filesystem.getRealDirectory(file)
if path and path~=SAVEDIR then
return true return true
elseif mes then elseif mes then
MES.new('warn',mes) MES.new('warn',mes)
@@ -109,23 +111,7 @@ end
function saveSettings() function saveSettings()
return saveFile(SETTING,'conf/settings') return saveFile(SETTING,'conf/settings')
end end
function applyLanguage() do--function applySettings()
text=LANG.get(SETTING.locale)
WIDGET.setLang(text.WidgetText)
for k,v in next,TEXTOBJ do
if rawget(text,k)then
v:set(text[k])
end
end
end
function applyCursor()
love.mouse.setVisible(SETTING.sysCursor)
end
function applyFullscreen()
love.window.setFullscreen(SETTING.fullscreen)
love.resize(gc.getWidth(),gc.getHeight())
end
do--function applyBlockSatur,applyFieldSatur(mode)
local saturateValues={ local saturateValues={
normal={0,1}, normal={0,1},
soft={.2,.7}, soft={.2,.7},
@@ -133,58 +119,79 @@ do--function applyBlockSatur,applyFieldSatur(mode)
light={.2,.8}, light={.2,.8},
color={-.2,1.2}, color={-.2,1.2},
} }
function applyBlockSatur(mode) function applySettings()
local m=saturateValues[mode]or saturateValues.normal --Apply fullscreen
love.window.setFullscreen(SETTING.fullscreen)
love.resize(gc.getWidth(),gc.getHeight())
--Apply Zframework setting
Z.setClickFX(SETTING.clickFX)
Z.setFrameMul(SETTING.frameMul)
Z.setPowerInfo(SETTING.powerInfo)
Z.setCleanCanvas(SETTING.cleanCanvas)
--Apply VK shape
VK.setShape(SETTING.VKSkin)
--Apply sound
love.audio.setVolume(SETTING.mainVol)
BGM.setVol(SETTING.bgm)
SFX.setVol(SETTING.sfx)
VOC.setVol(SETTING.voc)
--Apply saturs
local m
m=saturateValues[SETTING.blockSatur]or saturateValues.normal
SHADER.blockSatur:send('b',m[1]) SHADER.blockSatur:send('b',m[1])
SHADER.blockSatur:send('k',m[2]) SHADER.blockSatur:send('k',m[2])
end m=saturateValues[SETTING.fieldSatur]or saturateValues.normal
function applyFieldSatur(mode)
local m=saturateValues[mode]or saturateValues.normal
SHADER.fieldSatur:send('b',m[1]) SHADER.fieldSatur:send('b',m[1])
SHADER.fieldSatur:send('k',m[2]) SHADER.fieldSatur:send('k',m[2])
end
end --Apply language
function applyBG() text=LANG.get(SETTING.locale)
if SETTING.bg=='on'then WIDGET.setLang(text.WidgetText)
BG.unlock() for k,v in next,TEXTOBJ do
BG.set() if rawget(text,k)then
elseif SETTING.bg=='off'then v:set(text[k])
BG.unlock() end
BG.set('gray') end
BG.send(SETTING.bgAlpha)
BG.lock() --Apply cursor
elseif SETTING.bg=='custom'then love.mouse.setVisible(SETTING.sysCursor)
if love.filesystem.getInfo('conf/customBG')then
local res,image=pcall(gc.newImage,love.filesystem.newFile('conf/customBG')) --Apply BG
if res then if SETTING.bg=='on'then
BG.unlock() BG.unlock()
BG.set('custom') BG.set()
gc.setDefaultFilter('linear','linear') elseif SETTING.bg=='off'then
BG.send(SETTING.bgAlpha,image) BG.unlock()
gc.setDefaultFilter('nearest','nearest') BG.set('gray')
BG.lock() BG.send(SETTING.bgAlpha)
else BG.lock()
MES.new('error',text.customBGloadFailed) elseif SETTING.bg=='custom'then
if love.filesystem.getInfo('conf/customBG')then
local res,image=pcall(gc.newImage,love.filesystem.newFile('conf/customBG'))
if res then
BG.unlock()
BG.set('custom')
gc.setDefaultFilter('linear','linear')
BG.send(SETTING.bgAlpha,image)
gc.setDefaultFilter('nearest','nearest')
BG.lock()
else
MES.new('error',text.customBGloadFailed)
end
else--Switch off when custom BG not found
SETTING.bg='off'
BG.unlock()
BG.set('gray')
BG.send(SETTING.bgAlpha)
BG.lock()
end end
else
SETTING.bg='off'
applyBG()
end end
end end
end end
function applyAllSettings()
applyFullscreen()
love.audio.setVolume(SETTING.mainVol)
VK.setShape(SETTING.VKSkin)
BGM.setVol(SETTING.bgm)
SFX.setVol(SETTING.sfx)
VOC.setVol(SETTING.voc)
applyBlockSatur(SETTING.blockSatur)
applyFieldSatur(SETTING.fieldSatur)
applyLanguage()
applyCursor()
applyBG()
end
--Royale mode --Royale mode
function randomTarget(P)--Return a random opponent for P function randomTarget(P)--Return a random opponent for P
@@ -491,12 +498,9 @@ end
function loadGame(mode,ifQuickPlay,ifNet)--Load a mode and go to game scene function loadGame(mode,ifQuickPlay,ifNet)--Load a mode and go to game scene
freshDate() freshDate()
if legalGameTime()then if legalGameTime()then
if not MODES[mode]and love.filesystem.getRealDirectory('parts/modes/'..mode)~=SAVEDIR then if not MODES[mode].available then
MODES[mode]=require('parts.modes.'..mode) MES.new('error',"Unavailable mode: "..mode)
MODES[mode].name=mode return
end
if MODES[mode].score then
STAT.lastPlay=mode
end end
GAME.playing=true GAME.playing=true
GAME.init=true GAME.init=true
@@ -537,29 +541,9 @@ function gameOver()--Save record
GAME.rank=R GAME.rank=R
end end
if not GAME.replaying and M.score and scoreValid()then if not GAME.replaying and M.score and scoreValid()then
if RANKS[M.name]then--Old rank exist if not RANKS[M.name]or R>RANKS[M.name]then--Old rank exist
local needSave RANKS[M.name]=R
if R>RANKS[M.name]then saveProgress()
RANKS[M.name]=R
needSave=true
end
if R>0 then
if M.unlock then
for i=1,#M.unlock do
local m=M.unlock[i]
local n=MODES[m].name
if not RANKS[n]then
if MODES[m].x then
RANKS[n]=0
end
needSave=true
end
end
end
end
if needSave then
saveProgress()
end
end end
local D=M.score(P) local D=M.score(P)
local L=M.records local L=M.records
@@ -771,7 +755,7 @@ do--function resetGameData(args)
BGM.play(type(bgm)=='string'and bgm or type(bgm)=='table'and bgm[math.random(#bgm)]) BGM.play(type(bgm)=='string'and bgm or type(bgm)=='table'and bgm[math.random(#bgm)])
TEXT.clear() TEXT.clear()
if GAME.modeEnv.eventset=='royale'then if GAME.modeEnv.eventSet=='royale'then
for i=1,#PLAYERS do for i=1,#PLAYERS do
PLAYERS[i]:changeAtk(randomTarget(PLAYERS[i])) PLAYERS[i]:changeAtk(randomTarget(PLAYERS[i]))
end end
@@ -792,7 +776,7 @@ do--function resetGameData(args)
end end
do--function checkWarning() do--function checkWarning()
local max=math.max local max=math.max
function checkWarning() function checkWarning(dt)
local P1=PLAYERS[1] local P1=PLAYERS[1]
if P1.alive then if P1.alive then
if P1.frameRun%26==0 then if P1.frameRun%26==0 then
@@ -812,7 +796,7 @@ do--function checkWarning()
end end
local _=GAME.warnLVL local _=GAME.warnLVL
if _<GAME.warnLVL0 then if _<GAME.warnLVL0 then
_=_*.95+GAME.warnLVL0*.05 _=approach(_,GAME.warnLVL0,dt*6)
elseif _>0 then elseif _>0 then
_=max(_-.026,0) _=max(_-.026,0)
end end

View File

@@ -13,6 +13,13 @@ BLOCK_COLORS={
COLOR.dH,COLOR.D,COLOR.lY,COLOR.H,COLOR.lH,COLOR.dV,COLOR.dR,COLOR.dG, COLOR.dH,COLOR.D,COLOR.lY,COLOR.H,COLOR.lH,COLOR.dV,COLOR.dR,COLOR.dG,
} }
RANK_CHARS={'B','A','S','U','X'}for i=1,#RANK_CHARS do RANK_CHARS[i]=CHAR.icon['rank'..RANK_CHARS[i]]end RANK_CHARS={'B','A','S','U','X'}for i=1,#RANK_CHARS do RANK_CHARS[i]=CHAR.icon['rank'..RANK_CHARS[i]]end
RANK_BASE_COLORS={
{.1,.2,.3},
{.3,.42,.32},
{.45,.44,.15},
{.42,.25,.2},
{.42,.15,.4},
}
RANK_COLORS={ RANK_COLORS={
{.8,.86,.9}, {.8,.86,.9},
{.6,.9,.7}, {.6,.9,.7},
@@ -594,7 +601,7 @@ do--Userdata tables
FTLock=true, FTLock=true,
--System --System
reTime=4, reTime=2,
allowTAS=false, allowTAS=false,
autoPause=true, autoPause=true,
menuPos='middle', menuPos='middle',
@@ -603,6 +610,8 @@ do--Userdata tables
autoLogin=true, autoLogin=true,
simpMode=false, simpMode=false,
sysCursor=true, sysCursor=true,
maxFPS=60,
frameMul=100,
locale='zh', locale='zh',
skinSet='crystal_scf', skinSet='crystal_scf',
skin={ skin={
@@ -625,7 +634,6 @@ do--Userdata tables
splashFX=2, splashFX=2,
shakeFX=2, shakeFX=2,
atkFX=2, atkFX=2,
frameMul=100,
cleanCanvas=false, cleanCanvas=false,
blockSatur='normal', blockSatur='normal',
fieldSatur='normal', fieldSatur='normal',
@@ -723,3 +731,44 @@ do--Userdata tables
todayTime=0, todayTime=0,
} }
end end
do--Mode data tables
MODES=setmetatable({},{__index=function(self,name)
local M
if love.filesystem.getInfo('parts/modes/'..name..'.lua')and love.filesystem.getRealDirectory('parts/modes/'..name..'.lua')~=SAVEDIR then
M=require('parts.modes.'..name)
M.available=true
M.name=name
do--Check if need slowmark
for k in next,M.env do
if
k=='mindas'or k=='minarr'or
k=='das'or k=='arr'or
k=='minsdarr'
then
M.slowMark=true
break
end
end
end
if M.score then
M.records=loadFile("record/"..name..".rec",'-luaon -canSkip')or{}
end
else
M={
available=false,
}
MES.new('error',"Failed to load mode file: "..name)
end
self[name]=M
return M
end})
MODEICON=setmetatable({},{__index=function(self,k)
if isSafeFile('media/image/modeicon/'..k..'.png')then
local img=love.graphics.newImage('media/image/modeicon/'..k..'.png')
self[k]=img
return img
else
return PAPER
end
end})
end

View File

@@ -1,20 +1,20 @@
local HDsearch="https://harddrop.com/wiki?search=" local HDsearch="https://harddrop.com/wiki?search="
local HDwiki="\nVisit HD Wiki for more information" local HDwiki="\nVisit Hard Drop Wiki for more information."
return{ return{
{"Translator Note 1", {"Translator Note 1",
"", "",
"help", "help",
"This translation of the TetroDictionary is provided by me, User670 (Discord: User670#9501).\n\nThe translation may not completely reflect the contents of the original Chinese text.\n\nCorrected by C₂₉H₂₅N₃O₅ (Discord: C29H25N3O5#1606).\n\nTo view the list of contributors or make contributions, feel free to visit the GitHub page.", "This translation of the TetroDictionary is maly provided by User670 (Discord: User670#9501).\n\nThe translation may not completely reflect the contents of the original Chinese text.\n\nTo view the list of contributors or make contributions, feel free to visit the GitHub page.",
"https://github.com/26F-Studio/Techmino/blob/main/parts/language/dict_en.lua", "https://github.com/26F-Studio/Techmino/blob/main/parts/language/dict_en.lua",
}, },
{"Official Website", {"Official Website",
"official website homepage", "official website homepage mainpage",
"help", "help",
"The official website of Techmino!\nYou can modify your profile on it", "The official website of Techmino!\nYou can modify your profile on it",
"http://home.techmino.org", "http://home.techmino.org",
}, },
{"To New Players", {"To New Players",
"guide newbie noob", "guide newbie noob readme",
"help", "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 to read the translated article by User670.", "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", "https://github.com/user670/temp/blob/master/tips_to_those_new_to_top.md",
@@ -39,7 +39,7 @@ return{
{"Four.lol", {"Four.lol",
"four wiki", "four wiki",
"help", "help",
"An website containing collections of various openings with simple UI and very detailed consecutive PC analyses (Not recommended for new players as you may have to memorize many techniques).", "An website containing collections of various openings with simple UI and very detailed consecutive PC analyses (Not recommended for new players, as you may have to memorize many techniques).",
"https://four.lol", "https://four.lol",
}, },
{"Tetris Wiki Fandom", {"Tetris Wiki Fandom",
@@ -59,7 +59,7 @@ return{
{"Github Repository", {"Github Repository",
"githubrepository sourcecode", "githubrepository sourcecode",
"org", "org",
"Techmino's Github repository. Stars are appreciated.", "Techmino's official Github repository. Stars are appreciated.",
"https://github.com/26F-Studio/Techmino", "https://github.com/26F-Studio/Techmino",
}, },
{"Communities", {"Communities",
@@ -69,7 +69,7 @@ return{
"https://discord.gg/harddrop" "https://discord.gg/harddrop"
}, },
{"Mew", {"Mew",
"mew tieba forum", "mew tieba forum reddit",
"org", "org",
"The Mew forum owned by Chinese Tetris Research Community, and was founded in the second half of 2021. Mew is a Chinese social media that can be thought of a combination of Discord and Reddit, with many channels in a big community. Users can chat in the channels or submit posts to the channel. Mew also has a function called \"Library\" which allows storing documentations systematically. The Tetris Mew forum is currently under construction and not too much contents are available (2/Nov/2021).", "The Mew forum owned by Chinese Tetris Research Community, and was founded in the second half of 2021. Mew is a Chinese social media that can be thought of a combination of Discord and Reddit, with many channels in a big community. Users can chat in the channels or submit posts to the channel. Mew also has a function called \"Library\" which allows storing documentations systematically. The Tetris Mew forum is currently under construction and not too much contents are available (2/Nov/2021).",
"https://mew.fun/n/tetris", "https://mew.fun/n/tetris",
@@ -83,225 +83,241 @@ return{
{"Support 1", {"Support 1",
"support wechat vx alipay zfb", "support wechat vx alipay zfb",
"org", "org",
"vx/zfb-console-support", FNNS and "This feature is restricted due to platform policy restrictions. You may discuss about this feature in our Discord server." or "To donate to Techmino via WeChat Pay or Alipay, type \"support\" in console.",
}, },
{"Support 2", {"Support 2",
"support afdian", "support afdian",
"org", "org",
"Afdian", FNNS and "This feature is restricted due to platform policy restrictions. You may discuss about this feature in our Discord server. The URL in this entry is a rickroll, by the way." or "To donate to Techmino via Aifadian, use the globe icon on the bottom right to open URL. Aifadian charges 6% transaction fee off your purchase.",
FNNS and"https://www.bilibili.com/video/BV1GJ411x7h7"or"https://afdian.net/@MrZ_26", FNNS and"https://youtu.be/dQw4w9WgXcQ"or"https://afdian.net/@MrZ_26",
}, },
{"Support 3", {"Support 3",
"support p\97\116\114\101\111\110", "support p\97\116\114\101\111\110",
"org", "org",
"P\97\116\114\101\111\110", FNNS and "This feature is restricted due to platform policy restrictions. You may discuss about this feature in our Discord server. The URL in this entry is a rickroll, by the way." or "To donate to Techmino via P\97\116\114\101\111\110, use the globe icon on the bottom right to open URL. P\97\116\114\101\111\110 charges 7.9% + 0.30 USD transaction fee off your purchase that is greater than 3 USD.",
FNNS and"https://www.bilibili.com/video/BV1GJ411x7h7"or"https://www.p\97\116\114\101\111\110.com/techmino", FNNS and"https://youtu.be/dQw4w9WgXcQ"or"https://www.p\97\116\114\101\111\110.com/techmino",
}, },
--Games --Games
{"TTT", {"TTT",
"ttt tetris trainer tres bien", "ttt tetris trainer tres bien",
"game", "game",
"*Web-based, no mobile support | Single-player*\nTetris Trainer Tres-Bien. A hands-on tutorial of advanced techniques in modern Tetris.\nRecommended for players that can complete a 40-line Sprint with all Tetris line clears and no hold.\nCovered topics include T-Spin, finesse, SRS, and some battle setups.\nLink translated to Simplified Chinese; originally in Japanese.", "Tetris Trainer Très-Bien. A hands-on tutorial of advanced techniques in modern Tetris.\nRecommended for players that can complete a 40-line Sprint with all Tetris line clears and no hold.\nCovered topics include T-Spin, finesse, SRS, and some battle setups.\nLink in Japanese.",
"http://teatube.ltd/ttt", "http://taninkona.web.fc2.com/ttt/",
}, },
{"TTPC", {"TTPC",
"ttpc tetris perfect clear challenge", "ttpc tetris perfect clear challenge",
"game", "game",
"*Web-based, no mobile support | Single-player*\nTetris Perfect Clear Challenge. The PC opener tutorial for SRS+7 Bag.\nRecommended for players that have completed TTT. You need to know SRS to play this.\nIncludes only the basic PC opener.\nLink translated to Simplified Chinese; originally in Japanese.", "Tetris Perfect Clear Challenge. The PC opener tutorial for SRS and 7-Bag.\nRecommended for players that have completed TTT. You need to know SRS to play this.\nIncludes only the basic PC opener.\nLink translated to Simplified Chinese; originally in Japanese.",
"http://teatube.ltd/ttpc", "http://teatube.ltd/ttpc",
}, },
{"NAZO", {"NAZO",
"nazo", "nazo",
"game", "game",
"*Web-based, no mobile support | Single-player*\nAll sorts of SRS puzzles. Recommended for players that have completed TTT.\nHas T-Spin and all spin puzzles of all difficulties.\nLink translated to Simplified Chinese; originally in Japanese.", "All sorts of SRS puzzles. Recommended for players that have completed TTT.\nHas T-Spin and all spin puzzles of all difficulties.\nLink translated to Simplified Chinese; originally in Japanese.",
"http://teatube.ltd/nazo", "http://teatube.ltd/nazo",
}, },
{"Side Note 1",
"note nb NB DM notice",
"game",
"The following contents are some brief introductions about some official and fan-made Tetris games with high popularity. We make absolutely no guarantees that they would cover every Tetris game. Also, the author of this game has made some comments on some of these games. Notice that they are just personal opinions and cannot be used to judge the qualities of these games. To better differentiate between the facts and opinions, all the commentary contents are enclosed with square brackets and are separated from the main contents.",
},
{"King of Stackers", {"King of Stackers",
"kos kingofstackers", "kos kingofstackers",
"game", "game",
"*Web-based | Multiplayer*\nTurn-based battle Tetris game.", "Browser Game | Multiplayer | Mobile Support\nKoS for short. A turn-based battle Tetris game. In this game, the players can place seven tetrominoes in his or her turn, and garbage lines can enter the field only if the player places a block that does not clear a line. This game requires careful thinking and there are multiple modes with different attack mechanics.",
"https://kingofstackers.com/games.php", "https://kingofstackers.com/games.php",
}, },
{"Tetr.js", {"Tetr.js",
"tetrjs tetr.js", "tetrjs tetr.js",
"game", "game",
"*Web-based | Single-player*\nHas newbie-friendly custom modes (most common features). Only a few on-screen control schemes are available to mobile.\nLink to Farter's Dig Mod, which itself is a mod of another version. Also has another mod called Tetr.js Enhanced.", "Browser Game | Singleplayer | Mobile Support\nA browser-based Tetris game. It has many professional tunings and many modes, but the visuals are simple and there are barely any animations; besides that, only a few on-screen control schemes are available to mobile.\nLink to Farter's Dig Mod, which itself is a mod of another version. Also has another mod called Tetr.js Enhanced (You can find the link on Tetris Wiki).",
"http://farter.cn/t", "http://farter.cn/t",
}, },
{"Tetra Legends", {"Tetra Legends",
"tl tetralegends", "tl tetralegends",
"game", "game",
"*Web-based, no mobile support | Single-player*\nFeature-rich game with fancy visuals, also visualized some data that are otherwise hidden in other games, although controls aren't exactly the most comfortable. Has a rhythm mode.\nIt can be slow to load the game for the first time.", "Browser Game | Singleplayer | No Mobile Support\nOr TL for short. It has many single-player modes, two hidden rhythm modes, and visualizes many hidden mechanics with rich animations. The development of this game was halted for multiple reasons in December 2020.",
"https://tetralegends.app", "https://tetralegends.app",
}, },
{"Ascension", {"Ascension",
"asc ascension", "asc ascension ASC",
"game", "game",
"Or ASC for short. A cross-platform web-based Tetris game using its own rotation system called ASC. It may take a very long time when first loading this game. It also has many single-player modes (The \"Stack\" mode in Techmino was inspired by Ascension). Battle mode is currently in the testing phase (08/20/2021).", "Browser Game | Singleplayer/Multiplayer\nOr ASC for short. It uses its own rotation system (also called ASC) and has many single-player modes. Battle modes are currently under beta testing (15/Dec/2021). The Stack mode in this game was also inspired by Ascension. ",
"https://asc.winternebs.com", "https://asc.winternebs.com",
}, },
{"Jstris", {"Jstris",
"js jstris", "js jstris",
"game", "game",
"*Web-based | Single-player and multiplayer*\nBasic web-based battle Tetris game.", "Browser Game | Singleplayer/Multiplayer | Mobile Support\nOr JS for short. It has some single-player modes with multiple customizable parameters, Adjustable virtual keys layouts for mobile, but it doesn't have any animation. ",
"https://jstris.jezevec10.com", "https://jstris.jezevec10.com",
}, },
{"TETR.IO", {"TETR.IO",
"io tetrio tetr.io", "io tetrio tetr.io",
"game", "game",
"*Web-based, no mobile support | Single-player and multiplayer*\nFancy online battling Tetris game.", "Browser Game | Singleplayer/Multiplayer\nOr IO for short. It has a ranking system and custom game with many adjustable parameters. Also, it provides desktop clients for improved performances and no ads.\n[It seems that Safari cannot open this game.]",
"https://tetr.io", "https://tetr.io",
}, },
{"Nuketris", {"Nuketris",
"nuketris", "nuketris",
"game", "game",
"*Web-based | Single-player and multiplayer*\nA block stacker game with 1-vs-1 ranked mode and a few single-player modes. A PC is recommended for playing this game.", "*Browser Game | Singleplayer/Multiplayer\nA block stacker game with 1V1 ranked matches and basic single-player modes.",
"https://nuketris.herokuapp.com", "https://nuketris.herokuapp.com",
}, },
{"WWC", {"Worldwide Combos",
"wwc worldwidecombos", "wwc worldwidecombos",
"game", "game",
"*Web-based | Multiplayer*\nWorldwide Combos, a web-based worldwide 1-vs-1 battle Tetris game.", "Browser Game | Singleplayer/Multiplayer\nOr WWC for short. It has worldwide 1V1 ranked matches, recorded battles (which means that your opponent doesn't have to be a real person), many different rulesets, and bomb-handicapped garbage lines.",
"https://worldwidecombos.com", "https://worldwidecombos.com",
}, },
{"Tetris Friends", {"Tetris Friends",
"tf tetrisfriends notrisfoes", "tf tetrisfriends notrisfoes",
"game", "game",
"*Web-based, no mobile support | Single-player and multiplayer*\nA now-defunct web-based Tetris game; used to be a decent battle game. An unofficial private server known as Notris Foes exists.\nBuilt using Flash, which might require workarounds to play or cannot run at all on your devices.", "Browser Game | Singleplayer/Multiplayer\n or TF for short, a now-defunct official Tetris game. Used to be a popular game but now nobody plays it because the website was shut down. However an unofficial private server known as \"Notris Foes\" still exists and you will need to download desktop client for full experiences.",
}, },
{"tetris.com", {"tetris.com",
"tetris online official", "tetris online official",
"game", "game",
"The Tetris game on tetris.com. It only has one mode marathon, and you can control the game with your mouse.", "Browser Game | Singleplayer\nThe Tetris game on tetris.com. It only has one mode marathon, and you can control the game with your mouse.",
}, },
{"Tetris Gems", {"Tetris Gems",
"tetris online official gem", "tetris online official gem",
"game", "game",
"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.", "Browser Game | Singleplayer\nAnother 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 Mind Bender",
"tetris online official gem", "tetris online official gem",
"game", "game",
"Another Tetris game from tetris.com. It introduced \"Mind Bender\" minoes on the basis of marathon mode. Clearing a line with a Mind Bender mino will give you either a good or bad effect.", "Browser Game | Singleplayer\nAnother Tetris game from tetris.com. It introduced \"Mind Bender\" minoes on the basis of marathon mode. Clearing a line with a Mind Bender mino will give you either a good or bad effect.",
},
{"Techmino",
"techmino",
"game",
"Cross-Platform | Singleplayer/Multiplayer\nOr Tech for short. A block stacker game developed using LÖVE. It has many single-player modes and many customizable parameters, and online multiplayer modes are gradually being developed.",
},
{"Falling Lightblocks",
"fl fallinglightblocks",
"game",
"Browser Game/iOS/Android | Singleplayer/Multiplayer\n A cross-platform Tetris game that can be played in portrait and landscape modes. It has fixed DAS and line clear ARE. Has some customizable controls on mobile. Most of the game modes are designed based on NES classic Tetris, but there are some modern-ish modes. Battles are half turn-based, half real-time, and garbage cannot be buffered or canceled.",
"https://golfgl.de/lightblocks/",
},
{"Cambridge",
"cambridge",
"game",
"Cross-Platform | Singleplayer\n A Tetris game developed using LÖVE and is dedicated to creating a robust, easily customizable platform for creating new, custom game modes. Originally made by Joe Zeng, but Milla took over the development on 08/Oct/2020 starting from V0.1.5.\n — Tetris Wiki",
},
{"Nanamino",
"nanamino",
"game",
"Windows/Android | Singleplayer\nA developing fan game which has a interesting original rotation system.",
}, },
{"TGM", {"TGM",
"tgm tetrisgrandmaster tetristhegrandmaster", "tgm tetrisgrandmaster tetristhegrandmaster",
"game", "game",
"*Arcade | Single-player*\nTetris The Grand Master, an arcade Tetris series that can run on Microsoft Windows. Titles like S13 or GM come from this series.\n\nTGM3 is the most well-known game in this series.", "Arcade | Singleplayer/Local Multiplayer\nTetris The Grand Master, an arcade Tetris series. Titles like S13 and GM come from this series.\n\nTGM3 is the most well-known game in this series.",
}, },
{"DTET", {"DTET",
"dtet", "dtet",
"game", "game",
"*Windows | Single-player*\nA game based on TGM's Classic rule with 20G and a powerful rotation system. Decent controls, but has no customization other than control mappings. The game is a bit hard to find now and you might need to manually install required DLLs.", "Windows | Singleplayer\nA game based on TGM's Classic rule with 20G and a powerful rotation system. Decent controls, but has no customization other than control mappings. The game is a bit hard to find now and you may need to manually install required DLLs.",
}, },
{"Heboris", {"Heboris",
"hb heboris", "hb heboris",
"game", "game",
"*Windows*\nA game with Arcade-ish play style, simulates some modes of many Tetris games.", "Windows | Singleplayer\nA game with Arcade-ish play style, capable of simulating many modes of other Tetris games.",
}, },
{"Texmaster", {"Texmaster",
"txm texmaster", "txm texmaster",
"game", "game",
"*Windows | Single-player*\nA game with all modes from TGM which you can use to practice. Has better controls than actual TGM. The world rule is slightly different, however (eg, instant-lock soft drops, and slightly different kick tables)", "Windows | Singleplayer\nA game with all modes from TGM which you can use to practice. The world rule is slightly different, however (e.g. instant-lock soft drops and slightly different kick tables).",
},
{"Cambridge",
"cambridge",
"game",
"*Windows, macOS, Linux | Single-player*\nA Lua-based game engine dedicated to creating a robust, easily customizable platform for creating new, custom game modes. It was originally made by Joe Zeng, and starting with version 0.1.5 on October 8, 2020, Milla took over development of the game.\n--Tetris Wiki",
}, },
{"Tetris99", {"Tetris Effect",
"tec tetriseffectconnected",
"game",
"PS/Oculus Quest/Xbox/NS/Windows | Singleplayer/Multiplayer\nOr TE(C) for short. An official Tetris game with fancy graphics and soundtracks that react to your input. The basic version (without the word \"Connected\") only has singleplayer modes. The extended version, Tetris Effect Connected, features four online battle modes, Connected (VS), Zone Battle, Score Attack, and Classic Score Attack.",
},
{"Tetris 99",
"t99 tetris99", "t99 tetris99",
"game", "game",
"*Nintendo Switch | Multiplayer*\nA game famous for its 99-player battle royale mode and has many interesting strategies not present on traditional battle Tetris games. Also has limited single-player modes like Marathon and bot matches available as DLC.", "Nintendo Switch | Singleplayer/Multiplayer\nA game famous for its 99-player battle royale mode and has many interesting strategies not present on traditional battle Tetris games. Also has limited single-player modes like Marathon and bot matches available as DLC.",
}, },
{"Puyo Puyo Tetris", {"Puyo Puyo Tetris",
"ppt puyopuyotetris", "ppt puyopuyotetris",
"game", "game",
"*Multiple platforms | Single-player and multiplayer*\nA game that combines two games, Tetris and Puyo Puyo, and can battle between those two games. Has many modes for both single-player and online. The PC/Steam version has worse controls and horrible online experience, so it is not recommended.", "PS/NS/Xbox/Windows | Singleplayer/multiplayer\nA game that combines two games, Tetris and Puyo Puyo, and can battle between those two games. Has many modes for both single-player and online\n\n[The Steam PC version has worse controls and horrible online experience.]",
}, },
{"Tetris Online", {"Tetris Online",
"top tetrisonline", "top tetrisonline",
"game", "game",
"*Windows | Single-player and multiplayer*\nA now-defunct Japanese Tetris game with both online and single-player modes. Allows custom DAS/ARR but neither can be set to 0. Minor input delay. Private servers exist and is decent for new players to get started.", "Windows | Singleplayer/Multiplayer*\nA now-defunct Japanese Tetris game with both online and single-player modes. Allows custom DAS/ARR but neither can be set to 0. Minor input delay. Private servers do exist and is decent for new players to get started.",
}, },
{"Tetris Effect", {"Tetra Online",
"te tetriseffect", "TO tetraonline",
"game", "game",
"*PS4, Windows, Xbox | Single-player*\nFancy graphics and soundtrack that react to your actions. Not-so-good controls. You can have a go if you are into the visuals, but not exactly worth it if you are just trying to play some Tetris.", "Windows/macOS/Linux | Singleplayer/Multiplayer\nTO for short. A Tetris game developed by Dr Ocelot and Mine. The delays are AREs are intentionally set to high values, and players who get used to Tetris games with no delays may not get used to this game.\nThe game was removed from Steam on 09/Dec/2020 due to a DMCA notice filed by TTC.\nHowever, an offline build can still be downloaded on GitHub.",
}, "https://github.com/Juan-Cartes/Tetra-Offline/releases/tag/1.0",
{"Techmino",
"techmino",
"game",
"*Windows, macOS, Android, Linux, iOS/iPadOS | Single-player and multiplayer*\nA game with many modes and loads of customization. Low input delay, decent controls.",
}, },
{"Cultris II", {"Cultris II",
"c2 cultris2 cultrisii", "c2 cultris2 cultrisii",
"game", "game",
"*Windows, macOS, Linux | Single-player and multiplayer*\nA game focusing on speed. Has no hold and limited lockdown timer (like old school Tetris), but has customizable DAS/ARR. The main gimmick is its timer-based combos and emphasizes on speed, combo setups and digging.", "Windows/OS X | Singleplayer/Multiplayer\nC2 for short. Designed based on classic Tetris, Cultris II supports customizable DAS and ARR. The battle mode is focused on time-based combos, which challenges players speed, n-wide setups, and downstacking skills.\n[The Mac version was not being maintained for a long time. Any macOS build newer than macOS Catalina cannot run this game at all.]",
}, },
{"Nullpomino", {"Nullpomino",
"np nullpomino", "np nullpomino",
"game", "game",
"*Windows | Single-player and multiplayer*\nProfessional Tetris game with extreme room for customization. You can customize almost every aspect of the game. However, this is not a beginner-friendly game (you can get lost in the menus quite easily).", "Windows/macOS/Linux | Singleplayer/Multiplayer\nOr NP for short. A high-customizable professional Tetris game. Nearly every parameter in the game can be adjusted.\n[But the UI was outdated, and this game requires full-keyboard controls. New players may have some problems getting used to it. Also, it seems that macOS Monterey cannot run this game.]",
},
{"Touhoumino",
"touhoumino",
"game",
"*Windows | Single-player*\nA Nullpomino mod with elements from Touhou Project. It is fun to play but difficult. Recommended for players with at least half-decent skills otherwise you don't even know how you die",
},
{"Nanamino",
"nanamino",
"game",
"*Windows, Android | Single-player*\nDeveloping game, has a interesting rotation system",
}, },
{"Misamino", {"Misamino",
"misamino", "misamino",
"game", "game",
"*Windows | Single-player?*\nLocal 1-vs-1 game, mainly plays turn-based mode. You can write your own bot for it (though you need to learn its API if you do).\nMisamino is also the name of its built-in bot. Said bot is also the core for the Puyo Puyo Tetris bot, Zetris.", "Windows | Single-player\nLocal 1V1 game, mainly plays turn-based mode. You can write your own bot for it (though you need to learn its API if you do).\nMisamino is also the name of its built-in bot.",
}, },
{"Tetris Journey", {"Touhoumino",
"huanyouji tetrisjourney mobile phone", "touhoumino",
"game", "game",
"An official mobile Tetris game developed by Tencent (available only in China). It has level modes, battle modes, and some single-player modes. You can customize the sizes and positions of the virtual keys but you cannot adjust DAS or ARR.\n The battle mode lasts for 2 minutes and if both player did not top out, the one who sent more attacks wins." "Windows | Singleplayer\nA fan-made Tetris game, basically Nullpomino with elements from Touhou Project. The \"Spellcards\" from Touhou was introduced in the game, and you can only get bonus scores if you can reach the target score within the given period of time.\n[Recommended for players with at least half-decent skills otherwise you don't even know how you die.]",
}, },
{"Tetris Blitz", {"Tetris Blitz",
"blitz ea mobile phone", "blitz ea mobile phone",
"game", "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 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.", "iOS/Android | Singleplayer\nA 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)",
"tetris ea galaxy universe cosmos mobile phone", "tetris ea galaxy universe cosmos mobile phone",
"game", "game",
"Another mobile Tetris game by EA. It has two control modes Swipe and One-Touch. It also has a Galaxy Mode besides the Marathon Mode (with gravity mechanism), and the goal of this mode is to clear all Galaxy minoes before the sequence runs out.\n\nThis game is no longer available since April 2020." "iOS/Android | Singleplayer/Multiplayer?\nAnother mobile Tetris game by EA. It has two control modes Swipe and One-Touch. It also has a Galaxy Mode besides the Marathon Mode (with gravity mechanism), and the goal of this mode is to clear all Galaxy minoes before the sequence runs out.\n\nThis game is no longer available since April 2020."
}, },
{"Tetris (N3TWORK)", {"Tetris (N3TWORK)",
"tetris n3twork mobile phone", "tetris n3twork mobile phone",
"game", "game",
"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.", "iOS/Android | Singleplayer\nThe mobile Tetris game from N3TWORK Inc. It has a 3-minute ultra mode, a marathon mode and a 100-player Royale mode.\n[The UI is great but its controls are not so good.]",
}, },
{"Tetris Beat", {"Tetris Beat",
"tetris beat n3twork rhythm", "tetris beat n3twork rhythm",
"game", "game",
"A mobile Tetris game from N3TWORK. It has a \"Beat\" mode besides the Marathon mode, but in this game you only have drop the blocks in rhythm with the BGM. The effects are very heavy and the controls are not so good." "iOS | Singleplayer\nA mobile Tetris game from N3TWORK. It has a \"Beat\" mode besides the Marathon mode, but in this game you only have drop the blocks in rhythm with the BGM.\n[The effects are very heavy and the controls are not so good.]"
},
{"Tetris Journey",
"tetrisjourney mobile phone huanyouji",
"game",
"iOS/Android | Singleplayer\nAn official mobile Tetris game developed by Tencent (available exclusively in China). It has level modes, battle modes, and some single-player modes. You can customize the sizes and positions of the virtual keys but you cannot adjust DAS or ARR.\n The battle mode lasts for 2 minutes and if both player did not top out, the one who sent more attacks wins."
}, },
{"JJ Tetris", {"JJ Tetris",
"jjtetris", "jjtetris",
"game", "game",
"*Android | Multiplayer*\n(JJ块)\nA casual game on JJ Card Games (JJ棋牌). Portrait screen, low input delay, smooth controls. Customizable DAS/ARR and toggle-able 20G soft drop, limited control scheme customization. No hold nor B2B, no garbage buffer nor cancelling. Every attack sends at most 4 lines, combos are more powerful, otherwise similar to modern Tetris.", "Android | Multiplayer\n(JJ块)\nA casual game on JJ Card Games (JJ棋牌). Portrait screen, low input delay, smooth controls. Customizable DAS/ARR and toggle-able 20G soft drop, limited control scheme customization. No hold nor B2B, no garbage buffer nor cancelling. Every attack sends at most 4 lines, combos are more powerful, otherwise similar to modern Tetris.",
},
{"Falling lightblock",
"fl fallinglightblock",
"game",
"*Android, iOS, Web | Single-player and multiplayer*\nA game that supports many platforms. Has delays that cannot be adjusted. Can, to some extent, customize controls on mobile. Most of the modes are similar to classic Tetris, but modern-ish modes also exist. Battles are half-turn-based-half-real-time, and garbage cannot be buffered or cancelled.",
"https://golfgl.de/lightblocks/",
}, },
{"Huopin Tetris", {"Huopin Tetris",
"huopin qq", "huopin qq",
"game", "game",
"*Windows | Multiplayer*\n(火拼俄罗斯)\n\nThe Tetris game on Tencent Game Center, 12-wide board, DAS/ARR the same as your typing, 1 next, no hold. Can only send garbage through Tetris (sends 3 lines) and Triple (sends 2 lines). Garbage is checker-board-shaped and is very difficult to dig through.", "Windows | Multiplayer\n(火拼俄罗斯)\n\nThe Tetris game on Tencent Game Center, 12-wide board, DAS/ARR the same as your typing, 1 next, no hold. Can only send garbage through Tetris (sends 3 lines) and Triple (sends 2 lines). Garbage is checker-board-shaped and is nearly impossible to dig through.",
}, },
--Terms --Terms
@@ -799,6 +815,11 @@ return{
"term", "term",
"Vibrate your finger on the controller to achieve faster sideways movement speed than holding it.\nIt is most commonly used on classic Tetris where DAS is rather slow. In most cases, you do not need to hypertap in modern Tetris games, because their DAS is often fast enough.", "Vibrate your finger on the controller to achieve faster sideways movement speed than holding it.\nIt is most commonly used on classic Tetris where DAS is rather slow. In most cases, you do not need to hypertap in modern Tetris games, because their DAS is often fast enough.",
}, },
{"Rolling",
"rolling",
"term",
"Another method of fast-tapping in high-gravity (around 1G) modes (with slow DAS/ARR setting).\nWhen you perform rolling, you fix the position of one hand and the controller, and then tap the back of the controller with fingers on your other hand repeatedly. This method allows even faster moving speeds than hypertapping (see \"Hypertapping\" for more)and requires much less effort.\nThis method was first discovered by Cheez-fish and he has once achieved a tapping speed of more than 20 Hz.",
},
{"Passthrough", {"Passthrough",
"passthrough pingthrough", "passthrough pingthrough",
"term", "term",
@@ -1037,9 +1058,9 @@ return{
--Savedata managing --Savedata managing
{"Console", {"Console",
"console cmd commamd minglinghang kongzhitai", "console cmd commamd minglinghang kongzhitai terminal",
"command", "command",
"Techmino has a console that enables debugging/advanced features.\nTo access the console, repeatedly tap the Techmino logo or press the C key on the keyboard on the main menu.\n\nCareless actions in the console may result in corrupting or losing saved data. Proceed at your own risk.", "Techmino has a console that enables debugging/advanced features.\nTo access the console, repeatedly tap (or click) the Techmino logo or press the C key on the keyboard on the main menu.\n\nCareless actions in the console may result in corrupting or losing saved data. Proceed at your own risk.",
}, },
{"Reset setting", {"Reset setting",
"reset setting", "reset setting",
@@ -1143,7 +1164,7 @@ return{
{"Jonas", {"Jonas",
"jonas", "jonas",
"name", "name",
"One of the top players in Classic Tetris.\nFour-times-in-a-row champion of CTWC.\n\n(1981-2021)", "(1981-2021) One of the top players in Classic Tetris.\nFour-times-in-a-row champion of CTWC.",
}, },
{"Joseph", {"Joseph",
"joseph", "joseph",
@@ -1183,10 +1204,10 @@ return{
{"TetroDictionary", {"TetroDictionary",
"zictionary tetrodictionary littlez", "zictionary tetrodictionary littlez",
"name", "name",
"(or Zictionary for short) The name of this dictionary!\nIt includes brief introductions on many common terms in Tetris.\nIt used to be a chatbot in our QQ group, which was used to answer new player's FAQs. The entries in the Tetrodictionary were also inherited from the database in the chatbot.", "(or Zictionary for short) The name of this dictionary!\nIt includes brief introductions on many common terms in Tetris.\nIt used to be a chatbot in our QQ group, which was used to answer new player's FAQs. The entries in the Tetrodictionary were also inherited from the database in the chatbot.\nThe contents in the TetroDictionary was adapted from a variety of sources such as Tetris Wiki and Hard Drop Wiki.",
}, },
{"MrZ", {"MrZ",
"mrz_26", "mrz_26 t026 t626",
"name", "name",
"Tetris Research community member, the author of Techmino.\nPersonal bests: Sprint 25.95 seconds, MPH Sprint 57 seconds, #8 on Jstris leaderboards, X rank on TETR.IO, cleared TGM3 (World rule, Shirase gold 1300).", "Tetris Research community member, the author of Techmino.\nPersonal bests: Sprint 25.95 seconds, MPH Sprint 57 seconds, #8 on Jstris leaderboards, X rank on TETR.IO, cleared TGM3 (World rule, Shirase gold 1300).",
"https://space.bilibili.com/225238922", "https://space.bilibili.com/225238922",
@@ -1195,7 +1216,7 @@ return{
{"Circu1ation", {"Circu1ation",
"circu1ation", "circu1ation",
"name", "name",
"One of the top players. First one to achieve sub-20 Sprint in China, X rank on TETR.IO.", "One of the top players. First one to achieve sub-20 40L Sprint in China, X rank on TETR.IO.",
"https://space.bilibili.com/557547205", "https://space.bilibili.com/557547205",
}, },
{"Farter", {"Farter",
@@ -1276,7 +1297,7 @@ return{
"https://space.bilibili.com/109356367", "https://space.bilibili.com/109356367",
}, },
{"ZXC", {"ZXC",
"zxc thtsod", "zxc thtsod flag ctf",
"name", "name",
"Also known as ThTsOd.\nTetris Research community member.\nA technical player.", "Also known as ThTsOd.\nTetris Research community member.\nA technical player.",
"https://space.bilibili.com/4610502", "https://space.bilibili.com/4610502",
@@ -1300,7 +1321,7 @@ return{
"https://space.bilibili.com/471341780", "https://space.bilibili.com/471341780",
}, },
{"思竣", {"思竣",
"sijun", "sijun acm oi",
"name", "name",
"(Sī Jùn)\n\nTetris Research community member.\nLots of mental computation power.", "(Sī Jùn)\n\nTetris Research community member.\nLots of mental computation power.",
"https://space.bilibili.com/403250559", "https://space.bilibili.com/403250559",

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,6 @@ return{
loadSample="Loading instrument samples", loadSample="Loading instrument samples",
loadVoice="Loading voice packs", loadVoice="Loading voice packs",
loadFont="Loading fonts", loadFont="Loading fonts",
loadModeIcon="Loading mode icons",
loadMode="Loading modes", loadMode="Loading modes",
loadOther="Loading other assets", loadOther="Loading other assets",
finish="Press any key to start!", finish="Press any key to start!",
@@ -138,7 +137,8 @@ return{
chatStart="------Beginning of log------", chatStart="------Beginning of log------",
chatHistory="------New messages below------", chatHistory="------New messages below------",
keySettingInstruction="Press to bind key\nescape: cancel\nbackspace: delete", searchModeHelp="Type to search",
keySettingHelp="Press to bind key\nescape: cancel\nbackspace: delete",
customBGhelp="Drop image file here to apply custom background", customBGhelp="Drop image file here to apply custom background",
customBGloadFailed="Unsupport image format for custom background", customBGloadFailed="Unsupport image format for custom background",
@@ -252,9 +252,8 @@ return{
sprint="Sprint", sprint="Sprint",
marathon="Marathon", marathon="Marathon",
}, },
mode={ modeExplorer={
mod="Mods (F1)", mod="Mods (F1)",
start="Start",
}, },
mod={ mod={
title="Mods", title="Mods",
@@ -713,6 +712,7 @@ return{
['master_final']= {"Master", "FINAL", "20G and beyond"}, ['master_final']= {"Master", "FINAL", "20G and beyond"},
['master_ph']= {"Master", "PHANTASM", "???"}, ['master_ph']= {"Master", "PHANTASM", "???"},
['master_ex']= {"GrandMaster", "EXTRA", "An eternity shorter than an instant"}, ['master_ex']= {"GrandMaster", "EXTRA", "An eternity shorter than an instant"},
['master_instinct']={"Master", "INSTINCT", "What if the active piece turned invisible?"},
['strategy_e']= {"Strategy", "EASY", "Fast 20G decision"}, ['strategy_e']= {"Strategy", "EASY", "Fast 20G decision"},
['strategy_h']= {"Strategy", "HARD", "Fast 20G decision"}, ['strategy_h']= {"Strategy", "HARD", "Fast 20G decision"},
['strategy_u']= {"Strategy", "ULTIMATE", "Fast 20G decision"}, ['strategy_u']= {"Strategy", "ULTIMATE", "Fast 20G decision"},
@@ -850,9 +850,9 @@ return{
"Soon you'll be able to play against friends and foes all over the world.", "Soon you'll be able to play against friends and foes all over the world.",
"Split clear coming soon!", "Split clear coming soon!",
"sudo rm -rf /*", "sudo rm -rf /*",
"Techmino is a combination of Technique and Tetromino.", "Techmino is a portmanteau of \"technique\" and \"tetromino\".",
"Techmino has a Nspire-CX edition!",
"Techmino is so fun!", "Techmino is so fun!",
"Techmino on Nspire-CX: yes it exists, no it's not the same game.",
"TetroDictionary is now available in English.", "TetroDictionary is now available in English.",
"Most of the music tracks in this game are made using Beepbox.", "Most of the music tracks in this game are made using Beepbox.",
"The names that appeared in the background of the Staff page is a list of our sponsors.", "The names that appeared in the background of the Staff page is a list of our sponsors.",
@@ -874,7 +874,7 @@ return{
"You can connect a keyboard to your phone or tablet (not functional on iOS though).", "You can connect a keyboard to your phone or tablet (not functional on iOS though).",
"You can customize the key mappings in settings!", "You can customize the key mappings in settings!",
"You can open the save directory from the Stats page.", "You can open the save directory from the Stats page.",
"You can perform a spin with 28 of the 29 minoes in this game; the exception being O1.", "You can perform a spin with all of the minoes in this game.",
"You can set the spawning orientation for each piece.", "You can set the spawning orientation for each piece.",
"ZS JL T O I", "ZS JL T O I",
{C.C,"Also try 15puzzle!"}, {C.C,"Also try 15puzzle!"},

View File

@@ -1,25 +1,25 @@
return{ return{
fallback='en', fallback='en',
sureQuit="Pulsa de nuevo para salir", sureQuit="Pulsa de nuevo para salir",
-- sureReset="Press again to reset", sureReset="Pulsa de nuevo para reiniciar",
-- sureDelete="Press again to delete", sureDelete="Pulsa de nuevo para borrar",
newDay="[Anti-adicción] ¡Nuevo día, nuevo comienzo!", 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.", 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.", playedTooMuch="[Anti-adicción] ¡Has jugado mucho por hoy! No puedes jugar más.",
-- settingWarn="Modifing uncommon setting, be careful!", settingWarn="¡Ten cuidado con modificar esto!",
atkModeName={"Al azar","Medallas","KOs","Atacantes"}, atkModeName={"Al azar","Medallas","KOs","Atacantes"},
royale_remain="$1 Jugadores Restantes", royale_remain="$1 Jugadores Restantes",
cmb={nil,"Combo de 1","Combo de 2","Combo de 3","Combo de 4","Combo de 5","Combo de 6","Combo de 7","Combo de 8","Combo de 9","¡Combo de 10!","¡Combo de 11!","¡Combo de 12!","¡Combo de 13!","¡Combo de 14!","¡Combo de 15!","¡Combo de 16!","¡Combo de 17!","¡Combo de 18!","¡Combo de 19!","MEGACOMBO"}, cmb={nil,"Combo de 1","Combo de 2","Combo de 3","Combo de 4","Combo de 5","Combo de 6","Combo de 7","Combo de 8","Combo de 9","¡Combo de 10!","¡Combo de 11!","¡Combo de 12!","¡Combo de 13!","¡Combo de 14!","¡Combo de 15!","¡Combo de 16!","¡Combo de 17!","¡Combo de 18!","¡Combo de 19!","MEGACOMBO"},
spin="-spin", spin="-spin",
clear={"Single","Doble","Triple","Techrash","Pentacrash","Hexacrash","Heptacrash","Octacrash","Nonacrash","Decacrash","Undecacrash","Dodecacrash","Tridecacrash","Tetradecacrash","Pentadecacrash","Hexadecacrash","Heptadecacrash","Octadecacrash","Nonadecacrash","Ultracrash","Impossicrash"}, clear={"Single","Doble","Triple","Techrash","Pentacrash","Hexacrash","Heptacrash","Octacrash","Nonacrash","Decacrash","Undecacrash","Dodecacrash","Tridecacrash","Tetradecacrash","Pentadecacrash","Hexadecacrash","Heptadecacrash","Octadecacrash","Nonadecacrash","Ultracrash","Impossicrash"},
-- cleared="$1 lines", cleared="$1 líneas",
mini="Mini",b2b="B2B ",b3b="B2B2B ", mini="Mini",b2b="B2B ",b3b="B2B2B ",
PC="Perfect Clear",HPC="Half Clear", PC="Perfect Clear",HPC="Half Clear",
replaying="[Repetición]", replaying="[Repetición]",
tasUsing="[TAS]", tasUsing="[TAS]",
-- stage="Stage $1 completed", stage="Fase $1 Completada",
great="¡Genial!", great="¡Genial!",
awesome="¡Fantástico!", awesome="¡Fantástico!",
almost="¡Casi!", almost="¡Casi!",
@@ -28,7 +28,7 @@ return{
speedup="¡Más rápido!", speedup="¡Más rápido!",
missionFailed="Misión Fallida", missionFailed="Misión Fallida",
speedLV="Vel. de juego", speedLV="Veloc. de juego",
piece="Piezas",line="Líneas",atk="Ataque",eff="Eficiencia", piece="Piezas",line="Líneas",atk="Ataque",eff="Eficiencia",
rpm="RPM",tsd="TSD", rpm="RPM",tsd="TSD",
grade="Grado",techrash="Techrash", grade="Grado",techrash="Techrash",
@@ -50,25 +50,25 @@ return{
page="Página:", page="Página:",
-- cc_fixed="CC is incompatible with fixed sequences", cc_fixed="CC no es compatible con piezas prefijadas",
-- cc_swap="CC is incompatible with swap holdmode", cc_swap="CC no es compatible con Swap Hold",
ai_prebag="La IA no es compatible con piezas que no sean Tetrominos.", ai_prebag="La IA no es compatible con piezas que no sean Tetrominos.",
ai_mission="La IA no es compatible con misiones personalizadas.", ai_mission="La IA no es compatible con misiones personalizadas.",
switchSpawnSFX="Habilita los sonidos de aparición de las piezas ;)", switchSpawnSFX="Habilita los sonidos de aparición de las piezas ;)",
needRestart="Reinicia Techmino para que los cambios tengan efecto.", needRestart="Reinicia Techmino para que los cambios tengan efecto.",
-- loadError_errorMode="'$1' loading failed: no load mode '$2'", loadError_errorMode="'$1' Error al cargar: no hay modo '$2'",
-- loadError_read="'$1' loading failed: read failed", loadError_read="'$1' Error al cargar: error de lectura",
-- loadError_noFile="'$1' loading failed no file:", loadError_noFile="'$1' Error al cargar, no existe el archivo:",
-- loadError_other="'$1' loading failed: $2", loadError_other="'$1' Error al cargar: $2",
-- loadError_unknown="'$1' loading failed: unknown reason", loadError_unknown="'$1' Error al cargar: desconocido",
-- saveError_duplicate="'$1' saving failed: duplicated filename", saveError_duplicate="'$1' Error al guardar: archivo duplicado",
-- saveError_encode="'$1' saving failed: encode failed", saveError_encode="'$1' Error al guardar: error de encoding",
-- saveError_other="'$1' saving failed: $2", saveError_other="'$1' Error al guardar: $2",
-- saveError_unknown="'$1' saving failed: unknown reason", saveError_unknown="'$1' Error al guardar: desconocido",
-- copyDone="Copied!", copyDone="¡Copiado con éxito!",
saveDone="Datos guardados", saveDone="Datos guardados",
exportSuccess="Exportado con éxito", exportSuccess="Exportado con éxito",
importSuccess="Importado con éxito", importSuccess="Importado con éxito",
@@ -90,7 +90,7 @@ return{
replayBroken="No se puede cargar la repetición", replayBroken="No se puede cargar la repetición",
-- dictNote="==Copied from TetroDictionary==", dictNote="==Copia de TetroDictionary==",
getNoticeFail="Error al buscar novedades.", getNoticeFail="Error al buscar novedades.",
oldVersion="¡Está disponible la nueva versión $1!", oldVersion="¡Está disponible la nueva versión $1!",
@@ -127,12 +127,13 @@ return{
chatStart="------Comienzo del historial------", chatStart="------Comienzo del historial------",
chatHistory="------Nuevos mensajes------", chatHistory="------Nuevos mensajes------",
-- keySettingInstruction="Press to bind key\nescape: cancel\nbackspace: delete", -- searchModeHelp="Type to search",
-- customBGhelp="Drop image file here to apply custom background", keySettingHelp="Pulsa la tecla a mapear\nEsc.: Cancelar\nBackspace: Borrar",
-- customBGloadFailed="Unsupport image format for custom background", customBGhelp="Suelta una imagen aquí para aplicarla de fondo",
customBGloadFailed="Formato de imagen no soportado",
errorMsg="Ha ocurrido un error y Techmino necesita reiniciarse.\nSe creó un registro de error, puedes enviarlo al autor.", errorMsg="Ha ocurrido un error y Techmino necesita reiniciarse.\nSe creó un registro de error, puedes enviarlo al autor.",
-- tryAnotherBuild="[Invalid UTF-8] If you are on Windows, try downloading Techmino-win32 or Techmino-win64 (different from what you are using now).", tryAnotherBuild="[UTF-8 Inválido] Si estás usando Windows, intenta descargar Techmino-win32 o Techmino-win64 (el que no estés usando ahora).",
-- modInstruction="", -- modInstruction="",
-- modInfo={},--See lang_en.lua -- modInfo={},--See lang_en.lua
@@ -173,7 +174,7 @@ return{
"Descargas desde otros sitios pueden contener malware/viruses, y en smartphones sólo requiere permisos de internet y vibración.", "Descargas desde otros sitios pueden contener malware/viruses, y en smartphones sólo requiere permisos de internet y vibración.",
"El autor no se responabiliza por daños ocasionados debido a modificaciones del juego.", "El autor no se responabiliza por daños ocasionados debido a modificaciones del juego.",
FNNS and"/"or"Por favor descarga las últimas versiones desde los sitios oficiales. El juego es gratuito", FNNS and"/"or"Por favor descarga las últimas versiones desde los sitios oficiales. El juego es gratuito",
-- FNNS and"/"or"Check Zictionary for more", FNNS and"/"or"Ve el Zictionary (en inglés) para más info",
}, },
staff={ staff={
"Autor:MrZ Email: 1046101471@qq.com", "Autor:MrZ Email: 1046101471@qq.com",
@@ -218,9 +219,8 @@ return{
sprint="Sprint", sprint="Sprint",
marathon="Maratón", marathon="Maratón",
}, },
mode={ modeExplorer={
mod="Mods (F1)", mod="Mods (F1)",
start="Empezar",
}, },
mod={ mod={
title="Mods", title="Mods",
@@ -273,8 +273,8 @@ return{
lock="Retraso de Bloqueo", lock="Retraso de Bloqueo",
wait="Retraso de Spawneo", wait="Retraso de Spawneo",
fall="Retraso de Línea", fall="Retraso de Línea",
-- hang="Death Delay", hang="Retraso de Muerte",
-- hurry="ARE Interruption", hurry="Interrupc. de ARE",
capacity="Capacidad", capacity="Capacidad",
create="Crear", create="Crear",
@@ -282,14 +282,14 @@ return{
ospin="O-Spin", ospin="O-Spin",
fineKill="100% Finesse", fineKill="100% Finesse",
b2bKill="No Romper B2B ", b2bKill="No Romper B2B ",
-- lockout="Fail when lock out", lockout="Derrota al ocurrir Lock Out",
easyFresh="Reinicio de Bloqueo Normal", easyFresh="Reinicio de Bloqueo Normal",
deepDrop="Deep Drop", deepDrop="Deep Drop",
bone="Bone Block", bone="Bone Block",
-- eventSet="Rule Set", eventSet="Ruleset",
-- holdMode="Hold Mode", holdMode="Modo de Reserva",
nextCount="Siguiente", nextCount="Siguiente",
holdCount="Reserva", holdCount="Reserva",
infHold="Reserva Inft.", infHold="Reserva Inft.",
@@ -298,13 +298,13 @@ return{
net_game={ net_game={
ready="Estoy Listo", ready="Estoy Listo",
spectate="Espectear", spectate="Espectear",
-- cancel="Cancel ready", cancel="Esperar",
}, },
setting_game={ setting_game={
title="Ajustes del Juego", title="Ajustes del Juego",
graphic="←Video", graphic="←Video",
sound="Sonido→", sound="Sonido→",
-- style="Style", style="Estilo",
ctrl="Sensibilidad", ctrl="Sensibilidad",
key="Teclas", key="Teclas",
@@ -313,10 +313,10 @@ return{
reTime="Retraso de Inicio", reTime="Retraso de Inicio",
RS="Sistema de Rotación", RS="Sistema de Rotación",
menuPos="Pos. del Botón de Menú", menuPos="Pos. del Botón de Menú",
-- sysCursor="Use system cursor", sysCursor="Usar cursor del sistema",
autoPause="Pausar cuando la ventana no está enfocada", autoPause="Pausar cuando la ventana no está enfocada",
autoSave="Autograbar Récords", autoSave="Autograbar Récords",
-- autoLogin="Auto Login on Start", autoLogin="Autologueo al Iniciar",
simpMode="Modo Sencillo", simpMode="Modo Sencillo",
}, },
setting_video={ setting_video={
@@ -344,13 +344,13 @@ return{
atkFX="FX Vis. de Ataque", atkFX="FX Vis. de Ataque",
frame="Ratio de FPSs(%)", frame="Ratio de FPSs(%)",
-- FTlock="Frame-Time Lock", FTlock="Bloqueo por frames",
text="Texto de Acciones", text="Texto de Acciones",
score="Puntaje en Pantalla", score="Puntaje en Pantalla",
bufferWarn="Alerta de Búfer", bufferWarn="Alerta de Búfer",
showSpike="Contador de Spike", showSpike="Contador de Spike",
-- nextPos="Spawn Preview", nextPos="Prever Spawn de Pzas.",
highCam="Cám. Vista Aérea", highCam="Cám. Vista Aérea",
warn="Alerta de Peligro", warn="Alerta de Peligro",
@@ -359,9 +359,9 @@ return{
clean="Fast Draw", clean="Fast Draw",
fullscreen="Pant. Completa", fullscreen="Pant. Completa",
-- bg_on="Normal B.G.", bg_on="Fondo Normal",
-- bg_on="No B.G.", bg_off="Sin Fondo",
-- bg_custom="Use Custom B.G.", bg_custom="Fondo Personalizado",
blockSatur="Saturac. de los Bloques", blockSatur="Saturac. de los Bloques",
fieldSatur="Saturac. del Tablero", fieldSatur="Saturac. del Tablero",
@@ -371,7 +371,7 @@ return{
game="←Juego", game="←Juego",
graphic="Video→", graphic="Video→",
-- mainVol="Main Volume", mainVol="Vol. Principal",
bgm="BGM", bgm="BGM",
sfx="SFX", sfx="SFX",
stereo="Estéreo", stereo="Estéreo",
@@ -380,9 +380,9 @@ return{
vib="Vibración", vib="Vibración",
voc="Voces", voc="Voces",
-- autoMute="Mute while unfocused", autoMute="Silenciar cuando la ventana no está enfocada",
fine="Sonido de Error de Finesse", fine="Sonido de Error de Finesse",
-- sfxPack="SFX Pack", sfxPack="Pack de SFX",
vocPack="Pack de Voces", vocPack="Pack de Voces",
apply="Aplicar", apply="Aplicar",
}, },
@@ -460,8 +460,8 @@ return{
lock="Retraso de Bloqueo", lock="Retraso de Bloqueo",
wait="Retraso de Spawneo", wait="Retraso de Spawneo",
fall="Retraso de Línea", fall="Retraso de Línea",
-- hang="Death Delay", hang="Retraso de Muerte",
-- hurry="ARE Interruption", hurry="Interrupc. de ARE",
bg="Fondo", bg="Fondo",
bgm="Música", bgm="Música",
@@ -478,9 +478,9 @@ return{
sequence="Editar Secuencia (S)", sequence="Editar Secuencia (S)",
mission="Editar Misiones (M)", mission="Editar Misiones (M)",
-- eventSet="Rule Set", eventSet="Ruleset",
-- holdMode="Hold Mode", holdMode="Modo de Reserva",
nextCount="Siguiente", nextCount="Siguiente",
holdCount="Reserva", holdCount="Reserva",
infHold="Reserva Inft.", infHold="Reserva Inft.",
@@ -499,7 +499,7 @@ return{
ospin="O-Spin", ospin="O-Spin",
fineKill="100% Finesse", fineKill="100% Finesse",
b2bKill="No Romper B2B ", b2bKill="No Romper B2B ",
-- lockout="Fail when lock out", lockout="Derrota al ocurrir Lock Out",
easyFresh="Reinicio de Bloqueo Normal", easyFresh="Reinicio de Bloqueo Normal",
deepDrop="Deep Drop", deepDrop="Deep Drop",
bone="Bone Block", bone="Bone Block",
@@ -534,7 +534,7 @@ return{
about={ about={
staff="Staff", staff="Staff",
his="Hist. de Acts.", his="Hist. de Acts.",
-- legals="Legals", legals="Legalidades",
}, },
dict={ dict={
title="TetroDictionary", title="TetroDictionary",
@@ -558,7 +558,7 @@ return{
sfx="SFX", sfx="SFX",
voc="Voces", voc="Voces",
music="BGMs", music="BGMs",
-- label="label", label="Etiq.",
}, },
login={ login={
title="Entrar", title="Entrar",
@@ -645,7 +645,7 @@ return{
['dig_100l']= {"Queso", "100L", "Limpia 100 líneas de queso."}, ['dig_100l']= {"Queso", "100L", "Limpia 100 líneas de queso."},
['dig_400l']= {"Queso", "400L", "Limpia 400 líneas de queso."}, ['dig_400l']= {"Queso", "400L", "Limpia 400 líneas de queso."},
['drought_n']= {"Sequía", "100L", "¡Sin piezas I!"}, ['drought_n']= {"Sequía", "100L", "¡Sin piezas I!"},
['drought_l']= {"Sequía+", "100L", "Guat de foc..."}, ['drought_l']= {"Sequía+", "100L", "Qué es esto..."},
['marathon_n']= {"Maratón", "Normal", "Maratón de 200 líneas con velocidad en aumento."}, ['marathon_n']= {"Maratón", "Normal", "Maratón de 200 líneas con velocidad en aumento."},
['marathon_h']= {"Maratón", "Difícil", "Maratón de 200 líneas a velocidad máxima."}, ['marathon_h']= {"Maratón", "Difícil", "Maratón de 200 líneas a velocidad máxima."},
['solo_e']= {"VS.", "Fácil", "¡Derrota a la CPU!"}, ['solo_e']= {"VS.", "Fácil", "¡Derrota a la CPU!"},
@@ -653,12 +653,12 @@ return{
['solo_h']= {"VS.", "Difícil", "¡Derrota a la CPU!"}, ['solo_h']= {"VS.", "Difícil", "¡Derrota a la CPU!"},
['solo_l']= {"VS.", "Lunático", "¡Derrota a la CPU!"}, ['solo_l']= {"VS.", "Lunático", "¡Derrota a la CPU!"},
['solo_u']= {"VS.", "Supremo", "¡Derrota a la CPU!"}, ['solo_u']= {"VS.", "Supremo", "¡Derrota a la CPU!"},
['techmino49_e']= {"Tech 49", "Fácil", "Batalla de 49 jugadores. ¡El último en pie gana!"}, ['techmino49_e']= {"Tech 49", "Fácil", "Batalla de 49 jugadores.\n¡El último en pie gana!"},
['techmino49_h']= {"Tech 49", "Difícil", "Batalla de 49 jugadores. ¡El último en pie gana!"}, ['techmino49_h']= {"Tech 49", "Difícil", "Batalla de 49 jugadores.\n¡El último en pie gana!"},
['techmino49_u']= {"Tech 49", "Supremo", "Batalla de 49 jugadores. ¡El último en pie gana!"}, ['techmino49_u']= {"Tech 49", "Supremo", "Batalla de 49 jugadores.\n¡El último en pie gana!"},
['techmino99_e']= {"Tech 99", "Fácil", "Batalla de 99 jugadores. ¡El último en pie gana!"}, ['techmino99_e']= {"Tech 99", "Fácil", "Batalla de 99 jugadores.\n¡El último en pie gana!"},
['techmino99_h']= {"Tech 99", "Difícil", "Batalla de 99 jugadores. ¡El último en pie gana!"}, ['techmino99_h']= {"Tech 99", "Difícil", "Batalla de 99 jugadores.\n¡El último en pie gana!"},
['techmino99_u']= {"Tech 99", "Supremo", "Batalla de 99 jugadores. ¡El último en pie gana!"}, ['techmino99_u']= {"Tech 99", "Supremo", "Batalla de 99 jugadores.\n¡El último en pie gana!"},
['round_e']= {"Por Turnos", "Fácil", "Modo ajedrez."}, ['round_e']= {"Por Turnos", "Fácil", "Modo ajedrez."},
['round_n']= {"Por Turnos", "Normal", "Modo ajedrez."}, ['round_n']= {"Por Turnos", "Normal", "Modo ajedrez."},
['round_h']= {"Por Turnos", "Difícil", "Modo ajedrez."}, ['round_h']= {"Por Turnos", "Difícil", "Modo ajedrez."},
@@ -666,15 +666,15 @@ return{
['round_u']= {"Por Turnos", "Supremo", "Modo ajedrez."}, ['round_u']= {"Por Turnos", "Supremo", "Modo ajedrez."},
['master_n']= {"Master", "Normal", "Para principiantes en 20G"}, ['master_n']= {"Master", "Normal", "Para principiantes en 20G"},
['master_h']= {"Master", "Difícil", "¡Desafío profesional de 20G!"}, ['master_h']= {"Master", "Difícil", "¡Desafío profesional de 20G!"},
-- ['master_m']= {"Master", "M21", "For 20G Masters."}, ['master_m']= {"Master", "M21", "Para Maestros del 20G."},
['master_final']= {"Master", "FINAL", "El verdadero 20G Supremo: el final es inalcanzable."}, ['master_final']= {"Master", "FINAL", "El verdadero 20G Supremo:\nel final es inalcanzable."},
['master_ex']= {"GrandMaster", "EXTRA", "Para ser un gran maestro, acepta este desafío"}, ['master_ex']= {"GrandMaster", "EXTRA", "Para ser un gran maestro,\nacepta este desafío"},
['strategy_e']= {"Strategy", "EASY", "Fast 20G decision"}, ['strategy_e']= {"Strategy", "EASY", "Decisiones rápidas en 20G."},
['strategy_h']= {"Strategy", "HARD", "Fast 20G decision"}, ['strategy_h']= {"Strategy", "HARD", "Decisiones rápidas en 20G."},
['strategy_u']= {"Strategy", "ULTIMATE", "Fast 20G decision"}, ['strategy_u']= {"Strategy", "ULTIMATE", "Decisiones rápidas en 20G."},
-- ['strategy_e_plus']={"Strategi", "MUDAH+", "Keputusan 20G cepat"}, ['strategy_e_plus']={"Strategi", "MUDAH+", "Decisiones rápidas en 20G."},
-- ['strategy_h_plus']={"Strategi", "SULIT+", "Keputusan 20G cepat"}, ['strategy_h_plus']={"Strategi", "SULIT+", "Decisiones rápidas en 20G."},
-- ['strategy_u_plus']={"Strategi", "TERAKHIR+", "Keputusan 20G cepat"}, ['strategy_u_plus']={"Strategi", "TERAKHIR+", "Decisiones rápidas en 20G."},
['blind_e']= {"A Ciegas", "Parcial", "Para novatos."}, ['blind_e']= {"A Ciegas", "Parcial", "Para novatos."},
['blind_n']= {"A Ciegas", "Total", "Para jugadores intermedios."}, ['blind_n']= {"A Ciegas", "Total", "Para jugadores intermedios."},
['blind_h']= {"A Ciegas", "Inmediato", "Para jugadores experimentados"}, ['blind_h']= {"A Ciegas", "Inmediato", "Para jugadores experimentados"},
@@ -695,7 +695,7 @@ return{
['defender_l']= {"Defensor", "Lunático", "¡Practica la defensa!"}, ['defender_l']= {"Defensor", "Lunático", "¡Practica la defensa!"},
['dig_h']= {"Downstack", "Difícil", "¡Practica el downstackeo!"}, ['dig_h']= {"Downstack", "Difícil", "¡Practica el downstackeo!"},
['dig_u']= {"Downstack", "Supremo", "¡Practica el downstackeo!"}, ['dig_u']= {"Downstack", "Supremo", "¡Practica el downstackeo!"},
-- ['clearRush']= {"Clear Rush", "NORMAL", "All-spin tutorial!\n[Under construction]"}, ['clearRush']= {"Clear Rush", "NORMAL", "¡Tutorial de Allspins!\n[En construcción]"},
['c4wtrain_n']= {"Entrenar C4W", "Normal", "Combos infinitos."}, ['c4wtrain_n']= {"Entrenar C4W", "Normal", "Combos infinitos."},
['c4wtrain_l']= {"Entrenar C4W", "Lunático", "Combos infinitos."}, ['c4wtrain_l']= {"Entrenar C4W", "Lunático", "Combos infinitos."},
['pctrain_n']= {"Entrenar PC", "Normal", "Modo sencillo para practicar Perfect Clears."}, ['pctrain_n']= {"Entrenar PC", "Normal", "Modo sencillo para practicar Perfect Clears."},
@@ -711,7 +711,7 @@ return{
['tech_l']= {"Tech", "Lunático", "¡Mantén el B2B!"}, ['tech_l']= {"Tech", "Lunático", "¡Mantén el B2B!"},
['tech_l_plus']= {"Tech", "Lunático+", "¡Sólo se permiten Spins y PCs!"}, ['tech_l_plus']= {"Tech", "Lunático+", "¡Sólo se permiten Spins y PCs!"},
['tech_finesse']= {"Tech", "Finesse", "¡No cometas errores de Finesse!"}, ['tech_finesse']= {"Tech", "Finesse", "¡No cometas errores de Finesse!"},
['tech_finesse_f']= {"Tech", "Finesse+", "Sin errores de finesse, ¡pero tampoco clears normales!"}, ['tech_finesse_f']= {"Tech", "Finesse+", "Sin errores de finesse,\n¡pero tampoco clears normales!"},
['tsd_e']= {"Desafío de TSD", "Fácil", "¡Sólo se permiten T-Spin Dobles!"}, ['tsd_e']= {"Desafío de TSD", "Fácil", "¡Sólo se permiten T-Spin Dobles!"},
['tsd_h']= {"Desafío de TSD", "Difícil", "¡Sólo se permiten T-Spin Dobles!"}, ['tsd_h']= {"Desafío de TSD", "Difícil", "¡Sólo se permiten T-Spin Dobles!"},
['tsd_u']= {"Desafío de TSD", "Supremo", "¡Sólo se permiten T-Spin Dobles!"}, ['tsd_u']= {"Desafío de TSD", "Supremo", "¡Sólo se permiten T-Spin Dobles!"},
@@ -720,7 +720,7 @@ return{
['backfire_l']= {"Retorno", "Lunático", "Lidia con tus propias líneas basura."}, ['backfire_l']= {"Retorno", "Lunático", "Lidia con tus propias líneas basura."},
['backfire_u']= {"Retorno", "Supremo", "Lidia con tus propias líneas basura."}, ['backfire_u']= {"Retorno", "Supremo", "Lidia con tus propias líneas basura."},
['sprintAtk']= {"Sprint", "100L - Ataque", "¡Envía 100 líneas de ataque!"}, ['sprintAtk']= {"Sprint", "100L - Ataque", "¡Envía 100 líneas de ataque!"},
-- ['sprintEff']= {"Sprint", "Efficiency", "Send more attack in 40lines!"}, ['sprintEff']= {"Sprint", "Efficiency", "¡Envía ataque eficiente en 40neas!"},
['zen']= {'Zen', "200L", "200 líneas sin límite de tiempo."}, ['zen']= {'Zen', "200L", "200 líneas sin límite de tiempo."},
['ultra']= {'Ultra', "Extra", "¡Consigue el mayor puntaje posible en 2 minutos!"}, ['ultra']= {'Ultra', "Extra", "¡Consigue el mayor puntaje posible en 2 minutos!"},
['infinite']= {"Infinito", "", "Modo Sandbox."}, ['infinite']= {"Infinito", "", "Modo Sandbox."},

View File

@@ -128,7 +128,8 @@ return{
chatStart="--------Début des logs--------", chatStart="--------Début des logs--------",
chatHistory="-Nouveaux messages en dessous-", chatHistory="-Nouveaux messages en dessous-",
-- keySettingInstruction="Press to bind key\nescape: cancel\nbackspace: delete", -- searchModeHelp="Type to search",
-- keySettingHelp="Press to bind key\nescape: cancel\nbackspace: delete",
-- customBGhelp="Drop image file here to apply custom background", -- customBGhelp="Drop image file here to apply custom background",
-- customBGloadFailed="Unsupport image format for custom background", -- customBGloadFailed="Unsupport image format for custom background",
@@ -214,9 +215,8 @@ return{
dict="Zictionary", dict="Zictionary",
-- replays="Replays", -- replays="Replays",
}, },
mode={ modeExplorer={
mod="Mods (F1)", mod="Mods (F1)",
start="Démarrer",
}, },
mod={ mod={
title="Mods", title="Mods",
@@ -357,7 +357,7 @@ return{
fullscreen="Plein écran", fullscreen="Plein écran",
-- bg_on="Normal B.G.", -- bg_on="Normal B.G.",
-- bg_on="No B.G.", -- bg_off="No B.G.",
-- bg_custom="Use Custom B.G.", -- bg_custom="Use Custom B.G.",
-- blockSatur="Block Saturation", -- blockSatur="Block Saturation",
@@ -714,7 +714,7 @@ return{
['tech_l']= {"Tech", "LUNATIQUE", "Gardez le B2B !"}, ['tech_l']= {"Tech", "LUNATIQUE", "Gardez le B2B !"},
['tech_l_plus']= {"Tech", "LUNATIQUE+", "Spin & PC uniquement"}, ['tech_l_plus']= {"Tech", "LUNATIQUE+", "Spin & PC uniquement"},
['tech_finesse']= {"Tech", "FINESSE", "Pas d'erreurs de finesse !"}, ['tech_finesse']= {"Tech", "FINESSE", "Pas d'erreurs de finesse !"},
['tech_finesse_f']={"Tech", "FINESSE+", "Pas de nettoyages normaux, Pas d'erreurs de finesse !"}, ['tech_finesse_f']={"Tech", "FINESSE+", "Pas de nettoyages normaux,\nPas d'erreurs de finesse !"},
['tsd_e']= {"TSD Challenge", "FACILE", "T-spin doubles uniquement !"}, ['tsd_e']= {"TSD Challenge", "FACILE", "T-spin doubles uniquement !"},
['tsd_h']= {"TSD Challenge", "DIFFICILE", "T-spin doubles uniquement !"}, ['tsd_h']= {"TSD Challenge", "DIFFICILE", "T-spin doubles uniquement !"},
['tsd_u']= {"TSD Challenge", "ULTIME", "T-spin doubles uniquement !"}, ['tsd_u']= {"TSD Challenge", "ULTIME", "T-spin doubles uniquement !"},

View File

@@ -1,11 +1,11 @@
local C=COLOR local C=COLOR
return{ return{
fallback='en',
loadText={ loadText={
loadSFX="Memuat efek suara", loadSFX="Memuat efek suara",
loadSample="Memuat sampel-sampel instrumen", loadSample="Memuat sampel-sampel instrumen",
loadVoice="Memuat kumpulan suara", loadVoice="Memuat kumpulan suara",
loadFont="Memuat fon", loadFont="Memuat fon",
loadModeIcon="Memuat ikon-ikon mode",
loadMode="Memuat mode-mode", loadMode="Memuat mode-mode",
loadOther="Memuat aset-aset yang lain", loadOther="Memuat aset-aset yang lain",
finish="Tekan tombol apapun untuk memulai!", finish="Tekan tombol apapun untuk memulai!",
@@ -138,7 +138,8 @@ return{
chatStart="------Awal percakapan------", chatStart="------Awal percakapan------",
chatHistory="------Pesan-pesan baru di bawah ini------", chatHistory="------Pesan-pesan baru di bawah ini------",
keySettingInstruction="Tekan untuk menghubung tombol ke aksi tertentu\nescape: batal\nbackspace: hapus", -- searchModeHelp="Type to search",
keySettingHelp="Tekan untuk menghubung tombol ke aksi tertentu\nescape: batal\nbackspace: hapus",
customBGhelp="Seret file gambar di sini untuk memasangkan background", customBGhelp="Seret file gambar di sini untuk memasangkan background",
customBGloadFailed="Format file gambar tidak didukung untuk background", customBGloadFailed="Format file gambar tidak didukung untuk background",
@@ -252,9 +253,8 @@ return{
sprint="Balapan", sprint="Balapan",
marathon="Maraton", marathon="Maraton",
}, },
mode={ modeExplorer={
mod="Mod (F1)", mod="Mod (F1)",
start="Mulai",
}, },
mod={ mod={
title="Mod", title="Mod",
@@ -713,6 +713,7 @@ return{
['master_final']= {"Jago", "TERAKHIR", "Lebih dari 20G"}, ['master_final']= {"Jago", "TERAKHIR", "Lebih dari 20G"},
['master_ph']= {"Jago", "KHAYALAN", "???"}, ['master_ph']= {"Jago", "KHAYALAN", "???"},
['master_ex']= {"Sangat Jago", "EKSTRA", "Blok tidak kelihatan"}, ['master_ex']= {"Sangat Jago", "EKSTRA", "Blok tidak kelihatan"},
['master_instinct']={"Jago", "INSTINK", "Bagaimana jika blok terkontrol tersembunyi?"},
['strategy_e']= {"Strategi", "MUDAH", "Keputusan 20G cepat"}, ['strategy_e']= {"Strategi", "MUDAH", "Keputusan 20G cepat"},
['strategy_h']= {"Strategi", "SULIT", "Keputusan 20G cepat"}, ['strategy_h']= {"Strategi", "SULIT", "Keputusan 20G cepat"},
['strategy_u']= {"Strategi", "TERAKHIR", "Keputusan 20G cepat"}, ['strategy_u']= {"Strategi", "TERAKHIR", "Keputusan 20G cepat"},

View File

@@ -126,7 +126,8 @@ return{
chatStart="------Começo do log------", chatStart="------Começo do log------",
chatHistory="------Novas mensagens abaixo------", chatHistory="------Novas mensagens abaixo------",
-- keySettingInstruction="Press to bind key\nescape: cancel\nbackspace: delete", -- searchModeHelp="Type to search",
-- keySettingHelp="Press to bind key\nescape: cancel\nbackspace: delete",
-- customBGhelp="Drop image file here to apply custom background", -- customBGhelp="Drop image file here to apply custom background",
-- customBGloadFailed="Unsupport image format for custom background", -- customBGloadFailed="Unsupport image format for custom background",
@@ -240,9 +241,8 @@ return{
sprint="Sprint", sprint="Sprint",
marathon="Maratona", marathon="Maratona",
}, },
mode={ modeExplorer={
mod="Mods (F1)", mod="Mods (F1)",
start="Começar",
}, },
mod={ mod={
title="Mods", title="Mods",
@@ -382,7 +382,7 @@ return{
fullscreen="Tela cheia", fullscreen="Tela cheia",
-- bg_on="Normal B.G.", -- bg_on="Normal B.G.",
-- bg_on="No B.G.", -- bg_off="No B.G.",
-- bg_custom="Use Custom B.G.", -- bg_custom="Use Custom B.G.",
-- blockSatur="Block Saturation", -- blockSatur="Block Saturation",
@@ -745,7 +745,7 @@ return{
['tech_l']= {"Tech", "LUNÁTICO", "Não quebre o B2B!"}, ['tech_l']= {"Tech", "LUNÁTICO", "Não quebre o B2B!"},
['tech_l_plus']= {"Tech", "LUNÁTICO+", "Apenas spins e PC"}, ['tech_l_plus']= {"Tech", "LUNÁTICO+", "Apenas spins e PC"},
['tech_finesse']= {"Tech", "FINESSE", "Não erre a destreza!"}, ['tech_finesse']= {"Tech", "FINESSE", "Não erre a destreza!"},
['tech_finesse_f']= {"Tech", "FINESSE+", "Sem limpas normais, não erre a destreza!"}, ['tech_finesse_f']= {"Tech", "FINESSE+", "Sem limpas normais,\nnão erre a destreza!"},
['tsd_e']= {"Desafio TSD", "FÁCIL", "Apenas T-spin-doubles!"}, ['tsd_e']= {"Desafio TSD", "FÁCIL", "Apenas T-spin-doubles!"},
['tsd_h']= {"Desafio TSD", "DIFÍCIL", "Apenas T-spin-doubles!"}, ['tsd_h']= {"Desafio TSD", "DIFÍCIL", "Apenas T-spin-doubles!"},
['tsd_u']= {"Desafio TSD", "ULTIMATE", "Apenas T-spin-doubles!"}, ['tsd_u']= {"Desafio TSD", "ULTIMATE", "Apenas T-spin-doubles!"},

View File

@@ -6,7 +6,6 @@ return{
loadSample="#~#", loadSample="#~#",
loadVoice="#<()==)#", loadVoice="#<()==)#",
loadFont="#Aa#", loadFont="#Aa#",
loadModeIcon="#[ ]#",
loadMode="#[…]#", loadMode="#[…]#",
loadOther="#…#", loadOther="#…#",
finish="&", finish="&",
@@ -143,9 +142,8 @@ return{
dict="z", dict="z",
replays="=~~~", replays="=~~~",
}, },
mode={ modeExplorer={
mod="?!?!?!(F1)", mod="?!?!?!(F1)",
start="!!!",
}, },
mod={ mod={
title="?!?!?!", title="?!?!?!",

View File

@@ -4,7 +4,6 @@ return{fallback='zh',
loadSample="乐器", loadSample="乐器",
loadVoice="语音", loadVoice="语音",
loadFont="字体", loadFont="字体",
loadModeIcon="模式图标",
loadMode="模式", loadMode="模式",
loadOther="其他", loadOther="其他",
finish="走你", finish="走你",

View File

@@ -5,7 +5,6 @@ return{
loadSample="加载乐器采样", loadSample="加载乐器采样",
loadVoice="加载语音资源", loadVoice="加载语音资源",
loadFont="缓存字体资源", loadFont="缓存字体资源",
loadModeIcon="加载模式图标",
loadMode="加载模式", loadMode="加载模式",
loadOther="加载杂项", loadOther="加载杂项",
finish="按任意键继续", finish="按任意键继续",
@@ -138,7 +137,8 @@ return{
chatStart="------消息的开头------", chatStart="------消息的开头------",
chatHistory="------以上是历史消息------", chatHistory="------以上是历史消息------",
keySettingInstruction="点击添加键位绑定\nesc取消选中\n退格键清空选中", searchModeHelp="直接输入关键词搜索",
keySettingHelp="点击添加键位绑定\nesc取消选中\n退格键清空选中",
customBGhelp="把图片文件拖到这个窗口里使用自定义背景", customBGhelp="把图片文件拖到这个窗口里使用自定义背景",
customBGloadFailed="自定义背景的图片文件格式不支持", customBGloadFailed="自定义背景的图片文件格式不支持",
@@ -252,9 +252,8 @@ return{
sprint="40行", sprint="40行",
marathon="马拉松", marathon="马拉松",
}, },
mode={ modeExplorer={
mod="Mods (F1)", mod="Mods (F1)",
start="开始",
}, },
mod={ mod={
title="Mods", title="Mods",
@@ -712,6 +711,7 @@ return{
['master_final']= {"大师", "终点", "究极20G:无法触及的终点"}, ['master_final']= {"大师", "终点", "究极20G:无法触及的终点"},
['master_ph']= {"大师", "虚幻", "虚幻20G:"}, ['master_ph']= {"大师", "虚幻", "虚幻20G:"},
['master_ex']= {"宗师", "EX", "成为方块大师"}, ['master_ex']= {"宗师", "EX", "成为方块大师"},
['master_instinct']={"大师", "本能", "隐藏当前块"},
['strategy_e']= {"策略堆叠", "简单", "20G堆叠中速决策练习"}, ['strategy_e']= {"策略堆叠", "简单", "20G堆叠中速决策练习"},
['strategy_h']= {"策略堆叠", "困难", "20G堆叠快速决策练习"}, ['strategy_h']= {"策略堆叠", "困难", "20G堆叠快速决策练习"},
['strategy_u']= {"策略堆叠", "极限", "20G堆叠极速决策练习"}, ['strategy_u']= {"策略堆叠", "极限", "20G堆叠极速决策练习"},
@@ -796,6 +796,7 @@ return{
"报时机器人:新的一天开始了", "报时机器人:新的一天开始了",
"本游戏还在测试中,出各种问题都是有可能的哦", "本游戏还在测试中,出各种问题都是有可能的哦",
"本游戏使用精简版字体,可能有些特殊字符不能正确显示", "本游戏使用精简版字体,可能有些特殊字符不能正确显示",
"别催了,在做了!",
"不要大力拍打或滑动哦", "不要大力拍打或滑动哦",
"不要卖弱不要卖弱不要卖弱", "不要卖弱不要卖弱不要卖弱",
"不知道有多少人玩游戏的时候会关心游戏是谁做的", "不知道有多少人玩游戏的时候会关心游戏是谁做的",
@@ -803,9 +804,7 @@ return{
"彩色消除即将到来!", "彩色消除即将到来!",
"草(日本语)", "草(日本语)",
"车万方块是一家(暴论", "车万方块是一家(暴论",
"成就系统在做了!",
"吃键?真的吗?建议回放看看到底按没按到,按了多久", "吃键?真的吗?建议回放看看到底按没按到,按了多久",
"触摸板打osu也很好",
"凑数tip什么时候能站起来", "凑数tip什么时候能站起来",
"打铁.png", "打铁.png",
"打铁", "打铁",
@@ -836,7 +835,6 @@ return{
"混合消除即将到来!", "混合消除即将到来!",
"架空消除即将到来!", "架空消除即将到来!",
"建议使用双手游玩", "建议使用双手游玩",
"据某个群友描述玩了Techmino之后打字速度变快了",
"绝大多数按钮上的图标是调用Unicode私用区里的自制字符实现的", "绝大多数按钮上的图标是调用Unicode私用区里的自制字符实现的",
"科技骨牌 你的创新式块堆栈业务技术管理器", "科技骨牌 你的创新式块堆栈业务技术管理器",
"块东V共荣", "块东V共荣",
@@ -854,8 +852,9 @@ return{
"你今天的人品值是(满分100):"..math.random(100), "你今天的人品值是(满分100):"..math.random(100),
"你们考虑过Z酱的感受吗没有你们只考虑你自己。", "你们考虑过Z酱的感受吗没有你们只考虑你自己。",
"你有一个好", "你有一个好",
"你这场地是金子的还是是金子做的", "你这是金子的还是垃圾行是金子做的",
"你准备好了吗?", "你准备好了吗?",
"配乐是有考虑到模式氛围的哦",
"请谨慎向没有方块经验的玩家推荐,会对本游戏的生存环境造成影响,感谢配合。", "请谨慎向没有方块经验的玩家推荐,会对本游戏的生存环境造成影响,感谢配合。",
"请勿大力敲打设备敲坏了就没有Techmino玩了", "请勿大力敲打设备敲坏了就没有Techmino玩了",
"请勿使用三只手游玩", "请勿使用三只手游玩",
@@ -882,7 +881,6 @@ return{
"物理hold了解一下", "物理hold了解一下",
"希望极简率没事", "希望极简率没事",
"希望你们都能喜欢Z……哦不是喜欢Techmino", "希望你们都能喜欢Z……哦不是喜欢Techmino",
"喜欢本游戏的话可以到应用商店下载",
"享受Tech的特色旋转系统", "享受Tech的特色旋转系统",
"写不出那种很酷的音乐(哭", "写不出那种很酷的音乐(哭",
"要盯着bug不放", "要盯着bug不放",
@@ -898,7 +896,7 @@ return{
"中文方块百科全书tetris.huijiwiki.com", "中文方块百科全书tetris.huijiwiki.com",
"众所周知俄罗斯方块是经典编程练手游戏(", "众所周知俄罗斯方块是经典编程练手游戏(",
"众所周知mac不能拿来玩游戏", "众所周知mac不能拿来玩游戏",
"作业没做完别玩手机", "作业没做完别玩手机",
"作者40行sub26了", "作者40行sub26了",
"作者电脑上装了11个方块", "作者电脑上装了11个方块",
"作者浏览器收藏夹里有6个方块", "作者浏览器收藏夹里有6个方块",
@@ -945,6 +943,26 @@ return{
"Z酱是谁", "Z酱是谁",
"Z酱只是个写代码的懂什么方块", "Z酱只是个写代码的懂什么方块",
"Z块等身抱枕来一个(x", "Z块等身抱枕来一个(x",
"时间碎片[000] 2021/11/21加入这个版块",
"时间碎片[001] V0.0.091726加入TRS旋转系统",
"时间碎片[002] V0.7.9加入O-spin",
"时间碎片[003] V0.7.19加入语音系统",
"时间碎片[004] V0.7.22加入平滑下落",
"时间碎片[005] V0.8.5加入模式地图",
"时间碎片[006] V0.8.19加入五连块",
"时间碎片[007] V0.9.0加入自定义序列和模式",
"时间碎片[008] V0.10.0加入录像回放",
"时间碎片[009] V0.11.1加入小z词典",
"时间碎片[010] V0.12.2加入mod系统",
"时间碎片[011] V0.13.0联网对战测试",
"时间碎片[012] V0.13.2加入任意场地高度",
"时间碎片[013] V0.13.3加入控制台",
"时间碎片[014] V0.14.4加入第一首非Beepbox制作的BGM",
"时间碎片[015] V0.14.5加入第一首社区玩家自制BGM",
"时间碎片[016] V0.15.5加入录像回放菜单",
"时间碎片[017] V0.16.0加入BIRS",
"时间碎片[018] V0.16.2加入打击垫样式的音效室",
"时间碎片[019] V0.17.0加入手柄的摇杆和扳机支持",
"豆知识[001]总共有400多条tip哦", "豆知识[001]总共有400多条tip哦",
"豆知识[002]背景影响游玩?可以去设置关闭", "豆知识[002]背景影响游玩?可以去设置关闭",
"豆知识[003]方块默认出现的方向都是重心在下哦(如果你没乱动设置", "豆知识[003]方块默认出现的方向都是重心在下哦(如果你没乱动设置",
@@ -1047,18 +1065,16 @@ return{
"豆知识[100]Techmino生日不太清楚那就定在2019.6.26吧", "豆知识[100]Techmino生日不太清楚那就定在2019.6.26吧",
"豆知识[101]Techmino有一个简单的节日主题系统", "豆知识[101]Techmino有一个简单的节日主题系统",
"豆知识[102]Techmino有一个Nspire-CX原型版本", "豆知识[102]Techmino有一个Nspire-CX原型版本",
"豆知识[103]请在有一定基础之后再学Tspin不然副作用非常大",
"豆知识[104]新人请千万记住,打好基础,不要太早学那些花里胡哨的。",
"豆知识[105]长时间游戏状态会越来越差!玩久了记得放松一下~",
"健康小贴士[01]玩游戏多眨眼,不然会干眼病", "健康小贴士[01]玩游戏多眨眼,不然会干眼病",
"健康小贴士[02]少玩点游戏,多注意眨眼和休息", "健康小贴士[02]少玩点游戏,多注意眨眼和休息",
"健康小贴士[03]戴耳机(尤其是半入耳式)时音量千万别拉满,不然真的会影响听力(虽然很慢)", "健康小贴士[03]戴耳机(尤其是半入耳式)时音量千万别拉满,不然真的会影响听力(虽然很慢)",
"健康小贴士[04]不要熬夜,真的会猝死", "健康小贴士[04]不要熬夜,真的会猝死",
"健康小贴士[05]长期睡眠不足会引起不可逆的脑损伤(变傻)", "健康小贴士[05]长期睡眠不足会引起不可逆的脑损伤(变傻)",
"Z思辨[01]《教育的力量》", "群友名言[001]“玩了Techmino之后发现打字速度变快了”",
"Z思辨[02]《学习的意义》", "群友名言[002]“我要陪伴着tech一步步成长然后就可以疯狂的享受他”",
"Z思辨[03]《练习的力量》",
"Z思辨[04]《知识的力量》",
"Z思辨[05]《梦想的价值》",
"Z思辨[06]《天赋的力量》",
"Z思辨[07]《游戏的意义》",
"Frt评[01]“成天被夸赞‘好玩’的”", "Frt评[01]“成天被夸赞‘好玩’的”",
"Frt评[02]“可以形成方块圈子小中心话题,同作者一起衍生一些概念与梗的”", "Frt评[02]“可以形成方块圈子小中心话题,同作者一起衍生一些概念与梗的”",
"Frt评[03]“论方块的软工意义(就算这么小个范围内,各种取舍蒙混翻车现象都总会以很易懂的方式出现(”", "Frt评[03]“论方块的软工意义(就算这么小个范围内,各种取舍蒙混翻车现象都总会以很易懂的方式出现(”",
@@ -1086,26 +1102,6 @@ return{
"今日数学[13]sin²α-cos²β=-C(α+β)C(α-β)", "今日数学[13]sin²α-cos²β=-C(α+β)C(α-β)",
"今日数学[14]sin²α-sin²β=S(α+β)S(α-β)", "今日数学[14]sin²α-sin²β=S(α+β)S(α-β)",
"今日数学[15]sin2α=2SαCα", "今日数学[15]sin2α=2SαCα",
"时间碎片[000] 2021/11/21加入这个版块",
"时间碎片[001] V0.0.091726加入TRS旋转系统",
"时间碎片[002] V0.7.9加入O-spin",
"时间碎片[003] V0.7.19加入语音系统",
"时间碎片[004] V0.7.22加入平滑下落",
"时间碎片[005] V0.8.5加入模式地图",
"时间碎片[006] V0.8.19加入五连块",
"时间碎片[007] V0.9.0加入自定义序列和模式",
"时间碎片[008] V0.10.0加入录像回放",
"时间碎片[009] V0.11.1加入小z词典",
"时间碎片[010] V0.12.2加入mod系统",
"时间碎片[011] V0.13.0联网对战测试",
"时间碎片[012] V0.13.2加入任意场地高度",
"时间碎片[013] V0.13.3加入控制台",
"时间碎片[014] V0.14.4加入第一首非Beepbox制作的BGM",
"时间碎片[015] V0.14.5加入第一首社区玩家自制BGM",
"时间碎片[016] V0.15.5加入录像回放菜单",
"时间碎片[017] V0.16.0加入BIRS",
"时间碎片[018] V0.16.2加入打击垫样式的音效室",
"时间碎片[019] V0.17.0加入手柄的摇杆和扳机支持",
"Z哲[01]方块教会我们,合群了就会消失,……", "Z哲[01]方块教会我们,合群了就会消失,……",
"Z哲[02]假如生活欺骗了你,不要悲伤,不要心急,还有块陪着你", "Z哲[02]假如生活欺骗了你,不要悲伤,不要心急,还有块陪着你",
"Z哲[03]……合群了就会消失不合群世界毁灭指game over", "Z哲[03]……合群了就会消失不合群世界毁灭指game over",
@@ -1120,22 +1116,32 @@ return{
"Z哲[12]学习能力很重要,只要你以变强为目的,无论玩游戏学知识都可以很难", "Z哲[12]学习能力很重要,只要你以变强为目的,无论玩游戏学知识都可以很难",
"Z哲[13]游戏确实可以是一种艺术形式,而不一定是纯“玩具”", "Z哲[13]游戏确实可以是一种艺术形式,而不一定是纯“玩具”",
"Z哲[14]不希望激烈的零和竞争充斥整个游戏", "Z哲[14]不希望激烈的零和竞争充斥整个游戏",
"Z哲[15]尝试手动控制圈子规模扩大速度,希望能对维持社区氛围有帮助",
"Z哲[16]圈子大了真的会……吗?我们可以试着做些什么,起码让这个过程慢一点",
"Z思辨[01]《教育的力量》",
"Z思辨[02]《学习的意义》",
"Z思辨[03]《练习的力量》",
"Z思辨[04]《知识的力量》",
"Z思辨[05]《梦想的价值》",
"Z思辨[06]《天赋的力量》",
"Z思辨[07]《游戏的意义》",
"Z思辨[08]《自强与竞争》",
"Z推[01]东方Project好玩",
"Z推[02]Minecraft好玩",
"Z推[03]Osu!好玩!",
"Z推[04]Terraria好玩",
"Z推[05]Celeste好玩",
"Z推[06]World of goo好玩",
"Z推[07]Orzmic好玩",
"Z推[08]噗哟噗哟好玩!",
"Z推[09]Phigros好玩",
"Z推[10]VVVVVV好玩",
"Z推[11]Ballance好玩",
"Z推[12]Zuma好玩",
"Z推[13]魔方好玩!",
"Z推[14]15puzzle好玩",
"Z推[15]扫雷好玩!",
{C.C,"<PURE ",C.P,"MEMORY>"}, {C.C,"<PURE ",C.P,"MEMORY>"},
{C.C,"z推[01]东方Project好玩"},
{C.C,"z推[02]Minecraft好玩"},
{C.C,"z推[03]Osu!好玩!"},
{C.C,"z推[04]Terraria好玩"},
{C.C,"z推[05]Celeste好玩"},
{C.C,"z推[06]World of goo好玩"},
{C.C,"z推[07]Orzmic好玩"},
{C.C,"z推[08]噗哟噗哟好玩!"},
{C.C,"z推[09]Phigros好玩"},
{C.C,"z推[10]VVVVVV好玩"},
{C.C,"z推[11]Ballance好玩"},
{C.C,"z推[12]Zuma好玩"},
{C.C,"z推[13]魔方好玩!"},
{C.C,"z推[14]15puzzle好玩"},
{C.C,"z推[15]扫雷好玩!"},
{C.H,"暂定段位:9"}, {C.H,"暂定段位:9"},
{C.H,"REGRET!!"}, {C.H,"REGRET!!"},
{C.lC,"Xspin",C.Z,"是啥"}, {C.lC,"Xspin",C.Z,"是啥"},
@@ -1149,12 +1155,8 @@ return{
{C.R,"《滥用DMCA》"}, {C.R,"《滥用DMCA》"},
{C.R,"《知识产权法》"}, {C.R,"《知识产权法》"},
{C.R,"本游戏难度上限很高,做好心理准备。"}, {C.R,"本游戏难度上限很高,做好心理准备。"},
{C.R,"不要向不感兴趣的路人推荐!!!!!!!!"},
{C.R,"请在有一定游戏基础之后再学Tspin不然副作用非常大"},
{C.R,"上班时间不许摸鱼打块!"}, {C.R,"上班时间不许摸鱼打块!"},
{C.R,"上课时间不许摸鱼打块!"}, {C.R,"上课时间不许摸鱼打块!"},
{C.R,"新人请千万记住,打好基础,不要太早学那些花里胡哨的。"},
{C.R,"长时间游戏状态会越来越差!玩久了记得放松一下~"},
{C.R,"DD",C.Z,"炮=",C.P,"TS",C.R,"D",C.Z,"+",C.P,"TS",C.R,"D",C.Z,""}, {C.R,"DD",C.Z,"炮=",C.P,"TS",C.R,"D",C.Z,"+",C.P,"TS",C.R,"D",C.Z,""},
{C.R,"DT",C.Z,"炮=",C.P,"TS",C.R,"D",C.Z,"+",C.P,"TS",C.R,"T",C.Z,""}, {C.R,"DT",C.Z,"炮=",C.P,"TS",C.R,"D",C.Z,"+",C.P,"TS",C.R,"T",C.Z,""},
{C.R,"LrL ",C.G,"RlR ",C.B,"LLr ",C.O,"RRl ",C.P,"RRR LLL ",C.C,"FFF ",C.Y,"RfR RRf rFF"}, {C.R,"LrL ",C.G,"RlR ",C.B,"LLr ",C.O,"RRl ",C.P,"RRR LLL ",C.C,"FFF ",C.Y,"RfR RRf rFF"},
@@ -1168,9 +1170,11 @@ return{
{C.Y,"暂定段位:MO"}, {C.Y,"暂定段位:MO"},
{C.Y,"暂定段位:MV"}, {C.Y,"暂定段位:MV"},
{C.Y,"Miya",C.Z," 可爱!"}, {C.Y,"Miya",C.Z," 可爱!"},
{C.Y,"O-spin Triple"}, {C.Y,"O-spin"},
{C.Z,"12",C.C,"",C.Z,""}, {C.Z,"12",C.C,"",C.Z,""},
{C.Z,"效率药水",C.H," 效率提升 (8:00)"}, {C.Z,"堆叠药水",C.H," 堆叠提升 (3:00)"},
{C.Z,"挖掘药水",C.H," 挖掘提升 (8:00)"},
{C.Z,"效率药水",C.H," 效率提升 (3:00)"},
{C.Z,"协调药水",C.H," MD减少 II(1:30)"}, {C.Z,"协调药水",C.H," MD减少 II(1:30)"},
-- "Z酱 可爱!", -- "Z酱 可爱!",
} }

View File

@@ -50,7 +50,7 @@ return{
radar={"","","","","",""}, radar={"","","","","",""},
radarData={"防/分","守/分","攻/分","送/分","行/分","挖/分"}, radarData={"防/分","守/分","攻/分","送/分","行/分","挖/分"},
WidgetText={ WidgetText={
mode={ modeExplorer={
mod="模组(F1)", mod="模组(F1)",
}, },
mod={ mod={
@@ -119,6 +119,7 @@ return{
['master_final']= {"大师", "终点", "究极20G:无法触及的终点"}, ['master_final']= {"大师", "终点", "究极20G:无法触及的终点"},
['master_ph']= {"大师", "虚幻", "虚幻20G:???"}, ['master_ph']= {"大师", "虚幻", "虚幻20G:???"},
['master_ex']= {"宗师", "EX", "成为方块大师"}, ['master_ex']= {"宗师", "EX", "成为方块大师"},
['master_instinct']={"大师", "本能", "隐藏当前块"},
['strategy_e']= {"策略堆叠", "简单", "20G堆叠中速决策练习"}, ['strategy_e']= {"策略堆叠", "简单", "20G堆叠中速决策练习"},
['strategy_h']= {"策略堆叠", "困难", "20G堆叠快速决策练习"}, ['strategy_h']= {"策略堆叠", "困难", "20G堆叠快速决策练习"},
['strategy_u']= {"策略堆叠", "极限", "20G堆叠极速决策练习"}, ['strategy_u']= {"策略堆叠", "极限", "20G堆叠极速决策练习"},

View File

@@ -5,7 +5,6 @@ return{
loadSample="装载仪器样品", loadSample="装载仪器样品",
loadVoice="加载语音包", loadVoice="加载语音包",
loadFont="加载字体", loadFont="加载字体",
loadModeIcon="加载模式图标",
loadMode="加载方式", loadMode="加载方式",
loadOther="加载其他资产", loadOther="加载其他资产",
finish="按任意按钮开始!", finish="按任意按钮开始!",
@@ -136,7 +135,8 @@ return{
chatStart="------日志开始------", chatStart="------日志开始------",
chatHistory="------下面是新消息------", chatHistory="------下面是新消息------",
keySettingInstruction="按绑定键\n退出:取消\n退格:删除", searchModeHelp="键入要搜索的内容",
keySettingHelp="按绑定键\n退出:取消\n退格:删除",
customBGhelp="将图像文件拖放到此处以应用自定义背景", customBGhelp="将图像文件拖放到此处以应用自定义背景",
customBGloadFailed="不支持自定义背景的图像格式", customBGloadFailed="不支持自定义背景的图像格式",
@@ -250,9 +250,9 @@ return{
sprint="冲刺", sprint="冲刺",
marathon="马拉松赛跑", marathon="马拉松赛跑",
}, },
mode={ modeExplorer={
mod="多重器官衰竭(F1)", mod="多重器官衰竭(F1)",
start="开始", sel="选择",
}, },
mod={ mod={
title="多重器官衰竭", title="多重器官衰竭",
@@ -709,7 +709,8 @@ return{
['master_m']= {"主人", "M21", "20克大师赛"}, ['master_m']= {"主人", "M21", "20克大师赛"},
['master_final']= {"主人", "最终", "20G及以上"}, ['master_final']= {"主人", "最终", "20G及以上"},
['master_ph']= {"主人", "幻觉", ""}, ['master_ph']= {"主人", "幻觉", ""},
['master_ex']= {"大师", "额外的", "比瞬间还短的永恒"}, ['master_ex']= {"主人", "额外的", "比瞬间还短的永恒"},
['master_instinct']={"主人", "情绪", "步行的秘密部分"},
['strategy_e']= {"策略堆叠", "简单", "20G堆叠中速决策练习"}, ['strategy_e']= {"策略堆叠", "简单", "20G堆叠中速决策练习"},
['strategy_h']= {"策略堆叠", "困难", "20G堆叠快速决策练习"}, ['strategy_h']= {"策略堆叠", "困难", "20G堆叠快速决策练习"},
['strategy_u']= {"策略堆叠", "极限", "20G堆叠极速决策练习"}, ['strategy_u']= {"策略堆叠", "极限", "20G堆叠极速决策练习"},

View File

@@ -5,7 +5,6 @@ return{
loadSample="加載樂器取樣", loadSample="加載樂器取樣",
loadVoice="加載語音資源", loadVoice="加載語音資源",
loadFont="加載字體資源", loadFont="加載字體資源",
loadModeIcon="加載模式圖標",
loadMode="加載模式", loadMode="加載模式",
loadOther="加載雜項", loadOther="加載雜項",
finish="按任意鍵繼續!", finish="按任意鍵繼續!",
@@ -138,7 +137,8 @@ return{
chatStart="------訊息開始------", chatStart="------訊息開始------",
chatHistory="------以上為歷史訊息------", chatHistory="------以上為歷史訊息------",
keySettingInstruction="點擊來設置鍵位\n按esc來取消選中\n按退格鍵來清除選中", searchModeHelp="直接輸入關鍵字搜索",
keySettingHelp="點擊來設置鍵位\n按esc來取消選中\n按退格鍵來清除選中",
customBGhelp="把圖片檔案拖到這個視窗裏使用自定義背景", customBGhelp="把圖片檔案拖到這個視窗裏使用自定義背景",
customBGloadFailed="自定義背景的圖片檔案格式不支持", customBGloadFailed="自定義背景的圖片檔案格式不支持",
@@ -252,9 +252,8 @@ return{
sprint="40行", sprint="40行",
marathon="馬拉松", marathon="馬拉松",
}, },
mode={ modeExplorer={
mod="Mods (F1)", mod="Mods (F1)",
start="開始",
}, },
mod={ mod={
title="Mods", title="Mods",
@@ -712,6 +711,7 @@ return{
['master_final']= {"大師", "究極", "究極20G:無法觸及的終點"}, ['master_final']= {"大師", "究極", "究極20G:無法觸及的終點"},
['master_ph']= {"大師", "虛幻", "虛幻20G:"}, ['master_ph']= {"大師", "虛幻", "虛幻20G:"},
['master_ex']= {"宗師", "EX", "成為方塊大師"}, ['master_ex']= {"宗師", "EX", "成為方塊大師"},
['master_instinct']={"大師", "本能", "隱藏當前塊"},
['strategy_e']= {"策略堆疊", "簡單", "20G堆疊中速決策練習"}, ['strategy_e']= {"策略堆疊", "簡單", "20G堆疊中速決策練習"},
['strategy_h']= {"策略堆疊", "困難", "20G堆疊快速決策練習"}, ['strategy_h']= {"策略堆疊", "困難", "20G堆疊快速決策練習"},
['strategy_u']= {"策略堆疊", "極限", "20G堆疊極速決策練習"}, ['strategy_u']= {"策略堆疊", "極限", "20G堆疊極速決策練習"},
@@ -724,6 +724,7 @@ return{
['blind_l']= {"隱形", "瞬隱+", "最強大腦"}, ['blind_l']= {"隱形", "瞬隱+", "最強大腦"},
['blind_u']= {"隱形", "啊這", "你準備好了嗎"}, ['blind_u']= {"隱形", "啊這", "你準備好了嗎"},
['blind_wtf']= {"隱形", "不會吧", "還沒準備好"}, ['blind_wtf']= {"隱形", "不會吧", "還沒準備好"},
['blind_inv']= {"隱形", "倒置的", "隱形活動件"},
['classic_e']= {"高速經典", "簡單", "高速經典"}, ['classic_e']= {"高速經典", "簡單", "高速經典"},
['classic_h']= {"高速經典", "困難", "飛速經典"}, ['classic_h']= {"高速經典", "困難", "飛速經典"},
['classic_u']= {"高速經典", "極限", "極速經典"}, ['classic_u']= {"高速經典", "極限", "極速經典"},

163
parts/modeTree.lua Normal file
View File

@@ -0,0 +1,163 @@
return{
{folder=true,name='sprint',
{name='sprint_10l'},
{name='sprint_20l'},
{name='sprint_40l'},
{name='sprint_100l'},
{name='sprint_400l'},
{name='sprint_1000l'},
},
{folder=true,name='marathon',
{name='marathon_n'},
{name='marathon_h'},
{name='master_n'},
{name='master_h'},
{name='master_m'},
{name='master_final'},
{name='master_ph'},
{name='master_ex'},
},
{folder=true,name='dig_sprint',
{name='dig_10l'},
{name='dig_40l'},
{name='dig_100l'},
{name='dig_400l'},
},
{folder=true,name='survival',author='MrZ',
{folder=true,name='survivor',
{name='survivor_e'},
{name='survivor_n'},
{name='survivor_h'},
{name='survivor_l'},
{name='survivor_u'},
},
{folder=true,name='attacker',
{name='attacker_h'},
{name='attacker_u'},
},
{folder=true,name='defender',
{name='defender_n'},
{name='defender_l'},
},
{folder=true,name='dig',
{name='dig_h'},
{name='dig_u'},
},
},
{folder=true,name='battle',
{folder=true,name='solo',
{name='solo_e'},
{name='solo_n'},
{name='solo_h'},
{name='solo_l'},
{name='solo_u'},
},
{folder=true,name='round',
{name='round_e'},
{name='round_n'},
{name='round_h'},
{name='round_l'},
{name='round_u'},
},
{folder=true,name='techmino',author='MrZ',
{name='techmino49_e'},
{name='techmino49_h'},
{name='techmino49_u'},
{name='techmino99_e'},
{name='techmino99_h'},
{name='techmino99_u'},
},
},
{folder=true,name='drought',author='MrZ',
{name='drought_n'},
{name='drought_l'},
},
{folder=true,name='blind',author='MrZ',
{name='blind_e'},
{name='blind_n'},
{name='blind_h'},
{name='blind_l'},
{name='blind_u'},
{name='blind_wtf'},
},
{folder=true,name='classic',
{name='classic_e'},
{name='classic_h'},
{name='classic_u'},
},
{folder=true,name='train',author='MrZ',
{name='clearRush'},
{name='c4wtrain_n'},
{name='c4wtrain_l'},
{name='pctrain_n'},
{name='pctrain_l'},
},
{folder=true,name='pc',author='MrZ',
{name='pc_n'},
{name='pc_h'},
{name='pc_l'},
{name='pc_inf'},
},
{folder=true,name='tech',author='MrZ',
{name='sprintAtk'},
{name='sprintEff'},
{name='tech_n'},
{name='tech_n_plus'},
{name='tech_h'},
{name='tech_h_plus'},
{name='tech_l'},
{name='tech_l_plus'},
{name='tech_finesse'},
{name='tech_finesse_f'},
},
{folder=true,name='tsd',author='MrZ',
{name='tsd_e'},
{name='tsd_h'},
{name='tsd_u'},
},
{folder=true,name='backfire',author='MrZ',
{name='backfire_n'},
{name='backfire_h'},
{name='backfire_l'},
{name='backfire_u'},
},
{folder=true,name='infinite',
{name='zen'},
{name='ultra'},
{name='infinite'},
{name='infinite_dig'},
{name='marathon_inf'},
},
{folder=true,name='special',author='MrZ',
{folder=true,name='sprint',
{name='sprintPenta'},
{name='sprintMPH'},
{name='sprintSmooth'},
{name='sprintMD'},
{name='sprintSym'},
{name='sprintLock'},
{name='sprintFix'},
},
{folder=true,name='sprint',
{name='stack_e'},
{name='stack_u'},
},
{folder=true,name='sprint',
{name='techrash_n'},
{name='techrash_u'},
},
{name='marathon_bfmax'},
},
{folder=true,name='big_pack',author='NOT_A_ROBOT',
{name='big_n'},
{name='big_h'},
},
{folder=true,name='strategy_pack',author='Milla',
{name='strategy_e'},
{name='strategy_h'},
{name='strategy_u'},
{name='strategy_e_plus'},
{name='strategy_h_plus'},
{name='strategy_u_plus'},
},
}

View File

@@ -1,119 +0,0 @@
return{
{name='sprint_10l', x=0, y=0, size=40,shape=1,icon="sprint1", unlock={'sprint_20l','sprint_40l'}},
{name='sprint_20l', x=-200, y=200, size=50,shape=1,icon="sprint1"},
{name='sprint_40l', x=0, y=-300, size=40,shape=1,icon="sprint2", unlock={'dig_10l','sprint_100l','marathon_n','sprintPenta','sprintMPH'}},
{name='sprint_100l', x=-200, y=0, size=50,shape=1,icon="sprint2", unlock={'sprint_400l','drought_n'}},
{name='sprint_400l', x=-400, y=0, size=40,shape=1,icon="sprint3", unlock={'sprint_1000l'}},
{name='sprint_1000l', x=-600, y=0, size=40,shape=1,icon="sprint3"},
{name='sprintPenta', x=180, y=-160, size=40,shape=3,icon="sprint2"},
{name='sprintMPH', x=220, y=-340, size=40,shape=3,icon="sprint2"},
{name='drought_n', x=-400, y=200, size=40,shape=1,icon="drought", unlock={'drought_l'}},
{name='drought_l', x=-600, y=200, size=40,shape=1,icon="drought"},
{name='dig_10l', x=-200, y=-200, size=40,shape=1,icon="dig_sprint", unlock={'dig_40l'}},
{name='dig_40l', x=-400, y=-200, size=40,shape=1,icon="dig_sprint", unlock={'dig_100l'}},
{name='dig_100l', x=-600, y=-200, size=40,shape=1,icon="dig_sprint", unlock={'dig_400l'}},
{name='dig_400l', x=-800, y=-200, size=40,shape=1,icon="dig_sprint"},
{name='marathon_n', x=0, y=-600, size=60,shape=1,icon="marathon", unlock={'marathon_h','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'}},
{name='solo_h', x=-1000, y=-1000, size=40,shape=1,icon="solo", unlock={'solo_l','techmino49_e'}},
{name='solo_l', x=-1200, y=-1000, size=40,shape=1,icon="solo", unlock={'solo_u'}},
{name='solo_u', x=-1400, y=-1000, size=40,shape=1,icon="solo"},
{name='techmino49_e', x=-1100, y=-1200, size=40,shape=1,icon="t49", unlock={'techmino49_h','techmino99_e'}},
{name='techmino49_h', x=-1100, y=-1400, size=40,shape=1,icon="t49", unlock={'techmino49_u'}},
{name='techmino49_u', x=-1100, y=-1600, size=40,shape=1,icon="t49"},
{name='techmino99_e', x=-1300, y=-1400, size=40,shape=1,icon="t99", unlock={'techmino99_h'}},
{name='techmino99_h', x=-1300, y=-1600, size=40,shape=1,icon="t99", unlock={'techmino99_u'}},
{name='techmino99_u', x=-1300, y=-1800, size=40,shape=1,icon="t99"},
{name='round_e', x=-600, y=-800, size=40,shape=1,icon="round", unlock={'round_n'}},
{name='round_n', x=-800, y=-800, size=40,shape=1,icon="round", unlock={'round_h'}},
{name='round_h', x=-1000, y=-800, size=40,shape=1,icon="round", unlock={'round_l'}},
{name='round_l', x=-1200, y=-800, size=40,shape=1,icon="round", unlock={'round_u'}},
{name='round_u', x=-1400, y=-800, size=40,shape=1,icon="round"},
{name='master_n', x=0, y=-1000, size=40,shape=1,icon="master", unlock={'master_h','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=-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'}},
{name='blind_h', x=150, y=-900, size=35,shape=1,icon="hidden", unlock={'blind_l'}},
{name='blind_l', x=150, y=-1000, size=35,shape=3,icon="hidden2", unlock={'blind_u'}},
{name='blind_u', x=150, y=-1100, size=30,shape=3,icon="hidden2", unlock={'blind_wtf'}},
{name='blind_wtf', x=150, y=-1200, size=25,shape=2,icon="hidden2"},
{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'}},
{name='survivor_h', x=700, y=-600, size=40,shape=1,icon="survivor", unlock={'survivor_l'}},
{name='survivor_l', x=900, y=-600, size=40,shape=3,icon="survivor", unlock={'survivor_u'}},
{name='survivor_u', x=1100, y=-600, size=40,shape=2,icon="survivor"},
{name='attacker_h', x=300, y=-800, size=40,shape=1,icon="attack", unlock={'attacker_u'}},
{name='attacker_u', x=300, y=-1000, size=40,shape=1,icon="attack"},
{name='defender_n', x=500, y=-800, size=40,shape=1,icon="defend", unlock={'defender_l'}},
{name='defender_l', x=500, y=-1000, size=40,shape=1,icon="defend"},
{name='dig_h', x=700, y=-800, size=40,shape=1,icon="dig", unlock={'dig_u'}},
{name='dig_u', x=700, y=-1000, size=40,shape=1,icon="dig"},
{name='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"},
{name='pctrain_n', x=700, y=-250, size=40,shape=1,icon="pc", unlock={'pctrain_l','pc_n'}},
{name='pctrain_l', x=900, y=-250, size=40,shape=1,icon="pc"},
{name='pc_n', x=800, y=-110, size=40,shape=1,icon="pc", unlock={'pc_h'}},
{name='pc_h', x=950, y=-110, size=40,shape=3,icon="pc", unlock={'pc_l','pc_inf'}},
{name='pc_l', x=1100, y=-110, size=40,shape=3,icon="pc"},
{name='pc_inf', x=1100, y=-250, size=40,shape=2,icon="pc"},
{name='sprintAtk', x=530, y=-150, size=40,shape=1,icon="sprint2", unlock={'sprintEff','tech_n','tech_finesse','tsd_e','backfire_n'}},
{name='sprintEff', x=360, y=-150, size=40,shape=1,icon="sprint2"},
{name='tech_n', x=400, y=50, size=40,shape=1,icon="tech", unlock={'tech_n_plus','tech_h'}},
{name='tech_n_plus', x=200, y=20, size=40,shape=3,icon="tech"},
{name='tech_h', x=400, y=200, size=40,shape=1,icon="tech", unlock={'tech_h_plus','tech_l'}},
{name='tech_h_plus', x=200, y=170, size=35,shape=3,icon="tech"},
{name='tech_l', x=400, y=350, size=40,shape=1,icon="tech", unlock={'tech_l_plus'}},
{name='tech_l_plus', x=200, y=320, size=35,shape=3,icon="tech"},
{name='tech_finesse', x=800, y=50, size=40,shape=1,icon="tech", unlock={'tech_finesse_f'}},
{name='tech_finesse_f',x=1000, y=50, size=40,shape=1,icon="tech"},
{name='tsd_e', x=720, y=200, size=40,shape=1,icon="tsd", unlock={'tsd_h'}},
{name='tsd_h', x=960, y=200, size=40,shape=1,icon="tsd", unlock={'tsd_u'}},
{name='tsd_u', x=1200, y=200, size=40,shape=1,icon="tsd"},
{name='backfire_n', x=650, y=350, size=40,shape=1,icon="backfire", unlock={'backfire_h'}},
{name='backfire_h', x=850, y=350, size=40,shape=1,icon="backfire", unlock={'backfire_l'}},
{name='backfire_l', x=1050, y=350, size=40,shape=3,icon="backfire", unlock={'backfire_u'}},
{name='backfire_u', x=1250, y=350, size=35,shape=2,icon="backfire"},
{name='zen', x=-1000, y=-600, size=40,shape=1,icon="zen", unlock={'ultra','infinite','infinite_dig','marathon_inf'}},
{name='ultra', x=-1200, y=-600, size=40,shape=1,icon="ultra"},
{name='infinite', x=-1200, y=-400, size=40,shape=1,icon='infinite'},
{name='infinite_dig', x=-1000, y=-400, size=40,shape=1,icon="dig"},
{name='marathon_inf', x=-800, y=-400, size=40,shape=1,icon="marathon"}
}

View File

@@ -6,7 +6,6 @@ return{
eventSet='classic_e', eventSet='classic_e',
bg='rgb',bgm='1980s', bg='rgb',bgm='1980s',
}, },
slowMark=true,
score=function(P)return{P.stat.score,P.stat.row}end, score=function(P)return{P.stat.score,P.stat.row}end,
scoreDisp=function(D)return D[1].." "..D[2].." Lines"end, scoreDisp=function(D)return D[1].." "..D[2].." Lines"end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,

View File

@@ -6,7 +6,6 @@ return{
eventSet='classic_h', eventSet='classic_h',
bg='rgb',bgm='1980s', bg='rgb',bgm='1980s',
}, },
slowMark=true,
score=function(P)return{P.stat.score,P.stat.row}end, score=function(P)return{P.stat.score,P.stat.row}end,
scoreDisp=function(D)return D[1].." "..D[2].." Lines"end, scoreDisp=function(D)return D[1].." "..D[2].." Lines"end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,

View File

@@ -6,7 +6,6 @@ return{
eventSet='classic_u', eventSet='classic_u',
bg='rgb',bgm='1980s', bg='rgb',bgm='1980s',
}, },
slowMark=true,
score=function(P)return{P.stat.score,P.stat.row}end, score=function(P)return{P.stat.score,P.stat.row}end,
scoreDisp=function(D)return D[1].." "..D[2].." Lines"end, scoreDisp=function(D)return D[1].." "..D[2].." Lines"end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,

View File

@@ -5,7 +5,6 @@ return{
eventSet='marathon_bfmax', eventSet='marathon_bfmax',
bg='bg2',bgm='blank', bg='bg2',bgm='blank',
}, },
slowMark=true,
getRank=function(P) getRank=function(P)
local L=P.stat.row local L=P.stat.row
if L>=200 then if L>=200 then

View File

@@ -6,7 +6,6 @@ return{
eventSet='marathon_h', eventSet='marathon_h',
bg='cubes',bgm='push', bg='cubes',bgm='push',
}, },
slowMark=true,
score=function(P)return{math.min(P.stat.row,200),P.stat.time}end, score=function(P)return{math.min(P.stat.row,200),P.stat.time}end,
scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end, scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,

View File

@@ -6,7 +6,6 @@ return{
eventSet='marathon_inf', eventSet='marathon_inf',
bg='bg2',bgm='push', bg='bg2',bgm='push',
}, },
slowMark=true,
score=function(P)return{P.stat.score,P.stat.row,P.stat.time}end, score=function(P)return{P.stat.score,P.stat.row,P.stat.time}end,
scoreDisp=function(D)return D[1].."P "..D[2].."L "..STRING.time(D[3])end, scoreDisp=function(D)return D[1].."P "..D[2].."L "..STRING.time(D[3])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,

View File

@@ -6,7 +6,6 @@ return{
eventSet='marathon_n', eventSet='marathon_n',
bg='bg2',bgm='push', bg='bg2',bgm='push',
}, },
slowMark=true,
score=function(P)return{math.min(P.stat.row,200),P.stat.time}end, score=function(P)return{math.min(P.stat.row,200),P.stat.time}end,
scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end, scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,

View File

@@ -5,7 +5,6 @@ return{
eventSet='master_ex', eventSet='master_ex',
bg='blockspace',bgm='hope', bg='blockspace',bgm='hope',
}, },
slowMark=true,
score=function(P)return{P.modeData.rankPoint,P.stat.score}end, score=function(P)return{P.modeData.rankPoint,P.stat.score}end,
scoreDisp=function(D)return sectionName[math.floor(D[1]/10)+1].." "..D[2]end, scoreDisp=function(D)return sectionName[math.floor(D[1]/10)+1].." "..D[2]end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]>b[2]end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]>b[2]end,

View File

@@ -4,7 +4,6 @@ return{
eventSet='master_final', eventSet='master_final',
bg='lightning',bgm='rectification', bg='lightning',bgm='rectification',
}, },
slowMark=true,
score=function(P)return{P.modeData.pt,P.stat.time}end, score=function(P)return{P.modeData.pt,P.stat.time}end,
scoreDisp=function(D)return D[1].."P "..STRING.time(D[2])end, scoreDisp=function(D)return D[1].."P "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,

View File

@@ -5,7 +5,6 @@ return{
eventSet='master_h', eventSet='master_h',
bg='bg2',bgm='secret7th', bg='bg2',bgm='secret7th',
}, },
slowMark=true,
score=function(P)return{P.modeData.pt,P.stat.time}end, score=function(P)return{P.modeData.pt,P.stat.time}end,
scoreDisp=function(D)return D[1].."P "..STRING.time(D[2])end, scoreDisp=function(D)return D[1].."P "..STRING.time(D[2])end,
comp=function(a,b) comp=function(a,b)

View File

@@ -0,0 +1,24 @@
return{
env={
sequence="bagES",
freshLimit=15,
eventSet='master_instinct',
bg='glow',bgm='sugar fairy',
},
slowMark=true,
score=function(P)return{P.modeData.pt,P.stat.time}end,
scoreDisp=function(D)return D[1].."P "..STRING.time(D[2])end,
comp=function(a,b)
return a[1]>b[1]or(a[1]==b[1]and a[2]<b[2])
end,
getRank=function(P)
local S=P.modeData.pt
return
S>=1000 and 5 or
S>=800 and 4 or
S>=500 and 3 or
S>=300 and 2 or
S>=100 and 1 or
S>=60 and 0
end,
}

View File

@@ -4,7 +4,6 @@ return{
eventSet='master_m', eventSet='master_m',
bg='bg2',bgm='super7th', bg='bg2',bgm='super7th',
}, },
slowMark=true,
score=function(P)return{math.min(P.stat.row,200),P.stat.time}end, score=function(P)return{math.min(P.stat.row,200),P.stat.time}end,
scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end, scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,

View File

@@ -5,7 +5,6 @@ return{
eventSet='master_n', eventSet='master_n',
bg='bg1',bgm='secret8th', bg='bg1',bgm='secret8th',
}, },
slowMark=true,
score=function(P)return{P.modeData.pt,P.stat.time}end, score=function(P)return{P.modeData.pt,P.stat.time}end,
scoreDisp=function(D)return D[1].."P "..STRING.time(D[2])end, scoreDisp=function(D)return D[1].."P "..STRING.time(D[2])end,
comp=function(a,b) comp=function(a,b)

View File

@@ -3,7 +3,6 @@ return{
eventSet='master_ph', eventSet='master_ph',
bg='blockspace',bgm='race remix', bg='blockspace',bgm='race remix',
}, },
slowMark=true,
score=function(P)return{P.result=='win'and 260 or P.modeData.pt,P.stat.time}end, score=function(P)return{P.result=='win'and 260 or P.modeData.pt,P.stat.time}end,
scoreDisp=function(D)return D[1].."P "..STRING.time(D[2])end, scoreDisp=function(D)return D[1].."P "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,

View File

@@ -4,7 +4,6 @@ return{
eventSet='strategy_e', eventSet='strategy_e',
bg='bg2',bgm='push', bg='bg2',bgm='push',
}, },
slowMark=true,
score=function(P)return{math.min(P.stat.row,200),P.stat.time}end, score=function(P)return{math.min(P.stat.row,200),P.stat.time}end,
scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end, scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,

View File

@@ -4,7 +4,6 @@ return{
eventSet='strategy_e_plus', eventSet='strategy_e_plus',
bg='bg2',bgm='push', bg='bg2',bgm='push',
}, },
slowMark=true,
score=function(P)return{math.min(P.stat.row,200),P.stat.time}end, score=function(P)return{math.min(P.stat.row,200),P.stat.time}end,
scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end, scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,

View File

@@ -4,7 +4,6 @@ return{
eventSet='strategy_h', eventSet='strategy_h',
bg='bg2',bgm='secret8th', bg='bg2',bgm='secret8th',
}, },
slowMark=true,
score=function(P)return{math.min(P.stat.row,200),P.stat.time}end, score=function(P)return{math.min(P.stat.row,200),P.stat.time}end,
scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end, scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,

View File

@@ -4,7 +4,6 @@ return{
eventSet='strategy_h_plus', eventSet='strategy_h_plus',
bg='bg2',bgm='secret8th', bg='bg2',bgm='secret8th',
}, },
slowMark=true,
score=function(P)return{math.min(P.stat.row,200),P.stat.time}end, score=function(P)return{math.min(P.stat.row,200),P.stat.time}end,
scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end, scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,

View File

@@ -4,7 +4,6 @@ return{
eventSet='strategy_u', eventSet='strategy_u',
bg='bg2',bgm='secret7th', bg='bg2',bgm='secret7th',
}, },
slowMark=true,
score=function(P)return{math.min(P.stat.row,200),P.stat.time}end, score=function(P)return{math.min(P.stat.row,200),P.stat.time}end,
scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end, scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,

View File

@@ -4,7 +4,6 @@ return{
eventSet='strategy_u_plus', eventSet='strategy_u_plus',
bg='bg2',bgm='secret7th', bg='bg2',bgm='secret7th',
}, },
slowMark=true,
score=function(P)return{math.min(P.stat.row,200),P.stat.time}end, score=function(P)return{math.min(P.stat.row,200),P.stat.time}end,
scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end, scoreDisp=function(D)return D[1].." Lines "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,

View File

@@ -7,7 +7,6 @@ return{
eventSet='checkAttack_100', eventSet='checkAttack_100',
bg='flink',bgm='infinite', bg='flink',bgm='infinite',
}, },
slowMark=true,
score=function(P)return{P.stat.atk<=100 and math.floor(P.stat.atk)or 100,P.stat.time}end, score=function(P)return{P.stat.atk<=100 and math.floor(P.stat.atk)or 100,P.stat.time}end,
scoreDisp=function(D)return D[1].." Attack "..STRING.time(D[2])end, scoreDisp=function(D)return D[1].." Attack "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,

View File

@@ -20,7 +20,6 @@ return{
hook_drop=tech_check_hard, hook_drop=tech_check_hard,
bg='flink',bgm='infinite', bg='flink',bgm='infinite',
}, },
slowMark=true,
score=function(P)return{P.stat.atk<=100 and math.floor(P.stat.atk)or 100,P.stat.time}end, score=function(P)return{P.stat.atk<=100 and math.floor(P.stat.atk)or 100,P.stat.time}end,
scoreDisp=function(D)return D[1].." Attack "..STRING.time(D[2])end, scoreDisp=function(D)return D[1].." Attack "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end, comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,

View File

@@ -1,6 +1,6 @@
return{ return{
env={ env={
drop=1e99,lock=1e99, drop=120,lock=1e99,
infHold=true, infHold=true,
ospin=false, ospin=false,
eventSet='tsd_e', eventSet='tsd_e',

View File

@@ -1,6 +1,6 @@
return{ return{
env={ env={
drop=30,lock=60, drop=60,lock=60,
freshLimit=15, freshLimit=15,
ospin=false, ospin=false,
eventSet='tsd_h', eventSet='tsd_h',

View File

@@ -7,7 +7,6 @@ return{
eventSet='ultra', eventSet='ultra',
bg='fan',bgm='sakura', bg='fan',bgm='sakura',
}, },
slowMark=true,
score=function(P)return{P.stat.score}end, score=function(P)return{P.stat.score}end,
scoreDisp=function(D)return tostring(D[1])end, scoreDisp=function(D)return tostring(D[1])end,
comp=function(a,b)return a[1]>b[1]end, comp=function(a,b)return a[1]>b[1]end,

View File

@@ -79,7 +79,7 @@ end
--Parse notice --Parse notice
local function _parseNotice(str) local function _parseNotice(str)
if str:find("///")then if str:find("///")then
str=STRING.split(str,"///") str=str:split("///")
for i=1,#str do for i=1,#str do
local m=str[i] local m=str[i]
if m:find("=")then if m:find("=")then
@@ -279,7 +279,7 @@ function NET.loadSavedData(sections)
TABLE.cover(NET.cloudData.SETTING,SETTING) TABLE.cover(NET.cloudData.SETTING,SETTING)
success=success and saveSettings() success=success and saveSettings()
applyAllSettings() applySettings()
TABLE.cover(NET.cloudData.keyMap,KEY_MAP) TABLE.cover(NET.cloudData.keyMap,KEY_MAP)
success=success and saveFile(KEY_MAP,'conf/key') success=success and saveFile(KEY_MAP,'conf/key')

View File

@@ -7,6 +7,7 @@ local rnd,min=math.random,math.min
local sin,cos=math.sin,math.cos local sin,cos=math.sin,math.cos
local ins,rem=table.insert,table.remove local ins,rem=table.insert,table.remove
local setFont=FONT.set local setFont=FONT.set
local approach=MATH.expApproach
local posLists={ local posLists={
--1~5 --1~5
@@ -168,7 +169,7 @@ function NETPLY.setConnect(uid)PLYmap[uid].connected=true end
function NETPLY.setPlace(uid,place)PLYmap[uid].place=place end function NETPLY.setPlace(uid,place)PLYmap[uid].place=place end
function NETPLY.setStat(uid,S) function NETPLY.setStat(uid,S)
PLYmap[uid].stat={ PLYmap[uid].stat={
lpm=("%.1f %s"):format(S.row/S.time*60,text.radarData[5]), lpm=("%.1f %s"):format(S.piece/S.time*24,text.radarData[5]),
apm=("%.1f %s"):format(S.atk/S.time*60,text.radarData[3]), apm=("%.1f %s"):format(S.atk/S.time*60,text.radarData[3]),
adpm=("%.1f %s"):format((S.atk+S.dig)/S.time*60,text.radarData[2]), adpm=("%.1f %s"):format((S.atk+S.dig)/S.time*60,text.radarData[2]),
} }
@@ -193,14 +194,15 @@ function NETPLY.mouseMove(x,y)
end end
end end
function NETPLY.update() function NETPLY.update(dt)
for i=1,#PLYlist do for i=1,#PLYlist do
local p=PLYlist[i] local p=PLYlist[i]
local t=posList[i] local t=posList[i]
p.x=p.x*.9+t.x*.1 local d=dt*12
p.y=p.y*.9+t.y*.1 p.x=approach(p.x,t.x,d)
p.w=p.w*.9+t.w*.1 p.y=approach(p.y,t.y,d)
p.h=p.h*.9+t.h*.1 p.w=approach(p.w,t.w,d)
p.h=approach(p.h,t.h,d)
end end
end end

View File

@@ -904,10 +904,10 @@ function draw.norm(P,repMode)
setFont(25) setFont(25)
local tm=STRING.time(P.stat.time) local tm=STRING.time(P.stat.time)
gc_setColor(0,0,0,.3) gc_setColor(0,0,0,.3)
gc_print(P.score1,18,509) gc_print(ceil(P.score1),18,509)
gc_print(tm,18,539) gc_print(tm,18,539)
gc_setColor(.97,.97,.92) gc_setColor(.97,.97,.92)
gc_print(P.score1,20,510) gc_print(ceil(P.score1),20,510)
gc_setColor(.85,.9,.97) gc_setColor(.85,.9,.97)
gc_print(tm,20,540) gc_print(tm,20,540)

View File

@@ -97,7 +97,7 @@ local function _newEmptyPlayer(id,mini)
P.seqRND=love.math.newRandomGenerator(GAME.seed) P.seqRND=love.math.newRandomGenerator(GAME.seed)
P.atkRND=love.math.newRandomGenerator(GAME.seed) P.atkRND=love.math.newRandomGenerator(GAME.seed)
P.holeRND=love.math.newRandomGenerator(GAME.seed) P.holeRND=love.math.newRandomGenerator(GAME.seed)
P.aiRND=love.math.newRandomGenerator(GAME.seed) P.aiRND=love.math.newRandomGenerator(GAME.seed+P.id)
--Field-related --Field-related
P.field,P.visTime={},{} P.field,P.visTime={},{}

View File

@@ -8,6 +8,7 @@ local int,ceil,rnd=math.floor,math.ceil,math.random
local max,min,abs,modf=math.max,math.min,math.abs,math.modf local max,min,abs,modf=math.max,math.min,math.abs,math.modf
local assert,ins,rem=assert,table.insert,table.remove local assert,ins,rem=assert,table.insert,table.remove
local resume,yield,status=coroutine.resume,coroutine.yield,coroutine.status local resume,yield,status=coroutine.resume,coroutine.yield,coroutine.status
local approach=MATH.expApproach
local SFX,BGM,VOC,VIB,SYSFX=SFX,BGM,VOC,VIB,SYSFX local SFX,BGM,VOC,VIB,SYSFX=SFX,BGM,VOC,VIB,SYSFX
local FREEROW,TABLE,TEXT,TASK=LINE,TABLE,TEXT,TASK local FREEROW,TABLE,TEXT,TASK=LINE,TABLE,TEXT,TASK
@@ -318,8 +319,8 @@ function Player:act_softDrop()
self:act_down1() self:act_down1()
end end
self:checkTouchSound() self:checkTouchSound()
elseif self.gameEnv.deepdrop then elseif self.gameEnv.deepDrop then
self:_deepdrop() self:_deepDrop()
end end
end end
end end
@@ -408,8 +409,8 @@ function Player:act_down1()
self.curY=self.curY-1 self.curY=self.curY-1
self:freshBlock('fresh') self:freshBlock('fresh')
self.spinLast=false self.spinLast=false
elseif self.gameEnv.deepdrop then elseif self.gameEnv.deepDrop then
self:_deepdrop() self:_deepDrop()
end end
end end
end end
@@ -422,8 +423,8 @@ function Player:act_down4()
self.curY,self.ghoY=self.ghoY,ghoY0 self.curY,self.ghoY=self.ghoY,ghoY0
self:freshBlock('fresh') self:freshBlock('fresh')
self.spinLast=false self.spinLast=false
elseif self.gameEnv.deepdrop then elseif self.gameEnv.deepDrop then
self:_deepdrop() self:_deepDrop()
end end
end end
end end
@@ -436,8 +437,8 @@ function Player:act_down10()
self.curY,self.ghoY=self.ghoY,ghoY0 self.curY,self.ghoY=self.ghoY,ghoY0
self:freshBlock('fresh') self:freshBlock('fresh')
self.spinLast=false self.spinLast=false
elseif self.gameEnv.deepdrop then elseif self.gameEnv.deepDrop then
self:_deepdrop() self:_deepDrop()
end end
end end
end end
@@ -494,6 +495,15 @@ local playerActions={
Player.act_zangiLeft, --19 Player.act_zangiLeft, --19
Player.act_zangiRight,--20 Player.act_zangiRight,--20
}function Player:pressKey(keyID) }function Player:pressKey(keyID)
if self.id==1 then
if GAME.recording then
local L=GAME.rep
ins(L,self.frameRun)
ins(L,keyID)
elseif self.streamProgress then
VK.press(keyID)
end
end
if self.keyAvailable[keyID]and self.alive then if self.keyAvailable[keyID]and self.alive then
if self.waiting>self.gameEnv.hurry then if self.waiting>self.gameEnv.hurry then
self.waiting=self.gameEnv.hurry self.waiting=self.gameEnv.hurry
@@ -505,18 +515,8 @@ local playerActions={
playerActions[keyID](self) playerActions[keyID](self)
self.stat.key=self.stat.key+1 self.stat.key=self.stat.key+1
end end
if self.id==1 then
if GAME.recording then
local L=GAME.rep
ins(L,self.frameRun)
ins(L,keyID)
elseif self.streamProgress then
VK.press(keyID)
end
end
end end
function Player:releaseKey(keyID) function Player:releaseKey(keyID)
self.keyPressing[keyID]=false
if self.id==1 then if self.id==1 then
if GAME.recording then if GAME.recording then
local L=GAME.rep local L=GAME.rep
@@ -526,6 +526,7 @@ function Player:releaseKey(keyID)
VK.release(keyID) VK.release(keyID)
end end
end end
self.keyPressing[keyID]=false
end end
function Player:newTask(code,...) function Player:newTask(code,...)
local thread=coroutine.create(code) local thread=coroutine.create(code)
@@ -1823,7 +1824,7 @@ do
end end
piece.pc=true piece.pc=true
piece.special=true piece.special=true
elseif cc>1 or #self.field==self.garbageBeneath then elseif cc>1 or self.field[#self.field].garbage then
self:showText(text.HPC,0,-80,50,'fly') self:showText(text.HPC,0,-80,50,'fly')
atk=atk+4 atk=atk+4
exblock=exblock+2 exblock=exblock+2
@@ -2166,7 +2167,7 @@ end
--------------------------</Tick>-------------------------- --------------------------</Tick>--------------------------
--------------------------<Event>-------------------------- --------------------------<Event>--------------------------
local function _updateMisc(P) local function _updateMisc(P,dt)
--Finesse combo animation --Finesse combo animation
if P.finesseComboTime>0 then if P.finesseComboTime>0 then
P.finesseComboTime=P.finesseComboTime-1 P.finesseComboTime=P.finesseComboTime-1
@@ -2216,7 +2217,7 @@ local function _updateMisc(P)
end end
local f=P.fieldUp local f=P.fieldUp
if f~=y then if f~=y then
P.fieldUp=f>y and max(f*.95+y*.05-2,y)or min(f*.97+y*.03+1,y) P.fieldUp=f>y and max(approach(f,y,dt*6)-2,y)or min(approach(f,y,dt*3)+1,y)
end end
end end
@@ -2225,7 +2226,7 @@ local function _updateMisc(P)
if P.stat.score-P.score1<10 then if P.stat.score-P.score1<10 then
P.score1=P.score1+1 P.score1=P.score1+1
else else
P.score1=int(min(P.score1*.9+P.stat.score*.1+1)) P.score1=approach(P.score1,P.stat.score,dt*62)
end end
end end
@@ -2302,7 +2303,7 @@ local function _updateFX(P,dt)
end end
end end
end end
local function update_alive(P) local function update_alive(P,dt)
local ENV=P.gameEnv local ENV=P.gameEnv
P.frameRun=P.frameRun+1 P.frameRun=P.frameRun+1
@@ -2332,11 +2333,11 @@ local function update_alive(P)
if P.timing then P.stat.frame=P.stat.frame+1 end if P.timing then P.stat.frame=P.stat.frame+1 end
--Calculate key speed --Calculate drop speed
do do
local v=0 local v=0
for i=2,10 do v=v+i*(i-1)*72/(P.frameRun-P.dropTime[i])end for i=2,10 do v=v+i*(i-1)*72/(P.frameRun-P.dropTime[i])end
P.dropSpeed=P.dropSpeed*.99+v*.01 P.dropSpeed=approach(P.dropSpeed,v,dt)
end end
if P.gameEnv.layout=='royale'then if P.gameEnv.layout=='royale'then
@@ -2532,14 +2533,15 @@ local function update_alive(P)
::THROW_stop:: ::THROW_stop::
--B2B bar animation --B2B bar animation
if P.b2b1==P.b2b then if P.b2b1~=P.b2b then
elseif P.b2b1<P.b2b then if P.b2b1<P.b2b then
P.b2b1=min(P.b2b1*.98+P.b2b*.02+.4,P.b2b) P.b2b1=min(approach(P.b2b1,P.b2b,dt*6)+.4,P.b2b)
else else
P.b2b1=max(P.b2b1*.95+P.b2b*.05-.6,P.b2b) P.b2b1=max(approach(P.b2b1,P.b2b,dt*12)-.6,P.b2b)
end
end end
_updateMisc(P) _updateMisc(P,dt)
--[[ --[[
P:setPosition( P:setPosition(
640-150-(30*(P.curX+P.cur.sc[2])-15), 640-150-(30*(P.curX+P.cur.sc[2])-15),
@@ -2590,11 +2592,11 @@ local function update_streaming(P)
eventTime=P.stream[P.streamProgress] eventTime=P.stream[P.streamProgress]
end end
end end
local function update_dead(P) local function update_dead(P,dt)
local S=P.stat local S=P.stat
--Final average speed --Final average speed
P.dropSpeed=P.dropSpeed*.96+S.piece/S.frame*144 P.dropSpeed=approach(P.dropSpeed,S.piece/S.frame*3600,dt)
if P.gameEnv.layout=='royale'then if P.gameEnv.layout=='royale'then
P.swappingAtkMode=min(P.swappingAtkMode+2,30) P.swappingAtkMode=min(P.swappingAtkMode+2,30)
@@ -2606,7 +2608,7 @@ local function update_dead(P)
if P.b2b1>0 then if P.b2b1>0 then
P.b2b1=max(0,P.b2b1*.92-1) P.b2b1=max(0,P.b2b1*.92-1)
end end
_updateMisc(P) _updateMisc(P,dt)
end end
function Player:_die() function Player:_die()
self.alive=false self.alive=false
@@ -2664,17 +2666,17 @@ function Player:update(dt)
20 20
do do
update_streaming(self) update_streaming(self)
update_alive(self) update_alive(self,dt)
end end
end end
else else
update_alive(self) update_alive(self,dt)
end end
self.trigFrame=self.trigFrame-1 self.trigFrame=self.trigFrame-1
end end
else else
while self.trigFrame>=1 do while self.trigFrame>=1 do
update_dead(self) update_dead(self,dt)
self.trigFrame=self.trigFrame-1 self.trigFrame=self.trigFrame-1
end end
end end

View File

@@ -232,7 +232,7 @@ local commands={}do
commands.mv={ commands.mv={
code=function(arg) code=function(arg)
--Check arguments --Check arguments
arg=STRING.split(arg," ") arg=arg:split(" ")
if #arg>2 then if #arg>2 then
log{C.lY,"Warning: file names must have no spaces"} log{C.lY,"Warning: file names must have no spaces"}
return return
@@ -532,7 +532,7 @@ local commands={}do
if arg:find"pl"and arg:find"fk"then if arg:find"pl"and arg:find"fk"then
SCN.go('support','none') SCN.go('support','none')
else else
love.system.openURL("https://www.bilibili.com/video/BV1GJ411x7h7?secretcode=fkpl") love.system.openURL("https://www.bilibili.com/video/BV1uT4y1P7CX?secretcode=fkpl")
end end
else else
SCN.go('support','none') SCN.go('support','none')
@@ -647,6 +647,11 @@ local commands={}do
scene='app_triple', scene='app_triple',
description="A Match-3 Game. Original idea from Sanlitun / Triple Town" description="A Match-3 Game. Original idea from Sanlitun / Triple Town"
}, },
{
code="sw",
scene='app_stopwatch',
description="A stopwatch"
},
{ {
code="spin", code="spin",
scene='app_spin', scene='app_spin',
@@ -862,7 +867,7 @@ local commands={}do
--Network --Network
commands.switchhost={ commands.switchhost={
code=function(arg) code=function(arg)
arg=STRING.split(arg," ") arg=arg:split(" ")
if arg[1]and #arg<=3 then if arg[1]and #arg<=3 then
WS.switchHost(unpack(arg)) WS.switchHost(unpack(arg))
log{C.Y,"Host switched"} log{C.Y,"Host switched"}

View File

@@ -174,7 +174,7 @@ function scene.update(dt)
end end
end end
life1=life1*.7+life*.3 life1=MATH.expApproach(life1,life,dt*16)
if play then if play then
if inv>0 then if inv>0 then

View File

@@ -280,13 +280,13 @@ function scene.touchDown(x)
end end
end end
function scene.update() function scene.update(dt)
if state==1 then if state==1 then
local t=TIME() local t=TIME()
time=t-startTime time=t-startTime
local v=0 local v=0
for i=2,20 do v=v+i*(i-1)*.3/(t-keyTime[i])end for i=2,20 do v=v+i*(i-1)*.3/(t-keyTime[i])end
speed=speed*.99+v*.01 speed=MATH.expApproach(speed,v,dt)
if speed>maxSpeed then maxSpeed=speed end if speed>maxSpeed then maxSpeed=speed end
if arcade then if arcade then

View File

@@ -171,10 +171,10 @@ end
scene.widgetList={ scene.widgetList={
WIDGET.newButton{name='reset', x=160,y=100,w=180,h=100,color='lG',font=50,fText=CHAR.icon.retry_spin,code=pressKey'space',hideF=function()return state==0 end}, WIDGET.newButton{name='reset', x=160,y=100,w=180,h=100,color='lG',font=50,fText=CHAR.icon.retry_spin,code=pressKey'space',hideF=function()return state==0 end},
WIDGET.newSlider{name='rank', x=130,y=250,lim=105,w=150,unit=3,show=false,font=40,disp=function()return rank-3 end,code=function(v)rank=v+3 end,hideF=function()return state>0 end}, WIDGET.newSlider{name='rank', x=130,y=250,lim=105,w=150,axis={3,6,1},show=false,font=40,disp=function()return rank end,code=function(v)rank=v end,hideF=function()return state>0 end},
WIDGET.newSwitch{name='invis', x=240,y=330,lim=200,font=40,disp=function()return invis end, code=pressKey'q',hideF=function()return state==1 end}, WIDGET.newSwitch{name='invis', x=240,y=330,lim=200,font=40,disp=function()return invis end,code=pressKey'q',hideF=function()return state==1 end},
WIDGET.newSwitch{name='disappear',x=240,y=420,lim=200,font=40,disp=function()return disappear end,code=pressKey'w',hideF=function()return state==1 end}, WIDGET.newSwitch{name='disappear',x=240,y=420,lim=200,font=40,disp=function()return disappear end,code=pressKey'w',hideF=function()return state==1 end},
WIDGET.newSwitch{name='tapFX', x=240,y=510,lim=200,font=40,disp=function()return tapFX end, code=pressKey'e',hideF=function()return state==1 end}, WIDGET.newSwitch{name='tapFX', x=240,y=510,lim=200,font=40,disp=function()return tapFX end,code=pressKey'e',hideF=function()return state==1 end},
WIDGET.newButton{name='back', x=1140,y=640,w=170,h=80,sound='back',font=60,fText=CHAR.icon.back,code=backScene}, WIDGET.newButton{name='back', x=1140,y=640,w=170,h=80,sound='back',font=60,fText=CHAR.icon.back,code=backScene},
} }

View File

@@ -0,0 +1,70 @@
local state
local pressTime
local releaseTime
local time1,time2
local function press()
if state==0 then
state=1
pressTime=TIME()
releaseTime=false
time2=STRING.time(0)
elseif state==2 then
state=0
end
end
local function release()
if state==1 then
state=2
releaseTime=TIME()
end
end
local scene={}
function scene.sceneInit()
state=0
time1=STRING.time(0)
time2=STRING.time(0)
end
function scene.mouseDown()
press()
end
function scene.mouseUp()
release()
end
function scene.keyDown(key,isRep)
if isRep then return end
if key=='escape'then
SCN.back()
else
press()
end
end
function scene.keyUp()
release()
end
function scene.update()
if state~=0 then
time1=STRING.time(TIME()-pressTime)
if releaseTime then
time2=STRING.time(TIME()-releaseTime)
end
end
end
function scene.draw()
FONT.set(60)
mStr(CHAR.icon.import,340,230)
mStr(CHAR.icon.export,940,230)
mStr(time1,340,300)
mStr(time2,940,300)
end
scene.widgetList={
WIDGET.newButton{name="back", x=1140,y=640,w=170,h=80,font=60,fText=CHAR.icon.back,code=backScene},
}
return scene

View File

@@ -31,11 +31,11 @@ function scene.keyDown(key,isRep)
end end
end end
function scene.update() function scene.update(dt)
local t=TIME() local t=TIME()
local v=0 local v=0
for i=2,40 do v=v+i*(i-1)*.075/(t-keyTime[i])end for i=2,40 do v=v+i*(i-1)*.075/(t-keyTime[i])end
speed=speed*.99+v*.01 speed=MATH.expApproach(speed,v,dt)
if speed>maxSpeed then if speed>maxSpeed then
maxSpeed=speed maxSpeed=speed
end end

View File

@@ -103,7 +103,7 @@ function scene.keyDown(key,isRep)
MES.new('check',text.exportSuccess) MES.new('check',text.exportSuccess)
elseif key=='v'and kb.isDown('lctrl','rctrl')or key=='cV'then elseif key=='v'and kb.isDown('lctrl','rctrl')or key=='cV'then
local str=sys.getClipboardText() local str=sys.getClipboardText()
local args=STRING.split(str:sub((str:find(":")or 0)+1),"!") local args=str:sub((str:find(":")or 0)+1):split("!")
if #args<4 then goto THROW_fail end if #args<4 then goto THROW_fail end
if not( if not(
DATA.pasteQuestArgs(args[1])and DATA.pasteQuestArgs(args[1])and
@@ -226,10 +226,10 @@ scene.widgetList={
--Next & Hold --Next & Hold
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.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='nextCount', x=140, y=960, lim=130,w=180,axis={0,6,1},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.newSlider{name='holdCount', x=140, y=1030,lim=130,w=180,axis={0,6,1},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='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}, 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 --BG & BGM
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='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},

View File

@@ -140,6 +140,7 @@ function scene.mouseMove(x,y)
end end
end end
function scene.mouseDown(x,y,k) function scene.mouseDown(x,y,k)
if k>3 then return end
if not curPen then if not curPen then
curPen=k curPen=k
elseif curPen~=k then elseif curPen~=k then
@@ -149,6 +150,7 @@ function scene.mouseDown(x,y,k)
scene.mouseMove(x,y) scene.mouseMove(x,y)
end end
function scene.mouseUp(_,_,k) function scene.mouseUp(_,_,k)
if k>3 then return end
if curPen==k then if curPen==k then
_pDraw() _pDraw()
curPen=false curPen=false

View File

@@ -9,9 +9,9 @@ local scene={}
function scene.sceneInit() function scene.sceneInit()
BGcolor=rnd()>.026 and{.3,.5,.9}or{.62,.3,.926} BGcolor=rnd()>.026 and{.3,.5,.9}or{.62,.3,.926}
sysAndScn=SYSTEM.."-"..VERSION.string.." scene:"..Z.errData[#Z.errData].scene sysAndScn=SYSTEM.."-"..VERSION.string.." scene:"..Z.getErr('#').scene
errorText=LOADED and text.errorMsg or"An error has occurred while the game was loading.\nAn error log has been created so you can send it to the author." errorText=LOADED and text.errorMsg or"An error has occurred while the game was loading.\nAn error log has been created so you can send it to the author."
errorShot,errorInfo=Z.errData[#Z.errData].shot,Z.errData[#Z.errData].mes errorShot,errorInfo=Z.getErr('#').shot,Z.getErr('#').mes
NET.wsclose_app() NET.wsclose_app()
NET.wsclose_user() NET.wsclose_user()
NET.wsclose_play() NET.wsclose_play()

View File

@@ -298,7 +298,7 @@ local function _update_common(dt)
end end
--Warning check --Warning check
checkWarning() checkWarning(dt)
end end
function scene.update(dt) function scene.update(dt)
trigGameRate=trigGameRate+gameRate trigGameRate=trigGameRate+gameRate

View File

@@ -2,7 +2,7 @@ local scene={}
function scene.sceneInit() function scene.sceneInit()
BG.set('cubes') BG.set('cubes')
WIDGET.active.texts:setTexts(STRING.split(require"parts.updateLog","\n")) WIDGET.active.texts:setTexts(require"parts.updateLog":split("\n"))
end end
function scene.wheelMoved(_,y) function scene.wheelMoved(_,y)

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