Compare commits

...

34 Commits

Author SHA1 Message Date
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
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
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
42 changed files with 613 additions and 549 deletions

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

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

View File

@@ -32,9 +32,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
@@ -53,9 +54,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 +72,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
@@ -94,9 +97,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 }}
@@ -120,9 +124,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 }}
@@ -137,6 +142,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 }}'

View File

@@ -5,10 +5,10 @@ elseif arg[1]=="-code"then
local str=require"version".code
print(str)
elseif arg[1]=="-name"then
local str=require"version".string:gsub("@DEV","")
local str=require"version".string
print(str)
elseif arg[1]=="-release"then
local str=require"version".string:gsub("V","",1):gsub("@DEV","")
local str=require"version".string:gsub("V","",1)
print(str)
elseif arg[1]=="-updateTitle"then
local note=require"parts.updateLog"

View File

@@ -35,9 +35,7 @@ jobs:
needs: get-info
steps:
- uses: actions/checkout@v2
- name: Update Version
run: |
python .\.github\workflows\updateVersion.py -T Version
- 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
@@ -58,9 +56,7 @@ jobs:
needs: get-info
steps:
- uses: actions/checkout@v2
- name: Update Version
run: |
python .\.github\workflows\updateVersion.py -T Version
- 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
@@ -81,9 +77,7 @@ jobs:
needs: get-info
steps:
- uses: actions/checkout@v2
- name: Update Version
run: |
python3 .github/workflows/updateVersion.py -T Version
- uses: ./.github/actions/update-version
- uses: ./.github/actions/build-linux
with:
file-path: Techmino.a${{ needs.get-info.outputs.release }}.AppImage
@@ -99,9 +93,7 @@ jobs:
needs: get-info
steps:
- uses: actions/checkout@v2
- name: Update Version
run: |
python3 .github/workflows/updateVersion.py -T Version
- uses: ./.github/actions/update-version
- uses: ./.github/actions/build-android
with:
type: Release
@@ -123,9 +115,7 @@ jobs:
needs: get-info
steps:
- uses: actions/checkout@v2
- name: Update Version
run: |
python3 .github/workflows/updateVersion.py -T Version
- uses: ./.github/actions/update-version
- name: remove media
run: |
rm -rf media/music media/effect media/vocal
@@ -150,9 +140,7 @@ jobs:
needs: get-info
steps:
- uses: actions/checkout@v2
- name: Update Version
run: |
python3 .github/workflows/updateVersion.py -T Version
- uses: ./.github/actions/update-version
- uses: ./.github/actions/build-macos
with:
name: ${{ needs.get-info.outputs.name }}
@@ -179,9 +167,7 @@ jobs:
needs: get-info
steps:
- uses: actions/checkout@v2
- uses: ./.github/actions/snapshot-update
with:
commit: ${{ needs.get-info.outputs.commit }}
- uses: ./.github/actions/update-version
- uses: ./.github/actions/build-ios
with:
name: ${{ needs.get-info.outputs.name }}
@@ -196,6 +182,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 }}'
@@ -214,9 +201,7 @@ jobs:
needs: get-info
steps:
- uses: actions/checkout@v2
- name: Update Version
run: |
python3 .github/workflows/updateVersion.py -T Version
- uses: ./.github/actions/update-version
- uses: ./.github/actions/build-love
with:
file-path: Techmino.a${{ needs.get-info.outputs.release }}.love

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
@@ -54,9 +55,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
@@ -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
@@ -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 }}
@@ -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,6 +143,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 }}'

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

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

View File

@@ -382,8 +382,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 +443,14 @@ do
fs.remove('record/round_l.rec')
fs.remove('record/round_u.rec')
end
if STAT.version<1604 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
@@ -576,3 +587,36 @@ 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
if TABLE.find(arg,'--test')then
TASK.new(function()
while not LOADED do YIELD()end
print("\27[92m\27[1mAutomatic Test Started\27[0m")
BGM.setVol(0)SFX.setVol(0)
love.keypressed('space')
while SCN.swapping do YIELD()end
for k,mode in next,MODES do
if k~='netBattle'then
print("Scanning mode: "..mode.name)
loadGame(mode.name.."a",true)
while SCN.swapping do YIELD()end
SCN.back()
while SCN.swapping do YIELD()end
end
end
print("\27[92m\27[1mAutomatic Test Passed :)\27[0m")
for _=1,60 do YIELD()end
love.event.quit(0)
end)
TASK.new(function()
while true do
YIELD()
if ERRDATA[1]then break end
end
print("\27[91m\27[1mAutomatic Test Failed :(\27[0m\nThe error message is:\n"..table.concat(ERRDATA[1].mes,"\n").."\27[91m\nAborting\27[0m")
for _=1,60 do YIELD()end
love.event.quit(1)
end)
end

View File

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

