Compare commits

...

284 Commits

Author SHA1 Message Date
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
MrZ626
684cb90a7d 修改堆叠模式玩法(自动清除之前记录)
修改更新历史和build号
2021-11-02 03:38:43 +08:00
MrZ626
172101ed55 整理玩家类代码,再分离出一个方法 2021-11-02 02:27:08 +08:00
MrZ626
98b5914726 移除机翻语言的tips 2021-11-02 02:15:34 +08:00
MrZ626
d1518e7ba4 词典新增研究群下属mew词条 2021-11-02 00:31:43 +08:00
MrZ626
72d4faa52a 微调进控制台音效力度 2021-11-01 21:56:57 +08:00
MrZ626
862dcbf806 准备&开始音效改为函数整理到gameFuncs文件里
launchpad可以执行任意函数,添加准备-开始音效
2021-11-01 20:30:04 +08:00
MrZ626
3db28f5136 再修正ci替换版本号的问题 2021-11-01 17:33:42 +08:00
MrZ626
f9e37f3c6a 修正ci替换版本号的小问题 2021-11-01 17:24:47 +08:00
MrZ626
457681e6ec 中英tips调整 2021-11-01 16:26:34 +08:00
MrZ626
904bcf6852 版本号改为0.16.4,移除@DEV标记(需要测试) 2021-11-01 15:52:23 +08:00
MrZ626
e21e57ff84 添加tip命令方便看tips 2021-11-01 14:51:40 +08:00
MrZ626
562a69831a 给中英tip排序 2021-11-01 14:32:26 +08:00
C29H25N3O5
706a683540 修正标点, .gitignore添加几个文件类型 2021-11-01 14:13:08 +08:00
C29H25N3O5
8e2aee5e84 再改语言文件 2021-11-01 14:13:08 +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
MrZ626
f68facbe0e 检测到启动参数有--test时启动测试脚本(需要更多测试)
Co-authored-by: Trebor Huang <41145779+Trebor-Huang@users.noreply.github.com>
2021-11-01 03:41:19 +08:00
MrZ626
5535366bb1 TASK模块创建任务第一次执行的时候也用assert保证错误被捕捉 2021-11-01 03:23:00 +08:00
Imple Lee
d75b709f23 Move Python code from updateVersion.py into action.ymls directly (#423)
* test python3

* try use `python` instead of `python3`

* use `update-version` everywhere

* fix variable injection

* fix python2vs3

* move `updateVersion.py` into action files
2021-11-01 02:12:32 +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
MrZ626
0a15011ec7 修复模式目录下非完整模式文件也会被当成模式加载 2021-10-31 02:03:54 +08:00
ParticleG
f7dfe1d869 - Re-enable other workflows 2021-10-31 00:39:54 +08:00
ParticleG
5e9c9cb5fa - Try use discordrb 2021-10-31 00:39:52 +08:00
MrZ626
c485c26c93 修改更新历史和build号 2021-10-31 00:34:49 +08:00
MrZ626
137d9296cd 移除一个TODO的注释 2021-10-30 15:57:34 +08:00
MrZ626
11b144da74 词典场景按键也会自动开始输入 2021-10-30 15:36:56 +08:00
MrZ626
25ef9d9886 再调整中英两个词典 2021-10-30 15:02:11 +08:00
MrZ626
0e1e279209 游戏界面布局微调:录像播放时单独一套;模式名文本太长的时候会横向压缩 2021-10-30 14:48:19 +08:00
C29H25N3O5
a960897a83 字体加几个新的 Unicode 字符 2021-10-30 14:33:03 +08:00
C29H25N3O5
69ab7849c5 英文词典补完 2021-10-30 14:33:03 +08:00
MrZ626
bc55c3d892 中文词典添加are和line are两个词条,英文词典添加几个todo 2021-10-29 16:01:42 +08:00
283 changed files with 4491 additions and 2698 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

@@ -59,11 +59,41 @@ runs:
shell: bash
run: |
7z a -tzip love-android/app/src/main/assets/game.love libAndroid
- name: update Android information
shell: python
run: |
if '${{ inputs.type }}' == 'Release':
appName = 'Techmino'
packageName = 'org.love2d.MrZ.Techmino'
edition = 'release'
elif '${{ inputs.type }}' == 'Snapshot':
appName = 'Techmino_Snapshot'
packageName = 'org.love2d.MrZ.Techmino.Snapshot'
edition = 'snapshot'
with open('./love-android/app/src/main/AndroidManifest.xml', "r+", encoding='utf-8') as file:
data = file.read()
data = data\
.replace('@appName', appName)\
.replace('@edition', edition)
file.seek(0)
file.truncate()
file.write(data)
with open("./love-android/app/build.gradle", "r+", encoding='utf-8') as file:
data = file.read()
data = data\
.replace('@packageName', packageName)\
.replace('@versionCode', '${{ inputs.apkCode }}')\
.replace('@versionName', '${{ inputs.name }}')\
.replace('@storePassword', '${{ inputs.KEY_STORE_PASSWORD }}')\
.replace('@keyAlias', '${{ inputs.ALIAS }}')\
.replace('@keyPassword', '${{ inputs.KEY_PASSWORD }}')
file.seek(0)
file.truncate()
file.write(data)
- name: Build Techmino
shell: bash
run: |
echo "${{ inputs.SIGNING_KEY }}" | base64 -d > love-android/app/android.keystore
python3 .github/workflows/updateVersion.py -T Android${{ inputs.type }} -C ${{ inputs.apkCode }} -N ${{ inputs.name }} -S ${{ inputs.KEY_STORE_PASSWORD }} -A ${{ inputs.ALIAS }} -K ${{ inputs.KEY_PASSWORD }}
chmod 777 love-android/gradlew
cd love-android/
./gradlew assembleRelease

View File

@@ -40,6 +40,9 @@ inputs:
FASTLANE_DISCORD_WEBHOOK:
required: true
description: "Fastlane Discord webhook"
FASTLANE_ACTION_ID:
required: true
description: "Fastlane Action ID"
FASTLANE_MATCH_PWD:
required: true
description: "Fastlane Match description password"
@@ -71,6 +74,7 @@ runs:
lane: '${{ inputs.type }}'
subdirectory: 'Techmino-iOS/platform/xcode'
env:
ACTION_ID: '${{ inputs.FASTLANE_ACTION_ID }}'
API_ID: '${{ inputs.APPLE_API_ID }}'
API_ISSUER: '${{ inputs.APPLE_API_ISSUER }}'
API_KEY: '${{ inputs.APPLE_API_KEY }}'

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

View File

@@ -59,12 +59,22 @@ runs:
MATCH_PASSWORD: '${{ inputs.FASTLANE_MATCH_PWD }}'
MATCH_TOKEN: '${{ inputs.FASTLANE_MATCH_TOKEN }}'
- name: Modify template
shell: python
run: |
import datetime
from io import open
thisYear = str(datetime.datetime.today().year)
with open('./.github/build/macOS/info.plist.template', 'r', encoding='utf-8') as file:
data = file.read()
data = data\
.replace('@versionName', '${{ inputs.name }}'[1:])\
.replace('@thisYear', thisYear)\
.replace('@bundleId', '${{ inputs.APPLE_APP_IDENTIFIER }}')
with open('./Techmino-macOS/Techmino.app/Contents/info.plist', 'w+', encoding='utf-8') as file:
file.write(data)
- name: Pack
shell: bash
run: |
python3 .github/workflows/updateVersion.py -T macOS \
-N ${{ inputs.name }} \
-B ${{ inputs.APPLE_APP_IDENTIFIER }}
mv Techmino.love Techmino-macOS/Techmino.app/Contents/Resources
mv CCloader.dylib Techmino-macOS/Techmino.app/Contents/Frameworks
mv ${{ inputs.icon }} Techmino-macOS/Techmino.app/Contents/Resources/iconfile.icns

View File

@@ -30,6 +30,18 @@ runs:
with:
url: http://www.angusj.com/resourcehacker/resource_hacker.zip
- uses: ./.github/actions/build-love
- name: update Windows template
shell: python
run: |
Version = '${{ inputs.version }}'.replace('V', '')
FileVersion = (f"{Version.replace('.', ',')},0")
with open('./.github/build/Windows/Techmino.rc.template', 'r', encoding='utf8') as file:
data = file.read()
data = data\
.replace('@FileVersion', FileVersion)\
.replace('@Version', Version)
with open('Techmino.rc', 'w+', encoding='utf8') as file:
file.write(data)
- name: Pack Techmino
shell: pwsh
run: |
@@ -42,7 +54,6 @@ runs:
del .\love\readme.txt
move .\cold_clear.dll .\love
move .\CCloader.dll .\love
python .\.github\workflows\updateVersion.py -T Windows -N ${{ inputs.version }}
cmd /c '.\ResourceHacker.exe -open .\love\Techmino.exe -save .\love\Techmino.exe -action delete -mask ICONGROUP,,'
cmd /c '.\ResourceHacker.exe -open .\Techmino.rc -save .\Techmino.res -action compile'
cmd /c '.\ResourceHacker.exe -open .\love\Techmino.exe -save .\love\Techmino.exe -action addoverwrite -res "${{ inputs.icon }}" -mask ICONGROUP,1,'

View File

@@ -1,12 +0,0 @@
name: 'update for a snapshot'
description: 'common update logic for snapshot'
inputs:
commit:
required: true
runs:
using: "composite"
steps:
- shell: bash
run: |
python3 .github/workflows/updateVersion.py -T Conf
python3 .github/workflows/updateVersion.py -T Version -H ${{ inputs.commit }}

View File

@@ -0,0 +1,37 @@
name: 'update version'
description: 'common update logic for snapshot and release'
inputs:
commit:
required: false
type:
required: true
runs:
using: "composite"
steps:
- shell: python
name: update snapshot saving folder
run: |
from io import open
if '${{ inputs.type }}'.lower() != 'snapshot':
exit(0)
with open('conf.lua', 'r+', encoding='utf-8') as file:
data = file.read()
data = data.replace("t.identity='Techmino'--Saving folder", "t.identity='Techmino_Snapshot'--Saving folder")
file.seek(0)
file.truncate()
file.flush()
file.write(data)
- shell: python
run: |
from io import open
import re
with open('version.lua', 'r+', encoding='utf-8') as file:
commitHash = '${{ inputs.commit }}'
if commitHash != '':
commitHash = '@' + commitHash[0:4]
data = file.read()
data = re.sub('(\d)"', r'\1' + commitHash + '"', data, 1)
file.seek(0)
file.truncate()
file.flush()
file.write(data)

Binary file not shown.

View File

@@ -27,14 +27,21 @@ 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
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/snapshot-update
- uses: ./.github/actions/update-version
with:
commit: ${{ needs.get-info.outputs.commit }}
type: snapshot
- uses: ./.github/actions/build-windows
with:
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win64.zip
@@ -53,9 +60,10 @@ jobs:
needs: get-info
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/snapshot-update
- uses: ./.github/actions/update-version
with:
commit: ${{ needs.get-info.outputs.commit }}
type: snapshot
- uses: ./.github/actions/build-linux
with:
icon: .github/build/Linux/icon_snapshot.png
@@ -70,9 +78,10 @@ jobs:
needs: get-info
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/snapshot-update
- uses: ./.github/actions/update-version
with:
commit: ${{ needs.get-info.outputs.commit }}
type: snapshot
- uses: ./.github/actions/build-android
with:
type: Snapshot
@@ -88,15 +97,44 @@ 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
needs: get-info
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/snapshot-update
- uses: ./.github/actions/update-version
with:
commit: ${{ needs.get-info.outputs.commit }}
type: snapshot
- uses: ./.github/actions/build-macos
with:
name: ${{ needs.get-info.outputs.name }}
@@ -117,12 +155,14 @@ 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
- uses: ./.github/actions/snapshot-update
- uses: ./.github/actions/update-version
with:
commit: ${{ needs.get-info.outputs.commit }}
type: snapshot
- uses: ./.github/actions/build-ios
with:
name: ${{ needs.get-info.outputs.name }}
@@ -137,6 +177,7 @@ jobs:
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 }}'
@@ -144,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
local str=require"version".string:gsub("@DEV","")
elseif arg=="-name"then
local str=require"version".string
print(str)
elseif arg[1]=="-release"then
local str=require"version".string:gsub("V","",1):gsub("@DEV","")
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,233 +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
- name: Update Version
run: |
python .\.github\workflows\updateVersion.py -T 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
- name: Update Version
run: |
python .\.github\workflows\updateVersion.py -T 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
- name: Update Version
run: |
python3 .github/workflows/updateVersion.py -T 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
- name: Update Version
run: |
python3 .github/workflows/updateVersion.py -T 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
- name: Update Version
run: |
python3 .github/workflows/updateVersion.py -T 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
- name: Update Version
run: |
python3 .github/workflows/updateVersion.py -T 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/snapshot-update
with:
commit: ${{ needs.get-info.outputs.commit }}
- 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_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
- name: Update Version
run: |
python3 .github/workflows/updateVersion.py -T 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

