Compare commits
199 Commits
pre0.16.4-
...
pre0.17.0-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55a1bd06f3 | ||
|
|
6a29abf7f0 | ||
|
|
83bdd9f2c4 | ||
|
|
95879827c8 | ||
|
|
2ade518207 | ||
|
|
36c8449e4d | ||
|
|
3c04df69f3 | ||
|
|
1224ee9a67 | ||
|
|
fdd1d4463a | ||
|
|
940ac3736c | ||
|
|
d38897b54d | ||
|
|
90848c6654 | ||
|
|
0220d5aefc | ||
|
|
f42032df07 | ||
|
|
05d7eb60bc | ||
|
|
942416317c | ||
|
|
576de945fb | ||
|
|
8b02084428 | ||
|
|
9f666d69db | ||
|
|
a4c52d9162 | ||
|
|
592b11366e | ||
|
|
07f50b9243 | ||
|
|
ec74d55686 | ||
|
|
4518513e87 | ||
|
|
7df4e2144f | ||
|
|
7f9c9248ce | ||
|
|
9c1db48804 | ||
|
|
0628830f0c | ||
|
|
9436f2f5fb | ||
|
|
c5e1b5617f | ||
|
|
298c417aa3 | ||
|
|
fc74831700 | ||
|
|
d9db55de44 | ||
|
|
3fd205e8c2 | ||
|
|
5cb828fb92 | ||
|
|
5f7a3fd53f | ||
|
|
8e3e598753 | ||
|
|
2a0a0f60f8 | ||
|
|
6b7d1fdf9f | ||
|
|
65199a40f7 | ||
|
|
f9082a8800 | ||
|
|
1670c6e7d6 | ||
|
|
ff2073ed4d | ||
|
|
f14aaac635 | ||
|
|
c709fa622f | ||
|
|
c752556bf3 | ||
|
|
e7d9703fcc | ||
|
|
1ed52a84b0 | ||
|
|
4fdb278751 | ||
|
|
8318803923 | ||
|
|
42de7e3676 | ||
|
|
3efa646ee3 | ||
|
|
b414c2ab42 | ||
|
|
205dea3db7 | ||
|
|
6cac688555 | ||
|
|
09b1b08c1e | ||
|
|
b61a1270e9 | ||
|
|
b85cee7e1f | ||
|
|
8e674e3e29 | ||
|
|
aa2812c874 | ||
|
|
6f282431c4 | ||
|
|
470e54cdd0 | ||
|
|
da3ef1c2a6 | ||
|
|
9efe0e62d5 | ||
|
|
7038f81b46 | ||
|
|
de972a60df | ||
|
|
6a87787d6f | ||
|
|
6dc9a4b507 | ||
|
|
5b7c888d57 | ||
|
|
a1f761b83e | ||
|
|
c40a6bfaa0 | ||
|
|
441c6f7667 | ||
|
|
a07d57cf71 | ||
|
|
a467f972f9 | ||
|
|
3f455ee360 | ||
|
|
7a0b913768 | ||
|
|
a7b240ade8 | ||
|
|
bb64404821 | ||
|
|
caf92eb3c8 | ||
|
|
6a117a0fab | ||
|
|
26682509f7 | ||
|
|
d85d92fb43 | ||
|
|
c412003cb3 | ||
|
|
e39b5dbd51 | ||
|
|
db162ea66f | ||
|
|
f9f9fde368 | ||
|
|
4b221c2eb5 | ||
|
|
ed45bebfa0 | ||
|
|
fa0bc3805f | ||
|
|
7710f0b70f | ||
|
|
0277ddadb5 | ||
|
|
88e23e32f5 | ||
|
|
8ab5b4a17a | ||
|
|
503dfd69ef | ||
|
|
ae61ec26c0 | ||
|
|
00bc24bd50 | ||
|
|
abd15d6307 | ||
|
|
c01ac546d1 | ||
|
|
af77221ba2 | ||
|
|
204f0938d3 | ||
|
|
ad39d1408c | ||
|
|
ed011173f6 | ||
|
|
491fcb5860 | ||
|
|
c2d5537d8d | ||
|
|
7d5037ae87 | ||
|
|
07d7714317 | ||
|
|
2cab97f37d | ||
|
|
d184778c9a | ||
|
|
9fd3b3008d | ||
|
|
71aa35b214 | ||
|
|
4443dc9d3e | ||
|
|
839e357301 | ||
|
|
ac56c5a415 | ||
|
|
36e3343341 | ||
|
|
510f7d7513 | ||
|
|
3128eb38c0 | ||
|
|
14ef654612 | ||
|
|
bc5193f95e | ||
|
|
8cbb4a38bc | ||
|
|
fce08c83ef | ||
|
|
018e99f9e6 | ||
|
|
7fe390b34b | ||
|
|
8c7202c569 | ||
|
|
ab386bb53c | ||
|
|
87c791b8c7 | ||
|
|
00e3e2d19d | ||
|
|
8d7d5c7b04 | ||
|
|
849a18e159 | ||
|
|
a4357d0843 | ||
|
|
e2b4a78b59 | ||
|
|
01387b5488 | ||
|
|
168e2f80b8 | ||
|
|
4f79ef8708 | ||
|
|
16497833df | ||
|
|
cd6a50d5a0 | ||
|
|
4c5a61f2d8 | ||
|
|
1fd8d39970 | ||
|
|
d133d64890 | ||
|
|
b27aa8b60d | ||
|
|
230d67492e | ||
|
|
4f9d5b282c | ||
|
|
a2955e8722 | ||
|
|
df892671d5 | ||
|
|
7fa96eee1a | ||
|
|
a1030906c7 | ||
|
|
e6a9a4f4be | ||
|
|
efa1247596 | ||
|
|
069fcee721 | ||
|
|
66621404f1 | ||
|
|
e09609ea21 | ||
|
|
d02ae67bc0 | ||
|
|
27327d57c4 | ||
|
|
cce93b6df9 | ||
|
|
546104ba5b | ||
|
|
ca5816ba14 | ||
|
|
e5bd16476e | ||
|
|
94431d4c2e | ||
|
|
f98d6892f1 | ||
|
|
1fe436cbe3 | ||
|
|
c5a37a9920 | ||
|
|
eed7e96096 | ||
|
|
a7f36a4162 | ||
|
|
8ba872d45d | ||
|
|
7a55451faa | ||
|
|
372571bd80 | ||
|
|
77120c0b90 | ||
|
|
01d1e44644 | ||
|
|
0ad8cddefe | ||
|
|
ce67253502 | ||
|
|
cb9f2c0617 | ||
|
|
635d9407ed | ||
|
|
0f9f6565f1 | ||
|
|
a45b6ad57e | ||
|
|
a5de06dedb | ||
|
|
fbfbd1ed98 | ||
|
|
8f06b3bd1a | ||
|
|
7e0dbceefc | ||
|
|
7e3db1de17 | ||
|
|
111790fdab | ||
|
|
bec03de7b8 | ||
|
|
f5dfae3a6c | ||
|
|
d3dec2b5f1 | ||
|
|
f083136998 | ||
|
|
cd3d0b370c | ||
|
|
f4c6632941 | ||
|
|
750cb9a669 | ||
|
|
62a198a017 | ||
|
|
5780ba0f3e | ||
|
|
86edeb1e0c | ||
|
|
53b1852f28 | ||
|
|
e3c385693b | ||
|
|
572c0fbfa1 | ||
|
|
bbdf71167a | ||
|
|
2136ccd9a2 | ||
|
|
2131aea575 | ||
|
|
32b21c7d29 | ||
|
|
8f6f6f316f | ||
|
|
66f9ac2791 | ||
|
|
ac0ba90438 |
7
.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE_1.md
vendored
7
.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE_1.md
vendored
@@ -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*)
|
||||
7
.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE_2.md
vendored
7
.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE_2.md
vendored
@@ -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*):
|
||||
|
||||
2
.github/actions/build-linux/action.yml
vendored
2
.github/actions/build-linux/action.yml
vendored
@@ -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
|
||||
|
||||
2
.github/actions/build-love/action.yml
vendored
2
.github/actions/build-love/action.yml
vendored
@@ -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
|
||||
|
||||
BIN
.github/build/macOS/backgroundImage.tiff
vendored
BIN
.github/build/macOS/backgroundImage.tiff
vendored
Binary file not shown.
45
.github/workflows/dev.yml
vendored
45
.github/workflows/dev.yml
vendored
@@ -97,6 +97,34 @@ jobs:
|
||||
with:
|
||||
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_Android
|
||||
path: Techmino_Snapshot.apk
|
||||
|
||||
build-android-mini:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
with:
|
||||
commit: ${{ needs.get-info.outputs.commit }}
|
||||
type: snapshot
|
||||
- name: remove media
|
||||
run: |
|
||||
rm -rf media/music media/effect media/vocal
|
||||
- uses: ./.github/actions/build-android
|
||||
with:
|
||||
type: Snapshot
|
||||
apkCode: ${{ needs.get-info.outputs.apkCode }}
|
||||
name: ${{ needs.get-info.outputs.name }}
|
||||
file-path: Techmino_Snapshot_Mini.apk
|
||||
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
||||
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||
ALIAS: ${{ secrets.ALIAS }}
|
||||
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Techmino_${{ needs.get-info.outputs.name }}_${{ GITHUB.RUN_NUMBER }}_${{ needs.get-info.outputs.commit }}_Android_Mini
|
||||
path: Techmino_Snapshot_Mini.apk
|
||||
|
||||
build-macOS:
|
||||
runs-on: macos-10.15
|
||||
@@ -157,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
|
||||
|
||||
316
.github/workflows/release.yml
vendored
316
.github/workflows/release.yml
vendored
@@ -3,7 +3,7 @@ name: Techmino Release CI
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
- "v*"
|
||||
|
||||
jobs:
|
||||
get-info:
|
||||
@@ -14,218 +14,176 @@ jobs:
|
||||
code: ${{ steps.actual-get-info.outputs.code }}
|
||||
release: ${{ steps.actual-get-info.outputs.release }}
|
||||
updateTitle: ${{ steps.actual-get-info.outputs.updateTitle }}
|
||||
updateNote: ${{ steps.actual-get-info.outputs.updateNote }}
|
||||
commit: ${{ steps.actual-get-info.outputs.commit }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install lua
|
||||
run: |
|
||||
sudo apt-get install lua5.3 -y
|
||||
- name: Get Version
|
||||
id: actual-get-info
|
||||
run: |
|
||||
echo "::set-output name=name::$(lua .github/workflows/getVersion.lua -name)"
|
||||
echo "::set-output name=apkCode::$(lua .github/workflows/getVersion.lua -apkCode)"
|
||||
echo "::set-output name=code::$(lua .github/workflows/getVersion.lua -code)"
|
||||
echo "::set-output name=release::$(lua .github/workflows/getVersion.lua -release)"
|
||||
echo "::set-output name=updateTitle::$(lua .github/workflows/getVersion.lua -updateTitle)"
|
||||
echo "::set-output name=commit::$(git rev-parse --short ${{ GITHUB.SHA }})"
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install lua
|
||||
run: |
|
||||
sudo apt-get install lua5.3 -y
|
||||
- name: Get Version
|
||||
id: actual-get-info
|
||||
run: |
|
||||
UPDATE_NOTE=$(lua .github/workflows/getVersion.lua -updateNote)
|
||||
UPDATE_NOTE="${UPDATE_NOTE//'%'/'%25'}"
|
||||
UPDATE_NOTE="${UPDATE_NOTE//$'\n'/'%0A'}"
|
||||
UPDATE_NOTE="${UPDATE_NOTE//$'\r'/'%0D'}"
|
||||
echo "::set-output name=name::$(lua .github/workflows/getVersion.lua -name)"
|
||||
echo "::set-output name=apkCode::$(lua .github/workflows/getVersion.lua -apkCode)"
|
||||
echo "::set-output name=code::$(lua .github/workflows/getVersion.lua -code)"
|
||||
echo "::set-output name=release::$(lua .github/workflows/getVersion.lua -release)"
|
||||
echo "::set-output name=updateTitle::$(lua .github/workflows/getVersion.lua -updateTitle)"
|
||||
echo "::set-output name=updateNote::$UPDATE_NOTE"
|
||||
echo "::set-output name=commit::$(git rev-parse --short ${{ GITHUB.SHA }})"
|
||||
|
||||
build-windows-x64:
|
||||
runs-on: windows-latest
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
- uses: ./.github/actions/build-windows
|
||||
with:
|
||||
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win64.zip
|
||||
love-dir: love-11.3-win64
|
||||
arch: win64
|
||||
version: ${{ needs.get-info.outputs.release }}
|
||||
icon: .\.github\build\Windows\icon.ico
|
||||
- name: Pack Techmino
|
||||
run: 7z a -tzip .\Techmino.a${{ needs.get-info.outputs.release }}.Win64.zip .\love
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
files: Techmino.a${{ needs.get-info.outputs.release }}.Win64.zip
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
- uses: ./.github/actions/build-windows
|
||||
with:
|
||||
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win64.zip
|
||||
love-dir: love-11.3-win64
|
||||
arch: win64
|
||||
version: ${{ needs.get-info.outputs.release }}
|
||||
icon: .\.github\build\Windows\icon.ico
|
||||
- name: Pack Techmino
|
||||
run: 7z a -tzip .\Techmino_a${{ needs.get-info.outputs.release }}_Win64.zip .\love
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
files: Techmino_a${{ needs.get-info.outputs.release }}_Win64.zip
|
||||
|
||||
build-windows-x86:
|
||||
runs-on: windows-latest
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
- uses: ./.github/actions/build-windows
|
||||
with:
|
||||
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win32.zip
|
||||
love-dir: love-11.3-win32
|
||||
arch: win32
|
||||
version: ${{ needs.get-info.outputs.release }}
|
||||
icon: .\.github\build\Windows\icon.ico
|
||||
- name: Pack Techmino
|
||||
run: 7z a -tzip .\Techmino.a${{ needs.get-info.outputs.release }}.Win32.zip .\love
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
files: Techmino.a${{ needs.get-info.outputs.release }}.Win32.zip
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
- uses: ./.github/actions/build-windows
|
||||
with:
|
||||
love-url: https://github.com/love2d/love/releases/download/11.3/love-11.3-win32.zip
|
||||
love-dir: love-11.3-win32
|
||||
arch: win32
|
||||
version: ${{ needs.get-info.outputs.release }}
|
||||
icon: .\.github\build\Windows\icon.ico
|
||||
- name: Pack Techmino
|
||||
run: 7z a -tzip .\Techmino_a${{ needs.get-info.outputs.release }}_Win32.zip .\love
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
files: Techmino_a${{ needs.get-info.outputs.release }}_Win32.zip
|
||||
|
||||
build-linux:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
- uses: ./.github/actions/build-linux
|
||||
with:
|
||||
file-path: Techmino.a${{ needs.get-info.outputs.release }}.AppImage
|
||||
icon: .github/build/Linux/icon.png
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
files: Techmino.a${{ needs.get-info.outputs.release }}.AppImage
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
- uses: ./.github/actions/build-linux
|
||||
with:
|
||||
file-path: Techmino_a${{ needs.get-info.outputs.release }}_Linux.AppImage
|
||||
icon: .github/build/Linux/icon.png
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
files: Techmino_a${{ needs.get-info.outputs.release }}_Linux.AppImage
|
||||
|
||||
build-android:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
- uses: ./.github/actions/build-android
|
||||
with:
|
||||
type: Release
|
||||
apkCode: ${{ needs.get-info.outputs.apkCode }}
|
||||
name: ${{ needs.get-info.outputs.name }}
|
||||
file-path: Techmino.a${{ needs.get-info.outputs.release }}.apk
|
||||
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
||||
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||
ALIAS: ${{ secrets.ALIAS }}
|
||||
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
files: Techmino.a${{ needs.get-info.outputs.release }}.apk
|
||||
|
||||
build-android-mini:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
- name: remove media
|
||||
run: |
|
||||
rm -rf media/music media/effect media/vocal
|
||||
- uses: ./.github/actions/build-android
|
||||
with:
|
||||
type: Release
|
||||
apkCode: ${{ needs.get-info.outputs.apkCode }}
|
||||
name: ${{ needs.get-info.outputs.name }}
|
||||
file-path: Techmino.a${{ needs.get-info.outputs.release }}.mini.apk
|
||||
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
||||
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||
ALIAS: ${{ secrets.ALIAS }}
|
||||
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
files: Techmino.a${{ needs.get-info.outputs.release }}.mini.apk
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
- uses: ./.github/actions/build-android
|
||||
with:
|
||||
type: Release
|
||||
apkCode: ${{ needs.get-info.outputs.apkCode }}
|
||||
name: ${{ needs.get-info.outputs.name }}
|
||||
file-path: Techmino_a${{ needs.get-info.outputs.release }}_Android.apk
|
||||
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
||||
KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||
ALIAS: ${{ secrets.ALIAS }}
|
||||
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
files: Techmino_a${{ needs.get-info.outputs.release }}_Android.apk
|
||||
|
||||
build-macOS:
|
||||
runs-on: macos-10.15
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
- uses: ./.github/actions/build-macos
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.name }}
|
||||
icon: .github/build/macOS/icon.icns
|
||||
APPLE_API_ID: '${{ secrets.APPLE_API_ID }}'
|
||||
APPLE_API_ISSUER: '${{ secrets.APPLE_API_ISSUER }}'
|
||||
APPLE_API_KEY: '${{ secrets.APPLE_API_KEY }}'
|
||||
APPLE_APP_IDENTIFIER: '${{ secrets.APPLE_APP_IDENTIFIER }}'
|
||||
APPLE_KEYCHAIN_NAME: '${{ secrets.APPLE_KEYCHAIN_NAME }}'
|
||||
APPLE_KEYCHAIN_PWD: '${{ secrets.APPLE_KEYCHAIN_PWD }}'
|
||||
FASTLANE_MATCH_PWD: '${{ secrets.FASTLANE_MATCH_PWD }}'
|
||||
FASTLANE_MATCH_TOKEN: '${{ secrets.FASTLANE_MATCH_TOKEN }}'
|
||||
- name: Pack Techmino
|
||||
run: |
|
||||
mv Techmino.dmg Techmino.a${{ needs.get-info.outputs.release }}.macOS.dmg
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
files: Techmino.a${{ needs.get-info.outputs.release }}.macOS.zip
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
- uses: ./.github/actions/build-macos
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.name }}
|
||||
icon: .github/build/macOS/icon.icns
|
||||
APPLE_API_ID: "${{ secrets.APPLE_API_ID }}"
|
||||
APPLE_API_ISSUER: "${{ secrets.APPLE_API_ISSUER }}"
|
||||
APPLE_API_KEY: "${{ secrets.APPLE_API_KEY }}"
|
||||
APPLE_APP_IDENTIFIER: "${{ secrets.APPLE_APP_IDENTIFIER }}"
|
||||
APPLE_KEYCHAIN_NAME: "${{ secrets.APPLE_KEYCHAIN_NAME }}"
|
||||
APPLE_KEYCHAIN_PWD: "${{ secrets.APPLE_KEYCHAIN_PWD }}"
|
||||
FASTLANE_MATCH_PWD: "${{ secrets.FASTLANE_MATCH_PWD }}"
|
||||
FASTLANE_MATCH_TOKEN: "${{ secrets.FASTLANE_MATCH_TOKEN }}"
|
||||
- name: Pack Techmino
|
||||
run: |
|
||||
mv Techmino.dmg Techmino_a${{ needs.get-info.outputs.release }}_MacOS.dmg
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
files: Techmino_a${{ needs.get-info.outputs.release }}_MacOS.dmg
|
||||
|
||||
build-iOS:
|
||||
runs-on: macos-latest
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
- uses: ./.github/actions/build-ios
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.name }}
|
||||
type: 'release'
|
||||
APPLE_API_ID: '${{ secrets.APPLE_API_ID }}'
|
||||
APPLE_API_ISSUER: '${{ secrets.APPLE_API_ISSUER }}'
|
||||
APPLE_API_KEY: '${{ secrets.APPLE_API_KEY }}'
|
||||
APPLE_APP_BUILD: '${{ needs.get-info.outputs.code }}.0.${{ github.run_number }}.${{ github.run_attempt }}'
|
||||
APPLE_APP_CHANGELOG: '${{ github.event.commits[0].message }}'
|
||||
APPLE_APP_ID: '${{ secrets.APPLE_APP_ID }}'
|
||||
APPLE_APP_IDENTIFIER: '${{ secrets.APPLE_APP_IDENTIFIER }}'
|
||||
APPLE_APP_PROFILE: '${{ secrets.APPLE_APP_PROFILE }}'
|
||||
APPLE_KEYCHAIN_NAME: '${{ secrets.APPLE_KEYCHAIN_NAME }}'
|
||||
APPLE_KEYCHAIN_PWD: '${{ secrets.APPLE_KEYCHAIN_PWD }}'
|
||||
FASTLANE_ACTION_ID: '${{ github.run_id }}'
|
||||
FASTLANE_DISCORD_WEBHOOK: '${{ secrets.FASTLANE_DISCORD_WEBHOOK }}'
|
||||
FASTLANE_MATCH_PWD: '${{ secrets.FASTLANE_MATCH_PWD }}'
|
||||
FASTLANE_MATCH_TOKEN: '${{ secrets.FASTLANE_MATCH_TOKEN }}'
|
||||
- name: Rename ipa
|
||||
shell: bash
|
||||
run: |
|
||||
mv Techmino.ipa Techmino.a${{ needs.get-info.outputs.release }}.ipa
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
files: Techmino.a${{ needs.get-info.outputs.release }}.ipa
|
||||
|
||||
build-love:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
- uses: ./.github/actions/build-love
|
||||
with:
|
||||
file-path: Techmino.a${{ needs.get-info.outputs.release }}.love
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
files: Techmino.a${{ needs.get-info.outputs.release }}.love
|
||||
- uses: actions/checkout@v2
|
||||
- uses: ./.github/actions/update-version
|
||||
- uses: ./.github/actions/build-ios
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.name }}
|
||||
type: "release"
|
||||
APPLE_API_ID: "${{ secrets.APPLE_API_ID }}"
|
||||
APPLE_API_ISSUER: "${{ secrets.APPLE_API_ISSUER }}"
|
||||
APPLE_API_KEY: "${{ secrets.APPLE_API_KEY }}"
|
||||
APPLE_APP_BUILD: "${{ needs.get-info.outputs.code }}.0.${{ github.run_number }}.${{ github.run_attempt }}"
|
||||
APPLE_APP_CHANGELOG: "${{ needs.get-info.outputs.updateNote }}"
|
||||
APPLE_APP_ID: "${{ secrets.APPLE_APP_ID }}"
|
||||
APPLE_APP_IDENTIFIER: "${{ secrets.APPLE_APP_IDENTIFIER }}"
|
||||
APPLE_APP_PROFILE: "${{ secrets.APPLE_APP_PROFILE }}"
|
||||
APPLE_KEYCHAIN_NAME: "${{ secrets.APPLE_KEYCHAIN_NAME }}"
|
||||
APPLE_KEYCHAIN_PWD: "${{ secrets.APPLE_KEYCHAIN_PWD }}"
|
||||
FASTLANE_ACTION_ID: "${{ github.run_id }}"
|
||||
FASTLANE_DISCORD_WEBHOOK: "${{ secrets.FASTLANE_DISCORD_WEBHOOK }}"
|
||||
FASTLANE_MATCH_PWD: "${{ secrets.FASTLANE_MATCH_PWD }}"
|
||||
FASTLANE_MATCH_TOKEN: "${{ secrets.FASTLANE_MATCH_TOKEN }}"
|
||||
- name: Rename ipa
|
||||
shell: bash
|
||||
run: |
|
||||
mv Techmino.ipa Techmino_a${{ needs.get-info.outputs.release }}_iOS.ipa
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
files: Techmino_a${{ needs.get-info.outputs.release }}_iOS.ipa
|
||||
|
||||
Add-Release-note:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install lua
|
||||
run: |
|
||||
sudo apt-get update -y
|
||||
sudo apt-get upgrade -y
|
||||
sudo apt-get install lua5.3 -y
|
||||
- name: Get ReleaseNote
|
||||
run: |
|
||||
lua .github/workflows/getVersion.lua -updateNote > updateNote.txt
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
body_path: updateNote.txt
|
||||
- uses: actions/checkout@v2
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.updateTitle }}
|
||||
body: ${{ needs.get-info.outputs.updateNote }}
|
||||
|
||||
14
.github/workflows/test.yml
vendored
14
.github/workflows/test.yml
vendored
@@ -47,9 +47,9 @@ jobs:
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Techmino.pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}.Windows
|
||||
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Windows
|
||||
path: love
|
||||
|
||||
|
||||
build-linux:
|
||||
runs-on: ubuntu-20.04
|
||||
needs: get-info
|
||||
@@ -65,7 +65,7 @@ jobs:
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Techmino.pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}.Linux
|
||||
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Linux
|
||||
path: Techmino.AppImage
|
||||
|
||||
build-android:
|
||||
@@ -90,7 +90,7 @@ jobs:
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Techmino.pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}.Android
|
||||
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_Android
|
||||
path: Techmino_Snapshot.apk
|
||||
|
||||
build-macOS:
|
||||
@@ -117,7 +117,7 @@ jobs:
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Techmino.pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}.macOS
|
||||
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_MacOS
|
||||
path: Techmino.dmg
|
||||
|
||||
build-iOS:
|
||||
@@ -150,5 +150,5 @@ jobs:
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Techmino.pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}.iOS
|
||||
path: "Techmino.ipa"
|
||||
name: Techmino_pre${{ needs.get-info.outputs.release }}_${{ needs.get-info.outputs.commit }}_iOS
|
||||
path: Techmino.ipa
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
local Sources={}
|
||||
local lastLoaded={}
|
||||
local maxLoadedCount=3
|
||||
local SourceObjList={}
|
||||
local volume=1
|
||||
|
||||
local BGM={
|
||||
@@ -37,15 +39,41 @@ end
|
||||
local function check_curFadeOut(task,code,src)
|
||||
return task.code==code and task.args[1]==src
|
||||
end
|
||||
local function _tryReleaseSources()
|
||||
local n=#lastLoaded
|
||||
while #lastLoaded>maxLoadedCount do
|
||||
local name=lastLoaded[n]
|
||||
if SourceObjList[name].source:isPlaying()then
|
||||
n=n-1
|
||||
if n<=0 then return end
|
||||
else
|
||||
SourceObjList[name].source=SourceObjList[name].source:release()and nil
|
||||
table.remove(lastLoaded,n)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
function BGM.setDefault(bgm)
|
||||
BGM.default=bgm
|
||||
end
|
||||
function BGM.setMaxSources(count)
|
||||
maxLoadedCount=count
|
||||
_tryReleaseSources()
|
||||
end
|
||||
function BGM.setChange(func)
|
||||
BGM.onChange=func
|
||||
end
|
||||
function BGM.setVol(v)
|
||||
assert(type(v)=='number'and v>=0 and v<=1)
|
||||
assert(type(v)=='number'and v>=0 and v<=1,'Wrong volume')
|
||||
volume=v
|
||||
if BGM.playing then
|
||||
if volume>0 then
|
||||
BGM.playing:setVolume(volume)
|
||||
BGM.playing:play()
|
||||
elseif BGM.nowPlay then
|
||||
BGM.playing:pause()
|
||||
end
|
||||
end
|
||||
end
|
||||
function BGM.init(list)
|
||||
BGM.init=nil
|
||||
@@ -53,7 +81,7 @@ function BGM.init(list)
|
||||
local simpList={}
|
||||
for _,v in next,list do
|
||||
table.insert(simpList,v.name)
|
||||
Sources[v.name]=v.path
|
||||
SourceObjList[v.name]={path=v.path,source=false}
|
||||
end
|
||||
table.sort(simpList)
|
||||
function BGM.getList()return simpList end
|
||||
@@ -61,58 +89,43 @@ function BGM.init(list)
|
||||
LOG(count.." BGM files added")
|
||||
function BGM.getCount()return count end
|
||||
|
||||
local function _load(name)
|
||||
if type(Sources[name])=='string'then
|
||||
if love.filesystem.getInfo(Sources[name])then
|
||||
Sources[name]=love.audio.newSource(Sources[name],'stream')
|
||||
Sources[name]:setLooping(true)
|
||||
Sources[name]:setVolume(0)
|
||||
local function _tryLoad(name)
|
||||
if SourceObjList[name]then
|
||||
if SourceObjList[name].source then
|
||||
return true
|
||||
elseif love.filesystem.getInfo(SourceObjList[name].path)then
|
||||
SourceObjList[name].source=love.audio.newSource(SourceObjList[name].path,'stream')
|
||||
SourceObjList[name].source:setLooping(true)
|
||||
SourceObjList[name].source:setVolume(0)
|
||||
table.insert(lastLoaded,1,name)
|
||||
_tryReleaseSources()
|
||||
return true
|
||||
else
|
||||
LOG("No BGM: "..Sources[name],5)
|
||||
LOG("No BGM: "..SourceObjList[name],5)
|
||||
end
|
||||
elseif Sources[name]then
|
||||
return true
|
||||
elseif name then
|
||||
LOG("No BGM: "..name,5)
|
||||
end
|
||||
end
|
||||
function BGM.setVol(v)
|
||||
assert(type(v)=='number'and v>=0 and v<=1)
|
||||
volume=v
|
||||
if BGM.playing then
|
||||
if volume>0 then
|
||||
BGM.playing:setVolume(volume)
|
||||
BGM.playing:play()
|
||||
elseif BGM.nowPlay then
|
||||
BGM.playing:pause()
|
||||
end
|
||||
end
|
||||
end
|
||||
function BGM.loadAll()--Not neccessary, unless you want avoid the lag when playing something for the first time
|
||||
for name in next,Sources do
|
||||
_load(name)
|
||||
end
|
||||
end
|
||||
function BGM.play(name)
|
||||
name=name or BGM.default
|
||||
if not _load(name)then return end
|
||||
if not _tryLoad(name)then return end
|
||||
if volume==0 then
|
||||
BGM.nowPlay=name
|
||||
BGM.playing=Sources[name]
|
||||
BGM.playing=SourceObjList[name].source
|
||||
return true
|
||||
end
|
||||
if name and Sources[name]then
|
||||
if name and SourceObjList[name].source then
|
||||
if BGM.nowPlay~=name then
|
||||
if BGM.nowPlay then
|
||||
TASK.new(task_fadeOut,BGM.playing)
|
||||
end
|
||||
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,Sources[name])
|
||||
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,SourceObjList[name].source)
|
||||
TASK.removeTask_code(task_fadeIn)
|
||||
|
||||
TASK.new(task_fadeIn,Sources[name])
|
||||
TASK.new(task_fadeIn,SourceObjList[name].source)
|
||||
BGM.nowPlay=name
|
||||
BGM.playing=Sources[name]
|
||||
BGM.playing=SourceObjList[name].source
|
||||
BGM.lastPlayed=BGM.nowPlay
|
||||
BGM.playing:seek(0)
|
||||
BGM.playing:play()
|
||||
@@ -128,8 +141,8 @@ function BGM.init(list)
|
||||
end
|
||||
function BGM.continue()
|
||||
if BGM.lastPlayed then
|
||||
BGM.nowPlay,BGM.playing=BGM.lastPlayed,Sources[BGM.lastPlayed]
|
||||
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,Sources[BGM.nowPlay])
|
||||
BGM.nowPlay,BGM.playing=BGM.lastPlayed,SourceObjList[BGM.lastPlayed].source
|
||||
TASK.removeTask_iterate(check_curFadeOut,task_fadeOut,SourceObjList[BGM.nowPlay].source)
|
||||
TASK.removeTask_code(task_fadeIn)
|
||||
TASK.new(task_fadeIn,BGM.playing)
|
||||
BGM.playing:play()
|
||||
|
||||
@@ -1,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',
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
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'
|
||||
@@ -73,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
|
||||
|
||||
@@ -287,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',
|
||||
@@ -306,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>.5 and 1 or
|
||||
val<-.5 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>0 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
|
||||
@@ -378,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
|
||||
|
||||
@@ -402,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
|
||||
@@ -538,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 _
|
||||
@@ -622,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)
|
||||
@@ -703,6 +741,9 @@ end
|
||||
|
||||
local Z={}
|
||||
|
||||
Z.js=jsState
|
||||
Z.errData=errData
|
||||
|
||||
function Z.setIfPowerInfo(func)showPowerInfo=func end
|
||||
|
||||
--[Warning] Color and line width is uncertain value, set it in the function.
|
||||
|
||||
23
Zframework/mathExtend.lua
Normal file
23
Zframework/mathExtend.lua
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -63,9 +63,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
|
||||
|
||||
|
||||
@@ -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={
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
local TEST={}
|
||||
|
||||
--Wait for the scene swapping animation to finish
|
||||
function TEST.switchSCN()
|
||||
function TEST.yieldUntilNextScene()
|
||||
while SCN.swapping do YIELD()end
|
||||
end
|
||||
|
||||
function TEST.wait(frames)
|
||||
function TEST.yieldN(frames)
|
||||
for _=1,frames do YIELD()end
|
||||
end
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
44
legals.md
44
legals.md
@@ -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 People’s 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.
|
||||
|
||||
88
main.lua
88
main.lua
@@ -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()
|
||||
@@ -199,7 +208,7 @@ Z.setOnQuit(destroyPlayers)
|
||||
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.coverR(FILE.load('conf/data')or{},STAT)
|
||||
TABLE.cover (FILE.load('conf/key')or{},KEY_MAP)
|
||||
TABLE.cover (FILE.load('conf/virtualkey')or{},VK_ORG)
|
||||
|
||||
@@ -222,7 +231,7 @@ if missionData then
|
||||
DATA.pasteMission(missionData)
|
||||
end
|
||||
local customData=FILE.load('conf/customEnv')
|
||||
if customData and customData.version==VERSION.code then
|
||||
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
|
||||
@@ -443,7 +453,7 @@ do
|
||||
fs.remove('record/round_l.rec')
|
||||
fs.remove('record/round_u.rec')
|
||||
end
|
||||
if STAT.version<1604 then
|
||||
if RANKS.stack_e then
|
||||
RANKS.stack_e=nil
|
||||
RANKS.stack_h=nil
|
||||
RANKS.stack_u=nil
|
||||
@@ -459,17 +469,37 @@ 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 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
|
||||
@@ -505,26 +535,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
|
||||
|
||||
@@ -588,6 +603,7 @@ 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
|
||||
@@ -595,28 +611,28 @@ if TABLE.find(arg,'--test')then
|
||||
LOG("\27[92m\27[1mAutomatic Test Started\27[0m")
|
||||
BGM.setVol(0)SFX.setVol(0)
|
||||
love.keypressed('space')
|
||||
TEST.switchSCN()
|
||||
TEST.yieldUntilNextScene()
|
||||
|
||||
for k,mode in next,MODES do
|
||||
if k~='netBattle'then
|
||||
LOG("Scanning mode: "..mode.name)
|
||||
loadGame(mode.name,true)
|
||||
TEST.switchSCN()
|
||||
TEST.yieldUntilNextScene()
|
||||
SCN.back()
|
||||
TEST.switchSCN()
|
||||
TEST.yieldUntilNextScene()
|
||||
end
|
||||
end
|
||||
LOG("\27[92m\27[1mAutomatic Test Passed :)\27[0m")
|
||||
TEST.wait(60)
|
||||
TEST.yieldN(60)
|
||||
love.event.quit(0)
|
||||
end)
|
||||
TASK.new(function()
|
||||
while true do
|
||||
YIELD()
|
||||
if ERRDATA[1]then break end
|
||||
if Z.errData[1]then break end
|
||||
end
|
||||
LOG("\27[91m\27[1mAutomatic Test Failed :(\27[0m\nThe error message is:\n"..table.concat(ERRDATA[1].mes,"\n").."\27[91m\nAborting\27[0m")
|
||||
TEST.wait(60)
|
||||
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
BIN
media/music/1980s.ogg
Normal file
Binary file not shown.
BIN
media/music/peak.ogg
Normal file
BIN
media/music/peak.ogg
Normal file
Binary file not shown.
@@ -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'},
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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[_])
|
||||
|
||||
@@ -12,7 +12,7 @@ local baseBot={
|
||||
function baseBot.update(bot)
|
||||
local P=bot.P
|
||||
local keys=bot.keys
|
||||
if P.control and P.waiting==-1 then
|
||||
if P.control and P.waiting==0 then
|
||||
bot.delay=bot.delay-1
|
||||
if not keys[1]then
|
||||
if bot.runningThread then
|
||||
|
||||
@@ -6,6 +6,8 @@ return{
|
||||
lock=1e99,
|
||||
wait=0,
|
||||
fall=0,
|
||||
hang=5,
|
||||
hurry=1e99,
|
||||
|
||||
--Control
|
||||
nextCount=6,
|
||||
@@ -19,6 +21,7 @@ return{
|
||||
|
||||
--Rule
|
||||
sequence='bag',
|
||||
lockout=false,
|
||||
fieldH=20,
|
||||
heightLimit=1e99,
|
||||
bufferLimit=1e99,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
36
parts/eventsets/bigbang.lua
Normal file
36
parts/eventsets/bigbang.lua
Normal 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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
return{
|
||||
dropPiece=function(P)
|
||||
hook_drop=function(P)
|
||||
if #PLY_ALIVE>1 then
|
||||
P.control=false
|
||||
local id1=P.sid
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
56
parts/eventsets/marathon_inf.lua
Normal file
56
parts/eventsets/marathon_inf.lua
Normal 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
|
||||
}
|
||||
@@ -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')
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
20
parts/eventsets/sprintEff_40.lua
Normal file
20
parts/eventsets/sprintEff_40.lua
Normal 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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -5,10 +5,11 @@ return{
|
||||
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,
|
||||
dropPiece=function(P)
|
||||
if #P.field>20 then
|
||||
local cc=P:clearFilledLines(P.garbageBeneath+1,#P.field-P.garbageBeneath)
|
||||
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)
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
return{
|
||||
fieldH=21,
|
||||
fillClear=false,
|
||||
mesDisp=function(P)
|
||||
setFont(60)
|
||||
mStr(P.stat.row,63,280)
|
||||
mText(TEXTOBJ.line,63,350)
|
||||
end,
|
||||
dropPiece=function(P)
|
||||
if #P.field>20 then
|
||||
local cc=P:clearFilledLines(P.garbageBeneath+1,#P.field-P.garbageBeneath)
|
||||
local h=20-cc-P.garbageBeneath-2
|
||||
if h>0 then
|
||||
P:garbageRise(21,h,2e10-1)
|
||||
if P.garbageBeneath>=20 then
|
||||
P:lose()
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
}
|
||||
@@ -5,10 +5,11 @@ return{
|
||||
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,
|
||||
dropPiece=function(P)
|
||||
if #P.field>20 then
|
||||
local cc=P:clearFilledLines(P.garbageBeneath+1,#P.field-P.garbageBeneath)
|
||||
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)
|
||||
|
||||
30
parts/eventsets/strategy_e.lua
Normal file
30
parts/eventsets/strategy_e.lua
Normal 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
|
||||
}
|
||||
30
parts/eventsets/strategy_h.lua
Normal file
30
parts/eventsets/strategy_h.lua
Normal 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
|
||||
}
|
||||
30
parts/eventsets/strategy_u.lua
Normal file
30
parts/eventsets/strategy_u.lua
Normal 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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -4,7 +4,7 @@ return{
|
||||
mStr(P.stat.clear[7][4],63,250)
|
||||
mText(TEXTOBJ.techrash,63,315)
|
||||
end,
|
||||
dropPiece=function(P)
|
||||
hook_drop=function(P)
|
||||
if P.lastPiece.row>0 and P.lastPiece.row<4 then
|
||||
P:lose()
|
||||
end
|
||||
|
||||
@@ -8,12 +8,12 @@ return{
|
||||
PLY.draw.applyField(P)
|
||||
local L=P.modeData.history
|
||||
for i=1,#L do
|
||||
gc.setColor(1,.3,.3,.45-i*.04)
|
||||
gc.setColor(1,.3,.3,.5-i*.04)
|
||||
gc.rectangle('fill',30*L[i]-30,0,30,600)
|
||||
end
|
||||
PLY.draw.cancelField(P)
|
||||
end,
|
||||
dropPiece=function(P)
|
||||
hook_drop=function(P)
|
||||
local C=P.lastPiece
|
||||
if C.row>0 then
|
||||
if C.row==4 then
|
||||
|
||||
@@ -4,7 +4,7 @@ return{
|
||||
mStr(P.modeData.tsd,63,250)
|
||||
mText(TEXTOBJ.tsd,63,315)
|
||||
end,
|
||||
dropPiece=function(P)
|
||||
hook_drop=function(P)
|
||||
local C=P.lastPiece
|
||||
if C.row>0 then
|
||||
if C.id==5 and C.row==2 and C.spin then
|
||||
|
||||
@@ -13,7 +13,7 @@ return{
|
||||
PLY.draw.cancelField(P)
|
||||
end
|
||||
end,
|
||||
dropPiece=function(P)
|
||||
hook_drop=function(P)
|
||||
local C=P.lastPiece
|
||||
if C.row>0 then
|
||||
if C.id==5 and C.row==2 and C.spin then
|
||||
|
||||
@@ -8,12 +8,12 @@ return{
|
||||
PLY.draw.applyField(P)
|
||||
local L=P.modeData.history
|
||||
for i=1,#L do
|
||||
gc.setColor(1,.3,.3,.3-i*.05)
|
||||
gc.setColor(1,.3,.3,.4-i*.05)
|
||||
gc.rectangle('fill',30*L[i]-30,0,30,600)
|
||||
end
|
||||
PLY.draw.cancelField(P)
|
||||
end,
|
||||
dropPiece=function(P)
|
||||
hook_drop=function(P)
|
||||
local C=P.lastPiece
|
||||
if C.row>0 then
|
||||
if C.id==5 and C.row==2 and C.spin then
|
||||
|
||||
@@ -16,9 +16,9 @@ return{
|
||||
if P.stat.frame/60>=warnTime[P.modeData.stage]then
|
||||
if P.modeData.stage<9 then
|
||||
P.modeData.stage=P.modeData.stage+1
|
||||
SFX.play('ready',.7+P.modeData.stage*.03)
|
||||
playReadySFX(3,.7+P.modeData.stage*.03)
|
||||
else
|
||||
SFX.play('start')
|
||||
playReadySFX(0,.7+P.modeData.stage*.03)
|
||||
P:win('finish')
|
||||
return
|
||||
end
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,37 +0,0 @@
|
||||
local FREEROW={}
|
||||
local L={}--Storage
|
||||
local len=0--Length
|
||||
function FREEROW.reset(num)
|
||||
if num<len then
|
||||
for i=len,num+1,-1 do
|
||||
L[i]=nil
|
||||
end
|
||||
elseif num>len then
|
||||
for i=len+1,num do
|
||||
L[i]={0,0,0,0,0,0,0,0,0,0,garbage=false}
|
||||
end
|
||||
end
|
||||
len=num
|
||||
end
|
||||
function FREEROW.get(val,ifGarbage)
|
||||
if len==0 then
|
||||
for i=1,10 do
|
||||
L[i]={0,0,0,0,0,0,0,0,0,0,garbage=false}
|
||||
end
|
||||
len=len+10
|
||||
end
|
||||
local t=L[len]
|
||||
for i=1,10 do t[i]=val end
|
||||
t.garbage=ifGarbage==true
|
||||
L[len]=nil
|
||||
len=len-1
|
||||
return t
|
||||
end
|
||||
function FREEROW.discard(t)
|
||||
len=len+1
|
||||
L[len]=t
|
||||
end
|
||||
function FREEROW.getCount()
|
||||
return len
|
||||
end
|
||||
return FREEROW
|
||||
@@ -206,34 +206,30 @@ function playClearSFX(cc)
|
||||
end
|
||||
end
|
||||
end
|
||||
function playReadySFX(i)
|
||||
function playReadySFX(i,vol)
|
||||
if i==3 then
|
||||
Snd('bass','A3')
|
||||
Snd('lead','A4')
|
||||
Snd('bass','A3',vol)
|
||||
Snd('lead','A4',vol)
|
||||
elseif i==2 then
|
||||
Snd('bass','F3')
|
||||
Snd('lead','A4')
|
||||
Snd('lead','D5')
|
||||
Snd('bass','F3',vol)
|
||||
Snd('lead','A4',vol)
|
||||
Snd('lead','D5',vol)
|
||||
elseif i==1 then
|
||||
Snd('bass','G3')
|
||||
Snd('lead','B4')
|
||||
Snd('lead','E5')
|
||||
Snd('bass','G3',vol)
|
||||
Snd('lead','B4',vol)
|
||||
Snd('lead','E5',vol)
|
||||
elseif i==0 then
|
||||
Snd('bass','A3')
|
||||
Snd('lead','A4')
|
||||
Snd('lead','E5')
|
||||
Snd('lead','A5')
|
||||
Snd('bass','A3',vol)
|
||||
Snd('lead','A4',vol)
|
||||
Snd('lead','E5',vol)
|
||||
Snd('lead','A5',vol)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--Game
|
||||
function coin(a,b)
|
||||
if rnd()<.5 then
|
||||
return a
|
||||
else
|
||||
return b
|
||||
end
|
||||
function getItem(itemName,amount)
|
||||
STAT.item[itemName]=STAT.item[itemName]+(amount or 1)
|
||||
end
|
||||
function generateLine(hole)
|
||||
return 1023-2^(hole-1)
|
||||
@@ -257,8 +253,8 @@ function setField(P,page)
|
||||
local t=P.showTime*3
|
||||
for y=1,height do
|
||||
local notEmpty=notEmptyLine(F[y])
|
||||
P.field[y]=FREEROW.get(0,notEmpty)
|
||||
P.visTime[y]=FREEROW.get(t)
|
||||
P.field[y]=LINE.new(0,notEmpty)
|
||||
P.visTime[y]=LINE.new(t)
|
||||
if notEmpty then
|
||||
for x=1,10 do
|
||||
P.field[y][x]=F[y][x]
|
||||
@@ -275,9 +271,11 @@ function freshDate(mode)
|
||||
if STAT.date~=date then
|
||||
STAT.date=date
|
||||
STAT.todayTime=0
|
||||
getItem('zTicket',1)
|
||||
if not mode:find'q'then
|
||||
MES.new('info',text.newDay)
|
||||
end
|
||||
saveStats()
|
||||
return true
|
||||
end
|
||||
end
|
||||
@@ -331,8 +329,8 @@ function destroyPlayers()--Destroy all player objects, restore freerows and free
|
||||
P.canvas:release()
|
||||
end
|
||||
while P.field[1]do
|
||||
FREEROW.discard(rem(P.field))
|
||||
FREEROW.discard(rem(P.visTime))
|
||||
rem(P.field)
|
||||
rem(P.visTime)
|
||||
end
|
||||
end
|
||||
TABLE.cut(PLAYERS)
|
||||
@@ -668,7 +666,6 @@ do--function resetGameData(args)
|
||||
GAME.secDangerous=false
|
||||
GAME.stage=1
|
||||
end
|
||||
FREEROW.reset(30*#PLAYERS)
|
||||
TASK.removeTask_code(task_showMods)
|
||||
if GAME.setting.allowMod then
|
||||
TASK.new(task_showMods)
|
||||
|
||||
@@ -20,140 +20,129 @@ RANK_COLORS={
|
||||
{1,.5,.4},
|
||||
{.95,.5,.95},
|
||||
}
|
||||
do--SVG_TITLE
|
||||
SVG_TITLE={
|
||||
do--SVG_TITLE_FILL, SVG_TITLE_LINE
|
||||
SVG_TITLE_FILL={
|
||||
{
|
||||
53, 60,
|
||||
1035, 0,
|
||||
964, 218,
|
||||
660, 218,
|
||||
391, 1300,
|
||||
231, 1154,
|
||||
415, 218,
|
||||
0, 218,
|
||||
0,0,
|
||||
0,34,
|
||||
63,34,
|
||||
63,227,
|
||||
97,227,
|
||||
97,34,
|
||||
160,34,
|
||||
160,0,
|
||||
},
|
||||
{
|
||||
716, 290,
|
||||
1429, 290,
|
||||
1312, 462,
|
||||
875, 489,
|
||||
821, 695,
|
||||
1148, 712,
|
||||
1017, 902,
|
||||
761, 924,
|
||||
707, 1127,
|
||||
1106, 1101,
|
||||
1198, 1300,
|
||||
465, 1300,
|
||||
126,60,
|
||||
244,60,
|
||||
244,94,
|
||||
160,94,
|
||||
160,127,
|
||||
230,127,
|
||||
230,161,
|
||||
160,161,
|
||||
160,194,
|
||||
244,194,
|
||||
244,227,
|
||||
126,227,
|
||||
},
|
||||
{
|
||||
1516, 287,
|
||||
2102, 290,
|
||||
2036, 464,
|
||||
1598, 465,
|
||||
1322, 905,
|
||||
1395, 1102,
|
||||
1819, 1064,
|
||||
1743, 1280,
|
||||
1286, 1310,
|
||||
1106, 902,
|
||||
262,82,
|
||||
283,60,
|
||||
385,60,
|
||||
385,94,
|
||||
296,94,
|
||||
296,194,
|
||||
385,194,
|
||||
385,227,
|
||||
283,227,
|
||||
262,206,
|
||||
},
|
||||
{
|
||||
2179, 290,
|
||||
2411, 290,
|
||||
2272, 688,
|
||||
2674, 666,
|
||||
2801, 290,
|
||||
3041, 290,
|
||||
2693, 1280,
|
||||
2464, 1280,
|
||||
2601, 879,
|
||||
2199, 897,
|
||||
2056, 1280,
|
||||
1828, 1280,
|
||||
404,60,
|
||||
437,60,
|
||||
437,127,
|
||||
505,127,
|
||||
505,60,
|
||||
538,60,
|
||||
538,227,
|
||||
505,227,
|
||||
505,161,
|
||||
437,161,
|
||||
437,227,
|
||||
404,227,
|
||||
},
|
||||
{
|
||||
3123, 290,
|
||||
3480, 290,
|
||||
3496, 480,
|
||||
3664, 290,
|
||||
4017, 294,
|
||||
3682, 1280,
|
||||
3453, 1280,
|
||||
3697, 578,
|
||||
3458, 843,
|
||||
3304, 842,
|
||||
3251, 561,
|
||||
3001, 1280,
|
||||
2779, 1280,
|
||||
558,60,
|
||||
604,60,
|
||||
640,153,
|
||||
676,60,
|
||||
722,60,
|
||||
722,227,
|
||||
688,227,
|
||||
688,108,
|
||||
655,194,
|
||||
625,194,
|
||||
591,108,
|
||||
591,227,
|
||||
558,227,
|
||||
},
|
||||
{
|
||||
4088, 290,
|
||||
4677, 290,
|
||||
4599, 501,
|
||||
4426, 502,
|
||||
4219, 1069,
|
||||
4388, 1070,
|
||||
4317, 1280,
|
||||
3753, 1280,
|
||||
3822, 1068,
|
||||
3978, 1068,
|
||||
4194, 504,
|
||||
4016, 504,
|
||||
743,60,
|
||||
777,60,
|
||||
777,227,
|
||||
743,227,
|
||||
},
|
||||
{
|
||||
4747, 290,
|
||||
4978, 295,
|
||||
4921, 464,
|
||||
5186, 850,
|
||||
5366, 290,
|
||||
5599, 295,
|
||||
5288, 1280,
|
||||
5051, 1280,
|
||||
5106, 1102,
|
||||
4836, 709,
|
||||
4641, 1280,
|
||||
4406, 1280,
|
||||
798,60,
|
||||
831,60,
|
||||
899,173,
|
||||
899,60,
|
||||
933,60,
|
||||
933,227,
|
||||
899,227,
|
||||
831,115,
|
||||
831,227,
|
||||
798,227,
|
||||
},
|
||||
{
|
||||
5814, 290,
|
||||
6370, 295,
|
||||
6471, 415,
|
||||
6238, 1156,
|
||||
6058, 1280,
|
||||
5507, 1280,
|
||||
5404, 1154,
|
||||
5635, 416,
|
||||
-- 5814, 290,
|
||||
-- 5878, 463,
|
||||
5770, 542,
|
||||
5617, 1030,
|
||||
5676, 1105,
|
||||
5995, 1106,
|
||||
6100, 1029,
|
||||
6255, 541,
|
||||
6199, 465,
|
||||
5878, 463,
|
||||
950,82,
|
||||
971,60,
|
||||
1064,60,
|
||||
1085,82,
|
||||
1085,206,
|
||||
1064,227,
|
||||
971,227,
|
||||
950,206,
|
||||
950,82,
|
||||
|
||||
984,94,
|
||||
984,194,
|
||||
1051,194,
|
||||
1051,94,
|
||||
984,94,
|
||||
},
|
||||
}
|
||||
for _,C in next,SVG_TITLE do
|
||||
for _,C in next,SVG_TITLE_FILL do
|
||||
for i=1,#C do
|
||||
C[i]=C[i]*.1626
|
||||
C[i]=C[i]*.94
|
||||
end
|
||||
end
|
||||
|
||||
SVG_TITLE_LINE=TABLE.shift(SVG_TITLE_FILL)
|
||||
SVG_TITLE_LINE[8],SVG_TITLE_LINE[9]={},{}
|
||||
for j=1,16 do SVG_TITLE_LINE[8][j]=SVG_TITLE_FILL[8][j]end
|
||||
for j=19,#SVG_TITLE_FILL[8]-2 do SVG_TITLE_LINE[9][j-18]=SVG_TITLE_FILL[8][j]end
|
||||
end
|
||||
do--SVG_TITLE_FAN
|
||||
SVG_TITLE_FAN={}
|
||||
local sin,cos=math.sin,math.cos
|
||||
for i=1,8 do
|
||||
local L={}
|
||||
for i=1,9 do
|
||||
local L=TABLE.copy(SVG_TITLE_LINE[i])
|
||||
SVG_TITLE_FAN[i]=L
|
||||
for j=1,#SVG_TITLE[i]do
|
||||
L[j]=SVG_TITLE[i][j]
|
||||
end
|
||||
for j=1,#L,2 do
|
||||
local x,y=L[j],L[j+1]--0<x<3041, 290<y<1280
|
||||
x,y=-(x+240+y*.3)*.002,(y-580)*.9
|
||||
local x,y=L[j],L[j+1]--0<x<988, 290<y<1280
|
||||
x,y=-(x+280)*.002,(y-580)*.9--X=ang, Y=dist
|
||||
x,y=y*cos(x),-y*sin(x)--Rec-Pol-Rec
|
||||
L[j],L[j+1]=x,y+300
|
||||
end
|
||||
@@ -345,7 +334,6 @@ EVENTSETS={
|
||||
'marathon_n','marathon_h',
|
||||
'master_n','master_h','master_final','master_m','master_ex','master_ph',
|
||||
'pctrain_n','pctrain_l','pc_inf',
|
||||
'rhythm_e','rhythm_h','rhythm_u',
|
||||
'survivor_e','survivor_n','survivor_h','survivor_l','survivor_u',
|
||||
'tsd_e','tsd_h','tsd_u',
|
||||
'ultra',
|
||||
@@ -548,13 +536,12 @@ do--Game data tables
|
||||
ROOMENV={
|
||||
--Room config
|
||||
capacity=10,
|
||||
FTLock=true,
|
||||
|
||||
--Basic
|
||||
drop=30,
|
||||
lock=60,
|
||||
wait=0,
|
||||
fall=0,
|
||||
FTLock=true,
|
||||
drop=30,lock=60,
|
||||
wait=0,fall=0,
|
||||
hang=5,hurry=1e99,
|
||||
|
||||
--Control
|
||||
nextCount=6,
|
||||
@@ -727,6 +714,10 @@ do--Userdata tables
|
||||
spin=(function()local L={}for i=1,29 do L[i]={0,0,0,0,0,0,0}end return L end)(),
|
||||
pc=0,hpc=0,b2b=0,b3b=0,score=0,
|
||||
lastPlay='sprint_10l',--Last played mode ID
|
||||
item=setmetatable({},{__index=function(self,k)
|
||||
self[k]=0
|
||||
return 0
|
||||
end}),
|
||||
date=false,
|
||||
todayTime=0,
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ return{
|
||||
{"Translator Note 1",
|
||||
"",
|
||||
"help",
|
||||
"This translation of the TetroDictionary is provided by me, User670 (Discord: User670#9501).\n\nThe translation may not completely reflect the contents of the original Chinese text.\n\nCorrected by C29H25N3O5.\n\nTo view the list of contributors or make contributions, feel free to visit the GitHub page.",
|
||||
"This translation of the TetroDictionary is provided by me, User670 (Discord: User670#9501).\n\nThe translation may not completely reflect the contents of the original Chinese text.\n\nCorrected by C₂₉H₂₅N₃O₅ (Discord: C29H25N3O5#1606).\n\nTo view the list of contributors or make contributions, feel free to visit the GitHub page.",
|
||||
"https://github.com/26F-Studio/Techmino/blob/main/parts/language/dict_en.lua",
|
||||
},
|
||||
{"Official Website",
|
||||
@@ -16,8 +16,8 @@ return{
|
||||
{"To New Players",
|
||||
"guide newbie noob",
|
||||
"help",
|
||||
"To new players that want to get better at the game:\n\tTwo principles:\n\t1. find a version with good controls (e.g. Techmino, Tetr.io, Tetris Online, Jstris, Tetr.js). Do not use those version used for programming practice.\n\t2. Build foundations in your skills (stable Techrashes using next queue to aid decisions), don't go for fancy T-Spins from the start.\n\n\tTwo main techniques:\n\t1. familiarize yourself with spawn locations of pieces, and the controls to move the piece into each location\n\t2. Plan ahead of where to put the pieces\nWe recommend that you read this article titled \"Words to newbies from a Tetris Pro\" (Click \"Open URL\". In Simplified Chinese)",
|
||||
"https://bilibili.com/read/cv2352939",
|
||||
"To new players that want to get better at the game:\n\tTwo principles:\n\t1. find a version with good controls (e.g. Techmino, Tetr.io, Tetris Online, Jstris, Tetr.js). Do not use those version used for programming practice.\n\t2. Build foundations in your skills (stable Techrashes using next queue to aid decisions), don't go for fancy T-Spins from the start.\n\n\tTwo main techniques:\n\t1. familiarize yourself with spawn locations of pieces, and the controls to move the piece into each location\n\t2. Plan ahead of where to put the pieces\nHere is a article written by a well-known player in Chinese Tetris community talking about advices to new players. Click the globe to read the translated article by User670.",
|
||||
"https://github.com/user670/temp/blob/master/tips_to_those_new_to_top.md",
|
||||
},
|
||||
{"Learning T-spins",
|
||||
"tspin learning study guide tips",
|
||||
@@ -55,6 +55,37 @@ return{
|
||||
"https://tetris.huijiwiki.com",
|
||||
},
|
||||
|
||||
--Webpages / Organizations
|
||||
{"Github Repository",
|
||||
"githubrepository sourcecode",
|
||||
"org",
|
||||
"Techmino's Github repository. Stars are appreciated.",
|
||||
"https://github.com/26F-Studio/Techmino",
|
||||
},
|
||||
{"Communities",
|
||||
"community communities",
|
||||
"org",
|
||||
"Join Tetris communities and talk with other players!\n\nChina: [QQ] Tetris Research: 112897780\nGlobal: [Discord] Hard Drop: discord.gg/harddrop (click the globe icon to open).",
|
||||
"https://discord.gg/harddrop"
|
||||
},
|
||||
{"Mew",
|
||||
"mew tieba forum",
|
||||
"org",
|
||||
"The Mew forum owned by Chinese Tetris Research Community, and was founded in the second half of 2021. Mew is a Chinese social media that can be thought of a combination of Discord and Reddit, with many channels in a big community. Users can chat in the channels or submit posts to the channel. Mew also has a function called \"Library\" which allows storing documentations systematically. The Tetris Mew forum is currently under construction and not too much contents are available (2/Nov/2021).",
|
||||
"https://mew.fun/n/tetris",
|
||||
},
|
||||
{"Tetris OL Servers",
|
||||
"tetrisonline servers",
|
||||
"org",
|
||||
"Google \"Tetris Online Poland\" for the Poland server.\nClick on the globe icon for information about the Tetris Online Study server.",
|
||||
"http://teatube.ltd/tos",
|
||||
},
|
||||
{"P\97\116\114\101\111\110",
|
||||
"p\97\116\114\101\111\110 support",
|
||||
"org",
|
||||
"Techmino's P\97\116\114\101\111\110 Page",
|
||||
FNSF and"https://www.youtube.com/watch?v=DVl0IiUKX_g"or"https://www.p\97\116\114\101\111\110.com/techmino",
|
||||
},
|
||||
--Games
|
||||
{"TTT",
|
||||
"ttt tetris trainer tres bien",
|
||||
@@ -136,12 +167,12 @@ return{
|
||||
{"Tetris Gems",
|
||||
"tetris online official gem",
|
||||
"game",
|
||||
"Another Tetris game from tetris.com. It has the gravity mechanism, and each game lasts for 2 minutes. There are three kinds of gem blocks with different abilities.",
|
||||
"Another Tetris game from tetris.com. It has the gravity mechanism, and each game lasts for 1 minute. There are three kinds of gem blocks with different abilities.",
|
||||
},
|
||||
{"Tetris Mind Bender",
|
||||
"tetris online official gem",
|
||||
"game",
|
||||
"Another Tetris game from tetris.com. It introduced “Mind Bender” minoes on the basis of marathon mode. Clearing a line with a Mind Bender mino will give you either a good or bad effect.",
|
||||
"Another Tetris game from tetris.com. It introduced \"Mind Bender\" minoes on the basis of marathon mode. Clearing a line with a Mind Bender mino will give you either a good or bad effect.",
|
||||
},
|
||||
|
||||
{"TGM",
|
||||
@@ -164,6 +195,11 @@ return{
|
||||
"game",
|
||||
"*Windows | Single-player*\nA game with all modes from TGM which you can use to practice. Has better controls than actual TGM. The world rule is slightly different, however (eg, instant-lock soft drops, and slightly different kick tables)",
|
||||
},
|
||||
{"Cambridge",
|
||||
"cambridge",
|
||||
"game",
|
||||
"*Windows, macOS, Linux | Single-player*\nA Lua-based game engine dedicated to creating a robust, easily customizable platform for creating new, custom game modes. It was originally made by Joe Zeng, and starting with version 0.1.5 on October 8, 2020, Milla took over development of the game.\n--Tetris Wiki",
|
||||
},
|
||||
|
||||
{"Tetris99",
|
||||
"t99 tetris99",
|
||||
@@ -223,17 +259,17 @@ return{
|
||||
{"Tetris Blitz",
|
||||
"blitz ea mobile phone",
|
||||
"game",
|
||||
"A mobile Tetris game by Electronic Arts (EA). It has the gravity mechanism, and each game lasts for 2 minutes. A bunch of minoes fall down to the field at the beginning of the game, and you can enter the \"Frenzy\" mode by performing Tetris line clears continuously. There are many different power-ups available.\n\nThis game is no longer available since January 2020.",
|
||||
"A mobile Tetris game by Electronic Arts (EA). It has the gravity mechanism, and each game lasts for 2 minutes. A bunch of minoes fall down to the field at the beginning of the game, and you can enter the \"Frenzy\" mode by performing line clears continuously. There are many different power-ups available. Also, this game has no top-out mechanism. When an incoming block overlaps with existing blocks in the field, the top lines will be cleared automatically. \n\nThis game is no longer available since April 2020.",
|
||||
},
|
||||
{"Tetris (EA)",
|
||||
"tetris ea galaxy universe cosmos mobile phone",
|
||||
"game",
|
||||
"Another mobile Tetris game by EA. It has two control modes – Swipe and One-Touch. It also has a Galaxy Mode besides the Marathon Mode (with gravity mechanism), and the goal of this mode is to clear all Galaxy minoes before the sequence runs out.\n\nThis game is no longer available since April 2020."
|
||||
},
|
||||
{"Tetris(N3TWORK)",
|
||||
{"Tetris (N3TWORK)",
|
||||
"tetris n3twork mobile phone",
|
||||
"game",
|
||||
"The latest mobile Tetris from N3TWORK Inc. It has a 3-minute ultra mode, a marathon mode and a Royale mode. The UI is great but its controls are not so good.",
|
||||
"The latest mobile Tetris from N3TWORK Inc. It has a 3-minute ultra mode, a marathon mode and a 100-player Royale mode. The UI is great but its controls are not so good.",
|
||||
},
|
||||
{"Tetris Beat",
|
||||
"tetris beat n3twork rhythm",
|
||||
@@ -276,7 +312,7 @@ return{
|
||||
{"BPM",
|
||||
"bpm blocksperminute piecesperminute speed",
|
||||
"term",
|
||||
"Blocks per minute\n\tReflects playing speed of a player.\nAlso MrZ forgot that it can be called PPM to avoid confusing with the music term.",
|
||||
"Blocks per minute\n\tReflects playing speed of a player.\nAlso called PPM (to avoid confusing with the musical term).",
|
||||
},
|
||||
{"KPM",
|
||||
"kpm keysperminute keypressesperminute",
|
||||
@@ -342,7 +378,7 @@ return{
|
||||
{"Tetris",
|
||||
"tetris",
|
||||
"term",
|
||||
"The name of the game (and its trademark). Also the name for clearing 4 lines at one time in official games.\nCoined from Tetra (greek for \"four\") and Tennis (favorite sport of the creator of Tetris).",--Thanks to Alexey Pajitnov!
|
||||
"The name of the game (and its trademark). Also the name for clearing 4 lines at one time in official games.\nCoined from Tetra (greek for \"four\") and Tennis (favorite sport of the creator of Tetris). Also, the Tetris games developed by Nintendo and SEGA was licensed by TTC and these two companies do not have the copyright of Tetris.",--Thanks to Alexey Pajitnov!
|
||||
},
|
||||
{"All Clear",
|
||||
"pc perfectclear ac allclear",
|
||||
@@ -410,6 +446,11 @@ return{
|
||||
"term",
|
||||
"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.",
|
||||
},
|
||||
{"Orientation",
|
||||
"orientation direction 0r2l 02 20 rl lr",
|
||||
"term",
|
||||
"In SRS and SRS-like rotation systems, there are standard notations describing the orientations of the minoes:\n 0 for Original orientation; R for right, or 90° clockwise; L for left, or 90° counterclockwise; 2 for spin twice (180°). For example, 0→L means rotating counterclockwise from original orientation (0) to L; 0→R means rotating clockwise from original orientation (0) to R; 2→R means rotating counterclockwise from 2 (180°) to R.",
|
||||
},
|
||||
{"ARS",
|
||||
"ars arikrotationsystem atarirotationsystem",
|
||||
"term",
|
||||
@@ -484,7 +525,7 @@ return{
|
||||
{"Tetrominos' Shapes",
|
||||
"shape structure form tetromino tetrimino",
|
||||
"term",
|
||||
"In standard Tetris games, all the blocks used are tetrominoes (spelt as \"Tetrimino\" in official games), i.e. Blocks that are linked by four minoes side-by-side.\n\nThere are seven kinds of tetrominoes in total when allowing rotations and disallowing reflections. These tetrominoes are named by the letter in the alphabet that they resemble. They are Z, S, J, L, T, O, and I.",
|
||||
"In standard Tetris games, all the blocks used are tetrominoes, i.e. Blocks that are linked by four minoes side-by-side.\n\nThere are seven kinds of tetrominoes in total when allowing rotations and disallowing reflections. These tetrominoes are named by the letter in the alphabet that they resemble. They are Z, S, J, L, T, O, and I.",
|
||||
},
|
||||
{"Tetrominos' Colors",
|
||||
"colour hue tint tetromino tetrimino",
|
||||
@@ -504,7 +545,7 @@ return{
|
||||
{"IMS",
|
||||
"ims initialmovesystem",
|
||||
"term",
|
||||
"*Techmino-exclusive*\nInitial Movement System\nHolding a sideways movement key during spawn delay to spawn the piece one block off to the side. Sometimes prevents death.",
|
||||
"*Techmino-exclusive*\nInitial Movement System\nHolding a sideways movement key during spawn delay to spawn the piece one block off to the side. Sometimes prevents death.\nNote that DAS need to be full charged when new piece appear",
|
||||
},
|
||||
{"Next",
|
||||
"nextpreview",
|
||||
@@ -521,6 +562,11 @@ return{
|
||||
"term",
|
||||
"Like *hold*, swap your current piece and the first piece of next queue. You can also only perform this once per piece in most cases.",
|
||||
},
|
||||
{"Deepdrop",
|
||||
"deepdrop shenjiang",
|
||||
"term",
|
||||
"*Techmino exclusive*\n\nA special function that allows minoes to teleport through the wall to enter a hole. When the mino hits the bottom, pressing the soft drop button again will enable the deep drop. if there is a hole that fits the shape of the mino, it will teleport into this hole immediately/nThis mechanism is especially useful for AI because it allows AI to disregard the differences between different rotation systems.",
|
||||
},
|
||||
{"Misdrop",
|
||||
"md misdrop",
|
||||
"term",
|
||||
@@ -546,7 +592,7 @@ return{
|
||||
"term",
|
||||
"A terminology used in the Chinese Tetris community. A \"debt\" refers to a situation where one must first finish constructing a specific setup before he or she can perform one or more T-spins with real attacks. When constructing a setup where one or multiple debts are created, it is important to observe the opponent carefully to ensure your safety; otherwise, there is a high probability of topping out before the construction is finished.\n\nThis term is frequently used to describe setups such as TST tower. No real attacks can be made before the setup is constructed completely.",
|
||||
},
|
||||
{"Attacking & Defending",
|
||||
{"Attack & Defend",
|
||||
"attacking defending",
|
||||
"term",
|
||||
"Attacking: send garbage lines to your opponent by clearing lines.\nDefending: after your opponent send you lines, you offset this garbage by clearing lines.\nCounter attack: Send attack back at your opponent after offsetting incoming garbage, or taking the hit then attack back.\nIn most games, garbage offsetting is 1:1, i.e. one attack offsets one incoming garbage.",
|
||||
@@ -616,20 +662,36 @@ return{
|
||||
"term",
|
||||
"A way of stacking where you have a 6-block-wide stack on the left, and a 3-block-wide stack on the right.\nFor a skilled player, this method of stacking might reduce the keypresses needed for stacking, and is a popular Sprint stacking method. The reason why it works has to do with the fact that pieces spawn with a bias to the left.",
|
||||
},
|
||||
{"20G",
|
||||
"20g",
|
||||
{"Freestyle",
|
||||
"freestyle ziyou",
|
||||
"term",
|
||||
"The fastest falling speed of modern Tetris. In 20G, pieces do not have a falling process and instantly appear on the bottom. This sometimes also limits a piece's sideways movements, as it is not always possible to make a piece climb over a bump or out of a well in 20G.",
|
||||
"This term is usually used in 20TSDs. Freestyle means finishing 20 TSDs without using static stacking modes. Freestyle 20TSDs is more difficult than static tsacking modes such as LST, and the performance can represent the T-spin skills a player has in battles.",
|
||||
},
|
||||
{"Topping out",
|
||||
"die death topout toppingout",
|
||||
"term",
|
||||
"Modern Tetris games have three different conditions in which the player tops out:\n1. Block out: when a piece spawned overlaps with the existing blocks in the field;\n2. Lock out: when a piece locks entirely above the skyline;\n3. Garbage out: when the stack exceeds 40 lines in height (often due to incoming garbage).\nTechmino does not check for locking out and garbage out.",
|
||||
"Modern Tetris games have three different conditions in which the player tops out:\n1. Block out: when a piece spawned overlaps with the existing blocks in the field;\n2. Lock out: when a piece locks entirely above the skyline;\n3. Top out: when the stack exceeds 40 lines in height (often due to incoming garbage).\nTechmino does not check for locking out and topping out.",
|
||||
},
|
||||
{"Buffer zone",
|
||||
"buffer zone above super invisible disappear",
|
||||
"term",
|
||||
"Refers to 21st-40th lines above the visible field. Because the blocks in the field could go over the visible field (this usually happens when multiple garbage lines come in) so the buffer zone was created so those blocks could go back to the field when garbage lines are cleared. Also, the buffer zone is usually located at 21st-40th lines because this is sufficient for most cases. Refer to \"Vanish Zone\" to learn more.",
|
||||
},
|
||||
{"Vanish zone",
|
||||
"vanish zone disappear gone cut die",
|
||||
"term",
|
||||
"Refers to the area located above the 40th line. This is usually realised by combining c4w and multiple garbage lines. In many games, when any block reaches the vanish zone, the game is terminated immediately.\nHowever, this area can have different behaviours in different games. Some games are flawed because the game could crash when the blocks enter the vanish zone (e.g. Tetris Online). Wierd behaviours could also happen when the blocks enter the vanish zone (you can refer to this video, click on the globe icon to open the link).\n\nFurthermore, the vanish zone in Jstris is located above the 22nd line, and any blocks locked above the 21st line will disappear. ",
|
||||
"https://youtu.be/z4WtWISkrdU",
|
||||
},
|
||||
{"Falling speed",
|
||||
"fallingspeed",
|
||||
"fallingspeed gravity",
|
||||
"term",
|
||||
"Falling speed is often described in terms of G, i.e. how many lines it falls in one frame (often assuming 60 frames per second).\nG is a large unit. The speed of Lv 1 in a regular Marathon (one second per line) is 1/60 G, and 1G is about Lv 13 speed. G usually caps at 20G, for there are only 20 (visible) blocks in the matrix's height.",
|
||||
"Falling speed is often described in terms of \"G\", i.e. how many lines the blocks fall in one frame (usually assuming 60 fps).\nG is a relatively large unit. The speed of Lv 1 in a regular Marathon (one second per line) is 1/60 G, and 1G is about Lv 13 speed. The highest speed of modern Tetris is 20G because the field height is 20 lines. In fact, the real meaning of 20G is \"Infinite falling speed\", and even when the field height is more than 20 lines, 20G modes force all the blocks to fall down to the bottom instantly. You can learn more about 20G at the \"20G\" entry.",
|
||||
},
|
||||
{"20G",
|
||||
"20g gravity instant",
|
||||
"term",
|
||||
"The fastest falling speed of modern Tetris. In 20G modes, pieces appear instantly on the bottom of the field without the actual process of \"falling down\". This sometimes also limits a piece's sideways movements, as it is not always possible to make a piece climb over a bump or out of a well in 20G. You can learn more at the unit \"G\" at the \"falling speed\" entry. ",
|
||||
},
|
||||
{"Lockdown Delay",
|
||||
"lockdelay lockdowndelay lockdowntimer",
|
||||
@@ -641,11 +703,16 @@ return{
|
||||
"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",
|
||||
"line are appearance delay",
|
||||
"term",
|
||||
"The delay between the start of a line clear animation to the spawn of the next piece.",
|
||||
},
|
||||
{"Death ARE",
|
||||
"death are die delay",
|
||||
"term",
|
||||
"(Techmino exclusive) When the spawn location of the next piece is blocked by an existing block in the field, a delay will be added in addition to the spawn ARE, and this delay is referred to as the death ARE. This mechanism can be used along with IHS and IRS to prevent death. \nOriginal idea by NOT_A_ROBOT",
|
||||
},
|
||||
{"Finesse",
|
||||
"finesse",
|
||||
"term",
|
||||
@@ -766,6 +833,16 @@ return{
|
||||
"term",
|
||||
"The block skin used by the earliest version of Tetris.\nIn the early times, computers were all using Command Line Interface instead of Graphical User Interface, so at that time a single mino in the game of Tetris is represented using two enclosing square brackets [ ]. It looks kinds of like bones so it is sometimes called the bone blocks.\nIn Techmino, bone blocks are defined as \"A single, fancy block skin that all of the blocks use.\". Different block skins may have different types of bone block styles.",
|
||||
},
|
||||
{"Semi-invisible",
|
||||
"half invisible semi",
|
||||
"term",
|
||||
"Refers to a rule where the tetrominoes will become invisible after a period of time.\nThis time interval is not definite and it is acceptable to describe it as \"disappear after a few seconds\".",
|
||||
},
|
||||
{"Invisible",
|
||||
"invisible",
|
||||
"term",
|
||||
"Refers to a rule where blocks will disappear instantly when locked onto the field. \nN.B. It is also acceptable to refer to an invisible mode where a disappearing animation is shown. However, this makes the game a lot easier, so in this game, the invisible mode without such animations is referred to as \"Sudden Invisible\".",
|
||||
},
|
||||
{"MPH mode",
|
||||
"mph",
|
||||
"term",
|
||||
@@ -942,32 +1019,6 @@ return{
|
||||
"Stacking TST(s) on top of a STSD.",
|
||||
},
|
||||
|
||||
--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",
|
||||
},
|
||||
|
||||
--Savedata managing
|
||||
{"Console",
|
||||
"console cmd commamd minglinghang kongzhitai",
|
||||
@@ -1066,7 +1117,7 @@ return{
|
||||
{"Furea",
|
||||
"furea fuleiya jk",
|
||||
"name",
|
||||
"(ふれあ)\n\nOne of the top players.\nWorld record holder of Puyo Puyo Tetris's Sprint mode and Ultra mode.",
|
||||
"(ふれあ)\n\nOne of the top players.\nWorld record holder of Puyo Puyo Tetris's Ultra mode.",
|
||||
},
|
||||
{"Iljain",
|
||||
"iljain yijianlian",
|
||||
@@ -1116,10 +1167,10 @@ return{
|
||||
{"TetroDictionary",
|
||||
"zictionary tetrodictionary littlez",
|
||||
"name",
|
||||
"(or Zictionary for short) The name of this thing.\nUsed to be a chatbot that serves for the same function, and mostly uses the same list of keywords.",
|
||||
"(or Zictionary for short) The name of this dictionary!\nIt includes brief introductions on many common terms in Tetris.\nIt used to be a chatbot in our QQ group, which was used to answer new player's FAQs. The entries in the Tetrodictionary were also inherited from the database in the chatbot.",
|
||||
},
|
||||
{"MrZ",
|
||||
"mrz 626",
|
||||
"mrz_26",
|
||||
"name",
|
||||
"Tetris Research community member, the author of Techmino.\nPersonal bests: Sprint 25.95 seconds, MPH Sprint 57 seconds, #8 on Jstris leaderboards, X rank on TETR.IO, cleared TGM3 (World rule, Shirase gold 1300).",
|
||||
"https://space.bilibili.com/225238922",
|
||||
@@ -1193,7 +1244,7 @@ return{
|
||||
{"他天一",
|
||||
"tty tatianyi hydrofierus",
|
||||
"name",
|
||||
"(Tā Tiān Yī)\n\nTetris Research community member.\nPersonal bests: Sprint 22.72 seconds, U rank on Tetr.io.\nOne of the top players of Tetris in China.",
|
||||
"(Tā Tiān Yī)\n\nTetris Research community member.\nPersonal bests: Sprint 21.908 seconds, U rank on Tetr.io.\nOne of the top players of Tetris in China.",
|
||||
"https://space.bilibili.com/3895759",
|
||||
},
|
||||
{"Mars608",
|
||||
@@ -1205,7 +1256,7 @@ return{
|
||||
{"Mifu",
|
||||
"mifu swl nanmaomao",
|
||||
"name",
|
||||
"Originally known as swl.\nPersonal bests: Sprint 32 seconds, Tetris Research community member.\nMiya's Tetris coach. Miya made an animated character art for him called Mifu, meaning \"Miya's Shifu\".",
|
||||
"Originally known as swl.\nPersonal bests: Sprint 28.445 seconds, Tetris Research community member.\nMiya's Tetris coach. Miya made an animated character art for him called Mifu, meaning \"Miya's Shifu\".",
|
||||
"https://space.bilibili.com/109356367",
|
||||
},
|
||||
{"ZXC",
|
||||
@@ -1247,7 +1298,7 @@ return{
|
||||
{"琳雨空",
|
||||
"linyukong",
|
||||
"name",
|
||||
"(Lín Yǔ Kong)\n\nTetris Research community member.\nSprint 38.3 seconds, S Rank in pentomino mode and Blind-WTF (world No.1)",
|
||||
"(Lín Yǔ Kong)\n\nTetris Research community member.\nSprint 38.3 seconds, Highest Rank in pentomino mode and Blind-WTF (world No.1)",
|
||||
"https://space.bilibili.com/263909369",
|
||||
},
|
||||
{"子心Koishi",
|
||||
@@ -1256,12 +1307,12 @@ return{
|
||||
"(Zǐ Xīn Koishi)\n\nTetris Research community member, Virtual content creator.\nA top Tetris 99 players known for his strategies.",
|
||||
"https://space.bilibili.com/147529",
|
||||
},
|
||||
{"ditoly",
|
||||
"ditoly icrem kuimei jk",
|
||||
"name",
|
||||
"Tetris Research community member. The developer of Nanamino.",
|
||||
"https://space.bilibili.com/13014410",
|
||||
},
|
||||
{"ditoly",
|
||||
"ditoly icrem kuimei jk",
|
||||
"name",
|
||||
"Tetris Research community member. The developer of Nanamino.",
|
||||
"https://space.bilibili.com/13014410",
|
||||
},
|
||||
{"蓝绿",
|
||||
"lanlv lanlyu gompyn imple lee blari'o blariho",
|
||||
"name",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user