Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
848cc41c72 | ||
|
|
f212076604 | ||
|
|
ee4fd51e0f | ||
|
|
f96b4f6724 | ||
|
|
7b6f2f826a | ||
|
|
8ed4fd6cba | ||
|
|
b914cb26be | ||
|
|
97472e9a17 | ||
|
|
dece8c0daa | ||
|
|
5796d1af32 | ||
|
|
06d7a1df6b | ||
|
|
ed293ddad8 | ||
|
|
d7a92344e5 | ||
|
|
3fa020fe91 | ||
|
|
ce19af7da0 | ||
|
|
e558a9fc9d | ||
|
|
fb5544ce0f | ||
|
|
051f0d484c | ||
|
|
108cbea686 | ||
|
|
8b61bd7d8a | ||
|
|
1699a2b68a | ||
|
|
2fca95e81b | ||
|
|
969aa87a10 | ||
|
|
b3dfa7d7ce | ||
|
|
483de50169 | ||
|
|
96762ffa5c | ||
|
|
88d05c2354 | ||
|
|
8aac152ee6 | ||
|
|
d83779662a | ||
|
|
c19e656d46 | ||
|
|
4631a2f440 | ||
|
|
338f5811a1 | ||
|
|
bc634b2eeb | ||
|
|
23cbb9e261 | ||
|
|
fbfbf3c32b | ||
|
|
3073a2e90d | ||
|
|
29e4dc93ab | ||
|
|
2b16a20032 | ||
|
|
59b412899d | ||
|
|
e656ab5e1d | ||
|
|
b90c06da72 | ||
|
|
f62f3652e2 | ||
|
|
dbbec9d2bd | ||
|
|
1be8189058 | ||
|
|
b8b3160ccd | ||
|
|
54fd3995e6 | ||
|
|
e506190c7f | ||
|
|
8f418a0da9 | ||
|
|
0403ee91ea | ||
|
|
47d1856143 | ||
|
|
e521f0fea0 | ||
|
|
eb1e7fd15a | ||
|
|
c9e0a58232 | ||
|
|
9acd8b54e3 | ||
|
|
acd66b1634 | ||
|
|
3820855812 | ||
|
|
056abe7b68 | ||
|
|
bf05b1bda2 | ||
|
|
77a3c146c0 | ||
|
|
5761f7f543 | ||
|
|
5ed5b543ce |
10
.github/build/linux/dev/template.desktop
vendored
10
.github/build/linux/dev/template.desktop
vendored
@@ -1,10 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Name=Techmino Development
|
||||
Comment=Techmino is fun!
|
||||
MimeType=application/x-love-game;
|
||||
Exec=app %f
|
||||
Type=Application
|
||||
Categories=Game;
|
||||
Terminal=false
|
||||
Icon=icon
|
||||
NoDisplay=false
|
||||
1
.github/build/linux/release/.gitattributes
vendored
1
.github/build/linux/release/.gitattributes
vendored
@@ -1 +0,0 @@
|
||||
*.template text eol=lf
|
||||
10
.github/build/linux/release/template.desktop
vendored
10
.github/build/linux/release/template.desktop
vendored
@@ -1,10 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Name=Techmino
|
||||
Comment=Techmino is fun!
|
||||
MimeType=application/x-love-game;
|
||||
Exec=app %f
|
||||
Type=Application
|
||||
Categories=Game;
|
||||
Terminal=false
|
||||
Icon=icon
|
||||
NoDisplay=false
|
||||
7
.github/build/windows/dev/template.rc
vendored
7
.github/build/windows/dev/template.rc
vendored
@@ -8,9 +8,12 @@ FILETYPE 0x1
|
||||
{
|
||||
BLOCK "040904B0"
|
||||
{
|
||||
VALUE "FileDescription", "Techmino Development"
|
||||
VALUE "CompanyName", "26F Studio"
|
||||
VALUE "LegalCopyright", "Copyright @ 26F Studio"
|
||||
VALUE "FileDescription", "Techmino Development"
|
||||
VALUE "FileVersion", "@Version"
|
||||
VALUE "InternalName", "Techmino"
|
||||
VALUE "LegalCopyright", "Copyright © 2019-2023 26F-Studio. Some Rights Reserved."
|
||||
VALUE "OriginalFilename", "Techmino.exe"
|
||||
VALUE "ProductName", "Techmino"
|
||||
VALUE "ProductVersion", "@Version"
|
||||
}
|
||||
|
||||
7
.github/build/windows/release/template.rc
vendored
7
.github/build/windows/release/template.rc
vendored
@@ -8,9 +8,12 @@ FILETYPE 0x1
|
||||
{
|
||||
BLOCK "040904B0"
|
||||
{
|
||||
VALUE "FileDescription", "Techmino"
|
||||
VALUE "CompanyName", "26F Studio"
|
||||
VALUE "LegalCopyright", "Copyright @ 26F Studio"
|
||||
VALUE "FileDescription", "Techmino"
|
||||
VALUE "FileVersion", "@Version"
|
||||
VALUE "InternalName", "Techmino"
|
||||
VALUE "LegalCopyright", "Copyright © 2019-2023 26F-Studio. Some Rights Reserved."
|
||||
VALUE "OriginalFilename", "Techmino.exe"
|
||||
VALUE "ProductName", "Techmino"
|
||||
VALUE "ProductVersion", "@Version"
|
||||
}
|
||||
|
||||
189
.github/workflows/main.yml
vendored
189
.github/workflows/main.yml
vendored
@@ -99,6 +99,11 @@ jobs:
|
||||
with:
|
||||
name: ${{ env.CORE_LOVE_ARTIFACT_NAME }}
|
||||
path: ${{ env.CORE_LOVE_PACKAGE_PATH }}
|
||||
- name: Add icon to love package
|
||||
run: |
|
||||
cp ./.github/build/linux/${{ env.BUILD_TYPE }}/icon.png media/image/icon.png
|
||||
zip -u ${{ env.CORE_LOVE_PACKAGE_PATH }} media/image/icon.png
|
||||
rm media/image/icon.png
|
||||
- name: Rename love package
|
||||
run: |
|
||||
mkdir -p ${{ env.OUTPUT_FOLDER }}
|
||||
@@ -123,12 +128,20 @@ jobs:
|
||||
body: ${{ needs.get-info.outputs.update-note }}
|
||||
name: ${{ needs.get-info.outputs.update-title }}
|
||||
prerelease: ${{ startsWith(github.ref, 'refs/tags/pre') }}
|
||||
- name: Get transfer
|
||||
shell: bash
|
||||
run: |
|
||||
curl -sL --retry 5 https://raw.githubusercontent.com/Mikubill/transfer/master/install.sh | sh
|
||||
- name: Upload to WeTransfer
|
||||
id: transfer
|
||||
run: |
|
||||
curl -sL https://git.io/file-transfer | sh
|
||||
./transfer wet -s -p 16 --no-progress ${{ env.OUTPUT_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}.love 2>&1>./wetransfer.log
|
||||
echo "download-url=$(cat ./wetransfer.log | grep https | cut -f3 -d" ")" >> $GITHUB_OUTPUT
|
||||
uses: nick-fields/retry@v2
|
||||
with:
|
||||
max_attempts: 5
|
||||
retry_wait_seconds: 10
|
||||
timeout_minutes: 5
|
||||
command: |
|
||||
./transfer wet -s -p 16 --no-progress ${{ env.OUTPUT_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}.love 2>&1>./wetransfer.log
|
||||
echo "download-url=$(cat ./wetransfer.log | grep https | cut -f3 -d" ")" >> $GITHUB_OUTPUT
|
||||
|
||||
auto-test:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -163,12 +176,12 @@ jobs:
|
||||
import os
|
||||
import re
|
||||
with open(os.getenv('GITHUB_OUTPUT'), 'a') as f:
|
||||
if "${{ env.BUILD_TYPE }}" == "dev":
|
||||
if "${{ env.BUILD_TYPE }}" == "dev":
|
||||
f.write('bundle-id=org.f26_studio.' + re.sub(r'[^A-Za-z0-9]+', '_', '${{ needs.get-info.outputs.app-name }}') + '.snapshot\n')
|
||||
f.write('product-name=' + re.sub(r'[^A-Za-z0-9]+', '_', '${{ needs.get-info.outputs.app-name }}') + '_Snapshot\n')
|
||||
f.write('product-name=' + re.sub(r'[^A-Za-z0-9]+', '-', '${{ needs.get-info.outputs.app-name }}') + '_Snapshot\n')
|
||||
else:
|
||||
f.write('bundle-id=org.f26_studio.' + re.sub(r'[^A-Za-z0-9]+', '_', '${{ needs.get-info.outputs.app-name }}') + '\n')
|
||||
f.write('product-name=' + re.sub(r'[^A-Za-z0-9]+', '_', '${{ needs.get-info.outputs.app-name }}') + '\n')
|
||||
f.write('product-name=' + re.sub(r'[^A-Za-z0-9]+', '-', '${{ needs.get-info.outputs.app-name }}') + '\n')
|
||||
- name: Download core love package
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
@@ -180,7 +193,7 @@ jobs:
|
||||
dir: ./libAndroid
|
||||
- name: Build Android packages
|
||||
id: build-packages
|
||||
uses: love-actions/love-actions-android@v1
|
||||
uses: love-actions/love-actions-android@main
|
||||
with:
|
||||
app-name: ${{ needs.get-info.outputs.app-name }}
|
||||
bundle-id: ${{ steps.process-app-name.outputs.bundle-id }}
|
||||
@@ -192,6 +205,7 @@ jobs:
|
||||
love-package: ${{ env.CORE_LOVE_PACKAGE_PATH }}
|
||||
resource-path: ./.github/build/android/${{ env.BUILD_TYPE }}/res
|
||||
extra-assets: ./libAndroid/
|
||||
custom-scheme: studio26f://oauth
|
||||
product-name: ${{ steps.process-app-name.outputs.product-name }}
|
||||
version-string: ${{ needs.get-info.outputs.version-string }}
|
||||
version-code: ${{ needs.get-info.outputs.version-code }}
|
||||
@@ -216,12 +230,20 @@ jobs:
|
||||
body: ${{ needs.get-info.outputs.update-note }}
|
||||
name: ${{ needs.get-info.outputs.update-title }}
|
||||
prerelease: ${{ startsWith(github.ref, 'refs/tags/pre') }}
|
||||
- name: Get transfer
|
||||
shell: bash
|
||||
run: |
|
||||
curl -sL --retry 5 https://raw.githubusercontent.com/Mikubill/transfer/master/install.sh | sh
|
||||
- name: Upload to WeTransfer
|
||||
id: transfer
|
||||
run: |
|
||||
curl -sL https://git.io/file-transfer | sh
|
||||
./transfer wet -s -p 16 --no-progress ${{ steps.build-packages.outputs.package-paths }} 2>&1>./wetransfer.log
|
||||
echo "download-url=$(cat ./wetransfer.log | grep https | cut -f3 -d" ")" >> $GITHUB_OUTPUT
|
||||
uses: nick-fields/retry@v2
|
||||
with:
|
||||
max_attempts: 5
|
||||
retry_wait_seconds: 10
|
||||
timeout_minutes: 5
|
||||
command: |
|
||||
./transfer wet -s -p 16 --no-progress ${{ steps.build-packages.outputs.package-paths }} 2>&1>./wetransfer.log
|
||||
echo "download-url=$(cat ./wetransfer.log | grep https | cut -f3 -d" ")" >> $GITHUB_OUTPUT
|
||||
|
||||
build-ios:
|
||||
runs-on: macos-latest
|
||||
@@ -260,7 +282,7 @@ jobs:
|
||||
with:
|
||||
app-name: ${{ needs.get-info.outputs.app-name }}
|
||||
bundle-id: ${{ steps.process-app-name.outputs.bundle-id }}
|
||||
copyright: "Copyright © 2019-2022 26F-Studio. Some Rights Reserved."
|
||||
copyright: "Copyright © 2019-2023 26F-Studio. Some Rights Reserved."
|
||||
icon-path: ./.github/build/iOS/${{ env.BUILD_TYPE }}/icon
|
||||
love-patch: ./.github/build/iOS/love.patch
|
||||
love-package: ${{ env.CORE_LOVE_PACKAGE_PATH }}
|
||||
@@ -305,12 +327,20 @@ jobs:
|
||||
body: ${{ needs.get-info.outputs.update-note }}
|
||||
name: ${{ needs.get-info.outputs.update-title }}
|
||||
prerelease: ${{ startsWith(github.ref, 'refs/tags/pre') }}
|
||||
- name: Upload to WeTransfer
|
||||
id: transfer
|
||||
- name: Get transfer
|
||||
shell: bash
|
||||
run: |
|
||||
wget -qO- https://github.com/Mikubill/transfer/releases/download/v0.4.17/transfer_0.4.17_darwin_amd64.tar.gz | tar xvz
|
||||
./transfer wet -s -p 16 --no-progress ${{ steps.build-packages.outputs.package-paths }} 2>&1>./wetransfer.log
|
||||
echo "download-url=$(cat ./wetransfer.log | grep https | cut -f3 -d" ")" >> $GITHUB_OUTPUT
|
||||
- name: Upload to WeTransfer
|
||||
id: transfer
|
||||
uses: nick-fields/retry@v2
|
||||
with:
|
||||
max_attempts: 5
|
||||
retry_wait_seconds: 10
|
||||
timeout_minutes: 5
|
||||
command: |
|
||||
./transfer wet -s -p 16 --no-progress ${{ steps.build-packages.outputs.package-paths }} 2>&1>./wetransfer.log
|
||||
echo "download-url=$(cat ./wetransfer.log | grep https | cut -f3 -d" ")" >> $GITHUB_OUTPUT
|
||||
|
||||
build-linux:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -330,12 +360,20 @@ jobs:
|
||||
run: |
|
||||
import os
|
||||
import re
|
||||
|
||||
product_name = re.sub(r'[^A-Za-z0-9]+', '-', '${{ needs.get-info.outputs.app-name }}').strip('-').lower()
|
||||
with open(os.getenv('GITHUB_OUTPUT'), 'a') as f:
|
||||
f.write('product-name=' + re.sub(r'[^A-Za-z0-9]+', '_', '${{ needs.get-info.outputs.app-name }}') + '\n')
|
||||
f.write('bundle-id=org.26f-studio.' + product_name + '\n')
|
||||
f.write('product-name=' + product_name + '\n')
|
||||
- name: Download core love package
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: ${{ env.CORE_LOVE_ARTIFACT_NAME }}
|
||||
- name: Add icon to love package
|
||||
run: |
|
||||
cp ./.github/build/linux/${{ env.BUILD_TYPE }}/icon.png media/image/icon.png
|
||||
zip -u ${{ env.CORE_LOVE_PACKAGE_PATH }} media/image/icon.png
|
||||
rm media/image/icon.png
|
||||
- name: Download ColdClear
|
||||
uses: ./.github/actions/get-cc
|
||||
with:
|
||||
@@ -351,8 +389,10 @@ jobs:
|
||||
id: build-packages
|
||||
uses: love-actions/love-actions-linux@v1
|
||||
with:
|
||||
desktop-file-path: ./.github/build/linux/${{ env.BUILD_TYPE }}/template.desktop
|
||||
executable-name: app
|
||||
app-name: ${{ needs.get-info.outputs.app-name }}
|
||||
bundle-id: ${{ steps.process-app-name.outputs.bundle-id }}
|
||||
description: Techmino is fun!
|
||||
version-string: ${{ needs.get-info.outputs.version-string }}
|
||||
icon-path: ./.github/build/linux/${{ env.BUILD_TYPE }}/icon.png
|
||||
love-package: ${{ env.CORE_LOVE_PACKAGE_PATH }}
|
||||
lib-path: ./ColdClear/lib
|
||||
@@ -363,27 +403,43 @@ jobs:
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.base-name }}_Linux_AppImage
|
||||
path: ${{ env.OUTPUT_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}.AppImage
|
||||
- name: Upload Debian artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.base-name }}_Linux_Debian
|
||||
path: ${{ env.OUTPUT_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}.deb
|
||||
- name: Prepare for release
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/pre') || startsWith(github.ref, 'refs/tags/v') }}
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p ${{ env.RELEASE_FOLDER }}
|
||||
cp ${{ env.OUTPUT_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}.AppImage ${{ env.RELEASE_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}_Linux.AppImage
|
||||
cp ${{ env.OUTPUT_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}.deb ${{ env.RELEASE_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}_Linux.deb
|
||||
- name: Upload release
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/pre') || startsWith(github.ref, 'refs/tags/v') }}
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
allowUpdates: true
|
||||
artifacts: ${{ env.RELEASE_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}_Linux.AppImage
|
||||
artifacts: |
|
||||
${{ env.RELEASE_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}_Linux.AppImage
|
||||
${{ env.RELEASE_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}_Linux.deb
|
||||
body: ${{ needs.get-info.outputs.update-note }}
|
||||
name: ${{ needs.get-info.outputs.update-title }}
|
||||
prerelease: ${{ startsWith(github.ref, 'refs/tags/pre') }}
|
||||
- name: Get transfer
|
||||
shell: bash
|
||||
run: |
|
||||
curl -sL --retry 5 https://raw.githubusercontent.com/Mikubill/transfer/master/install.sh | sh
|
||||
- name: Upload to WeTransfer
|
||||
id: transfer
|
||||
run: |
|
||||
curl -sL https://git.io/file-transfer | sh
|
||||
./transfer wet -s -p 16 --no-progress ${{ steps.build-packages.outputs.package-paths }} 2>&1>./wetransfer.log
|
||||
echo "download-url=$(cat ./wetransfer.log | grep https | cut -f3 -d" ")" >> $GITHUB_OUTPUT
|
||||
uses: nick-fields/retry@v2
|
||||
with:
|
||||
max_attempts: 5
|
||||
retry_wait_seconds: 10
|
||||
timeout_minutes: 5
|
||||
command: |
|
||||
./transfer wet -s -p 16 --no-progress ${{ steps.build-packages.outputs.package-paths }} 2>&1>./wetransfer.log
|
||||
echo "download-url=$(cat ./wetransfer.log | grep https | cut -f3 -d" ")" >> $GITHUB_OUTPUT
|
||||
|
||||
build-macos-appstore:
|
||||
runs-on: macos-latest
|
||||
@@ -426,7 +482,7 @@ jobs:
|
||||
with:
|
||||
app-name: ${{ needs.get-info.outputs.app-name }}
|
||||
bundle-id: ${{ steps.process-app-name.outputs.bundle-id }}
|
||||
copyright: "Copyright © 2019-2022 26F-Studio. Some Rights Reserved."
|
||||
copyright: "Copyright © 2019-2023 26F-Studio. Some Rights Reserved."
|
||||
icon-path: ./.github/build/macOS/${{ env.BUILD_TYPE }}/icon.icns
|
||||
love-package: ${{ env.CORE_LOVE_PACKAGE_PATH }}
|
||||
libs-path: ./ColdClear/universal/
|
||||
@@ -470,12 +526,20 @@ jobs:
|
||||
body: ${{ needs.get-info.outputs.update-note }}
|
||||
name: ${{ needs.get-info.outputs.update-title }}
|
||||
prerelease: ${{ startsWith(github.ref, 'refs/tags/pre') }}
|
||||
- name: Upload to WeTransfer
|
||||
id: transfer
|
||||
- name: Get transfer
|
||||
shell: bash
|
||||
run: |
|
||||
wget -qO- https://github.com/Mikubill/transfer/releases/download/v0.4.17/transfer_0.4.17_darwin_amd64.tar.gz | tar xvz
|
||||
./transfer wet -s -p 16 --no-progress ${{ steps.build-packages.outputs.package-paths }} 2>&1>./wetransfer.log
|
||||
echo "download-url=$(cat ./wetransfer.log | grep https | cut -f3 -d" ")" >> $GITHUB_OUTPUT
|
||||
- name: Upload to WeTransfer
|
||||
id: transfer
|
||||
uses: nick-fields/retry@v2
|
||||
with:
|
||||
max_attempts: 5
|
||||
retry_wait_seconds: 10
|
||||
timeout_minutes: 5
|
||||
command: |
|
||||
./transfer wet -s -p 16 --no-progress ${{ steps.build-packages.outputs.package-paths }} 2>&1>./wetransfer.log
|
||||
echo "download-url=$(cat ./wetransfer.log | grep https | cut -f3 -d" ")" >> $GITHUB_OUTPUT
|
||||
|
||||
build-macos-portable:
|
||||
runs-on: macos-latest
|
||||
@@ -518,7 +582,7 @@ jobs:
|
||||
with:
|
||||
app-name: ${{ needs.get-info.outputs.app-name }}
|
||||
bundle-id: ${{ steps.process-app-name.outputs.bundle-id }}
|
||||
copyright: "Copyright © 2019-2022 26F-Studio. Some Rights Reserved."
|
||||
copyright: "Copyright © 2019-2023 26F-Studio. Some Rights Reserved."
|
||||
icon-path: ./.github/build/macOS/${{ env.BUILD_TYPE }}/icon.icns
|
||||
love-package: ${{ env.CORE_LOVE_PACKAGE_PATH }}
|
||||
libs-path: ./ColdClear/universal/
|
||||
@@ -568,16 +632,26 @@ jobs:
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
allowUpdates: true
|
||||
artifacts: ${{ env.RELEASE_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}_macOS_portable.pkg, ${{ env.RELEASE_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}_macOS_portable.dmg
|
||||
artifacts: |
|
||||
${{ env.RELEASE_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}_macOS_portable.pkg
|
||||
${{ env.RELEASE_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}_macOS_portable.dmg
|
||||
body: ${{ needs.get-info.outputs.update-note }}
|
||||
name: ${{ needs.get-info.outputs.update-title }}
|
||||
prerelease: ${{ startsWith(github.ref, 'refs/tags/pre') }}
|
||||
- name: Upload to WeTransfer
|
||||
id: transfer
|
||||
- name: Get transfer
|
||||
shell: bash
|
||||
run: |
|
||||
wget -qO- https://github.com/Mikubill/transfer/releases/download/v0.4.17/transfer_0.4.17_darwin_amd64.tar.gz | tar xvz
|
||||
./transfer wet -s -p 16 --no-progress ${{ steps.build-packages.outputs.package-paths }} 2>&1>./wetransfer.log
|
||||
echo "download-url=$(cat ./wetransfer.log | grep https | cut -f3 -d" ")" >> $GITHUB_OUTPUT
|
||||
- name: Upload to WeTransfer
|
||||
id: transfer
|
||||
uses: nick-fields/retry@v2
|
||||
with:
|
||||
max_attempts: 5
|
||||
retry_wait_seconds: 10
|
||||
timeout_minutes: 5
|
||||
command: |
|
||||
./transfer wet -s -p 16 --no-progress ${{ steps.build-packages.outputs.package-paths }} 2>&1>./wetransfer.log
|
||||
echo "download-url=$(cat ./wetransfer.log | grep https | cut -f3 -d" ")" >> $GITHUB_OUTPUT
|
||||
|
||||
build-windows:
|
||||
runs-on: windows-latest
|
||||
@@ -608,6 +682,19 @@ jobs:
|
||||
with:
|
||||
platform: Windows
|
||||
dir: ./ColdClear
|
||||
- name: Update Windows template
|
||||
shell: python3 {0}
|
||||
run: |
|
||||
version_string = "${{ needs.get-info.outputs.version-string }}"
|
||||
file_version = (f"{version_string.replace('.', ',')},0")
|
||||
with open("./.github/build/windows/${{ env.BUILD_TYPE }}/template.rc", "r+", encoding="utf8") as file:
|
||||
data = file.read()
|
||||
data = data\
|
||||
.replace("@Version", version_string)\
|
||||
.replace("@FileVersion", file_version)
|
||||
file.seek(0)
|
||||
file.truncate()
|
||||
file.write(data)
|
||||
- name: Build Windows packages
|
||||
id: build-packages
|
||||
uses: love-actions/love-actions-windows@v1
|
||||
@@ -618,7 +705,9 @@ jobs:
|
||||
extra-assets-x86: ./ColdClear/x86/CCloader.dll ./ColdClear/x86/cold_clear.dll
|
||||
extra-assets-x64: ./ColdClear/x64/CCloader.dll ./ColdClear/x64/cold_clear.dll
|
||||
product-name: ${{ steps.process-app-name.outputs.product-name }}
|
||||
version-string: ${{ needs.get-info.outputs.version-string }}
|
||||
app-id: ${{ secrets.WINDOWS_APP_ID }}
|
||||
project-website: https://www.studio26f.org/
|
||||
installer-languages: ChineseSimplified.isl ChineseTraditional.isl English.isl Spanish.isl French.isl Indonesian.isl Japanese.isl Portuguese.isl
|
||||
output-folder: ${{ env.OUTPUT_FOLDER }}
|
||||
- name: Upload 32-bit artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
@@ -630,6 +719,11 @@ jobs:
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.base-name }}_Windows_x64
|
||||
path: ${{ env.OUTPUT_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}_x64.zip
|
||||
- name: Upload installer artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ needs.get-info.outputs.base-name }}_Windows_installer
|
||||
path: ${{ env.OUTPUT_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}_installer.exe
|
||||
- name: Prepare for release
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/pre') || startsWith(github.ref, 'refs/tags/v') }}
|
||||
shell: bash
|
||||
@@ -637,12 +731,16 @@ jobs:
|
||||
mkdir -p ${{ env.RELEASE_FOLDER }}
|
||||
cp ${{ env.OUTPUT_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}_x86.zip ${{ env.RELEASE_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}_Windows_x86.zip
|
||||
cp ${{ env.OUTPUT_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}_x64.zip ${{ env.RELEASE_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}_Windows_x64.zip
|
||||
cp ${{ env.OUTPUT_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}_installer.exe ${{ env.RELEASE_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}_Windows_installer.exe
|
||||
- name: Upload release
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/pre') || startsWith(github.ref, 'refs/tags/v') }}
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
allowUpdates: true
|
||||
artifacts: ${{ env.RELEASE_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}_Windows_x86.zip, ${{ env.RELEASE_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}_Windows_x64.zip
|
||||
artifacts: |
|
||||
${{ env.RELEASE_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}_Windows_x86.zip
|
||||
${{ env.RELEASE_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}_Windows_x64.zip
|
||||
${{ env.RELEASE_FOLDER }}/${{ steps.process-app-name.outputs.product-name }}_Windows_installer.exe
|
||||
body: ${{ needs.get-info.outputs.update-note }}
|
||||
name: ${{ needs.get-info.outputs.update-title }}
|
||||
prerelease: ${{ startsWith(github.ref, 'refs/tags/pre') }}
|
||||
@@ -651,15 +749,20 @@ jobs:
|
||||
TEMP_PATH: ./temp.zip
|
||||
shell: bash
|
||||
run: |
|
||||
curl -L --retry 5 https://github.com/Mikubill/transfer/releases/download/v0.4.17/transfer_0.4.17_windows_amd64.zip -o ${{ env.TEMP_PATH }}
|
||||
curl -sL --retry 5 https://github.com/Mikubill/transfer/releases/download/v0.4.17/transfer_0.4.17_windows_amd64.zip -o ${{ env.TEMP_PATH }}
|
||||
7z x ${{ env.TEMP_PATH }} -o./
|
||||
rm ${{ env.TEMP_PATH }}
|
||||
- name: Upload to WeTransfer
|
||||
id: transfer
|
||||
shell: pwsh
|
||||
run: |
|
||||
./transfer.exe wet -s -p 16 --no-progress ${{ steps.build-packages.outputs.package-paths }} 2>&1>./wetransfer.log
|
||||
"download-url=$(cat ./wetransfer.log | grep https | cut -f3 -d" ")" >> $env:GITHUB_OUTPUT
|
||||
uses: nick-fields/retry@v2
|
||||
with:
|
||||
max_attempts: 5
|
||||
retry_wait_seconds: 10
|
||||
shell: pwsh
|
||||
timeout_minutes: 5
|
||||
command: |
|
||||
./transfer.exe wet -s -p 16 --no-progress ${{ steps.build-packages.outputs.package-paths }} 2>&1>./wetransfer.log
|
||||
"download-url=$(cat ./wetransfer.log | grep https | cut -f3 -d" ")" >> $env:GITHUB_OUTPUT
|
||||
|
||||
post-build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
69
conf.lua
69
conf.lua
@@ -1,28 +1,63 @@
|
||||
SYSTEM=love._os if SYSTEM=='OS X' then SYSTEM='macOS' end
|
||||
MOBILE=SYSTEM=='Android' or SYSTEM=='iOS'
|
||||
FNNS=SYSTEM:find'\79\83'-- What does FNSF stand for? IDK so don't ask me lol
|
||||
|
||||
function love.conf(t)
|
||||
t.identity='Techmino'-- Saving folder
|
||||
t.version="11.1"
|
||||
local identity='Techmino'
|
||||
local msaa=0
|
||||
local portrait=false
|
||||
|
||||
local fs=love.filesystem
|
||||
fs.setIdentity(identity)
|
||||
do -- Load grapgic settings from conf/settings
|
||||
local fileData=fs.read('conf/settings')
|
||||
if fileData then
|
||||
msaa=tonumber(fileData:match('"msaa":(%d+)')) or 0;
|
||||
portrait=MOBILE and fileData:find('"portrait":true') and true
|
||||
end
|
||||
end
|
||||
|
||||
t.identity=identity -- Saving folder
|
||||
t.version="11.4"
|
||||
t.gammacorrect=false
|
||||
t.appendidentity=true-- Search files in source then in save directory
|
||||
t.accelerometerjoystick=false-- Accelerometer=joystick on ios/android
|
||||
t.appendidentity=true -- Search files in source then in save directory
|
||||
t.accelerometerjoystick=false -- Accelerometer=joystick on ios/android
|
||||
if t.audio then
|
||||
t.audio.mic=false
|
||||
t.audio.mixwithsystem=true
|
||||
end
|
||||
|
||||
local W=t.window
|
||||
W.title="Techmino "..require"version".string
|
||||
W.width,W.height=1280,720
|
||||
W.minwidth,W.minheight=640,360
|
||||
W.borderless=false
|
||||
W.resizable=true
|
||||
W.fullscreen=false
|
||||
W.vsync=0-- Unlimited FPS
|
||||
W.msaa=0-- Multi-sampled antialiasing
|
||||
W.depth=0-- Bits/samp of depth buffer
|
||||
W.stencil=1-- Bits/samp of stencil buffer
|
||||
W.display=1-- Monitor ID
|
||||
W.highdpi=true-- High-dpi mode for the window on a Retina display
|
||||
W.x,W.y=nil
|
||||
W.title="Techmino "..require "version".string
|
||||
if portrait then
|
||||
W.width,W.height=720,1280
|
||||
W.minwidth,W.minheight=360,640
|
||||
else
|
||||
W.width,W.height=1280,720
|
||||
W.minwidth,W.minheight=640,360
|
||||
end
|
||||
|
||||
W.vsync=0 -- Unlimited FPS
|
||||
W.msaa=msaa -- Multi-sampled antialiasing
|
||||
W.depth=0 -- Bits/samp of depth buffer
|
||||
W.stencil=1 -- Bits/samp of stencil buffer
|
||||
W.display=1 -- Monitor ID
|
||||
W.highdpi=true -- High-dpi mode for the window on a Retina display
|
||||
W.x,W.y=nil,nil -- Position of the window
|
||||
|
||||
if fs.getInfo('media/image/icon.png') then
|
||||
W.icon='media/image/icon.png'
|
||||
end
|
||||
|
||||
if MOBILE then
|
||||
W.borderless=true
|
||||
W.resizable=false
|
||||
W.fullscreen=true
|
||||
else
|
||||
W.borderless=false
|
||||
W.resizable=true
|
||||
W.fullscreen=false
|
||||
end
|
||||
|
||||
local M=t.modules
|
||||
M.window,M.system,M.event,M.thread=true,true,true,true
|
||||
|
||||
22
main.lua
22
main.lua
@@ -22,9 +22,6 @@
|
||||
local fs=love.filesystem
|
||||
VERSION=require"version"
|
||||
TIME=love.timer.getTime
|
||||
SYSTEM=love.system.getOS() if SYSTEM=='OS X' then SYSTEM='macOS' end
|
||||
FNNS=SYSTEM:find'\79\83'-- What does FNSF stand for? IDK so don't ask me lol
|
||||
MOBILE=SYSTEM=='Android' or SYSTEM=='iOS'
|
||||
|
||||
-- Global Vars & Settings
|
||||
SFXPACKS={'chiptune'}
|
||||
@@ -37,11 +34,6 @@ math.randomseed(os.time()*626)
|
||||
love.setDeprecationOutput(false)
|
||||
love.keyboard.setKeyRepeat(true)
|
||||
love.keyboard.setTextInput(false)
|
||||
if MOBILE then
|
||||
local w,h,f=love.window.getMode()
|
||||
f.resizable=false
|
||||
love.window.setMode(w,h,f)
|
||||
end
|
||||
|
||||
local _LOADTIMELIST_={}
|
||||
local _LOADTIME_=TIME()
|
||||
@@ -183,7 +175,7 @@ Z.setOnFnKeys({
|
||||
function() MES.new('error',"挂了") end,
|
||||
function()
|
||||
if GAME.playing and not GAME.net then
|
||||
for _=1,8 do
|
||||
for _=1,1 do
|
||||
if #PLY_ALIVE>1 then
|
||||
local P=PLY_ALIVE[math.random(2,#PLY_ALIVE)]
|
||||
P.lastRecv=PLAYERS[1]
|
||||
@@ -197,9 +189,11 @@ Z.setOnFnKeys({
|
||||
function() if love['_openConsole'] then love['_openConsole']() end end,
|
||||
})
|
||||
Z.setOnGlobalKey('f11',function()
|
||||
SETTING.fullscreen=not SETTING.fullscreen
|
||||
applySettings()
|
||||
saveSettings()
|
||||
if not MOBILE then
|
||||
SETTING.fullscreen=not SETTING.fullscreen
|
||||
applySettings()
|
||||
saveSettings()
|
||||
end
|
||||
end)
|
||||
Z.setVersionText(VERSION.string)
|
||||
Z.setDebugInfo{
|
||||
@@ -523,7 +517,7 @@ LANG.init('zh',
|
||||
local mes="No Text ("..SETTING.locale.."): "..k
|
||||
LOG(mes)
|
||||
MES.new('warn',mes)
|
||||
self[k]=CHAR.zChan.thinking
|
||||
self[k]="["..k.."]"
|
||||
return self[k]
|
||||
end})
|
||||
end
|
||||
@@ -607,6 +601,8 @@ for _,fileName in next,fs.getDirectoryItems('replay') do
|
||||
end
|
||||
table.sort(REPLAY,function(a,b) return a.fileName>b.fileName end)
|
||||
|
||||
AUTHURL="https://studio26f.org/oauth?product=techmino"
|
||||
AUTHHOST="cafuuchino1.3322.org:8081"
|
||||
WS.switchHost('cafuuchino1.3322.org','10026','/techmino/ws/v1')
|
||||
HTTP.setHost("cafuuchino1.3322.org:10026")
|
||||
HTTP.setThreadCount(1)
|
||||
|
||||
Binary file not shown.
@@ -938,6 +938,40 @@ do
|
||||
}
|
||||
end
|
||||
|
||||
local N64
|
||||
do
|
||||
local R={'+0+0','+0-1','+1+0','-1+0','+0+1'}
|
||||
local L={'+0+0','+0-1','-1+0','+1+0','+0+1'}
|
||||
N64={
|
||||
centerTex=GC.DO{10,10,
|
||||
{'setLW',2},
|
||||
{'line',2,9,2,1,8,9,8,1},
|
||||
},
|
||||
kickTable=TABLE.new({
|
||||
[01]=R,[10]=L,[12]=R,[21]=L,
|
||||
[23]=R,[32]=L,[30]=R,[03]=L,
|
||||
},29)
|
||||
}
|
||||
end
|
||||
|
||||
local N64_plus
|
||||
do
|
||||
local R={'+0+0','+0-1','+1+0','-1+0','+0+1'}
|
||||
local L={'+0+0','+0-1','-1+0','+1+0','+0+1'}
|
||||
local F={'+0+0','+0-1','+0+1'}
|
||||
N64_plus={
|
||||
centerTex=GC.DO{10,10,
|
||||
{'setLW',2},
|
||||
{'line',4,9,2,9,2,1,8,9,8,1,6,1},
|
||||
},
|
||||
kickTable=TABLE.new({
|
||||
[01]=R,[10]=L,[12]=R,[21]=L,
|
||||
[23]=R,[32]=L,[30]=R,[03]=L,
|
||||
[02]=F,[20]=F,[13]=F,[31]=F,
|
||||
},29)
|
||||
}
|
||||
end
|
||||
|
||||
local Classic do
|
||||
local centerPos=TABLE.copy(defaultCenterPos)
|
||||
centerPos[1]={[0]={1,1},{1,0},{1,1},{1,0}}
|
||||
@@ -978,7 +1012,7 @@ local None={
|
||||
{'setLW',2},
|
||||
{'line',2,2,6,6},
|
||||
},
|
||||
kickTable=TABLE.new(noKickSet_180,29)
|
||||
kickTable=TABLE.new(noKickSet,29)
|
||||
}
|
||||
|
||||
local None_plus={
|
||||
@@ -987,7 +1021,7 @@ local None_plus={
|
||||
{'line',1,1,7,7},
|
||||
{'fRect',2,2,4,4},
|
||||
},
|
||||
kickTable=TABLE.new(noKickSet,29)
|
||||
kickTable=TABLE.new(noKickSet_180,29)
|
||||
}
|
||||
|
||||
local RSlist={
|
||||
@@ -1002,6 +1036,8 @@ local RSlist={
|
||||
ASC_plus=ASC_plus,
|
||||
C2=C2,
|
||||
C2_sym=C2_sym,
|
||||
N64=N64,
|
||||
N64_plus=N64_plus,
|
||||
Classic=Classic,
|
||||
Classic_plus=Classic_plus,
|
||||
None=None,
|
||||
|
||||
@@ -30,11 +30,11 @@ function back.draw()
|
||||
for i=1,#sDist do
|
||||
local d,r=sDist[i],sRev[i]
|
||||
if d<5 then
|
||||
setColor(hsv(.088,(d-2)/7,1,.7))
|
||||
setColor(hsv(.088,(d-2)/7,1,.2))
|
||||
else
|
||||
setColor(hsv(.572,d/70+.1,(22-d)/12,.7))
|
||||
setColor(hsv(.572,d/70+.1,(22-d)/12,.2))
|
||||
end
|
||||
circle('fill',8*d*cos(r),24*d*sin(r),3)
|
||||
circle('fill',8*d*cos(r),24*d*sin(r),5)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
local gc=love.graphics
|
||||
local hsv=COLOR.hsv
|
||||
local circle,push,pop,rot,translate,setColor=gc.circle,gc.push,gc.pop,gc.rotate,gc.translate,gc.setColor
|
||||
local rnd,sin,cos,log,ceil=math.random,math.sin,math.cos,math.log,math.ceil
|
||||
local rnd,sin,cos,log=math.random,math.sin,math.cos,math.log
|
||||
local back={}
|
||||
|
||||
local qX,qY,qdX,qdY={},{},{},{} -- quark data in SoA [size, X, Y, dx, dy, color]
|
||||
|
||||
local ptcclr={{1,0,0},{0,1,0},{0,0,1}}
|
||||
local apcclr={{0,1,1},{1,0,1},{1,1,0}}
|
||||
local ptcclr={{1,0,0,.5},{0,1,0,.5},{0,0,1,.5}}
|
||||
local apcclr={{0,1,1,.5},{1,0,1,.5},{1,1,0,.5}}
|
||||
|
||||
local blasts={} -- data about annihilation blasts from particles and antiparticles colliding
|
||||
local ptc={} -- particle-antiparticle data (antiparticle is a mirror of particle)
|
||||
@@ -115,9 +115,9 @@ function back.draw()
|
||||
translate(-10,-10)
|
||||
|
||||
-- Draw quarks in R/G/B
|
||||
setColor(1,0,0,.8) for i=1, math.floor(quarkCount/3) do circle('fill',qX[i],qY[i],size) end
|
||||
setColor(0,1,0,.8) for i=math.floor(quarkCount/3)+1, math.floor(quarkCount*2/3) do circle('fill',qX[i],qY[i],size) end
|
||||
setColor(0,0,1,.8) for i=math.floor(quarkCount*2/3)+1,quarkCount do circle('fill',qX[i],qY[i],size) end
|
||||
setColor(1,0,0,.5) for i=1, math.floor(quarkCount/3) do circle('fill',qX[i],qY[i],size) end
|
||||
setColor(0,1,0,.5) for i=math.floor(quarkCount/3)+1, math.floor(quarkCount*2/3) do circle('fill',qX[i],qY[i],size) end
|
||||
setColor(0,0,1,.5) for i=math.floor(quarkCount*2/3)+1,quarkCount do circle('fill',qX[i],qY[i],size) end
|
||||
|
||||
for i=1,#ptc do
|
||||
local p=ptc[i]
|
||||
|
||||
@@ -22,7 +22,7 @@ function bot_cc:checkDest(b2b,atk,exblock,yomi)
|
||||
for k=1,#dest,2 do
|
||||
local r=CB[dest[k+1]-self.P.curY+2]
|
||||
if not r or not r[dest[k]-self.P.curX+2] then
|
||||
print('wrong place')
|
||||
-- print('wrong place')
|
||||
self:lockWrongPlace()
|
||||
self.P.destFX=nil
|
||||
return
|
||||
@@ -31,8 +31,8 @@ function bot_cc:checkDest(b2b,atk,exblock,yomi)
|
||||
local should_spawn = self.P:getNextSpawn() - 1
|
||||
if dest.spawn ~= should_spawn then
|
||||
assert(dest.spawn > should_spawn)
|
||||
print('wrong spawn: should be '..dest.spawn..' but '..should_spawn)
|
||||
print('-- should only happen when camera is going down')
|
||||
-- print('wrong spawn: should be '..dest.spawn..' but '..should_spawn)
|
||||
-- print('-- should only happen when camera is going down')
|
||||
self:lockWrongPlace()
|
||||
self.P.destFX=nil
|
||||
return
|
||||
|
||||
Binary file not shown.
@@ -608,68 +608,295 @@ function trySave()
|
||||
end
|
||||
end
|
||||
do-- function freshPlayerPosition(sudden)
|
||||
local posLists={
|
||||
-- 1~5
|
||||
{
|
||||
{340,75,1},
|
||||
{965,390,.5},
|
||||
{965,30,.5},
|
||||
{20,390,.5},
|
||||
{20,30,.5},
|
||||
local posLists=setmetatable({
|
||||
alive={
|
||||
[1]={main={340,75,1}},
|
||||
[3]={main={340,75,1},
|
||||
{25,210,.5},
|
||||
{955,210,.5},
|
||||
},
|
||||
[4]={main={340,75,1},
|
||||
{25,210,.5},
|
||||
{970,90,.45},{970,410,.45},
|
||||
},
|
||||
[5]={main={340,75,1},
|
||||
{40,90,.45},{40,410,.45},
|
||||
{970,90,.45},{970,410,.45},
|
||||
},
|
||||
[6]={main={340,75,1},
|
||||
{40,90,.45},{40,410,.45},
|
||||
{1010,80,.305},{1010,290,.305},{1010,500,.305},
|
||||
},
|
||||
[7]={main={340,75,1},
|
||||
{100,80,.305},{100,290,.305},{100,500,.305},
|
||||
{1010,80,.305},{1010,290,.305},{1010,500,.305},
|
||||
},
|
||||
[10]={main={340,75,1},
|
||||
{100,80,.305},{100,290,.305},{100,500,.305},
|
||||
{935,90,.275},{935,300,.275},{935,510,.275},
|
||||
{1105,90,.275},{1105,300,.275},{1105,510,.275},
|
||||
},
|
||||
[13]={main={340,75,1},
|
||||
{10,90,.275},{10,300,.275},{10,510,.275},
|
||||
{180,90,.275},{180,300,.275},{180,510,.275},
|
||||
{935,90,.275},{935,300,.275},{935,510,.275},
|
||||
{1105,90,.275},{1105,300,.275},{1105,510,.275},
|
||||
},
|
||||
[14]={main={340,75,1},
|
||||
{10,90,.275},{10,300,.275},{10,510,.275},
|
||||
{180,90,.275},{180,300,.275},{180,510,.275},
|
||||
{935,90,.275},{935,300,.275},{935,510,.275},
|
||||
{1120,80,.225},{1120,240,.225},{1120,400,.225},{1120,560,.225},
|
||||
},
|
||||
[15]={main={340,75,1},
|
||||
{10,90,.275},{10,300,.275},{10,510,.275},
|
||||
{180,90,.275},{180,300,.275},{180,510,.275},
|
||||
{960,80,.225},{960,240,.225},{960,400,.225},{960,560,.225},
|
||||
{1120,80,.225},{1120,240,.225},{1120,400,.225},{1120,560,.225},
|
||||
},
|
||||
[16]={main={340,75,1},
|
||||
{10,90,.275},{10,300,.275},{10,510,.275},
|
||||
{190,80,.225},{190,240,.225},{190,400,.225},{190,560,.225},
|
||||
{960,80,.225},{960,240,.225},{960,400,.225},{960,560,.225},
|
||||
{1120,80,.225},{1120,240,.225},{1120,400,.225},{1120,560,.225},
|
||||
},
|
||||
[17]={main={340,75,1},
|
||||
{30,80,.225},{30,240,.225},{30,400,.225},{30,560,.225},
|
||||
{190,80,.225},{190,240,.225},{190,400,.225},{190,560,.225},
|
||||
{960,80,.225},{960,240,.225},{960,400,.225},{960,560,.225},
|
||||
{1120,80,.225},{1120,240,.225},{1120,400,.225},{1120,560,.225},
|
||||
},
|
||||
[24]={main={340,75,1},
|
||||
{30,80,.225},{30,240,.225},{30,400,.225},{30,560,.225},
|
||||
{190,80,.225},{190,240,.225},{190,400,.225},{190,560,.225},
|
||||
{940,80,.175},{940,205,.175},{940,330,.175},{940,455,.175},{940,580,.175},
|
||||
{1050,80,.175},{1050,205,.175},{1050,330,.175},{1050,455,.175},{1050,580,.175},
|
||||
{1160,80,.175},{1160,205,.175},{1160,330,.175},{1160,455,.175},{1160,580,.175},
|
||||
},
|
||||
[31]={main={340,75,1},
|
||||
{10,80,.175},{10,205,.175},{10,330,.175},{10,455,.175},{10,580,.175},
|
||||
{120,80,.175},{120,205,.175},{120,330,.175},{120,455,.175},{120,580,.175},
|
||||
{230,80,.175},{230,205,.175},{230,330,.175},{230,455,.175},{230,580,.175},
|
||||
{940,80,.175},{940,205,.175},{940,330,.175},{940,455,.175},{940,580,.175},
|
||||
{1050,80,.175},{1050,205,.175},{1050,330,.175},{1050,455,.175},{1050,580,.175},
|
||||
{1160,80,.175},{1160,205,.175},{1160,330,.175},{1160,455,.175},{1160,580,.175},
|
||||
},
|
||||
[33]=(function()
|
||||
local l={main={340,75,1}}
|
||||
for y=-1.5,1.5 do for x=0,3 do
|
||||
table.insert(l,{265-85*x,310+160*y,.125})
|
||||
table.insert(l,{940+85*x,310+160*y,.125})
|
||||
end end
|
||||
return l
|
||||
end)(),
|
||||
[51]=(function()
|
||||
local l={main={340,75,1}}
|
||||
for y=-2,2 do for x=0,4 do
|
||||
table.insert(l,{275-65*x,315+125*y,.1})
|
||||
table.insert(l,{945+65*x,315+125*y,.1})
|
||||
end end
|
||||
return l
|
||||
end)(),
|
||||
[75]=(function()
|
||||
local l={main={340,75,1}}
|
||||
for y=-2,2 do for x=0,4 do
|
||||
table.insert(l,{275-65*x,310+125*y,.1})
|
||||
end end
|
||||
for y=-3,3 do for x=0,6 do
|
||||
table.insert(l,{940+47*x,340+92*y,.075})
|
||||
end end
|
||||
return l
|
||||
end)(),
|
||||
[99]=(function()
|
||||
local l={main={340,75,1}}
|
||||
for y=-3,3 do for x=0,6 do
|
||||
table.insert(l,{290-47*x,340+92*y,.075})
|
||||
table.insert(l,{940+47*x,340+92*y,.075})
|
||||
end end
|
||||
return l
|
||||
end)(),
|
||||
[MATH.inf]=(function()
|
||||
local l={main={340,75,1}}
|
||||
for y=-3,3 do for x=0,6 do
|
||||
table.insert(l,{290-47*x,340+92*y,.075})
|
||||
table.insert(l,{940+47*x,340+92*y,.075})
|
||||
end end
|
||||
return l
|
||||
end)(),
|
||||
},
|
||||
-- 6~17
|
||||
(function()
|
||||
local L={{340,75,1}}
|
||||
for i=1,4 do ins(L,{15,-160+180*i,.25}) end
|
||||
for i=1,4 do ins(L,{180,-160+180*i,.25}) end
|
||||
for i=1,4 do ins(L,{950,-160+180*i,.25}) end
|
||||
for i=1,4 do ins(L,{1120,-160+180*i,.25}) end
|
||||
return L
|
||||
end)(),
|
||||
-- 18~31
|
||||
(function()
|
||||
local L={{340,75,1}}
|
||||
for i=1,5 do ins(L,{10, -100+135*i,.18}) end
|
||||
for i=1,5 do ins(L,{120, -100+135*i,.18}) end
|
||||
for i=1,5 do ins(L,{230, -100+135*i,.18}) end
|
||||
for i=1,5 do ins(L,{940, -100+135*i,.18}) end
|
||||
for i=1,5 do ins(L,{1050,-100+135*i,.18}) end
|
||||
for i=1,5 do ins(L,{1160,-100+135*i,.18}) end
|
||||
return L
|
||||
end)(),
|
||||
-- 32~49
|
||||
(function()
|
||||
local L={{340,75,1}}
|
||||
for i=1,4 do for j=1,6 do ins(L,{78*i-54,115*j-98,.09}) end end
|
||||
for i=9,12 do for j=1,6 do ins(L,{78*i+267,115*j-98,.09}) end end
|
||||
return L
|
||||
end)(),
|
||||
-- 50~99
|
||||
(function()
|
||||
local L={{340,75,1}}
|
||||
for i=1,7 do for j=1,7 do ins(L,{46*i-36,97*j-72,.068}) end end
|
||||
for i=15,21 do for j=1,7 do ins(L,{46*i+264,97*j-72,.068}) end end
|
||||
return L
|
||||
end)(),
|
||||
}
|
||||
function freshPlayerPosition(sudden)-- Set initial position for every player
|
||||
dead={
|
||||
[1]={{340,75,1}},
|
||||
[2]={
|
||||
{50,130,.925},{670,130,.925},
|
||||
},
|
||||
[3]={
|
||||
{25,160,.675},{440,160,.675},{855,160,.675},
|
||||
},
|
||||
[4]={
|
||||
{13,200,.525},{328,200,.525},{643,200,.525},{948,200,.525},
|
||||
},
|
||||
[5]={
|
||||
{8,230,.425},{260,230,.425},{512,230,.425},{764,230,.425},{1016,230,.425},
|
||||
},
|
||||
[10]={
|
||||
{8,110,.425},{260,110,.425},{512,110,.425},{764,110,.425},{1016,110,.425},
|
||||
{8,410,.425},{260,410,.425},{512,410,.425},{764,410,.425},{1016,410,.425},
|
||||
},
|
||||
[12]={
|
||||
{10,120,.35},{220,120,.35},{430,120,.35},{640,120,.35},{850,120,.35},{1060,120,.35},
|
||||
{10,400,.35},{220,400,.35},{430,400,.35},{640,400,.35},{850,400,.35},{1060,400,.35},
|
||||
},
|
||||
[18]={
|
||||
{10,90,.305},{220,90,.305},{430,90,.305},{640,90,.305},{850,90,.305},{1060,90,.305},
|
||||
{10,300,.305},{220,300,.305},{430,300,.305},{640,300,.305},{850,300,.305},{1060,300,.305},
|
||||
{10,510,.305},{220,510,.305},{430,510,.305},{640,510,.305},{850,510,.305},{1060,510,.305},
|
||||
},
|
||||
[21]={
|
||||
{10,90,.295},{190,90,.295},{370,90,.295},{550,90,.295},{730,90,.295},{910,90,.295},{1090,90,.295},
|
||||
{10,300,.295},{190,300,.295},{370,300,.295},{550,300,.295},{730,300,.295},{910,300,.295},{1090,300,.295},
|
||||
{10,510,.295},{190,510,.295},{370,510,.295},{550,510,.295},{730,510,.295},{910,510,.295},{1090,510,.295},
|
||||
},
|
||||
[24]={
|
||||
{20,100,.25},{175,100,.25},{330,100,.25},{485,100,.25},{640,100,.25},{795,100,.25},{950,100,.25},{1105,100,.25},
|
||||
{20,300,.25},{175,300,.25},{330,300,.25},{485,300,.25},{640,300,.25},{795,300,.25},{950,300,.25},{1105,300,.25},
|
||||
{20,500,.25},{175,500,.25},{330,500,.25},{485,500,.25},{640,500,.25},{795,500,.25},{950,500,.25},{1105,500,.25},
|
||||
},
|
||||
[27]={
|
||||
{10,100,.225},{150,100,.225},{290,100,.225},{430,100,.225},{570,100,.225},{710,100,.225},{850,100,.225},{990,100,.225},{1130,100,.225},
|
||||
{10,300,.225},{150,300,.225},{290,300,.225},{430,300,.225},{570,300,.225},{710,300,.225},{850,300,.225},{990,300,.225},{1130,300,.225},
|
||||
{10,500,.225},{150,500,.225},{290,500,.225},{430,500,.225},{570,500,.225},{710,500,.225},{850,500,.225},{990,500,.225},{1130,500,.225},
|
||||
},
|
||||
[36]={
|
||||
{10,90,.225},{150,90,.225},{290,90,.225},{430,90,.225},{570,90,.225},{710,90,.225},{850,90,.225},{990,90,.225},{1130,90,.225},
|
||||
{10,245,.225},{150,245,.225},{290,245,.225},{430,245,.225},{570,245,.225},{710,245,.225},{850,245,.225},{990,245,.225},{1130,245,.225},
|
||||
{10,400,.225},{150,400,.225},{290,400,.225},{430,400,.225},{570,400,.225},{710,400,.225},{850,400,.225},{990,400,.225},{1130,400,.225},
|
||||
{10,555,.225},{150,555,.225},{290,555,.225},{430,555,.225},{570,555,.225},{710,555,.225},{850,555,.225},{990,555,.225},{1130,555,.225},
|
||||
},
|
||||
[39]=(function()
|
||||
local l={}
|
||||
for y=0,2 do for x=0,12 do
|
||||
table.insert(l,{13+97*x,110+190*y,.15})
|
||||
end end
|
||||
return l
|
||||
end)(),
|
||||
[42]=(function()
|
||||
local l={}
|
||||
for y=0,2 do for x=0,13 do
|
||||
table.insert(l,{15+90*x,120+190*y,.135})
|
||||
end end
|
||||
return l
|
||||
end)(),
|
||||
[45]=(function()
|
||||
local l={}
|
||||
for y=0,2 do for x=0,14 do
|
||||
table.insert(l,{8+85*x,120+190*y,.125})
|
||||
end end
|
||||
return l
|
||||
end)(),
|
||||
[60]=(function()
|
||||
local l={}
|
||||
for y=0,3 do for x=0,14 do
|
||||
table.insert(l,{8+85*x,85+155*y,.125})
|
||||
end end
|
||||
return l
|
||||
end)(),
|
||||
[64]=(function()
|
||||
local l={}
|
||||
for y=0,3 do for x=0,15 do
|
||||
table.insert(l,{13+79*x,85+155*y,.115})
|
||||
end end
|
||||
return l
|
||||
end)(),
|
||||
[68]=(function()
|
||||
local l={}
|
||||
for y=0,3 do for x=0,16 do
|
||||
table.insert(l,{6+75*x,85+155*y,.115})
|
||||
end end
|
||||
return l
|
||||
end)(),
|
||||
[72]=(function()
|
||||
local l={}
|
||||
for y=0,3 do for x=0,17 do
|
||||
table.insert(l,{15+70*x,95+155*y,.1})
|
||||
end end
|
||||
return l
|
||||
end)(),
|
||||
[90]=(function()
|
||||
local l={}
|
||||
for y=0,4 do for x=0,17 do
|
||||
table.insert(l,{15+70*x,82+127*y,.1})
|
||||
end end
|
||||
return l
|
||||
end)(),
|
||||
[95]=(function()
|
||||
local l={}
|
||||
for y=0,4 do for x=0,18 do
|
||||
table.insert(l,{15+66*x,82+127*y,.1})
|
||||
end end
|
||||
return l
|
||||
end)(),
|
||||
[100]=(function()
|
||||
local l={}
|
||||
for y=0,4 do for x=0,19 do
|
||||
table.insert(l,{12+63*x,82+127*y,.1})
|
||||
end end
|
||||
return l
|
||||
end)(),
|
||||
[MATH.inf]={},
|
||||
},
|
||||
}, {
|
||||
__call=function(self,alive,count)
|
||||
local lastTested=MATH.inf
|
||||
for k in next,self[alive and 'alive' or 'dead'] do
|
||||
if k<lastTested and k>=count then
|
||||
lastTested=k
|
||||
end
|
||||
end
|
||||
return self[alive and 'alive' or 'dead'][lastTested]
|
||||
end,
|
||||
})
|
||||
|
||||
function freshPlayerPosition(mode)-- Set initial position for every player, mode: 'normal'|'quick'|'update'
|
||||
assert(mode=='normal' or mode=='quick' or mode=='update',"Wrong freshPlyPos mode")
|
||||
local L=PLY_ALIVE
|
||||
if not sudden then
|
||||
if mode~='update' then
|
||||
for i=1,#L do
|
||||
L[i]:setPosition(640,#L<=5 and 360 or -62,0)
|
||||
end
|
||||
end
|
||||
|
||||
local posList
|
||||
if #L<=5 then posList=posLists[1]
|
||||
elseif #L<=17 then posList=posLists[2]
|
||||
elseif #L<=31 then posList=posLists[3]
|
||||
elseif #L<=49 then posList=posLists[4]
|
||||
elseif #L<=99 then posList=posLists[5]
|
||||
else error("TOO MANY PLAYERS!")
|
||||
local alive=PLAYERS[1].alive
|
||||
|
||||
if mode=='update' then
|
||||
if alive then
|
||||
if #L<=31 then
|
||||
for i=2,#L do
|
||||
L[i].miniMode=false
|
||||
L[i].draw=require"parts.player.draw".norm
|
||||
end
|
||||
end
|
||||
else
|
||||
if #L<=36 then
|
||||
for i=1,#L do
|
||||
L[i].miniMode=false
|
||||
L[i].draw=require"parts.player.draw".norm
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local posList=posLists(alive,#L)
|
||||
local method=mode=='normal' and 'setPosition' or 'movePosition'
|
||||
|
||||
if alive then
|
||||
for i=1,#L do
|
||||
L[i][method](L[i],unpack(posList[i==1 and 'main' or i-1]))
|
||||
end
|
||||
else
|
||||
for i=1,#L do
|
||||
L[i][method](L[i],unpack(posList[i]))
|
||||
end
|
||||
end
|
||||
local method=sudden and 'setPosition' or 'movePosition'
|
||||
for i=1,#L do L[i][method](L[i],unpack(posList[i])) end
|
||||
end
|
||||
end
|
||||
do-- function dumpBasicConfig()
|
||||
@@ -772,7 +999,7 @@ do-- function resetGameData(args)
|
||||
else
|
||||
PLY.newPlayer(1)
|
||||
end
|
||||
freshPlayerPosition(args:find'q')
|
||||
freshPlayerPosition((args:find'q') and 'quick' or 'normal')
|
||||
VK.restore()
|
||||
|
||||
local bg=GAME.modeEnv.bg
|
||||
|
||||
@@ -587,10 +587,8 @@ do-- Userdata tables
|
||||
USER=setmetatable({-- User infomation
|
||||
__data={
|
||||
uid=false,
|
||||
email=false,
|
||||
password=false,
|
||||
rToken=false,
|
||||
aToken=false,
|
||||
oToken=false,
|
||||
},
|
||||
},{
|
||||
__index=function(self,k)
|
||||
@@ -655,6 +653,8 @@ do-- Userdata tables
|
||||
highCam=true,
|
||||
nextPos=true,
|
||||
fullscreen=true,
|
||||
portrait=false,
|
||||
msaa=0,
|
||||
bg='on',
|
||||
bgAlpha=.26,
|
||||
powerInfo=false,
|
||||
|
||||
@@ -27,7 +27,7 @@ return {
|
||||
"homepage mainpage websites",
|
||||
"help",
|
||||
"The official website of Techmino!\nYou can download the latest stable build of Techmino and change your profile there.\nClick on the globe icon to open the website in your browser.",
|
||||
"http://101.43.110.22:10026",
|
||||
"http://studio26f.org",
|
||||
},
|
||||
{"Huiji Wiki",
|
||||
"huiji wiki",
|
||||
@@ -104,12 +104,6 @@ return {
|
||||
"Join the Tetris communities and talk with other players! You can join the Hard Drop Discord server by clicking on the globe icon.",
|
||||
"https://discord.gg/harddrop"
|
||||
},
|
||||
{"Mew",
|
||||
"tieba forum reddit discord",
|
||||
"org",
|
||||
"The Mew forum owned by the Chinese Tetris Research Community and was founded in the second half of 2021. Mew is a Chinese social media, kind of like a combination of Discord and Reddit, with many channels in a big community. Users can chat in the channels and submit posts to the channel. Mew also has a function called “Library,” which systematically stores the documentation. The Tetris Mew forum is currently under construction, and not too many contents are available (2/Nov/2021).",
|
||||
"https://mew.fun/n/tetris",
|
||||
},
|
||||
{"Tetris OL Servers",
|
||||
"tetrisonline servers tos",
|
||||
"org",
|
||||
|
||||
@@ -32,7 +32,7 @@ return {
|
||||
"homepage web mainpage ホームページ ウェブ メインページ テクミノ テックミノ techmino",
|
||||
"help",
|
||||
"Techminoの公式ホームページです!\n最新の安定版Techminoをダウンロードしたり、プロフィールを編集したりできます\n地球儀ボタンから是非アクセスしてください",
|
||||
"http://101.43.110.22:10026",
|
||||
"http://studio26f.org",
|
||||
},
|
||||
{"灰机wiki",
|
||||
"huiji wiki ウィキ うぃき 灰机 フイジ",
|
||||
@@ -85,7 +85,7 @@ return {
|
||||
{"ほゐスライド",
|
||||
"上達 練習 ほゐ スライド",
|
||||
"help",
|
||||
"日本のテトリスプレイヤー、whipemerald氏が作ったテトリスを上達させるためのスライド¥nテトリスフレンズの時代に作られたものだが今の時代でも問題なく通じる",
|
||||
"日本のテトリスプレイヤー、whipemerald氏が作ったテトリスを上達させるためのスライド\nテトリスフレンズの時代に作られたものだが今の時代でも問題なく通じる",
|
||||
"https://docs.google.com/presentation/d/1kYU2T6Kb-CVVshOa3BHGIhCoOWbbbKUekQqq-TsZgoY/mobilepresent?slide=id.p",
|
||||
},
|
||||
{"テト譜",
|
||||
@@ -125,12 +125,6 @@ return {
|
||||
"org",
|
||||
"テトリスコミュニティに参加して、他のプレイヤーと交流しよう!\n地球儀ボタンからHardDropのdiscordサーバーに参加できます",
|
||||
"https://discord.gg/harddrop"
|
||||
},
|
||||
{"Mew",
|
||||
"tieba forum reddit discord mew みゅー ミュー",
|
||||
"org",
|
||||
"discordとredditを合わせたような中国のSNSでしたが2022年10月31日より閉鎖されました",
|
||||
"https://mew.fun/n/tetris",
|
||||
},
|
||||
{"テトリスオンラインポーランド",
|
||||
"tetrisonline servers top toj toz poland japan zapan",
|
||||
@@ -301,7 +295,7 @@ return {
|
||||
{"Cambridge",
|
||||
"cambridge ケンブリッジ",
|
||||
"game",
|
||||
"クロスプラットフォーム | シングルプレイ\nLÖVEを使って開発された非公式テトリスです\n簡単かつ高度にカスタマイズできる新しいゲームモードを持っています\n元々はJoe Zeng氏が開発していましたが2020年10月8日のver.0.1.5からMilla氏が引継ぎました\n-Tetris wikiより",
|
||||
"クロスプラットフォーム | シングルプレイ\nLÖVEを使って開発された非公式テトリスです\n簡単かつ高度にカスタマイズできる新しいゲームモードがあります\n元々はJoe Zeng氏が開発していましたが2020年10月8日のver.0.1.5からMilla氏が引継ぎました\n-Tetris wikiより",
|
||||
},
|
||||
{"Nanamino",
|
||||
"nanamino ななみの なな ナナミノ ナナ",
|
||||
@@ -317,7 +311,7 @@ return {
|
||||
{"DTET",
|
||||
"dtet デテト でてと ディテト でぃてと",
|
||||
"game",
|
||||
"Windows | シングルプレイ\nTGMのクラッシクルールをベースに20Gや強力な回転システムを導入した非公式テトリスです\n現在、このゲームを見つけ出すのは難しく、見つからないDLLファイルを自分で補う必要がある可能性があります",
|
||||
"Windows | シングルプレイ\nTGMのクラッシクルールをベースに20Gや強力な回転システムを導入した非公式テトリスです\n現在、このゲームを見つけ出すのは難しく、見つからないDLLファイルを自分で補う必要があります",
|
||||
},
|
||||
{"Heboris",
|
||||
"hb heboris へぼ ヘボリス へぼりす",
|
||||
@@ -348,7 +342,7 @@ return {
|
||||
{"Tetris online",
|
||||
"top toj toz tetrisonline poland japan zapan テトオン",
|
||||
"game",
|
||||
"Windows | シングル/マルチプレイ\n今は亡き日本の公式テトリス\nDASとARRの値を設定できますがどちらも0にはできません\nプライベートサーバーで稼働していましたが2022年11月26日現在、ポーランドサーバーと2種類の日本サーバー全てダウンしています",
|
||||
"Windows | シングル/マルチプレイ\n今は亡き日本の公式テトリス\nDASとARRの値を設定できますがどちらも0にはできません\nプライベートサーバーで稼働していましたが2022年12月3日現在、2種類の日本サーバー全てダウンしています",
|
||||
},
|
||||
{"Tetra Online",
|
||||
"TO tetraonline tetraoffline offline テトラ てとら オンライン オフライン",
|
||||
@@ -511,7 +505,7 @@ return {
|
||||
{"All Clear",
|
||||
"pc perfectclear ac allclear パフェ オール パーフェクト",
|
||||
"term",
|
||||
"Perfect Clear(PC、パフェ)とも言われる\n盤面内にある全てのミノを消去すること¥n明らかにあるのに見逃した場合、「今パ」と言われることがある(逆にこれに言い返すフレーズも存在する)",
|
||||
"Perfect Clear(PC、パフェ)とも言われる\n盤面内にある全てのミノを消去すること\n明らかにあるのに見逃した場合、「今パ」と言われることがある(逆にこれに言い返すフレーズも存在する)",
|
||||
},
|
||||
{"HPC",
|
||||
"hc clear halfperfectclear ハーフ セミ",
|
||||
@@ -532,7 +526,7 @@ return {
|
||||
{"All-Spin",
|
||||
"allspin オール 全",
|
||||
"term",
|
||||
"全てのミノのspinに火力、スコア補正がかかるルールのこと(通常はTspinのみ)\nまた稀にルールではなくAll-spinという回転法則を指すこともある",
|
||||
"全てのミノのspinに火力、スコア補正がかかるルールのこと(通常ルールはTspinのみ)\nまた稀にルールではなくAll-spinという回転法則を指すこともある",
|
||||
},
|
||||
{"T-Spin",
|
||||
"tspin ティ ts ふんどし",
|
||||
@@ -567,7 +561,7 @@ return {
|
||||
{"O-Spin",
|
||||
"ospin o オー 2",
|
||||
"term",
|
||||
"Oミノはどんなに回転させても形が変化しないため回転入れが不可能でした(一部では毎秒500~600回転させることでOミノが熱膨張したり溶けたり変形するという噂があります)\nそのためテトリスコミュニティ内でミームのように扱われ、フェイクビデオ等も作成されました\n\nXRSという回転法則ではOミノを特定の地形で回転させると穴にテレポートするように設計し、それをOspinとしています\nまたTRSでは同様にすることでテレポートさせるだけでなく、他のミノの形に変形することによってOspinを実現しています",
|
||||
"Oミノはどんなに回転させても形が変化しないため回転入れが不可能でした(一部では毎秒500~600回転させることでOミノが熱膨張したり溶けたり変形したりするという噂があります)\nそのためテトリスコミュニティ内でミームのように扱われ、フェイクビデオ等も作成されました\n\nXRSという回転法則ではOミノを特定の地形で回転させると穴にテレポートするように設計し、それをOspinとしています\nまたTRSでは同様にすることでテレポートさせるだけでなく、他のミノの形に変形することによってOspinを実現しています",
|
||||
},
|
||||
{"Rotation Systems(回転システム、回転法則)",
|
||||
"wallkick rotationsystem 回転 壁 法則",
|
||||
@@ -575,9 +569,9 @@ return {
|
||||
"ミノがどのように回転するかを決定しているシステムのこと\nモダンテトリスの場合、ミノは特定の回転軸を中心に回転している(もちろんそれがないゲームもある)\nそして回転させたときに壁や既にマスが埋まっている場所にミノが重なると通常「壁蹴り」という処理が行われ、あらかじめ決められた位置にズレ、再び壁蹴りが必要かの判定が行われる\nこれを繰り返しミノは設置可能な穴に移動する\nまたこの時、spin判定が出る場合がある",
|
||||
},
|
||||
{"方向表記",
|
||||
"direction 0r2l 02 20 rl lr",
|
||||
"direction 0r2l 02 20 rl lr 表記 ミッション",
|
||||
"term",
|
||||
"SRS系統の回転システムではミノの向きを記述する表記法がある\n「0」や「正の向き」の場合は出現した時と同じ向き、「R」や「右」という場合は90°右回転(CW)した向き、「L」や「左」の場合は90°左回転(CCW)した向き、「2」や「逆の向き」の場合は180°回転させた向きを表す\n\n例えば0->Lは左回転1回、2->右は逆の向きの状態から左回転1回となる(これは回転方向ではなくミノの向きを表す表記法なので右回転ではない)\n\n「->」を使った表記は日本であまり使われず、操作で表現することの方が多い",
|
||||
"SRS系統の回転システムではミノの向きを記述する表記法がある\n「0」や「正の向き」の場合は出現した時と同じ向き、「R」や「右」、「1」という場合は90°右回転(CW)した向き、「L」や「左」、「2」や「逆の向き」の場合は180°回転させた向き、「3」の場合は90°左回転(CCW)した向きを表す\n\n例えば0->Lは左回転1回、2->右は逆の向きの状態から左回転1回となる(これは回転方向ではなくミノの向きを表す表記法なので右回転ではない)\nカスタムモードにあるミッションはこの表記を使っている\n\n「->」や数字使った表記は日本であまり使われない",
|
||||
},
|
||||
{"ARS",
|
||||
"arikrotationsystem atarirotationsystem あたり アタリ ありか アリカ",
|
||||
@@ -637,7 +631,7 @@ return {
|
||||
{"TRS",
|
||||
"techminorotationsystem techmino",
|
||||
"term",
|
||||
"*Techmino用語*\nTechmino Rotation System\nSRSを基にした回転法則\nSとZが回転しない場合を修正しいくつかの便利なキックテーブルがあります\n\nTRSはOspinをサポートしています",
|
||||
"*Techmino用語*\nTechmino Rotation System\nSRSを基にした回転法則\nSとZが回転しない場合を修正し、いくつかの便利なキックテーブルがあります\n\nTRSはOspinをサポートしています",
|
||||
},
|
||||
{"XRS",
|
||||
"xrs",
|
||||
@@ -728,17 +722,17 @@ return {
|
||||
{"Digging(掘り)",
|
||||
"downstacking ds 掘り 堀り dig ダウン",
|
||||
"term",
|
||||
"盤面の下にある下穴などを消していくこと¥n「堀り」ではなく、「掘り」",
|
||||
"盤面の下にある下穴などを消していくこと\n「堀り」ではなく、「掘り」",
|
||||
},
|
||||
{"Downstack",
|
||||
"downstacking down ds 掘り dig ダウン upstack up ud 積み stack",
|
||||
"term",
|
||||
"大きく見た時に地形を下げる積み方のこと¥n掘りはこれの1種である¥n対義語としてUpstackがある¥n¥n1巡毎に2Line消去をする場合、盤面内は1巡につき8つブロックが増えていく¥nつまり毎巡TSDをすると火力が送れる上にリソースが溜まっていくのである。",
|
||||
"大きく見た時に地形を下げる積み方のこと\n掘りはこれの1種である\n対義語としてUpstackがある\n\n1巡毎に2Line消去をする場合、盤面内は1巡につき8つブロックが増えていく\nつまり毎巡TSDをすると火力が送れる上にリソースが溜まっていくのである。",
|
||||
},
|
||||
{"削り",
|
||||
"削り 整地",
|
||||
"term",
|
||||
"主に整地を目的として1~3Line消去をすること¥n無駄な削りもあるが必要な削りも世の中には存在する",
|
||||
"主に整地を目的として1~3Line消去をすること\n無駄な削りもあるが必要な削りも世の中には存在する",
|
||||
},
|
||||
{"Donation(ドネイト)",
|
||||
"donate ドネイト 空中",
|
||||
@@ -748,28 +742,33 @@ return {
|
||||
{"‘Debt’",
|
||||
"qianzhai debt owe",
|
||||
"term",
|
||||
"中国のテトリスコミュニティで使われる用語(欠债と呼ばれている)\n\n特定の地形を完成させないとまともな攻撃(Tspinやテトリス)ができない状況や地形を表す用語\n端的に言えばTSTタワーやキングくクリムゾンのような大型テンプレを組み終わるまでの隙のことを指す\n大型テンプレを実践でする場合には凝視等で安全なことを確認してから行わないと不利な状況になります",
|
||||
"中国のテトリスコミュニティで使われる用語(欠债と呼ばれている)\n\n特定の地形を完成させないとまともな攻撃(Tspinやテトリス)ができない状況や地形を表す用語\n端的に言えばTSTタワーやキングクリムゾンのような大型テンプレを組み終わるまでの隙のことを指す\n大型テンプレを実践でする場合には凝視等で安全なことを確認してから行わないと不利な状況になります",
|
||||
},
|
||||
{"謎テト",
|
||||
"クイズ quiz 謎 上達 練習",
|
||||
"term",
|
||||
"特定の状況とお題が与えられ、それを満たすような答えを探す詰将棋みたいなもの¥n謎テトがまとめられたサイトもある",
|
||||
"特定の状況とお題が与えられ、それを満たすような答えを探す詰将棋みたいなもの\n謎テトがまとめられたサイトもある",
|
||||
},
|
||||
{"てとぼ",
|
||||
"募集 上達 練習 tetobo",
|
||||
"term",
|
||||
"テトリス募集の略¥nTwitterやDiscord上で対戦相手を募る時に使う言葉¥nTwitterではてとぼをRTしてくれるbotが存在する",
|
||||
"テトリス募集の略\nTwitterやDiscord上で対戦相手を募る時に使う言葉\nTwitterではてとぼをRTしてくれるbotが存在する",
|
||||
},
|
||||
{"テト譜コード",
|
||||
"開発 テト譜 譜面 コード",
|
||||
"term",
|
||||
"テト譜URLの「v115@~」以降の部分のこと¥nこれにはテト譜地形やコメント等の情報が収められている¥n「v115@」の部分は「m115@」だったり「v095@」だったりする¥n詳しくはnewjade氏が作成した「テト譜v115のデータ構造」というスライド参照",
|
||||
"テト譜URLの「v115@~」以降の部分のこと\nこれにはテト譜地形やコメント等の情報が収められている\n「v115@」の部分は「m115@」だったり「v095@」だったりする\n詳しくはnewjade氏が作成した「テト譜v115のデータ構造」というスライド参照",
|
||||
"https://docs.google.com/presentation/d/1P5xt0vPGuxSb9hbRW6hvQFYKFoIccfNTJkWTdjtyigc/edit#slide=id.p",
|
||||
},
|
||||
{"地力",
|
||||
"実力 上達",
|
||||
"term",
|
||||
"あらゆる場面に対応できる総合的な能力のこと\n要はテトリスの実力\n\n実際には速さや見える手、凝視等の根本的な能力の総称として使われることが多い",
|
||||
},
|
||||
{"パリティ",
|
||||
"開発 テト譜 譜面 研究 練習",
|
||||
"term",
|
||||
"地形を特定の法則に従って2色以上で塗り分けた時の性質のこと¥n今までは主に市松パリティや縦パリティでパフェが取れる条件を絞り込みだけだったが、最近では研究が進みアップスタック時に安定して火力が出せる地形を維持する条件などが解明されている",
|
||||
"地形を特定の法則に従って2色以上で塗り分けた時の性質のこと\n今までは主に市松パリティや縦パリティでパフェが取れる条件を絞り込みだけだったが、最近では研究が進みアップスタック時に安定して火力が出せる地形を維持する条件などが解明されている",
|
||||
},
|
||||
{"Attack & Defend",
|
||||
"attacking defending 攻撃 防御 攻防 アタック ディフェンス 火力 相殺",
|
||||
@@ -900,7 +899,7 @@ return {
|
||||
{"‘Doing Research’",
|
||||
"scientificresearch 研究 上達 練習 科研",
|
||||
"term",
|
||||
"「科研」という中国のテトリスコミュニティで使われる言葉\n落下速度の低い、1人用モードで技術やテンプレを研究・練習することを言います(日本でもこの練習はありますがその行為を指す単語は存在しません)",
|
||||
"「科研」という中国のテトリスコミュニティで使われる言葉\n落下速度の低い1人用モードで技術やテンプレを研究・練習することを言います(日本でもこの練習はありますがその行為のみを指す単語は存在しません)",
|
||||
},
|
||||
{"Keymapping(キー配置)",
|
||||
"feel キー key 操作",
|
||||
@@ -1016,6 +1015,11 @@ return {
|
||||
"triplerotation 回転 左 右 180 3",
|
||||
"term",
|
||||
"左右,180°回転の全てを使えばどんな回転方向でも1回の入力で済みます\nしかし全てのゲームに180°回転があるわけでなく、この技術を習得しても左右回転を習得した時ほどの上達はないでしょう\n最適化という点では速さを極端に求めない限り必要ありません(ただし180°の回転入れは覚える必要があります)",
|
||||
},
|
||||
{"ザンギ",
|
||||
"操作 ザンギ ざんぎ zangi",
|
||||
"term",
|
||||
"左右移動->ソニックドロップ->もう一方の左右移動と行われる操作のこと\n例えば左ザンギの場合、左端へ一瞬で移動->ソニックドロップ->右へ壁に衝突するまで移動 となる",
|
||||
},
|
||||
{"Drought(ドラウト)",
|
||||
"drought ドラウト 干ばつ 連続",
|
||||
@@ -1055,13 +1059,29 @@ return {
|
||||
{"Cold Clear",
|
||||
"cc coldclear ai bot コールド",
|
||||
"term",
|
||||
"テトリスのbot\n元々はMinus Kelvinがぷよぷよテトリス用に開発したbotだがTechminoではAllspinとTRSに対応できるよう改良されている",
|
||||
"テトリスのbot\n元々はMinus Kelvin氏がぷよぷよテトリス用に開発したbotだがTechminoではAllspinとTRSに対応できるよう改良されている",
|
||||
},
|
||||
{"ZZZbot",
|
||||
"ai bot zzztoj misamino",
|
||||
"term",
|
||||
"テトリスのbot\n中国のテトリスプレイヤー、奏之章 (Zòu Zhī Zhāng)が開発し、多くのゲームで動作する",
|
||||
"テトリスのbot\n中国のテトリスプレイヤー、奏之章 (Zòu Zhī Zhāng)氏が開発し、多くのゲームで動作する",
|
||||
},
|
||||
{"Zetris",
|
||||
"ai bot zetris misamino",
|
||||
"term",
|
||||
"テトリスのbot\nmat氏がぷよぷよテトリス用に開発したbot\nmisaminoを元に開発された\n凝視はしてないが受けた後に一定段以下になる攻撃は外すような仕様になっている",
|
||||
},
|
||||
{"ほいこ",
|
||||
"ai bot hoiko howyiko ほゐこ",
|
||||
"term",
|
||||
"テトリスのbot\nうかん氏がぷよぷよテトリス用に開発したbot\n相手から送られる火力を見ており、直列になる確率と待ち時間から相殺外しを判断している",
|
||||
},
|
||||
{"wataame",
|
||||
"ai bot わたあめ watame",
|
||||
"term",
|
||||
"テトリスのbot\n雨安氏がぷよぷよテトリス用に開発したbot\n多様なモードを搭載している",
|
||||
},
|
||||
|
||||
|
||||
-- Setups
|
||||
{"Openers(開幕テンプレ)",
|
||||
@@ -1098,6 +1118,12 @@ return {
|
||||
"setup",
|
||||
"開幕TSDからもう一度TSDを撃ち、パフェを取るテンプレ"..HDwiki,
|
||||
HDsearch.."TKI_3_Perfect_Clear",
|
||||
},
|
||||
{"MKO積み",
|
||||
"mko むこうみず",
|
||||
"setup",
|
||||
"派生を含めれば大体のことはできる開幕テンプレ\nHarddropのwikiを載せるがmko全体の内、1割も情報が書かれていない\n使い方がかなり重要な開幕テンプレなので使う場合は積極的に情報収集することをおすすめする",
|
||||
HDsearch.."MKO_Stacking",
|
||||
},
|
||||
{"QT砲",
|
||||
"qtcannon 砲",
|
||||
@@ -1156,7 +1182,7 @@ return {
|
||||
{"Perfect Clear Opener(パフェ積み)",
|
||||
"7piecepuzzle パフェ 積み",
|
||||
"setup",
|
||||
"7ミノ置いた後、パフェが取れる確率が最も高い形\n通常はパフェ率61.2%だがIミノを置かず残り4ミノからパフェを見抜くことで84.6%までパフェ率が上昇する\nTechminoのパフェトレーニングでジグザグの形が出たらこのテンプレの形です"..HDwiki,
|
||||
"7ミノ置いた後、パフェを取れる確率が最も高い形\n通常はパフェ率61.2%だがIミノを置かず残り4ミノからパフェを見抜くことで84.6%までパフェ率が上昇する\nTechminoのパフェトレーニングでジグザグの形が出たらこのテンプレの形です"..HDwiki,
|
||||
HDsearch.."Perfect_Clear_Opener",
|
||||
},
|
||||
{"Grace System(グレースシステム)",
|
||||
@@ -1193,7 +1219,7 @@ return {
|
||||
{"STSD",
|
||||
"stsd",
|
||||
"pattern",
|
||||
"Super T-Spin Double\n2回TSDを撃てる形\nしかし盤面の底に作った場合、相手からの下穴により1/10の確率で最初のTSDが撃てなくなる\n人によってはこの確率は100%らしい"..HDwiki,
|
||||
"Super T-Spin Double\n2回TSDを撃てる形\nしかし盤面の底に作った場合、相手からの下穴により1/10の確率で最初のTSDが撃てなくなる\nこの確率は100%と言う人もいる"..HDwiki,
|
||||
HDsearch.."stsd",
|
||||
},
|
||||
{"STMB Cave(STMBケイブ)",
|
||||
@@ -1325,6 +1351,16 @@ return {
|
||||
"afk",
|
||||
"english",
|
||||
"Away From Keyboardの略\n画面前から離れる時だけじゃなく、休憩するときにも使われる\n適度に休憩することで身体と頭が休み、より質の高いプレイができる",
|
||||
},
|
||||
{"BRB",
|
||||
"brb",
|
||||
"english",
|
||||
"Be right backの略\n一旦離れるけどすぐに戻るときに使われる\n人によっては試合中にbrbというが結局セットが終わるまで戻らない人もいる",
|
||||
},
|
||||
{"sweep",
|
||||
"sweep ストレート",
|
||||
"english",
|
||||
"日本語で言うストレートのこと\n例えば、7先の試合で1本も取られずに勝利した場合、相手をsweepしたと言う",
|
||||
},
|
||||
{"Timing",
|
||||
"timing shiji fanji タイミング",
|
||||
|
||||
@@ -20,8 +20,8 @@ return {
|
||||
{"游戏官网",
|
||||
"official website homepage mainpage guanwang",
|
||||
"help",
|
||||
"Techmino的官网!\n可以在上面下载游戏本体,或者修改头像以及个人信息。\n\n游戏作者的一些话:强烈不建议在任何公开场合提及甚至宣传Techmino,更不要随便就对外公布我们的官网链接!请务必只在私下里向有基础或真的很有兴趣入坑认真玩的玩家推荐,不然很容易拉低社群质量破坏交流氛围,非常难处理,甚至有可能影响游戏的未来发展。为了保证游戏未来会变得越来越好玩,千万慎重考虑您对游戏的推广方式!感谢您对Techmino的支持!!感谢配合!!!",
|
||||
"http://101.43.110.22:10026",
|
||||
"Techmino的官网!\n可以在上面下载游戏本体,或者修改头像以及个人信息。\n\n游戏作者的一些话:强烈不建议在任何公开场合提及甚至宣传Techmino,更不要随便对外发送我们的官网链接!请务必只在私下里向有基础或真的很有兴趣入坑认真玩的玩家推荐,不然很容易拉低社群质量破坏交流氛围,比较难处理,甚至有可能影响游戏的未来发展。为了保证游戏能够变得越来越好玩,千万慎重考虑您对游戏的推广方式!感谢您对Techmino的大力支持!!",
|
||||
"http://studio26f.org",
|
||||
},
|
||||
{"灰机Wiki",
|
||||
"huiji",
|
||||
@@ -96,12 +96,6 @@ return {
|
||||
"org",
|
||||
"俄罗斯方块·[研究]群QQ号764916351,“中国俄罗斯方块总群”",
|
||||
},
|
||||
{"Mew据点",
|
||||
"mew tieba forum",
|
||||
"org",
|
||||
"研究群下属的Mew据点(类似贴吧或者Discord的服务器),2021年下半年建立,可以在同一个大社区的各个频道实时聊天,也可以发帖以主题交流,同时还有一个叫图书馆的功能方便各种方块资料整理(还在建设中,目前没多少内容,2021/11/02)",
|
||||
"https://mew.fun/n/tetris",
|
||||
},
|
||||
{"茶服",
|
||||
"tos tea study chafu",
|
||||
"org",
|
||||
@@ -1158,17 +1152,11 @@ return {
|
||||
"在STSD上叠若干个T3的形状。"..HDwiki,
|
||||
HDsearch.."King_Crimson",
|
||||
},
|
||||
{"连续PC (1/2)",
|
||||
"pcloop",
|
||||
{"连续PC",
|
||||
"lianxuquanxiao lianxupc pcloop",
|
||||
"pattern",
|
||||
"テトリス堂的从开局起第1、2、3、4、7个4行pc的开局整理。第七个pc做完总共用掉70块,相当于回到游戏开始阶段可以做1st pc\n\n第5和第6详见下一个词条",
|
||||
"https://shiwehi.com/tetris/template/consecutivepc.php"
|
||||
},
|
||||
{"连续PC (2/2)",
|
||||
"pcloop",
|
||||
"pattern",
|
||||
"four.lol的从开局起第5、6个4行pc的开局整理。\n(链接点开是5th,可以到6th,其他的推荐看上一个词条)",
|
||||
"https://four.lol/perfect-clears/5th"
|
||||
"研究群群友加加编写的一份连续PC教程",
|
||||
"https://docs.qq.com/sheet/DRmxvWmt3SWxwS2tV"
|
||||
},
|
||||
|
||||
-- 存档管理
|
||||
|
||||
@@ -17,6 +17,7 @@ return {
|
||||
playedLong="You have been playing for a long time. Time to take a break!",
|
||||
playedTooMuch="You have been playing for far too long! Techmino is fun, but remember to take some rests!",
|
||||
settingWarn="Careful — you’re about to change some uncommon settings!",
|
||||
settingWarn2="This setting takes effect after restart",
|
||||
|
||||
atkModeName={"Random","Badges","K.O.s","Attackers"},
|
||||
royale_remain="$1 Players Left",
|
||||
@@ -531,6 +532,8 @@ return {
|
||||
power="Battery Info",
|
||||
clean="Quick Draw",
|
||||
fullscreen="Fullscreen",
|
||||
portrait="Portrait",
|
||||
msaa="MSAA level",
|
||||
|
||||
bg_on="Normal B.G.",
|
||||
bg_off="No B.G.",
|
||||
@@ -741,21 +744,11 @@ return {
|
||||
music="BGMs",
|
||||
label="label",
|
||||
},
|
||||
login_pw={
|
||||
login={
|
||||
title="Sign In",
|
||||
login_mail="Login with E-mail/Sign Up",
|
||||
email="Email Address",
|
||||
password="Password",
|
||||
showEmail="Show Email",
|
||||
login="Log In",
|
||||
},
|
||||
login_mail={
|
||||
title="Sign In/Sign Up",
|
||||
login_pw="Password Sign In",
|
||||
email="Email Address",
|
||||
send="Send code",
|
||||
code="Verification Code",
|
||||
verify="Verify",
|
||||
ticket="Auth Ticket",
|
||||
authorize="Open Authorizing Page",
|
||||
submit="Submit",
|
||||
},
|
||||
reset_password={
|
||||
title="Reset Password",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
return {
|
||||
fallback='en',
|
||||
loadText={
|
||||
loadSFX="Cargando efectos de sonido",
|
||||
loadSample="Cargando samples de música",
|
||||
@@ -9,7 +10,6 @@ return {
|
||||
loadOther="Cargando otros assets",
|
||||
finish="Pulsa cualquier tecla",
|
||||
},
|
||||
fallback='en',
|
||||
sureQuit="Pulsa de nuevo para salir",
|
||||
sureReset="Pulsa de nuevo para reiniciar",
|
||||
sureDelete="Pulsa de nuevo para borrar",
|
||||
@@ -17,6 +17,7 @@ return {
|
||||
playedLong="[Anti-adicción] Estuviste jugando un buen rato hoy. Recuerda descansar de vez en cuando.",
|
||||
playedTooMuch="[Anti-adicción] ¡Has jugado mucho por hoy! No puedes jugar más.",
|
||||
settingWarn="¡Ten cuidado con modificar esto!",
|
||||
-- settingWarn2="This setting takes effect after restart",
|
||||
|
||||
atkModeName={"Al azar","Medallas","KOs","Atacantes"},
|
||||
royale_remain="$1 Jugadores Restantes",
|
||||
@@ -531,6 +532,8 @@ return {
|
||||
power="Inf. de Batería",
|
||||
clean="Fast Draw",
|
||||
fullscreen="Pant. Completa",
|
||||
-- portrait="Portrait",
|
||||
-- msaa="MSAA level",
|
||||
|
||||
bg_on="Fondo Normal",
|
||||
bg_off="Sin Fondo",
|
||||
@@ -733,21 +736,11 @@ return {
|
||||
music="BGMs",
|
||||
label="Etiq.",
|
||||
},
|
||||
login_pw={
|
||||
title="Entrar",
|
||||
login_mail="Registrarse/Pedir código",
|
||||
email="Correo Elec.",
|
||||
password="Contraseña",
|
||||
showEmail="Mostrar Correo",
|
||||
login="Entrar",
|
||||
},
|
||||
login_mail={
|
||||
title="Entrar/Registrarse",
|
||||
login_pw="Ingr. con Contraseña",
|
||||
email="Correo Elec.",
|
||||
send="Enviar código",
|
||||
code="Código de Verif.",
|
||||
verify="Verificar",
|
||||
login={
|
||||
-- title="Sign In",
|
||||
-- ticket="Auth Ticket",
|
||||
-- authorize="Open Authorizing Page",
|
||||
-- submit="Submit",
|
||||
},
|
||||
reset_password={
|
||||
title="Restablecer Contraseña",
|
||||
|
||||
@@ -7,6 +7,7 @@ return {
|
||||
playedLong="[Anti-addiction] Vous avez joué pendant un bon bout de temps aujourd'hui. Faites des pauses.",
|
||||
playedTooMuch="[Anti-addiction] Vous avez joué trop longtemps ! Vous ne pouvez plus jouer.",
|
||||
-- settingWarn="Modifing uncommon setting, be careful!",
|
||||
-- settingWarn2="This setting takes effect after restart",
|
||||
|
||||
atkModeName={"Aléatoire","Badges","K.O.s faciles","Attaquants"},
|
||||
royale_remain="$1 Joueurs restants",
|
||||
@@ -496,6 +497,8 @@ return {
|
||||
power="Infos d'alimentation",
|
||||
-- clean="Fast Draw",
|
||||
fullscreen="Plein écran",
|
||||
-- portrait="Portrait",
|
||||
-- msaa="MSAA level",
|
||||
|
||||
-- bg_on="Normal B.G.",
|
||||
-- bg_off="No B.G.",
|
||||
@@ -696,21 +699,11 @@ return {
|
||||
music="Musique",
|
||||
-- label="label",
|
||||
},
|
||||
login_pw={
|
||||
title="Connexion",
|
||||
-- login_mail="Login with E-mail/Sign Up",
|
||||
email="E-mail",
|
||||
password="Mot de passe",
|
||||
-- showEmail="Show Email",
|
||||
login="Connexion",
|
||||
},
|
||||
login_mail={
|
||||
title="Connexion/Enregistrement",
|
||||
-- login_pw="Password Sign In",
|
||||
email="E-mail",
|
||||
-- send="Send code",
|
||||
-- code="Verification Code",
|
||||
-- verify="Verify",
|
||||
login={
|
||||
-- title="Sign In",
|
||||
-- ticket="Auth Ticket",
|
||||
-- authorize="Open Authorizing Page",
|
||||
-- submit="Submit",
|
||||
},
|
||||
reset_password={
|
||||
-- title="Reset Password",
|
||||
|
||||
@@ -18,6 +18,7 @@ return {
|
||||
playedLong="Anda telah bermain lama. Waktunya istirahat!",
|
||||
playedTooMuch="Anda telah bermain terlalu lama! Techmino sangat menyenangkan, tetapi jangan lupa istirahat!",
|
||||
settingWarn="Awas, Anda akan mengubah beberapa pengaturan yang tidak biasanya diubah!",
|
||||
-- settingWarn2="This setting takes effect after restart",
|
||||
|
||||
atkModeName={"Acak","Badge","K.O.","Penyerang"},
|
||||
royale_remain="$1 Pemain Tersisa",
|
||||
@@ -532,6 +533,8 @@ return {
|
||||
power="Info Baterai",
|
||||
clean="Gambar Cepat",
|
||||
fullscreen="Layar Penuh",
|
||||
-- portrait="Portrait",
|
||||
-- msaa="MSAA level",
|
||||
|
||||
bg_on="B.G. Normal",
|
||||
bg_off="Tidak Ada B.G.",
|
||||
@@ -742,21 +745,11 @@ return {
|
||||
music="Musik",
|
||||
label="label",
|
||||
},
|
||||
login_pw={
|
||||
title="Masuk",
|
||||
-- login_mail="Login with E-mail/Sign Up",
|
||||
email="Alamat Email",
|
||||
password="Password",
|
||||
showEmail="Tunjukkan Email",
|
||||
login="Masuk",
|
||||
},
|
||||
login_mail={
|
||||
title="Masuk/Daftar",
|
||||
-- login_pw="Password Sign In",
|
||||
email="Alamat Email",
|
||||
-- send="Send code",
|
||||
-- code="Verification Code",
|
||||
-- verify="Verify",
|
||||
login={
|
||||
-- title="Sign In",
|
||||
-- ticket="Auth Ticket",
|
||||
-- authorize="Open Authorizing Page",
|
||||
-- submit="Submit",
|
||||
},
|
||||
reset_password={
|
||||
-- title="Reset Password",
|
||||
|
||||
@@ -14,10 +14,11 @@ return {
|
||||
sureQuit="終了するにはもう一度押してください!",
|
||||
sureReset="リセットするにはもう一度押してください!",
|
||||
sureDelete="削除するにはもう一度押してください!",
|
||||
newDay="新しい1日、新しい始まりです!",
|
||||
playedLong="長時間プレイしています、適度に休憩をして!",
|
||||
playedTooMuch="かなり長くプレイしています! Techminoは楽しいですが、休憩を忘れずに!",
|
||||
settingWarn="使用頻度の少ない設定に変更しています。注意してください。",
|
||||
newDay="新しい1日の始まりです!",
|
||||
playedLong="長時間プレイしています、適度な休憩を",
|
||||
playedTooMuch="長時間プレイしています! Techminoは楽しいですが、休憩を忘れずに!",
|
||||
settingWarn="使用頻度の少ない設定を変更しています。注意してください。",
|
||||
settingWarn2="この設定は再起動後に適用されます",
|
||||
|
||||
atkModeName={"ランダム","バッジ狙い","トドメ撃ち","カウンター"},
|
||||
royale_remain="残り $1 人",
|
||||
@@ -33,13 +34,13 @@ return {
|
||||
tasUsing="[TAS]",
|
||||
|
||||
stage="ステージ $1 クリア!",
|
||||
great="よし!",
|
||||
awesome="すごい!",
|
||||
almost="あと少し!",
|
||||
continue="がんばれ!",
|
||||
great="GREAT",
|
||||
awesome="素晴らしい",
|
||||
almost="あと少し...",
|
||||
continue="まだ行ける!",
|
||||
maxspeed="最高速度!",
|
||||
speedup="スピードアップ!",
|
||||
missionFailed="失敗…",
|
||||
missionFailed="ミッション失敗",
|
||||
|
||||
speedLV="レベル",
|
||||
piece="ミノ数",line="line数",atk="火力",eff="効率",
|
||||
@@ -57,15 +58,15 @@ return {
|
||||
gameover="Game Over",
|
||||
|
||||
pause="ポーズ",
|
||||
pauseCount="ポーズした回数",
|
||||
pauseCount="ポーズ回数",
|
||||
finesse_ap="All Perfect",
|
||||
finesse_fc="Full Combo",
|
||||
|
||||
page="ページ:",
|
||||
|
||||
cc_fixed="CCは固定されたミノ順に非対応です!",
|
||||
cc_swap="CCはホールドモードがSwapの時に非対応です!",
|
||||
ai_prebag="AIは通常のテトロミノではない物やカスタマイズされたミノ順に非対応です!",
|
||||
cc_fixed="CCはミノ順の指定に非対応です!",
|
||||
cc_swap="CCはホールドモード、Swapに非対応です!",
|
||||
ai_prebag="AIは通常のテトロミノ以外やミノ順指定に非対応です!",
|
||||
ai_mission="AIはカスタムミッションに非対応です!",
|
||||
switchSpawnSFX="ブロック出現時の効果音をONにしてください!",
|
||||
needRestart="すべての変更を適用する為にリスタートしてください!",
|
||||
@@ -74,7 +75,7 @@ return {
|
||||
loadError_read="'$1'の読み込みに失敗: 読み込みに失敗しました",
|
||||
loadError_noFile="'$1'の読み込みに失敗: ファイルが存在しません",
|
||||
loadError_other="'$1'の読み込みに失敗: $2",
|
||||
loadError_unknown="'$1'の読み込みに失敗: 原因不明です",
|
||||
loadError_unknown="'$1'の読み込みに失敗: 原因不明",
|
||||
|
||||
saveError_duplicate="'$1'の保存に失敗: 既に同じ名前のファイルがあります",
|
||||
saveError_encode="'$1'の保存に失敗: エンコードエラー",
|
||||
@@ -84,9 +85,9 @@ return {
|
||||
copyDone="コピーしました!",
|
||||
saveDone="データを保存しました!",
|
||||
exportSuccess="書き出し成功!",
|
||||
importSuccess="取り込み成功!",
|
||||
importSuccess="読み取り成功!",
|
||||
dataCorrupted="データが破損してます",
|
||||
pasteWrongPlace="貼り付ける位置が間違ってませんか?",
|
||||
pasteWrongPlace="貼り付ける位置を間違っていませんか?",
|
||||
noFile="ファイルが見つかりません",
|
||||
|
||||
nowPlaying="再生中:",
|
||||
@@ -97,8 +98,8 @@ return {
|
||||
|
||||
noScore="スコア無し",
|
||||
modeLocked="未開放",
|
||||
unlockHint="前のステージでランクB以上を取得すると解放されます!",
|
||||
highScore="最高得点",
|
||||
unlockHint="前のステージでBランク以上を取得すると解放されます!",
|
||||
highScore="最高記録",
|
||||
newRecord="新記録!",
|
||||
|
||||
replayBroken="リプレイが読み込めませんでした",
|
||||
@@ -114,14 +115,14 @@ return {
|
||||
invalidFormat="非対応の形式です",
|
||||
invalidArguments="無効な引数です",
|
||||
tooFrequent="リクエストが多すぎます",
|
||||
notAvailable="使用不可",
|
||||
notAvailable="無効なリクエスト",
|
||||
noPermission="権限がありません",
|
||||
roomNotFound="部屋が見つかりません",
|
||||
|
||||
-- Controllers
|
||||
WebSocket={
|
||||
invalidConnection="接続されていません",
|
||||
invalidAction="無効な操作です",
|
||||
invalidAction="無効な操作",
|
||||
playerNotFound="プレイヤーが見つかりませんでした",
|
||||
connectionFailed="接続失敗",
|
||||
},
|
||||
@@ -136,7 +137,7 @@ return {
|
||||
connectionReplaced="接続切替",
|
||||
},
|
||||
NoticeManager={
|
||||
noticeNotFound="通知が見つかりませんでした",
|
||||
noticeNotFound="通知はありません",
|
||||
},
|
||||
PlayerManager={
|
||||
invalidCode="無効なコード",
|
||||
@@ -164,7 +165,7 @@ return {
|
||||
roomPasswordChanged="部屋のパスワードを変更しました",
|
||||
oldVersion="バージョン$1のダウンロードが可能になりました",
|
||||
versionNotMatch="バージョンが一致しません",
|
||||
notFinished="未完成ですので、ご期待ください",
|
||||
notFinished="未完成です、ご期待ください",
|
||||
|
||||
noUsername="ユーザーネームを入力してください!",
|
||||
wrongEmail="メールアドレスが無効です!",
|
||||
@@ -176,7 +177,7 @@ return {
|
||||
wsFailed="ウェブソケットとの通信に失敗しました: $1",
|
||||
wsClose="ウェブソケットとの通信を終了: $1",
|
||||
netTimeout="接続がタイムアウトしました",
|
||||
serverDown="うわ! サーバーが落ちています...",
|
||||
serverDown="あー、サーバーが落ちています...",
|
||||
requestFailed="リクエスト失敗",
|
||||
|
||||
onlinePlayerCount="オンライン人数: $1",
|
||||
@@ -186,20 +187,20 @@ return {
|
||||
started="プレイ中",
|
||||
joinRoom="$1 が入室しました",
|
||||
leaveRoom="$1 が退出しました",
|
||||
roomRemoved="部屋が撤去されました",
|
||||
roomRemoved="部屋が解散しました",
|
||||
ready="準備OK",
|
||||
spectating="観戦中",
|
||||
|
||||
|
||||
|
||||
keySettingInstruction="選択してキーを入力\nEscape: キャンセル\nBackspace: キーを削除",
|
||||
customBGhelp="カスタム背景にする画像ファイルをドロップ",
|
||||
customBGloadFailed="サポートされていないフォーマットのファイルです",
|
||||
customBGhelp="背景にする画像ファイルをドロップ",
|
||||
customBGloadFailed="非対応のファイル形式です",
|
||||
|
||||
errorMsg="問題が発生! ゲームを再起動し、エラーログを開発者に送ってください",
|
||||
tryAnotherBuild="[Invalid UTF-8]使用しているOSがMicrosoft WindowsであればTechmino-win32かTechmino-win64をダウンロードしてください! (現在使用しているソフトは違うバージョンです)",
|
||||
|
||||
modInstruction="Modを選択してください!\nModはゲームの中身を変えます\nしかしゲームが破損することもあります\nModを使用した場合スコアは保存されません",
|
||||
modInstruction="Modを選択してください!\nModはゲームルールを変えられますが正常にプレイできなくなる可能性があります\nModを使用した場合、スコアは保存されません",
|
||||
modInfo={
|
||||
next="NEXT\nNEXTの個数を変更します",
|
||||
hold="HOLD\nHOLDの個数を変更します",
|
||||
@@ -209,7 +210,7 @@ return {
|
||||
hideGhost="No Ghost\nゴーストを消します",
|
||||
hidden="Hide Locked Pieces\n設置されたピースが時間内に見えなくなります",
|
||||
hideBoard="Hide Board\n盤面の一部もしくは、全体を隠します",
|
||||
flipBoard="Flip Board\n盤面が回転もしくは滑ります",
|
||||
flipBoard="Flip Board\n盤面が回転もしくは、滑ります",
|
||||
dropDelay="Gravity\n落下速度をフレーム単位で変更します",
|
||||
lockDelay="Lock Delay\n設置猶予をフレーム単位で変更します",
|
||||
waitDelay="Spawn Delay\nブロックの出現猶予をフレーム単位で変更します",
|
||||
@@ -401,7 +402,7 @@ return {
|
||||
mod={
|
||||
title="Mods",
|
||||
reset="リセット (tab)",
|
||||
unranked="ランク無し",
|
||||
unranked="記録不可",
|
||||
},
|
||||
pause={
|
||||
setting="設定 (S)",
|
||||
@@ -531,8 +532,10 @@ return {
|
||||
|
||||
clickFX="クリック演出",
|
||||
power="バッテリー",
|
||||
clean="素早い描画",
|
||||
clean="描画処理の最適化",
|
||||
fullscreen="フルスクリーン",
|
||||
portrait="縦画面",
|
||||
msaa="アンチエイリアス(MSAA)レベル",
|
||||
|
||||
bg_on="通常背景",
|
||||
bg_off="背景なし ",
|
||||
@@ -584,16 +587,16 @@ return {
|
||||
a6="ハードドロップ",
|
||||
a7="ソフトドロップ",
|
||||
a8="ホールド",
|
||||
a9="ファンクション 1",
|
||||
a10="ファンクション 2",
|
||||
a9="機能 1",
|
||||
a10="機能 2",
|
||||
a11="即左移動",
|
||||
a12="即右移動",
|
||||
a13="ソニックドロップ",
|
||||
a14="下1移動",
|
||||
a15="下4移動",
|
||||
a16="下10移動",
|
||||
a17="左ドロップ",
|
||||
a18="右ドロップ",
|
||||
a14="落下移動 1",
|
||||
a15="落下移動 4",
|
||||
a16="落下移動 10",
|
||||
a17="左端ハードドロップ",
|
||||
a18="右端ハードドロップ",
|
||||
a19="左ザンギ",
|
||||
a20="右ザンギ",
|
||||
restart="リトライ",
|
||||
@@ -713,7 +716,7 @@ return {
|
||||
Z2="Z2",S2="S2",J2="J2",L2="L2",T2="T2",O2="O2",I2="I2",
|
||||
Z3="Z3",S3="S3",J3="J3",L3="L3",T3="T3",O3="O3",I3="I3",
|
||||
O4="O4",I4="I4",
|
||||
mission="強制ミッション",
|
||||
mission="ミッションを強制",
|
||||
},
|
||||
about={
|
||||
staff="スタッフ",
|
||||
@@ -743,21 +746,11 @@ return {
|
||||
music="曲",
|
||||
label="ラベル",
|
||||
},
|
||||
login_pw={
|
||||
title="ログイン",
|
||||
login_mail="アカウントを登録/パスワードを忘れた",
|
||||
email="Eメールアドレス",
|
||||
password="パスワード",
|
||||
showEmail="Eメールアドレスを表示",
|
||||
login="ログイン",
|
||||
},
|
||||
login_mail={
|
||||
title="サインイン/サインアップ",
|
||||
login_pw="パスワードでログイン",
|
||||
email="Eメールアドレス",
|
||||
send="認証コード送信",
|
||||
code="認証コード",
|
||||
verify="認証",
|
||||
logi={
|
||||
-- title="Sign In",
|
||||
-- ticket="Auth Ticket",
|
||||
-- authorize="Open Authorizing Page",
|
||||
-- submit="Submit",
|
||||
},
|
||||
reset_password={
|
||||
title="パスワード再設定",
|
||||
@@ -771,41 +764,41 @@ return {
|
||||
title="アカウント",
|
||||
},
|
||||
app_15p={
|
||||
color="Color",
|
||||
invis="Invis",
|
||||
slide="Slide",
|
||||
pathVis="Show Path",
|
||||
revKB="Reverse",
|
||||
color="色",
|
||||
invis="インビジブル",
|
||||
slide="スライド",
|
||||
pathVis="ポインター",
|
||||
revKB="逆順",
|
||||
},
|
||||
app_schulteG={
|
||||
rank="Size",
|
||||
invis="Invis",
|
||||
disappear="Hide",
|
||||
tapFX="Tap FX",
|
||||
rank="サイズ",
|
||||
invis="インビジブル",
|
||||
disappear="済消去",
|
||||
tapFX="効果音",
|
||||
},
|
||||
app_AtoZ={
|
||||
level="Level",
|
||||
keyboard="Keyboard",
|
||||
level="レベル",
|
||||
keyboard="キーボード",
|
||||
},
|
||||
app_2048={
|
||||
invis="Invis",
|
||||
tapControl="Tap controls",
|
||||
invis="インビジブル",
|
||||
tapControl="タッチ操作",
|
||||
|
||||
skip="Skip Round",
|
||||
skip="スキップ",
|
||||
},
|
||||
app_ten={
|
||||
next="Next",
|
||||
invis="Invis",
|
||||
fast="Fast",
|
||||
invis="インビジブル",
|
||||
fast="高速落下",
|
||||
},
|
||||
app_dtw={
|
||||
color="Color",
|
||||
mode="Mode",
|
||||
color="色",
|
||||
mode="モード",
|
||||
bgm="BGM",
|
||||
arcade="Arcade",
|
||||
arcade="アーケード",
|
||||
},
|
||||
app_link={
|
||||
invis="Invis",
|
||||
invis="インビジブル",
|
||||
},
|
||||
savedata={
|
||||
export="クリップボードにコピー",
|
||||
|
||||
@@ -8,6 +8,7 @@ return {
|
||||
playedLong="[Anti-vício] Você andou jogando bastante hoje. Certifique-se de fazer pausas.",
|
||||
playedTooMuch="[Anti-vício] Você esteve jogando demais hoje! Você não pode jogar mais.",
|
||||
-- settingWarn="Modifing uncommon setting, be careful!",
|
||||
-- settingWarn2="This setting takes effect after restart",
|
||||
|
||||
atkModeName={"Aleatório","Emblemas","K.O.s","Atacantes"},
|
||||
royale_remain="$1 Jogadores restantes",
|
||||
@@ -520,6 +521,8 @@ return {
|
||||
power="Informação bateria",
|
||||
-- clean="Fast Draw",
|
||||
fullscreen="Tela cheia",
|
||||
-- portrait="Portrait",
|
||||
-- msaa="MSAA level",
|
||||
|
||||
-- bg_on="Normal B.G.",
|
||||
-- bg_off="No B.G.",
|
||||
@@ -731,21 +734,11 @@ return {
|
||||
-- music="BGMs",
|
||||
-- label="label",
|
||||
},
|
||||
login_pw={
|
||||
title="Log in",
|
||||
-- login_mail="Login with E-mail/Sign Up",
|
||||
email="Endereço De Email",
|
||||
password="Senha",
|
||||
-- showEmail="Show Email",
|
||||
login="Log in",
|
||||
},
|
||||
login_mail={
|
||||
title="Log in/Registrar",
|
||||
-- login_pw="Password Sign In",
|
||||
email="Endereço De Email",
|
||||
-- send="Send code",
|
||||
-- code="Verification Code",
|
||||
-- verify="Verify",
|
||||
login={
|
||||
-- title="Sign In",
|
||||
-- ticket="Auth Ticket",
|
||||
-- authorize="Open Authorizing Page",
|
||||
-- submit="Submit",
|
||||
},
|
||||
reset_password={
|
||||
-- title="Reset Password",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
return {
|
||||
fallback='en',
|
||||
|
||||
loadText={
|
||||
loadSFX="#!#",
|
||||
loadSample="#~#",
|
||||
@@ -283,6 +282,8 @@ return {
|
||||
power="+.",
|
||||
clean="[]→→O",
|
||||
fullscreen="|←→|",
|
||||
portrait="↑▉↓",
|
||||
msaa="/ _",
|
||||
|
||||
bg_on="__?__",
|
||||
bg_off="__.__",
|
||||
@@ -484,21 +485,11 @@ return {
|
||||
music="~~~",
|
||||
label="...",
|
||||
},
|
||||
login_pw={
|
||||
title="Log in",
|
||||
-- login_mail="Login with E-mail/Sign Up",
|
||||
email="@",
|
||||
password="*",
|
||||
showEmail="?",
|
||||
login="→",
|
||||
},
|
||||
login_mail={
|
||||
title="Log in/Sign up",
|
||||
login_pw="*** →",
|
||||
email="@",
|
||||
send="→",
|
||||
code="←",
|
||||
verify="!",
|
||||
login={
|
||||
title="Sign In",
|
||||
ticket="***",
|
||||
authorize="**?",
|
||||
submit="<!>",
|
||||
},
|
||||
reset_password={
|
||||
title="R ***",
|
||||
|
||||
@@ -17,6 +17,7 @@ return {
|
||||
playedLong="已经玩很久了!注意休息!",
|
||||
playedTooMuch="今天玩太久啦!打块好玩但也要适可而止哦~",
|
||||
settingWarn="正在修改不常用设置,小心操作!",
|
||||
settingWarn2="该设置需要重启后生效",
|
||||
|
||||
atkModeName={"随机","徽章","击杀","反击"},
|
||||
royale_remain="剩余 $1 名玩家",
|
||||
@@ -256,7 +257,7 @@ return {
|
||||
"",
|
||||
"使用LÖVE引擎",
|
||||
"错误或者建议请附带截图发送到内测群或者作者邮箱~",
|
||||
"仅通过官网 *暂无域名,见词典* 免费下载/更新",
|
||||
"仅通过官网(见主菜单词典) 免费下载/更新",
|
||||
"其他渠道获得游戏皆有被修改/加广告/植入病毒的风险,程序只申请了振动&联网权限!",
|
||||
"若由于被修改的本游戏产生的各种损失作者不负责(怎么负责啊我又没法管)",
|
||||
FNNS and "/" or "请从正规途径获得最新版,游戏现为免费,不过有打赏当然感谢啦~",
|
||||
@@ -338,7 +339,7 @@ return {
|
||||
"Airun",
|
||||
"幽灵3383",
|
||||
"",
|
||||
"Performances",
|
||||
"演出",
|
||||
"Electric283",
|
||||
"Hebomai",
|
||||
"",
|
||||
@@ -532,6 +533,8 @@ return {
|
||||
power="电量和时间",
|
||||
clean="绘制优化",
|
||||
fullscreen="全屏",
|
||||
portrait="竖屏",
|
||||
msaa="抗锯齿等级",
|
||||
|
||||
bg_on="普通背景",
|
||||
bg_off="关闭背景",
|
||||
@@ -741,21 +744,11 @@ return {
|
||||
path="打开存储目录",
|
||||
save="用户档案管理",
|
||||
},
|
||||
login_pw={
|
||||
login={
|
||||
title="登录",
|
||||
login_mail="邮箱登录/注册",
|
||||
email="邮箱",
|
||||
password="密码",
|
||||
showEmail="显示邮箱",
|
||||
login="登录",
|
||||
},
|
||||
login_mail={
|
||||
title="登录/注册",
|
||||
login_pw="密码登录",
|
||||
email="邮箱",
|
||||
send="发送验证码",
|
||||
code="验证码",
|
||||
verify="验证邮箱",
|
||||
ticket="登录口令",
|
||||
authorize="去官网获取口令",
|
||||
submit="登录",
|
||||
},
|
||||
reset_password={
|
||||
title="重置密码",
|
||||
@@ -971,7 +964,6 @@ return {
|
||||
"方块能吃吗",
|
||||
"感觉明明按键了但是没反应?你真的按到了吗?",
|
||||
"感谢群友帮忙想tip",
|
||||
"隔壁不在乎玩家意见但是我们在乎,没人提过的合理建议一定会回应",
|
||||
"隔断消除即将到来!",
|
||||
"还能写些什么tip呢",
|
||||
"好像还没人能用脚打块打到一定水平",
|
||||
@@ -993,7 +985,7 @@ return {
|
||||
"你今天的人品值是(满分100):"..math.random(100),
|
||||
"你们考虑过Z酱的感受吗?没有!你们只考虑你自己。",
|
||||
"配乐是有考虑到模式氛围的哦",
|
||||
"请谨慎向没有方块经验的玩家推荐,会对本游戏的生存环境造成影响,感谢配合。",
|
||||
"拼图与趣味",
|
||||
"请勿使用三只手游玩",
|
||||
"全球目前应该没人能全X评价(大爆炸不算)",
|
||||
"如何O-spin: 一秒转626圈(误",
|
||||
@@ -1019,14 +1011,13 @@ return {
|
||||
"游戏使用un……LÖVE引擎制作",
|
||||
"游戏原声已上架网易云音乐",
|
||||
"有建议的话可以反馈给作者~",
|
||||
"有两个模式是以东方Project里的角色为主题的",
|
||||
"这不是休闲游戏……别怪关卡要求太高,多练吧",
|
||||
"中文方块百科全书:tetris.huijiwiki.com",
|
||||
"众所周知mac不能拿来玩游戏",
|
||||
"作业没做完别玩手机",
|
||||
"作者40行sub26了",
|
||||
"作者电脑上装了11个方块",
|
||||
"作者浏览器收藏夹里有6个方块",
|
||||
"作者电脑上装了16个方块",
|
||||
"作者浏览器收藏夹里有7个方块",
|
||||
"ALLSPIN!",
|
||||
"Am G F G",
|
||||
"B2B2B???",
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
local C=COLOR
|
||||
return {
|
||||
loadText={
|
||||
loadSFX="Load(SFX);",
|
||||
@@ -17,6 +16,7 @@ return {
|
||||
playedLong="PlayedLong=true",
|
||||
playedTooMuch="PlayedTooMuch=true",
|
||||
settingWarn="SettingWarn();",
|
||||
settingWarn2="SettingWarn2();",
|
||||
|
||||
atkModeName={"Random();","Badges();","Kills();","Back();"},
|
||||
royale_remain="LeftPlayers=$1",
|
||||
@@ -205,7 +205,7 @@ return {
|
||||
"",
|
||||
"使用LÖVE引擎",
|
||||
"错误或者建议请附带截图发送到内测群或者作者邮箱~",
|
||||
"仅通过官网 *暂无域名,见词典* 免费下载/更新",
|
||||
"仅通过官网/*见主菜单词典*/ 免费下载/更新",
|
||||
"其他渠道获得游戏皆有被修改/加广告/植入病毒的风险,程序只申请了振动&联网权限!",
|
||||
"若由于被修改的本游戏产生的各种损失作者不负责(怎么负责啊我又没法管)",
|
||||
FNNS and "/" or "请从正规途径获得最新版,游戏现为免费,不过有打赏当然感谢啦~",
|
||||
@@ -288,7 +288,7 @@ return {
|
||||
-- "XMiao",
|
||||
"幽灵3383",
|
||||
"",
|
||||
"Performances",
|
||||
"演出",
|
||||
"Electric283",
|
||||
"Hebomai",
|
||||
"",
|
||||
@@ -482,6 +482,8 @@ return {
|
||||
power="Set.Battery",
|
||||
clean="Set.QuickDraw",
|
||||
fullscreen="Set.Fullscreen",
|
||||
portrait="Set.Portrait",
|
||||
msaa="Set.MSAA",
|
||||
|
||||
bg_on="Set.BG(Normal);",
|
||||
bg_off="Set.BG(Off);",
|
||||
@@ -691,21 +693,11 @@ return {
|
||||
path="OpenPath();",
|
||||
save="DataManagement();",
|
||||
},
|
||||
login_pw={
|
||||
title="LogIn.UI",
|
||||
login_mail="Login_mail_sign_up()",
|
||||
email="Email=",
|
||||
password="Password=",
|
||||
showEmail="ShowEmail",
|
||||
login="Login();",
|
||||
},
|
||||
login_mail={
|
||||
title="LogIn_Register.UI",
|
||||
login_pw="Login_pw();",
|
||||
email="Email=",
|
||||
send="Send();",
|
||||
code="V-code=",
|
||||
verify="Verify();",
|
||||
login={
|
||||
title="SignIn.UI",
|
||||
ticket="Ticket=",
|
||||
authorize="Authorize()",
|
||||
submit="Submit()",
|
||||
},
|
||||
reset_password={
|
||||
title="Reset_Password.UI",
|
||||
|
||||
@@ -17,6 +17,7 @@ return {
|
||||
playedLong="你玩太久了!注意休息!",
|
||||
playedTooMuch="今天玩得太久啦!Techmino好玩但也要注意休息哦~",
|
||||
settingWarn="正在修改不常用設定,小心操作!",
|
||||
settingWarn2="該設定需要重啟後生效",
|
||||
|
||||
atkModeName={"隨機","徽章","K.O.","反擊"},
|
||||
royale_remain="剩下 $1 名玩家",
|
||||
@@ -532,6 +533,8 @@ return {
|
||||
power="電量顯示",
|
||||
clean="渲染優化",
|
||||
fullscreen="全屏幕",
|
||||
portrait="豎屏",
|
||||
msaa="抗鋸齒等級",
|
||||
|
||||
bg_on="普通背景",
|
||||
bg_off="無背景",
|
||||
@@ -741,21 +744,11 @@ return {
|
||||
path="打開存儲目錄",
|
||||
save="用戶資料管理",
|
||||
},
|
||||
login_pw={
|
||||
login={
|
||||
title="登錄",
|
||||
login_mail="電郵登錄/注册",
|
||||
email="電郵",
|
||||
password="密碼",
|
||||
showEmail="顯示郵箱",
|
||||
login="登錄",
|
||||
},
|
||||
login_mail={
|
||||
title="登錄/註冊",
|
||||
login_pw="密碼登錄",
|
||||
email="電郵",
|
||||
send="發送驗證碼",
|
||||
code="驗證碼",
|
||||
verify="驗證郵箱",
|
||||
ticket="登錄口令",
|
||||
authorize="去官網獲取口令",
|
||||
submit="登錄",
|
||||
},
|
||||
reset_password={
|
||||
title="重設密碼",
|
||||
|
||||
282
parts/net.lua
282
parts/net.lua
@@ -119,257 +119,43 @@ local function getMsg(request,timeout)
|
||||
end
|
||||
end
|
||||
end
|
||||
function NET.getCode(email)
|
||||
if not TASK.lock('getCode') then return end
|
||||
|
||||
function NET.login(auto)
|
||||
if not TASK.lock('login') then return end
|
||||
TASK.new(function()
|
||||
WAIT{
|
||||
quit=function()
|
||||
TASK.unlock('getCode')
|
||||
HTTP.deletePool('getCode')
|
||||
end,
|
||||
timeout=12.6,
|
||||
}
|
||||
|
||||
local res=getMsg({
|
||||
pool='getCode',
|
||||
path='/techmino/api/v1/auth/verify/email',
|
||||
body={email=email},
|
||||
},12.6)
|
||||
|
||||
if res and res.code==200 then
|
||||
MES.new('info',text.checkEmail,5)
|
||||
end
|
||||
|
||||
WAIT.interrupt()
|
||||
end)
|
||||
end
|
||||
function NET.codeLogin(email,code)
|
||||
if not TASK.lock('codeLogin') then return end
|
||||
TASK.new(function()
|
||||
WAIT{
|
||||
quit=function()
|
||||
TASK.unlock('codeLogin')
|
||||
HTTP.deletePool('codeLogin')
|
||||
end,
|
||||
timeout=6.26,
|
||||
}
|
||||
|
||||
local res=getMsg({
|
||||
pool='codeLogin',
|
||||
path='/techmino/api/v1/auth/login/email',
|
||||
body={
|
||||
email=email,
|
||||
code=code,
|
||||
},
|
||||
},6.26)
|
||||
|
||||
if res then
|
||||
if res.code==200 then
|
||||
USER.rToken=res.data.refreshToken
|
||||
USER.aToken=res.data.accessToken
|
||||
saveUser()
|
||||
NET.ws_connect()
|
||||
SCN.swapTo('net_menu')
|
||||
elseif res.code==201 then
|
||||
USER.rToken=res.data.refreshToken
|
||||
USER.aToken=res.data.accessToken
|
||||
saveUser()
|
||||
SCN.pop()SCN.push('net_menu')
|
||||
SCN.go('reset_password',nil,code)
|
||||
end
|
||||
end
|
||||
|
||||
WAIT.interrupt()
|
||||
end)
|
||||
end
|
||||
function NET.setPW(code,pw)
|
||||
if not TASK.lock('setPW') then return end
|
||||
TASK.new(function()
|
||||
WAIT{
|
||||
quit=function()
|
||||
TASK.unlock('setPW')
|
||||
HTTP.deletePool('setPW')
|
||||
end,
|
||||
timeout=6.26,
|
||||
}
|
||||
|
||||
local salt do
|
||||
local res=getMsg({
|
||||
pool='pwLogin',
|
||||
path='/techmino/api/v1/auth/seed/email',
|
||||
body={
|
||||
email=USER.email,
|
||||
},
|
||||
},6.26)
|
||||
|
||||
if res and res.code==200 then
|
||||
salt=res.data
|
||||
else
|
||||
WAIT.interrupt()
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
pw=HASH.pbkdf2(HASH.sha3_256,pw,salt,260)
|
||||
|
||||
local res=getMsg({
|
||||
pool='setPW',
|
||||
method='PUT',
|
||||
path='/techmino/api/v1/auth/reset/email',
|
||||
body={
|
||||
email=USER.email,
|
||||
code=code,
|
||||
newPassword=pw,
|
||||
},
|
||||
},6.26)
|
||||
|
||||
if res then
|
||||
if res.code==200 then
|
||||
USER.password=pw
|
||||
saveUser()
|
||||
SCN.back()
|
||||
end
|
||||
end
|
||||
|
||||
WAIT.interrupt()
|
||||
end)
|
||||
end
|
||||
function NET.autoLogin()
|
||||
if not TASK.lock('autoLogin') then return end
|
||||
TASK.new(function()
|
||||
WAIT{
|
||||
quit=function()
|
||||
TASK.unlock('autoLogin')
|
||||
HTTP.deletePool('autoLogin')
|
||||
TASK.unlock('login')
|
||||
HTTP.deletePool('login')
|
||||
end,
|
||||
timeout=12.6,
|
||||
}
|
||||
|
||||
if USER.aToken then
|
||||
local res=getMsg({
|
||||
pool='autoLogin',
|
||||
path='/techmino/api/v1/auth/check',
|
||||
pool='login',
|
||||
url=AUTHHOST,
|
||||
path='/studio26f/api/v1/auth/check',
|
||||
headers={["x-access-token"]=USER.aToken},
|
||||
},6.26)
|
||||
|
||||
if res then
|
||||
if res.code==200 then
|
||||
USER.uid=res.data
|
||||
saveUser()
|
||||
NET.ws_connect()
|
||||
SCN.go('net_menu')
|
||||
WAIT.interrupt()
|
||||
return
|
||||
end
|
||||
else
|
||||
WAIT.interrupt()
|
||||
return
|
||||
end
|
||||
end
|
||||
if USER.rToken then
|
||||
local res=getMsg({
|
||||
pool='autoLogin',
|
||||
path='/techmino/api/v1/auth/refresh',
|
||||
headers={["x-refresh-token"]=USER.rToken},
|
||||
},6.26)
|
||||
|
||||
if res then
|
||||
if res.code==200 then
|
||||
USER.rToken=res.data.refreshToken
|
||||
if res and math.floor(res.code/100)==2 then
|
||||
USER.uid=res.data.playerId
|
||||
if res.data.accessToken then
|
||||
USER.aToken=res.data.accessToken
|
||||
saveUser()
|
||||
NET.ws_connect()
|
||||
SCN.go('net_menu')
|
||||
WAIT.interrupt()
|
||||
return
|
||||
end
|
||||
else
|
||||
WAIT.interrupt()
|
||||
return
|
||||
end
|
||||
end
|
||||
if USER.password then
|
||||
local res=getMsg({
|
||||
pool='pwLogin',
|
||||
path='/techmino/api/v1/auth/login/email',
|
||||
body={
|
||||
email=USER.email,
|
||||
password=USER.password,
|
||||
},
|
||||
},6.26)
|
||||
if res then
|
||||
if res.code==200 then
|
||||
USER.rToken=res.data.refreshToken
|
||||
USER.aToken=res.data.accessToken
|
||||
saveUser()
|
||||
NET.ws_connect()
|
||||
SCN.go('net_menu')
|
||||
WAIT.interrupt()
|
||||
return
|
||||
saveUser()
|
||||
NET.ws_connect()
|
||||
if not auto then-- Quit login menu
|
||||
SCN.pop()
|
||||
end
|
||||
else
|
||||
WAIT.interrupt()
|
||||
end
|
||||
end
|
||||
|
||||
SCN.go('login_pw')
|
||||
WAIT.interrupt()
|
||||
end)
|
||||
end
|
||||
function NET.pwLogin(email,pw)
|
||||
if not TASK.lock('pwLogin') then return end
|
||||
TASK.new(function()
|
||||
WAIT{
|
||||
quit=function()
|
||||
TASK.unlock('pwLogin')
|
||||
HTTP.deletePool('pwLogin')
|
||||
end,
|
||||
timeout=12.6,
|
||||
}
|
||||
TEST.yieldT(.26)
|
||||
|
||||
local salt do
|
||||
local res=getMsg({
|
||||
pool='pwLogin',
|
||||
path='/techmino/api/v1/auth/seed/email',
|
||||
body={
|
||||
email=email,
|
||||
},
|
||||
},6.26)
|
||||
|
||||
if res and res.code==200 then
|
||||
salt=res.data
|
||||
else
|
||||
SCN.go('net_menu')
|
||||
WAIT.interrupt()
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
pw=HASH.pbkdf2(HASH.sha3_256,pw,salt,260)
|
||||
|
||||
do
|
||||
local res=getMsg({
|
||||
pool='pwLogin',
|
||||
path='/techmino/api/v1/auth/login/email',
|
||||
body={
|
||||
email=email,
|
||||
password=pw,
|
||||
},
|
||||
},6.26)
|
||||
|
||||
if res then
|
||||
if res.code==200 then
|
||||
USER.email=email
|
||||
USER.password=pw
|
||||
USER.rToken=res.data.refreshToken
|
||||
USER.aToken=res.data.accessToken
|
||||
saveUser()
|
||||
NET.ws_connect()
|
||||
SCN.swapTo('net_menu')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
SCN.go('login')
|
||||
WAIT.interrupt()
|
||||
end)
|
||||
end
|
||||
@@ -377,7 +163,8 @@ function NET.getUserInfo(uid)
|
||||
TASK.new(function()
|
||||
local res=getMsg({
|
||||
pool='getInfo',
|
||||
path='/techmino/api/v1/player/info?playerId='..uid,
|
||||
url=AUTHHOST,
|
||||
path='/studio26f/api/v1/player/info?playerId='..uid,
|
||||
},6.26)
|
||||
|
||||
if res and res.code==200 and type(res.data)=='table' then
|
||||
@@ -389,7 +176,8 @@ function NET.getAvatar(uid)
|
||||
TASK.new(function()
|
||||
local res=getMsg({
|
||||
pool='getInfo',
|
||||
path='/techmino/api/v1/player/avatar?playerId='..uid,
|
||||
url=AUTHHOST,
|
||||
path='/studio26f/api/v1/player/avatar?playerId='..uid,
|
||||
},6.26)
|
||||
|
||||
if res and res.code==200 and type(res.data)=='string' then
|
||||
@@ -397,6 +185,20 @@ function NET.getAvatar(uid)
|
||||
end
|
||||
end)
|
||||
end
|
||||
function NET.getNotice(lang,count)
|
||||
WAIT{timeout=6.26}
|
||||
TASK.new(function()
|
||||
local res=getMsg({
|
||||
pool='getNotice',
|
||||
path='/techmino/api/v1/notice?language='..(lang or 'zh_cn')..'&lastCount='..(count or 5),
|
||||
},6.26)
|
||||
|
||||
if res and res.code==200 and type(res.data)=='string' then
|
||||
local dataStr=""
|
||||
SCN.go('notice',nil,dataStr)
|
||||
end
|
||||
end)
|
||||
end
|
||||
--------------------------<NEW WS API>
|
||||
local actMap={
|
||||
global_getOnlineCount= 1000,
|
||||
@@ -759,7 +561,7 @@ end
|
||||
|
||||
function NET.ws_connect()
|
||||
if WS.status('game')=='dead' then
|
||||
WS.connect('game','',{['x-access-token']=USER.aToken},6)
|
||||
WS.connect('game','',{['x-access-token']=USER.oToken},6)
|
||||
TASK.removeTask_code(NET.ws_update)
|
||||
TASK.new(NET.ws_update)
|
||||
end
|
||||
@@ -772,6 +574,8 @@ function NET.ws_update()
|
||||
while true do
|
||||
TEST.yieldT(1/26)
|
||||
if WS.status('game')=='dead' then
|
||||
USER.aToken=false
|
||||
USER.oToken=false
|
||||
TEST.yieldUntilNextScene()
|
||||
GAME.playing=false
|
||||
SCN.backTo('main')
|
||||
@@ -785,11 +589,15 @@ function NET.ws_update()
|
||||
local res=getMsg({
|
||||
pool='getUID',
|
||||
path='/techmino/api/v1/auth/check',
|
||||
headers={["x-access-token"]=USER.aToken},
|
||||
headers={["x-access-token"]=USER.oToken},
|
||||
},6.26)
|
||||
|
||||
if res and res.code==200 then
|
||||
USER.uid=res.data
|
||||
if res and math.floor(res.code/100)==2 then
|
||||
USER.uid=res.data.playerId
|
||||
if res.data.accessToken then
|
||||
USER.oToken=res.data.accessToken
|
||||
end
|
||||
saveUser()
|
||||
else
|
||||
TEST.yieldUntilNextScene()
|
||||
GAME.playing=false
|
||||
|
||||
@@ -30,7 +30,6 @@ local hideBoardStencil={
|
||||
down=function() gc_rectangle('fill',0,-300,300,300,6) end,
|
||||
all=function() gc_rectangle('fill',0,-600,300,600,6) end,
|
||||
}
|
||||
local dialFrame=TEXTURE.dial.frame
|
||||
local dialNeedle=TEXTURE.dial.needle
|
||||
local multiple=TEXTURE.multiple
|
||||
local playerborder=TEXTURE.playerBorder
|
||||
@@ -571,13 +570,47 @@ local function _drawNext(P,repMode)
|
||||
end
|
||||
gc_translate(-488,-20)
|
||||
end
|
||||
local function _drawDial(x,y,speed)
|
||||
gc_setColor(1,1,1,.7)
|
||||
gc_draw(dialFrame,x,y)
|
||||
gc_setColor(1,1,1,.3)
|
||||
gc_draw(dialNeedle,x+40,y+40,2.094+(speed<=175 and .02094*speed or 4.712-52.36/(speed-125)),nil,nil,1,1)
|
||||
gc_setColor(.9,.9,.91)
|
||||
setFont(30)GC.mStr(int(speed),x+40,y+19)
|
||||
local _drawDial do
|
||||
local function _getDialBackColor(speed)
|
||||
if speed<60 then return COLOR.H
|
||||
elseif speed<120 then return COLOR.Z
|
||||
elseif speed<180 then return COLOR.lC
|
||||
elseif speed<240 then return COLOR.lG
|
||||
elseif speed<300 then return COLOR.lY
|
||||
elseif speed<420 then return COLOR.O
|
||||
else return COLOR.R
|
||||
end
|
||||
end
|
||||
local function _getDialColor(speed)
|
||||
if speed<60 then return COLOR.Z
|
||||
elseif speed<120 then return COLOR.lC
|
||||
elseif speed<180 then return COLOR.lG
|
||||
elseif speed<240 then return COLOR.lY
|
||||
elseif speed<300 then return COLOR.O
|
||||
else return COLOR.R
|
||||
end
|
||||
end
|
||||
function _drawDial(x,y,speed)
|
||||
local theta=3*math.pi/2+((math.pi*(speed<300 and speed or 150+speed/2)/30)%MATH.tau)
|
||||
|
||||
gc_setColor(0,0,0,.4)
|
||||
gc.circle('fill',x+40,y+40,36)
|
||||
|
||||
gc_setColor(1,1,1)
|
||||
gc_draw(dialNeedle,x+40,y+40,theta,nil,nil,1,1)
|
||||
|
||||
gc_setLineWidth(3)
|
||||
gc_setColor(_getDialBackColor(speed))
|
||||
gc.circle('line',x+40,y+40,37)
|
||||
|
||||
gc_setColor(_getDialColor(speed))
|
||||
if speed<420 then
|
||||
gc.arc('line','open',x+40,y+40,37,3*math.pi/2,theta)
|
||||
else
|
||||
gc.circle('line',x+40,y+40,37)
|
||||
end
|
||||
setFont(30)GC.mStr(int(speed),x+40,y+19)
|
||||
end
|
||||
end
|
||||
local function _drawFinesseCombo_norm(P)
|
||||
if P.finesseCombo>2 then
|
||||
|
||||
@@ -600,6 +600,28 @@ do-- function Player:movePosition(x,y,size)
|
||||
TASK.new(task_movePosition,self,x,y,size or self.size)
|
||||
end
|
||||
end
|
||||
do-- function Player:dropPosition(x,y,size)
|
||||
local function task_dropPosition(self)
|
||||
local vy=0
|
||||
local x,y,size=self.x,self.y,self.size
|
||||
while true do
|
||||
yield()
|
||||
y=y+vy
|
||||
vy=vy+.0626
|
||||
self:setPosition(x,y,size)
|
||||
if y>2600 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
local function check_player(obj,Ptar)
|
||||
return obj.args[1]==Ptar
|
||||
end
|
||||
function Player:dropPosition()
|
||||
TASK.removeTask_iterate(check_player,self)
|
||||
TASK.new(task_dropPosition,self)
|
||||
end
|
||||
end
|
||||
|
||||
local frameColorList={[0]=COLOR.Z,COLOR.lG,COLOR.lB,COLOR.lV,COLOR.lO}
|
||||
function Player:setFrameColor(c)
|
||||
@@ -2654,6 +2676,13 @@ local function update_dead(P,dt)
|
||||
_updateMisc(P,dt)
|
||||
end
|
||||
function Player:_die()
|
||||
do
|
||||
local p=TABLE.find(PLY_ALIVE,self)
|
||||
if p then
|
||||
PLY_ALIVE[p]=PLY_ALIVE[#PLY_ALIVE]
|
||||
rem(PLY_ALIVE)
|
||||
end
|
||||
end
|
||||
self.alive=false
|
||||
self.timing=false
|
||||
self.control=false
|
||||
@@ -2818,7 +2847,6 @@ function Player:lose(force)
|
||||
end
|
||||
self:_die()
|
||||
self.result='lose'
|
||||
do local p=TABLE.find(PLY_ALIVE,self) if p then rem(PLY_ALIVE,p) end end
|
||||
if self.gameEnv.layout=='royale' then
|
||||
self:changeAtk()
|
||||
self.modeData.place=#PLY_ALIVE+1
|
||||
@@ -2862,7 +2890,7 @@ function Player:lose(force)
|
||||
SFX.play('fail')
|
||||
VOC.play('lose')
|
||||
if self.gameEnv.layout=='royale' then
|
||||
BGM.play(' end')
|
||||
BGM.play('end')
|
||||
end
|
||||
gameOver()
|
||||
self:newTask(#PLAYERS>1 and task_lose or task_finish)
|
||||
@@ -2876,6 +2904,9 @@ function Player:lose(force)
|
||||
end
|
||||
|
||||
if #PLY_ALIVE>0 then
|
||||
self:dropPosition()
|
||||
freshPlayerPosition('update')
|
||||
|
||||
local cur=PLY_ALIVE[1].group
|
||||
for i=2,#PLY_ALIVE do
|
||||
local g=PLY_ALIVE[i].group
|
||||
|
||||
60
parts/scenes/login.lua
Normal file
60
parts/scenes/login.lua
Normal file
@@ -0,0 +1,60 @@
|
||||
local scene={}
|
||||
|
||||
local function _authorize()
|
||||
love.system.openURL(AUTHURL)
|
||||
end
|
||||
local function _submit()
|
||||
local tickets=scene.widgetList.ticket:getText():upper()
|
||||
if #tickets~=128 then
|
||||
MES.new('error',text.wrongCode)
|
||||
else
|
||||
USER.aToken=tickets:sub(1,64)
|
||||
USER.oToken=tickets:sub(65)
|
||||
NET.login()
|
||||
end
|
||||
end
|
||||
local function _paste()
|
||||
local t=love.system.getClipboardText()
|
||||
if t then
|
||||
t=STRING.trim(t)
|
||||
if #t==128 and t:match("[0-9A-Z]+") then
|
||||
scene.widgetList.ticket:setText(t)
|
||||
return
|
||||
end
|
||||
end
|
||||
MES.new('error',text.wrongCode)
|
||||
end
|
||||
|
||||
function scene.enter()
|
||||
scene.widgetList.ticket:clear()
|
||||
end
|
||||
|
||||
function scene.keyDown(key,rep)
|
||||
if key=='escape' and not rep then
|
||||
SCN.back()
|
||||
elseif key=='return' or key=='kpenter' then
|
||||
if #scene.widgetList.ticket:getText()==0 then
|
||||
_authorize()
|
||||
else
|
||||
_submit()
|
||||
end
|
||||
elseif key=='v' and love.keyboard.isDown('lctrl','rctrl') then
|
||||
_paste()
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
scene.widgetList={
|
||||
WIDGET.newText{name='title', x=80, y=50,font=70,align='L'},
|
||||
|
||||
WIDGET.newInputBox{name='ticket', x=280, y=200,w=730,h=320,font=30,regex="[0-9A-Z]",limit=128},
|
||||
|
||||
WIDGET.newKey{name='authorize', x=430, y=600,w=300,h=80,font=40,code=_authorize},
|
||||
WIDGET.newKey{name='submit', x=755, y=600,w=300,h=80,font=40,code=_submit},
|
||||
WIDGET.newKey{name='paste', x=970, y=600,w=80,font=40,fText=CHAR.icon.import,code=_paste},
|
||||
|
||||
WIDGET.newButton{name='back', x=1140,y=640,w=170,h=80,sound='back',font=60,fText=CHAR.icon.back,code=pressKey'escape'},
|
||||
}
|
||||
|
||||
return scene
|
||||
@@ -1,67 +0,0 @@
|
||||
local scene={}
|
||||
|
||||
local function _getCode()
|
||||
local email=scene.widgetList.email:getText()
|
||||
if not STRING.simpEmailCheck(email) then
|
||||
MES.new('error',text.wrongEmail)
|
||||
else
|
||||
USER.email=email
|
||||
NET.getCode(email)
|
||||
end
|
||||
end
|
||||
local function _codeLogin()
|
||||
local code=scene.widgetList.code:getText():upper()
|
||||
if #code~=8 then
|
||||
MES.new('error',text.wrongCode)
|
||||
else
|
||||
NET.codeLogin(USER.email,code)
|
||||
end
|
||||
end
|
||||
local function _paste()
|
||||
local t=love.system.getClipboardText()
|
||||
if t then
|
||||
t=STRING.trim(t)
|
||||
if #t==8 and t:match("[0-9]+") then
|
||||
scene.widgetList.code:setText(t)
|
||||
return
|
||||
end
|
||||
end
|
||||
MES.new('warn',text.wrongCode)
|
||||
end
|
||||
|
||||
function scene.enter()
|
||||
scene.widgetList.email:setText(USER.email or "")
|
||||
scene.widgetList.code:clear()
|
||||
end
|
||||
|
||||
function scene.keyDown(key,rep)
|
||||
if key=='escape' and not rep then
|
||||
SCN.back()
|
||||
elseif key=='return' or key=='kpenter' then
|
||||
if #scene.widgetList.code:getText():upper()==0 then
|
||||
_getCode()
|
||||
else
|
||||
_codeLogin()
|
||||
end
|
||||
elseif key=='v' and love.keyboard.isDown('lctrl','rctrl') then
|
||||
_paste()
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
scene.widgetList={
|
||||
WIDGET.newText{name='title', x=80, y=50,font=70,align='L'},
|
||||
WIDGET.newButton{name='login_pw', x=1080,y=100,w=260,h=80,color='lY',code=function() SCN.swapTo('login_pw','swipeR') end},
|
||||
|
||||
WIDGET.newInputBox{name='email', x=380, y=200,w=626,h=60,limit=128},
|
||||
WIDGET.newKey{name='send', x=640, y=330,w=300,h=80,font=40,code=_getCode},
|
||||
|
||||
WIDGET.newInputBox{name='code', x=380, y=400,w=626,h=60,regex="[0-9a-zA-Z]",limit=8},
|
||||
WIDGET.newKey{name='verify', x=640, y=530,w=300,h=80,font=40,code=_codeLogin},
|
||||
WIDGET.newKey{name='paste', x=850, y=530,w=80,font=40,fText=CHAR.icon.import,code=_paste},
|
||||
|
||||
WIDGET.newButton{name='back', x=1140,y=640,w=170,h=80,sound='back',font=60,fText=CHAR.icon.back,code=pressKey'escape'},
|
||||
}
|
||||
|
||||
return scene
|
||||
@@ -1,44 +0,0 @@
|
||||
local emailBox=WIDGET.newInputBox{name='email',x=380,y=200,w=500,h=60,limit=128}
|
||||
local passwordBox=WIDGET.newInputBox{name='password',x=380,y=300,w=620,h=60,secret=true,regex="[ -~]",limit=64}
|
||||
|
||||
local showEmail=true
|
||||
|
||||
local function _login()
|
||||
local email,password=emailBox:getText(),passwordBox:getText()
|
||||
if not STRING.simpEmailCheck(email) then
|
||||
MES.new('error',text.wrongEmail) return
|
||||
elseif #password==0 then
|
||||
MES.new('error',text.noPassword) return
|
||||
end
|
||||
NET.pwLogin(email,password)
|
||||
end
|
||||
|
||||
local scene={}
|
||||
|
||||
function scene.enter()
|
||||
showEmail=false
|
||||
emailBox.secret=true
|
||||
emailBox:setText(USER.email)
|
||||
passwordBox:setText("")
|
||||
end
|
||||
|
||||
function scene.keyDown(key,rep)
|
||||
if rep then return true end
|
||||
if key=='return' then
|
||||
_login()
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
scene.widgetList={
|
||||
WIDGET.newText{name='title', x=80, y=50,font=70,align='L'},
|
||||
WIDGET.newButton{name='login_mail',x=1080,y=100,w=260,h=80,color='lY',code=function() SCN.swapTo('login_mail','swipeL') end},
|
||||
emailBox,
|
||||
passwordBox,
|
||||
WIDGET.newSwitch{name='showEmail', x=550, y=420,disp=function() return showEmail end,code=function() showEmail=not showEmail emailBox.secret=not showEmail end},
|
||||
WIDGET.newKey{name='login', x=1140,y=540,w=170,h=80,font=40,code=pressKey'return'},
|
||||
WIDGET.newButton{name='back', x=1140,y=640,w=170,h=80,sound='back',font=60,fText=CHAR.icon.back,code=backScene},
|
||||
}
|
||||
|
||||
return scene
|
||||
@@ -76,7 +76,7 @@ function scene.keyDown(key,isRep)
|
||||
end
|
||||
elseif key=='a' then
|
||||
if _testButton(3) then
|
||||
NET.autoLogin()
|
||||
NET.login(true)
|
||||
end
|
||||
elseif key=='z' then
|
||||
if _testButton(4) then
|
||||
@@ -104,14 +104,19 @@ function scene.keyDown(key,isRep)
|
||||
end
|
||||
elseif key=='3' then
|
||||
if _testButton(10) then
|
||||
MES.new('warn',text.notFinished)
|
||||
-- NET.getNotice()
|
||||
end
|
||||
elseif key=='4' then
|
||||
if _testButton(11) then
|
||||
SCN.go('lang')
|
||||
end
|
||||
elseif key=='x' then
|
||||
if _testButton(11) then
|
||||
if _testButton(12) then
|
||||
SCN.go('about')
|
||||
end
|
||||
elseif key=='m' then
|
||||
if _testButton(12) then
|
||||
if _testButton(13) then
|
||||
SCN.go('manual')
|
||||
end
|
||||
elseif key=='c' then
|
||||
@@ -215,8 +220,9 @@ scene.widgetList={
|
||||
WIDGET.newButton{name='dict', x=2480,y=450,w=800,h=100, color='lG',font=40,align='L',edge=30,code=pressKey'l'},
|
||||
WIDGET.newButton{name='replays',x=2480,y=570,w=800,h=100, color='lC',font=40,align='L',edge=30,code=pressKey','},
|
||||
|
||||
WIDGET.newButton{name='music', x=120,y=80,w=100, color='lO',code=pressKey'2',font=70,fText=CHAR.icon.music},
|
||||
WIDGET.newButton{name='lang', x=280,y=80,w=100, color='lN',code=pressKey'3',font=70,fText=CHAR.icon.language},
|
||||
WIDGET.newButton{name='music', x=90,y=80,w=100, color='lY',code=pressKey'2',font=70,fText=CHAR.icon.music},
|
||||
WIDGET.newButton{name='notice', x=210,y=80,w=100, color='lA',code=pressKey'3',font=70,fText=CHAR.key.winMenu},
|
||||
WIDGET.newButton{name='lang', x=330,y=80,w=100, color='lN',code=pressKey'4',font=70,fText=CHAR.icon.language},
|
||||
WIDGET.newButton{name='about', x=-110,y=670,w=600,h=70, color='lB',align='R',edge=20,code=pressKey'x',font=50,fText=CHAR.icon.info},
|
||||
WIDGET.newButton{name='manual', x=1390,y=670,w=600,h=70, color='lR',align='L',edge=20,code=pressKey'm',font=50,fText=CHAR.icon.help},
|
||||
}
|
||||
|
||||
@@ -111,9 +111,16 @@ function scene.draw()
|
||||
GC.shadedPrint(playing,710,508,'left',2)
|
||||
GC.setColor(sin(t*.5)*.2+.8,sin(t*.7)*.2+.8,sin(t)*.2+.8)
|
||||
GC.print(playing,710,508)
|
||||
|
||||
setFont(35)
|
||||
GC.setColor(1,sin(t*2.6)*.5+.5,sin(t*2.6)*.5+.5)
|
||||
GC.print(author[playing] or "MrZ",670,465)
|
||||
local name=author[playing] or "MrZ"
|
||||
GC.setColor(.26,.26,.26)
|
||||
GC.print(name,670-1,465-1)
|
||||
GC.print(name,670-1,465+1)
|
||||
GC.print(name,670+1,465-1)
|
||||
GC.print(name,670+1,465+1)
|
||||
GC.setColor(1,sin(t*2.6)*.3+.7,sin(t*2.6)*.3+.7)
|
||||
GC.print(name,670,465)
|
||||
|
||||
setFont(20)
|
||||
GC.setColor(COLOR.Z)
|
||||
|
||||
@@ -18,15 +18,13 @@ scene.widgetList={
|
||||
WIDGET.newButton{name='league',x=640, y=180,w=350,h=120,font=40,color='D',code=goScene'net_league'},
|
||||
WIDGET.newButton{name='ffa', x=640, y=360,w=350,h=120,font=40,color='D',code=function() MES.new('warn',text.notFinished)--[[NET.enterRoom({name='ffa'})]] end},
|
||||
WIDGET.newButton{name='rooms', x=640, y=540,w=350,h=120,font=40,code=goScene'net_rooms'},
|
||||
WIDGET.newButton{name='resetPW',x=680,y=40,w=180,h=60,color='dG',code=goScene'reset_password'},
|
||||
WIDGET.newButton{name='logout',x=880, y=40,w=180, h=60,color='dR',
|
||||
code=function()
|
||||
if tryBack() then
|
||||
print('logout')
|
||||
USER.__data.uid=false
|
||||
USER.__data.email=false
|
||||
USER.__data.password=false
|
||||
USER.__data.rToken=false
|
||||
USER.__data.aToken=false
|
||||
USER.__data.oToken=false
|
||||
love.filesystem.remove('conf/user')
|
||||
SCN.back()
|
||||
end
|
||||
|
||||
34
parts/scenes/notice.lua
Normal file
34
parts/scenes/notice.lua
Normal file
@@ -0,0 +1,34 @@
|
||||
local scene={}
|
||||
|
||||
function scene.enter()
|
||||
BG.set('cubes')
|
||||
if type(SCN.args[1])=='string' then
|
||||
scene.widgetList.texts:setTexts(SCN.args[1])
|
||||
else
|
||||
scene.widgetList.texts:setTexts({"No data"})
|
||||
end
|
||||
end
|
||||
|
||||
function scene.wheelMoved(_,y)
|
||||
WHEELMOV(y)
|
||||
end
|
||||
function scene.keyDown(key)
|
||||
if key=='up' then
|
||||
scene.widgetList.texts:scroll(-5)
|
||||
elseif key=='down' then
|
||||
scene.widgetList.texts:scroll(5)
|
||||
elseif key=='pageup' then
|
||||
scene.widgetList.texts:scroll(-20)
|
||||
elseif key=='pagedown' then
|
||||
scene.widgetList.texts:scroll(20)
|
||||
elseif key=='escape' then
|
||||
SCN.back()
|
||||
end
|
||||
end
|
||||
|
||||
scene.widgetList={
|
||||
WIDGET.newTextBox{name='texts',x=30,y=45,w=1000,h=640,font=20,fix=true},
|
||||
WIDGET.newButton{name='back',x=1140,y=640,w=170,h=80,sound='back',font=60,fText=CHAR.icon.back,code=backScene},
|
||||
}
|
||||
|
||||
return scene
|
||||
@@ -17,7 +17,7 @@ local trophyColor-- Current trophy color
|
||||
|
||||
function scene.enter()
|
||||
page=0
|
||||
if SCN.prev:find("setting") then
|
||||
if type(SCN.prev)=='string' and SCN.prev:find("setting") then
|
||||
TEXT.show(text.needRestart,640,410,50,'fly',.6)
|
||||
end
|
||||
local P1=PLAYERS[1]
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
local logged
|
||||
|
||||
local scene={}
|
||||
|
||||
function scene.enter()
|
||||
logged=false
|
||||
end
|
||||
|
||||
local function _dumpCB(T)
|
||||
love.system.setClipboardText(STRING.packText(TABLE.dump(T)))
|
||||
MES.new('check',text.exportSuccess)
|
||||
@@ -79,9 +85,9 @@ scene.widgetList={
|
||||
end},
|
||||
|
||||
WIDGET.newText{name='couldSave', x=55,y=485,color='lB',align='L',font=50},
|
||||
WIDGET.newText{name='notLogin', x=55,y=550,color='dB',align='L',font=30,hideF=function() return WS.status('user')=='running' end},
|
||||
WIDGET.newButton{name='upload', x=190,y=610,w=280,h=90,color='lB',font=25,code=NET.uploadSave,hideF=function() return WS.status('user')~='running' end},
|
||||
WIDGET.newButton{name='download', x=490,y=610,w=280,h=90,color='lB',font=25,code=NET.downloadSave,hideF=function() return WS.status('user')~='running' end},
|
||||
WIDGET.newText{name='notLogin', x=55,y=550,color='C',align='L',font=30,hideF=function() return logged end},
|
||||
WIDGET.newButton{name='upload', x=190,y=610,w=280,h=90,color='lB',font=25,code=NET.uploadSave,hideF=function() return not logged end},
|
||||
WIDGET.newButton{name='download', x=490,y=610,w=280,h=90,color='lB',font=25,code=NET.downloadSave,hideF=function() return not logged end},
|
||||
WIDGET.newButton{name='back', x=1140,y=640,w=170,h=80,sound='back',font=60,fText=CHAR.icon.back,code=backScene},
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ scene.widgetList={
|
||||
WIDGET.newButton{name='touch', x=990, y=220, w=320,h=80,color=not MOBILE and 'dH',font=35, code=goScene'setting_touch',hideF=function() return not SETTING.VKSwitch end},
|
||||
WIDGET.newSwitch{name='showVK', x=1100, y=150, lim=400, disp=SETval('VKSwitch'), code=SETrev('VKSwitch')},
|
||||
WIDGET.newSlider{name='reTime', x=330, y=320, w=300,lim=180,axis={.5,3,.25},disp=SETval('reTime'), code=SETsto('reTime'),show=SETval('reTime')},
|
||||
WIDGET.newSelector{name='RS', x=300, y=420, w=300,color='S', disp=SETval('RS'), code=SETsto('RS'),list={'TRS','SRS','SRS_plus','SRS_X','BiRS','ARS_Z','DRS_weak','ASC','ASC_plus','C2','C2_sym','Classic','Classic_plus','None','None_plus'}},
|
||||
WIDGET.newSelector{name='RS', x=300, y=420, w=300,color='S', disp=SETval('RS'), code=SETsto('RS'),list={'TRS','SRS','SRS_plus','SRS_X','BiRS','ARS_Z','DRS_weak','ASC','ASC_plus','C2','C2_sym','N64','N64_plus','Classic','Classic_plus','None','None_plus'}},
|
||||
WIDGET.newSelector{name='menuPos',x=980, y=320, w=300,color='O', disp=SETval('menuPos'), code=SETsto('menuPos'),list={'left','middle','right'}},
|
||||
WIDGET.newSwitch{name='sysCursor',x=1060, y=400, lim=580, disp=SETval('sysCursor'),code=function() SETTING.sysCursor=not SETTING.sysCursor applySettings() end},
|
||||
WIDGET.newSwitch{name='autoPause',x=1060, y=470, lim=580, disp=SETval('autoPause'),code=SETrev('autoPause')},
|
||||
|
||||
@@ -42,6 +42,11 @@ function scene.draw()
|
||||
gc.pop()
|
||||
end
|
||||
|
||||
local function _msaaShow(S)
|
||||
S=S.disp()
|
||||
return S==0 and 0 or 2^S
|
||||
end
|
||||
|
||||
scene.widgetScrollHeight=900
|
||||
scene.widgetList={
|
||||
WIDGET.newText{name='title', x=640,y=15,lim=630,font=80},
|
||||
@@ -70,21 +75,23 @@ scene.widgetList={
|
||||
|
||||
WIDGET.newSelector{name='frame', x=400,y=890,lim=280,w=460,list={8,10,13,17,22,29,37,47,62,80,100},disp=SETval('frameMul'),code=function(v) SETTING.frameMul=v;Z.setFrameMul(SETTING.frameMul) end},
|
||||
|
||||
WIDGET.newSwitch{name='text', x=450,y=980,lim=360,disp=SETval('text'), code=SETrev('text')},
|
||||
WIDGET.newSwitch{name='score', x=450,y=1030,lim=360,disp=SETval('score'), code=SETrev('score')},
|
||||
WIDGET.newSwitch{name='bufferWarn', x=450,y=1100,lim=360,disp=SETval('bufferWarn'), code=SETrev('bufferWarn')},
|
||||
WIDGET.newSwitch{name='showSpike', x=450,y=1150,lim=360,disp=SETval('showSpike'), code=SETrev('showSpike')},
|
||||
WIDGET.newSwitch{name='nextPos', x=450,y=1220,lim=360,disp=SETval('nextPos'), code=SETrev('nextPos')},
|
||||
WIDGET.newSwitch{name='highCam', x=450,y=1270,lim=360,disp=SETval('highCam'), code=SETrev('highCam')},
|
||||
WIDGET.newSwitch{name='warn', x=450,y=1340,lim=360,disp=SETval('warn'), code=SETrev('warn')},
|
||||
WIDGET.newSwitch{name='text', x=450,y=980,lim=360,disp=SETval('text'), code=SETrev('text')},
|
||||
WIDGET.newSwitch{name='score', x=450,y=1030,lim=360,disp=SETval('score'), code=SETrev('score')},
|
||||
WIDGET.newSwitch{name='bufferWarn', x=450,y=1100,lim=360,disp=SETval('bufferWarn'), code=SETrev('bufferWarn')},
|
||||
WIDGET.newSwitch{name='showSpike', x=450,y=1150,lim=360,disp=SETval('showSpike'), code=SETrev('showSpike')},
|
||||
WIDGET.newSwitch{name='nextPos', x=450,y=1220,lim=360,disp=SETval('nextPos'), code=SETrev('nextPos')},
|
||||
WIDGET.newSwitch{name='highCam', x=450,y=1270,lim=360,disp=SETval('highCam'), code=SETrev('highCam')},
|
||||
WIDGET.newSwitch{name='warn', x=450,y=1340,lim=360,disp=SETval('warn'), code=SETrev('warn')},
|
||||
|
||||
WIDGET.newSwitch{name='clickFX', x=950,y=980,lim=360,disp=SETval('clickFX'), code=function() SETTING.clickFX=not SETTING.clickFX applySettings() end},
|
||||
WIDGET.newSwitch{name='power', x=950,y=1070,lim=360,disp=SETval('powerInfo'), code=function() SETTING.powerInfo=not SETTING.powerInfo applySettings() end},
|
||||
WIDGET.newSwitch{name='clean', x=950,y=1160,lim=360,disp=SETval('cleanCanvas'), code=function() SETTING.cleanCanvas=not SETTING.cleanCanvas applySettings() end},
|
||||
WIDGET.newSwitch{name='fullscreen', x=950,y=1250,lim=360,disp=SETval('fullscreen'), code=function() SETTING.fullscreen=not SETTING.fullscreen applySettings() end},
|
||||
WIDGET.newSwitch{name='clickFX', x=950,y=980,lim=360,disp=SETval('clickFX'), code=function() SETTING.clickFX=not SETTING.clickFX; applySettings() end},
|
||||
WIDGET.newSwitch{name='power', x=950,y=1050,lim=360,disp=SETval('powerInfo'), code=function() SETTING.powerInfo=not SETTING.powerInfo; applySettings() end},
|
||||
WIDGET.newSwitch{name='clean', x=950,y=1120,lim=360,disp=SETval('cleanCanvas'), code=function() SETTING.cleanCanvas=not SETTING.cleanCanvas; applySettings() end},
|
||||
WIDGET.newSwitch{name='fullscreen', x=950,y=1190,lim=360,disp=SETval('fullscreen'), code=function() SETTING.fullscreen=not SETTING.fullscreen; applySettings() end,hideF=function() return MOBILE end},
|
||||
WIDGET.newSwitch{name='portrait', x=950,y=1190,lim=360,disp=SETval('portrait'), code=function() SETTING.portrait=not SETTING.portrait; saveSettings(); MES.new('warn',text.settingWarn2,6.26) end,hideF=function() return not MOBILE end},
|
||||
WIDGET.newSlider{name='msaa', x=950,y=1250,lim=360,w=200,axis={0,4,1},show=_msaaShow,disp=function() return SETTING.msaa==0 and 0 or math.log(SETTING.msaa,2) end,code=function(v) SETTING.msaa=v==0 and 0 or 2^v; saveSettings(); if TASK.lock('warnMessage',6.26) then MES.new('warn',text.settingWarn2,6.26) end end},
|
||||
|
||||
WIDGET.newKey{name='bg_on', x=680,y=1340,w=200,h=80,code=function() SETTING.bg='on'applySettings() end},
|
||||
WIDGET.newKey{name='bg_off', x=900,y=1340,w=200,h=80,code=function() SETTING.bg='off'applySettings() end},
|
||||
WIDGET.newKey{name='bg_on', x=680,y=1340,w=200,h=80,code=function() SETTING.bg='on'; applySettings() end},
|
||||
WIDGET.newKey{name='bg_off', x=900,y=1340,w=200,h=80,code=function() SETTING.bg='off'; applySettings() end},
|
||||
WIDGET.newKey{name='bg_custom', x=1120,y=1340,w=200,h=80,
|
||||
code=function()
|
||||
if love.filesystem.getInfo('conf/customBG') then
|
||||
|
||||
@@ -62,6 +62,7 @@ local spinChars={
|
||||
|
||||
function scene.draw()
|
||||
local t=TIME()
|
||||
GC.setColor(1,1,1)
|
||||
GC.draw(TEXTURE.title,260,615,.2+.04*math.sin(t*3),.4,nil,580,118)
|
||||
|
||||
GC.setColor(COLOR.Z)
|
||||
|
||||
@@ -148,10 +148,6 @@ TEXTURE.gridLines=(function()
|
||||
end)()
|
||||
|
||||
TEXTURE.dial={
|
||||
frame=GC.DO{80,80,
|
||||
{'setLW',3},
|
||||
{'dCirc',40,40,38},
|
||||
},
|
||||
needle=GC.DO{32,3,
|
||||
{'setLW',3},
|
||||
{'fRect',0,0,32,3,2},
|
||||
|
||||
@@ -2,6 +2,19 @@ return[=[
|
||||
未来计划:
|
||||
正在点亮科技树...
|
||||
|
||||
0.17.11: 暂停 Break
|
||||
改动:
|
||||
新的登录流程(因为服务器代码重写)
|
||||
添加抗锯齿和横竖屏的设置选项
|
||||
添加N64和N64_plus旋转系统 #805
|
||||
好看一些的速度表(by NOT_A_ROBOT) #824 #825
|
||||
丢失的文本会显示为内部名称而不是神秘符号
|
||||
音乐室的作者文本加上描边
|
||||
修复:
|
||||
调整galaxy和quarks背景的粒子颜色,减少对游戏画面的影响
|
||||
None和None_plus搞反
|
||||
音乐Way开头爆音
|
||||
|
||||
0.17.9: 暂停 Break
|
||||
修复:
|
||||
第一次启动选择语言后直接就退出了
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
return {
|
||||
["apkCode"]=453,
|
||||
["code"]=1709,
|
||||
["string"]="V0.17.9",
|
||||
["apkCode"]=456,
|
||||
["code"]=1711,
|
||||
["string"]="V0.17.11",
|
||||
["room"]="ver A-9",
|
||||
["name"]="暂停 Break",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user