@@ -33,9 +33,10 @@ jobs:
needs: get-info
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/snapshot-update
- uses: ./.github/actions/update-version
with:
commit: ${{ needs.get-info.outputs.commit }}
type: snapshot
- uses: ./.github/actions/build-windows
with:
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win64.zip
@@ -46,24 +47,25 @@ 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
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/snapshot-update
- uses: ./.github/actions/update-version
with:
commit: ${{ needs.get-info.outputs.commit }}
type: snapshot
- uses: ./.github/actions/build-linux
with:
icon: .github/build/Linux/icon_snapshot.png
- 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:
@@ -71,9 +73,10 @@ jobs:
needs: get-info
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/snapshot-update
- uses: ./.github/actions/update-version
with:
commit: ${{ needs.get-info.outputs.commit }}
type: snapshot
- uses: ./.github/actions/build-android
with:
type: Snapshot
@@ -87,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:
@@ -95,9 +98,10 @@ jobs:
needs: get-info
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/snapshot-update
- uses: ./.github/actions/update-version
with:
commit: ${{ needs.get-info.outputs.commit }}
type: snapshot
- uses: ./.github/actions/build-macos
with:
name: ${{ needs.get-info.outputs.name }}
@@ -113,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:
@@ -121,9 +125,10 @@ jobs:
needs: get-info
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/snapshot-update
- uses: ./.github/actions/update-version
with:
commit: ${{ needs.get-info.outputs.commit }}
type: snapshot
- uses: ./.github/actions/build-ios
with:
name: ${{ needs.get-info.outputs.name }}
@@ -138,11 +143,12 @@ jobs:
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: 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

@@ -1,100 +0,0 @@
import argparse
import re
def updateConf(): #更新存档位置
with open('conf.lua', 'r+', encoding='utf-8') as file:
data = file.read()
data = data.replace("t.identity='Techmino'--Saving folder", "t.identity='Techmino_Snapshot'--Saving folder")
file.seek(0)
file.truncate()
file.flush()
file.write(data)
def updateVersion(args): #更新版本号
with open('version.lua', 'r+', encoding='utf-8') as file:
data = file.read()
if args.Hash != False:
data = data.replace('@DEV', f'@{args.Hash[0:4]}')
else:
data = data.replace('@DEV', '')
file.seek(0)
file.truncate()
file.flush()
file.write(data)
def updateMacOS(args): #更新macOS打包信息
import datetime
thisYear = str(datetime.datetime.today().year)
with open('./.github/build/macOS/info.plist.template', 'r', encoding='utf-8') as file:
data = file.read()
data = data\
.replace('@versionName', args.Name[1:])\
.replace('@thisYear', thisYear)\
.replace('@bundleId', args.Bundle)
with open('./Techmino-macOS/Techmino.app/Contents/info.plist', 'w+', encoding='utf-8') as file:
file.write(data)
def updateWindows(args): #更新Windows打包信息
Version = (args.Name).replace('V', '')
FileVersion = (f"{Version.replace('.', ',')},0")
with open('./.github/build/Windows/Techmino.rc.template', 'r', encoding='utf8') as file:
data = file.read()
data = data\
.replace('@FileVersion', FileVersion)\
.replace('@Version', Version)
with open('Techmino.rc', 'w+', encoding='utf8') as file:
file.write(data)
def updateAndroid(args, edition): #更新Android打包信息
if edition == 'Release':
appName = 'Techmino'
packageName = 'org.love2d.MrZ.Techmino'
edition = 'release'
elif edition == 'Snapshot':
appName = 'Techmino_Snapshot'
packageName = 'org.love2d.MrZ.Techmino.Snapshot'
edition = 'snapshot'
with open('./love-android/app/src/main/AndroidManifest.xml', "r+", encoding='utf-8') as file:
data = file.read()
data = data\
.replace('@appName', appName)\
.replace('@edition', edition)
file.seek(0)
file.truncate()
file.write(data)
with open("./love-android/app/build.gradle", "r+", encoding='utf-8') as file:
data = file.read()
data = data\
.replace('@packageName', packageName)\
.replace('@versionCode', args.Code)\
.replace('@versionName', args.Name)\
.replace('@storePassword', args.Store)\
.replace('@keyAlias', args.Alias)\
.replace('@keyPassword', args.Key)
file.seek(0)
file.truncate()
file.write(data)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='用于CI更新程序各类信息')
parser.add_argument('-T', '--Type', type=str, help = '更新的种类')
parser.add_argument('-B', '--Bundle', type=str, help = '应用包名')
parser.add_argument('-H', '--Hash', type=str, default = False, help = 'Github提交Hash')
parser.add_argument('-C', '--Code', type=str, default = False, help = 'versionCode')
parser.add_argument('-N', '--Name', type=str, default = False, help = 'versionName')
parser.add_argument('-S', '--Store', type=str, default = False, help = 'storePassword')
parser.add_argument('-A', '--Alias', type=str, default = False, help = 'keyAlias')
parser.add_argument('-K', '--Key', type=str, default = False, help = 'keyPassword')
args = parser.parse_args()
if args.Type == 'Conf':
updateConf()
elif args.Type == 'Version':
updateVersion(args)
elif args.Type == 'Windows':
updateWindows(args)
elif args.Type == 'macOS':
updateMacOS(args)
elif args.Type == 'AndroidRelease':
updateAndroid(args, 'Release')
elif args.Type == 'AndroidSnapshot':
updateAndroid(args, 'Snapshot')

