Compare commits

...

488 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
MrZ626
41e7b8e0f4 版本推进 2021-12-07 22:43:53 +08:00
MrZ626
4bd723a7ee 整理代码 2021-12-07 22:43:48 +08:00
MrZ626
66d5bd5490 更多场景的大标题添加最大显示长度 2021-12-07 22:40:16 +08:00
MrZ626
351d0258b2 再优化miya立绘 2021-12-07 22:40:16 +08:00
NOT_A_ROBOT
26fb9a7052 Add Strategy+ (#539) 2021-12-07 22:39:00 +08:00
MrZ626
307fd637fa 换新miya立绘
给不同立绘添加不同点击动画
2021-12-07 20:25:14 +08:00
MrZ626
93fb716f89 fix 2021-12-07 17:10:02 +08:00
MrZ626
7b41551e2d xitonglai 2021-12-07 16:57:47 +08:00
MrZ626
4806af5f7d 重做关于页面,赞助二维码搬家 2021-12-07 16:00:52 +08:00
MrZ626
85cb55cdd0 文本控件也支持设置最大宽度了 2021-12-07 15:51:19 +08:00
MrZ626
27a9697e47 修改scene模块,支持在切换场景的时候传参了 2021-12-07 15:04:27 +08:00
MrZ626
7d230cc3b0 修正印尼语按钮文本错误 close #536 2021-12-07 14:33:04 +08:00
MrZ626
0db2fffad1 版本推进 2021-12-07 01:43:17 +08:00
MrZ626
2a3296a0e8 调整pixel皮肤,修改x块的默认色为黄色 2021-12-07 01:26:46 +08:00
MrZ626
941b875afa 再微调语言设置界面
整理代码
2021-12-07 01:05:46 +08:00
MrZ626
99155bb9cf 更新macOS安装包用图
Co-authored-by: C₂₉H₂₅N₃O₅ <cgu52@wisc.edu>
2021-12-07 01:00:22 +08:00
MrZ626
0701dd2ad3 新皮肤:pixel(by C₂₉H₂₅N₃O₅) 2021-12-07 00:59:19 +08:00
MrZ626
5570c19e1f 调整颜色表
调整语言选择菜单
整理代码
2021-12-07 00:59:19 +08:00
NOT_A_ROBOT
a728c91476 Add Indonesian Translation (#535)
- Added Indonesian language file
- Added Indonesian button in language select menu
- Added Indonesian variant of the word "language" on the language select menu
- Added credit to me for translating (applies to all languages)
2021-12-07 00:00:51 +08:00
MrZ626
6a43481067 优化小程序triple体验 2021-12-06 22:42:49 +08:00
MrZ626
29a049fe4e 版本推进 2021-12-06 22:20:59 +08:00
MrZ626
b5a9c8e1bb 修正一处手柄事件可能爆炸 2021-12-06 21:17:30 +08:00
MrZ626
bb9a35c161 修复云存档/读档的一处小问题 2021-12-06 21:11:54 +08:00
MrZ626
b25a345b42 更换click音效,音乐室播放按钮声音调整 2021-12-06 20:33:41 +08:00
MrZ626
b22b0e0194 修正文件加载模块参数识别的小问题 2021-12-06 19:52:00 +08:00
MrZ626
55cf95f218 修正策略堆叠模式评级标准不当 2021-12-06 19:24:24 +08:00
MrZ626
225ddbcfac 调整几个tip 2021-12-06 16:43:46 +08:00
MrZ626
9377090c7c 【bug风险较大,需要测试】解耦玩家代码中的部分混战模式代码 2021-12-06 16:00:46 +08:00
MrZ626
ed002ec2e1 略微降低master-h模式骨块出现后的难度 2021-12-06 13:49:51 +08:00
MrZ626
e33036d9ec 调整几个词条的关键词 2021-12-06 12:46:17 +08:00
MrZ626
ef03e7c009 layout菜单名改为style 2021-12-06 12:46:11 +08:00
MrZ626
aef4220ac0 修复自定义场地16号颜色的方块名位置显示错误
优化皮肤设置页面交互效果
2021-12-06 03:25:39 +08:00
MrZ626
46223e38cd STRING模块新增一个简易摘要算法,未来保护用户密码明文可能用到 2021-12-06 03:18:41 +08:00
MrZ626
4bafa4bffe 版本推进 2021-12-05 22:01:16 +08:00
MrZ626
2b3dd877dd 修正100攻击竞速模式没有重力 2021-12-05 18:13:47 +08:00
MrZ626
0553e5c45e 调整中文tip 2021-12-05 18:11:12 +08:00
MrZ626
4d93374cf6 微调暂停界面和语言选择界面 2021-12-05 00:54:42 +08:00
MrZ626
4e421bf9ba 微调一些场景细节 2021-12-04 22:29:38 +08:00
user670
8b2a9d7c01 Update lang_en.lua (#534) 2021-12-04 22:17:43 +08:00
C₂₉H₂₅N₃O₅
5a3244d345 更改语言选择界面布局 (#532)
* 再更改语言选择布局
2021-12-04 19:56:24 +08:00
MrZ626
f1b9d0c5e4 新增返回按钮音效 2021-12-03 17:15:32 +08:00
MrZ626
6493e0e623 创建button和key控件时的sound参数可以指定音效名了 2021-12-03 16:45:37 +08:00
MrZ626
e71ba17f9f 微调一个中文词典词条 2021-12-03 11:57:21 +08:00
MrZ626
e656363e20 录像回放菜单对键盘支持更好 2021-12-03 11:23:44 +08:00
MrZ626
0826a748ae 版本推进 2021-12-03 11:04:51 +08:00
MrZ626
a595fe99ef 大规模整理中文tip 2021-12-03 10:50:05 +08:00
MrZ626
9dbc7942e3 调整语言菜单标题 2021-12-03 10:49:57 +08:00
C₂₉H₂₅N₃O₅
845d8ae32e 字体增加谚文/语言滚动菜单丰富 (#530)
* 字体支持谚文显示

* 语言选择界面滚动菜单增加一堆语言
2021-12-03 08:26:09 +08:00
MrZ626
5c524e138c 语言选择菜单会轮流显示不同语言的“语言” 2021-12-02 22:06:06 +08:00
MrZ626
86d9265ff9 修复最后一个hold的死锁问题 close #528 2021-12-02 18:42:03 +08:00
MrZ626
6994a5d6d3 调整tip 2021-12-02 18:16:59 +08:00
MrZ626
e6213b00c1 修复无尽挖掘规则包会对非指定背景做不好的事情 close #525 2021-12-02 14:07:52 +08:00
MrZ626
43e2caa30e 修正进入登录场景时本地没保存过账户信息文件时会弹出文件读取错误 2021-12-02 10:04:38 +08:00
MrZ626
97ca245dfc 修复放录像的时候虚拟按键不会自己动 2021-12-02 08:58:35 +08:00
MrZ626
36de1c0751 版本推进 2021-12-02 01:40:01 +08:00
MrZ626
704341fd15 修正软降在sddas/sdarr很小的时候行为不正确 2021-12-02 01:33:50 +08:00
MrZ626
22b61bc9c3 修正暂停界面数据显示条件为>=180帧而不是>180帧
key控件微调
2021-12-02 00:30:21 +08:00
MrZ626
f4cbbc0a2a 修复cc看不到初始场地 2021-12-01 22:15:54 +08:00
MrZ626
dc99187b9d 修改三个音效名称 2021-12-01 22:03:22 +08:00
MrZ626
915598dec4 整理代码,SFX模块load时会提示缺失多少音效 2021-12-01 19:23:39 +08:00
MrZ626
e7b4518d73 【警告:需要测试】
调整玩家能hold/移动/旋转方块的条件
修复cc复活后小bug
整理代码
2021-12-01 15:46:12 +08:00
NOT_A_ROBOT
9603a78e87 Halved field height for Big mode (#520)
* Halved field height for big mode

Co-authored-by: MrZ_26 <1046101471@qq.com>
2021-12-01 09:29:57 +08:00
MrZ626
bd90e051d4 版本推进 2021-12-01 02:41:18 +08:00
MrZ626
26e66b313f 继续收拾各种ui相关
空心控件统一加上灰色背景方便观察
按钮样式调整
2021-12-01 02:40:11 +08:00
MrZ626
c534bbd12a 微调马拉松和混战的速度曲线 2021-12-01 00:39:21 +08:00
NOT_A_ROBOT
83b5e217e5 Add Big Mode (#515)
I even halved the gravity :)
2021-12-01 00:10:00 +08:00
MrZ626
c0adf5bf0b COLOR模块新增三个半透明灰色并大量应用
微调颜色V和lV的hue值
2021-11-30 23:36:04 +08:00
MrZ626
4ff737a4ac 减小语音随机偏差范围 2021-11-30 23:20:59 +08:00
MrZ626
5af0706c09 普通消1不再有single语音 2021-11-30 22:52:27 +08:00
MrZ626
4ccee0f1de 修改小程序trp的next生成 2021-11-30 22:31:46 +08:00
MrZ626
9b752d540e 修正慢速下落有拖影不好看
测试代码忘删
2021-11-30 22:24:58 +08:00
MrZ626
e860c7b7ec 大改重力和软降的结算逻辑,两个值接近的时候不会看起来不自然了 close #438 2021-11-30 19:40:53 +08:00
C29H25N3O5
8a1fd9531f 修复NH块搞反的问题 2021-11-30 15:54:54 +08:00
C29H25N3O5
5fd6e0ee99 再更新虚拟按键贴图, 使用Plex字体 2021-11-30 15:54:52 +08:00
MrZ626
53b2b81fe0 再新增几个tip 2021-11-30 14:51:04 +08:00
MrZ626
6ccc811b46 微调tip 2021-11-30 12:56:32 +08:00
MrZ626
962a61567a OS X系统名称字符串强制改为macOS close #513 2021-11-30 12:25:59 +08:00
MrZ626
58f05e1cec 控制台sudo命令改名su 2021-11-30 12:22:14 +08:00
MrZ626
6b426790c7 调整小程序triple 2021-11-30 11:49:48 +08:00
MrZ626
d4fc578673 词典添加穿透词条 2021-11-30 11:17:17 +08:00
MrZ626
51b567b8db app -list输出美化 2021-11-30 03:53:22 +08:00
MrZ626
07b47dee3f 版本推进 2021-11-30 01:50:13 +08:00
MrZ626
4431a906b9 整理代码 2021-11-30 01:44:21 +08:00
NOT_A_ROBOT
2bb6852e3e Added multiple bg and bgm to Strategy Mode (#506)
(excluding strategy_e for the bgm)
2021-11-30 01:42:39 +08:00
user670
1948ed3e16 Update gameTables.lua (#508)
On an XBox controller, B is on the right and A is on the bottom (unlike a Nintendo controller), and it makes more sense to default B to rotate right and A to rotate left.
2021-11-30 01:42:02 +08:00
MrZ626
81b5ccae30 修复检测第一次启动失败 2021-11-30 01:40:53 +08:00
MrZ626
5543ff0d29 新小程序:Triple 2021-11-30 01:40:49 +08:00
MrZ626
cd567e9e98 删除添加作者qq按钮 2021-11-30 01:40:01 +08:00
MrZ626
5d86925a8a 大多数菜单的二次确认统一用tryXXX管理 2021-11-30 01:40:01 +08:00
MrZ626
e3db564a4b 整理代码,返回需要二次确认的小程序统一用一个函数 2021-11-30 01:40:01 +08:00
MrZ626
a4293624ab 微调wine颜色 2021-11-29 22:24:17 +08:00
MrZ626
367e2dc81a 新增几个tip 2021-11-29 21:32:09 +08:00
MrZ626
9ec33c6eef 修改BGM: sugar fairy的作者标注 2021-11-29 21:32:08 +08:00
MrZ626
9c9b8d36f2 小程序mem平衡调整 2021-11-29 21:32:08 +08:00
MrZ626
4fc6f335c7 新增小程序:Memorize 2021-11-29 15:40:55 +08:00
MrZ626
d2f4123d08 修改两个有数字键盘的小程序的退格键图标 2021-11-29 15:40:40 +08:00
MrZ626
b29d352a1b 把主菜单快捷键加回来 2021-11-29 12:57:17 +08:00
MrZ626
cd5a71cd12 更新赞助名单 2021-11-29 12:49:58 +08:00
MrZ626
cdd68e985d 修正键位设置菜单里mac的del键符号错误 2021-11-29 11:15:24 +08:00
MrZ626
8cf4d4280c 修正Ospin变O后操作序列不清空
Ospin变远端朝下JL时允许水平可移动
2021-11-29 11:11:54 +08:00
C29H25N3O5
cd29bf8702 调整字体
* Monospaced字体简中字库使用大陆标准字形, 日语部分仍然使用日语字形
* 调整自定义图标手柄和键盘部分的文字字体
* 修复proportional字体a的变音符没对齐的问题
* 修复Monospaced字体ij连字的问题
* 修复Monospaced字体slash还用的是plex字体的问题
2021-11-28 18:24:11 -06:00
MrZ626
13d98be051 版本推进 2021-11-29 04:23:05 +08:00
MrZ626
a350ff3182 微调背景模块,自定义模式设置背景的时候访问不到特殊背景了 2021-11-29 04:22:08 +08:00
MrZ626
e0360cc7eb 修正一处模块更新错误(傻了) 2021-11-29 03:57:18 +08:00
MrZ626
4249a29b63 继续优化键位设置菜单 2021-11-29 03:38:05 +08:00
MrZ626
43b2a0a8c8 优化键位设置菜单各种键的显示 2021-11-29 03:27:57 +08:00
MrZ626
6d6584f99e 修改按钮音效,给复选框和选择器添加新音效 2021-11-29 02:48:41 +08:00
MrZ626
077c651226 微调键位设置菜单 2021-11-29 01:16:22 +08:00
MrZ626
3fc872aa76 微调几个隐藏模式入口点击范围 2021-11-28 22:39:49 +08:00
MrZ626
cb0b347a38 更新赞助名单 2021-11-28 22:21:10 +08:00
MrZ626
d08967c688 整理词典 2021-11-28 22:02:39 +08:00
MrZ626
3666c0caa9 修复更换自定义背景图片时没有更新尺寸 2021-11-28 20:52:12 +08:00
MrZ626
4ef179fccb 控制台场景向全局环境添加一个输出到控制台的函数 close #499 2021-11-28 19:51:46 +08:00
MrZ626
861f9b3caa 继续完善手柄控制 2021-11-28 19:40:26 +08:00
MrZ626
05292df456 模式地图上读取手柄按键时不再报错 2021-11-28 17:43:36 +08:00
MrZ626
9fed692223 控制台help命令输出美化 close #502 2021-11-28 16:53:24 +08:00
MrZ626
b1c04c1fea 修复自定义模式用按钮开始游戏会报错 2021-11-28 16:21:27 +08:00
MrZ626
bc9adc2cd3 调整扳机键的默认触发阈值 2021-11-28 16:16:44 +08:00
MrZ626
cdf149afca 略微优化自定义背景绘制性能 2021-11-28 05:20:29 +08:00
MrZ626
73145b4e5e 自定义背景拖入无法识别的格式时会提示 2021-11-28 05:20:18 +08:00
MrZ626
f8b9f30fd6 修改框架的光标默认位置 2021-11-28 05:02:29 +08:00
MrZ626
e6bc567b12 两种按钮上的文本也会挤压绘制了
优化控件绘制性能
修正两个背景设置按钮位置错误
调整之前忘了同步的语言
2021-11-28 04:56:55 +08:00
MrZ626
fe004a72f0 版本推进 2021-11-28 04:17:44 +08:00
MrZ626
0433fd3d9d 三个高难隐形使用不同模式图标 close #493 2021-11-28 04:10:42 +08:00
MrZ626
1c18060570 尝试修复地图菜单读取手柄摇杆位置错误 2021-11-28 04:06:37 +08:00
MrZ626
be54c0e641 关闭背景时亮度可调
新增自定义图片背景功能(可调透明度,目前仅电脑可用)
2021-11-28 03:56:53 +08:00
MrZ626
0be2eb9107 修正一处可能未改回材质缩放模式 2021-11-28 03:30:34 +08:00
MrZ626
4859faf1e7 创建控件允许留空code域,什么都不会发生 2021-11-28 02:03:52 +08:00
MrZ626
c25d40c67d 启动加载数据文件时允许不存在,不会提醒 close #495 2021-11-28 01:59:24 +08:00
MrZ626
b6c37a5c9f 框架keyDown事件机制微调,重构框架主循环和控件相关代码
可以用键盘和手柄控制光标(手柄不完善)
整理代码和部分语言文件细节
2021-11-27 23:16:21 +08:00
MrZ626
f6b4c1b109 整理代码,表示键盘按键的字符串使用单引号 2021-11-27 19:01:32 +08:00
MrZ626
841faeede4 版本推进 2021-11-27 14:33:38 +08:00
MrZ626
e61b9b23a0 修复右侧c/s/a+方向键不能触发控件功能 close #492 2021-11-27 14:33:36 +08:00
MrZ626
72a826ef0a 微调报错界面,日志使用等宽字体 2021-11-27 14:25:13 +08:00
MrZ626
f070b8f295 修正svg标题的小问题 2021-11-27 14:20:05 +08:00
MrZ626
1646b75520 修正TRS的v块1<->2比0<->3少一个踢墙 2021-11-27 14:20:05 +08:00
C29H25N3O5
241617e31a 微调字体
* Monospaced的CJK字体也调整为思源
* 改动几个新元素汉字
* 精简Monospaced字符集
2021-11-26 22:58:40 -06:00
MrZ626
5de2893e07 帮0.17前的版本自动调大1帧的das打断,尝试维持手感 2021-11-27 05:52:35 +08:00
MrZ626
030e894040 theme移出框架,大改通常bgm的配置 2021-11-27 05:35:55 +08:00
MrZ626
e7b9a4ba87 添加DRS_weak旋转系统 close #441 2021-11-27 05:09:02 +08:00
MrZ626
617bae67c6 修正matt的一些翻译修改和控制台代码 2021-11-27 04:47:48 +08:00
MattMayuga
64d2d08820 Update English translation (#487)
* Update readme.md

* Update lang_en.lua

* Update app_console.lua

* Update error.lua

* Add warnings and extended time to 10s for resetall

When you use the resetall command, you will now get a message that there is no way to recover the saved data when it is deleted.
2021-11-27 04:28:08 +08:00
NOT_A_ROBOT
037b33c99a Update theme list (#489) 2021-11-27 04:26:40 +08:00
MrZ626
afa69ce9a4 版本推进 2021-11-27 04:24:41 +08:00
MrZ626
3226c0c831 重构字体模块,支持多字体
控制台应用等宽字体
2021-11-27 04:24:40 +08:00
MrZ626
4e759cad4c ultra模式重开时会重新播放bgm 2021-11-27 02:05:48 +08:00
MrZ626
291795928d 更多的设置修改的时候会触发警告 2021-11-26 21:52:10 +08:00
MrZ626
a1315e7f7f 修复一处遗留逻辑hold和序列生成相关的错误 2021-11-26 21:24:34 +08:00
MrZ626
657bc2b4e0 修正加载文件的时候会因为没有应用语言没法弹出消息而报错 2021-11-26 14:15:42 +08:00
MrZ626
d8b12fc55d 版本推进 2021-11-26 01:48:23 +08:00
MrZ626
6d11367ea4 新BGM:malate(暂未使用) 2021-11-26 01:47:14 +08:00
MrZ626
eb9e741b4f 关于界面的对称40行入口换成堆积模式 2021-11-26 00:59:23 +08:00
MrZ626
c47546d501 微调一些玩家动作逻辑
修复零ARE+非零lineARE的时候ihs失效
2021-11-26 00:55:29 +08:00
MrZ626
11aa178fc1 ultra模式计时器样式改为数字 2021-11-25 19:58:22 +08:00
MrZ626
f3a88ef269 游戏内再次封装saveFile和loadFile函数
原本的FILE模块更独立,不基于全局text变量和报错信息而是直接报错
2021-11-25 17:38:09 +08:00
MrZ626
720dc2131f 字符串扩展模块给默认string库补充两个方法repD和sArg 2021-11-25 17:37:46 +08:00
MrZ626
701ef17ae1 大爆炸改名清版竞速 2021-11-25 14:03:36 +08:00
MrZ626
1a689a5f07 修正当前方块显示条件 2021-11-25 09:57:45 +08:00
MrZ626
ef12ab0cee 版本推进 2021-11-25 02:43:57 +08:00
MrZ626
3d26db7a01 整理代码,修复消行延迟和出块延迟在极小时的错误行为 2021-11-25 02:42:25 +08:00
MrZ626
dd3df9981b TRS的J/L新增一个踢墙 2021-11-25 02:08:53 +08:00
MrZ626
5d04e83529 修正一个赞助id 2021-11-25 01:13:55 +08:00
MrZ626
7ed4626d71 微调logo 2021-11-24 21:34:26 +08:00
MrZ626
ecf5a29a71 添加一个赞助人 2021-11-24 20:36:52 +08:00
MrZ626
1a24b346a0 修正英文文本缺一个holdMode 2021-11-24 20:36:47 +08:00
MrZ626
72d06c7a02 软降n格的键也可以触发深降 2021-11-24 20:26:24 +08:00
MrZ626
26fde8c694 微调默认摇杆参数 2021-11-24 20:17:53 +08:00
MrZ626
8adeb99be7 修正标题图像素材首字母偏低 close #485 2021-11-24 19:39:38 +08:00
MrZ626
c92f15156b 虚拟按键显示开关移至菜单第一页
修改部分不常用设置时会显示警告
2021-11-24 19:33:08 +08:00
MrZ626
63f69d712b 修复自定义房间改不了锁外即死规则 close #484 2021-11-24 11:20:49 +08:00
MrZ626
55a1bd06f3 版本推进 2021-11-24 06:41:51 +08:00
MrZ626
6a29abf7f0 自定义hold数量为0时不显示hold模式选择器,顺便更新创建房间参数ui遗漏 close #483 2021-11-23 22:30:43 +08:00
MrZ626
83bdd9f2c4 【警告:可能有bug,需要测试】
较大规模整理玩家相关代码
较大规模整理玩家相关代码,重构出块延迟和消行延迟逻辑,现在0是真的无延迟,不再有1帧等待了
添加出块延迟打断(即ARE打断)(不包括消行延迟,默认为打断至无穷大,相当于无此功能)
自定义游戏和自定义房间ui跟进
close #471
2021-11-23 20:26:31 +08:00
MrZ626
95879827c8 调整游戏大logo为正体字 2021-11-23 18:13:45 +08:00
MrZ626
2ade518207 调整tip 2021-11-23 00:48:49 +08:00
MrZ626
36c8449e4d 内存过低的提示每次启动最多出现三次 2021-11-23 00:28:08 +08:00
MrZ626
3c04df69f3 移除手柄时自动松开所有按下了的键,整理代码 2021-11-23 00:27:57 +08:00
MrZ626
1224ee9a67 词典的新人引导条目链接向user670的翻译版本 close #482 2021-11-22 23:45:54 +08:00
MrZ626
fdd1d4463a 版本推进 2021-11-22 21:55:58 +08:00
MrZ626
940ac3736c 整理框架代码
整理手柄的摇杆/扳机支持代码
2021-11-22 15:59:57 +08:00
user670
d38897b54d (Experimental) Support controller axises, closes #466 (#477)
* (Experimental) Support controller axises

* Remove redundant variable; use more readable key event names

* Remove redundant comment; fix typo
2021-11-22 15:52:51 +08:00
MrZ626
90848c6654 全局默认使用5帧窒息延迟 2021-11-22 12:48:02 +08:00
NOT_A_ROBOT
0220d5aefc Make Strategy Ultimate have rhombus outline (#481) 2021-11-22 11:08:13 +08:00
MrZ626
f42032df07 更新赞助名单 2021-11-22 11:04:32 +08:00
MrZ626
05d7eb60bc 修正一处拼写问题导致报错消息识别错误 2021-11-21 21:45:37 +08:00
MrZ626
942416317c 小程序arm添加计时器和重置按钮,删除测试用的跳过按钮 2021-11-21 20:18:42 +08:00
MrZ626
576de945fb 添加一打tip 2021-11-21 05:25:55 +08:00
MrZ626
8b02084428 修复bgm模块清缓存导致报错 2021-11-21 05:11:01 +08:00
MrZ626
9f666d69db 调整大爆炸模式模板 2021-11-21 03:52:13 +08:00
MrZ626
a4c52d9162 修正玩家创建任务第一次初始化运行的时候报错没有任何提示 2021-11-21 03:08:34 +08:00
MrZ626
592b11366e table扩展模块新增两个去重方法和反转方法 2021-11-21 03:06:00 +08:00
MrZ626
07f50b9243 调整一些文本文件 2021-11-20 03:39:05 +08:00
MrZ626
ec74d55686 整理代码 2021-11-20 03:28:58 +08:00
MrZ626
4518513e87 应用1的语音偏移半径 2021-11-20 03:28:19 +08:00
MrZ626
7df4e2144f 语音模块支持设置轻微随机音调偏移半径(默认关闭) 2021-11-20 03:27:53 +08:00
MrZ626
7f9c9248ce 版本推进 2021-11-19 17:36:12 +08:00
MrZ626
9c1db48804 整理代码 2021-11-19 17:35:53 +08:00
C₂₉H₂₅N₃O₅
0628830f0c 继续调词典(嗯) 2021-11-19 01:21:48 -06:00
C₂₉H₂₅N₃O₅
9436f2f5fb 微调词典 大改legals (#472) 2021-11-19 01:17:12 -06:00
MrZ626
c5e1b5617f 再调整词典两个词条 2021-11-19 14:21:42 +08:00
MrZ626
298c417aa3 更新部分词条(英文待翻译) 2021-11-19 02:40:46 +08:00
MrZ626
fc74831700 添加lockout判负规则(默认关闭) 2021-11-19 02:33:21 +08:00
MrZ626
d9db55de44 整理代码,修正一处多余代码忘了删 2021-11-19 02:16:34 +08:00
MrZ626
3fd205e8c2 bgm模块添加可调节的最大加载数限制,更不容易达到引擎加载音频数上限 close #447 2021-11-19 01:47:14 +08:00
MrZ626
5cb828fb92 修改策略堆叠模式的解锁路径 2021-11-19 00:59:16 +08:00
MrZ626
5f7a3fd53f 版本推进 2021-11-18 19:54:31 +08:00
MrZ626
8e3e598753 词典添加cambridge词条(翻译自tetris wiki) 2021-11-18 19:52:42 +08:00
MrZ626
2a0a0f60f8 策略堆叠的das和arr参数移到规则包 2021-11-18 19:43:18 +08:00
MrZ626
6b7d1fdf9f 策略堆叠模式添加到地图 2021-11-18 19:41:27 +08:00
MrZ626
65199a40f7 修复40行效率左侧信息颜色问题 2021-11-18 19:27:27 +08:00
MrZ626
f9082a8800 整理代码 2021-11-18 19:16:06 +08:00
NOT_A_ROBOT
1670c6e7d6 Add strategy modes (#468)
* Add strategy mode
2021-11-18 19:08:46 +08:00
NOT_A_ROBOT
ff2073ed4d fix numpadenter on console (#469)
made numpadenter do the same thing as enter on console
2021-11-18 19:08:46 +08:00
MrZ626
f14aaac635 微调staff页面 close #470 2021-11-18 19:08:46 +08:00
MrZ626
c709fa622f 修正hold模式没有英文文本 2021-11-18 19:08:45 +08:00
MrZ626
c752556bf3 微调pc联系模式左侧信息位置
继续推进大爆炸模式框架
2021-11-18 03:54:42 +08:00
MrZ626
e7d9703fcc 修复向玩家场地里塞入垃圾行时如果不存在当前方块会报错 2021-11-18 03:54:42 +08:00
C29H25N3O5
1ed52a84b0 增加半隐和全隐的英文词条 2021-11-17 11:50:04 -06:00
C29H25N3O5
4fdb278751 微调dmg背景图片 2021-11-17 11:29:41 -06:00
MrZ626
8318803923 修改一首bgm名称和一个赞助id 2021-11-18 01:07:27 +08:00
MrZ626
42de7e3676 纠正一个帮助开发的网友id 2021-11-17 22:14:40 +08:00
MrZ626
3efa646ee3 再增加堆积模式的窒息延迟 2021-11-17 22:11:50 +08:00
MrZ626
b414c2ab42 版本推进 2021-11-17 22:08:00 +08:00
MrZ626
205dea3db7 TRS的S/Z添加四个踢墙防止在一些地方卡死 2021-11-17 21:49:37 +08:00
MrZ626
6cac688555 完善提前移动词条 2021-11-17 20:48:40 +08:00
MrZ626
09b1b08c1e 堆积模式添加8f窒息延迟 2021-11-17 20:29:42 +08:00
MrZ626
b61a1270e9 生成位置预览开启后hold的生成位置也可见 2021-11-17 16:47:25 +08:00
MrZ626
b85cee7e1f 修复机翻语言超级消除没有行数显示 close #462 2021-11-17 16:30:00 +08:00
MrZ626
8e674e3e29 版本推进 2021-11-17 16:25:38 +08:00
MrZ626
aa2812c874 大爆炸模式框架完成,等待具体关卡生成算法 2021-11-17 16:24:18 +08:00
MrZ626
6f282431c4 pc训练的序列模式和旋转系统参数放入规则包 2021-11-17 16:01:09 +08:00
MrZ626
470e54cdd0 两个pc练习模式添加胜利条件,不再无尽
略微降低pc练习-普通的X评级标准
2021-11-17 16:01:08 +08:00
MrZ626
da3ef1c2a6 pc训练代码整理,开局就能看到关卡并且没有提前硬降不会死的bug了 2021-11-17 16:01:08 +08:00
MrZ626
9efe0e62d5 词典添加半隐和全隐词条(英文待翻译) 2021-11-17 16:01:08 +08:00
MrZ626
7038f81b46 调整一些tip
整理代码
2021-11-17 10:59:38 +08:00
MrZ626
de972a60df blackhole背景改名blockhole 2021-11-17 10:59:34 +08:00
MrZ626
6a87787d6f 微调github issue模板 2021-11-17 10:59:30 +08:00
MrZ626
6dc9a4b507 安全,安全!(嗯嗯嗯 2021-11-17 10:59:27 +08:00
MrZ626
5b7c888d57 修正经典模式显示的速度等级 2021-11-17 10:59:01 +08:00
MrZ626
a1f761b83e 修正一处拼写错误 2021-11-17 10:58:51 +08:00
C₂₉H₂₅N₃O₅
c40a6bfaa0 换行 (#463) 2021-11-16 14:28:30 -06:00
MrZ626
441c6f7667 再次修复安全漏洞(嗯 2021-11-17 01:15:03 +08:00
MrZ626
a07d57cf71 版本推进 2021-11-16 20:39:29 +08:00
MrZ626
a467f972f9 调整死亡延迟的称呼 2021-11-16 20:39:19 +08:00
MrZ626
3f455ee360 整理代码 2021-11-16 20:29:55 +08:00
MrZ626
7a0b913768 修复安全漏洞(确信 2021-11-16 14:47:42 +08:00
MrZ626
a7b240ade8 微调符号语言 2021-11-16 14:00:09 +08:00
C₂₉H₂₅N₃O₅
bb64404821 完善字体和符号文本 (#460) 2021-11-15 22:27:40 -06:00
MrZ626
caf92eb3c8 修正几处全半角括号 2021-11-16 11:25:16 +08:00
MrZ626
6a117a0fab 词典添加死亡延迟词条 2021-11-16 11:18:33 +08:00
MrZ626
26682509f7 添加防止死亡延时 close #459 2021-11-16 11:18:32 +08:00
C₂₉H₂₅N₃O₅
d85d92fb43 添加几种语言的赞助说明 (#458) 2021-11-15 17:06:49 -06:00
MrZ626
c412003cb3 调整关于页面信息
词典添加patreon词条
2021-11-16 03:55:57 +08:00
MrZ626
e39b5dbd51 修改中文词典的官网词条 2021-11-16 03:27:46 +08:00
MrZ626
db162ea66f 微调about信息 2021-11-16 03:27:46 +08:00
Not-A-Normal-Robot
f9f9fde368 修改 legals.md 一处拼写错误 (#457) 2021-11-15 10:57:16 -06:00
MrZ626
4b221c2eb5 版本推进 2021-11-15 15:52:16 +08:00
MrZ626
ed45bebfa0 添加转盘模块和实验性每日转盘小程序 2021-11-15 15:47:05 +08:00
MrZ626
fa0bc3805f 整理代码,Zframework添加数学扩展模块 2021-11-15 15:46:57 +08:00
MrZ626
7710f0b70f 修正词典 2021-11-15 02:13:56 +08:00
C₂₉H₂₅N₃O₅
0277ddadb5 微调词典 (#456) 2021-11-14 12:05:00 -06:00
MrZ626
88e23e32f5 piano小程序支持shift/ctrl升降半音,左右alt变调,补充更多键位 2021-11-15 02:00:04 +08:00
MrZ626
8ab5b4a17a SFX模块新增音高获取音名的方法
整理代码
2021-11-15 02:00:04 +08:00
MrZ626
503dfd69ef 再调整SFX.playSample方法,支持用数字代表绝对音高,但是移除最后的音量参数 2021-11-15 01:40:53 +08:00
ParticleG
ae61ec26c0 - Remove upload to server 2021-11-15 01:39:37 +08:00
MrZ626
00bc24bd50 新增piano小程序(目前只支持键盘操作) 2021-11-14 22:19:45 +08:00
MrZ626
abd15d6307 table扩展模块新增一个函数 2021-11-14 22:09:44 +08:00
MrZ626
c01ac546d1 再修正播放采样的超音域问题 2021-11-14 21:48:02 +08:00
MrZ626
af77221ba2 修复换准备音效播放方式后ultra模式倒计时没声 2021-11-14 17:34:41 +08:00
MrZ626
204f0938d3 播放准备音效的函数可调音量 2021-11-14 17:32:10 +08:00
MrZ626
ad39d1408c 音乐室输入首字母自动跳转 2021-11-14 17:31:49 +08:00
MrZ626
ed011173f6 版本推进 2021-11-14 16:53:43 +08:00
MrZ626
491fcb5860 添加缓冲区和消失区两个词条
Co-authored-by: C₂₉H₂₅N₃O₅ <cgu52@wisc.edu>
2021-11-14 16:45:53 +08:00
MrZ626
c2d5537d8d 经典模式添加干旱计数器 close #452 2021-11-14 16:45:50 +08:00
MrZ626
7d5037ae87 竞速-效率显示剩余行数 2021-11-14 12:37:39 +08:00
MrZ626
07d7714317 修正无尽模式标题首字母大小写错误 close #454 2021-11-14 12:19:26 +08:00
MrZ626
2cab97f37d 修复0arr时自动移动时声音特别响 2021-11-14 11:49:41 +08:00
MrZ626
d184778c9a 修正string扩展模块时间转换函数可能出现1分60(截断小数点后两位防止被向上取整) 2021-11-14 11:24:11 +08:00
MrZ626
9fd3b3008d 新增物品数据,每日登录新增加一个zTicket 2021-11-13 22:33:25 +08:00
MrZ626
71aa35b214 修正统计里的日期每次启动都被刷新了导致单日统计时间不对 2021-11-13 17:32:54 +08:00
MrZ626
4443dc9d3e table扩展模块添加一个方法(未来会整理类似数据表更新函数) 2021-11-13 17:29:17 +08:00
MrZ626
839e357301 修改更新历史 2021-11-13 16:31:46 +08:00
MrZ626
ac56c5a415 修改竞速-效率左侧信息栏 2021-11-13 16:23:27 +08:00
MrZ626
36e3343341 TRS的J5和L5新增一个180度踢墙 2021-11-13 16:14:36 +08:00
MrZ626
510f7d7513 版本推进 2021-11-13 05:42:36 +08:00
MrZ626
3128eb38c0 再调整一些模式的bgm 2021-11-13 05:41:27 +08:00
MrZ626
14ef654612 混战模式信息绘制从玩家类移到规则包 2021-11-13 05:21:59 +08:00
MrZ626
bc5193f95e 落块事件改名落块钩子
添加死亡钩子(仅在窒息和超高触发)
堆积模式消行动作挂到死亡钩子上
2021-11-13 05:20:32 +08:00
MrZ626
8cbb4a38bc dropPiece事件改名hook_drop 2021-11-12 23:20:29 +08:00
MrZ626
fce08c83ef 堆积模式移出地图,删除h难度 2021-11-12 21:17:30 +08:00
MrZ626
018e99f9e6 修正改评级文本后tip没改 2021-11-12 16:39:30 +08:00
MrZ626
7fe390b34b 赞助名单添加三位 2021-11-12 16:28:37 +08:00
MrZ626
8c7202c569 版本推进 2021-11-12 03:35:54 +08:00
MrZ626
ab386bb53c 整理代码 2021-11-12 03:30:52 +08:00
MrZ626
87c791b8c7 tips新增几个好玩的游戏 2021-11-12 02:58:17 +08:00
MrZ626
00e3e2d19d 取消准备按钮不再只显示取消两个字 2021-11-12 02:54:14 +08:00
MrZ626
8d7d5c7b04 新BGM:peak(暂未使用) 2021-11-11 19:22:45 +08:00
MrZ626
849a18e159 移除模式的颜色 2021-11-11 19:14:37 +08:00
MrZ626
a4357d0843 移除节奏模式,准备之后添加音游模式 2021-11-11 18:59:04 +08:00
MrZ626
e2b4a78b59 修正超音源音域音符处理方法 2021-11-10 21:15:50 +08:00
MrZ626
01387b5488 版本推进(修改更新历史和build号) 2021-11-10 18:30:34 +08:00
MrZ626
168e2f80b8 SFX.play新增pitch参数,playSample方法允许超过音源范围(差太多了效果不好) 2021-11-10 17:52:48 +08:00
MrZ626
4f79ef8708 改进一处材质缺失后的报错 2021-11-10 16:40:00 +08:00
MrZ626
16497833df 修正COLOR.hsv函数s小于0时漏返回透明度 close #445 2021-11-10 14:35:22 +08:00
MrZ626
cd6a50d5a0 修复词典导出词条保留了替换敏感词的特殊字符 2021-11-10 14:35:22 +08:00
C₂₉H₂₅N₃O₅
4c5a61f2d8 修改License相关内容 (#444) 2021-11-09 21:38:45 -06:00
C29H25N3O5
1fd8d39970 更换中文字形 2021-11-09 18:57:35 -06:00
MrZ626
d133d64890 目标分数显示器分割线长度微调 2021-11-09 23:16:33 +08:00
MrZ626
b27aa8b60d freeRow模块改名line模块并暂时在“行”的管理上不再那么节约地使用内存 2021-11-09 20:14:08 +08:00
MrZ626
230d67492e 测试场景左上文本从最晚的开始显示 close #437 2021-11-09 16:04:08 +08:00
MrZ626
4f9d5b282c 修正一个开发者id写法问题 2021-11-09 16:04:08 +08:00
ParticleG
a2955e8722 - Fix wrong action name 2021-11-09 16:04:07 +08:00
MrZ626
df892671d5 修改更新历史和build号 2021-11-09 16:04:07 +08:00
MrZ626
7fa96eee1a 被攻击时场地会抖动 2021-11-09 16:04:07 +08:00
MrZ626
a1030906c7 场地晃动改名swing
添加场地抖动特效(跟场地晃动使用同一个设置值)
2021-11-09 16:04:07 +08:00
MrZ626
e6a9a4f4be 微调wine颜色,dark颜色更dark 2021-11-09 16:04:07 +08:00
MrZ626
efa1247596 颜色表的灰色饱和度更低并改为偏暖 2021-11-09 16:04:07 +08:00
MrZ626
069fcee721 整理代码
移除旧的切换攻击模式代码
旋转导致场地倾斜封装成玩家方法
调整瞬移到左右的场地晃动程度
调整场地平移晃动的恢复速度
软降触地时也会播放触地音效
2021-11-09 16:04:07 +08:00
C₂₉H₂₅N₃O₅
66621404f1 Changed the colours and the fonts in the game (#435)
* 微调字体

* 调整配色, 微调字体
2021-11-09 16:04:06 +08:00
ParticleG
e09609ea21 - Use Python 3.9 2021-11-09 16:04:06 +08:00
ParticleG
d02ae67bc0 - Add logs to upload-artifact 2021-11-09 16:04:06 +08:00
ParticleG
27327d57c4 - Test Windows with curl 2021-11-09 16:04:06 +08:00
MrZ626
cce93b6df9 整理代码 2021-11-09 16:04:06 +08:00
ParticleG
546104ba5b - Add Upload Action 2021-11-09 16:04:06 +08:00
MrZ626
ca5816ba14 进入newRoom菜单时不会试图修改背景和bgm 2021-11-09 16:04:06 +08:00
MrZ626
e5bd16476e 修改更新历史和build号 2021-11-09 16:04:05 +08:00
MrZ626
94431d4c2e 只在更新后触发自动转换以旧版本模式名存储的数据文件 2021-11-09 16:04:05 +08:00
MrZ626
f98d6892f1 颜色表改用hsv生成 2021-11-09 16:04:05 +08:00
MrZ626
1fe436cbe3 微调词典
微调两个小程序
整理代码
2021-11-09 16:04:05 +08:00
MrZ626
c5a37a9920 微调中文词典两个词条 2021-11-09 16:04:05 +08:00
MrZ626
eed7e96096 无尽马拉松的are每300行减小一次,line are每100行减小一次 2021-11-09 16:04:05 +08:00
MrZ626
a7f36a4162 无尽马拉松添加1700行的终点 2021-11-09 16:04:05 +08:00
MrZ626
8ba872d45d 微调排行榜字体大小 2021-11-09 16:04:04 +08:00
MrZ626
7a55451faa 无尽马拉松添加排行榜 2021-11-09 16:04:04 +08:00
MrZ626
372571bd80 修改更新历史
整理代码
2021-11-09 16:04:04 +08:00
MrZ626
77120c0b90 调整无尽马拉松的难度曲线 2021-11-09 16:04:04 +08:00
Not-A-Normal-Robot
01d1e44644 Decrease lock delay when level up above lvl20 2021-11-09 16:04:04 +08:00
Not-A-Normal-Robot
0ad8cddefe Added Infinite Marathon 2021-11-09 16:04:03 +08:00
MrZ626
ce67253502 修改更新历史 2021-11-09 16:04:03 +08:00
MrZ626
cb9f2c0617 修改mph模式的bgm 2021-11-09 16:04:03 +08:00
MrZ626
635d9407ed 新模式:竞速-效率 2021-11-09 16:04:03 +08:00
MrZ626
0f9f6565f1 修复超级消除结算时分数计算变量写错导致报错 2021-11-09 16:04:03 +08:00
MrZ626
a45b6ad57e move音效在方块因重力或旋转触地时也会播放,而不只是移动后
move音效名改为touch
2021-11-09 16:04:03 +08:00
MrZ626
a5de06dedb 修改更新历史 2021-11-09 16:04:03 +08:00
MrZ626
fbfbd1ed98 修正pr的一个符号错误 2021-11-09 16:04:02 +08:00
C₂₉H₂₅N₃O₅
8f06b3bd1a Changed the font and CN tips (#433)
* 补全英文词典翻译

* 大改字体

- 西文部分采用IBM Plex
- 全角标点样式采用西文样式
- 添加类Plex的IPA符号

* 微调中文tips

* 更新 Legals

* 修正一个语法错误
2021-11-09 16:04:02 +08:00
C₂₉H₂₅N₃O₅
7e0dbceefc 补全英文词典翻译 (#431) 2021-11-09 16:04:02 +08:00
MrZ626
7e3db1de17 新BGM:1989(用于几个经典模式)
重新安排一些模式的BGM
2021-11-09 16:04:02 +08:00
MrZ626
111790fdab 修正自动打包没有把legals.md和license.txt文件放进去 2021-11-06 03:27:09 +08:00
MrZ626
bec03de7b8 纠正几个错别字 2021-11-06 00:50:12 +08:00
MrZ626
f5dfae3a6c 词典新增deepdrop词条 2021-11-06 00:40:04 +08:00
MrZ626
d3dec2b5f1 更新版本号为0.17.0,追加更新历史 2021-11-06 00:39:50 +08:00
MrZ626
f083136998 整理代码 2021-11-05 11:02:45 +08:00
MrZ626
cd3d0b370c 修改一些词典词条 2021-11-05 10:36:49 +08:00
MrZ626
f4c6632941 降低无旋转40L评级标准 2021-11-04 21:57:24 +08:00
MrZ626
750cb9a669 调整繁中一些用词
微调语言菜单按钮文本大小
2021-11-04 21:50:05 +08:00
C₂₉H₂₅N₃O₅
62a198a017 添加繁体中文语言, 语言切换界面变更颜色和布局 (#429) 2021-11-04 21:39:05 +08:00
MrZ626
5780ba0f3e 词典other分类改为org并移到开始的help版块后
词典新增一个词条等待翻译
2021-11-04 19:40:42 +08:00
ParticleG
86edeb1e0c - Fix wrong upload file suffix 2021-11-04 16:12:48 +08:00
Particle_G
53b1852f28 Rel ios test (#427)
* - Test Release note

* - Test ios changelog

* - Finish touching
2021-11-04 04:01:12 +08:00
MrZ626
e3c385693b 修改更新历史和build号 2021-11-03 19:45:23 +08:00
MrZ626
572c0fbfa1 调整方块朝向菜单彩蛋模式进入方式 2021-11-03 19:43:36 +08:00
MrZ626
bbdf71167a 调整录像回放菜单按钮尺寸 2021-11-03 19:14:43 +08:00
MrZ626
2136ccd9a2 更新词典中的一些玩家信息 2021-11-03 15:46:46 +08:00
MrZ626
2131aea575 玩家类添加一个目标线绘制函数
堆叠模式添加需要填满的高度线
2021-11-03 15:41:13 +08:00
MrZ626
32b21c7d29 修改更新历史 2021-11-03 13:37:58 +08:00
MrZ626
8f6f6f316f 微调倒计时动画 2021-11-03 13:33:44 +08:00
MrZ626
66f9ac2791 修复无尽挖掘开局垃圾行可能会在同一列 2021-11-03 13:21:51 +08:00
MrZ626
ac0ba90438 修复wing背景颜色配置问题 2021-11-03 13:21:37 +08:00
MrZ626
990659ce91 修改更新历史和build号 2021-11-03 02:42:38 +08:00
MrZ626
00c602c844 再调整超级消除音效
调整launchpad
2021-11-03 02:40:21 +08:00
MrZ626
9db62ffc39 调整堆叠模式平衡 2021-11-03 02:33:31 +08:00
MrZ626
e7c777e502 超级消除有分数了
再调整超级消除的声音
2021-11-02 22:17:44 +08:00
MrZ626
4991e8cea2 优化堆叠模式体验,微调难度和评级 2021-11-02 20:15:23 +08:00
MrZ626
111d4e991f 微调单次超大消除相关的文本和效果 2021-11-02 19:37:50 +08:00
MrZ626
bedfa74a32 整理代码 2021-11-02 19:34:46 +08:00
MrZ626
f6944dc223 微调test模块 2021-11-02 17:39:23 +08:00
MrZ626
a34a3051a3 Merge remote-tracking branch 'tech/ci-autotest' into HEAD 2021-11-02 17:39:13 +08:00
MrZ626
0e13883faf 修改更新历史和build号 2021-11-02 17:21:36 +08:00
MrZ626
e8860eda1b 消除超过6行时部分语言会小字显示消的行数 2021-11-02 17:21:36 +08:00
MrZ626
33ba4820b3 音效室补充消除音效 2021-11-02 17:21:36 +08:00
MrZ626
5ed0dda8ab 修改一处中文语言里的BGM忘了改 2021-11-02 17:21:36 +08:00
MrZ626
bd260b2c6f 消除所有填满行的函数整理为玩家类的clearFilledLines方法
添加消7~20和20+的消除文本与消除音效
播放消n音效打包为函数移至gameFuncs文件
2021-11-02 17:21:36 +08:00
MrZ626
aa01ab07f7 英文词典补充一条翻译
Co-authored-by: C29H25N3O5 <a1228465111@163.com>
2021-11-02 17:21:35 +08:00
Trebor-Huang
c009893377 New part in Zframework 2021-11-01 10:14:09 +08:00
Trebor-Huang
3ae128d4c3 Revert init.lua 2021-11-01 10:00:39 +08:00
Trebor-Huang
cb2164c21d Fix string bug 2021-11-01 09:57:12 +08:00
Trebor-Huang
951b7407fc Keep up the pace 2021-11-01 09:52:41 +08:00
Trebor Huang
5a1fd0ca4d Correct semantic merge 2021-11-01 01:43:05 +08:00
Trebor Huang
f4b85e0dbb Merge branch 'main' into ci-autotest 2021-10-31 23:51:40 +08:00
Trebor-Huang
c38bceb87e Yay it works 2021-10-31 23:38:15 +08:00
Trebor-Huang
2569e8844e Test dummy failure 2021-10-31 23:36:44 +08:00
Trebor-Huang
e42fa8351e Can't get xvfb to return the correct value? 2021-10-31 23:35:12 +08:00
Trebor-Huang
9582a625ff Add shell 2021-10-31 23:20:33 +08:00
Trebor-Huang
81abb06f7b Add shell 2021-10-31 23:19:04 +08:00
Trebor-Huang
7cfea0eebe Try using composite 2021-10-31 23:15:57 +08:00
Trebor-Huang
01c2bfe955 Remove uneccesary needs 2021-10-31 22:51:12 +08:00
Trebor-Huang
70242e6a07 Add some more utils 2021-10-31 21:23:54 +08:00
Trebor-Huang
c1edba974f Maybe update first 2021-10-31 20:47:23 +08:00
Trebor-Huang
546b3f230d Prepare PulseAudio 2021-10-31 20:45:23 +08:00
Trebor-Huang
14593eb487 Okay ubuntu doesn't allow gui either 2021-10-31 20:27:03 +08:00
Trebor-Huang
838621a3ae Try without xvfb first 2021-10-31 20:23:34 +08:00
Trebor-Huang
283d4a5fce Test xvfb 2021-10-31 20:04:54 +08:00
Trebor-Huang
490cf44132 Change iOS ci condition 2021-10-31 19:41:36 +08:00
Trebor-Huang
9dcbd86fc3 Implement auto test 2021-10-31 19:03:05 +08:00
384 changed files with 9869 additions and 5503 deletions

View File

@@ -2,8 +2,7 @@
name: Bug report (bluescreen crash) Bug报告 (蓝屏报错)
about: Create a report of problems which made the crash with a bluescreen
---
Screenshot with crash information: (delete this line before submitting)
*Image Here*
Screenshot with crash information (*Image(s) Here*):
If you can reproduce it, write the steps here. If you can't, try to describe the exactly time the game crash, like pressing which key or which button: (delete this line before submitting)
*Details Here*
If you can reproduce it, write the steps here. If you can't, try to describe the exactly time the game crash, like pressing which key or which button (*Details Here*)

View File

@@ -2,8 +2,7 @@
name: Bug report (unintended behaviors) Bug报告 (奇怪的现象)
about: Create a report of unintended behaviors
---
Screenshot with unintended behaviors: (delete this line before submitting)
*Image(s) Here*
Screenshot with unintended behaviors (*Image(s) Here*):
If you can reproduce it, write the steps here. If you can't, try to describe the exactly time the game crash, like pressing which key or which button: (delete this line before submitting)
*Details Here*
If you can reproduce it, write the steps here. If you can't, try to describe the exactly time the game crash, like pressing which key or which button (*Details Here*):

View File

@@ -0,0 +1,24 @@
name: 'Automatic Test'
description: 'Check for obvious errors.'
runs:
using: "composite"
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/build-love
with:
file-path: Techmino.love
- name: Download love
shell: bash
run: |
curl -L https://github.com/love2d/love/releases/download/11.3/love-11.3-linux-x86_64.tar.gz | tar xz
- name: Prepare PulseAudio
shell: bash
run: |
sudo apt-get update
sudo apt-get install pulseaudio pulseaudio-utils pavucontrol alsa-oss alsa-utils -y
- name: Run automated test
uses: GabrielBB/xvfb-action@v1
with:
run: |
./dest/love Techmino.love --test

View File

@@ -33,7 +33,7 @@ runs:
cp squashfs-root/icon.png squashfs-root/.DirIcon
chmod 777 squashfs-root/love
mkdir -p squashfs-root/usr/share/Techmino
mv media parts Zframework conf.lua main.lua version.lua squashfs-root/usr/share/Techmino
mv media parts Zframework conf.lua main.lua version.lua legals.md license.txt squashfs-root/usr/share/Techmino
mv CCloader.so squashfs-root/usr/share/Techmino
mv libcold_clear.so squashfs-root/usr/lib
chmod 777 appimagetool-x86_64.AppImage

View File

@@ -7,5 +7,5 @@ inputs:
runs:
using: "composite"
steps:
- run: 7z a -tzip ${{ inputs.file-path }} media parts Zframework conf.lua main.lua version.lua
- run: 7z a -tzip ${{ inputs.file-path }} media parts Zframework conf.lua main.lua version.lua legals.md license.txt
shell: bash

Binary file not shown.

View File

@@ -27,6 +27,12 @@ jobs:
echo "::set-output name=code::$(lua .github/workflows/getVersion.lua -code)"
echo "::set-output name=commit::$(git rev-parse --short ${{ GITHUB.SHA }})"
automatic-test:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/automatic-test
build-windows:
runs-on: windows-latest
needs: get-info
@@ -91,6 +97,34 @@ jobs:
with:
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_Android
path: Techmino_Snapshot.apk
build-android-mini:
runs-on: ubuntu-20.04
needs: get-info
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/update-version
with:
commit: ${{ needs.get-info.outputs.commit }}
type: snapshot
- name: remove media
run: |
rm -rf media/music media/effect media/vocal
- uses: ./.github/actions/build-android
with:
type: Snapshot
apkCode: ${{ needs.get-info.outputs.apkCode }}
name: ${{ needs.get-info.outputs.name }}
file-path: Techmino_Snapshot_Mini.apk
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
ALIAS: ${{ secrets.ALIAS }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
- name: Upload
uses: actions/upload-artifact@v2
with:
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_Android_Mini
path: Techmino_Snapshot_Mini.apk
build-macOS:
runs-on: macos-10.15
@@ -121,6 +155,7 @@ jobs:
build-iOS:
runs-on: macos-latest
if: (!startsWith( github.ref , 'refs/heads/ci-')) || startsWith( github.ref , 'refs/heads/ci-ios-')
needs: get-info
steps:
- uses: actions/checkout@v2
@@ -150,4 +185,19 @@ jobs:
uses: actions/upload-artifact@v2
with:
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_iOS
path: "Techmino.ipa"
path: Techmino.ipa
build-love:
runs-on: ubuntu-20.04
needs: get-info
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/update-version
- uses: ./.github/actions/build-love
with:
file-path: Techmino.love
- name: Upload
uses: actions/upload-artifact@v2
with:
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_Love
path: Techmino.love

View File

@@ -1,22 +1,23 @@
if arg[1]=="-apkCode"then
local arg=arg[1]
if arg=="-apkCode"then
local code=require"version".apkCode
print(code)
elseif arg[1]=="-code"then
elseif arg=="-code"then
local str=require"version".code
print(str)
elseif arg[1]=="-name"then
elseif arg=="-name"then
local str=require"version".string
print(str)
elseif arg[1]=="-release"then
elseif arg=="-release"then
local str=require"version".string:gsub("V","",1)
print(str)
elseif arg[1]=="-updateTitle"then
elseif arg=="-updateTitle"then
local note=require"parts.updateLog"
local p1=note:find("\n%d")+1
local p2=note:find("\n",p1)-1
note=note:sub(p1,p2)
print(note)
elseif arg[1]=="-updateNote"then
elseif arg=="-updateNote"then
local note=require"parts.updateLog"
local p1=note:find("\n",note:find("\n%d")+1)+1
local p2=note:find("\n%d",p1+1)

View File

@@ -3,7 +3,7 @@ name: Techmino Release CI
on:
push:
tags:
- 'v*'
- "v*"
jobs:
get-info:
@@ -14,218 +14,176 @@ jobs:
code: ${{ steps.actual-get-info.outputs.code }}
release: ${{ steps.actual-get-info.outputs.release }}
updateTitle: ${{ steps.actual-get-info.outputs.updateTitle }}
updateNote: ${{ steps.actual-get-info.outputs.updateNote }}
commit: ${{ steps.actual-get-info.outputs.commit }}
steps:
- uses: actions/checkout@v2
- name: Install lua
run: |
sudo apt-get install lua5.3 -y
- name: Get Version
id: actual-get-info
run: |
echo "::set-output name=name::$(lua .github/workflows/getVersion.lua -name)"
echo "::set-output name=apkCode::$(lua .github/workflows/getVersion.lua -apkCode)"
echo "::set-output name=code::$(lua .github/workflows/getVersion.lua -code)"
echo "::set-output name=release::$(lua .github/workflows/getVersion.lua -release)"
echo "::set-output name=updateTitle::$(lua .github/workflows/getVersion.lua -updateTitle)"
echo "::set-output name=commit::$(git rev-parse --short ${{ GITHUB.SHA }})"
- uses: actions/checkout@v2
- name: Install lua
run: |
sudo apt-get install lua5.3 -y
- name: Get Version
id: actual-get-info
run: |
UPDATE_NOTE=$(lua .github/workflows/getVersion.lua -updateNote)
UPDATE_NOTE="${UPDATE_NOTE//'%'/'%25'}"
UPDATE_NOTE="${UPDATE_NOTE//$'\n'/'%0A'}"
UPDATE_NOTE="${UPDATE_NOTE//$'\r'/'%0D'}"
echo "::set-output name=name::$(lua .github/workflows/getVersion.lua -name)"
echo "::set-output name=apkCode::$(lua .github/workflows/getVersion.lua -apkCode)"
echo "::set-output name=code::$(lua .github/workflows/getVersion.lua -code)"
echo "::set-output name=release::$(lua .github/workflows/getVersion.lua -release)"
echo "::set-output name=updateTitle::$(lua .github/workflows/getVersion.lua -updateTitle)"
echo "::set-output name=updateNote::$UPDATE_NOTE"
echo "::set-output name=commit::$(git rev-parse --short ${{ GITHUB.SHA }})"
build-windows-x64:
runs-on: windows-latest
needs: get-info
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/update-version
- uses: ./.github/actions/build-windows
with:
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win64.zip
love-dir: love-11.3-win64
arch: win64
version: ${{ needs.get-info.outputs.release }}
icon: .\.github\build\Windows\icon.ico
- name: Pack Techmino
run: 7z a -tzip .\Techmino.a${{ needs.get-info.outputs.release }}.Win64.zip .\love
- name: Release
uses: softprops/action-gh-release@v1
with:
name: ${{ needs.get-info.outputs.updateTitle }}
files: Techmino.a${{ needs.get-info.outputs.release }}.Win64.zip
- uses: actions/checkout@v2
- uses: ./.github/actions/update-version
- uses: ./.github/actions/build-windows
with:
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win64.zip
love-dir: love-11.3-win64
arch: win64
version: ${{ needs.get-info.outputs.release }}
icon: .\.github\build\Windows\icon.ico
- name: Pack Techmino
run: 7z a -tzip .\Techmino_a${{ needs.get-info.outputs.release }}_Win64.zip .\love
- name: Release
uses: softprops/action-gh-release@v1
with:
name: ${{ needs.get-info.outputs.updateTitle }}
files: Techmino_a${{ needs.get-info.outputs.release }}_Win64.zip
build-windows-x86:
runs-on: windows-latest
needs: get-info
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/update-version
- uses: ./.github/actions/build-windows
with:
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win32.zip
love-dir: love-11.3-win32
arch: win32
version: ${{ needs.get-info.outputs.release }}
icon: .\.github\build\Windows\icon.ico
- name: Pack Techmino
run: 7z a -tzip .\Techmino.a${{ needs.get-info.outputs.release }}.Win32.zip .\love
- name: Release
uses: softprops/action-gh-release@v1
with:
name: ${{ needs.get-info.outputs.updateTitle }}
files: Techmino.a${{ needs.get-info.outputs.release }}.Win32.zip
- uses: actions/checkout@v2
- uses: ./.github/actions/update-version
- uses: ./.github/actions/build-windows
with:
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win32.zip
love-dir: love-11.3-win32
arch: win32
version: ${{ needs.get-info.outputs.release }}
icon: .\.github\build\Windows\icon.ico
- name: Pack Techmino
run: 7z a -tzip .\Techmino_a${{ needs.get-info.outputs.release }}_Win32.zip .\love
- name: Release
uses: softprops/action-gh-release@v1
with:
name: ${{ needs.get-info.outputs.updateTitle }}
files: Techmino_a${{ needs.get-info.outputs.release }}_Win32.zip
build-linux:
runs-on: ubuntu-20.04
needs: get-info
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/update-version
- uses: ./.github/actions/build-linux
with:
file-path: Techmino.a${{ needs.get-info.outputs.release }}.AppImage
icon: .github/build/Linux/icon.png
- name: Release
uses: softprops/action-gh-release@v1
with:
name: ${{ needs.get-info.outputs.updateTitle }}
files: Techmino.a${{ needs.get-info.outputs.release }}.AppImage
- uses: actions/checkout@v2
- uses: ./.github/actions/update-version
- uses: ./.github/actions/build-linux
with:
file-path: Techmino_a${{ needs.get-info.outputs.release }}_Linux.AppImage
icon: .github/build/Linux/icon.png
- name: Release
uses: softprops/action-gh-release@v1
with:
name: ${{ needs.get-info.outputs.updateTitle }}
files: Techmino_a${{ needs.get-info.outputs.release }}_Linux.AppImage
build-android:
runs-on: ubuntu-20.04
needs: get-info
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/update-version
- uses: ./.github/actions/build-android
with:
type: Release
apkCode: ${{ needs.get-info.outputs.apkCode }}
name: ${{ needs.get-info.outputs.name }}
file-path: Techmino.a${{ needs.get-info.outputs.release }}.apk
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
ALIAS: ${{ secrets.ALIAS }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
- name: Release
uses: softprops/action-gh-release@v1
with:
name: ${{ needs.get-info.outputs.updateTitle }}
files: Techmino.a${{ needs.get-info.outputs.release }}.apk
build-android-mini:
runs-on: ubuntu-20.04
needs: get-info
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/update-version
- name: remove media
run: |
rm -rf media/music media/effect media/vocal
- uses: ./.github/actions/build-android
with:
type: Release
apkCode: ${{ needs.get-info.outputs.apkCode }}
name: ${{ needs.get-info.outputs.name }}
file-path: Techmino.a${{ needs.get-info.outputs.release }}.mini.apk
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
ALIAS: ${{ secrets.ALIAS }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
- name: Release
uses: softprops/action-gh-release@v1
with:
name: ${{ needs.get-info.outputs.updateTitle }}
files: Techmino.a${{ needs.get-info.outputs.release }}.mini.apk
- uses: actions/checkout@v2
- uses: ./.github/actions/update-version
- uses: ./.github/actions/build-android
with:
type: Release
apkCode: ${{ needs.get-info.outputs.apkCode }}
name: ${{ needs.get-info.outputs.name }}
file-path: Techmino_a${{ needs.get-info.outputs.release }}_Android.apk
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
ALIAS: ${{ secrets.ALIAS }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
- name: Release
uses: softprops/action-gh-release@v1
with:
name: ${{ needs.get-info.outputs.updateTitle }}
files: Techmino_a${{ needs.get-info.outputs.release }}_Android.apk
build-macOS:
runs-on: macos-10.15
needs: get-info
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/update-version
- uses: ./.github/actions/build-macos
with:
name: ${{ needs.get-info.outputs.name }}
icon: .github/build/macOS/icon.icns
APPLE_API_ID: '${{ secrets.APPLE_API_ID }}'
APPLE_API_ISSUER: '${{ secrets.APPLE_API_ISSUER }}'
APPLE_API_KEY: '${{ secrets.APPLE_API_KEY }}'
APPLE_APP_IDENTIFIER: '${{ secrets.APPLE_APP_IDENTIFIER }}'
APPLE_KEYCHAIN_NAME: '${{ secrets.APPLE_KEYCHAIN_NAME }}'
APPLE_KEYCHAIN_PWD: '${{ secrets.APPLE_KEYCHAIN_PWD }}'
FASTLANE_MATCH_PWD: '${{ secrets.FASTLANE_MATCH_PWD }}'
FASTLANE_MATCH_TOKEN: '${{ secrets.FASTLANE_MATCH_TOKEN }}'
- name: Pack Techmino
run: |
mv Techmino.dmg Techmino.a${{ needs.get-info.outputs.release }}.macOS.dmg
- name: Release
uses: softprops/action-gh-release@v1
with:
name: ${{ needs.get-info.outputs.updateTitle }}
files: Techmino.a${{ needs.get-info.outputs.release }}.macOS.zip
- uses: actions/checkout@v2
- uses: ./.github/actions/update-version
- uses: ./.github/actions/build-macos
with:
name: ${{ needs.get-info.outputs.name }}
icon: .github/build/macOS/icon.icns
APPLE_API_ID: "${{ secrets.APPLE_API_ID }}"
APPLE_API_ISSUER: "${{ secrets.APPLE_API_ISSUER }}"
APPLE_API_KEY: "${{ secrets.APPLE_API_KEY }}"
APPLE_APP_IDENTIFIER: "${{ secrets.APPLE_APP_IDENTIFIER }}"
APPLE_KEYCHAIN_NAME: "${{ secrets.APPLE_KEYCHAIN_NAME }}"
APPLE_KEYCHAIN_PWD: "${{ secrets.APPLE_KEYCHAIN_PWD }}"
FASTLANE_MATCH_PWD: "${{ secrets.FASTLANE_MATCH_PWD }}"
FASTLANE_MATCH_TOKEN: "${{ secrets.FASTLANE_MATCH_TOKEN }}"
- name: Pack Techmino
run: |
mv Techmino.dmg Techmino_a${{ needs.get-info.outputs.release }}_MacOS.dmg
- name: Release
uses: softprops/action-gh-release@v1
with:
name: ${{ needs.get-info.outputs.updateTitle }}
files: Techmino_a${{ needs.get-info.outputs.release }}_MacOS.dmg
build-iOS:
runs-on: macos-latest
needs: get-info
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/update-version
- uses: ./.github/actions/build-ios
with:
name: ${{ needs.get-info.outputs.name }}
type: 'release'
APPLE_API_ID: '${{ secrets.APPLE_API_ID }}'
APPLE_API_ISSUER: '${{ secrets.APPLE_API_ISSUER }}'
APPLE_API_KEY: '${{ secrets.APPLE_API_KEY }}'
APPLE_APP_BUILD: '${{ needs.get-info.outputs.code }}.0.${{ github.run_number }}.${{ github.run_attempt }}'
APPLE_APP_CHANGELOG: '${{ github.event.commits[0].message }}'
APPLE_APP_ID: '${{ secrets.APPLE_APP_ID }}'
APPLE_APP_IDENTIFIER: '${{ secrets.APPLE_APP_IDENTIFIER }}'
APPLE_APP_PROFILE: '${{ secrets.APPLE_APP_PROFILE }}'
APPLE_KEYCHAIN_NAME: '${{ secrets.APPLE_KEYCHAIN_NAME }}'
APPLE_KEYCHAIN_PWD: '${{ secrets.APPLE_KEYCHAIN_PWD }}'
FASTLANE_ACTION_ID: '${{ github.run_id }}'
FASTLANE_DISCORD_WEBHOOK: '${{ secrets.FASTLANE_DISCORD_WEBHOOK }}'
FASTLANE_MATCH_PWD: '${{ secrets.FASTLANE_MATCH_PWD }}'
FASTLANE_MATCH_TOKEN: '${{ secrets.FASTLANE_MATCH_TOKEN }}'
- name: Rename ipa
shell: bash
run: |
mv Techmino.ipa Techmino.a${{ needs.get-info.outputs.release }}.ipa
- name: Release
uses: softprops/action-gh-release@v1
with:
name: ${{ needs.get-info.outputs.updateTitle }}
files: Techmino.a${{ needs.get-info.outputs.release }}.ipa
build-love:
runs-on: ubuntu-20.04
needs: get-info
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/update-version
- uses: ./.github/actions/build-love
with:
file-path: Techmino.a${{ needs.get-info.outputs.release }}.love
- name: Release
uses: softprops/action-gh-release@v1
with:
name: ${{ needs.get-info.outputs.updateTitle }}
files: Techmino.a${{ needs.get-info.outputs.release }}.love
- uses: actions/checkout@v2
- uses: ./.github/actions/update-version
- uses: ./.github/actions/build-ios
with:
name: ${{ needs.get-info.outputs.name }}
type: "release"
APPLE_API_ID: "${{ secrets.APPLE_API_ID }}"
APPLE_API_ISSUER: "${{ secrets.APPLE_API_ISSUER }}"
APPLE_API_KEY: "${{ secrets.APPLE_API_KEY }}"
APPLE_APP_BUILD: "${{ needs.get-info.outputs.code }}.0.${{ github.run_number }}.${{ github.run_attempt }}"
APPLE_APP_CHANGELOG: "${{ needs.get-info.outputs.updateNote }}"
APPLE_APP_ID: "${{ secrets.APPLE_APP_ID }}"
APPLE_APP_IDENTIFIER: "${{ secrets.APPLE_APP_IDENTIFIER }}"
APPLE_APP_PROFILE: "${{ secrets.APPLE_APP_PROFILE }}"
APPLE_KEYCHAIN_NAME: "${{ secrets.APPLE_KEYCHAIN_NAME }}"
APPLE_KEYCHAIN_PWD: "${{ secrets.APPLE_KEYCHAIN_PWD }}"
FASTLANE_ACTION_ID: "${{ github.run_id }}"
FASTLANE_DISCORD_WEBHOOK: "${{ secrets.FASTLANE_DISCORD_WEBHOOK }}"
FASTLANE_MATCH_PWD: "${{ secrets.FASTLANE_MATCH_PWD }}"
FASTLANE_MATCH_TOKEN: "${{ secrets.FASTLANE_MATCH_TOKEN }}"
- name: Rename ipa
shell: bash
run: |
mv Techmino.ipa Techmino_a${{ needs.get-info.outputs.release }}_iOS.ipa
- name: Release
uses: softprops/action-gh-release@v1
with:
name: ${{ needs.get-info.outputs.updateTitle }}
files: Techmino_a${{ needs.get-info.outputs.release }}_iOS.ipa
Add-Release-note:
runs-on: ubuntu-20.04
needs: get-info
steps:
- uses: actions/checkout@v2
- name: Install lua
run: |
sudo apt-get update -y
sudo apt-get upgrade -y
sudo apt-get install lua5.3 -y
- name: Get ReleaseNote
run: |
lua .github/workflows/getVersion.lua -updateNote > updateNote.txt
- name: Release
uses: softprops/action-gh-release@v1
with:
name: ${{ needs.get-info.outputs.updateTitle }}
body_path: updateNote.txt
- uses: actions/checkout@v2
- name: Release
uses: softprops/action-gh-release@v1
with:
name: ${{ needs.get-info.outputs.updateTitle }}
body: ${{ needs.get-info.outputs.updateNote }}

View File

@@ -47,9 +47,9 @@ jobs:
- name: Upload
uses: actions/upload-artifact@v2
with:
name: Techmino.pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}.Windows
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Windows
path: love
build-linux:
runs-on: ubuntu-20.04
needs: get-info
@@ -65,7 +65,7 @@ jobs:
- name: Upload
uses: actions/upload-artifact@v2
with:
name: Techmino.pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}.Linux
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Linux
path: Techmino.AppImage
build-android:
@@ -90,7 +90,7 @@ jobs:
- name: Upload
uses: actions/upload-artifact@v2
with:
name: Techmino.pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}.Android
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Android
path: Techmino_Snapshot.apk
build-macOS:
@@ -117,7 +117,7 @@ jobs:
- name: Upload
uses: actions/upload-artifact@v2
with:
name: Techmino.pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}.macOS
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_MacOS
path: Techmino.dmg
build-iOS:
@@ -150,5 +150,5 @@ jobs:
- name: Upload
uses: actions/upload-artifact@v2
with:
name: Techmino.pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}.iOS
path: "Techmino.ipa"
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_iOS
path: Techmino.ipa

View File

@@ -4,8 +4,9 @@ local BGs={
}
local BGlist={'none'}
local BG={
cur='none',
default='none',
locked=false,
cur='none',
init=false,
resize=false,
update=NULL,
@@ -14,6 +15,8 @@ local BG={
discard=NULL,
}
function BG.lock()BG.locked=true end
function BG.unlock()BG.locked=false end
function BG.add(name,bg)
BGs[name]=bg
BGlist[#BGlist+1]=name
@@ -21,6 +24,9 @@ end
function BG.getList()
return BGlist
end
function BG.remList(name)
table.remove(BGlist,TABLE.find(BGlist,name))
end
function BG.send(...)
if BG.event then
BG.event(...)
@@ -29,20 +35,20 @@ end
function BG.setDefault(bg)
BG.default=bg
end
function BG.set(background)
background=background or BG.default
if not BGs[background]or not SETTING.bg then return end
if background~=BG.cur then
function BG.set(name)
name=name or BG.default
if not BGs[name]or BG.locked then return end
if name~=BG.cur then
BG.discard()
BG.cur=background
background=BGs[background]
BG.cur=name
local bg=BGs[name]
BG.init= background.init or NULL
BG.resize= background.resize or NULL
BG.update= background.update or NULL
BG.draw= background.draw or NULL
BG.event= background.event or NULL
BG.discard=background.discard or NULL
BG.init= bg.init or NULL
BG.resize= bg.resize or NULL
BG.update= bg.update or NULL
BG.draw= bg.draw or NULL
BG.event= bg.event or NULL
BG.discard=bg.discard or NULL
BG.init()
end
return true

View File

@@ -1,17 +1,74 @@
local Sources={}
local lastLoaded={}
local maxLoadedCount=3
local nameList={}
local SourceObjList={}
local volume=1
local BGM={
default=false,
getList=function()error("Cannot getList before initialize!")end,
getCount=function()return 0 end,
play=NULL,
stop=NULL,
onChange=NULL,
--nowPlay=[str:playing ID]
--playing=[src:playing SRC]
--lastPlayed=[str:lastPlayed ID]
}
function BGM.getList()return nameList end
function BGM.getCount()return #nameList end
local function _addFile(name,path)
if not SourceObjList[name]then
table.insert(nameList,name)
SourceObjList[name]={path=path,source=false}
end
end
function BGM.load(name,path)
if type(name)=='table'then
for k,v in next,name do
_addFile(k,v)
end
else
_addFile(name,path)
end
table.sort(nameList)
LOG(BGM.getCount().." BGM files added")
end
local function _tryReleaseSources()
local n=#lastLoaded
while #lastLoaded>maxLoadedCount do
local name=lastLoaded[n]
if SourceObjList[name].source:isPlaying()then
n=n-1
if n<=0 then return end
else
SourceObjList[name].source=SourceObjList[name].source:release()and nil
table.remove(lastLoaded,n)
return
end
end
end
function BGM.setDefault(bgm)
BGM.default=bgm
end
function BGM.setMaxSources(count)
maxLoadedCount=count
_tryReleaseSources()
end
function BGM.setChange(func)
BGM.onChange=func
end
function BGM.setVol(v)
assert(type(v)=='number'and v>=0 and v<=1,'Wrong volume')
volume=v
if BGM.playing then
if volume>0 then
BGM.playing:setVolume(volume)
BGM.playing:play()
elseif BGM.nowPlay then
BGM.playing:pause()
end
end
end
local function task_fadeOut(src)
while true do
coroutine.yield()
@@ -37,110 +94,89 @@ end
local function check_curFadeOut(task,code,src)
return task.code==code and task.args[1]==src
end
function BGM.setDefault(bgm)
BGM.default=bgm
end
function BGM.setChange(func)
BGM.onChange=func
end
function BGM.setVol(v)
assert(type(v)=='number'and v>=0 and v<=1)
volume=v
end
function BGM.init(list)
BGM.init=nil
local simpList={}
for _,v in next,list do
table.insert(simpList,v.name)
Sources[v.name]=v.path
end
table.sort(simpList)
function BGM.getList()return simpList end
local count=#simpList
LOG(count.." BGM files added")
function BGM.getCount()return count end
local function _load(name)
if type(Sources[name])=='string'then
if love.filesystem.getInfo(Sources[name])then
Sources[name]=love.audio.newSource(Sources[name],'stream')
Sources[name]:setLooping(true)
Sources[name]:setVolume(0)
return true
else
LOG("No BGM: "..Sources[name],5)
end
elseif Sources[name]then
local function _tryLoad(name)
if SourceObjList[name]then
if SourceObjList[name].source then
return true
elseif name then
LOG("No BGM: "..name,5)
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
function BGM.setVol(v)
assert(type(v)=='number'and v>=0 and v<=1)
volume=v
if BGM.playing then
if volume>0 then
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.playing=SourceObjList[name].source
if not args:sArg('-sdin')then
BGM.playing:setVolume(0)
TASK.new(task_fadeIn,BGM.playing)
else
BGM.playing:setVolume(volume)
BGM.playing:play()
elseif BGM.nowPlay then
BGM.playing:pause()
end
end
end
function BGM.loadAll()--Not neccessary, unless you want avoid the lag when playing something for the first time
for name in next,Sources do
_load(name)
end
end
function BGM.play(name)
name=name or BGM.default
if not _load(name)then return end
if volume==0 then
BGM.nowPlay=name
BGM.playing=Sources[name]
return true
end
if name and Sources[name]then
if BGM.nowPlay~=name then
if BGM.nowPlay then
TASK.new(task_fadeOut,BGM.playing)
end
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,Sources[name])
TASK.removeTask_code(task_fadeIn)
TASK.new(task_fadeIn,Sources[name])
BGM.nowPlay=name
BGM.playing=Sources[name]
BGM.lastPlayed=BGM.nowPlay
BGM.playing:seek(0)
BGM.playing:play()
BGM.onChange(name)
end
return true
end
end
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,Sources[BGM.lastPlayed]
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,Sources[BGM.nowPlay])
TASK.removeTask_code(task_fadeIn)
TASK.new(task_fadeIn,BGM.playing)
SourceObjList[name].source:setLooping(not args:sArg('-noloop'))
BGM.lastPlayed=BGM.nowPlay
BGM.playing:seek(0)
BGM.playing:play()
BGM.onChange(name)
end
return true
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.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
TASK.new(task_fadeOut,BGM.playing)
end
BGM.nowPlay,BGM.playing=nil
elseif BGM.playing then
BGM.playing:pause()
end
BGM.nowPlay,BGM.playing=nil
end
return BGM

View File

@@ -1,66 +1,88 @@
local abs=math.abs
local function hsv(h,s,v,a)--Color type, Color amount, Light
if s<=0 then return v,v,v,a end
h=h*6
local c=v*s
local x=abs((h-1)%2-1)*c
if h<1 then return v,x+v-c,v-c,a
elseif h<2 then return x+v-c,v,v-c,a
elseif h<3 then return v-c,v,x+v-c,a
elseif h<4 then return v-c,x+v-c,v,a
elseif h<5 then return x+v-c,v-c,v,a
else return v,v-c,x+v-c,a
end
end
local COLOR={
red= {.92, .12, .12},
fire= {.92, 0.4, .12},
orange= {.92, 0.6, .12},
yellow= {.92, .92, .12},
lime= {0.7, .92, .12},
jade= {0.5, .92, .12},
green= {.12, .92, .12},
aqua= {.12, .92, 0.6},
cyan= {.12, .92, .92},
navy= {.12, 0.7, .92},
sea= {.12, 0.4, .92},
blue= {0.2, 0.2, .92},
violet= {0.4, .12, .92},
purple= {0.7, .12, .92},
magenta= {.92, .12, .92},
wine= {.92, .12, 0.5},
hsv=hsv,
lRed= {.95, 0.5, 0.5},
lFire= {.95, 0.7, 0.5},
lOrange= {.95, 0.8, 0.3},
lYellow= {.95, .95, 0.5},
lLime= {0.8, .95, 0.4},
lJade= {0.6, .95, 0.4},
lGreen= {0.5, .95, 0.5},
lAqua= {0.4, .95, 0.7},
lCyan= {0.5, .95, .95},
lNavy= {0.4, .85, .95},
lSea= {0.5, 0.7, .95},
lBlue= {0.7, 0.7, .95},
lViolet= {0.7, 0.4, .95},
lPurple= {0.8, 0.4, .95},
lMagenta={.95, 0.5, .95},
lWine= {.95, 0.4, 0.7},
red= {hsv(0.00, 0.89, 0.91)},
fire= {hsv(0.04, 0.93, 0.94)},
orange= {hsv(0.09, 0.99, 0.96)},
yellow= {hsv(0.15, 0.82, 0.90)},
lime= {hsv(0.20, 0.89, 0.88)},
jade= {hsv(0.25, 1.00, 0.82)},
green= {hsv(0.33, 1.00, 0.81)},
aqua= {hsv(0.47, 1.00, 0.76)},
cyan= {hsv(0.53, 1.00, 0.88)},
navy= {hsv(0.56, 1.00, 1.00)},
sea= {hsv(0.61, 1.00, 1.00)},
blue= {hsv(0.64, 1.00, 0.95)},
violet= {hsv(0.74, 1.00, 0.91)},
purple= {hsv(0.80, 1.00, 0.81)},
magenta= {hsv(0.86, 1.00, 0.78)},
wine= {hsv(0.92, 0.98, 0.91)},
dRed= {0.6, .08, .08},
dFire= {0.6, 0.3, .08},
dOrange= {0.6, 0.4, .08},
dYellow= {0.6, 0.6, .08},
dLime= {0.5, 0.6, .08},
dJade= {0.3, 0.6, .08},
dGreen= {.08, 0.6, .08},
dAqua= {.08, 0.6, 0.4},
dCyan= {.08, 0.6, 0.6},
dNavy= {.08, 0.4, 0.6},
dSea= {.08, 0.2, 0.6},
dBlue= {0.1, 0.1, 0.6},
dViolet= {0.2, .08, 0.6},
dPurple= {0.4, .08, 0.6},
dMagenta={0.6, .08, 0.6},
dWine= {0.6, .08, 0.3},
lRed= {hsv(0.00, 0.38, 0.93)},
lFire= {hsv(0.04, 0.45, 0.91)},
lOrange= {hsv(0.10, 0.53, 0.92)},
lYellow= {hsv(0.14, 0.61, 0.95)},
lLime= {hsv(0.20, 0.66, 0.92)},
lJade= {hsv(0.26, 0.56, 0.90)},
lGreen= {hsv(0.34, 0.49, 0.89)},
lAqua= {hsv(0.47, 0.59, 0.86)},
lCyan= {hsv(0.51, 0.77, 0.88)},
lNavy= {hsv(0.54, 0.80, 0.95)},
lSea= {hsv(0.57, 0.72, 0.97)},
lBlue= {hsv(0.64, 0.44, 0.96)},
lViolet= {hsv(0.72, 0.47, 0.95)},
lPurple= {hsv(0.80, 0.62, 0.89)},
lMagenta= {hsv(0.86, 0.61, 0.89)},
lWine= {hsv(0.93, 0.57, 0.92)},
black= {.05, .05, .05},
dGray= {0.3, 0.3, 0.3},
gray= {0.6, 0.6, 0.6},
lGray= {0.8, 0.8, 0.8},
white= {.97, .97, .97},
dRed= {hsv(0.00, 0.80, 0.48)},
dFire= {hsv(0.04, 0.80, 0.34)},
dOrange= {hsv(0.07, 0.80, 0.39)},
dYellow= {hsv(0.12, 0.80, 0.37)},
dLime= {hsv(0.20, 0.80, 0.26)},
dJade= {hsv(0.29, 0.80, 0.27)},
dGreen= {hsv(0.33, 0.80, 0.26)},
dAqua= {hsv(0.46, 0.80, 0.24)},
dCyan= {hsv(0.50, 0.80, 0.30)},
dNavy= {hsv(0.58, 0.80, 0.42)},
dSea= {hsv(0.64, 0.80, 0.40)},
dBlue= {hsv(0.67, 0.80, 0.34)},
dViolet= {hsv(0.71, 0.80, 0.35)},
dPurple= {hsv(0.76, 0.80, 0.32)},
dMagenta= {hsv(0.87, 0.80, 0.28)},
dWine= {hsv(0.92, 0.80, 0.28)},
black= {hsv(0.04, 0.04, 0.14)},
dGray= {hsv(0.02, 0.05, 0.44)},
gray= {hsv(0.02, 0.05, 0.65)},
lGray= {hsv(0.02, 0.06, 0.86)},
white= {hsv(0.01, 0.02, 0.99)},
xGray= {hsv(0.00, 0.00, 0.35,.8)},
lxGray= {hsv(0.00, 0.00, 0.62,.8)},
dxGray= {hsv(0.00, 0.00, 0.16,.8)},
}
for k,v in next,{
R='red', F='fire', O='orange', Y='yellow', L='lime', J='jade', G='green', A='aqua', C='cyan', N='navy', S='sea', B='blue', V='violet', P='purple', M='magenta', W='wine',
R='red', F='fire', O='orange', Y='yellow', L='lime', J='jade', G='green', A='aqua', C='cyan', N='navy', S='sea', B='blue', V='violet', P='purple', M='magenta', W='wine',
lR='lRed',lF='lFire',lO='lOrange',lY='lYellow',lL='lLime',lJ='lJade',lG='lGreen',lA='lAqua',lC='lCyan',lN='lNavy',lS='lSea',lB='lBlue',lV='lViolet',lP='lPurple',lM='lMagenta',lW='lWine',
dR='dRed',dF='dFire',dO='dOrange',dY='dYellow',dL='dLime',dJ='dJade',dG='dGreen',dA='dAqua',dC='dCyan',dN='dNavy',dS='dSea',dB='dBlue',dV='dViolet',dP='dPurple',dM='dMagenta',dW='dWine',
D='black',dH='dGray',H='gray',lH='lGray',Z='white',
X='xGray',lX='lxGray',dX='dxGray',
--Remain letter: EIKQTUX
}do
COLOR[k]=COLOR[v]

View File

@@ -1,66 +1,76 @@
local fs=love.filesystem
local FILE={}
function FILE.load(name,mode)
function FILE.load(name,args)
if not args then args=''end
if fs.getInfo(name)then
local F=fs.newFile(name)
if F:open'r'then
local s=F:read()
F:close()
if mode=='luaon'or not mode and s:sub(1,6)=="return{"then
s=loadstring(s)
if s then
setfenv(s,{})
return s()
end
elseif mode=='json'or not mode and s:sub(1,1)=="["and s:sub(-1)=="]"or s:sub(1,1)=="{"and s:sub(-1)=="}"then
local res=JSON.decode(s)
if res then
return res
end
elseif mode=='string'or not mode then
return s
assert(F:open'r','open error')
local s=F:read()F:close()
local mode=
STRING.sArg(args,'-luaon')and'luaon'or
STRING.sArg(args,'-lua')and'lua'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,1)=='['and s:sub(-1)==']'or s:sub(1,1)=='{'and s:sub(-1)=='}')and'json'or
'string'
if mode=='luaon'then
local func,err_mes=loadstring(s)
if func then
setfenv(func,{})
local res=func()
return assert(res,'decode error')
else
MES.new("No file loading mode called "..tostring(mode))
error('decode error: '..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
elseif mode=='json'then
local res=JSON.decode(s)
if res then
return res
end
error('decode error')
elseif mode=='string'then
return s
else
MES.new('error',name.." "..text.loadError)
error('unknown mode')
end
else
error('no file')
end
end
function FILE.save(data,name,mode)
if not mode then mode=""end
function FILE.save(data,name,args)
if not args then args=''end
if STRING.sArg(args,'-d')and fs.getInfo(name)then
error('duplicate')
end
if type(data)=='table'then
if mode:find'l'then
if STRING.sArg(args,'-luaon')then
data=TABLE.dump(data)
if not data then
MES.new('error',name.." "..text.saveError.."dump error")
return
error('encode error')
end
else
data=JSON.encode(data)
if not data then
MES.new('error',name.." "..text.saveError.."json error")
return
error('encode error')
end
end
else
data=tostring(data)
end
if mode:find'd'and fs.getInfo(name)then
MES.new('error',text.saveError_duplicate)
return
end
local F=fs.newFile(name)
F:open'w'
local success,mes=F:write(data)
F:flush()F:close()
if success then
return true
else
MES.new('error',text.saveError..(mes or"unknown error"))
MES.traceback()
end
assert(F:open('w'),'open error')
F:write(data)F:flush()F:close()
end
function FILE.clear(path)
if fs.getRealDirectory(path)==SAVEDIR and fs.getInfo(path).type=='directory'then

View File

@@ -1,67 +1,60 @@
local gc=love.graphics
local set=gc.setFont
local fontCache={}
local currentFontSize
local fontFiles,fontCache={},{}
local defaultFont,defaultFallBack
local curFont=false--Current using font object
local FONT={}
function FONT.set(s)
if s~=currentFontSize then
if not fontCache[s]then
fontCache[s]=gc.setNewFont(s,'light',gc.getDPIScale()*SCR.k*2)
end
set(fontCache[s])
currentFontSize=s
end
end
function FONT.get(s)
function FONT.setDefault(name)defaultFont=name end
function FONT.setFallback(name)defaultFallBack=name end
function FONT.rawget(s)
if not fontCache[s]then
fontCache[s]=gc.setNewFont(s,'light',gc.getDPIScale()*SCR.k*2)
end
return fontCache[s]
end
function FONT.reset()
for s in next,fontCache do
fontCache[s]=gc.setNewFont(s,'light',gc.getDPIScale()*SCR.k*2)
end
function FONT.rawset(s)
set(fontCache[s]or FONT.rawget(s))
end
function FONT.load(mainFont,secFont)
assert(love.filesystem.getInfo(mainFont),"Font file '"..mainFont.."' not exist!")
mainFont=love.filesystem.newFile(mainFont)
if secFont and love.filesystem.getInfo(secFont)then
secFont=love.filesystem.newFile(secFont)
else
secFont=false
end
function FONT.set(s)
if s~=currentFontSize then
if not fontCache[s]then
fontCache[s]=gc.setNewFont(mainFont,s,'light',gc.getDPIScale()*SCR.k*2)
if secFont then
fontCache[s]:setFallbacks(gc.setNewFont(secFont,s,'light',gc.getDPIScale()*SCR.k*2))
end
end
set(fontCache[s])
currentFontSize=s
end
end
function FONT.get(s)
if not fontCache[s]then
fontCache[s]=gc.setNewFont(mainFont,s,'light',gc.getDPIScale()*SCR.k*2)
if secFont then
fontCache[s]:setFallbacks(gc.setNewFont(secFont,s,'light',gc.getDPIScale()*SCR.k*2))
end
end
return fontCache[s]
end
function FONT.reset()
for s in next,fontCache do
fontCache[s]=gc.setNewFont(mainFont,s,'light',gc.getDPIScale()*SCR.k*2)
if secFont then
fontCache[s]:setFallbacks(gc.setNewFont(secFont,s,'light',gc.getDPIScale()*SCR.k*2))
end
end
function FONT.load(fonts)
for name,path in next,fonts do
assert(love.filesystem.getInfo(path),STRING.repD("Font file $1($2) not exist!",name,path))
fontFiles[name]=love.filesystem.newFile(path)
fontCache[name]={}
end
FONT.reset()
end
function FONT.get(size,name)
if not name then name=defaultFont end
local f=fontCache[name][size]
if not f then
f=gc.setNewFont(fontFiles[name],size,'light',gc.getDPIScale()*SCR.k*2)
if defaultFallBack and name~=defaultFallBack then
f:setFallbacks(FONT.get(size,defaultFallBack))
end
fontCache[name][size]=f
end
return f
end
function FONT.set(size,name)
if not name then name=defaultFont end
local f=fontCache[name][size]
if f~=curFont then
curFont=f or FONT.get(size,name)
set(curFont)
end
end
function FONT.reset()
for name,cache in next,fontCache do
if type(cache)=='table'then
for size in next,cache do
cache[size]=FONT.get(size,name)
end
else
fontCache[name]=FONT.rawget(name)
end
end
end
return FONT

View File

@@ -95,6 +95,7 @@ do--function GC.DO(L)
setLJ="setLineJoin",
print="print",
rawFT=function(...)FONT.rawset(...)end,
setFT=function(...)FONT.set(...)end,
mText=GC.mStr,
mDraw=GC.draw,

View File

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

View File

@@ -1,14 +1,16 @@
NONE={}function NULL()end
NONE={}function NULL()end PAPER=love.graphics.newCanvas(1,1)
EDITING=""
LOADED=false
ERRDATA={}
--Pure lua modules (basic)
MATH= require'Zframework.mathExtend'
COLOR= require'Zframework.color'
TABLE= require'Zframework.tableExtend'
STRING= require'Zframework.stringExtend'
PROFILE= require'Zframework.profile'
JSON= require'Zframework.json'
TEST= require'Zframework.test'
do--Add pcall & MES for JSON lib
local encode,decode=JSON.encode,JSON.decode
JSON.encode=function(val)
@@ -35,7 +37,6 @@ REQUIRE= require'Zframework.require'
TASK= require'Zframework.task'
WS= require'Zframework.websocket'
LANG= require'Zframework.languages'
THEME= require'Zframework.theme'
--Love-based modules (basic)
FILE= require'Zframework.file'
@@ -59,6 +60,7 @@ BGM= require'Zframework.bgm'
VOC= require'Zframework.voice'
local ms,kb=love.mouse,love.keyboard
local KBisDown=kb.isDown
local gc=love.graphics
local gc_push,gc_pop,gc_clear,gc_discard=gc.push,gc.pop,gc.clear,gc.discard
@@ -70,10 +72,24 @@ local WIDGET,SCR,SCN=WIDGET,SCR,SCN
local xOy=SCR.xOy
local ITP=xOy.inverseTransformPoint
local mx,my,mouseShow=-20,-20,false
joysticks={}
local max,min=math.max,math.min
local devMode
local mx,my,mouseShow,cursorSpd=640,360,false,0
local jsState={}--map, joystickID->axisStates: {axisName->axisVal}
local errData={}--list, each error create {mes={errMes strings},scene=sceneNameStr}
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,
{'fRect',1,0,26,2},
@@ -91,17 +107,16 @@ local function updatePowerInfo()
gc_clear(0,0,0,.25)
if state~='unknown'then
gc_setLineWidth(4)
local charging=state=='charging'
if state=='nobattery'then
gc_setColor(1,1,1)
gc_setLineWidth(2)
gc_line(74,SCR.safeX+5,100,22)
gc_line(74,5,100,22)
elseif pow then
if charging then gc_setColor(0,1,0)
elseif pow>50 then gc_setColor(1,1,1)
elseif pow>26 then gc_setColor(1,1,0)
elseif pow==26 then gc_setColor(.5,0,1)
else gc_setColor(1,0,0)
if state=='charging'then gc_setColor(0,1,0)
elseif pow>50 then gc_setColor(1,1,1)
elseif pow>26 then gc_setColor(1,1,0)
elseif pow==26 then gc_setColor(.5,0,1)
else gc_setColor(1,0,0)
end
gc.rectangle('fill',76,6,pow*.22,14)
if pow<100 then
@@ -124,36 +139,81 @@ local function updatePowerInfo()
end
-------------------------------------------------------------
local lastX,lastY=0,0--Last click pos
local function _updateMousePos(x,y,dx,dy)
if SCN.swapping then return end
dx,dy=dx/SCR.k,dy/SCR.k
if SCN.mouseMove then SCN.mouseMove(x,y,dx,dy)end
if ms.isDown(1)then
WIDGET.drag(x,y,dx,dy)
else
WIDGET.cursorMove(x,y)
end
end
local function _triggerMouseDown(x,y,k)
if devMode==1 then
print(("(%d,%d)<-%d,%d ~~(%d,%d)<-%d,%d"):format(
x,y,
x-lastX,y-lastY,
math.floor(x/10)*10,math.floor(y/10)*10,
math.floor((x-lastX)/10)*10,math.floor((y-lastY)/10)*10
))
end
if SCN.swapping then return end
if SCN.mouseDown then SCN.mouseDown(x,y,k)end
WIDGET.press(x,y,k)
lastX,lastY=x,y
if showClickFX then SYSFX.newTap(3,x,y)end
end
local function mouse_update(dt)
if not KBisDown('lctrl','rctrl')and KBisDown('up','down','left','right')then
local dx,dy=0,0
if KBisDown('up')then dy=dy-cursorSpd end
if KBisDown('down')then dy=dy+cursorSpd end
if KBisDown('left')then dx=dx-cursorSpd end
if KBisDown('right')then dx=dx+cursorSpd end
mx=max(min(mx+dx,1280),0)
my=max(min(my+dy,720),0)
if my==0 or my==720 then
WIDGET.sel=false
WIDGET.drag(0,0,0,-dy)
end
_updateMousePos(mx,my,dx,dy)
cursorSpd=min(cursorSpd+dt*26,12.6)
else
cursorSpd=6
end
end
local function gp_update(js,dt)
local sx,sy=js._jsObj:getGamepadAxis('leftx'),js._jsObj:getGamepadAxis('lefty')
if math.abs(sx)>.1 or math.abs(sy)>.1 then
local dx,dy=0,0
if sy<-.1 then dy=dy+2*sy*cursorSpd end
if sy>.1 then dy=dy+2*sy*cursorSpd end
if sx<-.1 then dx=dx+2*sx*cursorSpd end
if sx>.1 then dx=dx+2*sx*cursorSpd end
mx=max(min(mx+dx,1280),0)
my=max(min(my+dy,720),0)
if my==0 or my==720 then
WIDGET.sel=false
WIDGET.drag(0,0,0,-dy)
end
_updateMousePos(mx,my,dx,dy)
cursorSpd=min(cursorSpd+dt*26,12.6)
else
cursorSpd=6
end
end
function love.mousepressed(x,y,k,touch)
if touch then return end
mouseShow=true
mx,my=ITP(xOy,x,y)
if devMode==1 then
print(("(%d,%d)<-%d,%d ~~(%d,%d)<-%d,%d"):format(
mx,my,
mx-lastX,my-lastY,
math.floor(mx/10)*10,math.floor(my/10)*10,
math.floor((mx-lastX)/10)*10,math.floor((my-lastY)/10)*10
))
end
if SCN.swapping then return end
if SCN.mouseDown then SCN.mouseDown(mx,my,k)end
WIDGET.press(mx,my,k)
lastX,lastY=mx,my
if SETTING.clickFX then SYSFX.newTap(3,mx,my)end
_triggerMouseDown(mx,my,k)
end
function love.mousemoved(x,y,dx,dy,touch)
if touch then return end
mouseShow=true
mx,my=ITP(xOy,x,y)
if SCN.swapping then return end
dx,dy=dx/SCR.k,dy/SCR.k
if SCN.mouseMove then SCN.mouseMove(mx,my,dx,dy)end
if ms.isDown(1)then
WIDGET.drag(mx,my,dx/SCR.k,dy/SCR.k)
else
WIDGET.cursorMove(mx,my)
end
_updateMousePos(mx,my,dx,dy)
end
function love.mousereleased(x,y,k,touch)
if touch or SCN.swapping then return end
@@ -188,13 +248,13 @@ function love.touchpressed(id,x,y)
x,y=ITP(xOy,x,y)
lastX,lastY=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
end
function love.touchmoved(_,x,y,dx,dy)
function love.touchmoved(id,x,y,dx,dy)
if SCN.swapping then return end
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)
end
function love.touchreleased(id,x,y)
@@ -207,40 +267,40 @@ function love.touchreleased(id,x,y)
WIDGET.unFocus()
SCN.mainTouchID=false
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 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
local fnKey={NULL,NULL,NULL,NULL,NULL,NULL,NULL}
local function noDevkeyPressed(key)
if key=="f1"then fnKey[1]()
elseif key=="f2"then fnKey[2]()
elseif key=="f3"then fnKey[3]()
elseif key=="f4"then fnKey[4]()
elseif key=="f5"then fnKey[5]()
elseif key=="f6"then fnKey[6]()
elseif key=="f7"then fnKey[7]()
elseif key=="f8"then devMode=nil MES.new('info',"DEBUG OFF",.2)
elseif key=="f9"then devMode=1 MES.new('info',"DEBUG 1")
elseif key=="f10"then devMode=2 MES.new('info',"DEBUG 2")
elseif key=="f11"then devMode=3 MES.new('info',"DEBUG 3")
elseif key=="f12"then devMode=4 MES.new('info',"DEBUG 4")
if key=='f1'then fnKey[1]()
elseif key=='f2'then fnKey[2]()
elseif key=='f3'then fnKey[3]()
elseif key=='f4'then fnKey[4]()
elseif key=='f5'then fnKey[5]()
elseif key=='f6'then fnKey[6]()
elseif key=='f7'then fnKey[7]()
elseif key=='f8'then devMode=nil MES.new('info',"DEBUG OFF",.2)
elseif key=='f9'then devMode=1 MES.new('info',"DEBUG 1")
elseif key=='f10'then devMode=2 MES.new('info',"DEBUG 2")
elseif key=='f11'then devMode=3 MES.new('info',"DEBUG 3")
elseif key=='f12'then devMode=4 MES.new('info',"DEBUG 4")
elseif devMode==2 then
local W=WIDGET.sel
if W then
if key=="left"then W.x=W.x-10
elseif key=="right"then W.x=W.x+10
elseif key=="up"then W.y=W.y-10
elseif key=="down"then W.y=W.y+10
elseif key==","then W.w=W.w-10
elseif key=="."then W.w=W.w+10
elseif key=="/"then W.h=W.h-10
elseif key=="'"then W.h=W.h+10
elseif key=="["then W.font=W.font-5
elseif key=="]"then W.font=W.font+5
if key=='left'then W.x=W.x-10
elseif key=='right'then W.x=W.x+10
elseif key=='up'then W.y=W.y-10
elseif key=='down'then W.y=W.y+10
elseif key==','then W.w=W.w-10
elseif key=='.'then W.w=W.w+10
elseif key=='/'then W.h=W.h-10
elseif key=='\''then W.h=W.h+10
elseif key=='['then W.font=W.font-5
elseif key==']'then W.font=W.font+5
else return true
end
else
@@ -254,22 +314,34 @@ function love.keypressed(key,_,isRep)
mouseShow=false
if devMode and not noDevkeyPressed(key)then
return
elseif key=="f8"then
elseif key=='f8'then
devMode=1
MES.new('info',"DEBUG ON",.2)
elseif key=="f11"then
elseif key=='f11'then
SETTING.fullscreen=not SETTING.fullscreen
applyFullscreen()
applySettings()
saveSettings()
elseif not SCN.swapping then
if SCN.keyDown then
if EDITING==""then
SCN.keyDown(key,isRep)
if EDITING==""and(not SCN.keyDown or SCN.keyDown(key,isRep))then
local W=WIDGET.sel
if key=='escape'and not isRep then
SCN.back()
elseif key=='up'or key=='down'or key=='left'or key=='right'then
mouseShow=true
if KBisDown('lctrl','rctrl')then
if W and W.arrowKey then W:arrowKey(key)end
end
elseif key=='space'or key=='return'then
mouseShow=true
if not isRep then
if showClickFX then SYSFX.newTap(3,mx,my)end
_triggerMouseDown(mx,my,1)
end
else
if W and W.keypress then
W:keypress(key)
end
end
elseif key=="escape"and not isRep then
SCN.back()
else
WIDGET.keyPressed(key,isRep)
end
end
end
@@ -285,18 +357,18 @@ function love.textinput(texts)
WIDGET.textinput(texts)
end
function love.joystickadded(JS)
table.insert(joysticks,JS)
MES.new('info',"Joystick added")
end
function love.joystickremoved(JS)
local i=TABLE.find(joysticks,JS)
if i then
table.remove(joysticks,i)
MES.new('info',"Joystick removed")
end
end
local keyMirror={
--analog sticks: -1, 0, 1 for neg, neutral, pos
--triggers: 0 for released, 1 for pressed
local jsAxisEventName={
leftx={'leftstick_left','leftstick_right'},
lefty={'leftstick_up','leftstick_down'},
rightx={'rightstick_left','rightstick_right'},
righty={'rightstick_up','rightstick_down'},
triggerleft='triggerleft',
triggerright='triggerright'
}
local gamePadKeys={'a','b','x','y','back','guide','start','leftstick','rightstick','leftshoulder','rightshoulder','dpup','dpdown','dpleft','dpright'}
local dPadToKey={
dpup='up',
dpdown='down',
dpleft='left',
@@ -304,65 +376,131 @@ local keyMirror={
start='return',
back='escape',
}
function love.gamepadpressed(_,i)
function love.joystickadded(JS)
table.insert(jsState,{
_id=JS:getID(),
_jsObj=JS,
leftx=0,lefty=0,
rightx=0,righty=0,
triggerleft=0,triggerright=0
})
MES.new('info',"Joystick added")
end
function love.joystickremoved(JS)
for i=1,#jsState do
if jsState[i]._jsObj==JS then
for j=1,#gamePadKeys do
if JS:isGamepadDown(gamePadKeys[j])then
love.gamepadreleased(JS,gamePadKeys[j])
end
end
love.gamepadaxis(JS,'leftx',0)
love.gamepadaxis(JS,'lefty',0)
love.gamepadaxis(JS,'rightx',0)
love.gamepadaxis(JS,'righty',0)
love.gamepadaxis(JS,'triggerleft',-1)
love.gamepadaxis(JS,'triggerright',-1)
MES.new('info',"Joystick removed")
table.remove(jsState,i)
break
end
end
end
function love.gamepadaxis(JS,axis,val)
if jsState[1]and JS==jsState[1]._jsObj then
local js=jsState[1]
if axis=='leftx'or axis=='lefty'or axis=='rightx'or axis=='righty'then
local newVal=--range: [0,1]
val>.4 and 1 or
val<-.4 and -1 or
0
if newVal~=js[axis]then
if js[axis]==-1 then
love.gamepadreleased(JS,jsAxisEventName[axis][1])
elseif js[axis]~=0 then
love.gamepadreleased(JS,jsAxisEventName[axis][2])
end
if newVal==-1 then
love.gamepadpressed(JS,jsAxisEventName[axis][1])
elseif newVal==1 then
love.gamepadpressed(JS,jsAxisEventName[axis][2])
end
js[axis]=newVal
end
elseif axis=='triggerleft'or axis=='triggerright'then
local newVal=val>.3 and 1 or 0--range: [0,1]
if newVal~=js[axis]then
if newVal==1 then
love.gamepadpressed(JS,jsAxisEventName[axis])
else
love.gamepadreleased(JS,jsAxisEventName[axis])
end
js[axis]=newVal
end
end
end
end
function love.gamepadpressed(_,key)
mouseShow=false
if SCN.swapping then return end
if SCN.gamepadDown then SCN.gamepadDown(i)
elseif SCN.keyDown then SCN.keyDown(keyMirror[i]or i)
elseif i=="back"then SCN.back()
else WIDGET.gamepadPressed(keyMirror[i]or i)
if not SCN.swapping then
local cursorCtrl
if SCN.gamepadDown then
cursorCtrl=SCN.gamepadDown(key)
elseif SCN.keyDown then
cursorCtrl=SCN.keyDown(dPadToKey[key]or key)
else
cursorCtrl=true
end
if cursorCtrl then
key=dPadToKey[key]or key
mouseShow=true
local W=WIDGET.sel
if key=='back'then
SCN.back()
elseif key=='up'or key=='down'or key=='left'or key=='right'then
mouseShow=true
if W and W.arrowKey then W:arrowKey(key)end
elseif key=='return'then
mouseShow=true
if showClickFX then SYSFX.newTap(3,mx,my)end
_triggerMouseDown(mx,my,1)
else
if W and W.keypress then
W:keypress(key)
end
end
end
end
end
function love.gamepadreleased(_,i)
if SCN.swapping then return end
if SCN.gamepadUp then SCN.gamepadUp(i)end
end
--[[
function love.joystickpressed(JS,k)
mouseShow=false
if SCN.swapping then return end
if SCN.gamepadDown then SCN.gamepadDown(i)
elseif SCN.keyDown then SCN.keyDown(keyMirror[i]or i)
elseif i=="back"then SCN.back()
else WIDGET.gamepadPressed(i)
end
end
function love.joystickreleased(JS,k)
if SCN.swapping then return end
if SCN.gamepadUp then SCN.gamepadUp(i)
end
end
function love.joystickaxis(JS,axis,val)
end
function love.joystickhat(JS,hat,dir)
end
function love.sendData(data)end
function love.receiveData(id,data)end
]]
function love.filedropped(file)
if SCN.fileDropped then SCN.fileDropped(file)end
end
function love.directorydropped(dir)
if SCN.directoryDropped then SCN.directoryDropped(dir)end
end
local lastGCtime=0
local autoGCcount=0
function love.lowmemory()
if love.timer.getTime()-lastGCtime>6.26 then
collectgarbage()
lastGCtime=love.timer.getTime()
collectgarbage()
if autoGCcount<3 then
autoGCcount=autoGCcount+1
MES.new('check',"[auto GC] low MEM 设备内存过低")
end
end
local onResize=NULL
function love.resize(w,h)
if SCR.w==w and SCR.h==h then return end
SCR.resize(w,h)
if BG.resize then BG.resize(w,h)end
if SCN.resize then SCN.resize(w,h)end
WIDGET.resize(w,h)
FONT.reset()
SHADER.warning:send('w',w*SCR.dpi)
onResize(w,h)
end
local onFocus=NULL
@@ -376,7 +514,7 @@ end
function love.errorhandler(msg)
if type(msg)~='string'then
msg="Unknown error"
elseif msg:find("Invaild UTF-8")and text then
elseif msg:find("Invalid UTF-8")and text then
msg=text.tryAnotherBuild
end
@@ -400,20 +538,20 @@ function love.errorhandler(msg)
love.audio.stop()
gc.reset()
if LOADED and #ERRDATA<3 then
if LOADED and #errData<3 then
BG.set('none')
local scn=SCN and SCN.cur or"NULL"
table.insert(ERRDATA,{mes=err,scene=scn})
table.insert(errData,{mes=err,scene=scn})
--Write messages to log file
love.filesystem.append('conf/error.log',
os.date("%Y/%m/%d %A %H:%M:%S\n")..
#ERRDATA.." crash(es) "..love.system.getOS().."-"..VERSION.string.." scene: "..scn.."\n"..
#errData.." crash(es) "..love.system.getOS().."-"..VERSION.string.." scene: "..scn.."\n"..
table.concat(err,"\n",1,c-2).."\n\n"
)
--Get screencapture
gc.captureScreenshot(function(_)ERRDATA[#ERRDATA].shot=gc.newImage(_)end)
gc.captureScreenshot(function(_)errData[#errData].shot=gc.newImage(_)end)
gc.present()
--Create a new mainLoop thread to keep game alive
@@ -473,7 +611,7 @@ local devColor={
}
local WS=WS
local WSnames={'app','user','play','stream','chat','manage'}
local wsBottomImage do
local wsImg={}do
local L={78,18,
{'clear',1,1,1,0},
{'setCL',1,1,1,.3},
@@ -483,31 +621,23 @@ local wsBottomImage do
table.insert(L,{'setCL',1,1,1,i*.005})
table.insert(L,{'fRect',i,0,1,18})
end
wsBottomImage=GC.DO(L)
wsImg.bottom=GC.DO(L)
wsImg.dead=GC.DO{20,20,
{'rawFT',20},
{'setCL',1,.3,.3},
{'mText',"X",11,-1},
}
wsImg.connecting=GC.DO{20,20,
{'rawFT',20},
{'setLW',3},
{'mText',"C",11,-1},
}
wsImg.running=GC.DO{20,20,
{'rawFT',20},
{'setCL',.5,1,0},
{'mText',"R",11,-1},
}
end
local ws_deadImg=GC.DO{20,20,
{'setFT',20},
{'setCL',1,.3,.3},
{'mText',"X",11,-1},
}
local ws_connectingImg=GC.DO{20,20,
{'setFT',20},
{'setLW',3},
{'mText',"C",11,-1},
}
local ws_runningImg=GC.DO{20,20,
{'setFT',20},
{'setCL',.5,1,0},
{'mText',"R",11,-1},
}
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()
local love=love
@@ -519,12 +649,11 @@ function love.run()
local TASK_update=TASK.update
local SYSFX_update,SYSFX_draw=SYSFX.update,SYSFX.draw
local WIDGET_update,WIDGET_draw=WIDGET.update,WIDGET.draw
local STEP,WAIT=love.timer.step,love.timer.sleep
local FPS,MINI=love.timer.getFPS,love.window.isMinimized
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 lastFrame=timer()
@@ -536,7 +665,7 @@ function love.run()
--Scene Launch
while #SCN.stack>0 do SCN.pop()end
SCN.push('quit','slowFade')
SCN.init(#ERRDATA==0 and'load'or'error')
SCN.init(#errData==0 and'load'or'error')
return function()
local _
@@ -558,6 +687,8 @@ function love.run()
--UPDATE
STEP()
if mouseShow then mouse_update(dt)end
if next(jsState)then gp_update(jsState[1],dt)end
VOC.update()
BG.update(dt)
TEXT_update(dt)
@@ -571,11 +702,10 @@ function love.run()
--DRAW
if not MINI()then
FCT=FCT+SETTING.frameMul
FCT=FCT+frameMul
if FCT>=100 then
FCT=FCT-100
local safeX=SCR.safeX
gc_replaceTransform(SCR.origin)
gc_setColor(1,1,1)
BG.draw()
@@ -586,16 +716,14 @@ function love.run()
TEXT_draw()
--Draw cursor
if mouseShow then
drawCursor(time,mx,my)
end
gc_replaceTransform(SCR.xOy_ul)
MES_draw()
if mouseShow then drawCursor(time,mx,my)end
gc_replaceTransform(SCR.origin)
MES_draw()
--Draw power info.
if showPowerInfo()then
if showPowerInfo then
gc_setColor(1,1,1)
gc_draw(infoCanvas,safeX,0,0,SCR.k)
gc_draw(infoCanvas,SCR.safeX,0,0,SCR.k)
end
--Draw scene swapping animation
@@ -606,10 +734,12 @@ function love.run()
end
gc_replaceTransform(SCR.xOy_d)
--Draw Version string
gc_setColor(.8,.8,.8,.4)
gc_setColor(.9,.9,.9,.42)
FONT.set(20)
mStr(VERSION.string,0,-30)
gc_replaceTransform(SCR.xOy_dl)
local safeX=SCR.safeX/SCR.k
--Draw FPS
FONT.set(15)
gc_setColor(1,1,1)
@@ -620,9 +750,8 @@ function love.run()
--Left-down infos
gc_setColor(devColor[devMode])
gc_print("MEM "..gcinfo(),safeX+5,-40)
gc_print("Lines "..FREEROW.getCount(),safeX+5,-60)
gc_print("Tasks "..TASK.getCount(),safeX+5,-80)
gc_print("Voices "..VOC.getQueueCount(),safeX+5,-100)
gc_print("Tasks "..TASK.getCount(),safeX+5,-60)
gc_print("Voices "..VOC.getQueueCount(),safeX+5,-80)
--Update & draw frame time
table.insert(frameTimeList,1,dt)table.remove(frameTimeList,126)
@@ -650,14 +779,14 @@ function love.run()
for i=1,6 do
local status=WS.status(WSnames[i])
gc_setColor(1,1,1)
gc.draw(wsBottomImage,-79,20*i-139)
gc.draw(wsImg.bottom,-79,20*i-139)
if status=='dead'then
gc_draw(ws_deadImg,-20,20*i-140)
gc_draw(wsImg.dead,-20,20*i-140)
elseif status=='connecting'then
gc_setColor(1,1,1,.5+.3*math.sin(time*6.26))
gc_draw(ws_connectingImg,-20,20*i-140)
gc_draw(wsImg.connecting,-20,20*i-140)
elseif status=='running'then
gc_draw(ws_runningImg,-20,20*i-140)
gc_draw(wsImg.running,-20,20*i-140)
end
local t1,t2,t3=WS.getTimers(WSnames[i])
gc_setColor(.9,.9,.9,t1)gc.rectangle('fill',-60,20*i-122,-16,-16)
@@ -668,13 +797,13 @@ function love.run()
gc_present()
--SPEED UPUPUP!
if SETTING.cleanCanvas then gc_discard()end
if discardCanvas then gc_discard()end
end
end
--Fresh power info.
if time-lastFreshPow>2.6 then
if showPowerInfo()then
if showPowerInfo then
updatePowerInfo()
lastFreshPow=time
end
@@ -692,28 +821,44 @@ function love.run()
end
end
--Keep 60fps
_=timer()-lastFrame
if _<.0162 then WAIT(.0162-_)end
while timer()-lastFrame<1/60 do end
if _<sleepInterval*.9626 then WAIT(sleepInterval*.9626-_)end
while timer()-lastFrame<sleepInterval do end
end
end
local Z={}
function Z.setIfPowerInfo(func)showPowerInfo=func end
function Z.getJsState()return jsState end
function Z.getErr(i)
if i=='#'then
return errData[#errData]
elseif i then
return errData[i]
else
return errData
end
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.
function Z.setCursor(func)drawCursor=func end
--Change F1~F7 events of devmode (F8 mode)
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
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

37
Zframework/mathExtend.lua Normal file
View File

@@ -0,0 +1,37 @@
local MATH={}for k,v in next,math do MATH[k]=v end
local rnd=math.random
MATH.tau=2*math.pi
function MATH.sign(a)
return a>0 and 1 or a<0 and -1 or 0
end
function MATH.roll(chance)
return rnd()<(chance or .5)
end
function MATH.coin(a,b)
if rnd()<.5 then
return a
else
return b
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

View File

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

View File

@@ -15,6 +15,8 @@ local SCN={
draw=false, --Swap draw func
},
stack={},--Scene stack
prev=false,
args={},--Arguments from previous scene
scenes=scenes,
@@ -52,14 +54,15 @@ function SCN.swapUpdate(dt)
S.time=S.time-dt
if S.time<S.changeTime and S.time+dt>=S.changeTime then
--Scene swapped this frame
SCN.init(S.tar,SCN.cur)
SCN.prev=SCN.cur
SCN.init(S.tar)
SCN.mainTouchID=nil
end
if S.time<0 then
SCN.swapping=false
end
end
function SCN.init(s,org)
function SCN.init(s)
love.keyboard.setTextInput(false)
local S=scenes[s]
@@ -89,7 +92,7 @@ function SCN.init(s,org)
SCN.update=S.update
SCN.draw=S.draw
if S.sceneInit then
S.sceneInit(org)
S.sceneInit()
end
end
function SCN.push(tar,style)
@@ -165,11 +168,12 @@ local swap={
end
},
}--Scene swapping animations
function SCN.swapTo(tar,style)--Parallel scene swapping, cannot back
function SCN.swapTo(tar,style,...)--Parallel scene swapping, cannot back
if scenes[tar]then
if not SCN.swapping and tar~=SCN.cur then
style=style or'fade'
SCN.swapping=true
SCN.args={...}
local S=SCN.stat
S.tar,S.style=tar,style
S.time=swap[style].duration
@@ -180,15 +184,15 @@ function SCN.swapTo(tar,style)--Parallel scene swapping, cannot back
MES.new('warn',"No Scene: "..tar)
end
end
function SCN.go(tar,style)--Normal scene swapping, can back
function SCN.go(tar,style,...)--Normal scene swapping, can back
if scenes[tar]then
SCN.push()
SCN.swapTo(tar,style)
SCN.swapTo(tar,style,...)
else
MES.new('warn',"No Scene: "..tar)
end
end
function SCN.back()
function SCN.back(...)
if SCN.swapping then return end
--Leave scene
@@ -199,7 +203,7 @@ function SCN.back()
--Poll&Back to previous Scene
local m=#SCN.stack
if m>0 then
SCN.swapTo(SCN.stack[m-1],SCN.stack[m])
SCN.swapTo(SCN.stack[m-1],SCN.stack[m],...)
SCN.stack[m],SCN.stack[m-1]=nil
end
end

View File

@@ -1,4 +1,6 @@
local type,rem=type,table.remove
local int,rnd=math.floor,math.random
local interval=MATH.interval
local sfxList={}
local packSetting={}
@@ -6,7 +8,7 @@ local Sources={}
local volume=1
local stereo=1
local noteName={
local noteVal={
C=1,c=1,
D=3,d=3,
E=5,e=5,
@@ -15,10 +17,11 @@ local noteName={
A=10,a=10,
B=12,b=12,
}
local noteName={'C','C#','D','D#','E','F','F#','G','G#','A','A#','B'}
local function _getTuneHeight(tune)
local octave=tonumber(tune:sub(-1,-1))
if octave then
local tuneHeight=noteName[tune:sub(1,1)]
local tuneHeight=noteVal[tune:sub(1,1)]
if tuneHeight then
tuneHeight=tuneHeight+(octave-1)*12
local s=tune:sub(2,2)
@@ -40,29 +43,41 @@ function SFX.init(list)
end
function SFX.load(path)
local c=0
local missing=0
for i=1,#sfxList do
local fullPath=path..sfxList[i]..'.ogg'
if love.filesystem.getInfo(fullPath)then
if Sources[sfxList[i]]then
for j=1,#Sources[sfxList[i]]do
Sources[sfxList[i]][j]:release()
end
end
Sources[sfxList[i]]={love.audio.newSource(fullPath,'static')}
c=c+1
else
LOG("No SFX: "..sfxList[i]..'.ogg',.1)
missing=missing+1
end
end
LOG(c.."/"..#sfxList.." SFX files loaded")
LOG(missing.." SFX files missing")
if missing>0 then
MES.new('info',missing.." SFX files missing")
end
collectgarbage()
end
function SFX.loadSample(pack)
assert(type(pack)=='table',"Usage: SFX.loadsample([table])")
assert(pack.name,"No field: name")
assert(pack.path,"No field: path")
packSetting[pack.name]={
base=(_getTuneHeight(pack.base)or 37)-1,
}
local num=1
while love.filesystem.getInfo(pack.path..'/'..num..'.ogg')do
Sources[pack.name..num]={love.audio.newSource(pack.path..'/'..num..'.ogg','static')}
num=num+1
end
local base=(_getTuneHeight(pack.base)or 37)-1
local top=base+num-1
packSetting[pack.name]={base=base,top=top}
LOG((num-1).." "..pack.name.." samples loaded")
end
@@ -70,31 +85,47 @@ function SFX.getCount()
return #sfxList
end
function SFX.setVol(v)
assert(type(v)=='number'and v>=0 and v<=1)
assert(type(v)=='number'and v>=0 and v<=1,'Wrong volume')
volume=v
end
function SFX.setStereo(v)
assert(type(v)=='number'and v>=0 and v<=1)
assert(type(v)=='number'and v>=0 and v<=1,'Wrong stereo')
stereo=v
end
function SFX.playSample(pack,...)--vol-2, sampSet1, vol-3, sampSet2, vol-1
function SFX.getNoteName(note)
if note<1 then
return'---'
else
note=note-1
local octave=int(note/12)+1
return noteName[note%12+1]..octave
end
end
function SFX.playSample(pack,...)--vol-1, sampSet1, vol-2, sampSet2
if ... then
local arg={...}
local vol
if type(arg[#arg])=='number'then vol=rem(arg)end
for i=1,#arg do
if type(arg[i])=='number'then
vol=arg[i]
local a=arg[i]
if type(a)=='number'and a<=1 then
vol=a
else
local tune=arg[i]
tune=_getTuneHeight(tune)-packSetting[pack].base
SFX.play(pack..tune,vol)
local base=packSetting[pack].base
local top=packSetting[pack].top
local tune=type(a)=='string'and _getTuneHeight(a)or a--Absolute tune in number
local playTune=tune+rnd(-2,2)
if playTune<=base then--Too low notes
playTune=base+1
elseif playTune>top then--Too high notes
playTune=top
end
SFX.play(pack..playTune-base,vol,nil,tune-playTune)
end
end
end
end
function SFX.play(name,vol,pos)
local function _play(name,vol,pos,pitch)
if volume==0 or vol==0 then return end
local S=Sources[name]--Source list
if not S then return end
@@ -110,39 +141,20 @@ function SFX.play(name,vol,pos)
S=S[n]--AU_SRC
if S:getChannelCount()==1 then
if pos then
pos=pos*stereo
S:setPosition(pos,1-pos^2,0)
else
S:setPosition(0,0,0)
end
end
S:setVolume(((vol or 1)*volume)^1.626)
S:play()
end
function SFX.fplay(name,vol,pos)
local S=Sources[name]--Source list
if not S then return end
local n=1
while S[n]:isPlaying()do
n=n+1
if not S[n]then
S[n]=S[1]:clone()
S[n]:seek(0)
break
end
end
S=S[n]--AU_SRC
if S:getChannelCount()==1 then
if pos then
pos=pos*stereo
pos=interval(pos,-1,1)*stereo
S:setPosition(pos,1-pos^2,0)
else
S:setPosition(0,0,0)
end
end
S:setVolume(vol^1.626)
S:setPitch(pitch and 1.0594630943592953^pitch or 1)
S:play()
end
SFX.fplay=_play--Play sounds without apply module's volume setting
function SFX.play(name,vol,pos,pitch)
_play(name,(vol or 1)*volume,pos,pitch)
end
function SFX.reset()
for _,L in next,Sources do
if type(L)=='table'then

View File

@@ -2,9 +2,25 @@ local data=love.data
local STRING={}
local assert,tostring,tonumber=assert,tostring,tonumber
local int,format=math.floor,string.format
local find,sub,upper=string.find,string.sub,string.upper
local find,sub,gsub,upper=string.find,string.sub,string.gsub,string.upper
local char,byte=string.char,string.byte
--"Replace dollars", replace all $n with ...
function STRING.repD(str,...)
local l={...}
for i=#l,1,-1 do
str=gsub(str,'$'..i,l[i])
end
return str
end
--"Scan arg", scan if str has the arg (format of str is like "-json -q", arg is like "-q")
function STRING.sArg(str,switch)
if find(str.." ",switch.." ")then
return true
end
end
do--function STRING.shiftChar(c)
local shiftMap={
['1']='!',['2']='@',['3']='#',['4']='$',['5']='%',
@@ -63,9 +79,9 @@ function STRING.time(t)
if t<60 then
return format("%.3f\"",t)
elseif t<3600 then
return format("%d'%05.2f\"",int(t/60),t%60)
return format("%d'%05.2f\"",int(t/60),int(t%60*100)/100)
else
return format("%d:%.2d'%05.2f\"",int(t/3600),int(t/60%60),t%60)
return format("%d:%.2d'%05.2f\"",int(t/3600),int(t/60%60),int(t%60*100)/100)
end
end
@@ -153,6 +169,25 @@ function STRING.vcsDecrypt(text,key)
end
return result..buffer
end
function STRING.digezt(text)--Not powerful hash, just protect the original text
local out={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
local seed=26
for i=1,#text do
local c=byte(text,i)
seed=(seed+c)%26
c=c+seed
local pos=c*i%16
local step=(c+i)%4+1
local times=2+(c%6)
for _=1,times do
out[pos+1]=(out[pos+1]+c)%256
pos=(pos+step)%16
end
end
local result=""
for i=1,16 do result=result..char(out[i])end
return result
end
function STRING.readLine(str)
local p=str:find("\n")
@@ -162,6 +197,9 @@ function STRING.readLine(str)
return str,""
end
end
function STRING.readChars(str,n)
return sub(str,1,n),sub(str,n+1)
end
function STRING.packBin(s)
return data.encode('string','base64',data.compress('string','zlib',s))

View File

@@ -1,4 +1,5 @@
local find=string.find
local rem=table.remove
local next,type=next,type
local TABLE={}
@@ -46,6 +47,18 @@ function TABLE.cover(new,old)
end
end
--For all things in new, push to old
function TABLE.coverR(new,old)
for k,v in next,new do
if type(v)=='table'and type(old[k])=='table'then
TABLE.coverR(v,old[k])
else
old[k]=v
end
end
end
--For all things in new if same type in old, push to old
function TABLE.update(new,old)
for k,v in next,new do
@@ -71,7 +84,7 @@ function TABLE.complete(new,old)
end
end
--Remove positive integer index of table
--Remove [1~#] of table
function TABLE.cut(G)
for i=1,#G do
G[i]=nil
@@ -85,11 +98,53 @@ function TABLE.clear(G)
end
end
--Remove duplicated value of [1~#]
function TABLE.trimDuplicate(org)
local cache={}
for i=1,#org,-1 do
if cache[org[i]]then
rem(org,i)
else
cache[org[i]]=true
end
end
end
--Discard duplicated value
function TABLE.remDuplicate(org)
local cache={}
for k,v in next,org do
if cache[v]then
org[k]=nil
else
cache[v]=true
end
end
end
--Reverse [1~#]
function TABLE.reverse(org)
local l=#org
for i=1,math.floor(l/2)do
org[i],org[l+1-i]=org[l+1-i],org[i]
end
end
--------------------------
--Find value in [1~#]
function TABLE.find(t,val)
for i=1,#t do if t[i]==val then return i end end
end
--Return next value of [1~#] (by value)
function TABLE.next(t,val)
for i=1,#t do if t[i]==val then return t[i%#t+1]end end
end
--------------------------
--Find value in whole table
function TABLE.search(t,val)
for k,v in next,t do if v==val then return k end end
@@ -104,6 +159,8 @@ function TABLE.reIndex(org)
end
end
--------------------------
--Dump a simple lua table
do--function TABLE.dump(L,t)
local tabs={

12
Zframework/test.lua Normal file
View File

@@ -0,0 +1,12 @@
local TEST={}
--Wait for the scene swapping animation to finish
function TEST.yieldUntilNextScene()
while SCN.swapping do YIELD()end
end
function TEST.yieldN(frames)
for _=1,frames do YIELD()end
end
return TEST

View File

@@ -1,5 +1,7 @@
local rnd=math.random
local volume=1
local diversion=0
local VOC={
vol=1,
getCount=function()return 0 end,
getQueueCount=function()return 0 end,
load=function()error("Cannot load before init!")end,
@@ -7,13 +9,16 @@ local VOC={
play=NULL,
update=NULL,
}
function VOC.setDiversion(n)
assert(type(n)=='number'and n>0 and n<12,'Wrong div')
diversion=n
end
function VOC.setVol(v)
assert(type(v)=='number'and v>=0 and v<=1)
VOC.vol=v
assert(type(v)=='number'and v>=0 and v<=1,'Wrong volume')
volume=v
end
function VOC.init(list)
VOC.init=nil
local rnd=math.random
local rem=table.remove
local voiceQueue={free=0}
local bank={}--{vocName1={SRC1s},vocName2={SRC2s},...}
@@ -72,7 +77,7 @@ function VOC.init(list)
end
function VOC.play(s,chn)
if VOC.vol>0 then
if volume>0 then
local _=Source[s]
if not _ then return end
if chn then
@@ -95,13 +100,15 @@ function VOC.init(list)
end
elseif Q.s==1 then--Waiting load source
Q[1]=_getVoice(Q[1])
Q[1]:setVolume(VOC.vol)
Q[1]:setVolume(volume)
Q[1]:setPitch(1.0594630943592953^(diversion*(rnd()*2-1)))
Q[1]:play()
Q.s=Q[2]and 2 or 4
elseif Q.s==2 then--Playing 1,ready 2
if Q[1]:getDuration()-Q[1]:tell()<.08 then
Q[2]=_getVoice(Q[2])
Q[2]:setVolume(VOC.vol)
Q[2]:setVolume(volume)
Q[1]:setPitch(1.0594630943592953^(diversion*(rnd()*2-1)))
Q[2]:play()
Q.s=3
end

View File

@@ -9,11 +9,11 @@ return function(y,key1,key2)
trigDist=min(trigDist,0)-(-y)^1.2
end
while trigDist>=1 do
love.keypressed(key1 or"up")
love.keypressed(key1 or'up')
trigDist=trigDist-1
end
while trigDist<=-1 do
love.keypressed(key2 or"down")
love.keypressed(key2 or'down')
trigDist=trigDist+1
end
end

View File

@@ -13,13 +13,13 @@ local kb=love.keyboard
local timer=love.timer.getTime
local next=next
local int,ceil,abs=math.floor,math.ceil,math.abs
local int,ceil=math.floor,math.ceil
local max,min=math.max,math.min
local sub,ins,rem=string.sub,table.insert,table.remove
local mDraw,mDraw_X,mDraw_Y=GC.draw,GC.simpX,GC.simpY
local xOy=SCR.xOy
local FONT=FONT
local mStr=GC.mStr
local approach=MATH.expApproach
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}}
@@ -29,7 +29,7 @@ local clearIcon=GC.DO{40,40,
{'fRect',11,14,18,21},
}
local sureIcon=GC.DO{40,40,
{'setFT',35},
{'rawFT',35},
{'mText',"?",20,0},
}
local smallerThen=GC.DO{20,20,
@@ -46,7 +46,12 @@ local function _rectangleStencil()
gc.rectangle('fill',1,1,STW-2,STH-2)
end
local onChange=NULL
local WIDGET={}
function WIDGET.setOnChange(func)onChange=assert(type(func)=='function'and func,"WIDGET.setOnChange(func): func must be a function")end
local widgetMetatable={
__tostring=function(self)
return self:getInfo()
@@ -73,24 +78,28 @@ function text:draw()
if self.alpha>0 then
local c=self.color
gc_setColor(c[1],c[2],c[3],self.alpha)
local w=self.obj:getWidth()
local k=min(self.lim/self.obj:getWidth(),1)
if self.align=='M'then
mDraw_X(self.obj,self.x,self.y)
gc_draw(self.obj,self.x,self.y,nil,k,1,w*.5,0)
elseif self.align=='L'then
gc_draw(self.obj,self.x,self.y)
gc_draw(self.obj,self.x,self.y,nil,k,1)
elseif self.align=='R'then
gc_draw(self.obj,self.x-self.obj:getWidth(),self.y)
gc_draw(self.obj,self.x,self.y,nil,k,1,w,0)
end
end
end
function WIDGET.newText(D)--name,x,y[,fText][,color][,font=30][,align='M'][,hideF][,hide]
function WIDGET.newText(D)--name,x,y[,lim][,fText][,color][,font=30][,fType][,align='M'][,hideF][,hide]
local _={
name= D.name or"_",
x= D.x,
y= D.y,
lim= D.lim or 1e99,
fText=D.fText,
color=D.color and(COLOR[D.color]or D.color)or COLOR.Z,
font= D.font or 30,
fType=D.fType,
align=D.align or'M',
hideF=D.hideF,
}
@@ -139,7 +148,7 @@ function button:reset()
end
function button:setObject(obj)
if type(obj)=='string'or type(obj)=='number'then
self.obj=gc.newText(FONT.get(self.font),obj)
self.obj=gc.newText(FONT.get(self.font,self.fType),obj)
elseif obj then
self.obj=obj
end
@@ -148,9 +157,9 @@ function button:isAbove(x,y)
local ATV=self.ATV
return
x>self.x-ATV and
y>self.y-ATV and
y>self.y and
x<self.x+self.w+2*ATV and
y<self.y+self.h+2*ATV
y<self.y+self.h
end
function button:getCenter()
return self.x+self.w*.5,self.y+self.h*.5
@@ -171,45 +180,49 @@ function button:draw()
--Button
gc_setColor(.15+r*.7,.15+g*.7,.15+b*.7,.9)
gc_rectangle('fill',x-ATV,y-ATV,w+2*ATV,h+2*ATV,3)
gc_rectangle('fill',x-ATV,y,w+2*ATV,h,4)
gc_setLineWidth(2)
gc_setColor(.3+r*.7,.3+g*.7,.3+b*.7)
gc_rectangle('line',x-ATV,y,w+2*ATV,h,5)
if ATV>0 then
gc_setLineWidth(2)
gc_setColor(.97,.97,.97,ATV*.125)
gc_rectangle('line',x-ATV+2,y-ATV+2,w+2*ATV-4,h+2*ATV-4,3)
gc_rectangle('line',x-ATV,y,w+2*ATV,h,3)
end
--Drawable
local obj=self.obj
local y0=y+h*.5-ATV*.5
local ox,oy=obj:getWidth()*.5,obj:getHeight()*.5
local y0=y+h*.5
gc_setColor(1,1,1,.2+ATV*.05)
if self.align=='M'then
local x0=x+w*.5
mDraw(obj,x0-1,y0-1)
mDraw(obj,x0-1,y0+1)
mDraw(obj,x0+1,y0-1)
mDraw(obj,x0+1,y0+1)
local kx=obj:type()=='Text'and min(w/ox/2,1)or 1
gc_draw(obj,x0-1,y0-1,nil,kx,1,ox,oy)
gc_draw(obj,x0-1,y0+1,nil,kx,1,ox,oy)
gc_draw(obj,x0+1,y0-1,nil,kx,1,ox,oy)
gc_draw(obj,x0+1,y0+1,nil,kx,1,ox,oy)
gc_setColor(r*.55,g*.55,b*.55)
mDraw(obj,x0,y0)
gc_draw(obj,x0,y0,nil,kx,1,ox,oy)
elseif self.align=='L'then
local edge=self.edge
mDraw_Y(obj,x+edge-1,y0-1)
mDraw_Y(obj,x+edge-1,y0+1)
mDraw_Y(obj,x+edge+1,y0-1)
mDraw_Y(obj,x+edge+1,y0+1)
gc_draw(obj,x+edge-1,y0-1-oy)
gc_draw(obj,x+edge-1,y0+1-oy)
gc_draw(obj,x+edge+1,y0-1-oy)
gc_draw(obj,x+edge+1,y0+1-oy)
gc_setColor(r*.55,g*.55,b*.55)
mDraw_Y(obj,x+edge,y0)
gc_draw(obj,x+edge,y0-oy)
elseif self.align=='R'then
local x0=x+w-self.edge-obj:getWidth()
mDraw_Y(obj,x0-1,y0-1)
mDraw_Y(obj,x0-1,y0+1)
mDraw_Y(obj,x0+1,y0-1)
mDraw_Y(obj,x0+1,y0+1)
local x0=x+w-self.edge-ox*2
gc_draw(obj,x0-1,y0-1-oy)
gc_draw(obj,x0-1,y0+1-oy)
gc_draw(obj,x0+1,y0-1-oy)
gc_draw(obj,x0+1,y0+1-oy)
gc_setColor(r*.55,g*.55,b*.55)
mDraw_Y(obj,x0,y0)
gc_draw(obj,x0,y0-oy)
end
end
function button:getInfo()
return("x=%d,y=%d,w=%d,h=%d,font=%d"):format(self.x+self.w*.5,self.y+self.h*.5,self.w,self.h,self.font)
return("x=%d,y=%d,w=%d,h=%d,font=%d"):format(self.x+self.w*.5,self.y+self.h*.5,self.w,self.h,self.font,self.fType)
end
function button:press(_,_,k)
self.code(k)
@@ -217,15 +230,15 @@ function button:press(_,_,k)
SYSFX.newRectRipple(
6,
self.x-ATV,
self.y-ATV-WIDGET.scrollPos,
self.y-WIDGET.scrollPos,
self.w+2*ATV,
self.h+2*ATV
self.h
)
if self.sound then
SFX.play('button')
SFX.play(self.sound)
end
end
function WIDGET.newButton(D)--name,x,y,w[,h][,fText][,color][,font=30][,sound=true][,align='M'][,edge=0],code[,hideF][,hide]
function WIDGET.newButton(D)--name,x,y,w[,h][,fText][,color][,font=30][,fType][,sound][,align='M'][,edge=0][,code][,hideF][,hide]
if not D.h then D.h=D.w end
local _={
name= D.name or"_",
@@ -246,13 +259,21 @@ function WIDGET.newButton(D)--name,x,y,w[,h][,fText][,color][,font=30][,sound=tr
fText=D.fText,
color=D.color and(COLOR[D.color]or D.color)or COLOR.Z,
font= D.font or 30,
fType=D.fType,
align=D.align or'M',
edge= D.edge or 0,
sound=D.sound~=false,
code= D.code,
code= D.code or NULL,
hideF=D.hideF,
hide= D.hide,
}
if D.sound==false then
_.sound=false
elseif type(D.sound)=='string'then
_.sound=D.sound
else
_.sound='button'
end
for k,v in next,button do _[k]=v end
setmetatable(_,widgetMetatable)
return _
@@ -268,7 +289,7 @@ function key:reset()
end
function key:setObject(obj)
if type(obj)=='string'or type(obj)=='number'then
self.obj=gc.newText(FONT.get(self.font),obj)
self.obj=gc.newText(FONT.get(self.font,self.fType),obj)
elseif obj then
self.obj=obj
end
@@ -298,48 +319,54 @@ function key:draw()
local align=self.align
local r,g,b=c[1],c[2],c[3]
--Frame
if not self.noFrame then
gc_setColor(.2+r*.8,.2+g*.8,.2+b*.8,.7)
gc_setLineWidth(2)
gc_rectangle('line',x,y,w,h,3)
end
--Fill
if self.fShade then
gc_setColor(r,g,b,ATV*.25)
if align=='M'then
mDraw(self.fShade,x+w*.5,y+h*.5)
gc_draw(self.fShade,x+w*.5-self.fShade:getWidth()*.5,y+h*.5-self.fShade:getHeight()*.5)
elseif align=='L'then
mDraw_Y(self.fShade,x+self.edge,y+h*.5)
gc_draw(self.fShade,x+self.edge,y+h*.5-self.fShade:getHeight()*.5)
elseif align=='R'then
mDraw_Y(self.fShade,x+w-self.edge-self.fShade:getWidth(),y+h*.5)
gc_draw(self.fShade,x+w-self.edge-self.fShade:getWidth(),y+h*.5-self.fShade:getHeight()*.5)
end
else
--Background
gc_setColor(0,0,0,.3)
gc_rectangle('fill',x,y,w,h,4)
--Frame
gc_setColor(.2+r*.8,.2+g*.8,.2+b*.8,.7)
gc_setLineWidth(2)
gc_rectangle('line',x,y,w,h,3)
--Shade
gc_setColor(1,1,1,ATV*.05)
gc_rectangle('fill',x,y,w,h,3)
end
--Drawable
local obj=self.obj
local ox,oy=obj:getWidth()*.5,obj:getHeight()*.5
gc_setColor(r,g,b)
if align=='M'then
mDraw(self.obj,x+w*.5,y+h*.5)
local kx=obj:type()=='Text'and min(w/ox/2,1)or 1
gc_draw(obj,x+w*.5,y+h*.5,nil,kx,1,ox,oy)
elseif align=='L'then
mDraw_Y(self.obj,x+self.edge,y+h*.5)
gc_draw(obj,x+self.edge,y-oy+h*.5)
elseif align=='R'then
mDraw_Y(self.obj,x+w-self.edge-self.obj:getWidth(),y+h*.5)
gc_draw(obj,x+w-self.edge-ox*2,y-oy+h*.5)
end
end
function key:getInfo()
return("x=%d,y=%d,w=%d,h=%d,font=%d"):format(self.x+self.w*.5,self.y+self.h*.5,self.w,self.h,self.font)
return("x=%d,y=%d,w=%d,h=%d,font=%d"):format(self.x+self.w*.5,self.y+self.h*.5,self.w,self.h,self.font,self.fType)
end
function key:press(_,_,k)
self.code(k)
if self.sound then
SFX.play('key')
SFX.play(self.sound)
end
end
function WIDGET.newKey(D)--name,x,y,w[,h][,fText][,fShade][,noFrame][,color][,font=30][,sound=true][,align='M'][,edge=0],code[,hideF][,hide]
function WIDGET.newKey(D)--name,x,y,w[,h][,fText][,fShade][,color][,font=30][,fType][,sound][,align='M'][,edge=0][,code][,hideF][,hide]
if not D.h then D.h=D.w end
local _={
name= D.name or"_",
@@ -359,16 +386,22 @@ function WIDGET.newKey(D)--name,x,y,w[,h][,fText][,fShade][,noFrame][,color][,fo
fText= D.fText,
fShade= D.fShade,
noFrame=D.noFrame,
color= D.color and(COLOR[D.color]or D.color)or COLOR.Z,
font= D.font or 30,
sound= D.sound~=false,
fType= D.fType,
align= D.align or'M',
edge= D.edge or 0,
code= D.code,
code= D.code or NULL,
hideF= D.hideF,
hide= D.hide,
}
if D.sound==false then
_.sound=false
elseif type(D.sound)=='string'then
_.sound=D.sound
else
_.sound='key'
end
for k,v in next,key do _[k]=v end
setmetatable(_,widgetMetatable)
return _
@@ -408,6 +441,10 @@ function switch:draw()
local x,y=self.x,self.y
local ATV=self.ATV
--Background
gc_setColor(0,0,0,.3)
gc_rectangle('fill',x,y-25,50,50,4)
--Frame
gc_setLineWidth(2)
gc_setColor(1,1,1,.6+ATV*.1)
@@ -430,15 +467,15 @@ function switch:draw()
gc_draw(obj,x-12-ATV,y,nil,min(self.lim/obj:getWidth(),1),1,obj:getWidth(),obj:getHeight()*.5)
end
function switch:getInfo()
return("x=%d,y=%d,font=%d"):format(self.x,self.y,self.font)
return("x=%d,y=%d,font=%d"):format(self.x,self.y,self.font,self.fType)
end
function switch:press()
self.code()
if self.sound then
SFX.play('move')
SFX.play(self.disp()and'check'or'uncheck')
end
end
function WIDGET.newSwitch(D)--name,x,y[,lim][,fText][,color][,font=30][,sound=true][,disp],code[,hideF][,hide]
function WIDGET.newSwitch(D)--name,x,y[,lim][,fText][,color][,font=30][,fType][,sound=true][,disp][,code][,hideF][,hide]
local _={
name= D.name or"_",
@@ -453,9 +490,10 @@ function WIDGET.newSwitch(D)--name,x,y[,lim][,fText][,color][,font=30][,sound=tr
fText=D.fText,
color=D.color and(COLOR[D.color]or D.color)or COLOR.Z,
font= D.font or 30,
fType=D.fType,
sound=D.sound~=false,
disp= D.disp,
code= D.code,
code= D.code or NULL,
hideF=D.hideF,
hide= D.hide,
}
@@ -491,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
end
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
function slider:update(dt)
local ATV=self.ATV
@@ -505,7 +543,7 @@ function slider:update(dt)
if ATV>0 then self.ATV=max(ATV-dt*30,0)end
end
if not self.hide then
self.pos=self.pos*.7+self.disp()*.3
self.pos=approach(self.pos,self.disp(),dt*26)
end
end
function slider:draw()
@@ -518,8 +556,8 @@ function slider:draw()
--Units
if not self.smooth then
gc_setLineWidth(2)
for p=0,self.unit do
local X=x+(x2-x)*p/self.unit
for p=self.rangeL,self.rangeR,self.unit do
local X=x+(x2-x)*(p-self.rangeL)/(self.rangeR-self.rangeL)
gc_line(X,y+7,X,y-7)
end
end
@@ -529,7 +567,7 @@ function slider:draw()
gc_line(x,y,x2,y)
--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
gc_setColor(.8,.8,.8)
gc_rectangle('fill',bx,by,bw,bh,3)
@@ -564,13 +602,16 @@ end
function slider:drag(x)
if not x then return end
x=x-self.x
local p=self.disp()
local P=x<0 and 0 or x>self.w and self.unit or x/self.w*self.unit
if not self.smooth then
P=int(P+.5)
local newPos=MATH.interval(x/self.w,0,1)
local newVal
if not self.unit then
newVal=(1-newPos)*self.rangeL+newPos*self.rangeR
else
newVal=newPos*(self.rangeR-self.rangeL)
newVal=self.rangeL+newVal-newVal%self.unit
end
if p~=P then
self.code(P)
if newVal~=self.disp()then
self.code(newVal)
end
if self.change and timer()-self.lastTime>.5 then
self.lastTime=timer()
@@ -583,8 +624,8 @@ function slider:release(x)
end
function slider:scroll(n)
local p=self.disp()
local u=self.smooth and .01 or 1
local P=n==-1 and max(p-u,0)or min(p+u,self.unit)
local u=self.unit or .01
local P=MATH.interval(p+u*n,self.rangeL,self.rangeR)
if p==P or not P then return end
self.code(P)
if self.change and timer()-self.lastTime>.18 then
@@ -593,9 +634,15 @@ function slider:scroll(n)
end
end
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
function WIDGET.newSlider(D)--name,x,y,w[,lim][,fText][,color][,unit][,smooth][,font=30][,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 _={
name= D.name or"_",
@@ -614,32 +661,30 @@ function WIDGET.newSlider(D)--name,x,y,w[,lim][,fText][,color][,unit][,smooth][,
fText= D.fText,
color= D.color and(COLOR[D.color]or D.color)or COLOR.Z,
unit= D.unit or 1,
smooth=false,
rangeL=D.axis[1],
rangeR=D.axis[2],
unit= D.axis[3],
smooth=D.smooth,
font= D.font or 30,
fType= D.fType,
change=D.change,
disp= D.disp,
code= D.code,
code= D.code or NULL,
hideF= D.hideF,
hide= D.hide,
show= false,
}
if D.smooth~=nil then
_.smooth=D.smooth
else
_.smooth=_.unit<=1
end
if D.show then
if type(D.show)=='function'then
_.show=D.show
else
_.show=sliderShowFunc[D.show]
end
elseif D.show~=false then
if _.unit<=1 then
_.show=sliderShowFunc.percent
else
elseif D.show~=false then--Use default if nil
if _.unit and _.unit%1==0 then
_.show=sliderShowFunc.int
else
_.show=sliderShowFunc.percent
end
end
for k,v in next,slider do _[k]=v end
@@ -691,6 +736,10 @@ function selector:draw()
local w=self.w
local ATV=self.ATV
--Background
gc_setColor(0,0,0,.3)
gc_rectangle('fill',x,y,w,60,4)
--Frame
gc_setColor(1,1,1,.6+ATV*.1)
gc_setLineWidth(2)
@@ -744,7 +793,7 @@ function selector:press(x)
self.select=s
self.selText=self.list[s]
if self.sound then
SFX.play('prerotate')
SFX.play('selector')
end
end
end
@@ -764,14 +813,14 @@ function selector:scroll(n)
self.select=s
self.selText=self.list[s]
if self.sound then
SFX.play('prerotate')
SFX.play('selector')
end
end
function selector: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
function WIDGET.newSelector(D)--name,x,y,w[,fText][,color][,sound=true],list,disp,code,hide
function WIDGET.newSelector(D)--name,x,y,w[,fText][,color][,sound=true],list,disp[,code],hide
local _={
name= D.name or"_",
@@ -793,7 +842,7 @@ function WIDGET.newSelector(D)--name,x,y,w[,fText][,color][,sound=true],list,dis
font= 30,
list= D.list,
disp= D.disp,
code= D.code,
code= D.code or NULL,
hideF=D.hideF,
hide= D.hide,
}
@@ -854,18 +903,24 @@ function inputBox:draw()
local x,y,w,h=self.x,self.y,self.w,self.h
local ATV=self.ATV
gc_setColor(1,1,1,ATV*.08)
gc_rectangle('fill',x,y,w,h,3)
--Background
gc_setColor(0,0,0,.4)
gc_rectangle('fill',x,y,w,h,4)
--Highlight
gc_setColor(1,1,1,ATV*.08*(math.sin(TIME()*4.2)*.2+.8))
gc_rectangle('fill',x,y,w,h,4)
--Frame
gc_setColor(1,1,1)
gc_setLineWidth(3)
gc_rectangle('line',x,y,w,h,3)
--Drawable
local f=self.font
FONT.set(f)
FONT.set(f,self.fType)
if self.obj then
mDraw_Y(self.obj,x-12-self.obj:getWidth(),y+h*.5)
gc_draw(self.obj,x-12-self.obj:getWidth(),y+h*.5-self.obj:getHeight()*.5)
end
if self.secret then
y=y+h*.5-f*.2
@@ -892,21 +947,21 @@ end
function inputBox:keypress(k)
local t=self.value
if #t>0 and EDITING==""then
if k=="backspace"then
if k=='backspace'then
local p=#t
while t:byte(p)>=128 and t:byte(p)<192 do
p=p-1
end
t=sub(t,1,p-1)
SFX.play('lock')
elseif k=="delete"then
elseif k=='delete'then
t=""
SFX.play('hold')
end
self.value=t
end
end
function WIDGET.newInputBox(D)--name,x,y,w[,h][,font=30][,secret][,regex][,limit],hide
function WIDGET.newInputBox(D)--name,x,y,w[,h][,font=30][,fType][,secret][,regex][,limit],hide
local _={
name= D.name or"_",
@@ -922,6 +977,7 @@ function WIDGET.newInputBox(D)--name,x,y,w[,h][,font=30][,secret][,regex][,limit
},
font= D.font or int(D.h/7-1)*5,
fType= D.fType,
secret=D.secret==true,
regex= D.regex,
limit= D.limit,
@@ -999,9 +1055,9 @@ function textBox:scroll(dir)
self:drag(nil,nil,nil,-dir*self.lineH)
end
function textBox:arrowKey(k)
if k=="up"then
if k=='up'then
self:scroll(-1)
elseif k=="down"then
elseif k=='down'then
self:scroll(-1)
end
end
@@ -1013,8 +1069,8 @@ function textBox:draw()
local lineH=self.lineH
--Background
gc_setColor(0,0,0,.4)
gc_rectangle('fill',x,y,w,h,3)
gc_setColor(0,0,0,.3)
gc_rectangle('fill',x,y,w,h,4)
--Frame
gc_setLineWidth(2)
@@ -1022,7 +1078,7 @@ function textBox:draw()
gc_rectangle('line',x,y,w,h,3)
--Texts
FONT.set(self.font)
FONT.set(self.font,self.fType)
gc_push('transform')
gc_translate(x,y)
@@ -1054,7 +1110,7 @@ end
function textBox: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)
end
function WIDGET.newTextBox(D)--name,x,y,w,h[,font=30][,lineH][,fix],hide
function WIDGET.newTextBox(D)--name,x,y,w,h[,font=30][,fType][,lineH][,fix],hide
local _={
name= D.name or"_",
@@ -1076,6 +1132,7 @@ function WIDGET.newTextBox(D)--name,x,y,w,h[,font=30][,lineH][,fix],hide
h= D.h,
font= D.font or 30,
fType=D.fType,
fix= D.fix,
texts={},
hideF=D.hideF,
@@ -1153,7 +1210,7 @@ function listBox:press(x,y)
if self.list[y]then
if self.selected~=y then
self.selected=y
SFX.play('click',.4)
SFX.play('selector',.8,0,12)
end
end
end
@@ -1176,6 +1233,14 @@ function listBox:arrowKey(dir)
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()
local x,y,w,h=self.x,self.y,self.w,self.h
local list=self.list
@@ -1186,6 +1251,10 @@ function listBox:draw()
gc_push('transform')
gc_translate(x,y)
--Background
gc_setColor(0,0,0,.4)
gc_rectangle('fill',0,0,w,h,4)
--Frame
gc_setColor(WIDGET.sel==self and COLOR.lN or COLOR.Z)
gc_setLineWidth(2)
@@ -1214,7 +1283,7 @@ end
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)
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 _={
name= D.name or"_",
@@ -1271,16 +1340,7 @@ function WIDGET.setWidgetList(list)
for i=1,#list do
list[i]:reset()
end
if SCN.cur~='custom_field'then
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
onChange()
end
end
function WIDGET.setScrollHeight(height)
@@ -1373,101 +1433,17 @@ function WIDGET.release(x,y)
W:release(x,y+WIDGET.scrollPos)
end
end
function WIDGET.keyPressed(k,isRep)
local W=WIDGET.sel
if k=="space"or k=="return"then
if not isRep then
WIDGET.press()
end
elseif k=="up"or k=="down"or k=="left"or k=="right"then
if kb.isDown("lshift","lalt","lctrl")then
--Control some widgets with arrowkeys when hold shift/ctrl/alt
if W and W.arrowKey then W:arrowKey(k)end
else
if not W then
for _,w in next,WIDGET.active do
if not w.hide and w.isAbove then
WIDGET.focus(w)
return
end
end
elseif W.getCenter then
local WX,WY=W:getCenter()
local dir=(k=="right"or k=="down")and 1 or -1
local tar
local minDist=1e99
local swap_xy=k=="up"or k=="down"
if swap_xy then WX,WY=WY,WX end--note that we do not swap them back later
for _,W1 in ipairs(WIDGET.active)do
if W~=W1 and W1.resCtr and not W1.hide then
local L=W1.resCtr
for j=1,#L,2 do
local x,y=L[j],L[j+1]
if swap_xy then x,y=y,x end--note that we do not swap them back later
local dist=(x-WX)*dir
if dist>10 then
dist=dist+abs(y-WY)*6.26
if dist<minDist then
minDist=dist
tar=W1
end
end
end
end
end
if tar then
WIDGET.focus(tar)
end
end
end
else
if W and W.keypress then
W:keypress(k)
end
end
end
function WIDGET.textinput(texts)
local W=WIDGET.sel
if W and W.type=='inputBox'then
if(not W.regex or texts:match(W.regex))and(not W.limit or #(WIDGET.sel.value..texts)<=W.limit)then
WIDGET.sel.value=WIDGET.sel.value..texts
SFX.play('move')
SFX.play('touch')
else
SFX.play('finesseError',.3)
SFX.play('drop_cancel')
end
end
end
local keyMirror={
dpup="up",
dpdown="down",
dpleft="left",
dpright="right",
start="return",
back="escape",
}
function WIDGET.gamepadPressed(i)
if i=="start"then
WIDGET.press()
elseif i=="a"or i=="b"then
local W=WIDGET.sel
if W then
if W.type=='button'or W.type=='key'then
WIDGET.press()
elseif W.type=='slider'then
local p=W.disp()
local P=i=="left"and(p>0 and p-1)or p<W.unit and p+1
if p==P or not P then return end
W.code(P)
if W.change and timer()-W.lastTime>.18 then
W.lastTime=timer()
W.change()
end
end
end
elseif i=="dpup"or i=="dpdown"or i=="dpleft"or i=="dpright"then
WIDGET.keyPressed(keyMirror[i])
end
end
function WIDGET.update(dt)
for _,W in next,WIDGET.active do

View File

@@ -1,27 +1,23 @@
**TECHMINO © 2019-2021 26F Studio. Some rights reserved.**
TECHMINO and "26F Studio" are trademarks of 26F Studio.
The TECHMINO game and source code are under a GNU Lesser General Public License Version 3.
TECHMINO © 2019-2021 26F Studio. Some rights reserved.
TECHMINO and "26F Studio" are trademarks of 26F Studio. The TECHMINO game and source code are under a GNU Lesser General Public License Version 3.
TECHMINO is not a fan game of Tetris. TECHMINO and 26F Studio are not affiliated with Tetris Holding, LLC or The Tetris Company, Inc. in any way.
"Tetris" is the registered trademark of The Tetris Holding, LLC, licensed to The Tetris Company, Inc.
"Tetris" is the registered trademark of The Tetris Holding, LLC, licensed to The Tetris Company, Inc. TECHMINO is not a fan game of Tetris. TECHMINO and 26F Studio are not affiliated with Tetris Holding, LLC or The Tetris Company, Inc. in any way.
Powered by LÖVE, © 2006-2021 LÖVE Development Team.
Lua is free software distributed under the terms of the MIT license. Copyright © 1994-2021 by Lua.org, PUC-Rio.
Lua is free software distributed under the terms of the MIT license. Copyright © 1994~2021 by Lua.org, PUC-Rio.
SIMPLE LOVE LIGHTS is under a MIT License. Created by Dylan Hunn.
json.lua is copyrighted by rxi. © 2021 rxi.
IBM Plex is copyrighted by the International Business Machines Corporation. IBM and IBM Plex are trademarks of IBM Corp, registered in many jurisdictions worldwide. IBM Plex is licensed under the SIL Open Font License, Version 1.1.
The Apple logo, "Apple Inc.," iOS, iPadOS, macOS, iPhone, and Mac are registered trademarks of Apple Inc. in the United States of America and other countries or regions.
"Windows", the Windows logo, "Xbox", Xbox logo, and "Microsoft" are registered trademarks of Microsoft Corporation in the United States of America and other countries or regions.
Alibaba Sans is copyrighted by Alibaba Group Holding Limited. Alibaba is a trademark of Alibaba Group Holding Limited in the Peoples Republic of China and other countries or regions.
Source Han Sans is copyrighted by Adobe Inc. Source Han Sans and Adobe are registered trademarks of Adobe Inc. in United States and other countries or regions. Source Han Sans is licensed under the SIL Open Font License, Version 1.1.
JetBrains Mono is copyrighted by the JetBrains Mono Project authors. JetBrains Mono is a trademark of JetBrains s.r.o. JetBrains Mono is licensed under the SIL Open Font License, Version 1.1.
@@ -30,22 +26,26 @@ JetBrains Mono is copyrighted by the JetBrains Mono Project authors. JetBrains M
"PlayStation", "PS", "PlayStation Family Mark", "PS logo", "DualSense" and "Play Has No Limits" are registered trademarks or trademarks of Sony Interactive Entertainment Inc. "SONY" is a registered trademark of Sony Corporation. © 2021 Sony Interactive Entertainment LLC.
N3TWORK is a registered trademark of N3TWORK Inc. © 2021 N3TWORK Inc.
"Windows", the Windows logo, "Xbox", Xbox logo, and "Microsoft" are registered trademarks of Microsoft Corporation in the United States of America and other countries or regions.
The Apple logo, "Apple Inc.," iOS, iPadOS, macOS, iPhone, and Mac are registered trademarks of Apple Inc. in the United States of America and other countries or regions.
"EA" and "Electronic Arts" are registered trademarks of Electronic Arts Inc. © 2021 Electronic Arts Inc.
SEGA and the SEGA logo are registered trademarks of Sega Corporation. © 2021 Sega Corporation.
Oculus Quest is a registered trademark of Facebook Technologies, LLC. © Facebook, Inc.
Oculus Quest is a registered trademark of Facebook Technologies, LLC. © Meta Platforms, Inc.
"Nintendo" is a registered trademarks of Nintendo Co., Ltd. © 2021 Nintendo Co., Ltd.
N3TWORK is a registered trademark of N3TWORK Inc. © 2021 N3TWORK Inc.
GoldWave is a registered trademark of GoldWave, Inc.
Linux is a registered trademark of Linus Torvalds.
Linux is a registered trademark of Linus Torvalds.
Touhou Project © Team Shanghai Alice 2002-2021.
All other trademarks are the properties of their respective owners.
All other trademarks, logos, and copyrights are the properties of their respective owners.

230
main.lua
View File

@@ -23,13 +23,14 @@ local fs=love.filesystem
VERSION=require"version"
TIME=love.timer.getTime
YIELD=coroutine.yield
SYSTEM=love.system.getOS()
SYSTEM=love.system.getOS()if SYSTEM=='OS X'then SYSTEM='macOS'end
FNNS=SYSTEM:find'\79\83'--What does FNSF stand for? IDK so don't ask me lol
MOBILE=SYSTEM=='Android'or SYSTEM=='iOS'
SAVEDIR=fs.getSaveDirectory()
--Global Vars & Settings
SFXPACKS={'chiptune'}
VOCPACKS={'miya','mono','xiaoya','miku'}
VOCPACKS={'miya',--[['mono',]]'xiaoya','miku'}
FIRSTLAUNCH=false
DAILYLAUNCH=false
@@ -49,9 +50,30 @@ local _LOADTIME_=TIME()
--Load modules
Z=require'Zframework'
FONT.load('parts/fonts/proportional.ttf')
FONT.load{
norm='parts/fonts/proportional.ttf',
mono='parts/fonts/monospaced.ttf',
}
FONT.setDefault('norm')
FONT.setFallback('norm')
SCR.setSize(1280,720)--Initialize Screen size
BGM.setMaxSources(5)
BGM.setChange(function(name)MES.new('music',text.nowPlaying..name,5)end)
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_))
@@ -62,6 +84,9 @@ mStr=GC.mStr
mText=GC.simpX
mDraw=GC.draw
Snd=SFX.playSample
string.repD=STRING.repD
string.sArg=STRING.sArg
string.split=STRING.split
--Delete all naked files (from too old version)
FILE.clear('')
@@ -90,7 +115,8 @@ for _,v in next,fs.getDirectoryItems('parts/shaders')do
end
end
FREEROW= require'parts.freeRow'
THEME= require'parts.theme'
LINE= require'parts.line'
DATA= require'parts.data'
TEXTURE= require'parts.texture'
@@ -102,14 +128,17 @@ BOT= require'parts.bot'
RSlist= require'parts.RSlist'DSCP=RSlist.TRS.centerPos
PLY= require'parts.player'
NETPLY= require'parts.netPlayer'
MODES= require'parts.modes'
MODETREE= require'parts.modeTree'
setmetatable(TEXTURE,{__index=function(self,k)
MES.new('warn',"No texture called: "..k)
self[k]=PAPER
return self[k]
end})
table.insert(_LOADTIMELIST_,("Load Parts: %.3fs"):format(TIME()-_LOADTIME_))
--Init Zframework
Z.setIfPowerInfo(function()
return SETTING.powerInfo and LOADED
end)
do--Z.setCursor
local normImg=GC.DO{16,16,
{'fCirc',8,8,4},
@@ -143,8 +172,8 @@ Z.setOnFnKeys({
function()
if GAME.playing and not GAME.net then
for _=1,8 do
local P=PLY_ALIVE[math.random(#PLY_ALIVE)]
if P and P~=PLAYERS[1]then
if #PLY_ALIVE>1 then
local P=PLY_ALIVE[math.random(2,#PLY_ALIVE)]
P.lastRecv=PLAYERS[1]
P:lose()
end
@@ -153,8 +182,11 @@ Z.setOnFnKeys({
end,
function()print(WIDGET.getSelected()or"no widget selected")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
local function task_autoSoundOff()
while true do
@@ -196,15 +228,15 @@ end
Z.setOnQuit(destroyPlayers)
--Load settings and statistics
TABLE.cover (FILE.load('conf/user')or{},USER)
TABLE.cover (FILE.load('conf/unlock')or{},RANKS)
TABLE.update(FILE.load('conf/settings')or{},SETTING)
TABLE.update(FILE.load('conf/data')or{},STAT)
TABLE.cover (FILE.load('conf/key')or{},KEY_MAP)
TABLE.cover (FILE.load('conf/virtualkey')or{},VK_ORG)
TABLE.cover (loadFile('conf/user','-canSkip')or{},USER)
TABLE.cover (loadFile('conf/unlock','-canSkip')or{},RANKS)
TABLE.update(loadFile('conf/settings','-canSkip')or{},SETTING)
TABLE.coverR(loadFile('conf/data','-canSkip')or{},STAT)
TABLE.cover (loadFile('conf/key','-canSkip')or{},KEY_MAP)
TABLE.cover (loadFile('conf/virtualkey','-json -canSkip')or{},VK_ORG)
--Initialize fields, sequence, missions, gameEnv for cutsom game
local fieldData=FILE.load('conf/customBoards','string')
local fieldData=loadFile('conf/customBoards','-string -canSkip')
if fieldData then
fieldData=STRING.split(fieldData,"!")
for i=1,#fieldData do
@@ -213,16 +245,16 @@ if fieldData then
else
FIELD[1]=DATA.newBoard()
end
local sequenceData=FILE.load('conf/customSequence','string')
local sequenceData=loadFile('conf/customSequence','-string -canSkip')
if sequenceData then
DATA.pasteSequence(sequenceData)
end
local missionData=FILE.load('conf/customMissions','string')
local missionData=loadFile('conf/customMissions','-string -canSkip')
if missionData then
DATA.pasteMission(missionData)
end
local customData=FILE.load('conf/customEnv')
if customData and customData.version==VERSION.code then
local customData=loadFile('conf/customEnv','-canSkip')
if customData and customData['version']==VERSION.code then
TABLE.complete(customData,CUSTOMENV)
end
TABLE.complete(require"parts.customEnv0",CUSTOMENV)
@@ -239,14 +271,17 @@ IMG.init{
speedLimit='media/image/mess/speedLimit.png',--Not used, for future C2-mode
pay1='media/image/mess/pay1.png',
pay2='media/image/mess/pay2.png',
drought='media/image/mess/drought.png',
miyaCH='media/image/characters/miya.png',
miyaF1='media/image/characters/miya_f1.png',
miyaF2='media/image/characters/miya_f2.png',
miyaF3='media/image/characters/miya_f3.png',
miyaF4='media/image/characters/miya_f4.png',
miyaCH1='media/image/characters/miya1.png',
miyaCH2='media/image/characters/miya2.png',
miyaCH3='media/image/characters/miya3.png',
miyaCH4='media/image/characters/miya4.png',
miyaHeart='media/image/characters/miya_heart.png',
miyaGlow='media/image/characters/miya_glow.png',
monoCH='media/image/characters/mono.png',
xiaoyaCH='media/image/characters/xiaoya.png',
xiaoyaOmino='media/image/characters/xiaoya_Omino.png',
mikuCH='media/image/characters/miku.png',
electric='media/image/characters/electric.png',
hbm='media/image/characters/hbm.png',
@@ -263,7 +298,7 @@ IMG.init{
SKIN.load{
{name="crystal_scf",path='media/image/skin/crystal_scf.png'},
{name="matte_mrz",path='media/image/skin/matte_mrz.png'},
{name="shiny_cho",path='media/image/skin/shiny_cho.png'},
{name="shiny_chno",path='media/image/skin/shiny_chno.png'},
{name="contrast_mrz",path='media/image/skin/contrast_mrz.png'},
{name="polkadots_scf",path='media/image/skin/polkadots_scf.png'},
{name="toy_scf",path='media/image/skin/toy_scf.png'},
@@ -286,6 +321,7 @@ SKIN.load{
{name="classic",path='media/image/skin/classic_unknown.png'},
{name="ball_shaw",path='media/image/skin/ball_shaw.png'},
{name="retro_notypey",path='media/image/skin/retro_notypey.png'},
{name="pixel_chno",path='media/image/skin/pixel_chno.png'},
{name="textbone_mrz",path='media/image/skin/textbone_mrz.png'},
{name="coloredbone_mrz",path='media/image/skin/coloredbone_mrz.png'},
{name="wtf",path='media/image/skin/wtf_mrz.png'},
@@ -301,11 +337,11 @@ SFX.init((function()--[Warning] Not loading files here, just get the list of sou
end
return L
end)())
BGM.init((function()
BGM.load((function()
local L={}
for _,v in next,fs.getDirectoryItems('media/music')do
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
return L
@@ -324,17 +360,19 @@ VOC.init{
LANG.init('zh',
{
zh=require'parts.language.lang_zh',
zh_trad=require'parts.language.lang_zh_trad',
zh_full=require'parts.language.lang_zh_full',
en=require'parts.language.lang_en',
fr=require'parts.language.lang_fr',
es=require'parts.language.lang_es',
pt=require'parts.language.lang_pt',
id=require'parts.language.lang_id',
zh_grass=require'parts.language.lang_zh_grass',
zh_yygq=require'parts.language.lang_yygq',
symbol=require'parts.language.lang_symbol',
--1. Add language file to LANG folder;
--2. Require it;
--3. Add a button in parts/scenes/setting_lang.lua;
--3. Add a button in parts/scenes/lang.lua;
},
{
block=BLOCK_NAMES
@@ -363,6 +401,7 @@ for _,v in next,fs.getDirectoryItems('parts/backgrounds')do
BG.add(name,require('parts.backgrounds.'..name))
end
end
BG.remList('none')BG.remList('gray')BG.remList('custom')
--Load scene files from SOURCE ONLY
for _,v in next,fs.getDirectoryItems('parts/scenes')do
if isSafeFile('parts/scenes/'..v)then
@@ -371,24 +410,6 @@ for _,v in next,fs.getDirectoryItems('parts/scenes')do
LANG.addScene(sceneName)
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_))
@@ -397,7 +418,6 @@ do
local needSave
if not fs.getInfo('conf/data')then
FIRSTLAUNCH=true
needSave=true
end
if type(STAT.version)~='number'then
@@ -429,7 +449,6 @@ do
if RANKS.tsd_u then
RANKS.tsd_u=0
end
needSave=true
end
if STAT.version==1601 then
RANKS.round_e=nil
@@ -443,7 +462,14 @@ do
fs.remove('record/round_l.rec')
fs.remove('record/round_u.rec')
end
if STAT.version<1604 then
if STAT.version<1700 and SETTING.dascut<5 then
SETTING.dascut=SETTING.dascut+1
needSave=true
end
if SETTING.vocPack=='mono'then
SETTING.vocPack='miya'
end
if RANKS.stack_e then
RANKS.stack_e=nil
RANKS.stack_h=nil
RANKS.stack_u=nil
@@ -459,21 +485,48 @@ do
fs.remove('record/stack_40l.rec')
fs.remove('record/stack_100l.rec')
end
if RANKS.rhythm_e then
RANKS.rhythm_e=nil
RANKS.rhythm_h=nil
RANKS.rhythm_u=nil
fs.remove('record/rhythm_e.rec')
fs.remove('record/rhythm_h.rec')
fs.remove('record/rhythm_u.rec')
end
if RANKS.bigbang then
RANKS.clearRush,RANKS.bigbang=RANKS.bigbang
fs.remove('record/bigbang.rec')
end
if STAT.version~=VERSION.code then
for k,v in next,MODE_UPDATE_MAP do
if RANKS[k]then
RANKS[v]=RANKS[k]
RANKS[k]=nil
end
k='record/'..k
if fs.getInfo(k..'.dat')then
fs.write('record/'..v..'.rec',fs.read(k..'.dat'))
fs.remove(k..'.dat')
end
if fs.getInfo(k..'.rec')then
fs.write('record/'..v..'.rec',fs.read(k..'.rec'))
fs.remove(k..'.rec')
end
end
STAT.version=VERSION.code
needSave=true
love.event.quit('restart')
end
SETTING.appLock=nil
SETTING.dataSaving=nil
SETTING.swap=nil
SETTING.appLock,SETTING.dataSaving,SETTING.swap=nil
if not SETTING.VKSkin then SETTING.VKSkin=1 end
for _,v in next,SETTING.skin do if v<1 or v>17 then v=17 end end
if SETTING.RS=='ZRS'or SETTING.RS=='BRS'or SETTING.RS=='ASCplus'or SETTING.RS=='C2sym'then SETTING.RS='TRS'end
if not RSlist[SETTING.RS]then SETTING.RS='TRS'end
if SETTING.ghostType=='greyCell'then SETTING.ghostType='grayCell'end
if type(SETTING.skinSet)=='number'then SETTING.skinSet='crystal_scf'end
if not TABLE.find({8,10,13,17,22,29,37,47,62,80,100},SETTING.frameMul)then SETTING.frameMul=100 end
if SETTING.cv then SETTING.vocPack,SETTING.cv=SETTING.cv end
if type(SETTING.bg)~='string'then SETTING.bg='on'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_dig then RANKS.infinite_dig=0 end
if not RANKS.sprint_10l then RANKS.sprint_10l=0 end
@@ -484,40 +537,6 @@ do
if type(name)=='number'or type(rank)~='number'then
RANKS[name]=nil
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
if not MODES[STAT.lastPlay]then
STAT.lastPlay='sprint_10l'
needSave=true
end
for k,v in next,MODE_UPDATE_MAP do
if RANKS[k]then
RANKS[v]=RANKS[k]
RANKS[k]=nil
end
k='record/'..k
if fs.getInfo(k..'.dat')then
fs.write('record/'..v..'.rec',fs.read(k..'.dat'))
fs.remove(k..'.dat')
end
if fs.getInfo(k..'.rec')then
fs.write('record/'..v..'.rec',fs.read(k..'.rec'))
fs.remove(k..'.rec')
end
end
@@ -525,10 +544,12 @@ do
saveStats()
saveProgress()
saveSettings()
love.event.quit('restart')
end
end
--First start for phones
--First start
FIRSTLAUNCH=STAT.run==0
if FIRSTLAUNCH and MOBILE then
SETTING.VKSwitch=true
SETTING.powerInfo=true
@@ -536,7 +557,7 @@ if FIRSTLAUNCH and MOBILE then
end
--Apply system setting
applyAllSettings()
applySettings()
--Load replays
for _,fileName in next,fs.getDirectoryItems('replay')do
@@ -588,35 +609,36 @@ table.insert(_LOADTIMELIST_,("Initialize Data: %.3fs"):format(TIME()-_LOADTIME_)
for i=1,#_LOADTIMELIST_ do LOG(_LOADTIMELIST_[i])end
--Launch testing task if launch param received
if TABLE.find(arg,'--test')then
TASK.new(function()
while not LOADED do YIELD()end
print("\27[92m\27[1mAutomatic Test Started\27[0m")
LOG("\27[92m\27[1mAutomatic Test Started\27[0m")
BGM.setVol(0)SFX.setVol(0)
love.keypressed('space')
while SCN.swapping do YIELD()end
TEST.yieldUntilNextScene()
for k,mode in next,MODES do
if k~='netBattle'then
print("Scanning mode: "..mode.name)
loadGame(mode.name.."a",true)
while SCN.swapping do YIELD()end
LOG("Scanning mode: "..mode.name)
loadGame(mode.name,true)
TEST.yieldUntilNextScene()
SCN.back()
while SCN.swapping do YIELD()end
TEST.yieldUntilNextScene()
end
end
print("\27[92m\27[1mAutomatic Test Passed :)\27[0m")
for _=1,60 do YIELD()end
LOG("\27[92m\27[1mAutomatic Test Passed :)\27[0m")
TEST.yieldN(60)
love.event.quit(0)
end)
TASK.new(function()
while true do
YIELD()
if ERRDATA[1]then break end
if Z.getErr(1)then break end
end
print("\27[91m\27[1mAutomatic Test Failed :(\27[0m\nThe error message is:\n"..table.concat(ERRDATA[1].mes,"\n").."\27[91m\nAborting\27[0m")
for _=1,60 do YIELD()end
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)
love.event.quit(1)
end)
end

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

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: 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 41 KiB

BIN
media/music/1980s.ogg Normal file

Binary file not shown.

BIN
media/music/lounge.ogg Normal file

Binary file not shown.

BIN
media/music/malate.ogg Normal file

Binary file not shown.

BIN
media/music/peak.ogg Normal file

Binary file not shown.

View File

@@ -97,12 +97,12 @@ do
{131,2,2, 0, 0,0},{131,2,2,-1,-1,0},{131,2,2,-1, 0,0},--S
{131,1,2,-1, 0,0},{131,1,2, 0,-1,0},{131,1,2, 0, 0,0},--Z(misOrder)
{313,2,2, 0, 0,0},{313,2,2,-1,-1,0},{313,2,2,-1, 0,0},--S(misOrder)
{331,3,2, 0,-1,0},--J(farDown)
{113,4,2,-1,-1,0},--L(farDown)
{331,3,2, 0,-1,1},--J(farDown)
{113,4,2,-1,-1,1},--L(farDown)
{113,3,2,-1,-1,0},{113,3,0, 0, 0,0},--J
{331,4,2, 0,-1,0},{331,4,0,-1, 0,0},--L
{222,7,2,-1, 0,2},{222,7,2,-2, 0,2},{222,7,2, 0, 0,2},--I
{222,7,0,-1, 1,1},{222,7,0,-2, 1,1},{222,7,0, 0, 1,1},--I(high)
{222,7,2,-1, 0,2},{222,7,2,-2, 0,2},{222,7,2, 0, 0,2},--I(low)
{121,6,0, 1,-1,2},{112,6,0, 2,-1,2},{122,6,0, 1,-2,2},--O
{323,6,0,-1,-1,2},{332,6,0,-2,-1,2},{322,6,0,-1,-2,2},--O
}--{keys, ID, dir, dx, dy, freeLevel (0=immovable, 1=U/D-immovable, 2=free)}
@@ -129,10 +129,10 @@ do
[10]={'+0+0','+1+0','+1-1','+0+2','+1-2','+1-2'},
[03]={'+0+0','+1+0','+1+1','+0-2','+1-1','+1-2'},
[30]={'+0+0','-1+0','-1-1','+0+2','-1+2','+0-1'},
[12]={'+0+0','+1+0','+1-1','+0+2','+1+2'},
[21]={'+0+0','-1+0','-1+1','+0-2','-1-2'},
[32]={'+0+0','-1+0','-1-1','+0+2','-1+2'},
[23]={'+0+0','+1+0','+1+1','+0-2','+1-2'},
[12]={'+0+0','+1+0','+1-1','+0+2','+1+2','+1+1'},
[21]={'+0+0','-1+0','-1+1','+0-2','-1-2','-1-1'},
[32]={'+0+0','-1+0','-1-1','+0+2','-1+2','+0-1'},
[23]={'+0+0','+1+0','+1+1','+0-2','+1-2','+0+1'},
[02]={'+0+0','+1+0','-1+0','+0-1','+0+1'},
[20]={'+0+0','-1+0','+1+0','+0+1','+0-1'},
[13]={'+0+0','+0-1','+0+1','+0-2'},
@@ -140,8 +140,8 @@ do
},--Z
false,--S
{
[01]={'+0+0','-1+0','-1+1','+0-2','+1+1','+0+1'},
[10]={'+0+0','+1+0','+1-1','+0+2','-1-1','+0-1'},
[01]={'+0+0','-1+0','-1+1','+0-2','+1+1','+0+1','+0-1'},
[10]={'+0+0','+1+0','+1-1','+0+2','-1-1','+0-1','+0+1'},
[03]={'+0+0','+1+0','+1+1','+0-2','+1-2','+1-1','+0+1'},
[30]={'+0+0','-1+0','-1-1','+0+2','-1+2','+0-1','-1+1'},
[12]={'+0+0','+1+0','+1-1','+1+1','-1+0','+0-1','+0+2','+1+2'},
@@ -204,6 +204,7 @@ do
P.spinLast=2
P.stat.rotate=P.stat.rotate+1
P:freshBlock('move')
C.spinSeq=nil
return
end
end
@@ -304,8 +305,8 @@ do
[10]={'+0+0','+0+1','+1+0','+0-2','+1-2'},
[03]={'+0+0','+0-1','+0+1','+0+2'},
[30]={'+0+0','+0-1','+0+1','+0-2'},
[12]={'+0+0','+0-1','+0+1'},
[21]={'+0+0','+0-1','+0-2'},
[12]={'+0+0','+0-1','+0+1','+0+2'},
[21]={'+0+0','+0-1','+0-2','+0-2'},
[32]={'+0+0','+1+0','-1+0'},
[23]={'+0+0','-1+0','+1+0'},
[02]={'+0+0','-1+1','+1-1'},
@@ -353,8 +354,8 @@ do
[21]={'+0+0','-1+0','-1+1','+0+1','-1+2','+0+2','-1-1','+1+0','+0-2','-1-2'},
[32]={'+0+0','-1+0','-1+1','-1-1','+1+0','+0+2','-1+2','+0-2'},
[23]={'+0+0','+1+0','+1-1','+1+1','-1+0','+0-2','+1-2','+0+2'},
[02]={'+0+0','+0-1','+1-1','-1+0','+2-1'},
[20]={'+0+0','+0+1','-1+1','+1+0','-2+1'},
[02]={'+0+0','+0-1','-1-1','+1-1','-1+0','+2-1'},
[20]={'+0+0','+0+1','+1+1','-1+1','+1+0','-2+1'},
[13]={'+0+0','-1+0','-1-1','+0+1','-1-2'},
[31]={'+0+0','+1+0','+1+1','+0-1','+1+2'},
},--J5
@@ -375,8 +376,8 @@ do
},--R
false,--Y
{
[01]={'+0+0','-1+0','-1+1','+0+1','+1+0','-1+2','-2+0','+0-2'},
[10]={'+0+0','+1+0','-1+0','+0-1','+1-1','+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-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'},
[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'},
@@ -686,13 +687,7 @@ do
sfx='prerotate'
elseif P:ifoverlap(icb,x,y+1)and P:ifoverlap(icb,x-1,y)and P:ifoverlap(icb,x+1,y)then
sfx='rotatekick'
if P.gameEnv.shakeFX then
if d==1 or d==3 then
P.fieldOff.va=P.fieldOff.va+(2-d)*6e-3
else
P.fieldOff.va=P.fieldOff.va+P:getCenterX()*3e-3
end
end
P:_rotateField(d)
else
sfx='rotate'
end
@@ -767,6 +762,68 @@ do
ARS_Z.kickTable[25]=upSet
end
local DRS_weak
do
local centerPos=TABLE.copy(defaultCenterPos)
centerPos[1]={[0]={1,1},{1,0},{1,1},{1,1}}--Z
centerPos[2]={[0]={1,1},{1,0},{1,1},{1,1}}--S
centerPos[3]={[0]={1,1},{1,0},{1,1},{1,1}}--L
centerPos[4]={[0]={1,1},{1,0},{1,1},{1,1}}--J
centerPos[5]={[0]={1,1},{1,0},{1,1},{1,1}}--T
centerPos[7]={[0]={.5,1.5},{1.5,-.5},{.5,1.5},{1.5,.5}}--I
centerPos[10]={[0]={1,1},{1,0},{1,1},{1,0}}--P
centerPos[11]={[0]={1,1},{1,1},{1,1},{1,1}}--Q
centerPos[15]={[0]={1,1},{1,0},{1,1},{1,1}}--U
centerPos[16]={[0]={1,1},{1,1},{1,1},{1,1}}--V
centerPos[19]={[0]={1.5,1.5},{1.5,0.5},{1.5,1.5},{1.5,0.5}}--J5
centerPos[20]={[0]={1.5,1.5},{1.5,0.5},{1.5,1.5},{1.5,0.5}}--L5
centerPos[21]={[0]={1.5,1.5},{1.5,0.5},{1.5,1.5},{1.5,0.5}}--R
centerPos[22]={[0]={1.5,1.5},{1.5,0.5},{1.5,1.5},{1.5,0.5}}--Y
centerPos[23]={[0]={1.5,1.5},{1.5,0.5},{1.5,1.5},{1.5,0.5}}--N
centerPos[24]={[0]={1.5,1.5},{1.5,0.5},{1.5,1.5},{1.5,0.5}}--H
centerPos[26]={[0]={0,1},{0,0},{0,1},{0,0}}--I3
centerPos[28]={[0]={0,1},{0,0},{0,1},{0,0}}--I2
local L={'+0+0','-1+0','+1+0','+0-1','-1-1','+1-1'}
local R={'+0+0','+1+0','-1+0','+0-1','+1-1','-1-1'}
local Z={
[01]=R,[10]=L,[03]=L,[30]=R,
[12]=R,[21]=L,[32]=L,[23]=R,
[02]=R,[20]=L,[13]=L,[31]=R,
}
local S=_reflect(Z)
DRS_weak={
centerTex=GC.DO{10,10,
{'setLW',2},
{'dRect',1,1,8,8},
{'fRect',3,3,4,4},
},
centerPos=centerPos,
kickTable={
Z,S,--Z,S
Z,S,--J,L
Z,--T
noKickSet,--O
Z,--I
Z,S,--Z5,S5
Z,S,--P,Q
Z,S,--F,E
Z,Z,Z,Z,--T5,U,V,W
noKickSet,--X
Z,S,--J5,L5
Z,S,--R,Y
Z,S,--N,H
Z,--I5
Z,Z,--I3,C
Z,Z,--I2,O1
}
}
end
local ASC
do
local L={'+0+0','+1+0','+0-1','+1-1','+0-2','+1-2','+2+0','+2-1','+2-2','-1+0','-1-1','+0+1','+1+1','+2+1','-1-2','-2+0','+0+2','+1+2','+2+2','-2-1','-2-2'}
@@ -940,6 +997,7 @@ local RSlist={
SRS_X=SRS_X,
BiRS=BiRS,
ARS_Z=ARS_Z,
DRS_weak=DRS_weak,
ASC=ASC,
ASC_plus=ASC_plus,
C2=C2,

View File

@@ -1,4 +1,4 @@
--Blackhole
--blockhole
local gc=love.graphics
local gc_clear,gc_replaceTransform=gc.clear,gc.replaceTransform
local gc_setColor,gc_setLineWidth=gc.setColor,gc.setLineWidth
@@ -51,7 +51,7 @@ function back.draw()
gc_draw(S.texture,S.d*cos(S.ang),S.d*sin(S.ang),S.rotate,S.size*.026,nil,15,15)
end
--Blackhole
--blockhole
gc_setColor(.07,.07,.07)
gc_circle('fill',0,0,157)
gc_setLineWidth(6)

View File

@@ -0,0 +1,31 @@
--Secret custom background
local gc_clear,gc_setColor=love.graphics.clear,love.graphics.setColor
local back={}
local image=false
local alpha=.26
local mx,my,k
function back.init()
back.resize()
end
function back.resize()
mx,my=SCR.w*.5,SCR.h*.5
if image then
k=math.max(SCR.w/image:getWidth(),SCR.h/image:getHeight())
end
end
function back.draw()
gc_clear(.1,.1,.1)
if image then
gc_setColor(1,1,1,alpha)
mDraw(image,mx,my,nil,k)
end
end
function back.event(a,img)
if a then alpha=a end
if img then image=img end
back.resize()
end
return back

View File

@@ -12,10 +12,9 @@ local ins,rem=table.insert,table.remove
local back={}
local t
local fan,petal
local petal
function back.init()
t=0
fan=SVG_TITLE_FAN
petal={}
end
function back.update()
@@ -62,7 +61,7 @@ function back.draw()
gc_setLineWidth(6)
gc_setColor(.8,.9,1,.3)
for i=1,8 do gc_polygon('line',fan[i])end
for i=1,#SVG_TITLE_FAN do gc_polygon('line',SVG_TITLE_FAN[i])end
gc_setLineWidth(2)
gc_setColor(1,.5,.7,.3)

View File

@@ -0,0 +1,11 @@
--Customizable grey background
local gc=love.graphics
local back={}
local brightness=.26
function back.draw()
gc.clear(brightness,brightness,brightness)
end
function back.event(b)
brightness=b
end
return back

View File

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

View File

@@ -61,7 +61,7 @@ function back.draw()
gc.setColor(wingColor[i])
local B=crystals[i]
gc.draw(crystal_img,B.x,B.y,B.a,k,k,21,0)
B=crystals[17-i]
B=crystals[8+i]
gc.draw(crystal_img,B.x,B.y,B.a,-k,k,21,0)
end
end

View File

@@ -44,8 +44,7 @@ local function _ifoverlapAI(f,bk,x,y)
end
end end
end
local discardRow=FREEROW.discard
local getRow=FREEROW.get
local getRow,discardRow=LINE.new,LINE.discard
local function _resetField(f0,f,start)
for _=#f,start,-1 do
discardRow(f[_])

View File

@@ -25,8 +25,8 @@ function bot_cc:revive()
self.P:loadAI(self.data)
end
function bot_cc:pushNewNext(id)
self.ccBot:addNext(rem(self.nexts,1))
ins(self.nexts,id)
self.ccBot:addNext(rem(self.bufferedNexts,1))
ins(self.bufferedNexts,id)
end
function bot_cc:thread()
local P,keys=self.P,self.keys

View File

@@ -12,7 +12,7 @@ local baseBot={
function baseBot.update(bot)
local P=bot.P
local keys=bot.keys
if P.control and P.waiting==-1 then
if P.control and P.cur then
bot.delay=bot.delay-1
if not keys[1]then
if bot.runningThread then
@@ -85,7 +85,7 @@ function BOT.new(P,data)
if data.type=="CC"then
P:setRS('SRS')
bot.keys={}
bot.nexts={}
bot.bufferedNexts={}
bot.delay=data.delay
bot.delay0=data.delay
if P.gameEnv.holdCount>1 then
@@ -109,20 +109,25 @@ function BOT.new(P,data)
return
self.ccBot[k]and function(_,...)self.ccBot[k](self.ccBot,...)end or
cc_lua[k]and function(_,...)cc_lua[k](self,...)end or
baseBot[k]and baseBot[k]or
error("No actions called "..k)
assert(baseBot[k],"No CC action called "..k)
end})
for i,B in next,P.nextQueue do
if i<=data.next then
local pushed=0
if P.cur then
bot:addNext(P.cur.id)
pushed=pushed+1
end
for _,B in next,P.nextQueue do
if pushed<=data.next then
bot:addNext(B.id)
pushed=pushed+1
else
ins(bot.nexts,B.id)
ins(bot.bufferedNexts,B.id)
end
end
bot.runningThread=coroutine.wrap(cc_lua.thread)
bot.runningThread(bot)
elseif data.type=="9S"or true then--9s or else
else--if data.type=="9S"then--9s or else
TABLE.cover(baseBot,bot)
TABLE.cover(require"parts.bot.bot_9s",bot)
P:setRS('TRS')

View File

@@ -6,6 +6,8 @@ return{
lock=1e99,
wait=0,
fall=0,
hang=5,
hurry=1e99,
--Control
nextCount=6,
@@ -19,6 +21,7 @@ return{
--Rule
sequence='bag',
lockout=false,
fieldH=20,
heightLimit=1e99,
bufferLimit=1e99,

View File

@@ -33,6 +33,7 @@ return{
P:_showText(text.maxspeed,0,-140,100,'appear',.6)
end
end
P:shakeField(9)
D.wave=D.wave+1
end
end

View File

@@ -42,6 +42,7 @@ return{
P:_showText(text.maxspeed,0,-140,100,'appear',.6)
end
end
P:shakeField(10)
D.wave=D.wave+1
end
end

View File

@@ -1,5 +1,5 @@
return{
dropPiece=function(P)
hook_drop=function(P)
if P.lastPiece.atk>0 then
P:receive(nil,P.lastPiece.atk,0,generateLine(P.holeRND:random(10)))
end

View File

@@ -1,5 +1,5 @@
return{
dropPiece=function(P)
hook_drop=function(P)
if P.lastPiece.atk>0 then
P:receive(nil,P.lastPiece.atk,120,generateLine(P.holeRND:random(10)))
end

View File

@@ -1,5 +1,5 @@
return{
dropPiece=function(P)
hook_drop=function(P)
if P.lastPiece.atk>0 then
P:receive(nil,P.lastPiece.atk,30,generateLine(P.holeRND:random(10)))
end

View File

@@ -1,5 +1,5 @@
return{
dropPiece=function(P)
hook_drop=function(P)
if P.lastPiece.atk>0 then
P:receive(nil,P.lastPiece.atk,60,generateLine(P.holeRND:random(10)))
end

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