@@ -0,0 +1,15 @@
return{
fillClear=false,
dropPiece=function(P)
if #P.field>P.gameEnv.fieldH then
local cc=P:clearFilledLines(P.garbageBeneath+1,#P.field-P.garbageBeneath)
local h=P.gameEnv.fieldH-cc-P.garbageBeneath
if h>0 then
P:garbageRise(21,h,2e10-1)
if P.garbageBeneath>=P.gameEnv.fieldH then
P:lose()
end
end
end
end,
}

View File

@@ -0,0 +1,15 @@
return{
fillClear=false,
dropPiece=function(P)
if #P.field>P.gameEnv.fieldH then
local cc=P:clearFilledLines(P.garbageBeneath+1,#P.field-P.garbageBeneath)
local h=math.ceil((P.gameEnv.fieldH-cc-P.garbageBeneath)/2)
if h>0 then
P:garbageRise(21,h,2e10-1)
if P.garbageBeneath>=P.gameEnv.fieldH then
P:lose()
end
end
end
end,
}

Binary file not shown.

View File

@@ -10,6 +10,7 @@ local int,rnd=math.floor,math.random
local SETTING,GAME,SCR=SETTING,GAME,SCR
local PLAYERS=PLAYERS
local playSFX=SFX.play
@@ -174,6 +175,46 @@ function royaleLevelup()
end
end
--Sound shortcuts
function playClearSFX(cc)
if cc<=0 or cc%1~=0 then return end
if cc<=4 then
playSFX('clear_'..cc)
elseif cc<=6 then
playSFX('clear_5')
else
playSFX('clear_6',.4)
if cc<=9 then Snd('bass','A3','E4')
elseif cc<=12 then Snd('bass','A3','E4','A4')
elseif cc<=14 then Snd('bass',.8,'A3','E4')Snd('lead','A4','E5')
elseif cc<=16 then Snd('bass',.8,'A3','G4')Snd('lead','B4','G5')
elseif cc==17 then Snd('bass',.8,'A3','A4')Snd('lead','E5','G5')
elseif cc==18 then Snd('bass',.7,'A4')Snd('lead',.8,'C4','G5')Snd('bell','D5')
elseif cc==19 then Snd('bass',.7,'A4')Snd('lead',.8,'A4','E5')Snd('bell','B5')
elseif cc==20 then Snd('bass',.7,'A4')Snd('lead',.8,'A4','E4')Snd('bell','D5','B5','G6')
else Snd('bass',.7,'A4')Snd('lead',.8,'A4','E4')Snd('bell','B5','E6','A6')
end
end
end
function playReadySFX(i)
if i==3 then
Snd('bass','A3')
Snd('lead','A4')
elseif i==2 then
Snd('bass','F3')
Snd('lead','A4')
Snd('lead','D5')
elseif i==1 then
Snd('bass','G3')
Snd('lead','B4')
Snd('lead','E5')
elseif i==0 then
Snd('bass','A3')
Snd('lead','A4')
Snd('lead','E5')
Snd('lead','A5')
end
end
--Game
@@ -346,7 +387,7 @@ function loadGame(mode,ifQuickPlay,ifNet)--Load a mode and go to game scene
local modeText=text.modes[mode]or{"["..MODES[mode].name.."]",""}
TEXTOBJ.modeName:set(modeText[1].." "..modeText[2])
SCN.go('game',ifQuickPlay and'swipeD'or'fade_togame')
SFX.play('enter')
playSFX('enter')
end
end
end
@@ -410,7 +451,7 @@ function gameOver()--Save record
P:_showText(text.newRecord,0,-100,100,'beat',.5)
if SETTING.autoSave and DATA.saveReplay()then
GAME.saved=true
SFX.play('connected')
playSFX('connected')
MES.new('check',text.saveDone)
end
end
@@ -622,8 +663,7 @@ do--function resetGameData(args)
if GAME.setting.allowMod then
TASK.new(task_showMods)
end
Snd('bass','A3')
Snd('lead','A4')
playReadySFX(3)
collectgarbage()
end
end

View File

@@ -408,7 +408,7 @@ return{
{"Rotation Systems",
"wallkick rotationsystem",
"term",
"Systems that determine how pieces rotate.\n\nRotation systems usually handle two things: basic rotation and kicks.\n\nBasic rotation refers to how pieces rotate in an open area. Because rotating pieces on their geometric center will usually cause the piece to be misaligned from the grid, rotation systems need to specify alternative rotation centers or rotation offsets to align rotated pieces back to the grid.\n\nKicks refer to offsets applied if the rotated piece overlaps with the border of the matrix or other blocks. While older games, like the ones on NES and Gameboy, lack kicks, people soon realized that if a piece is too close to the wall, the floor or other pieces, the piece can (unintuitively) fail to rotate due to overlapping. Games started to implement systems that allow pieces close to walls/floors to rotate, and move them away from the wall/floor into a valid position (\"kicking off the wall/floor\"), and such movements, or offsets used in said movements, are referred to as (wall/floor) kicks.\n\nWhile Super Rotation System (SRS) is the current standard for modern official Tetris games, older games and unofficial games may have their own rotation systems, implementing different basic rotations and kicks.",
"Systems that determine how the pieces rotate.\n\nIn modern Tetris games, tetrominoes can rotate on a specfic rotation center (but this may be absent in some games). If the minoes overlap with the walls or the field, the system would attempt to perform some offsets (a process known as \"wall-kicking\"). Wall kicks allow minoes to move into in specific-shaped holes.",
},
{"ARS",
"ars arikrotationsystem atarirotationsystem",
@@ -448,7 +448,7 @@ return{
{"SRS",
"srs superrotationsystem",
"term",
"Super Rotation System\nThe rotation system used in modern, official Tetris games.\nEach Tetromino has a rotation center for the piece to rotate around. Should a Tetromino overlap with the wall, floor or another mino on the field after rotation, a few offset positions will be checked, allowing pieces to kick off walls and floors. This also allows pieces to rotate into openings that are otherwise unreachable.\n\nMany unofficial games implement some modification of this rotation system that adds a kick for 180 spins. In Techmino, such a modification is called SRS+.",
"Super Rotation System, the most widely used rotation system by modern Tetris games, and is the foundation of many self-made rotation systems. There are four orientations for each tetromino, and they can rotate clockwise or counterclockwise (But without 180° rotations). Should a Tetromino overlap with the wall, floor or other minoes on the field after rotation, a few offset positions will be checked, allowing pieces to kick off walls and floors. You can look up the details of the wall kick table on Tetris Wiki.",
},
{"TRS",
"trs techminorotationsystem",
@@ -636,6 +636,16 @@ return{
"term",
"The delay between block touching the ground and locking down (i.e. can no longer be controlled, and the next piece spawns).\nModern Tetris games often have forgiving lockdown delay mechanics where you can reset this delay by moving or rotating (up to 15 times), and you can sometimes stall for time by doing this. Classic Tetris games often have a far less forgiving lockdown delay.",
},
{"ARE",
"are spawn appearance delay",
"term",
"Sometimes called the Entry Delay. ARE refers to the delay between the lockdown of one piece and the spawn of another piece.",
},
{"line ARE",
"line are appearance delay",
"term",
"The delay between the start of a line clear animation to the spawn of the next piece.",
},
{"Finesse",
"finesse",
"term",
@@ -691,6 +701,21 @@ return{
"term",
"A way to generate pieces, notably used in Tetris: The Grand Master games. Every time a random Tetromino is selected, but if this Tetromino is the same as one of the few previous pieces, then reroll until a different piece is rolled or until a reroll limit is reached.\nFor example, a \"his 4 roll 6\" (h4r6) generator rerolls when the piece is the same as one of the 4 previous pieces and rerolls up to 6 times.\nThere are other variations as well, such as \"his4 roll6 pool35\", which further reduces the randomness of the piece sequence.\n\nIn Techmino, the max. reroll count is half of the sequence length, rounded up.",
},
{"HisPool generator",
"hisPool history pool",
"term",
"History Pool, a generator based on the His generator. It introduced a mechanism called \"Pool\". When generating a new piece, HisPool randomly selects a piece from the Pool and increase the probability of spawning of the least frequent piece.\n\nThis mechanism makes the sequence more stable and ensures that the drought won't last forever.",
},
{"bagES generator",
"bages easy start",
"term",
"*Techmino-exclusive*\nBag Easy-Start, an improved Bag generator. The first piece in the first bag won't be those hard-to-place pieces (S/Z/O/S5/Z5/F/E/W/X/N/H).",
},
{"Reverb generator",
"reverb",
"term",
"*Techmino-exclusive*\nA generator derived from Bag. Based on Bag generator, the Reverb generator repeats each piece several times. The probability of repetition decreases when a certain piece repeats too frequently and vice versa. ",
},
{"Hypertapping",
"hypertapping",
"term",
@@ -918,24 +943,30 @@ return{
},
--Other
{"Github Repository",
"githubrepository sourcecode",
"other",
"Techmino's Github repository. Stars are appreciated.",
"https://github.com/26F-Studio/Techmino",
},
{"Communities",
"community communities",
"other",
"Join Tetris communities and talk with other players!\n\nChina: [QQ] Tetris Research: 112897780\nGlobal: [Discord] Hard Drop: discord.gg/harddrop (click \"Open URL\").",
"https://discord.gg/harddrop"
},
{"Mew",
"mew tieba forum",
"help",
"The Mew forum owned by Chinese Tetris Research Community, and was founded in the second half of 2021. Mew is a Chinese social media that can be thought of a combination of Discord and Reddit, with many channels in a big community. Users can chat in the channels or submit posts to the channel. Mew also has a function called \"Library\" which allows storing documentations systematically. The Tetris Mew forum is currently under construction and not too much contents are available (2/Nov/2021).",
"https://mew.fun/n/tetris",
},
{"Tetris OL Servers",
"tetrisonline servers",
"other",
"Google \"Tetris Online Poland\" for the Poland server.\nClick \"Open URL\" for information about the Tetris Online Study server.",
"http://teatube.ltd/tos",
},
{"Github Repository",
"githubrepository sourcecode",
"other",
"Techmino's Github repository. Stars are appreciated.",
"https://github.com/26F-Studio/Techmino",
},
--Savedata managing
{"Console",

View File

@@ -408,7 +408,7 @@ return{
{"旋转系统(踢墙)",
"旋转系统 踢墙 xuanzhuanxitong wallkick tiqiang",
"term",
"(部分游戏中)方块旋转后可能和场地或墙壁有碰撞,此时系统可能会给方块施加偏移,让方块不会因此被卡住而不能操作。这个偏移就是踢墙。\n建议阅读SRS词条。",
"现代方块游戏中,方块可以绕着旋转中心(在本游戏中可见)旋转(部分游戏没有固定中心),如果旋转后和场地或墙壁有重合,会根据<从哪个方向转到哪个方向>进行一些偏移测试(这个偏移称为踢墙),不会卡住转不动,同时也可以让方块钻进入一些特定形状的洞",
},
{"ARS",
"旋转系统 ars rotate",
@@ -458,7 +458,7 @@ return{
{"SRS",
"超级旋转系统 srs rotate",
"term",
"Super Rotation System\n现代方块最常用的旋转系统,也是不少自制旋转系统的设计模板。\n简单原理介绍:每个方块都有一个旋转中心,旋转后如果和场地有重合,会根据<从哪个方向转到哪个方向>进行一些偏移测试,可以让方块钻进入一些特定形状的洞。\n注:对于SRS每个方块有四个方向可以朝两边转180°不算设计的时候还没有,所以不能踢墙所以总共8种对应8个偏移表具体数据去Wiki上查这里就不放了",
"Super Rotation System\n现代方块最常用的旋转系统,也是不少自制旋转系统的设计模板。\n对于SRS每个方块有四个方向可以朝两边转180°不算最开始没有这个设计所以总共8种对应8个偏移表具体数据去Wiki上查这里就不放了",
},
{"SRS+",
"超级旋转系统 srs+ srsplus rotate",
@@ -662,6 +662,16 @@ return{
"term",
"方块<碰到地面到锁定>之间的时间。经典块仅方块下落一格时刷新倒计时,而现代方块中往往任何操作都将重置该倒计时(但是方块本身必须可以移动/旋转所以连续移动和操作可以让方块不马上锁定拖一会时间本游戏和部分游戏重置次数有限一般是15",
},
{"出块延迟",
"出块延迟 are delay chukuaiyanchi",
"term",
"方块<锁定完成到下一个方块出现>之间的时间英文是ARE。",
},
{"消行延迟",
"消行延迟 line are delay xiaohangyanchi",
"term",
"方块<锁定完成能消行时的消行动画>占据的时间英文是line ARE。",
},
{"Finesse",
"极简操作 最简操作 finesse jijiancaozuo zuijiancaozuo",
"term",
@@ -964,23 +974,29 @@ return{
},
--其他
{"GitHub仓库",
"源代码 github git sourcecode yuandaima",
"other",
"Techmino的GitHub仓库地址欢迎Star",
"https://github.com/26F-Studio/Techmino",
},
{"研究群",
"研究群 yanjiu study",
"other",
"俄罗斯方块·[研究]群QQ号112897780“中国俄罗斯方块总群”",
},
{"Mew据点",
"mew tieba forum",
"help",
"研究群下属的mew据点类似贴吧或者discord的服务器2021年下半年建立是discord和贴吧的结合体可以在同一个大社区的各个频道实时聊天也可以发帖以主题交流同时还有一个叫图书馆的功能方便各种方块资料整理还在建设中目前没多少内容2021.11,2",
"https://mew.fun/n/tetris",
},
{"茶服",
"茶服 chafu study",
"other",
"TO-S的添加方法、说明等关于茶服的一切",
"http://teatube.ltd/tos",
},
{"GitHub仓库",
"源代码 github git sourcecode yuandaima",
"other",
"Techmino的GitHub仓库地址欢迎Star",
"https://github.com/26F-Studio/Techmino",
},
--存档管理
{"控制台",

View File

@@ -21,7 +21,8 @@ return{
powerUp={[0]="+000%","+025%","+050%","+075%","+100%"},
cmb={nil,"1 Combo","2 Combo","3 Combo","4 Combo","5 Combo","6 Combo","7 Combo","8 Combo","9 Combo","10 Combo!","11 Combo!","12 Combo!","13 Combo!","14 Combo!!","15 Combo!!","16 Combo!!","17 Combo!!!","18 Combo!!!","19 Combo!!!","MEGACMB"},
spin="-spin",
clear={"Single","Double","Triple","Techrash","Pentacrash","Hexacrash"},
clear={"Single","Double","Triple","Techrash","Pentacrash","Hexacrash","Heptacrash","Octacrash","Nonacrash","Decacrash","Undecacrash","Dodecacrash","Tridecacrash","Tetradecacrash","Pentadecacrash","Hexadecacrash","Heptadecacrash","Octadecacrash","Nonadecacrash","Ultracrash","Impossicrash"},
cleared="$1 LINES",
mini="Mini",b2b="B2B ",b3b="B2B2B ",
PC="Perfect Clear",HPC="Hemi-Perfect Clear",
replaying="[Replay]",
@@ -760,20 +761,20 @@ return{
['custom_puzzle']= {"Custom", "PUZZLE"},
},
getTip={refuseCopy=true,
'Free-to-play block stacking game with a Battle Royale mode!',
'Have you noticed what "rotating" does do to a block?',
":pog:",
"(RUR'U')R'FR2U'R'U'(RUR'F')",
"\"Example App\" cannot be opened because the developer cannot be verified.",
"\"Techmino.app\" cannot be opened because the developer cannot be verified.",
"\"Techmino.app\" will damage your computer. You should move it to the Bin.",
"\"TechminOS\"",
"\\jezevec/\\jezevec/\\jezevec/",
"\\osk/\\osk/\\osk/",
"↑↑↓↓←→←→BA",
"$include<studio.h>",
"0next 0hold",
"0next 0hold.",
"1next 0hold",
"1next 1hold!",
"1next 6hold!",
"20G actually is a brand new game rule.",
"20G actually is a brand new game rule!",
"40-line Sprint WR: 14.915s by Reset_",
"6next 1hold!",
"6next 6hold?!",
@@ -782,7 +783,6 @@ return{
"Am G F G",
"B2B2B???",
"B2B2B2B does not exist.",
"B2B2B2B exists?",
"Back-to-Back Techrash, 10 Combo, PC!",
"Be sure to give it your best shot again today!",
"Bridge clear coming soon!",
@@ -792,49 +792,60 @@ return{
"Color clear coming soon!",
"Decreasing DAS and ARR makes your game faster but harder to control.",
"Did I just see a Back-to-Back-to-Back?",
"Does B2B2B2B exists?",
"Don't let a small glitch ruin your entire day!",
"Don't look directly at the bugs!",
"Enjoy the Techmino rotation system!",
"Excellent, but let's go better next time…",
"Find out what's in the settings!",
"Found any bugs? Open up an issue in our GitHub page!",
"Free-to-play block stacking game with a Battle Royale mode!",
"git commit",
"git push -f",
"Got any suggestions? Post them in our Discord!",
"Have you noticed what \"rotating\" does do to a block?",
"Headphones recommended for a better experience.",
"Hello world!",
"I3 and L3 are the only two unique tetrominoes.",
"hello world",
"I3 and L3 are the only two unique triminoes.",
"if a==true",
"Increase your frame rate for a better experience.",
"Initial [insert action] system can save you.",
"Is B2B2B2B possible?",
"It's possible to finish 40L without left/right button.",
"It is loading! Not just a cutscene!",
"It's possible to finish 40L without left/right buttons.",
"It's possible to finish 40L without rotation buttons.",
"Join our Discord!",
"l-=-1",
"Let the bass kick!",
"Low frame rates reduce your gaming experience.",
"LrL RlR LLr RRl RRR LLL FFF RfR RRf rFF",
"Lua No.1",
"Mix clear coming soon!",
"Most of the button icons are realized by using self-drawn glyphs in the Unicode Private Use Area.",
"Music of this game is made using Beepbox.",
"Music too distracting? You can turn it off.",
"No easter eggs in this menu if you have the simplistic style turned on!",
"O-Spin Triple!",
"OHHHHHHHHHHHHHH",
"Online mode is planned - please be patient.",
"Online mode is planned please be patient.",
"Play single-handedly!",
"Playing good takes some time!",
"Powered by LÖVE",
"Powered by Un..LÖVE",
"pps-0.01",
"Secret number: 626",
"Server down randomly",
"Some requirements to achieve rank S are intentionally set to be difficult for even the best players.",
"Soon you'll be able to play against friends and foes all over the world.",
"Split clear coming soon!",
"Surely loading! Not just a cutscene!",
"sudo rm -rf /*",
"Techmino = Technique + Tetromino",
"Techmino has a Nspire-CX edition!",
"Techmino is so fun!",
"Techmino.app will damage your computer. You should move it to the Bin.",
"TetroDictionary is now available in English.",
"The names that appeared in the background of the Staff page is a list of our sponsors.",
"The stacker future is yours in Techmino!",
"There are four hidden modes in the game.",
"There are several hidden modes in the game that cannot be entered using the map.",
"There is a total of 18 different pentominoes.",
"There is a total of 7 different tetrominoes.",
"Try using multiple Hold Queues!",
@@ -846,10 +857,12 @@ return{
"What is this cheap UI & music smh",
"while(false)",
"You are a Grand Master!",
"You can connect a keyboard to your phone or tablet!",
"You are welcome to help us to make BGMs and SFXs!",
"You can connect a keyboard to your phone or tablet (not functional on iOS though).",
"You can customize the key mappings in settings!",
"You can navigate the menu with a keyboard, but only in this screen.",
"You can open the save directory from the Stats page.",
"You can perform a spin with 28 of the 29 minos in this game; the exception being O1.",
"You can perform a spin with 28 of the 29 minoes in this game; the exception being O1.",
"You can set the spawning orientation for each tetromino.",
"ZS JL T O I",
{C.C,"Also try 15puzzle!"},
@@ -858,16 +871,20 @@ return{
{C.C,"Also try Orzmic!"},
{C.C,"Also try osu!"},
{C.C,"Also try Phigros!"},
{C.C,"Also try Puyo Puyo!"},
{C.C,"Also try Rubik's cube!"},
{C.C,"Also try Terraria!"},
{C.C,"Also try Touhou Project!"},
{C.C,"Also try VVVVVV!"},
{C.H,"REGRET!!"},
{C.lP,"Secret number: 626"},
{C.lR,"Z ",C.lG,"S ",C.lS,"J ",C.lO,"L ",C.lP,"T ",C.lY,"O ",C.lC,"I"},
{C.lY,"COOL!!"},
{C.N,"Lua",C.Z," No.1"},
{C.P,"T-spin!"},
{C.R,"\"DMCA abusing\""},
{C.R,"\"Intellectual property law\""},
{C.R,"DD",C.Z," Cannon=",C.P,"TS",C.R,"D",C.Z,"+",C.P,"TS",C.R,"D",C.Z," Cannon"},
{C.R,"DT",C.Z," Cannon=",C.P,"TS",C.R,"D",C.Z,"+",C.P,"TS",C.R,"T",C.Z," Cannon"},
{C.R,"LrL ",C.G,"RlR ",C.B,"LLr ",C.O,"RRl ",C.P,"RRR ",C.P,"LLL ",C.C,"FFF ",C.Y,"RfR ",C.Y,"RRf ",C.Y,"rFF"},
{C.Y,"O-Spin Triple!"},

View File

@@ -10,7 +10,8 @@ return{
royale_remain="$1 Jugadores Restantes",
cmb={nil,"Combo de 1","Combo de 2","Combo de 3","Combo de 4","Combo de 5","Combo de 6","Combo de 7","Combo de 8","Combo de 9","¡Combo de 10!","¡Combo de 11!","¡Combo de 12!","¡Combo de 13!","¡Combo de 14!","¡Combo de 15!","¡Combo de 16!","¡Combo de 17!","¡Combo de 18!","¡Combo de 19!","MEGACOMBO"},
spin="-spin",
clear={"Single","Doble","Triple","Techrash","Pentacrash","Hexacrash"},
clear={"Single","Doble","Triple","Techrash","Pentacrash","Hexacrash","Heptacrash","Octacrash","Nonacrash","Decacrash","Undecacrash","Dodecacrash","Tridecacrash","Tetradecacrash","Pentadecacrash","Hexadecacrash","Heptadecacrash","Octadecacrash","Nonadecacrash","Ultracrash","Impossicrash"},
-- cleared="$1 LINES",
mini="Mini",b2b="B2B ",b3b="B2B2B ",
PC="Perfect Clear",HPC="Half Clear",
replaying="[Repetición]",

View File

@@ -10,7 +10,8 @@ return{
royale_remain="$1 Joueurs restants",
cmb={nil,"1 Combo","2 Combo","3 Combo","4 Combo","5 Combo","6 Combo","7 Combo","8 Combo","9 Combo","10 Combo!","11 Combo!","12 Combo!","13 Combo!","14 Combo!!","15 Combo!!","16 Combo!!","17 Combo!!!","18 Combo!!!","19 Combo!!!","MEGACMB"},
spin="-spin",
clear={"Simple","Double","Triple","Techrash","Pentacrash","Hexacrash"},
clear={"Simple","Double","Triple","Techrash","Pentacrash","Hexacrash","Heptacrash","Octacrash","Nonacrash","Decacrash","Undecacrash","Dodecacrash","Tridecacrash","Tetradecacrash","Pentadecacrash","Hexadecacrash","Heptadecacrash","Octadecacrash","Nonadecacrash","Ultracrash","Impossicrash"},
-- cleared="$1 LINES",
mini="Mini",b2b="B2B ",b3b="B2B2B ",
PC="Perfect Clear",HPC="Clear",
replaying="[Replay]",

View File

@@ -11,7 +11,8 @@ return{
royale_remain="$1 Jogadores restantes",
cmb={nil,"1 Combo","2 Combo","3 Combo","4 Combo","5 Combo","6 Combo","7 Combo","8 Combo","9 Combo","10 Combo!","11 Combo!","12 Combo!","13 Combo!","14 Combo!!","15 Combo!!","16 Combo!!","17 Combo!!!","18 Combo!!!","19 Combo!!!","MEGACMB"},
spin="-spin",
clear={"Single","Double","Triple","Techrash","Pentacrash","Hexacrash"},
clear={"Single","Double","Triple","Techrash","Pentacrash","Hexacrash","Heptacrash","Octacrash","Nonacrash","Decacrash","Undecacrash","Dodecacrash","Tridecacrash","Tetradecacrash","Pentadecacrash","Hexadecacrash","Heptadecacrash","Octadecacrash","Nonadecacrash","Ultracrash","Impossicrash"},
-- cleared="$1 LINES",
mini="Mini",b2b="B2B ",b3b="B2B2B ",
PC="Perfect Clear",HPC="Clear",
replaying="[Replay]",

View File

@@ -5,7 +5,8 @@ return{
royale_remain="$1 ~",
cmb={nil,"!","!!","!!!","!!!!","!!!!!","!!!!!!","!!!!!!!","!!!!!!!!","!!!!!!!!!","!!!!!!!!!!","!!!!!!!!!!!","!!!!!!!!!!!!","!!!!!!!!!!!!!","!!!!!!!!!!!!!!","!!!!!!!!!!!!!!!","!!!!!!!!!!!!!!!!","!!!!!!!!!!!!!!!!!","!!!!!!!!!!!!!!!!!!","!!!!!!!!!!!!!!!!!!!","!!!!!!!!!!!!!!!!!!!!",},
spin=" ~",
clear={"1","2","3","4","5","6"},
clear={"1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","20+"},
cleared="",
mini="v",b2b="^ ",b3b="^^ ",
PC="#<>#",HPC="<>",
replaying="[R]",

View File

@@ -15,7 +15,8 @@ return{fallback='zh',
royale_remain="剩 $1 人",
cmb={nil,"1连","2连","3连","4连","5连","6连","7连","8连","9连","10连!","11连!","12连!","13连!","14连!","15连!","16连!","17连!","18连!","19连!","Very 连"},
spin="",
clear={"消一","消二","消三","消四","卧槽","离谱"},
clear={"消一","消二","消三","消四","消五","消六","消七","消八","消九","消十","消十一","消十二","消十三","消十四","消十五","消十六","消十七","消十八","消十九","消二十","消超二十"},
cleared="",
mini="",b2b="牛逼",b3b="很牛逼",
PC="消干净了",HPC="消了半截",

View File

@@ -21,7 +21,8 @@ return{
powerUp={[0]="000%UP","025%UP","050%UP","075%UP","100%UP"},
cmb={nil,"1 Combo","2 Combo","3 Combo","4 Combo","5 Combo","6 Combo","7 Combo","8 Combo","9 Combo","10 Combo","11 Combo","12 Combo","13 Combo","14 Combo","15 Combo","16 Combo","17 Combo","18 Combo","19 Combo","MEGACMB"},
spin="-spin",
clear={"single","double","triple","Techrash","Pentacrash","Hexacrash"},
clear={"Single","Double","Triple","Techrash","Pentacrash","Hexacrash","Heptacrash","Octacrash","Nonacrash","Decacrash","Undecacrash","Dodecacrash","Tridecacrash","Tetradecacrash","Pentadecacrash","Hexadecacrash","Heptadecacrash","Octadecacrash","Nonadecacrash","Ultracrash","Impossicrash"},
cleared="$1 LINES",
mini="Mini",b2b="B2B ",b3b="B2B2B ",
PC="Perfect Clear",HPC="Half Clear",
replaying="[回放]",
@@ -556,7 +557,7 @@ return{
arrow="",
now="正在播放:",
bgm="BGM",
bgm="音乐",
sound="音效室",
},
launchpad={
@@ -767,6 +768,8 @@ return{
"……合群了就会消失不合群世界毁灭指game over",
"……,合群了就会消失,但消失不代表没有意义",
"……,没有对比就没有伤害",
"“Techmino.app”将对您的电脑造成伤害。您应该将它移到废纸篓。",
"“TechminOS”",
"(a+b)³=a³+3a²b+3ab²+b³",
"(RUR'U')R'FR2U'R'U'(RUR'F')",
"《按钮风格进化史》",
@@ -778,10 +781,9 @@ return{
"《游戏的意义》",
"《知识的力量》",
"《主题曲进化史》",
"\"TechminOS\"",
"↑↑↓↓←→←→BA",
"$include<studio.h>",
"0next 0hold",
"0next 0hold.",
"11renPC",
"1next 0hold",
"1next 1hold",
@@ -843,7 +845,7 @@ return{
"多年小游戏玩家表示痛恨假加载,启动动画主要是在加载资源",
"多hold现代块又回来了",
"俄罗斯方块完全可以作为电竞游戏",
"发现有个\"隐形\"皮肤了吗",
"发现有个“隐形”皮肤了吗",
"发现Bug可以去GitHub上开个issue反馈",
"方块不能吃",
"方块不是你生活的全部,适当走出去看看",
@@ -907,7 +909,6 @@ return{
"每个块的颜色可以自定义",
"每个虚拟按键都可以隐藏/显示,尺寸也可调",
"免费吃鸡方块",
"“Techmino.app”将对您的电脑造成伤害。您应该将它移到废纸篓。",
"喵!",
"魔方也是方块(确信",
"能导致吃键的问题有很多,建议说清楚具体发生了什么并且录视频说明",
@@ -926,7 +927,7 @@ return{
"你知道吗:O-Spin是在0.8.20 (Fantastic Global Update II)中诞生的",
"你知道吗:TRS旋转系统的最初形态在0.0.091726版本就存在了",
"你准备好了吗?",
"其实很多时候\"吃键\"是玩家对游戏机制不了解或者自己的操作问题导致的",
"其实很多时候“吃键”是玩家对游戏机制不了解或者自己的操作问题导致的",
"其实S和Z有四个方向(状态),虽然看起来只有两个",
"请谨慎向没有方块经验的玩家推荐,会对本游戏的生存环境造成影响,感谢配合。",
"请勿大力敲打设备敲坏了就没有Techmino玩了",
@@ -944,7 +945,7 @@ return{
"使用固定堆叠方法达成20TSD难度很低",
"试试用跳舞毯打块",
"适度游戏益脑,沉迷游戏伤身,合理安排时间,享受健康生活",
"手机玩也可以外接键盘哦",
"手机玩也可以外接键盘哦(iOS除外)",
"首页的机器人可能会不小心把自己给玩死",
"术语不认识?去右边那个词典里查查吧",
"水平是随着时间一点点提升的,不是几天几星期就能玩好的哦",
@@ -1005,7 +1006,7 @@ return{
"震惊我只是一条凑数tip吗",
"众所周知俄罗斯方块是经典编程练手游戏(",
"众所周知mac不能拿来玩游戏",
"注意到方块\"旋转\"的时候到底发生了些什么吗?",
"注意到方块“旋转”的时候到底发生了些什么吗?",
"自定义场地可以画图实现逐页演示",
"自己不确定的问题尽量不要教别人哦",
"总共有400多条tip哦",
@@ -1030,18 +1031,18 @@ return{
"e^(πi)=-1",
"e^(πi/2)=i",
"e^(πi/4)=(1+i)/√2",
"Farter:\"成天被夸赞'好玩'的\"",
"Farter:\"可以形成方块圈子小中心话题,同作者一起衍生一些概念与梗的\"",
"Farter:\"论方块的软工意义(就算这么小个范围内,各种取舍蒙混翻车现象都总会以很易懂的方式出现(\"",
"Farter:\"民间微创新\"",
"Farter:\"民间音le与图案\"",
"Farter:\"民间游戏设计\"",
"Farter:\"是方块爱好者研究平台\"",
"Farter:\"是方块萌新入坑接收器\"",
"Farter:\"是居家旅行装逼必备\"",
"Farter:\"是民间UI动效艺术作品\"",
"Farter:\"是一滩散乱的代码组成的蜜汁结构\"",
"Farter:\"它是现在的techmino已发布版本\"",
"Farter:成天被夸赞'好玩'的",
"Farter:可以形成方块圈子小中心话题,同作者一起衍生一些概念与梗的",
"Farter:论方块的软工意义(就算这么小个范围内,各种取舍蒙混翻车现象都总会以很易懂的方式出现(",
"Farter:民间微创新",
"Farter:民间音lè与图案",
"Farter:民间游戏设计",
"Farter:是方块爱好者研究平台",
"Farter:是方块萌新入坑接收器",
"Farter:是居家旅行装逼必备",
"Farter:是民间UI动效艺术作品",
"Farter:是一滩散乱的代码组成的蜜汁结构",
"Farter:它是现在的techmino已发布版本",
"fin neo iso 是满足tspin条件的特殊t2的名字",
"git commit",
"git push -f",
@@ -1052,7 +1053,6 @@ return{
"Let-The-Bass-Kick",
"MrZ是谁啊",
"pps-0.01",
"sudo rm -rf /*",
"S△ABC=√(h(h-a)(h-b)(h-c))h=(a+b+c)/2",
"shutdown -h now",
"sin(α+β)=SαCβ+SβCα",
@@ -1062,6 +1062,7 @@ return{
"sofunhowtoget",
"Staff名单里飘过的是赞助榜单喜欢本游戏的话可以给我们打赞助支持开发哦~",
"STSD必死",
"sudo rm -rf /*",
"Techmino = Technique + tetromino",
"Techmino 好玩!",
"Techmino 濂界帺锛",
@@ -1084,8 +1085,6 @@ return{
"Z酱累了Z酱不想更新",
"Z酱只是个写代码的懂什么方块",
"Z块等身抱枕来一个(x",
{C.A,"AQUA"},
{C.B,"BLUE"},
{C.C,"<PURE ",C.P,"MEMORY>"},
{C.C,"15puzzle好玩"},
{C.C,"东方Project好玩"},
@@ -1093,49 +1092,22 @@ return{
{C.C,"噗哟噗哟好玩!"},
{C.C,"扫雷好玩!"},
{C.C,"Celeste好玩"},
{C.C,"CYAN"},
{C.C,"Minecraft好玩"},
{C.C,"Orzmic好玩"},
{C.C,"Osu 好玩!"},
{C.C,"Osu! 好玩!"},
{C.C,"Phigros好玩"},
{C.C,"Terraria好玩"},
{C.C,"VVVVVV好玩"},
{C.G,"GREEN"},
{C.G,"mac快捷键: Cmd+[=返回上一级目录"},
{C.G,"mac快捷键: Cmd+A=全选"},
{C.G,"mac快捷键: Cmd+F=查找"},
{C.G,"mac快捷键: Cmd+Option+Delete=永久删除文件 (技术人员别杠)"},
{C.G,"mac快捷键: Cmd+Q=退出程序"},
{C.G,"mac快捷键: Control+↑=打开调度中心"},
{C.G,"mac快捷键: Cmd+Tab=切换App"},
{C.G,"mac快捷键: Cmd+W=关闭当前窗口"},
{C.G,"mac快捷键: Cmd+Z=撤销"},
{C.G,"win快捷键: Alt+F4=关闭当前窗口"},
{C.G,"win快捷键: Alt+Tab=切换窗口"},
{C.G,"win快捷键: backspace=返回上一级目录"},
{C.G,"win快捷键: Ctrl+鼠标滚轮=缩放"},
{C.G,"win快捷键: Ctrl+A=全选"},
{C.G,"win快捷键: Ctrl+Alt+Z=查看所有qq消息"},
{C.G,"win快捷键: Ctrl+F=查找"},
{C.G,"win快捷键: Ctrl+Tab=切换标签页"},
{C.G,"win快捷键: Ctrl+W=关闭当前标签页"},
{C.G,"win快捷键: shift+del=永久删除文件 (技术人员别杠)"},
{C.H,"暂定段位:9"},
{C.H,"REGRET"},
{C.J,"JADE"},
{C.L,"LIME"},
{C.H,"REGRET!!"},
{C.lC,"Xspin",C.Z,"是啥"},
{C.lP,"口〇口",C.Z," 可爱!"},
{C.lP,"秘密数字:626"},
{C.lR,"Z ",C.lG,"S ",C.lS,"J ",C.lO,"L ",C.lP,"T ",C.lY,"O ",C.lC,"I"},
{C.lS,"茶娘",C.Z," 可爱!"},
{C.lY,"COOL"},
{C.M,"MAGENTA"},
{C.N,"Lua",C.Z,"天下第一"},
{C.N,"NAVY"},
{C.O,"ORANGE"},
{C.P,"PURPLE"},
{C.P,"T-spin"},
{C.P,"T-spin!"},
{C.R,"《滥用DMCA》"},
{C.R,"《知识产权法》"},
{C.R,"本游戏难度上限很高,做好心理准备。"},
@@ -1148,11 +1120,7 @@ return{
{C.R,"DD",C.Z,"炮=",C.P,"TS",C.R,"D",C.Z,"+",C.P,"TS",C.R,"D",C.Z,""},
{C.R,"DT",C.Z,"炮=",C.P,"TS",C.R,"D",C.Z,"+",C.P,"TS",C.R,"T",C.Z,""},
{C.R,"LrL ",C.G,"RlR ",C.B,"LLr ",C.O,"RRl ",C.P,"RRR LLL ",C.C,"FFF ",C.Y,"RfR RRf rFF"},
{C.R,"RED"},
{C.S,"SEA"},
{C.V,"VIOLET"},
{C.W,"uid:225238922"},
{C.W,"WINE"},
{C.Y,"暂定段位:GM"},
{C.Y,"暂定段位:M"},
{C.Y,"暂定段位:MK"},
@@ -1161,7 +1129,6 @@ return{
{C.Y,"暂定段位:MV"},
{C.Y,"Miya",C.Z," 可爱!"},
{C.Y,"O-spin Triple"},
{C.Y,"YELLOW"},
{C.Z,"12",C.C,"",C.Z,""},
{C.Z,"效率药水",C.H," 效率提升 (8:00)"},
{C.Z,"协调药水",C.H," MD减少 II(1:30)"},

View File

@@ -1,7 +1,8 @@
return{
cmb={nil,"1连击","2连击","3连击","4连击","5连击","6连击","7连击","8连击","9连击","10连击!","11连击!","12连击!","13连击!","14连击!","15连击!","16连击!","17连击!","18连击!","19连击!","巨型连击"},
spin="型回旋",
clear={"单清","双清","三清","四清","五清","六清"},
clear={"单清","双清","三清","四清","五清","六清","七清","八清","九清","十清","十一清","十二清","十三清","十四清","十五清","十六清","十七清","十八清","十九清","二十清","超二十清"},
cleared="",
mini="迷你",b2b="满贯",b3b="大满贯",
PC="场地全清",HPC="场地半清",

View File

@@ -22,7 +22,8 @@ return{
powerUp={[0]="+000%","+025%","+050%","+075%","+100%"},
cmb={nil,"1连击","2连击","3连击","4连击","5连击","6连击","7连击","8连击","9连击","10连击","11连击","12连击","13连击","14连击","15连击","16连击","17连击","18连击","19连击","巨大连击"},
spin="-旋转",
clear={"单身的","双重的","三倍的","技术崩溃","五角碰撞","六面体碎裂"},
clear={"单身的","双重的","三倍的","技术崩溃","五角碰撞","六面体碎裂","七冲击","八度碰撞","非碰撞","十点崩溃","不祥","十二面体碰撞","三十年代的崩溃","十四烷","十五烷碰撞","十六进制","七烷酸","十八进制崩溃","非十进制碰撞","超级崩溃","冒牌货"},
cleared="",
mini="迷你",b2b="背靠背",b3b="背靠背靠背",
PC="清清楚楚",HPC="半完美清晰",
replaying="[重播]",
@@ -760,114 +761,4 @@ return{
['custom_clear']= {"习俗", "正常"} ,
['custom_puzzle']= {"习俗", "令人费解的"},
},
getTip={refuseCopy=true,
'免费玩积木游戏与战斗皇家模式!',
'你注意到什么了吗?"旋转的"去一个街区有什么用?',
":pog:",
"(RUR'U')R'FR2U'R'U'(RUR'F')",
"\\jezevec/\\jezevec/\\jezevec/",
"\\osk/\\osk/\\osk/",
"↑↑↓↓←→←→文学士",
"$包括<工作室.哈>",
"0下一个0等待",
"1下一个0等待",
"1下一个1等待",
"1下一个6等待",
"20克实际上是一个全新的游戏规则",
"40直线冲刺世界纪录:14.915秒重置_",
"6下一个1等待",
"6下一个6等一下",
"成就系统即将推出!",
"所有自旋!",
"上午 G F G",
"背靠背靠背???",
"背靠背靠背靠背不存在",
"背靠背靠背靠背存在吗?",
"背靠背技术崩溃10连击个人电脑",
"今天一定要再次尽你最大的努力!",
"桥很快就清了!",
"你能熟练掌握这个现代而又熟悉的堆垛机吗?",
"在不谐和上可以找到英语的变更日志",
"颜色很快就会清晰!",
"降低直连式存储和抗共振环速度更快,但更难控制",
"我刚才看到的是背靠背靠背吗?",
"不要让一个小故障毁掉你的一天!",
"不要直接看虫子!",
"享受技术米诺旋转系统!",
"太好了,但下次我们要做得更好",
"找出设置中的内容!",
"有什么建议吗?在我们的不谐和中发布它们!",
"建议佩戴耳机以获得更好的体验",
"你好,世界!",
"I3和L3是仅有的两种独特的三聚体",
"如果a==真",
"提高帧速率以获得更好的体验",
"初始[插入操作]系统可以节省您的时间",
"无需左/右按钮即可完成40升",
"它真的在加载!不仅仅是一个剪贴画!",
"加入我们的纷争吧!",
"让贝斯踢!",
"LrL RlR LLr RRl RRR LLL FFF RfR RRf rFF",
"路亚一号",
"快来了!",
"这个游戏的音乐是使用Beepbox制作的",
"音乐太让人分心了?你可以把它关掉",
"如果您启用了简单化样式,则此菜单中没有复活节彩蛋!",
"旋转三倍!",
"哦哦哦哦哦哦哦哦",
"已计划在线模式-请耐心等待",
"单枪匹马!",
"玩得好需要一些时间!",
"被爱冲昏头脑",
"由联合国...LÖVE为动力",
"pps-0.01",
"秘密号码:626",
"服务器随机停机",
"一些达到S级的要求被故意设定为即使是最好的球员也很难达到",
"很快,你就可以和全世界的朋友和敌人比赛了",
"马上就来!",
"技术米诺=技术+特特罗米诺",
"技术米诺有一个Nspire CX版本",
"太有趣了!",
"四联词典现在有英文版本",
"在技术米诺,堆垛机的未来属于您!",
"游戏中有四种隐藏模式",
"总共有18种不同的五分音符",
"总共有7种不同的河豚",
"尝试使用多个等待队列!",
"尝试使用两个旋转按钮。使用这三种方法会更好",
"警告:程序员艺术",
"20件怎么样",
"100条生产线23件怎么样",
"26个热关断怎么样",
"这个便宜的界面和音乐是什么",
"当(假)",
"你是大师!",
"您可以将键盘连接到手机或平板电脑!",
"您可以使用键盘浏览菜单,但仅限于此屏幕",
"您可以从统计数据页面打开保存目录",
"在这个游戏中你可以用29个米诺中的28个进行旋转;例外情况是O1",
"您可以为每个四格拼板设置繁殖方向",
"ZS JL T O I",
{C.C,"也试试15拼图"},
{C.C,"还试试我的世界!"},
{C.C,"也试试扫雷艇!"},
{C.C,"也试试奥兹米奇!"},
{C.C,"也试试俄亥俄州立大学!"},
{C.C,"也试试菲格罗斯!"},
{C.C,"也试试魔方!"},
{C.C,"也试试特拉里亚!"},
{C.C,"也试试VVVVVV"},
{C.H,"后悔!!!"},
{C.lR,"Z ",C.lG,"S ",C.lS,"J ",C.lO,"L ",C.lP,"T ",C.lY,"O ",C.lC,"I"},
{C.lY,"凉爽!!!"},
{C.N,"Lua",C.Z,"第一"},
{C.P,"旋转!"},
{C.R,"\"滥用数字千年版权法\""},
{C.R,"\"知识产权法\""},
{C.R,"DT",C.Z,"大炮=",C.P,"TS",C.R,"D",C.Z,"+",C.P,"TS",C.R,"T",C.Z,"大炮"},
{C.R,"月球接收实验室",C.G,"RlR",C.B,"最后贷款人",C.O,"区域铁路线",C.P,"存款准备金率",C.P,"微光",C.C,"熔丝制造",C.Y,"自由罗斯科电台",C.Y,"雨林基金会基金",C.Y,"雨林基金会基金"},
{C.Y,"旋转三倍!"},
{C.Z,"什么?",C.lC,"Xspin"},
}
}

View File

@@ -1,36 +1,25 @@
local function getHoleCount(P)
local hole=0
for x=1,10 do
for y=1,100 do
if not P:solid(x,y)then
hole=hole+1
end
end
end
return hole
end
return{
color=COLOR.cyan,
env={
drop=60,lock=60,
fieldH=100,
highCam=true,
fillClear=false,
wait=0,fall=50,
garbageSpeed=30,
highCam=false,
seqData={1,2,3,4,5,6,7},
mesDisp=function(P)PLY.draw.drawTargetLine(P,100)end,
eventSet='stack_100',
bg='blockrain',bgm='there',
},
score=function(P)return{getHoleCount(P),P.stat.time}end,
scoreDisp=function(D)return D[1].." Holes".." "..STRING.time(D[2])end,
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]<b[2]end,
score=function(P)return{P.stat.row,P.stat.time}end,
scoreDisp=function(D)return D[1].." Lines".." "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local H=getHoleCount(P)
local L=P.stat.row
return
H==0 and 5 or
H<=1 and 4 or
H<=2 and 3 or
H<=5 and 2 or
H<=10 and 1 or
H<=26 and 0
L>=200 and 5 or
L>=180 and 4 or
L>=160 and 3 or
L>=130 and 2 or
L>=100 and 1 or
L>=70 and 0
end,
}

View File

@@ -1,36 +1,26 @@
local function getHoleCount(P)
local hole=0
for x=1,10 do
for y=1,98 do
if not P:solid(x,y)then
hole=hole+1
end
end
end
return hole
end
return{
color=COLOR.magenta,
env={
drop=60,lock=60,
fieldH=100,
highCam=true,
fillClear=false,
wait=0,fall=50,
fieldH=21,
highCam=false,
garbageSpeed=30,
seqData={1,2,3,4,5,6,7,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25},
mesDisp=function(P)PLY.draw.drawTargetLine(P,98)end,
eventSet='stack_50',
bg='blockrain',bgm='there',
},
score=function(P)return{getHoleCount(P),P.stat.time}end,
scoreDisp=function(D)return D[1].." Holes".." "..STRING.time(D[2])end,
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]<b[2]end,
score=function(P)return{P.stat.row,P.stat.time}end,
scoreDisp=function(D)return D[1].." Lines".." "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local H=getHoleCount(P)
local L=P.stat.row
return
H==0 and 5 or
H<=2 and 4 or
H<=4 and 3 or
H<=10 and 2 or
H<=26 and 1 or
H<=62 and 0
L>=80 and 5 or
L>=70 and 4 or
L>=60 and 3 or
L>=50 and 2 or
L>=40 and 1 or
L>=20 and 0
end,
}
}

View File

@@ -1,36 +1,26 @@
local function getHoleCount(P)
local hole=0
for x=1,10 do
for y=1,97 do
if not P:solid(x,y)then
hole=hole+1
end
end
end
return hole
end
return{
color=COLOR.yellow,
env={
drop=60,lock=60,
fieldH=100,
highCam=true,
fillClear=false,
wait=0,fall=50,
fieldH=21,
highCam=false,
garbageSpeed=30,
seqData={8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25},
mesDisp=function(P)PLY.draw.drawTargetLine(P,97)end,
eventSet='stack_50',
bg='blockrain',bgm='there',
},
score=function(P)return{getHoleCount(P),P.stat.time}end,
scoreDisp=function(D)return D[1].." Holes".." "..STRING.time(D[2])end,
comp=function(a,b)return a[1]<b[1]or a[1]==b[1]and a[2]<b[2]end,
score=function(P)return{P.stat.row,P.stat.time}end,
scoreDisp=function(D)return D[1].." Lines".." "..STRING.time(D[2])end,
comp=function(a,b)return a[1]>b[1]or a[1]==b[1]and a[2]<b[2]end,
getRank=function(P)
local H=getHoleCount(P)
local L=P.stat.row
return
H<=2 and 5 or
H<=5 and 4 or
H<=10 and 3 or
H<=26 and 2 or
H<=62 and 1 or
H<=126 and 0
L>=60 and 5 or
L>=50 and 4 or
L>=45 and 3 or
L>=30 and 2 or
L>=20 and 1 or
L>=10 and 0
end,
}
}

View File

@@ -621,40 +621,39 @@ function Player:lock()
end
end
function Player:checkClear(field,start,height,CB,CX)
local cc=0
if self.gameEnv.fillClear then
for i=1,height do
local h=start+i-2
function Player:_checkClear(field,start,height,CB,CX)
local cc,gbcc=0,0
for i=1,height do
local h=start+i-2
--Bomb trigger (optional, must with CB)
if CB and h>0 and field[h]and self.clearedRow[cc]~=h then
for x=1,#CB[1]do
if CB[i][x]and field[h][CX+x-1]==19 then
cc=cc+1
self.clearingRow[cc]=h-cc+1
self.clearedRow[cc]=h
break
end
--Bomb trigger (optional, must with CB)
if CB and h>0 and field[h]and self.clearedRow[cc]~=h then
for x=1,#CB[1]do
if CB[i][x]and field[h][CX+x-1]==19 then
cc=cc+1
self.clearingRow[cc]=h-cc+1
self.clearedRow[cc]=h
break
end
end
h=h+1
--Row filled
for x=1,10 do
if field[h][x]<=0 then
goto CONTINUE_notFull
end
end
cc=cc+1
ins(self.clearingRow,h-cc+1)
ins(self.clearedRow,h)
::CONTINUE_notFull::
end
h=h+1
--Row filled
for x=1,10 do
if field[h][x]<=0 then
goto CONTINUE_notFull
end
end
cc=cc+1
if field[h].garbage then gbcc=gbcc+1 end
ins(self.clearingRow,h-cc+1)
ins(self.clearedRow,h)
::CONTINUE_notFull::
end
return cc
return cc,gbcc
end
function Player:roofCheck()
function Player:_roofCheck()
local CB=self.cur.bk
for x=1,#CB[1]do
local y=#CB
@@ -673,14 +672,43 @@ function Player:roofCheck()
end
return false
end
function Player:_removeClearedLines()
for i=#self.clearedRow,1,-1 do
local h=self.clearedRow[i]
if self.field[h].garbage then
self.garbageBeneath=self.garbageBeneath-1
end
FREEROW.discard(rem(self.field,h))
FREEROW.discard(rem(self.visTime,h))
end
end
function Player:clearFilledLines(start,height)
local _cc,_gbcc=self:_checkClear(self.field,start,height)
if _cc>0 then
playClearSFX(_cc)
self:showText(text.clear[min(_cc,21)],0,0,60,'beat',.4)
if _cc>6 then self:showText(text.cleared:gsub("$1",_cc),0,50,25,'fly',.4)end
self:_removeClearedLines()
self.falling=self.gameEnv.fall
self.stat.row=self.stat.row+_cc
self.stat.dig=self.stat.dig+_gbcc
end
return _cc,_gbcc
end
function Player:removeTopClearingFX()
for i=#self.clearingRow,1,-1 do
if self.clearingRow[i]>#self.field then
rem(self.clearingRow)
else
return
break
end
end
if self.clearingRow[1]then
self.falling=self.gameEnv.fall
return false
else
return true
end
end
function Player:checkMission(piece,mission)
if mission<5 then
@@ -695,7 +723,7 @@ function Player:checkMission(piece,mission)
return false
end
local spawnSFX_name={}for i=1,7 do spawnSFX_name[i]='spawn_'..i end
local spawnSFX_name={'spawn_1','spawn_2','spawn_3','spawn_4','spawn_5','spawn_6','spawn_7'}
function Player:resetBlock()--Reset Block's position and execute I*S
local C=self.cur
local sc=C.RS.centerPos[C.id][C.dir]
@@ -1068,7 +1096,6 @@ do--Player.drop(self)--Place piece
local spinVoice={'zspin','sspin','jspin','lspin','tspin','ospin','ispin','zspin','sspin','pspin','qspin','fspin','espin','tspin','uspin','vspin','wspin','xspin','jspin','lspin','rspin','yspin','nspin','hspin','ispin','ispin','cspin','ispin','ospin'}
local clearVoice={'single','double','triple','techrash','pentacrash','hexacrash'}
local spinSFX={[0]='spin_0','spin_1','spin_2'}
local clearSFX={'clear_1','clear_2','clear_3','clear_4','clear_5','clear_6'}
local renSFX={}for i=1,11 do renSFX[i]='ren_'..i end
local finesseList={
{
@@ -1225,7 +1252,10 @@ do--Player.drop(self)--Place piece
end
--Check line clear
cc=cc+self:checkClear(self.field,CY,#CB,CB,CX)
if self.gameEnv.fillClear then
local _cc,_gbcc=self:_checkClear(self.field,CY,#CB,CB,CX)
cc,gbcc=cc+_cc,gbcc+_gbcc
end
--Create clearing FX
for i=1,cc do
@@ -1254,28 +1284,13 @@ do--Player.drop(self)--Place piece
end
--Finesse: roof check
local finesse=CY>ENV.fieldH-2 or self:roofCheck()
local finesse=CY>ENV.fieldH-2 or self:_roofCheck()
--Remove rows need to be cleared
if cc>0 then
for i=cc,1,-1 do
_=self.clearedRow[i]
if self.field[_].garbage then
self.garbageBeneath=self.garbageBeneath-1
gbcc=gbcc+1
end
FREEROW.discard(rem(self.field,_))
FREEROW.discard(rem(self.visTime,_))
end
end
self:_removeClearedLines()
--Cancel top clearing FX
self:removeTopClearingFX()
if self.clearingRow[1]then
self.falling=ENV.fall
else
clear=true
end
--Cancel top clearing FX & get clear flag
clear=self:removeTopClearingFX()
--Finesse check (control)
local finePts
@@ -1516,7 +1531,7 @@ do--Player.drop(self)--Place piece
--SFX & Vibrate
if self.sound then
SFX.play(clearSFX[cc])
playClearSFX(cc)
SFX.play(renSFX[min(cmb,11)],.75)
if cmb>14 then
SFX.play('ren_mega',(cmb-10)*.1)
@@ -1888,24 +1903,11 @@ local function update_alive(P)
P.frameRun=P.frameRun+1
if P.frameRun<=180 then
if P.frameRun==60 then
if P.id==1 then
Snd('bass','F3')
Snd('lead','A4')
Snd('lead','D5')
end
if P.id==1 then playReadySFX(2)end
elseif P.frameRun==120 then
if P.id==1 then
Snd('bass','G3')
Snd('lead','B4')
Snd('lead','E5')
end
if P.id==1 then playReadySFX(1)end
elseif P.frameRun==180 then
if P.id==1 then
Snd('bass','A3')
Snd('lead','A4')
Snd('lead','E5')
Snd('lead','A5')
end
if P.id==1 then playReadySFX(0)end
P.control=true
P.timing=true
P:popNext()
@@ -2293,7 +2295,7 @@ function Player:revive()
SYSFX.newShade(1.4,self.fieldX,self.fieldY,300*self.size,610*self.size)
SYSFX.newRectRipple(2,self.fieldX,self.fieldY,300*self.size,610*self.size)
SYSFX.newRipple(2,self.x+(475+25*(self.life<3 and self.life or 0)+12)*self.size,self.y+(595+12)*self.size,20)
SFX.play('clear_3')
playClearSFX(3)
SFX.play('emit')
end
function Player:win(result)

View File

@@ -799,6 +799,12 @@ local commands={}do
"Usage: tas <on|off>",
},
}
commands.tip={
code=function()
log(text.getTip())
end,
description="Show a random tip",
}
--Network
commands.switchhost={

View File

@@ -134,7 +134,10 @@ function scene.keyDown(key)
MES.new('info',text.copyDone)
return
else
return
if not WIDGET.isFocus(inputBox)then
WIDGET.focus(inputBox)
end
WIDGET.keyPressed(key)
end
end

View File

@@ -12,7 +12,7 @@ local setFont,mStr=FONT.set,GC.mStr
local noTouch,noKey=false,false
local touchMoveLastFrame=false
local trigGameRate,gameRate
local modeTextPos
local modeTextPos,modeTextWidK
local replaying
local repRateStrings={[0]="pause",[.125]="0.125x",[.5]="0.5x",[1]="1x",[2]="2x",[5]="5x"}
@@ -23,10 +23,14 @@ local function _updateMenuButtons()
WIDGET.active.restart.hide=replaying
local pos=(GAME.tasUsed or replaying)and'right'or SETTING.menuPos
if GAME.replaying or pos=='right'then
modeTextWidK=math.min(280/TEXTOBJ.modeName:getWidth(),1)
if GAME.replaying then
WIDGET.active.pause.x=1195
modeTextPos=1185-TEXTOBJ.modeName:getWidth()*modeTextWidK
elseif pos=='right'then
WIDGET.active.restart.x=1125
WIDGET.active.pause.x=1195
modeTextPos=1100-TEXTOBJ.modeName:getWidth()
modeTextPos=1115-TEXTOBJ.modeName:getWidth()*modeTextWidK
elseif pos=='middle'then
WIDGET.active.restart.x=360
WIDGET.active.pause.x=860
@@ -34,7 +38,7 @@ local function _updateMenuButtons()
elseif pos=='left'then
WIDGET.active.restart.x=120
WIDGET.active.pause.x=190
modeTextPos=1200-TEXTOBJ.modeName:getWidth()
modeTextPos=1200-TEXTOBJ.modeName:getWidth()*modeTextWidK
end
end
local function _updateRepButtons()
@@ -357,7 +361,7 @@ function scene.draw()
--Mode info
gc_setColor(1,1,1,.82)
gc_draw(TEXTOBJ.modeName,modeTextPos,10)
gc_draw(TEXTOBJ.modeName,modeTextPos,10,0,modeTextWidK,1)
local M=GAME.curMode
if M and M.score and M.records[1]then
setFont(15)

View File

@@ -37,8 +37,22 @@ pad={x=140,y=65,page=1,
{0,0,0,0,0,0,0,0},
},
{
{{}, {}, {}, {}, {sfx='move'}, {sfx='lock'}, {sfx='drop'}, {sfx='fall'},},
{{sfx='hold'}, {sfx='prehold'}, {}, {}, {sfx='clear_1'},{sfx='clear_2'},{sfx='clear_3'},{sfx='clear_4'}},
{
{samp={tag='ready3',func=function()playReadySFX(3)end}},
{samp={tag='ready2',func=function()playReadySFX(2)end}},
{samp={tag='ready1',func=function()playReadySFX(1)end}},
{samp={tag='start',func=function()playReadySFX(0)end}},
{sfx='move'},{sfx='lock'},{sfx='drop'},{sfx='fall'},
},
{
{sfx='hold'},{sfx='prehold'},
{samp={tag='clear_1',func=function()playClearSFX(1)end}},
{samp={tag='clear_2',func=function()playClearSFX(2)end}},
{samp={tag='clear_3',func=function()playClearSFX(3)end}},
{samp={tag='clear_4',func=function()playClearSFX(4)end}},
{samp={tag='clear_5',func=function()playClearSFX(5)end}},
{samp={tag='clear_6',func=function()playClearSFX(6)end}},
},
{{sfx='prerotate'}, {sfx='rotate'}, {sfx='rotatekick'}, {}, {voc='single'}, {voc='double'}, {voc='triple'}, {voc='techrash'}},
{{sfx='finesseError'},{sfx='finesseError_long'},{sfx='drop_cancel'},{}, {sfx='spin_0'}, {sfx='spin_1'}, {sfx='spin_2'}, {sfx='spin_3'}},
{{sfx='ren_1'}, {sfx='ren_2'}, {sfx='ren_3'}, {sfx='ren_4'}, {}, {sfx='warning'},{sfx='reach'}, {sfx='pc'}},
@@ -57,8 +71,22 @@ pad={x=140,y=65,page=1,
{{}, {}, {}, {}, {}, {}, {}, {}},
},
{
{{}, {}, {}, {}, {sfx='move'}, {sfx='lock'}, {sfx='drop'}, {sfx='fall'},},
{{sfx='hold'}, {sfx='prehold'},{}, {}, {sfx='clear_1'}, {sfx='clear_2'}, {sfx='clear_3'}, {sfx='clear_4'},},
{
{samp={tag='ready3',func=function()playReadySFX(3)end}},
{samp={tag='ready2',func=function()playReadySFX(2)end}},
{samp={tag='ready1',func=function()playReadySFX(1)end}},
{samp={tag='start',func=function()playReadySFX(0)end}},
{sfx='move'},{sfx='lock'},{sfx='drop'},{sfx='fall'},
},
{
{sfx='hold'},{sfx='prehold'},
{samp={tag='clear_1',func=function()playClearSFX(1)end}},
{samp={tag='clear_2',func=function()playClearSFX(2)end}},
{samp={tag='clear_3',func=function()playClearSFX(3)end}},
{samp={tag='clear_4',func=function()playClearSFX(4)end}},
{samp={tag='clear_5',func=function()playClearSFX(5)end}},
{samp={tag='clear_6',func=function()playClearSFX(6)end}},
},
{{voc='mini'}, {voc='b2b'}, {voc='b3b'}, {voc='perfect_clear'}, {voc='half_clear'}, {sfx='finesseError'}, {sfx='finesseError_long'}, {sfx='drop_cancel'},},
{{voc='zspin'}, {voc='sspin'}, {voc='jspin'}, {voc='lspin'}, {voc='tspin'}, {voc='ospin'}, {voc='ispin'}, {}},
{{voc='single'}, {voc='double'}, {voc='triple'},{voc='techrash'}, {sfx='ren_mega', vol=0.25},{sfx='ren_mega', vol=0.5},{sfx='ren_mega', vol=0.75},{sfx='ren_mega'}},
@@ -67,9 +95,34 @@ pad={x=140,y=65,page=1,
{{sfx='ren_9'}, {sfx='ren_10'}, {sfx='ren_11'},{sfx='ren_mega'}, {voc='win'}, {voc='lose'}, {sfx='win'}, {sfx='fail'}},
},
{
{{},{},{},{},{},{},{},{}},
{{},{},{},{},{},{},{},{}},
{{},{},{},{},{},{},{},{}},
{
{samp={tag='clear_1',func=function()playClearSFX(1)end}},
{samp={tag='clear_2',func=function()playClearSFX(2)end}},
{samp={tag='clear_3',func=function()playClearSFX(3)end}},
{samp={tag='clear_4',func=function()playClearSFX(4)end}},
{samp={tag='clear_5',func=function()playClearSFX(5)end}},
{samp={tag='clear_6',func=function()playClearSFX(6)end}},
{samp={tag='clear_7',func=function()playClearSFX(7)end}},
{samp={tag='clear_8',func=function()playClearSFX(8)end}},
},
{
{samp={tag='clear_9',func=function()playClearSFX(9)end}},
{samp={tag='clear_10',func=function()playClearSFX(10)end}},
{samp={tag='clear_11',func=function()playClearSFX(11)end}},
{samp={tag='clear_12',func=function()playClearSFX(12)end}},
{samp={tag='clear_13',func=function()playClearSFX(13)end}},
{samp={tag='clear_14',func=function()playClearSFX(14)end}},
{samp={tag='clear_15',func=function()playClearSFX(15)end}},
{samp={tag='clear_16',func=function()playClearSFX(16)end}},
},
{
{samp={tag='clear_17',func=function()playClearSFX(17)end}},
{samp={tag='clear_18',func=function()playClearSFX(18)end}},
{samp={tag='clear_19',func=function()playClearSFX(19)end}},
{samp={tag='clear_20',func=function()playClearSFX(20)end}},
{samp={tag='clear_20+',func=function()playClearSFX(21)end}},
{},{},{}
},
{{},{},{},{},{},{},{},{}},
{{},{},{},{},{},{},{},{}},
{{},{},{},{},{},{},{},{}},
@@ -108,6 +161,7 @@ local function press(x,y)
pad.funcAlpha[y]=1
else
local k=pad[pad.page][y][x]
if k.samp then k.samp.func()end
if k.sfx then SFX.play(k.sfx,k.vol)end
if k.voc then VOC.play(k.voc)end
if k.bgm then BGM.play(k.bgm)end
@@ -201,10 +255,12 @@ function scene.draw()
if showLabel then
if k.sfx then mStr(k.sfx,x*80+40,y*80-30)gc_circle('fill',x*80+40,(y-1)*80+40,6)end
if k.voc then mStr(k.voc,x*80+40,y*80-17)gc_rectangle('line',x*80+30,(y-1)*80+30,20,20,1)end
if k.samp then mStr(k.samp.tag,x*80+40,y*80-30)gc_rectangle('fill',x*80+10,(y-1)*80+35,60,5,1)end
if k.bgm then mStr(k.bgm,x*80+40,y*80-78)gc_rectangle('fill',x*80+20,(y-1)*80+15,40,5,2)end
else
if k.sfx then gc_circle('fill',x*80+40,(y-1)*80+40,6)end
if k.voc then gc_rectangle('line',x*80+30,(y-1)*80+30,20,20,1)end
if k.samp then gc_rectangle('fill',x*80+10,(y-1)*80+35,60,5,1)end
if k.bgm then gc_rectangle('fill',x*80+20,(y-1)*80+15,40,5,2)end
end
if pad.alpha[y][x]>0 then

View File

@@ -23,9 +23,9 @@ local loadingThread=coroutine.wrap(function()
end
YIELD()
YIELD('loadSFX')SFX.load('media/effect/'..SETTING.sfxPack..'/')
YIELD('loadSample')SFX.loadSample{name='bass',path='media/sample/bass',base='A2'}
YIELD('loadSample')SFX.loadSample{name='lead',path='media/sample/lead',base='A3'}
YIELD('loadSample')SFX.loadSample{name='bell',path='media/sample/bell',base='A4'}
YIELD('loadSample')SFX.loadSample{name='bass',path='media/sample/bass',base='A2'}--A2~A4
YIELD('loadSample')SFX.loadSample{name='lead',path='media/sample/lead',base='A3'}--A3~A5
YIELD('loadSample')SFX.loadSample{name='bell',path='media/sample/bell',base='A4'}--A4~A6
YIELD('loadVoice')VOC.load('media/vocal/'..SETTING.vocPack..'/')
YIELD('loadFont')for i=1,17 do getFont(15+5*i)end

View File

@@ -14,10 +14,10 @@ local widgetX0={
}
local enterConsole=coroutine.wrap(function()
while true do
Snd('bell',.3,'A4',.5,'E5',1,coin('A5','B5'))YIELD()
Snd('bell',.3,'A4',.5,'F5',1,coin('C6','D6'))YIELD()
Snd('bell',.3,'A4',.5,'G5',1,coin('E6','G6'))YIELD()
Snd('bell',.3,'A4',.5,'A5',1,'A6')SFX.play('ren_mega')SCN.go('app_console')YIELD()
Snd('bell',.6,'A4',.7,'E5',1,coin('A5','B5'))YIELD()
Snd('bell',.6,'A4',.7,'F5',1,coin('C6','D6'))YIELD()
Snd('bell',.6,'A4',.7,'G5',1,coin('E6','G6'))YIELD()
Snd('bell',.6,'A4',.7,'A5',1,'A6')SFX.play('ren_mega')SCN.go('app_console')YIELD()
end
end)
function scene.sceneInit()

View File

@@ -7,21 +7,24 @@ return[=[
其他未来内容:
组队战; 实时统计数据可视化; 教学关; 从录像继续
重做模式选择UI; 重做模组UI; 加速下落; spike相关统计数据
更好的手柄支持; 场地格边缘线; 模式数据分析; 高级自定义序列
支持更多手柄; 场地格边缘线; 模式数据分析; 高级自定义序列
等级系统; 成就系统; Domain状态; 手势操作; C2连击; 特殊控件(虚拟摇杆等)
可调场地宽度; 可调攻击系统; 更多消除方式(隔断/架空/混合/彩色/穿墙)
方块位移/旋转动画; 更细节的DAS选项; 拓展主题系统; 复杂的攻击系统
方块位移/旋转动画; 更细节的DAS选项; 拓展主题系统; 无用货币
可调攻击系统; 更多消除方式; 可调场地宽度
工程编译到字节码; task-Z(新AI)
无用货币; 收集向抽奖; 自适应UI; 多方块
收集向抽奖; 自适应UI; 多方块
0.16.3: 虫洞 Wormhole
0.16.4: 虫洞 Wormhole
新增:
新连击音效
新准备&开始音效
Next槽上方显示序列模式标记
等级图标(暂时不能升级)
词典支持复制词条方便发给别人
修改堆叠模式玩法(自动清除之前记录)
添加消7~20和20+的消除文本与消除音效
改动:
修改TRS的JL踢墙表的0-R和R-0最后几项(可能会导致部分录像无法正常播放)
移除组合键切换攻击模式功能,固定为单点切换
iOS设备支持三档振动(原来只有一档)
微调TRS的R/Y块踢墙表
@@ -33,8 +36,7 @@ return[=[
计算器可以弹琴了
词典添加一些词条
控制台可以查看日志
暂时取消导入存档的版本限制(过早存档请不要导入!前两三个版本的不会有问题)
修改TRS的JL踢墙表的0-R和R-0最后几项(可能会导致部分录像无法正常播放)
暂时取消导入存档的版本限制(过早存档请不要导入!只能保证近两三个版本一定能用)
代码:
SFX模块大升级,支持播放乐器采样
整理大量代码
@@ -43,6 +45,7 @@ return[=[
生成AI玩家时没刷新20G开关
小程序uttt和calc的问题
"就这"语言的词典是英文
游戏场景ui微调
miku语音小修正
0.16.2: 曲率引擎 Warp drive

View File

@@ -1,7 +1,7 @@
return{
["apkCode"]=387,
["code"]=1603,
["string"]="V0.16.3@DEV",
["apkCode"]=390,
["code"]=1604,
["string"]="V0.16.4",
["room"]="ver A-0",
["name"]="虫洞 Wormhole",
}