7
.gitignore vendored
View File

@@ -1,3 +1,8 @@
.vscode
libAndroid
*.ini
*.ini
.DS_Store
Thumbs.db
Icon?
.Trash
.file

View File

@@ -1,4 +1,6 @@
local Sources={}
local lastLoaded={}
local maxLoadedCount=3
local SourceObjList={}
local volume=1
local BGM={
@@ -37,15 +39,41 @@ end
local function check_curFadeOut(task,code,src)
return task.code==code and task.args[1]==src
end
local function _tryReleaseSources()
local n=#lastLoaded
while #lastLoaded>maxLoadedCount do
local name=lastLoaded[n]
if SourceObjList[name].source:isPlaying()then
n=n-1
if n<=0 then return end
else
SourceObjList[name].source=SourceObjList[name].source:release()and nil
table.remove(lastLoaded,n)
return
end
end
end
function BGM.setDefault(bgm)
BGM.default=bgm
end
function BGM.setMaxSources(count)
maxLoadedCount=count
_tryReleaseSources()
end
function BGM.setChange(func)
BGM.onChange=func
end
function BGM.setVol(v)
assert(type(v)=='number'and v>=0 and v<=1)
assert(type(v)=='number'and v>=0 and v<=1,'Wrong volume')
volume=v
if BGM.playing then
if volume>0 then
BGM.playing:setVolume(volume)
BGM.playing:play()
elseif BGM.nowPlay then
BGM.playing:pause()
end
end
end
function BGM.init(list)
BGM.init=nil
@@ -53,7 +81,7 @@ function BGM.init(list)
local simpList={}
for _,v in next,list do
table.insert(simpList,v.name)
Sources[v.name]=v.path
SourceObjList[v.name]={path=v.path,source=false}
end
table.sort(simpList)
function BGM.getList()return simpList end
@@ -61,58 +89,43 @@ function BGM.init(list)
LOG(count.." BGM files added")
function BGM.getCount()return count end
local function _load(name)
if type(Sources[name])=='string'then
if love.filesystem.getInfo(Sources[name])then
Sources[name]=love.audio.newSource(Sources[name],'stream')
Sources[name]:setLooping(true)
Sources[name]:setVolume(0)
local function _tryLoad(name)
if SourceObjList[name]then
if SourceObjList[name].source then
return true
elseif love.filesystem.getInfo(SourceObjList[name].path)then
SourceObjList[name].source=love.audio.newSource(SourceObjList[name].path,'stream')
SourceObjList[name].source:setLooping(true)
SourceObjList[name].source:setVolume(0)
table.insert(lastLoaded,1,name)
_tryReleaseSources()
return true
else
LOG("No BGM: "..Sources[name],5)
LOG("No BGM: "..SourceObjList[name],5)
end
elseif Sources[name]then
return true
elseif name then
LOG("No BGM: "..name,5)
end
end
function BGM.setVol(v)
assert(type(v)=='number'and v>=0 and v<=1)
volume=v
if BGM.playing then
if volume>0 then
BGM.playing:setVolume(volume)
BGM.playing:play()
elseif BGM.nowPlay then
BGM.playing:pause()
end
end
end
function BGM.loadAll()--Not neccessary, unless you want avoid the lag when playing something for the first time
for name in next,Sources do
_load(name)
end
end
function BGM.play(name)
name=name or BGM.default
if not _load(name)then return end
if not _tryLoad(name)then return end
if volume==0 then
BGM.nowPlay=name
BGM.playing=Sources[name]
BGM.playing=SourceObjList[name].source
return true
end
if name and Sources[name]then
if name and SourceObjList[name].source then
if BGM.nowPlay~=name then
if BGM.nowPlay then
TASK.new(task_fadeOut,BGM.playing)
end
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,Sources[name])
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,SourceObjList[name].source)
TASK.removeTask_code(task_fadeIn)
TASK.new(task_fadeIn,Sources[name])
TASK.new(task_fadeIn,SourceObjList[name].source)
BGM.nowPlay=name
BGM.playing=Sources[name]
BGM.playing=SourceObjList[name].source
BGM.lastPlayed=BGM.nowPlay
BGM.playing:seek(0)
BGM.playing:play()
@@ -128,8 +141,8 @@ function BGM.init(list)
end
function BGM.continue()
if BGM.lastPlayed then
BGM.nowPlay,BGM.playing=BGM.lastPlayed,Sources[BGM.lastPlayed]
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,Sources[BGM.nowPlay])
BGM.nowPlay,BGM.playing=BGM.lastPlayed,SourceObjList[BGM.lastPlayed].source
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,SourceObjList[BGM.nowPlay].source)
TASK.removeTask_code(task_fadeIn)
TASK.new(task_fadeIn,BGM.playing)
BGM.playing:play()

View File

@@ -1,63 +1,80 @@
local abs=math.abs
local function hsv(h,s,v,a)
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.16, 0.82, 0.90)},
lime= {hsv(0.18, 0.89, 0.88)},
jade= {hsv(0.23, 1.00, 0.82)},
green= {hsv(0.33, 1.00, 0.81)},
aqua= {hsv(0.48, 1.00, 0.74)},
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.73, 1.00, 0.91)},
purple= {hsv(0.80, 1.00, 0.81)},
magenta= {hsv(0.86, 1.00, 0.78)},
wine= {hsv(0.94, 0.96, 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.15, 0.61, 0.95)},
lLime= {hsv(0.19, 0.66, 0.92)},
lJade= {hsv(0.24, 0.56, 0.90)},
lGreen= {hsv(0.34, 0.49, 0.89)},
lAqua= {hsv(0.49, 0.59, 0.85)},
lCyan= {hsv(0.51, 0.77, 0.88)},
lNavy= {hsv(0.54, 0.80, 0.95)},
lSea= {hsv(0.56, 0.72, 0.97)},
lBlue= {hsv(0.64, 0.44, 0.96)},
lViolet= {hsv(0.73, 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.11, 0.80, 0.37)},
dLime= {hsv(0.17, 0.80, 0.26)},
dJade= {hsv(0.31, 0.80, 0.27)},
dGreen= {hsv(0.33, 0.80, 0.26)},
dAqua= {hsv(0.47, 0.80, 0.23)},
dCyan= {hsv(0.50, 0.80, 0.30)},
dNavy= {hsv(0.59, 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)},
}
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',

View File

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

View File

@@ -1,14 +1,16 @@
NONE={}function NULL()end
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)
@@ -71,7 +73,8 @@ local xOy=SCR.xOy
local ITP=xOy.inverseTransformPoint
local mx,my,mouseShow=-20,-20,false
joysticks={}
local jsState={}--map, joystickID->axisStates: {axisName->axisVal}
local errData={}--list, each error create {mes={errMes strings},scene=sceneNameStr}
local devMode
@@ -285,18 +288,18 @@ function love.textinput(texts)
WIDGET.textinput(texts)
end
function love.joystickadded(JS)
table.insert(joysticks,JS)
MES.new('info',"Joystick added")
end
function love.joystickremoved(JS)
local i=TABLE.find(joysticks,JS)
if i then
table.remove(joysticks,i)
MES.new('info',"Joystick removed")
end
end
local keyMirror={
--analog sticks: -1, 0, 1 for neg, neutral, pos
--triggers: 0 for released, 1 for pressed
local jsAxisEventName={
leftx={'leftstick_left','leftstick_right'},
lefty={'leftstick_up','leftstick_down'},
rightx={'rightstick_left','rightstick_right'},
righty={'rightstick_up','rightstick_down'},
triggerleft='triggerleft',
triggerright='triggerright'
}
local gamePadKeys={'a','b','x','y','back','guide','start','leftstick','rightstick','leftshoulder','rightshoulder','dpup','dpdown','dpleft','dpright'}
local dPadToKey={
dpup='up',
dpdown='down',
dpleft='left',
@@ -304,54 +307,92 @@ local keyMirror={
start='return',
back='escape',
}
function love.joystickadded(JS)
jsState[JS:getID()]={
_loveJSObj=JS,
leftx=0,lefty=0,
rightx=0,righty=0,
triggerleft=0,triggerright=0
}
MES.new('info',"Joystick added")
end
function love.joystickremoved(JS)
local js=jsState[JS:getID()]
if js then
for i=1,#gamePadKeys do
if JS:isGamepadDown(gamePadKeys[i])then
love.gamepadreleased(JS,gamePadKeys[i])
end
end
love.gamepadaxis(JS,'leftx',0)
love.gamepadaxis(JS,'lefty',0)
love.gamepadaxis(JS,'rightx',0)
love.gamepadaxis(JS,'righty',0)
love.gamepadaxis(JS,'triggerleft',-1)
love.gamepadaxis(JS,'triggerright',-1)
jsState[JS:getID()]=nil
MES.new('info',"Joystick removed")
end
end
function love.gamepadaxis(JS,axis,val)
local js=jsState[JS:getID()]
if js then
if axis=='leftx'or axis=='lefty'or axis=='rightx'or axis=='righty'then
local newVal=--range: [0,1]
val>.4 and 1 or
val<-.4 and -1 or
0
if newVal~=js[axis]then
if js[axis]==-1 then
love.gamepadreleased(JS,jsAxisEventName[axis][1])
elseif js[axis]~=0 then
love.gamepadreleased(JS,jsAxisEventName[axis][2])
end
if newVal==-1 then
love.gamepadpressed(JS,jsAxisEventName[axis][1])
elseif newVal==1 then
love.gamepadpressed(JS,jsAxisEventName[axis][2])
end
js[axis]=newVal
end
elseif axis=='triggerleft'or axis=='triggerright'then
local newVal=val>-.3 and 1 or 0--range: [-1,1]
if newVal~=js[axis]then
if newVal==1 then
love.gamepadpressed(JS,jsAxisEventName[axis])
else
love.gamepadreleased(JS,jsAxisEventName[axis])
end
js[axis]=newVal
end
end
end
end
function love.gamepadpressed(_,i)
mouseShow=false
if SCN.swapping then return end
if SCN.gamepadDown then SCN.gamepadDown(i)
elseif SCN.keyDown then SCN.keyDown(keyMirror[i]or i)
elseif SCN.keyDown then SCN.keyDown(dPadToKey[i]or i)
elseif i=="back"then SCN.back()
else WIDGET.gamepadPressed(keyMirror[i]or i)
else WIDGET.gamepadPressed(dPadToKey[i]or i)
end
end
function love.gamepadreleased(_,i)
if SCN.swapping then return end
if SCN.gamepadUp then SCN.gamepadUp(i)end
end
--[[
function love.joystickpressed(JS,k)
mouseShow=false
if SCN.swapping then return end
if SCN.gamepadDown then SCN.gamepadDown(i)
elseif SCN.keyDown then SCN.keyDown(keyMirror[i]or i)
elseif i=="back"then SCN.back()
else WIDGET.gamepadPressed(i)
end
end
function love.joystickreleased(JS,k)
if SCN.swapping then return end
if SCN.gamepadUp then SCN.gamepadUp(i)
end
end
function love.joystickaxis(JS,axis,val)
end
function love.joystickhat(JS,hat,dir)
end
function love.sendData(data)end
function love.receiveData(id,data)end
]]
function love.filedropped(file)
if SCN.fileDropped then SCN.fileDropped(file)end
end
function love.directorydropped(dir)
if SCN.directoryDropped then SCN.directoryDropped(dir)end
end
local lastGCtime=0
local autoGCcount=0
function love.lowmemory()
if love.timer.getTime()-lastGCtime>6.26 then
collectgarbage()
lastGCtime=love.timer.getTime()
collectgarbage()
if autoGCcount<3 then
autoGCcount=autoGCcount+1
MES.new('check',"[auto GC] low MEM 设备内存过低")
end
end
@@ -376,7 +417,7 @@ end
function love.errorhandler(msg)
if type(msg)~='string'then
msg="Unknown error"
elseif msg:find("Invaild UTF-8")and text then
elseif msg:find("Invalid UTF-8")and text then
msg=text.tryAnotherBuild
end
@@ -400,20 +441,20 @@ function love.errorhandler(msg)
love.audio.stop()
gc.reset()
if LOADED and #ERRDATA<3 then
if LOADED and #errData<3 then
BG.set('none')
local scn=SCN and SCN.cur or"NULL"
table.insert(ERRDATA,{mes=err,scene=scn})
table.insert(errData,{mes=err,scene=scn})
--Write messages to log file
love.filesystem.append('conf/error.log',
os.date("%Y/%m/%d %A %H:%M:%S\n")..
#ERRDATA.." crash(es) "..love.system.getOS().."-"..VERSION.string.." scene: "..scn.."\n"..
#errData.." crash(es) "..love.system.getOS().."-"..VERSION.string.." scene: "..scn.."\n"..
table.concat(err,"\n",1,c-2).."\n\n"
)
--Get screencapture
gc.captureScreenshot(function(_)ERRDATA[#ERRDATA].shot=gc.newImage(_)end)
gc.captureScreenshot(function(_)errData[#errData].shot=gc.newImage(_)end)
gc.present()
--Create a new mainLoop thread to keep game alive
@@ -536,7 +577,7 @@ function love.run()
--Scene Launch
while #SCN.stack>0 do SCN.pop()end
SCN.push('quit','slowFade')
SCN.init(#ERRDATA==0 and'load'or'error')
SCN.init(#errData==0 and'load'or'error')
return function()
local _
@@ -620,9 +661,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)
@@ -701,6 +741,9 @@ end
local Z={}
Z.js=jsState
Z.errData=errData
function Z.setIfPowerInfo(func)showPowerInfo=func end
--[Warning] Color and line width is uncertain value, set it in the function.

23
Zframework/mathExtend.lua Normal file
View File

@@ -0,0 +1,23 @@
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
return MATH

View File

@@ -1,4 +1,5 @@
local type,rem=type,table.remove
local int,rnd=math.floor,math.random
local sfxList={}
local packSetting={}
@@ -6,7 +7,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 +16,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)
@@ -55,14 +57,14 @@ 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 +72,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
@@ -116,32 +134,13 @@ function SFX.play(name,vol,pos)
S:setPosition(0,0,0)
end
end
S:setVolume(((vol or 1)*volume)^1.626)
S:setVolume(vol^1.626)
S:setPitch(pitch and 1.0594630943592953^pitch or 1)
S:play()
end
function SFX.fplay(name,vol,pos)
local S=Sources[name]--Source list
if not S then return end
local n=1
while S[n]:isPlaying()do
n=n+1
if not S[n]then
S[n]=S[1]:clone()
S[n]:seek(0)
break
end
end
S=S[n]--AU_SRC
if S:getChannelCount()==1 then
if pos then
pos=pos*stereo
S:setPosition(pos,1-pos^2,0)
else
S:setPosition(0,0,0)
end
end
S:setVolume(vol^1.626)
S:play()
SFX.fplay=_play--Play sounds without apply module's volume setting
function SFX.play(name,vol,pos,pitch)
_play(name,(vol or 1)*volume,pos,pitch)
end
function SFX.reset()
for _,L in next,Sources do

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

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={

View File

@@ -23,7 +23,7 @@ function TASK.update(dt)
end
function TASK.new(code,...)
local thread=coroutine.create(code)
resume(thread,...)
assert(resume(thread,...))
if status(thread)~='dead'then
tasks[#tasks+1]={
thread=thread,

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

@@ -435,7 +435,7 @@ end
function switch:press()
self.code()
if self.sound then
SFX.play('move')
SFX.play('touch')
end
end
function WIDGET.newSwitch(D)--name,x,y[,lim][,fText][,color][,font=30][,sound=true][,disp],code[,hideF][,hide]
@@ -1431,7 +1431,7 @@ function WIDGET.textinput(texts)
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)
end

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.

142
main.lua
View File

@@ -24,6 +24,7 @@ VERSION=require"version"
TIME=love.timer.getTime
YIELD=coroutine.yield
SYSTEM=love.system.getOS()
FNSF=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()
@@ -51,7 +52,9 @@ local _LOADTIME_=TIME()
Z=require'Zframework'
FONT.load('parts/fonts/proportional.ttf')
SCR.setSize(1280,720)--Initialize Screen size
BGM.setMaxSources(5)
BGM.setChange(function(name)MES.new('music',text.nowPlaying..name,5)end)
VOC.setDiversion(1)
table.insert(_LOADTIMELIST_,("Load Zframework: %.3fs"):format(TIME()-_LOADTIME_))
@@ -90,7 +93,7 @@ for _,v in next,fs.getDirectoryItems('parts/shaders')do
end
end
FREEROW= require'parts.freeRow'
LINE= require'parts.line'
DATA= require'parts.data'
TEXTURE= require'parts.texture'
@@ -104,6 +107,12 @@ PLY= require'parts.player'
NETPLY= require'parts.netPlayer'
MODES= require'parts.modes'
setmetatable(TEXTURE,{__index=function(self,k)
MES.new('warn',"No texture called: "..k)
self[k]=love.graphics.newCanvas(1,1)
return self[k]
end})
table.insert(_LOADTIMELIST_,("Load Parts: %.3fs"):format(TIME()-_LOADTIME_))
--Init Zframework
@@ -143,8 +152,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,7 +162,7 @@ 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,
})
do--Z.setOnFocus
local function task_autoSoundOff()
@@ -196,15 +205,15 @@ end
Z.setOnQuit(destroyPlayers)
--Load settings and statistics
TABLE.cover (FILE.load('conf/user')or{},USER)
TABLE.cover (FILE.load('conf/unlock')or{},RANKS)
TABLE.update(FILE.load('conf/settings')or{},SETTING)
TABLE.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')or{},USER)
TABLE.cover (loadFile('conf/unlock')or{},RANKS)
TABLE.update(loadFile('conf/settings')or{},SETTING)
TABLE.coverR(loadFile('conf/data')or{},STAT)
TABLE.cover (loadFile('conf/key')or{},KEY_MAP)
TABLE.cover (loadFile('conf/virtualkey')or{},VK_ORG)
--Initialize fields, sequence, missions, gameEnv for cutsom game
local fieldData=FILE.load('conf/customBoards','string')
local fieldData=loadFile('conf/customBoards','-string')
if fieldData then
fieldData=STRING.split(fieldData,"!")
for i=1,#fieldData do
@@ -213,16 +222,16 @@ if fieldData then
else
FIELD[1]=DATA.newBoard()
end
local sequenceData=FILE.load('conf/customSequence','string')
local sequenceData=loadFile('conf/customSequence','-string')
if sequenceData then
DATA.pasteSequence(sequenceData)
end
local missionData=FILE.load('conf/customMissions','string')
local missionData=loadFile('conf/customMissions','-string')
if missionData then
DATA.pasteMission(missionData)
end
local customData=FILE.load('conf/customEnv')
if customData and customData.version==VERSION.code then
local customData=loadFile('conf/customEnv')
if customData and customData['version']==VERSION.code then
TABLE.complete(customData,CUSTOMENV)
end
TABLE.complete(require"parts.customEnv0",CUSTOMENV)
@@ -325,6 +334,7 @@ LANG.init('zh',
{
zh=require'parts.language.lang_zh',
zh_full=require'parts.language.lang_zh_full',
zh_trad=require'parts.language.lang_zh_trad',
en=require'parts.language.lang_en',
fr=require'parts.language.lang_fr',
es=require'parts.language.lang_es',
@@ -334,7 +344,7 @@ LANG.init('zh',
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
@@ -382,8 +392,11 @@ 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)}
TABLE.complete(require('parts.modes.'..M.name),M)
MODES[M.name]=M
local modeData=require('parts.modes.'..M.name)
if modeData.env then
TABLE.complete(modeData,M)
MODES[M.name]=M
end
end
end
@@ -440,6 +453,14 @@ do
fs.remove('record/round_l.rec')
fs.remove('record/round_u.rec')
end
if RANKS.stack_e then
RANKS.stack_e=nil
RANKS.stack_h=nil
RANKS.stack_u=nil
fs.remove('record/stack_e.rec')
fs.remove('record/stack_h.rec')
fs.remove('record/stack_u.rec')
end
if RANKS.stack_20l then
RANKS.stack_20l=nil
RANKS.stack_40l=nil
@@ -448,17 +469,41 @@ 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
@@ -494,26 +539,11 @@ do
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
if needSave then
saveStats()
saveProgress()
saveSettings()
love.event.quit('restart')
end
end
@@ -576,3 +606,37 @@ table.sort(REPLAY,function(a,b)return a.fileName>b.fileName end)
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
LOG("\27[92m\27[1mAutomatic Test Started\27[0m")
BGM.setVol(0)SFX.setVol(0)
love.keypressed('space')
TEST.yieldUntilNextScene()
for k,mode in next,MODES do
if k~='netBattle'then
LOG("Scanning mode: "..mode.name)
loadGame(mode.name,true)
TEST.yieldUntilNextScene()
SCN.back()
TEST.yieldUntilNextScene()
end
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 Z.errData[1]then break end
end
LOG("\27[91m\27[1mAutomatic Test Failed :(\27[0m\nThe error message is:\n"..table.concat(Z.errData[1].mes,"\n").."\27[91m\nAborting\27[0m")
TEST.yieldN(60)
love.event.quit(1)
end)
end

BIN
media/music/1980s.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

@@ -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'},
@@ -353,8 +353,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
@@ -686,13 +686,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

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

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

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

@@ -12,7 +12,7 @@ local baseBot={
function baseBot.update(bot)
local P=bot.P
local keys=bot.keys
if P.control and P.waiting==-1 then
if P.control and P.waiting==0 then
bot.delay=bot.delay-1
if not keys[1]then
if bot.runningThread then
@@ -50,9 +50,6 @@ local botMeta={__index=_undefMethod}
local BOT={}
local AISpeed={60,50,40,30,20,14,10,6,4,3}
-- For CC bot:
-- TODO you still need to switch20G() at the right time.
-- since it's not cc-specific I'm not dealing with it for now
--[[
arg={
next: number of nexts

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

View File

@@ -11,8 +11,8 @@ return{
task=function(P)
local F=P.field
for i=1,24 do
F[i]=FREEROW.get(20)
P.visTime[i]=FREEROW.get(20)
F[i]=LINE.new(20)
P.visTime[i]=LINE.new(20)
for x=4,7 do F[i][x]=0 end
end
if P.holeRND:random()<.6 then

View File

@@ -1,10 +1,10 @@
return{
dropPiece=function(P)
hook_drop=function(P)
if P.lastPiece.row>0 then
for _=1,#P.clearedRow do
local h=#P.field
P.field[h+1]=FREEROW.get(20)
P.visTime[h+1]=FREEROW.get(20)
P.field[h+1]=LINE.new(20)
P.visTime[h+1]=LINE.new(20)
for i=4,7 do P.field[h+1][i]=0 end
end
if P.combo>P.modeData.maxCombo then

View File

@@ -1,12 +1,12 @@
return{
dropPiece=function(P)
hook_drop=function(P)
if P.lastPiece.row==0 then
P:lose()
else
for _=1,P.lastPiece.row do
local h=#P.field
P.field[h+1]=FREEROW.get(20)
P.visTime[h+1]=FREEROW.get(20)
P.field[h+1]=LINE.new(20)
P.visTime[h+1]=LINE.new(20)
for i=4,7 do P.field[h+1][i]=0 end
end
if P.combo>P.modeData.maxCombo then

View File

@@ -6,7 +6,7 @@ return{
mText(TEXTOBJ.atk,63,243)
mText(TEXTOBJ.eff,63,363)
end,
dropPiece=function(P)
hook_drop=function(P)
if P.stat.atk>=100 then
P:win('finish')
end

View File

@@ -1,13 +1,11 @@
return{
dropPiece=function(P)
hook_drop=function(P)
if P.garbageBeneath==0 then
local D=P.modeData
D.finished=D.finished+1
if FIELD[D.finished+1]then
P.waiting=26
for i=#P.field,1,-1 do
FREEROW.discard(P.field[i])
FREEROW.discard(P.visTime[i])
P.field[i],P.visTime[i]=nil
end
setField(P,D.finished+1)

View File

@@ -6,7 +6,7 @@ return{
mStr(r,63,265)
PLY.draw.drawTargetLine(P,r)
end,
dropPiece=function(P)
hook_drop=function(P)
if P.stat.row>=10 then
P:win('finish')
end

View File

@@ -6,7 +6,7 @@ return{
mStr(r,63,265)
PLY.draw.drawTargetLine(P,r)
end,
dropPiece=function(P)
hook_drop=function(P)
if P.stat.row>=100 then
P:win('finish')
end

View File

@@ -6,7 +6,7 @@ return{
mStr(r,63,265)
PLY.draw.drawTargetLine(P,r)
end,
dropPiece=function(P)
hook_drop=function(P)
if P.stat.row>=1000 then
P:win('finish')
end

View File

@@ -6,7 +6,7 @@ return{
mStr(r,63,265)
PLY.draw.drawTargetLine(P,r)
end,
dropPiece=function(P)
hook_drop=function(P)
if P.stat.row>=20 then
P:win('finish')
end

View File

@@ -6,7 +6,7 @@ return{
mStr(r,63,265)
PLY.draw.drawTargetLine(P,r)
end,
dropPiece=function(P)
hook_drop=function(P)
if P.stat.row>=200 then
P:win('finish')
end

View File

@@ -6,7 +6,7 @@ return{
mStr(r,63,265)
PLY.draw.drawTargetLine(P,r)
end,
dropPiece=function(P)
hook_drop=function(P)
if P.stat.row>=40 then
P:win('finish')
end

View File

@@ -6,7 +6,7 @@ return{
mStr(r,63,265)
PLY.draw.drawTargetLine(P,r)
end,
dropPiece=function(P)
hook_drop=function(P)
if P.stat.row>=400 then
P:win('finish')
end

View File

@@ -1,5 +1,5 @@
return{
dropPiece=function(P)
hook_drop=function(P)
if #PLY_ALIVE>1 then
P.control=false
local id1=P.sid

View File

@@ -1,5 +1,5 @@
return{
dropPiece=function(P)
hook_drop=function(P)
if P.stat.piece%7==0 and #PLY_ALIVE>1 then
P.control=false
local id1=P.sid

View File

@@ -1,3 +1,4 @@
local gc_setColor=love.graphics.setColor
return{
das=16,arr=6,
sddas=6,sdarr=6,
@@ -18,12 +19,24 @@ return{
mStr(r<10 and 9 or r<30 and r or("%02x"):format(r*10-300),63,210)
mText(TEXTOBJ.speedLV,63,290)
PLY.draw.drawProgress(P.stat.row,P.modeData.target)
if P.modeData.drought>7 then
if P.modeData.drought<=14 then
gc_setColor(1,1,1,P.modeData.drought/7-1)
else
local gb=P.modeData.drought<=21 and 2-P.modeData.drought/14 or .5
gc_setColor(1,gb,gb)
end
setFont(50)
mStr(P.modeData.drought,63,130)
mDraw(MODES.drought_l.icon,63,200,nil,.5)
end
end,
task=function(P)
P.modeData.target=10
end,
dropPiece=function(P)
hook_drop=function(P)
local D=P.modeData
D.drought=P.lastPiece.id==7 and 0 or D.drought+1
if P.stat.row>=D.target then
if D.target==110 then
P.gameEnv.drop,P.gameEnv.lock=5,5

View File

@@ -1,3 +1,4 @@
local gc_setColor=love.graphics.setColor
return{
das=16,arr=6,
sddas=3,sdarr=3,
@@ -18,11 +19,22 @@ return{
mStr(r<11 and 18 or r<22 and r+8 or("%02x"):format(r*10-220),63,210)
mText(TEXTOBJ.speedLV,63,290)
PLY.draw.drawProgress(P.stat.row,P.modeData.target)
if P.modeData.drought>7 then
if P.modeData.drought<=14 then
gc_setColor(1,1,1,P.modeData.drought/7-1)
else
local gb=P.modeData.drought<=21 and 2-P.modeData.drought/14 or .5
gc_setColor(1,gb,gb)
end
setFont(50)
mStr(P.modeData.drought,63,130)
mDraw(MODES.drought_l.icon,63,200,nil,.5)
end
end,
task=function(P)
P.modeData.target=10
end,
dropPiece=function(P)
hook_drop=function(P)
local D=P.modeData
if P.stat.row>=D.target then
if D.target==110 then

View File

@@ -1,3 +1,4 @@
local gc_setColor=love.graphics.setColor
return{
das=16,arr=6,
sddas=1,sdarr=1,
@@ -18,11 +19,22 @@ return{
mStr(r==1 and 29 or("%02x"):format(r*10-20),63,210)
mText(TEXTOBJ.speedLV,63,290)
PLY.draw.drawProgress(P.stat.row,P.modeData.target)
if P.modeData.drought>7 then
if P.modeData.drought<=14 then
gc_setColor(1,1,1,P.modeData.drought/7-1)
else
local gb=P.modeData.drought<=21 and 2-P.modeData.drought/14 or .5
gc_setColor(1,gb,gb)
end
setFont(50)
mStr(P.modeData.drought,63,130)
mDraw(MODES.drought_l.icon,63,200,nil,.5)
end
end,
task=function(P)
P.modeData.target=10
end,
dropPiece=function(P)
hook_drop=function(P)
local D=P.modeData
if P.stat.row>=D.target then
if D.target==100 then

View File

@@ -0,0 +1,36 @@
local function task_newBoard(P,init)
local targetLine
local F,L={},{1}
--TODO
P:pushNextList(L)
P.control=false
if not init then for _=1,26 do YIELD()end end
P.control=true
P.gameEnv.heightLimit=targetLine or #F
P:pushLineList(F)
end
local function _check(P)
P.gameEnv.heightLimit=P.gameEnv.heightLimit-P.lastPiece.row
if P.gameEnv.heightLimit==0 then
P.modeData.stage=P.modeData.stage+1
if P.modeData.stage>=100 then
P:win('finish')
else
P:newTask(task_newBoard)
end
end
end
return{
sequence='none',
RS="TRS",
pushSpeed=5,
mesDisp=function(P)
setFont(60)
mStr(P.modeData.stage,63,280)
mText(TEXTOBJ.wave,63,350)
end,
hook_drop=_check,
task=function(P)task_newBoard(P,true)P.fieldBeneath=0 end,--Just run one time at first to start first level
}

View File

@@ -40,6 +40,7 @@ return{
P:_showText(text.maxspeed,0,-140,100,'appear',.6)
P.dropDelay,P.gameEnv.drop=2,2
end
P:shakeField(3)
end
end
end

View File

@@ -40,6 +40,7 @@ return{
P.dropDelay,P.gameEnv.drop=5,5
P:_showText(text.maxspeed,0,-140,100,'appear',.6)
end
P:shakeField(3)
end
end
end

View File

@@ -3,7 +3,7 @@ return{
setFont(55)
mStr(100-P.stat.dig,63,265)
end,
dropPiece=function(P)
hook_drop=function(P)
for _=1,math.min(10,100-P.stat.dig)-P.garbageBeneath do
P:garbageRise(21,1,P:getHolePos())
end

View File

@@ -3,7 +3,7 @@ return{
setFont(55)
mStr(10-P.stat.dig,63,265)
end,
dropPiece=function(P)
hook_drop=function(P)
if P.stat.dig==10 then
P:win('finish')
end

View File

@@ -3,7 +3,7 @@ return{
setFont(55)
mStr(400-P.stat.dig,63,265)
end,
dropPiece=function(P)
hook_drop=function(P)
for _=1,math.min(10,400-P.stat.dig)-P.garbageBeneath do
P:garbageRise(21,1,P:getHolePos())
end

View File

@@ -3,7 +3,7 @@ return{
setFont(55)
mStr(40-P.stat.dig,63,265)
end,
dropPiece=function(P)
hook_drop=function(P)
for _=1,math.min(10,40-P.stat.dig)-P.garbageBeneath do
P:garbageRise(21,1,P:getHolePos())
end

View File

@@ -11,7 +11,7 @@ return{
task=function(P)
P.modeData.target=10
end,
dropPiece=function(P)
hook_drop=function(P)
local flag
local l=P.lastPiece
if P.combo>1 then flag=true;P:showText("2x",0,-220,40,'flicker',.3)end

View File

@@ -10,7 +10,7 @@ return
task=function(P)
P.modeData.target=50
end,
dropPiece=function(P)
hook_drop=function(P)
if P.stat.row>=P.modeData.target then
if P.modeData.target==50 then
P.gameEnv.drop=.25

View File

@@ -0,0 +1,56 @@
local dropSpeed={
50,42,35,30,25,20,16,13,11,10,
9,8,7,6,5,5,4,4,3,3,
3,2,2,2,2,1,1,1,1,1,
.5,.5,.5,.5,.25,.25,.25,.125,.125,--Total 39 numbers, switch to 20G when reach 400 lines
}
local lockDelay={
57,54,51,48,46,44,42,40,38,36,
34,32,30,28,26,25,24,23,22,21,
20,20,19,19,18,18,17,17,16,16,
15,15,14,14,13,13,13,12,12,12,
11,11,11,11,11,10,10,10,10,10,
9,9,9,9,9,9,8,8,8,8,
8,8,8,8,7,7,7,7,7,7,
7,7,6,6,6,6,6,6,6,6,
5,5,5,5,5,5,5,5,5,5,
4,4,4,4,4,4,4,4,4,4,
3,3,3,3,3,3,3,3,3,3,
2,2,2,2,2,2,2,2,2,2,
1,1,1,1,1,1,1,1,1,--Finish at 1700
}
return
{
drop=60,lock=60,
wait=8,fall=20,
mesDisp=function(P)
PLY.draw.drawProgress(P.stat.row,P.modeData.target)
end,
task=function(P)
P.modeData.target=10
end,
hook_drop=function(P)
if P.stat.row>=P.modeData.target then
if P.modeData.target%300==0 then
P.gameEnv.wait=P.gameEnv.wait-1
end
if P.modeData.target%100==0 then
P.gameEnv.fall=P.gameEnv.fall-1
end
if P.modeData.target<400 then
P.gameEnv.drop=dropSpeed[P.modeData.target/10]
elseif P.modeData.target==400 then
P:set20G(true)
elseif P.modeData.target<1700 then
P.gameEnv.lock=lockDelay[(P.modeData.target-400)/10]
else
P.stat.row=1700
P:win('finish')
return
end
P.modeData.target=P.modeData.target+10
SFX.play('reach')
end
end
}

View File

@@ -12,7 +12,7 @@ return
task=function(P)
P.modeData.target=10
end,
dropPiece=function(P)
hook_drop=function(P)
if P.stat.row>=P.modeData.target then
if P.modeData.target==200 then
P:win('finish')

View File

@@ -30,7 +30,7 @@ return{
mStr(P.stat.row,63,230)
mStr(P.stat.clears[4],63,340)
end,
dropPiece=function(P)
hook_drop=function(P)
if P.modeData.rankPoint<140-passPoint then--If Less then X
local R=#P.clearedRow
if R>0 then

View File

@@ -8,7 +8,7 @@ return{
mesDisp=function(P)
PLY.draw.drawProgress(P.modeData.pt,P.modeData.target)
end,
dropPiece=function(P)
hook_drop=function(P)
local D=P.modeData
local c=#P.clearedRow

View File

@@ -12,7 +12,7 @@ return{
mesDisp=function(P)
PLY.draw.drawProgress(P.modeData.pt,P.modeData.target)
end,
dropPiece=function(P)
hook_drop=function(P)
local D=P.modeData
local c=#P.clearedRow

View File

@@ -14,7 +14,7 @@ return
task=function(P)
P.modeData.target=10
end,
dropPiece=function(P)
hook_drop=function(P)
if P.stat.row>=P.modeData.target then
if P.modeData.target==200 then
P:win('finish')

View File

@@ -12,7 +12,7 @@ return{
mesDisp=function(P)
PLY.draw.drawProgress(P.modeData.pt,P.modeData.target)
end,
dropPiece=function(P)
hook_drop=function(P)
local D=P.modeData
local c=#P.clearedRow

View File

@@ -13,7 +13,7 @@ return
mesDisp=function(P)
PLY.draw.drawProgress(P.modeData.pt,P.modeData.target)
end,
dropPiece=function(P)
hook_drop=function(P)
local p=P.modeData.pt+P.lastPiece.row
if p>=P.modeData.target then
local ENV=P.gameEnv
@@ -55,8 +55,8 @@ return
P.field[i][P.holeRND:random(10)]=0
end
else
P.field[i]=FREEROW.get(0)
P.visTime[i]=FREEROW.get(30)
P.field[i]=LINE.new(0)
P.visTime[i]=LINE.new(30)
for j=1,10 do
if P.holeRND:random()>.9 then
P.field[i][j]=P.holeRND:random(16)
@@ -89,6 +89,7 @@ return
ENV.bone=true
P.modeData.target=62
SFX.play('reach')
else
p=41
end
@@ -112,6 +113,7 @@ return
ENV.fall=4
P.modeData.target=162
SFX.play('reach')
elseif T==162 then--Stage 7: speed up+++
P:stageComplete(7)
P.life=P.life+1
@@ -146,6 +148,7 @@ return
P.modeData.target=260
p=260
SFX.play('blip_2')
SFX.play('reach')
else
p=260
end

View File

@@ -5,7 +5,7 @@ return{
mStr(P.stat.pc,63,340)
mText(TEXTOBJ.pc,63,410)
end,
dropPiece=function(P)
hook_drop=function(P)
if P.lastPiece.pc and P.stat.row%4==0 then
P.gameEnv.heightLimit=4
if P.stat.pc%5==0 then

View File

@@ -1,51 +1,54 @@
local pc_drop={50,45,40,35,30,26,22,18,15,12}
local pc_lock={55,50,46,42,39,36,33,31,29,27}
local pc_lock={55,50,46,42,40,38,36,34,32,30}
local pc_fall={18,16,14,12,10,9,8,7,6,5}
local PCbase=require"parts.modes.PCbase"
local PClist=require"parts.modes.PClist"
local function task_PC(P)
if P.frameRun>180 then
P.control=false
for _=1,26 do YIELD()end
P.control=true
end
local base=PCbase[P.modeData.type]
P:pushLineList(base[P.holeRND:random(#base)],P.modeData.symmetry)
local difficulty=P.stat.pc<10 and 4 or 5
local L=PClist[difficulty][P.holeRND:random(#PClist[difficulty])]
local symmetry=P.holeRND:random()>.5
P:pushNextList(L,symmetry)
P.control=false
if P.frameRun>180 then for _=1,26 do YIELD()end end
P.control=true
local base=PCbase[difficulty]
P:pushLineList(base[P.holeRND:random(#base)],symmetry)
end
local function check(P)
local f=P.field
if #f>0 then
if #f+P.stat.row%4>4 then
local function _check(P)
if #P.field>0 then
if #P.field+P.stat.row%4>4 then
P:lose()
end
else
local type=P.stat.pc<10 and 4 or 5
local L=PClist[type][P.holeRND:random(#PClist[type])]
local symmetry=P.holeRND:random()>.5
P.modeData.type=type
P.modeData.symmetry=symmetry
P:pushNextList(L,symmetry)
P.modeData.counter=P.stat.piece==0 and 20 or 0
P:newTask(task_PC)
if P.stat.pc>=100 then
P:win('finish')
else
P:newTask(task_PC)
if P.frameRun<180 then P.fieldBeneath=0 end
local s=P.stat.pc*.25
if math.floor(s)==s and s>0 then
P.gameEnv.drop=pc_drop[s]or 10
P.gameEnv.lock=pc_lock[s]or 25
P.gameEnv.fall=pc_fall[s]or 4
if s==10 then
P:_showText(text.maxspeed,0,-140,100,'appear',.6)
if P.stat.pc%4==0 and P.stat.pc>0 and P.stat.pc<=40 then
local s=P.stat.pc/4
P.gameEnv.drop=pc_drop[s]or 10
P.gameEnv.lock=pc_lock[s]or 25
P.gameEnv.fall=pc_fall[s]or 4
if s==10 then
P:_showText(text.maxspeed,0,-140,100,'appear',.6)
end
end
end
end
end
return{
sequence='none',
RS="SRS",
mesDisp=function(P)
setFont(60)
mStr(P.stat.pc,63,340)
mText(TEXTOBJ.pc,63,410)
mStr(P.stat.pc,63,260)
mText(TEXTOBJ.pc,63,330)
end,
dropPiece=check,
task=check,
hook_drop=_check,
task=_check,--Just run one time at first to start first level
}

View File

@@ -8,35 +8,40 @@ local PCtype={
1,2,3,
}
local function task_PC(P)
local difficulty=PCtype[P.stat.pc+1]or 3
local L=PClist[difficulty][P.holeRND:random(#PClist[difficulty])]
local symmetry=P.holeRND:random()>.5
P:pushNextList(L,symmetry)
P.control=false
for _=1,26 do YIELD()end
if P.frameRun>180 then for _=1,26 do YIELD()end end
P.control=true
local base=PCbase[P.modeData.type]
P:pushLineList(base[P.holeRND:random(#base)],P.modeData.symmetry)
local base=PCbase[difficulty]
P:pushLineList(base[P.holeRND:random(#base)],symmetry)
end
local function check(P)
local r=P.field
if #r>0 then
if #r+P.stat.row%4>4 then
local function _check(P)
if #P.field>0 then
if #P.field+P.stat.row%4>4 then
P:lose()
end
else
local type=PCtype[P.stat.pc+1]or 3
local L=PClist[type][P.holeRND:random(#PClist[type])]
local symmetry=P.holeRND:random()>.5
P.modeData.type=type
P.modeData.symmetry=symmetry
P:pushNextList(L,symmetry)
P.modeData.counter=P.stat.piece==0 and 20 or 0
P:newTask(task_PC)
if P.stat.pc>=60 then
P:win('finish')
else
P:newTask(task_PC)
if P.frameRun<180 then P.fieldBeneath=0 end
end
end
end
return{
sequence='none',
RS="SRS",
mesDisp=function(P)
setFont(60)
mStr(P.stat.pc,63,340)
mText(TEXTOBJ.pc,63,410)
mStr(P.stat.pc,63,260)
mText(TEXTOBJ.pc,63,330)
end,
dropPiece=check,
task=check,
hook_drop=_check,
task=_check,--Just run one time at first to start first level
}

View File

@@ -1,53 +0,0 @@
local gc=love.graphics
local dropSpeed={[0]=40,33,27,20,16,12,11,10,9,8,7,6,5,4,3,3,2,2,1,1}
return{
drop=40,
lock=1e99,
wait=20,
fall=90,
mesDisp=function(P)
PLY.draw.drawProgress(P.stat.row,P.modeData.target)
setFont(30)
mStr(P.modeData.bpm,63,178)
gc.setLineWidth(4)
gc.circle('line',63,200,30)
local beat=P.modeData.counter/P.modeData.beatFrame
gc.setColor(1,1,1,1-beat)
gc.setLineWidth(3)
gc.circle('line',63,200,30+45*beat)
end,
dropPiece=function(P)
if P.stat.row>=P.modeData.target then
if P.modeData.target==200 then
P:win('finish')
else
P.modeData.bpm=40+2*P.modeData.target/10
P.modeData.beatFrame=math.floor(3600/P.modeData.bpm)
P.gameEnv.fall=P.modeData.beatFrame
P.gameEnv.wait=math.max(P.gameEnv.wait-2,0)
P.gameEnv.drop=dropSpeed[P.modeData.target/10]
P.modeData.target=P.modeData.target+10
SFX.play('reach')
end
end
end,
task=function(P)
P.modeData.target=10
P.modeData.bpm=40
P.modeData.beatFrame=90
P.modeData.counter=90
while true do
YIELD()
P.modeData.counter=P.modeData.counter-1
if P.modeData.counter==0 then
P.modeData.counter=P.modeData.beatFrame
SFX.play('click',.3)
P:act_hardDrop()
end
end
end,
}

View File

@@ -1,53 +0,0 @@
local gc=love.graphics
local dropSpeed={[0]=30,26,23,20,17,14,12,10,8,6,5,4,3,2,1,1,.5,.5,.25,.25}
return{
drop=30,
lock=1e99,
wait=10,
fall=60,
mesDisp=function(P)
PLY.draw.drawProgress(P.stat.row,P.modeData.target)
setFont(30)
mStr(P.modeData.bpm,63,178)
gc.setLineWidth(4)
gc.circle('line',63,200,30)
local beat=P.modeData.counter/P.modeData.beatFrame
gc.setColor(1,1,1,1-beat)
gc.setLineWidth(3)
gc.circle('line',63,200,30+45*beat)
end,
dropPiece=function(P)
if P.stat.row>=P.modeData.target then
if P.modeData.target==200 then
P:win('finish')
else
P.modeData.bpm=60+3*P.modeData.target/10
P.modeData.beatFrame=math.floor(3600/P.modeData.bpm)
P.gameEnv.fall=P.modeData.beatFrame
P.gameEnv.wait=math.max(P.gameEnv.wait-1,0)
P.gameEnv.drop=dropSpeed[P.modeData.target/10]
P.modeData.target=P.modeData.target+10
SFX.play('reach')
end
end
end,
task=function(P)
P.modeData.target=10
P.modeData.bpm=60
P.modeData.beatFrame=60
P.modeData.counter=60
while true do
YIELD()
P.modeData.counter=P.modeData.counter-1
if P.modeData.counter==0 then
P.modeData.counter=P.modeData.beatFrame
SFX.play('click',.3)
P:act_hardDrop()
end
end
end,
}

View File

@@ -1,58 +0,0 @@
local gc=love.graphics
return{
drop=.5,
lock=1e99,
wait=5,
fall=30,
mesDisp=function(P)
PLY.draw.drawProgress(P.stat.row,P.modeData.target)
setFont(30)
mStr(P.modeData.bpm,63,178)
gc.setLineWidth(4)
gc.circle('line',63,200,30)
local beat=P.modeData.counter/P.modeData.beatFrame
gc.setColor(1,1,1,1-beat)
gc.setLineWidth(3)
gc.circle('line',63,200,30+45*beat)
end,
dropPiece=function(P)
if P.stat.row>=P.modeData.target then
if P.modeData.target==200 then
P:win('finish')
else
P.modeData.bpm=120+2*P.modeData.target/10
P.modeData.beatFrame=math.floor(3600/P.modeData.bpm)
P.gameEnv.fall=P.modeData.beatFrame
P.gameEnv.wait=math.max(P.gameEnv.wait-1,0)
if P.modeData.target==50 then
P.gameEnv.das=5
P.gameEnv.drop=.25
elseif P.modeData.target==100 then
P.gameEnv.das=4
P:set20G(true)
end
P.modeData.target=P.modeData.target+10
SFX.play('reach')
end
end
end,
task=function(P)
P.modeData.target=10
P.modeData.bpm=120
P.modeData.beatFrame=30
P.modeData.counter=30
while true do
YIELD()
P.modeData.counter=P.modeData.counter-1
if P.modeData.counter==0 then
P.modeData.counter=P.modeData.beatFrame
SFX.play('click',.3)
P:act_hardDrop()
end
end
end,
}

View File

@@ -1,5 +1,24 @@
local gc=love.graphics
local gc_draw,gc_print,gc_setColor=gc.draw,gc.print,gc.setColor
local setFont=setFont
local PLAYERS,PLY_ALIVE=PLAYERS,PLY_ALIVE
return{
mesDisp=function(P)
PLY.draw.drawRoyaleInfo(P)
setFont(35)
mStr(#PLY_ALIVE.."/"..#PLAYERS,63,175)
mStr(P.modeData.ko,80,215)
gc_draw(TEXTOBJ.ko,60-TEXTOBJ.ko:getWidth(),222)
setFont(20)
gc_setColor(1,.5,0,.6)
gc_print(P.badge,103,227)
gc_setColor(.97,.97,.97)
setFont(25)
mStr(text.powerUp[P.strength],63,290)
gc_setColor(1,1,1)
for i=1,P.strength do
gc_draw(IMG.badgeIcon,16*i+6,260)
end
end,
}

View File

@@ -0,0 +1,20 @@
return{
mesDisp=function(P)
setFont(45)
mStr(("%.1f"):format(P.stat.atk),63,270)
mText(TEXTOBJ.atk,63,323)
mStr(("%.2f"):format(P.stat.atk/P.stat.row),63,370)
mText(TEXTOBJ.eff,63,423)
setFont(55)
local r=40-P.stat.row
if r<0 then r=0 end
mStr(r,63,170)
PLY.draw.drawTargetLine(P,r)
end,
hook_drop=function(P)
if P.stat.row>=40 then
P:win('finish')
end
end
}

View File

@@ -36,7 +36,7 @@ return{
end
end
end,
dropPiece=function(P)
hook_drop=function(P)
if P.stat.row>=40 then
P:win('finish')
end

View File

@@ -14,7 +14,7 @@ return{
mStr(r,63,265)
PLY.draw.drawTargetLine(P,r)
end,
dropPiece=function(P)
hook_drop=function(P)
local F=P.field
for y=1,#F do
local l=F[y]

View File

@@ -0,0 +1,22 @@
return{
fieldH=20,
fillClear=false,
mesDisp=function(P)
setFont(60)
mStr(P.stat.row,63,280)
mText(TEXTOBJ.line,63,350)
PLY.draw.drawMarkLine(P,20,.3,1,1,TIME()%.42<.21 and .95 or .6)
end,
hook_die=function(P)
local cc=P:clearFilledLines(P.garbageBeneath+1,#P.field-P.garbageBeneath)
if cc>0 then
local h=20-cc-P.garbageBeneath
if h>0 then
P:garbageRise(21,h,2e10-1)
if P.garbageBeneath>=20 then
P:lose()
end
end
end
end,
}

View File

@@ -0,0 +1,22 @@
return{
fieldH=21,
fillClear=false,
mesDisp=function(P)
setFont(60)
mStr(P.stat.row,63,280)
mText(TEXTOBJ.line,63,350)
PLY.draw.drawMarkLine(P,17,.3,1,1,TIME()%.42<.21 and .95 or .6)
end,
hook_die=function(P)
local cc=P:clearFilledLines(P.garbageBeneath+1,#P.field-P.garbageBeneath)
if cc>0 then
local h=20-cc-P.garbageBeneath-3
if h>0 then
P:garbageRise(21,h,2e10-1)
if P.garbageBeneath>=20 then
P:lose()
end
end
end
end,
}

View File

@@ -0,0 +1,30 @@
local waitSpeed={60,59,58,57,56,55,54,52,50,48,46,44,42,40,38,36,34,32,30}
return
{
das=5,arr=1,
drop=0,lock=7,
wait=60,fall=0,
freshLimit=12,
mesDisp=function(P)
PLY.draw.drawProgress(P.stat.row,P.modeData.target)
PLY.draw.drawTargetLine(P,200-P.stat.row)
end,
task=function(P)
P.modeData.target=10
end,
hook_drop=function(P)
if P.stat.row>=P.modeData.target then
if P.modeData.target==200 then
P:win('finish')
else
if P.modeData.target==100 then
P.modeData.lock=6
end
P.gameEnv.wait=waitSpeed[P.modeData.target/10]
P.modeData.target=P.modeData.target+10
SFX.play('reach')
end
end
end
}

View File

@@ -0,0 +1,30 @@
local waitSpeed={30,29,28,27,26,25,24,23,22,21,20,19,18,18,17,17,16,16,15}
return
{
das=4,arr=1,
drop=0,lock=6,
wait=30,fall=0,
freshLimit=12,
mesDisp=function(P)
PLY.draw.drawProgress(P.stat.row,P.modeData.target)
PLY.draw.drawTargetLine(P,200-P.stat.row)
end,
task=function(P)
P.modeData.target=10
end,
hook_drop=function(P)
if P.stat.row>=P.modeData.target then
if P.modeData.target==200 then
P:win('finish')
else
if P.modeData.target==100 then
P.modeData.lock=5
end
P.gameEnv.wait=waitSpeed[P.modeData.target/10]
P.modeData.target=P.modeData.target+10
SFX.play('reach')
end
end
end
}

View File

@@ -0,0 +1,30 @@
local waitSpeed={15,15,14,14,13,13,12,12,11,11,10,10,9,9,8,8,7,7,7}
return
{
das=3,arr=1,
drop=0,lock=5,
wait=15,fall=0,
freshLimit=12,
mesDisp=function(P)
PLY.draw.drawProgress(P.stat.row,P.modeData.target)
PLY.draw.drawTargetLine(P,200-P.stat.row)
end,
task=function(P)
P.modeData.target=10
end,
hook_drop=function(P)
if P.stat.row>=P.modeData.target then
if P.modeData.target==200 then
P:win('finish')
else
if P.modeData.target==100 then
P.modeData.lock=4
end
P.gameEnv.wait=waitSpeed[P.modeData.target/10]
P.modeData.target=P.modeData.target+10
SFX.play('reach')
end
end
end
}

View File

@@ -21,6 +21,7 @@ return{
if D.wave==60 then
P:_showText(text.maxspeed,0,-140,100,'appear',.6)
end
P:shakeField(3)
D.timer=0
D.wave=D.wave+1
end

View File

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

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