Compare commits
131
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d9360f0ff | ||
|
|
1cfe6ca468 | ||
|
|
3bbeafcc3e | ||
|
|
9d9640071c | ||
|
|
8fc1493759 | ||
|
|
69d82f560d | ||
|
|
ccc509ac9f | ||
|
|
ce8e91b361 | ||
|
|
5ac7408af6 | ||
|
|
421ed4ca09 | ||
|
|
bfe152dd8f | ||
|
|
d318ccaca8 | ||
|
|
a87dff7240 | ||
|
|
8873d63067 | ||
|
|
2913d7eea7 | ||
|
|
a89f3509e3 | ||
|
|
cde7d46572 | ||
|
|
d504aa3c35 | ||
|
|
8b449e590f | ||
|
|
e6f1fed96e | ||
|
|
e585de7db5 | ||
|
|
219e95117b | ||
|
|
06e8ba8c18 | ||
|
|
34639d729d | ||
|
|
abf77f72f2 | ||
|
|
4a99e7eda7 | ||
|
|
8bab844e0c | ||
|
|
fb90e2dd96 | ||
|
|
7dcbbc3c64 | ||
|
|
9bd9490c49 | ||
|
|
1b403b2ab2 | ||
|
|
162f1add75 | ||
|
|
6951ac82cd | ||
|
|
56f53c73a9 | ||
|
|
87b825b046 | ||
|
|
cd631c6eda | ||
|
|
eccaa77f0e | ||
|
|
a24de64707 | ||
|
|
7d186d2203 | ||
|
|
86b3fb3ad9 | ||
|
|
82fb0bcf88 | ||
|
|
e6bcb144d9 | ||
|
|
44d134eed0 | ||
|
|
846f2deedb | ||
|
|
deef60b231 | ||
|
|
1d2a391a90 | ||
|
|
e9bd5a52ac | ||
|
|
74343852cf | ||
|
|
fa094580cd | ||
|
|
8cadcd78f6 | ||
|
|
d0bffe825a | ||
|
|
be27447de9 | ||
|
|
a8808be29e | ||
|
|
53aa9cc2e7 | ||
|
|
b7dfce0f70 | ||
|
|
b1de3b1896 | ||
|
|
cdb751e6e1 | ||
|
|
5eddbc59d3 | ||
|
|
15496de225 | ||
|
|
7fc047615f | ||
|
|
535e702bc2 | ||
|
|
31a01bea97 | ||
|
|
5b2a86aace | ||
|
|
43d599acfd | ||
|
|
38c9836dc3 | ||
|
|
a73a51eef3 | ||
|
|
36640c1a43 | ||
|
|
3720bc149c | ||
|
|
8f09809e69 | ||
|
|
5d8a9c71a2 | ||
|
|
bbe3464085 | ||
|
|
3a88e78cec | ||
|
|
4d73ec3477 | ||
|
|
4d8e99f630 | ||
|
|
323c51e42c | ||
|
|
c13a0a2afd | ||
|
|
eecfb619b7 | ||
|
|
c14207236f | ||
|
|
8938665acb | ||
|
|
8369e8fcab | ||
|
|
a465a97c32 | ||
|
|
8506619465 | ||
|
|
3469524d8c | ||
|
|
90e0e5618d | ||
|
|
7a9edf809c | ||
|
|
7719fd6a10 | ||
|
|
95b4d888f0 | ||
|
|
f5dde710e3 | ||
|
|
3220a2e360 | ||
|
|
86839ac6b3 | ||
|
|
dba8200854 | ||
|
|
a296b33c0f | ||
|
|
a3498ce32b | ||
|
|
d358724fd2 | ||
|
|
4ffd164fd2 | ||
|
|
b87c206d45 | ||
|
|
0f8354415e | ||
|
|
0251fe87bb | ||
|
|
b7c932f9a9 | ||
|
|
11b86c389c | ||
|
|
2b66d74b01 | ||
|
|
3b8859120f | ||
|
|
bacd218e0b | ||
|
|
b2049e6285 | ||
|
|
6612fa6205 | ||
|
|
5d63442626 | ||
|
|
2b77d2820c | ||
|
|
071f651d0b | ||
|
|
079fda42fb | ||
|
|
96aac150f0 | ||
|
|
fa135df33d | ||
|
|
ed8a9c6390 | ||
|
|
282fa0376d | ||
|
|
3dbb22667b | ||
|
|
9a2751733e | ||
|
|
734b13904e | ||
|
|
0803e82e58 | ||
|
|
2d6b85365b | ||
|
|
356607f53a | ||
|
|
f9402fe826 | ||
|
|
be1657884e | ||
|
|
e862d72d71 | ||
|
|
43e6aac281 | ||
|
|
157e209f31 | ||
|
|
b8fef83ef1 | ||
|
|
283929b1a2 | ||
|
|
000546e9ff | ||
|
|
7df13ec012 | ||
|
|
68a5dd2482 | ||
|
|
4f834169f3 | ||
|
|
689eda7114 |
@@ -33,4 +33,11 @@ f8b20774e3f035eeddb9211a28a391b20db74456
|
||||
|
||||
# Revert a revert (empty script)
|
||||
392416e00cbd82e1c49e82a9fafdcf2e069a654e
|
||||
159467de832a172681200c463d244a46e295c3c8
|
||||
159467de832a172681200c463d244a46e295c3c8
|
||||
|
||||
# Revert a revert (scripted cutscene path)
|
||||
d73f86d26ec2dbf031c01f588ba4be11842db09c
|
||||
fe0ab0aa454f4ae12ced9502db8a01e7bca3e04c
|
||||
|
||||
# Forgot the # in the commit message
|
||||
484bbcb22aa8f28b62912abb6d8c89fb58e63889
|
||||
+79
-11
@@ -1,22 +1,23 @@
|
||||
name: Linux Builds
|
||||
|
||||
name: Linux Build
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Linux Build
|
||||
permissions: write-all
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Pulling the source
|
||||
uses: actions/checkout@v2
|
||||
- name: Pulling the new commit
|
||||
uses: actions/checkout@v4
|
||||
- name: Setting up Haxe
|
||||
uses: krdlab/setup-haxe@v1
|
||||
uses: krdlab/setup-haxe@v2
|
||||
with:
|
||||
haxe-version: 4.2.5
|
||||
haxe-version: 4.3.7
|
||||
- name: Restore existing build cache for faster compilation
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4.2.3
|
||||
with:
|
||||
# not caching the bin folder to prevent asset duplication and stuff like that
|
||||
key: cache-build-linux
|
||||
@@ -24,8 +25,8 @@ jobs:
|
||||
.haxelib/
|
||||
export/release/linux/haxe/
|
||||
export/release/linux/obj/
|
||||
restore-keys: |
|
||||
cache-build-linux
|
||||
- run: |
|
||||
echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV
|
||||
- name: Installing LibVLC
|
||||
run: |
|
||||
sudo apt-get install libvlc-dev libvlccore-dev
|
||||
@@ -67,7 +68,7 @@ jobs:
|
||||
}
|
||||
}
|
||||
- name: Uploading new cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4.2.3
|
||||
with:
|
||||
# caching again since for some reason it doesnt work with the first post cache shit
|
||||
key: cache-build-linux
|
||||
@@ -75,5 +76,72 @@ jobs:
|
||||
.haxelib/
|
||||
export/release/linux/haxe/
|
||||
export/release/linux/obj/
|
||||
restore-keys: |
|
||||
cache-build-linux
|
||||
|
||||
# didnt compile debug in the same job or github would have said that job wasn't completed until debug was done too (debug uploads are not essential)
|
||||
debug_build:
|
||||
name: Linux Debug Build
|
||||
permissions: write-all
|
||||
runs-on: ubuntu-24.04
|
||||
needs: build # since its low priority, it'll run after, so actions will concentrate first on normal builds
|
||||
steps:
|
||||
- name: Pulling the new commit
|
||||
uses: actions/checkout@v4
|
||||
- name: Setting up Haxe
|
||||
uses: krdlab/setup-haxe@v2
|
||||
with:
|
||||
haxe-version: 4.3.7
|
||||
- name: Restore existing build cache for faster compilation
|
||||
uses: actions/cache@v4.2.3
|
||||
with:
|
||||
# not caching the bin folder to prevent asset duplication and stuff like that
|
||||
key: cache-build-linux-debug
|
||||
path: |
|
||||
.haxelib/
|
||||
export/debug/linux/haxe/
|
||||
export/debug/linux/obj/
|
||||
- run: |
|
||||
echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV
|
||||
- name: Installing LibVLC
|
||||
run: |
|
||||
sudo apt-get install libvlc-dev libvlccore-dev
|
||||
- name: Installing/Updating libraries
|
||||
run: |
|
||||
haxe -cp commandline -D analyzer-optimize --run Main setup -s
|
||||
- name: Building the game
|
||||
run: |
|
||||
haxelib run lime build linux -debug
|
||||
# - name: Tar files
|
||||
# run: tar -zcvf CodenameEngine.tar.gz -C export/debug/linux/bin .
|
||||
- name: Uploading artifact (entire build)
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Codename Engine Debug
|
||||
path: export/debug/linux/bin/
|
||||
- name: Clearing already existing cache
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
const caches = await github.rest.actions.getActionsCacheList({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
})
|
||||
for (const cache of caches.data.actions_caches) {
|
||||
if (cache.key == "cache-build-linux-debug") {
|
||||
console.log('Clearing ' + cache.key + '...')
|
||||
await github.rest.actions.deleteActionsCacheById({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
cache_id: cache.id,
|
||||
})
|
||||
console.log("Cache cleared.")
|
||||
}
|
||||
}
|
||||
- name: Uploading new cache
|
||||
uses: actions/cache@v4.2.3
|
||||
with:
|
||||
# caching again since for some reason it doesnt work with the first post cache shit
|
||||
key: cache-build-linux-debug
|
||||
path: |
|
||||
.haxelib/
|
||||
export/debug/linux/haxe/
|
||||
export/debug/linux/obj/
|
||||
+77
-12
@@ -1,22 +1,23 @@
|
||||
name: Mac OS Builds
|
||||
|
||||
name: Mac OS Build
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Mac OS Build
|
||||
permissions: write-all
|
||||
runs-on: macos-13
|
||||
runs-on: macos-14
|
||||
steps:
|
||||
- name: Pulling the new commit
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
- name: Setting up Haxe
|
||||
uses: krdlab/setup-haxe@v1
|
||||
uses: krdlab/setup-haxe@v2
|
||||
with:
|
||||
haxe-version: 4.2.5
|
||||
haxe-version: 4.3.7
|
||||
- name: Restore existing build cache for faster compilation
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4.2.3
|
||||
with:
|
||||
# not caching the bin folder to prevent asset duplication and stuff like that
|
||||
key: cache-build-mac
|
||||
@@ -24,14 +25,14 @@ jobs:
|
||||
.haxelib/
|
||||
export/release/macos/haxe/
|
||||
export/release/macos/obj/
|
||||
restore-keys: |
|
||||
cache-build-mac
|
||||
- run: |
|
||||
echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV
|
||||
- name: Installing/Updating libraries
|
||||
run: |
|
||||
haxe -cp commandline -D analyzer-optimize --run Main setup -s
|
||||
- name: Building the game
|
||||
run: |
|
||||
haxelib run lime build mac
|
||||
arch -x86_64 haxelib run lime build mac
|
||||
- name: Tar files
|
||||
run: tar -zcvf CodenameEngine.tar.gz -C export/release/macos/bin .
|
||||
- name: Uploading artifact (executable)
|
||||
@@ -64,7 +65,7 @@ jobs:
|
||||
}
|
||||
}
|
||||
- name: Uploading new cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4.2.3
|
||||
with:
|
||||
# caching again since for some reason it doesnt work with the first post cache shit
|
||||
key: cache-build-mac
|
||||
@@ -72,5 +73,69 @@ jobs:
|
||||
.haxelib/
|
||||
export/release/macos/haxe/
|
||||
export/release/macos/obj/
|
||||
restore-keys: |
|
||||
cache-build-mac
|
||||
|
||||
# didnt compile debug in the same job or github would have said that job wasn't completed until debug was done too (debug uploads are not essential)
|
||||
debug_build:
|
||||
name: Mac OS Debug Build
|
||||
permissions: write-all
|
||||
runs-on: macos-14
|
||||
needs: build # since its low priority, it'll run after, so actions will concentrate first on normal builds
|
||||
steps:
|
||||
- name: Pulling the new commit
|
||||
uses: actions/checkout@v4
|
||||
- name: Setting up Haxe
|
||||
uses: krdlab/setup-haxe@v2
|
||||
with:
|
||||
haxe-version: 4.3.7
|
||||
- name: Restore existing build cache for faster compilation
|
||||
uses: actions/cache@v4.2.3
|
||||
with:
|
||||
# not caching the bin folder to prevent asset duplication and stuff like that
|
||||
key: cache-build-mac-debug
|
||||
path: |
|
||||
.haxelib/
|
||||
export/debug/macos/haxe/
|
||||
export/debug/macos/obj/
|
||||
- run: |
|
||||
echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV
|
||||
- name: Installing/Updating libraries
|
||||
run: |
|
||||
haxe -cp commandline -D analyzer-optimize --run Main setup -s
|
||||
- name: Building the game
|
||||
run: |
|
||||
arch -x86_64 haxelib run lime build mac -debug
|
||||
- name: Tar files
|
||||
run: tar -zcvf CodenameEngine.tar.gz -C export/debug/macos/bin .
|
||||
- name: Uploading artifact (entire build)
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Codename Engine Debug
|
||||
path: CodenameEngine.tar.gz
|
||||
- name: Clearing already existing cache
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
const caches = await github.rest.actions.getActionsCacheList({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
})
|
||||
for (const cache of caches.data.actions_caches) {
|
||||
if (cache.key == "cache-build-mac-debug") {
|
||||
console.log('Clearing ' + cache.key + '...')
|
||||
await github.rest.actions.deleteActionsCacheById({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
cache_id: cache.id,
|
||||
})
|
||||
console.log("Cache cleared.")
|
||||
}
|
||||
}
|
||||
- name: Uploading new cache
|
||||
uses: actions/cache@v4.2.3
|
||||
with:
|
||||
# caching again since for some reason it doesnt work with the first post cache shit
|
||||
key: cache-build-mac-debug
|
||||
path: |
|
||||
.haxelib/
|
||||
export/debug/macos/haxe/
|
||||
export/debug/macos/obj/
|
||||
@@ -0,0 +1,197 @@
|
||||
name: Create Release Builds
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag_name:
|
||||
description: "Release name (e.g. v1.0.5 or v1.2-rc1)"
|
||||
required: true
|
||||
prerelease:
|
||||
description: "Is this a prerelease?"
|
||||
required: true
|
||||
type: boolean
|
||||
custom_message:
|
||||
description: "Optional pre-changelog message"
|
||||
required: false
|
||||
|
||||
jobs:
|
||||
collect-release:
|
||||
name: Release ${{ github.event.inputs.tag_name }} Builds
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Download Windows Full Build
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: windows.yml
|
||||
name: Codename Engine
|
||||
path: artifacts/windows/full_build
|
||||
allow_forks: false
|
||||
|
||||
- name: Download Windows Executable
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: windows.yml
|
||||
name: Codename Engine (Executable Only)
|
||||
path: artifacts/windows/executable
|
||||
allow_forks: false
|
||||
|
||||
- name: Download Mac OS Full Build
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: macos.yml
|
||||
name: Codename Engine
|
||||
path: artifacts/macos/full_build
|
||||
allow_forks: false
|
||||
|
||||
- name: Download Mac OS Executable
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: macos.yml
|
||||
name: Codename Engine (Executable Only)
|
||||
path: artifacts/macos/executable
|
||||
allow_forks: false
|
||||
|
||||
- name: Download Linux Full Build
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: linux.yml
|
||||
name: Codename Engine
|
||||
path: artifacts/linux/full_build
|
||||
allow_forks: false
|
||||
|
||||
- name: Download Linux Executable
|
||||
uses: dawidd6/action-download-artifact@v6
|
||||
with:
|
||||
workflow: linux.yml
|
||||
name: Codename Engine (Executable Only)
|
||||
path: artifacts/linux/executable
|
||||
allow_forks: false
|
||||
|
||||
- name: Prepare artifacts
|
||||
run: |
|
||||
mkdir -p renamed
|
||||
|
||||
# Windows
|
||||
mv artifacts/windows/executable/CodenameEngine.exe renamed/update-windows.exe
|
||||
cd artifacts/windows/full_build
|
||||
zip -r ../../../renamed/"Codename Engine-Windows.zip" *
|
||||
cd -
|
||||
|
||||
# Mac OS
|
||||
mv artifacts/macos/executable/CodenameEngine renamed/update-mac
|
||||
cd artifacts/macos/full_build
|
||||
if [ -f CodenameEngine.tar.gz ]; then
|
||||
# Keep tar.gz as-is
|
||||
cp CodenameEngine.tar.gz ../../../renamed/"Codename Engine-Mac.tar.gz"
|
||||
else
|
||||
# Zip contents at root
|
||||
zip -r ../../../renamed/"Codename Engine-Mac.zip" *
|
||||
fi
|
||||
cd -
|
||||
|
||||
# Linux
|
||||
mv artifacts/linux/executable/CodenameEngine renamed/update-linux
|
||||
cd artifacts/linux/full_build
|
||||
zip -r ../../../renamed/"Codename Engine-Linux.zip" *
|
||||
cd -
|
||||
|
||||
- name: Find Base Release
|
||||
id: get_base_release
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
echo "Looking for base release..."
|
||||
PRERELEASE="${{ github.event.inputs.prerelease }}"
|
||||
|
||||
if [[ "$PRERELEASE" == "true" ]]; then
|
||||
BASE=$(gh release list --repo ${{ github.repository }} --json tagName,isPrerelease,isDraft \
|
||||
-L 50 -q '.[] | select(.isPrerelease==false and .isDraft==false) | .tagName' | head -n 1)
|
||||
|
||||
if [ -z "$BASE" ]; then
|
||||
echo "No stable release found, resorting to prereleases."
|
||||
BASE=$(gh release list --repo ${{ github.repository }} --json tagName,isDraft \
|
||||
-L 1 -q '.[] | select(.isDraft==false) | .tagName')
|
||||
fi
|
||||
else
|
||||
BASE=$(gh release list --repo ${{ github.repository }} --json tagName,isPrerelease,isDraft \
|
||||
-L 50 -q '.[] | select(.isPrerelease==false and .isDraft==false) | .tagName' | head -n 1)
|
||||
fi
|
||||
|
||||
if [ -z "$BASE" ]; then
|
||||
echo "No older release found; please make sure to have at least one older release containing the 'update-assets.zip' file in order to generate the differences."
|
||||
exit 1
|
||||
else
|
||||
echo "Base release: $BASE"
|
||||
echo "base_release=$BASE" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Prepare update-assets.zip
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
echo "Looking for 'update-assets.zip' from release '${{ steps.get_base_release.outputs.base_release }}'"
|
||||
ASSETS=$(gh release view "${{ steps.get_base_release.outputs.base_release }}" \
|
||||
--repo "${{ github.repository }}" \
|
||||
--json assets \
|
||||
| jq -r '.assets[].name')
|
||||
|
||||
if echo "$ASSETS" | grep -xq "update-assets.zip"; then
|
||||
mkdir -p update_assets_temp renamed
|
||||
echo "Downloading assets from release '${{ steps.get_base_release.outputs.base_release }}'"
|
||||
gh release download "${{ steps.get_base_release.outputs.base_release }}" \
|
||||
--repo ${{ github.repository }} \
|
||||
--pattern "update-assets.zip" \
|
||||
-D update_assets_temp
|
||||
|
||||
unzip -q update_assets_temp/update-assets.zip -d update_assets_temp
|
||||
cd update_assets_temp
|
||||
zip -r ../renamed/update-assets.zip . -i assets
|
||||
else
|
||||
echo "No 'update-assets.zip' file found in release '${{ steps.get_base_release.outputs.base_release }}'; please make sure to have this file in that older release in order to generate the differences."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Prepare pre-changelog message
|
||||
id: pre_changelog_message
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
echo "Preparing a pre-changelog message..."
|
||||
|
||||
BODY="If you would like to download the full builds of the engine from this release, please ignore the files starting with 'update-' as they're needed for the engine's internal autoupdater.\n\n"
|
||||
|
||||
if [ -n "${{ github.event.inputs.custom_message }}" ]; then
|
||||
BODY="${{ github.event.inputs.custom_message }}\n${BODY}"
|
||||
fi
|
||||
|
||||
{
|
||||
echo "body<<EOF"
|
||||
echo -e "$BODY"
|
||||
echo "EOF"
|
||||
} >> $GITHUB_OUTPUT
|
||||
echo -e "Final pre-changelog message:\n\n$BODY"
|
||||
|
||||
- name: Create GitHub Release with Assets
|
||||
uses: softprops/action-gh-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.event.inputs.tag_name }}
|
||||
name: Release ${{ github.event.inputs.tag_name }}
|
||||
draft: true
|
||||
prerelease: ${{ github.event.inputs.prerelease }}
|
||||
body: ${{ steps.build_body.outputs.body }}
|
||||
generate_release_notes: true
|
||||
files: |
|
||||
renamed/Codename Engine-Windows.zip
|
||||
renamed/Codename Engine-Mac.zip
|
||||
renamed/Codename Engine-Mac.tar.gz
|
||||
renamed/Codename Engine-Linux.zip
|
||||
renamed/update-assets.zip
|
||||
renamed/update-windows.exe
|
||||
renamed/update-mac
|
||||
renamed/update-linux
|
||||
@@ -1,8 +1,9 @@
|
||||
name: Windows Builds
|
||||
|
||||
name: Windows Build
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Windows Build
|
||||
@@ -10,13 +11,13 @@ jobs:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Pulling the new commit
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
- name: Setting up Haxe
|
||||
uses: krdlab/setup-haxe@v1
|
||||
uses: krdlab/setup-haxe@v2
|
||||
with:
|
||||
haxe-version: 4.2.5
|
||||
haxe-version: 4.3.7
|
||||
- name: Restore existing build cache for faster compilation
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4.2.3
|
||||
with:
|
||||
# not caching the bin folder to prevent asset duplication and stuff like that
|
||||
key: cache-build-windows
|
||||
@@ -24,8 +25,8 @@ jobs:
|
||||
.haxelib/
|
||||
export/release/windows/haxe/
|
||||
export/release/windows/obj/
|
||||
restore-keys: |
|
||||
cache-build-windows
|
||||
- run: |
|
||||
echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV
|
||||
- name: Installing/Updating libraries
|
||||
run: |
|
||||
haxe -cp commandline -D analyzer-optimize --run Main setup -s --no-vscheck
|
||||
@@ -62,7 +63,7 @@ jobs:
|
||||
}
|
||||
}
|
||||
- name: Uploading new cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4.2.3
|
||||
with:
|
||||
# caching again since for some reason it doesnt work with the first post cache shit
|
||||
key: cache-build-windows
|
||||
@@ -70,5 +71,67 @@ jobs:
|
||||
.haxelib/
|
||||
export/release/windows/haxe/
|
||||
export/release/windows/obj/
|
||||
restore-keys: |
|
||||
cache-build-windows
|
||||
|
||||
# didnt compile debug in the same job or github would have said that job wasn't completed until debug was done too (debug uploads are not essential)
|
||||
debug_build:
|
||||
name: Windows Debug Build
|
||||
permissions: write-all
|
||||
runs-on: windows-latest
|
||||
needs: build # since its low priority, it'll run after, so actions will concentrate first on normal builds
|
||||
steps:
|
||||
- name: Pulling the new commit
|
||||
uses: actions/checkout@v4
|
||||
- name: Setting up Haxe
|
||||
uses: krdlab/setup-haxe@v2
|
||||
with:
|
||||
haxe-version: 4.3.7
|
||||
- name: Restore existing build cache for faster compilation
|
||||
uses: actions/cache@v4.2.3
|
||||
with:
|
||||
# not caching the bin folder to prevent asset duplication and stuff like that
|
||||
key: cache-build-windows-debug
|
||||
path: |
|
||||
.haxelib/
|
||||
export/debug/windows/haxe/
|
||||
export/debug/windows/obj/
|
||||
- run: |
|
||||
echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV
|
||||
- name: Installing/Updating libraries
|
||||
run: |
|
||||
haxe -cp commandline -D analyzer-optimize --run Main setup -s --no-vscheck
|
||||
- name: Building the game
|
||||
run: |
|
||||
haxelib run lime build windows -debug
|
||||
- name: Uploading artifact (entire build)
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Codename Engine Debug
|
||||
path: export/debug/windows/bin
|
||||
- name: Clearing already existing cache
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
const caches = await github.rest.actions.getActionsCacheList({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
})
|
||||
for (const cache of caches.data.actions_caches) {
|
||||
if (cache.key == "cache-build-windows-debug") {
|
||||
console.log('Clearing ' + cache.key + '...')
|
||||
await github.rest.actions.deleteActionsCacheById({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
cache_id: cache.id,
|
||||
})
|
||||
console.log("Cache cleared.")
|
||||
}
|
||||
}
|
||||
- name: Uploading new cache
|
||||
uses: actions/cache@v4.2.3
|
||||
with:
|
||||
# caching again since for some reason it doesnt work with the first post cache shit
|
||||
key: cache-build-windows-debug
|
||||
path: |
|
||||
.haxelib/
|
||||
export/debug/windows/haxe/
|
||||
export/debug/windows/obj/
|
||||
+2
-6
@@ -26,6 +26,7 @@ This changelog lists every change that has been added since the last update (inc
|
||||
- `--fast` for quickly downloading git libraries, but requires you to reinstall it fully when updates happen
|
||||
- Alphabet now allows multiple lines in the text ([d519db0](https://github.com/CodenameCrew/CodenameEngine/commit/d519db011a14aac0ddfc052089836c6b445f7f44))
|
||||
- Allow importing mod root level modules in hscript, instead of only source/ ([7e66ee8](https://github.com/CodenameCrew/CodenameEngine/commit/7e66ee81e24204cd152de20046fa1500bb9d204b))
|
||||
- Made the substate have the possibility to open automatically transitions ([d31454c](https://github.com/CodenameCrew/CodenameEngine/commit/d31454c7ddf4cbf6a681cc8b32cd3f9480f8eacd))
|
||||
- Added a way to force animations in the `Play Animation` event ([d7b6fbe](https://github.com/CodenameCrew/CodenameEngine/commit/d7b6fbe510edeb832112ab5adc8ab19dfe97d77f))
|
||||
- Adde unused boyfriend animations ([be55696](https://github.com/CodenameCrew/CodenameEngine/commit/be55696bbefe537f06ad6550b039278ffcbcfb2f))
|
||||
- Made it display the keybind for the mod menu in main menu ([1ac2e7f](https://github.com/CodenameCrew/CodenameEngine/commit/1ac2e7f53390a9e92aa2a1fea94d147ed50d3694))
|
||||
@@ -197,9 +198,4 @@ This changelog lists every change that has been added since the last update (inc
|
||||
- Cleaned up the controls code ([c3580cf](https://github.com/CodenameCrew/CodenameEngine/commit/c3580cf1413f90386dd52763042e11b20d21ce2d), [c1123b9](https://github.com/CodenameCrew/CodenameEngine/commit/c1123b9e3c3c1887888744e0c62827231abc48be))
|
||||
- Cleaned up unused variables in TitleState ([2779ef3](https://github.com/CodenameCrew/CodenameEngine/commit/2779ef3314471558e371b3ec2f17f8d4df48943a))
|
||||
- Restructured the events folder ([77b7eeb](https://github.com/CodenameCrew/CodenameEngine/commit/77b7eebed1ea077516ff884902528c0ff3d01872))
|
||||
- Reduced the amount of data thats stored for the Github Contributors savefile ([2abc45a](https://github.com/CodenameCrew/CodenameEngine/commit/2abc45a9e416a1c5dd2bd0a5297c664e60c6f1d8))
|
||||
|
||||
|
||||
## Unsorted list
|
||||
|
||||
- @NexIsDumb Please document this i still dont understand it ([d31454c](https://github.com/CodenameCrew/CodenameEngine/commit/d31454c7ddf4cbf6a681cc8b32cd3f9480f8eacd))
|
||||
- Reduced the amount of data thats stored for the Github Contributors savefile ([2abc45a](https://github.com/CodenameCrew/CodenameEngine/commit/2abc45a9e416a1c5dd2bd0a5297c664e60c6f1d8))
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
# Codename Engine features
|
||||
This markdown file contains every single feature Codename has, separated into multiple categories. List may be incomplete.
|
||||
This markdown file contains most of the main features Codename has, separated into multiple categories.
|
||||
|
||||
_**QOL = Quality of Life**_
|
||||
|
||||
@@ -71,11 +71,11 @@ _**QOL = Quality of Life**_
|
||||
- Characters are located in `data/weeks/characters`.
|
||||
- Weeks are located in `data/weeks/weeks/`
|
||||
- If you need to rearrange the weeks in-game, you can use the `data/weeks/weeks.txt` file.
|
||||
- Editors for Charts and Characters (Stage coming soon)
|
||||
- Editors for Charts and Characters
|
||||
- Undos/Redos supported
|
||||
- Warning on closing unsaved work
|
||||
- Clean UI (for ocd freaks)
|
||||
- Mature Chart editor (Character editor rework soon)
|
||||
- Mature Chart editor
|
||||
- Features not found in other editors!
|
||||
- Every single state & substate can be modified via HScript (`data/states/StateName.hx`)
|
||||
- **Instances launched via `lime test windows` will automatically use assets from source.**
|
||||
|
||||
@@ -1,91 +1,104 @@
|
||||
# Friday Night Funkin' - Codename Engine (WIP)
|
||||
# Friday Night Funkin' - Codename Engine
|
||||
|
||||
## PLEASE NOTE - THIS IS STILL IN A BETA STATE
|
||||
### Mods created with beta versions of Codename may not be compatible with the release version
|
||||
Known issues in the beta:
|
||||
- Some options are missing
|
||||

|
||||
|
||||
Build instructions are below. Press TAB on the main menu to switch mods.
|
||||
Codename Engine is a cross platform [Friday Night Funkin'](https://github.com/FunkinCrew/Funkin) Engine aimed at simplifying modding focusing on softcoding, along with extensiblity and ease of use.<br>
|
||||
It is the the official successor of the previously well known [Yoshi Engine](https://github.com/CodenameCrew/YoshiCrafterEngine).
|
||||
|
||||
Also, the command `.\cne test` uses the source assets folder instead of the export one for easier development (Although you can still use `lime test windows` normally).
|
||||
The engine uses [HaxeFlixel](https://haxeflixel.com/) and it mainly features:
|
||||
- A full scripting system with an optimized fork of [Hscript](https://lib.haxe.org/p/hscript/) (its name is [Hscript Improved](https://github.com/CodenameCrew/hscript-improved))
|
||||
- Uses forks of popular libraries tailored specifically for the engine for the goal of better optimization.
|
||||
- Modding system and softcoding is as capable as source coding.
|
||||
- Focuses heavily on optimization, and encourages its users to also take on optimization practices.
|
||||
- Many modding tools without changing the core gameplay and the base to mod on.
|
||||
- Allows modularity using addons and mods that apply on top of the core mod.
|
||||
- Advanced editors which allows for possibly better experience and easiness when creating the mod.
|
||||
- Much more can be read [HERE](FEATURES.md)
|
||||
|
||||
## Codename Engine
|
||||
> [!NOTE]
|
||||
> Please keep in mind that, despite these differences, we do not consider our engine to be any better or worse than the others.
|
||||
|
||||
Codename Engine is a new Friday Night Funkin' Engine aimed at simplifying modding, along with extensiblity and ease of use.<br>
|
||||
### Before making issues or need help with something, check our website [HERE](https://codename-engine.com/) (it contains a wiki of how to mod with EXAMPLES, an api, lists of mods made with Codename Engine and more)!!!
|
||||
#### The Engine includes many new features, as seen [here](FEATURES.md)<br>
|
||||
#### Wanna see the new features added in the most recent update? Click [here](PATCHNOTES.md)<br>
|
||||
---
|
||||
|
||||
## How to download
|
||||
> [!CAUTION]
|
||||
> Want to use this project's code for different purposes or something similar? Check out the ***Usage Info*** part below first, it basically explains what you can do or not do!<br>
|
||||
> We love open source but we also love proper credits for having respect of all the people who worked hard on this project!!
|
||||
|
||||
Latest builds for the engine can be found in the [Actions](https://github.com/CodenameCrew/CodenameEngine/actions) tab.<br>
|
||||
In the future (when the engine won't be a WIP anymore) we're gonna also publish the engine on platforms like Gamebanana; stay tuned!
|
||||
> [!WARNING]
|
||||
> Before making issues or if you need help with something, check our website [HERE](https://codename-engine.com/).<br>
|
||||
> It contains a wiki of how to mod with EXAMPLES, an api, lists of mods made with Codename Engine and more!
|
||||
|
||||
If you don't have a github account please go onto https://codename-engine.com/ and click the download button for the respective operating system.
|
||||
> [!TIP]
|
||||
> Want to stay updated with this project?<br>
|
||||
> Check out our [patch notes](PATCHNOTES.md)!
|
||||
|
||||
---
|
||||
|
||||
<img width="1080" height="146" alt="immagine" src="https://github.com/user-attachments/assets/93604082-6bac-4ffc-99b0-5393b1e340a4" />
|
||||
|
||||
<br><br>
|
||||
|
||||
<img width="1280" height="720" alt="immagine" src="https://github.com/user-attachments/assets/4106f77a-40f8-4159-9f4e-b601cc79e1d0" />
|
||||
<img width="1280" height="720" alt="immagine" src="https://github.com/user-attachments/assets/2c06f5ea-3462-459b-982e-bf4eddf3d099" />
|
||||
<img width="1280" height="720" alt="immagine" src="https://github.com/user-attachments/assets/4979e256-6b99-4857-8a2a-96abd94f9c4e" />
|
||||
<img width="1280" height="720" alt="immagine" src="https://github.com/user-attachments/assets/55a5a710-55b9-4988-bdcc-0977ba1de97a" />
|
||||
<img width="1280" height="720" alt="immagine" src="https://github.com/user-attachments/assets/4676b035-bec7-445b-a303-78e66f11c479" />
|
||||
|
||||
---
|
||||
|
||||
> [!NOTE]
|
||||
> Codename Engine as for now supports **Windows x64**, **Mac OS x64** and **Linux x64**.<br>
|
||||
> More platforms will soon come, stay tuned!<br>
|
||||
> - [ ] **Web (HTML5) Support**
|
||||
> - [ ] **Mobile Support**
|
||||
|
||||
<details>
|
||||
<summary><h2>How to build</h2></summary>
|
||||
<summary><h2>How to download</h2></summary>
|
||||
|
||||
> **Open the instructions for your platform**
|
||||
<details>
|
||||
<summary>Windows</summary>
|
||||
- Stable builds of the engine can be found on our [GameBanana](https://gamebanana.com/mods/598553) or our [itch.io](https://nex-isdumb.itch.io/codename-engine) pages.
|
||||
- Latest *EXPERIMENTAL* builds of the engine can be found in the [Actions](https://github.com/CodenameCrew/CodenameEngine/actions) tab. **REQUIRES A GITHUB ACCOUNT!!**
|
||||
|
||||
##### Tested on Windows 10 21H2
|
||||
1. Install [version 4.2.5 of Haxe](https://haxe.org/download/version/4.2.5/).
|
||||
2. Download and install [`git-scm`](https://git-scm.com/download/win).
|
||||
- Leave all installation options as default.
|
||||
3. Run `update.bat` using cmd or double-clicking it, and wait for the libraries to install.
|
||||
4. Once the libraries are installed, run `haxelib run lime test windows` to compile and launch the game (may take a long time)
|
||||
- ℹ You can run `haxelib run lime setup` to make the lime command global, allowing you to execute `lime test windows` directly.
|
||||
</details>
|
||||
<details>
|
||||
<summary>Linux</summary>
|
||||
|
||||
##### Requires testing
|
||||
1. Install [version 4.2.5 of Haxe](https://haxe.org/download/version/4.2.5/).
|
||||
2. Install `g++`, if not present already.
|
||||
3. Download and install [`git-scm`](https://git-scm.com/download/linux).
|
||||
4. Open a terminal in the Codename Engine source folder, and run `update.sh`.
|
||||
5. Once the libraries are installed, run `haxelib run lime test linux` to compile and launch the game (may take a long time)
|
||||
- ℹ You can run `haxelib run lime setup` to make the lime command global, allowing you to execute `lime test linux` directly.
|
||||
</details>
|
||||
<details>
|
||||
<summary>MacOS</summary>
|
||||
|
||||
##### Requires testing
|
||||
1. Install [version 4.2.5 of Haxe](https://haxe.org/download/version/4.2.5/).
|
||||
2. Install `Xcode` to allow C++ app building.
|
||||
3. Download and install [`git-scm`](https://git-scm.com/download/mac).
|
||||
4. Open a terminal in the Codename Engine source folder, and run `update.sh`.
|
||||
5. Once the libraries are installed, run `haxelib run lime test mac` to compile and launch the game (may take a long time)
|
||||
- ℹ You can run `haxelib run lime setup` to make the lime command global, allowing you to execute `lime test mac` directly.
|
||||
</details>
|
||||
If you don't have a GitHub account to download experimental builds, you can also go onto our [official website](https://codename-engine.com/) and click the download button for the respective operating system under the **Experimental** section.
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><h2>What can you do or not do</h2></summary>
|
||||
<summary><h2>How to mod</h2></summary>
|
||||
|
||||
### You can:
|
||||
Check out our wiki [HERE](https://codename-engine.com/wiki/)
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><h2>How to setup and build the engine and its documentation</h2></summary>
|
||||
|
||||
Check out our guide [HERE](building/README.md)
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><h2>Usage Info</h2></summary>
|
||||
|
||||
### Feel free to:
|
||||
- Download and play the engine with its mods and modpacks
|
||||
- Mod and fork the engine (without using it for illicit purposes)
|
||||
- Contribute to the engine (for example through *Pull Requests*, *Issues*, etc)
|
||||
- Contribute to the engine (for example through *Pull Requests*, *Issues*, etc.)
|
||||
- Create a sub engine with Codename Engine as **TEMPLATE** with **CREDITS** (for example leaving the *credits menu submenu with the GitHub contributors* and putting the *[main devs](https://github.com/CodenameCrew)* in a *README* specifying that it's a *sub engine from Codename Engine*)
|
||||
- Release excutable mods that use Codename Engine as source (Specifing that uses Codename Engine by for example the same way written above this)
|
||||
- Release modpacks
|
||||
- Release excutable mods that use Codename Engine as source (specifing that uses Codename Engine by for example the same way written above this)
|
||||
- Release Codename Engine modpacks
|
||||
|
||||
### You can't:
|
||||
### Please do not:
|
||||
- Create a *side/new/etc* engine (or mod that doesn't use Codename Engine) using Codename Engine's code
|
||||
- Steal code from Codename Engine for another different project that is not Codename Engine related (Codename Engine mods excluded) without properly crediting
|
||||
- Release the entire Codename Engine on platforms (Mods that use Codename Engine as source are fine, if it's specified even better)
|
||||
- Release the entirety of Codename Engine on platforms (mods that use Codename Engine as source are fine)
|
||||
|
||||
#### *If you need more info or feel like asking to do something which is not listed here, ask us directly on our discord (linked on the website)!*
|
||||
#### *If you need more info or feel like asking to do something which is not listed here, ask us directly on our [discord server](https://discord.com/servers/codename-engine-860561967383445535)!*
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><h2>Credits</h2></summary>
|
||||
|
||||
- All main Credits can be seen inside the Engine and specifically [HERE](https://github.com/CodenameCrew/CodenameEngine/graphs/contributors)
|
||||
- Credits to the [FlxAnimate](https://github.com/Dot-Stuff/flxanimate) team for the Animate Atlas support
|
||||
- Credits to Smokey555 for the backup Animate Atlas to spritesheet code
|
||||
- Credits to MAJigsaw77 for [hxvlc](https://github.com/MAJigsaw77/hxvlc) (video cutscene/mp4 support) and [hxdiscord_rpc](https://github.com/MAJigsaw77/hxdiscord_rpc) (discord rpc integration)
|
||||
- Credits to [TheoDev](https://github.com/TheoDevelops) for [FunkinModchart](https://lib.haxe.org/p/funkin-modchart/). ***(library used for modcharting features)***
|
||||
- Credits to [Ninjamuffin99](https://github.com/ninjamuffin99) and the [Funkin Crew](https://github.com/FunkinCrew) for the base game Friday Night Funkin'
|
||||
</details>
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
# Codename Engine Todo List
|
||||
|
||||
## `v1.0.0` - Initial release
|
||||
|
||||
- [x] Remove Herobrine
|
||||
- [ ] Chart Editor
|
||||
- [x] Place & Delete notes
|
||||
- [x] Ctrl+Z & Ctrl+Y
|
||||
- [x] Selection box & dragging
|
||||
- [x] Scroll bar at the right + Song info
|
||||
- [x] Fix the strumlines bar when zooming out
|
||||
- [x] Algorithm to make note placements faster & sorted out
|
||||
- [x] Play here working
|
||||
- [x] Cap zoom in & out
|
||||
- [x] Events (including Camera Movement)
|
||||
- [x] Metadata Editing
|
||||
- [ ] Custom Notetypes
|
||||
- [ ] Reorderable Strumlines
|
||||
- [ ] Step based zooming
|
||||
- [ ] Add Undo to more actions
|
||||
- [ ] New Chart Button
|
||||
- [ ] Bug fixes
|
||||
- [ ] Zooming in causing notes to disappear
|
||||
- [ ] Holds disappear too early
|
||||
- [ ] Time signature fixes
|
||||
- [ ] BPM Changes Events
|
||||
- [ ] Character Editor
|
||||
- [x] Animation Editing
|
||||
- [x] Animation Deletion/Creation
|
||||
- [x] Character Info Editing
|
||||
- [x] Character Saving
|
||||
- [x] Add Undos to Actions
|
||||
- [ ] Change Stage
|
||||
- [ ] New Character Button
|
||||
- [ ] Port Videos to a more stable video lib
|
||||
- [ ] Optimization to Editors
|
||||
- [ ] Fix Ratings Lag
|
||||
- [x] Re-export gf-christmas, gf-car and gf-tankmen with padding
|
||||
- [x] Re-add shader camera stuff
|
||||
- [x] Make update.bat use libs.xml instead of hmm.json
|
||||
- [ ] New Switch Mod menu
|
||||
- [x] Port shader camera stuff over to new flixel fork
|
||||
- [ ] Add note offset
|
||||
- [x] Dialogue
|
||||
- [ ] Finish Base Game port
|
||||
- [x] Add credits
|
||||
- [x] Verbose mode (`--verbose`)
|
||||
- [ ] Tooltips
|
||||
- [ ] Fix bugs
|
||||
|
||||
## `v1.1.0`
|
||||
- [ ] Charter Waveforms (maybe in v1.1.0, don't wanna slow shit down)
|
||||
- [ ] Custom classes
|
||||
- [ ] Proper super overrides (FlxText_HSX doesn't allow overrides for update because of this)
|
||||
- [ ] Custom Class extending Custom Classes
|
||||
- [ ] Statics on Custom Classes
|
||||
- [ ] Fix Bugs
|
||||
- [ ] Full 3D support via stages files
|
||||
- [ ] Multithread sprites and assets loading (for faster load times) ?
|
||||
- [ ] Stage Editor
|
||||
- [ ] Optimize flxanimate isOnScreen
|
||||
@@ -1,10 +0,0 @@
|
||||
## DEV (PRIVATE) REPO INSTRUCTIONS TO SYNC UP WITH IT INSTEAD OF SYNCING WITH THE PUBLIC ONE
|
||||
- Open a Command Prompt window in the public codename repo folder
|
||||
- Type those commands:
|
||||
- `git remote add dev https://www.github.com/YoshiCrafter29/CodenameEngine-Dev`
|
||||
- `git branch --set-upstream-to dev/main`
|
||||
- GitHub desktop should be synchronized with the dev repo now. If you're unsure,
|
||||
- Repo name should still say "CodenameEngine"
|
||||
- Current branch should still say "main"
|
||||
- "Fetch" button should say "Fetch dev"
|
||||
- You shouldn't have any commit to push.
|
||||
@@ -1,8 +0,0 @@
|
||||
@ECHO OFF
|
||||
cd ..
|
||||
echo Building Game...
|
||||
lime build windows --haxeflag="-xml docs/doc.xml" -D doc-gen -D DOCUMENTATION --no-output
|
||||
echo art
|
||||
|
||||
echo Generated the api xml file at docs/doc.xml
|
||||
echo Please put this in codename-website/api-generator/api/doc.xml
|
||||
@@ -47,10 +47,18 @@
|
||||
<anim char="8">character-eight</anim>
|
||||
<anim char="9">character-nine</anim>
|
||||
|
||||
<composite char="ã">
|
||||
<component anim="character-a0" x="0" y="0"/>
|
||||
<component anim="diacritic-tilde-fill" x="11" y="73" outline="diacritic-tilde-outline" outlineX="-1" hasOutline="true"/>
|
||||
</composite>
|
||||
<composite char="ẽ">
|
||||
<component anim="character-e0" x="0" y="0"/>
|
||||
<component anim="diacritic-tilde-fill" x="3" y="73" outline="diacritic-tilde-outline" outlineX="-1" hasOutline="true"/>
|
||||
</composite>
|
||||
<composite char="õ">
|
||||
<component anim="character-o0" x="0" y="0"/>
|
||||
<component anim="diacritic-tilde-fill" x="8" y="73" outline="diacritic-tilde-outline" outlineX="-1" hasOutline="true"/>
|
||||
</composite>
|
||||
<composite char="ñ">
|
||||
<component anim="character-n0" x="0" y="0"/>
|
||||
<component anim="diacritic-tilde-fill" x="3" y="73" outline="diacritic-tilde-outline" outlineX="-1" hasOutline="true"/>
|
||||
@@ -75,6 +83,22 @@
|
||||
<component anim="character-u0" x="0" y="0"/>
|
||||
<component anim="diacritic-acute-fill" x="15" y="60" outline="diacritic-acute-outline" outlineX="-1" hasOutline="true"/>
|
||||
</composite>
|
||||
<composite char="â">
|
||||
<component anim="character-a0" x="0" y="0"/>
|
||||
<component anim="diacritic-circumflex-fill" x="13" y="70" outline="diacritic-circumflex-outline" outlineX="-1" hasOutline="true"/>
|
||||
</composite>
|
||||
<composite char="ê">
|
||||
<component anim="character-e0" x="0" y="0"/>
|
||||
<component anim="diacritic-circumflex-fill" x="6" y="70" outline="diacritic-circumflex-outline" outlineX="-1" hasOutline="true"/>
|
||||
</composite>
|
||||
<composite char="ô">
|
||||
<component anim="character-o0" x="0" y="0"/>
|
||||
<component anim="diacritic-circumflex-fill" x="11" y="70" outline="diacritic-circumflex-outline" outlineX="-1" hasOutline="true"/>
|
||||
</composite>
|
||||
<composite char="à">
|
||||
<component anim="character-a0" x="0" y="0"/>
|
||||
<component anim="diacritic-acute-fill" x="16" y="70" outline="diacritic-acute-outline" outlineX="1" hasOutline="true" flipX="true"/>
|
||||
</composite>
|
||||
<composite char="ą">
|
||||
<component anim="character-a0" x="0" y="0"/>
|
||||
<component anim="diacritic-ogonek-fill" x="34" y="-12" outline="diacritic-ogonek-outline" outlineX="2" outlineY="-2" hasOutline="true"/>
|
||||
@@ -83,6 +107,10 @@
|
||||
<component anim="character-e0" x="0" y="0"/>
|
||||
<component anim="diacritic-ogonek-fill" x="23" y="-14" outline="diacritic-ogonek-outline" outlineX="2" outlineY="-2" hasOutline="true"/>
|
||||
</composite>
|
||||
<composite char="ç">
|
||||
<component anim="character-c0" x="0" y="0"/>
|
||||
<component anim="diacritic-cadilla-fill" x="20" y="-15" outline="diacritic-cadilla-outline" outlineX="3" outlineY="-1" hasOutline="true"/>
|
||||
</composite>
|
||||
<composite char="ć">
|
||||
<component anim="character-c0" x="0" y="0"/>
|
||||
<component anim="diacritic-acute-fill" x="18" y="73" outline="diacritic-acute-outline" outlineX="-1" hasOutline="true"/>
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# THIS FILE ISN'T NECESSARY,
|
||||
# BUT YOU CAN USE IT TO SORT AND WHITELIST FREEPLAY SONGS
|
||||
|
||||
test
|
||||
tutorial
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
# THIS FILE ISN'T NECESSARY,
|
||||
# BUT YOU CAN USE IT TO SORT AND WHITELIST GAME MODES
|
||||
|
||||
solo
|
||||
opponent
|
||||
coop
|
||||
coop-switched
|
||||
botplay
|
||||
@@ -1,5 +1,5 @@
|
||||
# THIS FILE ISN'T NECESSARY,
|
||||
# BUT YOU CAN USE IT TO SORT WEEKS
|
||||
# BUT YOU CAN USE IT TO SORT AND WHITELIST WEEKS
|
||||
|
||||
tutorial
|
||||
week1
|
||||
@@ -8,7 +8,7 @@ function onDiscordPresenceUpdate(e) {
|
||||
var data = e.presence;
|
||||
|
||||
if(data.button1Label == null)
|
||||
data.button1Label = "meow"; // "Codename Engine Discord"
|
||||
data.button1Label = "Codename Engine Discord";
|
||||
if(data.button1Url == null)
|
||||
data.button1Url = "https://discord.gg/2NTCdsQvx4";
|
||||
}
|
||||
@@ -33,8 +33,8 @@ function onEditorTreeLoaded(name:String) {
|
||||
DiscordUtil.changePresenceSince("Choosing a Character", null);
|
||||
case "Chart Editor":
|
||||
DiscordUtil.changePresenceSince("Choosing a Chart", null);
|
||||
//case "Stage Editor": // secret for now
|
||||
// DiscordUtil.changePresenceSince("Choosing a Stage", null);
|
||||
case "Stage Editor": // secret for now
|
||||
DiscordUtil.changePresenceSince("Choosing a Stage", null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ function onEditorLoaded(name:String, editingThing:String) {
|
||||
DiscordUtil.changePresenceSince("Editing a Character", editingThing);
|
||||
case "Chart Editor":
|
||||
DiscordUtil.changePresenceSince("Editing a Chart", editingThing);
|
||||
//case "Stage Editor":
|
||||
// DiscordUtil.changePresenceSince("Editing a Stage", editingThing);
|
||||
case "Stage Editor":
|
||||
DiscordUtil.changePresenceSince("Editing a Stage", editingThing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"displayName": "Botplay Mode",
|
||||
"modeID": "codename.botplay"
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
<!DOCTYPE codename-engine-game-mode>
|
||||
<mode name="Botplay Mode" id="codename.botplay"/>
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"displayName": "Co-Op Mode (Switched)",
|
||||
"modeID": "codename.coop-opponent",
|
||||
"scripts": ["opponent", "coop"]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<!DOCTYPE codename-engine-game-mode>
|
||||
<mode name="Co-Op Mode (Switched)" id="codename.coop-opponent">
|
||||
<script>coop</script>
|
||||
<script>opponent</script>
|
||||
|
||||
<!--
|
||||
just a small example of what you could do with fields!!
|
||||
<field name="switchStrums" type="bool" val="true"/>
|
||||
<field name="strumSize" type="float" val="0.6"/>
|
||||
-->
|
||||
</mode>
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"displayName": "Co-Op Mode",
|
||||
"modeID": "codename.coop"
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
<!DOCTYPE codename-engine-game-mode>
|
||||
<mode name="Co-Op Mode" id="codename.coop"/>
|
||||
@@ -0,0 +1,5 @@
|
||||
solo
|
||||
opponent
|
||||
coop
|
||||
coop-switched
|
||||
botplay
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"displayName": "Opponent Mode",
|
||||
"modeID": "codename.opponent"
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
<!DOCTYPE codename-engine-game-mode>
|
||||
<mode name="Opponent Mode" id="codename.opponent"/>
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"displayName": "Solo Mode",
|
||||
"modeID": "codename.solo"
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
<!DOCTYPE codename-engine-game-mode>
|
||||
<mode name="Solo Mode" id="codename.solo"/>
|
||||
@@ -16,5 +16,5 @@ version="version based on the English config.ini version"
|
||||
|
||||
4. Translate the texts in the copied xml files. The {0} and {1}, and so on are placeholders are used for variables, and should be left as is.
|
||||
|
||||
5. Make a pull request with your changes.
|
||||
5. **If you wanna help us with the language(s) you added in the engine**: Make a pull request with your changes.
|
||||
Make sure the pull request is labeled as `[LANG] Add <language name>` or `[LANG] Update <language name>` or `[LANG] Fix typo in <language name>`, generally anything is allowed but it has to contain the language name.
|
||||
|
||||
@@ -488,6 +488,7 @@
|
||||
<str id="newGlyph">New Glyph</str>
|
||||
<str id="editGlyph">Edit Glyph</str>
|
||||
<str id="deleteGlyph">Delete Glyph</str>
|
||||
<str id="deleteCurGlyph">Delete Current Glyph</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.offset">Offsets</str>
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
<str id="category.engine">Engine</str>
|
||||
<group name="engine" prefix="engine.">
|
||||
<str id="switchMod">Switch Mod</str>
|
||||
<str id="fpsCounter">FPS Counter</str>
|
||||
</group>
|
||||
|
||||
<str id="category.volume">Volume</str>
|
||||
|
||||
@@ -46,8 +46,9 @@
|
||||
|
||||
<group name="engine" prefix="engine.">
|
||||
<str id="switchMod">Cambiar Mod</str>
|
||||
<str id="fpsCounter">Contador de FPS</str>
|
||||
</group>
|
||||
|
||||
|
||||
<str id="category.volume">Volumen</str>
|
||||
<str id="volume.up">Arriba</str>
|
||||
<str id="volume.down">Abajo</str>
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
|
||||
<group name="engine" prefix="engine.">
|
||||
<str id="switchMod">Cambia Mod</str>
|
||||
<str id="fpsCounter">Contatore FPS</str>
|
||||
</group>
|
||||
|
||||
<str id="volume.up">Su</str>
|
||||
|
||||
@@ -44,8 +44,9 @@
|
||||
<str id="category.engine">Silnik</str>
|
||||
<group name="engine" prefix="engine.">
|
||||
<str id="switchMod">Zmień Moda</str>
|
||||
<str id="fpsCounter">Licznik FPS</str>
|
||||
</group>
|
||||
|
||||
|
||||
<str id="category.volume">Głośność</str>
|
||||
<str id="volume.up">Głóśniej</str>
|
||||
<str id="volume.down">Ciszej</str>
|
||||
|
||||
@@ -0,0 +1,686 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<language>
|
||||
<group name="General Editor Translations" prefix="editor.">
|
||||
<str id="autosavingIn">Guardando automáticamente em {0} segundos{1}</str>
|
||||
<str id="autosavingCanceledSuffix">(Cancelado)!</str>
|
||||
|
||||
<str id="ok">Ok</str>
|
||||
<str id="cancel">Cancelar</str>
|
||||
<str id="save">Guardar</str>
|
||||
<str id="saveClose">Guardar e Fechar</str>
|
||||
<str id="close">Fechar</str>
|
||||
<str id="notNow">Agora Não</str>
|
||||
<str id="yes">Sim</str>
|
||||
</group>
|
||||
|
||||
<group name="UIImageExplorer" prefix="uiImageExplorer.">
|
||||
<str id="symbol">Simbolo</str>
|
||||
<str id="animation">Animação</str>
|
||||
<str id="atlas">Atlas</str>
|
||||
<str id="spritemap">Mapa de Sprites</str>
|
||||
|
||||
<str id="directory">Diretório ({0}/)</str>
|
||||
<str id="found">{0} {1} Encontrado</str>
|
||||
<str id="foundplural">{0} {1} Encontrado</str>
|
||||
<str id="notFound">#{0}s NÃO Encontrado#</str>
|
||||
<str id="foundAtlas">{0} Mapa de Sprites Encontrado</str>
|
||||
<str id="foundAtlasplural">{0} Mapas de Sprites Encontrados</str>
|
||||
|
||||
<str id="fileAlreadyExists">Os seguintes ficheiros já existem: \n\n{0}\n\nIMPORTANTE: SUBSTITUIR NÃO PODE SER DESFEITO!</str>
|
||||
<str id="override">Substituir Ficheiros</str>
|
||||
<str id="useExisting">Usar Existentes</str>
|
||||
</group>
|
||||
|
||||
<group name="EditorPicker" prefix="editor.">
|
||||
<str id="alphabet.name">Editor de Alfabetos</str>
|
||||
<str id="chart.name">Editor de Mapas</str>
|
||||
<str id="character.name">Editor de Personagens</str>
|
||||
<str id="stage.name">Editor de Cenários</str>
|
||||
<str id="uiDebug.name">Interface de Depuração</str>
|
||||
<str id="wiki.name">Wiki</str>
|
||||
<str id="debugOptions.name">Opções de Depuração</str>
|
||||
</group>
|
||||
|
||||
<group name="ChartEditor">
|
||||
<group name="CharterSelection" prefix="charterSelection.">
|
||||
<str id="desc">Selecione uma canção para modificar os seus mapas.</str>
|
||||
<str id="acceptSong">Carregue em ACEITAR para escolher uma dificuldade para editar.</str>
|
||||
<str id="acceptVariation">Carregue em ACEITAR para escolher uma variação para editar.</str>
|
||||
<str id="acceptDifficulty">Carregue em ACEITAR para editar o mapa para a dificuldade selecionada.</str>
|
||||
<str id="selectDifficulty">Selecione uma dificuldade para continuar.</str>
|
||||
<str id="newDifficulty">Nova Dificuldade</str>
|
||||
<str id="newDifficultyDesc">Carregue em ACEITAR para criar uma dificuldade nova.</str>
|
||||
<str id="newSong">Nova Canção</str>
|
||||
<str id="newSongDesc">Carregue em ACEITAR para criar uma canção nova.</str>
|
||||
<str id="newVariation">Nova Variação</str>
|
||||
<str id="newSongDesc">Carregue em ACEITAR para criar uma variação nova.</str>
|
||||
</group>
|
||||
|
||||
<group name="ChartCreationScreen" prefix="chartCreation.">
|
||||
<str id="title">A Criar um Mapa Novo</str>
|
||||
<str id="info">Info. do Mapa</str>
|
||||
<str id="diffName">Nome da Dificuldade</str>
|
||||
<str id="stage">Cenário</str>
|
||||
<str id="scrollSpeed">Velocidade das Notas</str>
|
||||
|
||||
<str id="strumLineList">Pistas $* Pelo menos 1 Pista Necessária$</str>
|
||||
<str id="strumLine.format">Pistas - #{0}</str>
|
||||
|
||||
<group name="Warnings" prefix="warnings.">
|
||||
<str id="song-exists-title">Criação de Canção: Erro!</str>
|
||||
<str id="song-exists-body">A canção que está a tentar criar já existe, se a quiser substituir apague a canção primeiro!</str>
|
||||
<str id="chart-exists-title">Criação de Mapa: Erro!</str>
|
||||
<str id="chart-exists-body">O mapa que está a tentar criar já existe, se o quiser substituir apague o mapa primeiro!</str>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="ChartDataScreen" prefix="chartDataScreen.">
|
||||
<str id="title">Propriedades do Mapa</str>
|
||||
<str id="editChartData">Editar Dados do Mapa</str>
|
||||
<str id="stage">Cenário</str>
|
||||
<str id="scrollSpeed">Velocidade das Notas</str>
|
||||
</group>
|
||||
|
||||
<group name="SongPosInfo" prefix="songPosInfo.">
|
||||
<str id="step">Passo: {0}</str>
|
||||
<str id="beat">Batida: {0}</str>
|
||||
<str id="measure">Medida: {0}</str>
|
||||
<str id="bpm">BPM: {0}</str>
|
||||
<str id="timeSignature">Compasso: {0}/{1}</str>
|
||||
</group>
|
||||
|
||||
<group name="CharterEventScreen" prefix="charterEventScreen.">
|
||||
<str id="title-creating">Criar Grupo de Eventos</str>
|
||||
<str id="title-editing">Editar Grupo de Eventos</str>
|
||||
|
||||
<str id="noEvent">Sem Eventos</str>
|
||||
|
||||
<str id="strumLine.format">Pista #{0} ({1})</str>
|
||||
</group>
|
||||
|
||||
<group name="CharterEventTypeSelection" prefix="charterEventTypeSelection.">
|
||||
<str id="title">Escolha um tipo de evento...</str>
|
||||
</group>
|
||||
|
||||
<group name="CharterMetaDataScreen" prefix="charterMetaDataScreen.">
|
||||
<str id="title">Editar Metadados</str>
|
||||
|
||||
<str id="songData">Dados da Canção</str>
|
||||
<str id="songName">Nome da Canção</str>
|
||||
<str id="variation">Variação da Canção</str>
|
||||
<str id="bpm">BPM</str>
|
||||
<str id="timeSignature">Compasso</str>
|
||||
<str id="menusData">Dados dos Menus (Jogo Livre/História)</str>
|
||||
<str id="displayName">Nome Exibido</str>
|
||||
<str id="icon">Ícone</str>
|
||||
<str id="modesAllowed">Modos Permitidos</str>
|
||||
<str id="color">Cor</str>
|
||||
<str id="difficulties">Dificuldades</str>
|
||||
<str id="customValues">Valores Especiais (Avançado)</str>
|
||||
<str id="needsVoices">Necessita Vozes</str>
|
||||
|
||||
<str id="opponentMode">Modo Oponente</str>
|
||||
<str id="coopAllowed">Modo Cooperativo</str>
|
||||
</group>
|
||||
|
||||
<group name="CharterNoteTypesList" prefix="charterNoteTypesList.">
|
||||
<str id="title">Editor da Lista de Tipos de Nota</str>
|
||||
|
||||
<str id="editNoteTypes">Editar Tipos de Nota</str>
|
||||
<str id="editType">Tipo de Nota {0}</str>
|
||||
</group>
|
||||
|
||||
<group name="CharterStrumlineScreen" prefix="charterStrumlineScreen.">
|
||||
<str id="win-title-creating">A Criar a pista {0}</str>
|
||||
<str id="win-title-editing">A Editar as propriedades da pista {0}</str>
|
||||
|
||||
<str id="title-creating">Criar Nova Pista</str>
|
||||
<str id="title-editing">Editar Propriedades da Pista</str>
|
||||
</group>
|
||||
|
||||
<group name="SongCreationScreen" prefix="songCreationScreen.">
|
||||
<str id="win-title">A Criar Nova Canção</str>
|
||||
<str id="win-title-importing">A Importar Canção</str>
|
||||
<str id="title">Info. da Canção</str>
|
||||
|
||||
<str id="instAudio">Ficheiro do Instrumental $* Obrigatório*$</str>
|
||||
<str id="voicesAudio">Ficheiro das Vozes</str>
|
||||
|
||||
<str id="importFrom">Importar de...</str>
|
||||
<str id="importSource">Fonte de Importação:</str>
|
||||
<str id="legacyOrPsych">Psych/Legacy FNF</str>
|
||||
<str id="vslice">V-Slice</str>
|
||||
<str id="vsliceProject">Projeto V-Slice (.fnfc)</str>
|
||||
<str id="importChartFormat">Formato de Mapa</str>
|
||||
<str id="importAudios">Adicionar Audios</str>
|
||||
<str id="songFileName">Nome da canção $* Obrigatório$</str>
|
||||
<str id="songDataFile">Ficheiro Dados/Mapa $* Obrigatório$</str>
|
||||
<str id="songMetaFile">Ficheiro dos Metadados $* Obrigatório$</str>
|
||||
|
||||
<str id="back">Atrás</str>
|
||||
<str id="next">Seguinte</str>
|
||||
</group>
|
||||
|
||||
<group name="StrumlineOptions" prefix="charterStrumLine.">
|
||||
<str id="characters">Personagens</str>
|
||||
<str id="newChar">Nova Personagem</str>
|
||||
<str id="type">Tipo</str>
|
||||
<str id="scrollSpeed">Velocidade das Notas</str>
|
||||
<str id="stagePos">Posição no Cenário</str>
|
||||
<str id="scale">Tamanho</str>
|
||||
<str id="spacing">Espaço</str>
|
||||
<str id="hudPos">Posição HUD (X [Rácio 0-1],Y)</str>
|
||||
<str id="visible">Visível?</str>
|
||||
<str id="useChartScrollSpeed">Usa velocidade global?</str>
|
||||
<str id="vocalSuffix">Sufixo Vocal</str>
|
||||
<str id="keyCount">Número de Teclas</str>
|
||||
</group>
|
||||
|
||||
<group name="ChartEditor" prefix="charter.">
|
||||
<!-- Charter.hx -->
|
||||
<group name="TopBar">
|
||||
<str id="topBar.file">Ficheiro</str>
|
||||
<group name="FileMenu" prefix="file.">
|
||||
<str id="new">Novo</str>
|
||||
<str id="save">Guardar</str>
|
||||
<str id="saveAs">Guardar Como...</str>
|
||||
<str id="saveGlobalEvents">Guardar Eventos Globais</str>
|
||||
<str id="saveGlobalEventsAs">Guardar Eventos Globais Como...</str>
|
||||
<str id="saveNoLocalEvents">Guardar Mapa sem Eventos Locais</str>
|
||||
<str id="saveNoLocalEventsAs">Guardar Mapa sem Eventos Locais Como...</str>
|
||||
<str id="saveMeta">Guardar Metadados</str>
|
||||
<str id="saveMetaAs">Guardar Metadados Como...</str>
|
||||
<str id="exportFnfLegacy">Exportar Para FNF Legacy...</str>
|
||||
<str id="exportPsych">Exportar Para Psych Engine...</str>
|
||||
<str id="exit">Sair</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.edit">Editar</str>
|
||||
<group name="EditMenu" prefix="edit.">
|
||||
<str id="undo">Desfazer</str>
|
||||
<str id="redo">Refazer</str>
|
||||
<str id="copy">Copiar</str>
|
||||
<str id="paste">Colar</str>
|
||||
<str id="cut">Cortar</str>
|
||||
<str id="delete">Apagar</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.chart">Mapa</str>
|
||||
<group name="ChartMenu" prefix="chart.">
|
||||
<str id="playtest">Testar</str>
|
||||
<str id="playtestHere">Testar aqui</str>
|
||||
<str id="playtestOpponent">Testar como oponente</str>
|
||||
<str id="playtestOpponentHere">Testar como oponente aqui</str>
|
||||
<str id="enableScripts">Ativar scripts durante teste</str>
|
||||
<str id="editChartData">Editar dados do mapa</str>
|
||||
<str id="editMetadata">Editar info. dos metadados</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.view">Vista</str>
|
||||
<group name="ViewMenu" prefix="view.">
|
||||
<str id="zoomIn">Ampliar</str>
|
||||
<str id="zoomOut">Diminuir</str>
|
||||
<str id="resetZoom">Zoom Padrão</str>
|
||||
<str id="showSectionsSeparator">Mostrar Separador de Secções</str>
|
||||
<str id="showBeatsSeparator">Mostrar Separador de Batidas</str>
|
||||
<str id="rainbowWaveforms">Ondas Arcoíris</str>
|
||||
<str id="lowDetailWaveforms">Ondas de Baixo Detalhe</str>
|
||||
<str id="scrollLeft">Deslocar à Esquerda</str>
|
||||
<str id="scrollRight">Deslocar à Direita</str>
|
||||
<str id="scrollReset">Repor Deslocamento</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.song">Canção</str>
|
||||
<group name="SongMenu" prefix="song.">
|
||||
<str id="goStart">Voltar ao início</str>
|
||||
<str id="goEnd">Avançar até o fim</str>
|
||||
<str id="addOpponentCamera">Adicionar camera no Oponente</str>
|
||||
<str id="addPlayerCamera">Adicionar camera no Jogador</str>
|
||||
<str id="muteInst">Silenciar instrumental</str>
|
||||
<str id="muteVoices">Silenciar vozes</str>
|
||||
</group>
|
||||
|
||||
<group name="BookmarkMenu" prefix="bookmarks.">
|
||||
<str id="addBookmarkHere">Adicionar Marcador Aqui</str>
|
||||
<str id="editBookmarkList">Editar Lista de Marcadores</str>
|
||||
<str id="goTo">Ir para "{0}"</str>
|
||||
<str id="createBookmarkTitle">A Criar Marcador Novo...</str>
|
||||
<str id="createBookmarkName">Nome do Marcador:</str>
|
||||
<str id="createBookmarkColor">Cor do Marcador:</str>
|
||||
<str id="editBookmarkListTitle">Lista de Marcadores</str>
|
||||
<str id="editBookmarksTitle">Editar Marcador</str>
|
||||
<str id="newBookmarkName">Novo Marcador</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.note">Notas</str>
|
||||
<group name="NoteMenu" prefix="note.">
|
||||
<str id="addSustainLength">Alargar Nota</str>
|
||||
<str id="subtractSustainLength">Encurtar Nota</str>
|
||||
<str id="selectAll">Selecionar tudo</str>
|
||||
<str id="selectMeasure">Selecionar medida</str>
|
||||
<str id="editNoteTypesList">Editar Lista de Tipos de Nota</str>
|
||||
</group>
|
||||
<str id="topBar.snap">Ajustes</str>
|
||||
<group name="SnapMenu" prefix="snap.">
|
||||
<str id="increaseSnap">↑ Ajuste de Casa</str>
|
||||
<str id="resetSnap">Repor Ajuste de Casa</str>
|
||||
<str id="decreaseSnap">↓ Ajuste de Casa</str>
|
||||
|
||||
<str id="snap">Ajuste de Casa {0}x</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.playback">Reprodução</str>
|
||||
<group name="PlaybackMenu" prefix="playback.">
|
||||
<str id="play">Tocar/Pausar</str>
|
||||
<str id="speedRaise">↑ Velocidade {0}%</str>
|
||||
<str id="speedReset">Repor Velocidade</str>
|
||||
<str id="speedLower">↓ Velocidade {0}%</str>
|
||||
<str id="sectionBack">Voltar uma secção</str>
|
||||
<str id="sectionForward">Avançar uma secção</str>
|
||||
<str id="sectionStart">Voltar ao ínicio da secção</str>
|
||||
<str id="backStep">Voltar um passo</str>
|
||||
<str id="forwardStep">Avançar um passo</str>
|
||||
<str id="metronome">Metrónomo</str>
|
||||
<str id="visualMetronome">Metrónomo visual</str>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="NoteTypes" prefix="noteTypes.">
|
||||
<str id="default">Nota Normal</str>
|
||||
</group>
|
||||
|
||||
<group name="EventTypes" prefix="events.">
|
||||
<!-- You can add your custom event types here! -->
|
||||
<!-- Just need to do some conversion from the raw name to the id -->
|
||||
<!-- Example: HScript Call -> hscriptCall -->
|
||||
<!-- Example: Change Character -> changeCharacter -->
|
||||
<str id="hscriptCall">Chamar HScript</str>
|
||||
<str id="cameraMovement">Mover Câmara</str>
|
||||
<str id="cameraPosition">Posição da Câmara</str>
|
||||
<str id="addCameraZoom">Adicionar Zoom</str>
|
||||
<str id="cameraModuloChange">Mudar Pulso da Câmara</str>
|
||||
<str id="cameraFlash">Flash da Câmara</str>
|
||||
<str id="bpmChange">Mudar BPM</str>
|
||||
<str id="continuousBpmChange">Mudança contínua de BPM</str>
|
||||
<str id="timeSignatureChange">Mudar Compasso</str>
|
||||
<str id="scrollSpeedChange">Mudança de Velocidade das Notas</str>
|
||||
<str id="altAnimationToggle">Animações Alternativas</str>
|
||||
<str id="playAnimation">Reproduzir Animação</str>
|
||||
</group>
|
||||
|
||||
<group name="StrumlineOptions" prefix="strumLine.">
|
||||
<str id="button-name">Opções ↓</str>
|
||||
|
||||
<str id="hitsounds">Som ao Bater</str>
|
||||
<str id="muteVocals">Silenciar Voz</str>
|
||||
<str id="edit">Editar</str>
|
||||
<str id="delete">Apagar</str>
|
||||
|
||||
<str id="noWaveform">Sem onda</str>
|
||||
</group>
|
||||
|
||||
<str id="createNew">Criar Nova</str>
|
||||
<str id="lock-unlock">Trancar/\nDestrancar</str>
|
||||
|
||||
<str id="info.localEvents">Eventos Locais\n(Apenas Esta Dificuldade)</str>
|
||||
<str id="info.globalEvents">Eventos Globais\n(Todas as Dificuldades)</str>
|
||||
<str id="eventType-local">Evento Local</str>
|
||||
<str id="eventType-global">Evento Global</str>
|
||||
|
||||
<!-- CharterEventAdd.hx -->
|
||||
<str id="addEvent">Adicionar Evento</str>
|
||||
<str id="editEvent">Editar Evento</str>
|
||||
<str id="deleteEvent">Apagar Evento</str>
|
||||
|
||||
<group name="Notifications" prefix="popup.">
|
||||
<str id="savedChartAt">Mapa Guardado em {0}!</str>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="CharacterEditor">
|
||||
<group name="CharacterSelection" prefix="characterSelection.">
|
||||
<str id="acceptFolder">Carregue em ACEITAR para editar esta pasta.</str>
|
||||
<str id="acceptCharacter">Carregue em ACEITAR para editar esta personagem.</str>
|
||||
<str id="newCharacter">Nova Personagem</str>
|
||||
<str id="newCharacterDesc">Carregue em ACEITAR para criar uma personagem nova.</str>
|
||||
<str id="desc">Selecione uma personagem para editar</str>
|
||||
<str id="desc-folder">Selecione uma personagem para editar em {0}</str>
|
||||
</group>
|
||||
|
||||
<group name="CharacterInfoScreen" prefix="characterInfoScreen.">
|
||||
<str id="win-title">A Editar Personagem</str>
|
||||
<str id="title">Editar Info. da Personagem</str>
|
||||
<str id="icon">Ícone</str>
|
||||
<str id="iconColor">Cor do Ícone</str>
|
||||
<str id="singDuration">Duração de Canto</str>
|
||||
<str id="useSingDuration">Usar Duração de Canto?</str>
|
||||
<str id="customValues">Valores Especiais (Avançado)</str>
|
||||
</group>
|
||||
|
||||
<group name="CharacterEditor" prefix="characterEditor.">
|
||||
<group name="TopBar">
|
||||
<str id="topBar.file">Ficheiro</str>
|
||||
<group name="FileMenu" prefix="file.">
|
||||
<str id="new">Novo</str>
|
||||
<str id="save">Guardar</str>
|
||||
<str id="saveAs">Guardar Como...</str>
|
||||
<str id="exit">Sair</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.edit">Editar</str>
|
||||
<group name="EditMenu" prefix="edit.">
|
||||
<str id="copyOffset">Copiar Posição</str>
|
||||
<str id="pasteOffset">Colar Posição</str>
|
||||
<str id="undo">Desfazer</str>
|
||||
<str id="redo">Refazer</str>
|
||||
<str id="editInfo">Editar informação</str>
|
||||
<str id="editSprite">Editar imagem fonte</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.offset">Posição</str>
|
||||
<group name="OffsetsMenu" prefix="offset.">
|
||||
<str id="moveLeft">Mover Para a Esquerda</str>
|
||||
<str id="moveUp">Mover Para Cima</str>
|
||||
<str id="moveDown">Mover Para Baixo</str>
|
||||
<str id="moveRight">Mover Para a Direita</str>
|
||||
<str id="moveExtraLeft">Mover Mais Para a Esquerda</str>
|
||||
<str id="moveExtraUp">Mover Mais Para Cima</str>
|
||||
<str id="moveExtraDown">Mover Mais Para Baixo</str>
|
||||
<str id="moveExtraRight">Mover Mais Para a Direita</str>
|
||||
<str id="dragOffsetsMouse">Arrastar Posição Com o Rato?</str>
|
||||
<str id="clearOffsets">Limpar Posições</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.stage">Cenário</str>
|
||||
<group name="StageMenu" prefix="stage.">
|
||||
<str id="useStage">Usar "{0}"</str>
|
||||
<str id="useNone">Não Usar Cenário</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.view">Vista</str>
|
||||
<group name="ViewMenu" prefix="view.">
|
||||
<str id="zoomIn">Ampliar</str>
|
||||
<str id="zoomOut">Diminuir</str>
|
||||
<str id="resetZoom">Zoom Padrão</str>
|
||||
<str id="charHitbox">"Hitbox" da Personagem?</str>
|
||||
<str id="charCam">Câmara da Personagem?</str>
|
||||
<str id="axis">Eixo XY?</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.animation">Animação</str>
|
||||
<group name="AnimationMenu" prefix="animation.">
|
||||
<str id="playAnim">Reproduzir Animação</str>
|
||||
<str id="stopAnim">Parar Animação</str>
|
||||
<str id="changeAnimUp">Mudar Animação ↑</str>
|
||||
<str id="changeAnimDown">Mudar Animação ↓</str>
|
||||
<str id="playAnimOnOffset">Reproduzir Animação Reposicionada?</str>
|
||||
</group>
|
||||
|
||||
<group name="CharacterPropertiesWindow" prefix="characterProperties.">
|
||||
<str id="position">Posição (X, Y)</str>
|
||||
<str id="scale">Tamanho</str>
|
||||
<str id="editInfo">Editar Info.</str>
|
||||
<str id="editSprite">Editar Imagem</str>
|
||||
<str id="camPosition">Posição da Câmara (X, Y)</str>
|
||||
<str id="charFlipped">Espelhado?</str>
|
||||
<str id="antialiased">Suavizado?</str>
|
||||
<str id="testCharAs">Testar Como...</str>
|
||||
<str id="charDesign">Desenhada Como...</str>
|
||||
</group>
|
||||
|
||||
<group name="CharacterAnimButton" prefix="characterAnim.">
|
||||
<str id="defaultAnimName">Nova Animação</str>
|
||||
<str id="name">Nome</str>
|
||||
<str id="anim">Animação</str>
|
||||
<str id="position">Posição (X, Y)</str>
|
||||
<str id="fps">FPS</str>
|
||||
<str id="indices">Índices (Frames)</str>
|
||||
</group>
|
||||
|
||||
<group name="CharacterSpriteScreen" prefix="characterSpriteScreen.">
|
||||
<str id="win-title">Editar imagem da personagem</str>
|
||||
<str id="charImageFile">Imagem da personagem $* Obrigatório$</str>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="CharacterCreationScreen" prefix="characterCreationScreen.">
|
||||
<str id="win-title">A Criar uma Personagem Nova</str>
|
||||
<str id="charName">Nome da Personagem $* Required$</str>
|
||||
<str id="charImgName">Imagem $* Obrigatória$</str>
|
||||
|
||||
<group name="Warnings" prefix="warnings.">
|
||||
<str id="char-exists-title">Criação da Personagem: Erro!</str>
|
||||
<str id="char-exists-body">A personagem que está a tentar criar já existe, se quiser substituir apague a personagem primeiro!</str>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="AlphabetEditor" prefix="editor.alphabet.">
|
||||
<group name="AlphabetSelection" prefix="selection.">
|
||||
<str id="acceptTypeface">Carregue em ACEITAR para editar este tipo de letra.</str>
|
||||
<str id="newTypeface">Novo Tipo de Letra</str>
|
||||
<str id="newTypefaceDesc">Carregue em ACEITAR para criar um tipo de letra novo.</str>
|
||||
<str id="desc">Selecione um tipo de letra para editar</str>
|
||||
|
||||
<group name="Warnings" prefix="warnings.">
|
||||
<str id="notImplemented-title">Novo Tipo de Letra: Função Não Implementada!</str>
|
||||
<str id="notImplemented-body">Esta função ainda não foi implementada. Por favor espere por mais atualizações até ser implementada.\n\n\n- Codename Crew (Equipa Codename)</str>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="AlphabetEditor">
|
||||
<group name="TopBar">
|
||||
<str id="topBar.file">Ficheiro</str>
|
||||
<group name="FileMenu" prefix="file.">
|
||||
<str id="new">Novo</str>
|
||||
<str id="save">Guardar</str>
|
||||
<str id="saveAs">Guardar Como...</str>
|
||||
<str id="exit">Sair</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.edit">Editar</str>
|
||||
<group name="EditMenu" prefix="edit.">
|
||||
<str id="undo">Desfazer</str>
|
||||
<str id="redo">Refazer</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.glyph">Glifo</str>
|
||||
<group name="GlyphMenu" prefix="glyph.">
|
||||
<str id="newGlyph">Novo Glifo</str>
|
||||
<str id="editGlyph">Editar Glifo</str>
|
||||
<str id="deleteGlyph">Apagar Glifo</str>
|
||||
<str id="deleteCurGlyph">Apagar Glifo Atual</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.offset">Posição</str>
|
||||
<group name="OffsetsMenu" prefix="offset.">
|
||||
<str id="moveLeft">Mover Para a Esquerda</str>
|
||||
<str id="moveUp">Mover Para Cima</str>
|
||||
<str id="moveDown">Mover Para Baixo</str>
|
||||
<str id="moveRight">Mover Para a Direita</str>
|
||||
<str id="moveExtraLeft">Mover Mais Para a Esquerda</str>
|
||||
<str id="moveExtraUp">Mover Mais Para Cima</str>
|
||||
<str id="moveExtraDown">Mover Mais Para Baixo</str>
|
||||
<str id="moveExtraRight">Mover Mais Para a Direita</str>
|
||||
<str id="clearOffsets">Limpar Posições</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.view">Vista</str>
|
||||
<group name="ViewMenu" prefix="view.">
|
||||
<str id="zoomIn">Ampliar</str>
|
||||
<str id="zoomOut">Diminuir</str>
|
||||
<str id="resetZoom">Zoom Padrão</str>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="StageEditor">
|
||||
<group name="StageSelection" prefix="stageSelection.">
|
||||
<str id="desc">Selecione um cenário para editar. Cenários HSCRIPT PURO não são suportadas.</str>
|
||||
<str id="acceptStage">Carregue em ACEITAR para editar este cenário.</str>
|
||||
<str id="newStage">Novo Cenário</str>
|
||||
<str id="acceptNewStage">Carregue em ACEITAR para criar um cenário novo.</str>
|
||||
</group>
|
||||
|
||||
<group name="StageEditor" prefix="stageEditor.">
|
||||
<group name="TopBar">
|
||||
<str id="topBar.file">Ficheiro</str>
|
||||
<group name="FileMenu" prefix="file.">
|
||||
<str id="save">Guardar</str>
|
||||
<str id="saveAs">Guardar Como...</str>
|
||||
<str id="exit">Sair</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.edit">Editar</str>
|
||||
<group name="EditMenu" prefix="edit.">
|
||||
<str id="undo">Desfazer</str>
|
||||
<str id="redo">Refazer</str>
|
||||
<str id="editStageInfo">Editar Info. do Cenário</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.select">Seleção</str>
|
||||
<group name="SelectionMenu" prefix="select.">
|
||||
<str id="all">Selecionar Tudo</str>
|
||||
<str id="deselect">Desselecionar</str>
|
||||
<str id="inverse">Inverter Seleção</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.view">Vista</str>
|
||||
<group name="ViewMenu" prefix="view.">
|
||||
<str id="zoomIn">Ampliar</str>
|
||||
<str id="zoomOut">Diminuir</str>
|
||||
<str id="zoomReset">Zoom Padrão</str>
|
||||
<str id="focusDad">Focar no Oponente</str>
|
||||
<str id="focusGF">Focar em GF</str>
|
||||
<str id="focusBF">Focar em BF</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.editor">Editor</str>
|
||||
<group name="EditorMenu" prefix="editor.">
|
||||
<str id="showCharacters">Mostrar Personagens</str>
|
||||
</group>
|
||||
|
||||
<group name="StageSpriteScreen" prefix="stageSpriteScreen.">
|
||||
<str id="win-title">Editar imagem do cenário </str>
|
||||
<str id="stageImageFile">Imagem do Cenário $* Obrigatória$</str>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="StageCreationScreen" prefix="stageCreationScreen.">
|
||||
<str id="win-title">A Criar um Cenário Novo</str>
|
||||
<str id="title">Info. do Cenário</str>
|
||||
<str id="stageName">Nome do Cenário</str>
|
||||
<str id="stagePath">Caminho do Cenário</str>
|
||||
|
||||
<group name="Warnings" prefix="warnings.">
|
||||
<str id="stage-exists-title">Criação de Cenário: Erro!</str>
|
||||
<str id="stage-exists-body">O cenário que está a tentar criar já existe, se quiser substituir apague o cenário primeiro!</str>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="StageInfoScreen" prefix="stageInfoScreen">
|
||||
<str id="win-title">A Editar Info. do Cenário: "{0}"</str>
|
||||
<str id="title">Info. do Cenário</str>
|
||||
<str id="stageName">Nome do Cenário</str>
|
||||
<str id="spritePath">Caminho do Sprite\n(Requer Recarregamento)</str>
|
||||
<str id="startCamPos">Posição inicial da Câmara (X, Y)</str>
|
||||
<str id="zoom">Zoom</str>
|
||||
<str id="customAttributes">Atributos Especiais</str>
|
||||
</group>
|
||||
|
||||
<group name="StageElementEditScreen" prefix="stageElementEditScreen.">
|
||||
<str id="win-character-title">A Editar Personagem: "{0}"</str>
|
||||
<str id="win-sprite-title">A Editar Sprite: "{0}"</str>
|
||||
<str id="win-title">A Editar XML <{0} /></str>
|
||||
|
||||
<str id="character-title">Dados da Personagem</str>
|
||||
<str id="sprite-title">Dados do Sprite</str>
|
||||
<str id="title">Dados do XML</str>
|
||||
|
||||
<str id="elementName">Nome do Elemento</str>
|
||||
<str id="nameID">Nome Identificador</str>
|
||||
<str id="imageFile">Imagem (WIP: precisa recarregar)\nEm (${stage.spritesParentFolder})</str>
|
||||
<str id="scroll">Scroll {0}</str> <!-- it's "scroll" here because "deslocamento" is too big -->
|
||||
<str id="scale">Tamanho {0}</str>
|
||||
<str id="camera">Câmara {0}</str>
|
||||
<str id="spacing">Espaçamento (X, Y)</str>
|
||||
<str id="skew">Incline {0}</str>
|
||||
<str id="alpha">Opacidade</str>
|
||||
<str id="angle">Angulo</str>
|
||||
<str id="zoomFactor">Fator de Zoom</str> <!-- same as for scroll, "fator de ampliação" took too much space -->
|
||||
<str id="positionName">Nome de Posição</str>
|
||||
<str id="flipX">Espelhar X</str>
|
||||
<str id="antialiasing">"Antialiasing"</str>
|
||||
<str id="highMemory">Alta Memória</str>
|
||||
<str id="lowMemory">Baixa Memória</str>
|
||||
<str id="attributes">Atributos</str>
|
||||
<str id="transformPreview">Pré-visualização:</str>
|
||||
<str id="animations">Animações</str>
|
||||
|
||||
<str id="animType">Tipo de Animação</str>
|
||||
<group name="AnimTypeDropdown" prefix="animType.">
|
||||
<str id="none">NENHUM</str>
|
||||
<str id="beat">EM BATIDA</str>
|
||||
<str id="loop">REPETIR</str>
|
||||
</group>
|
||||
<str id="tipCustomProperties">Dica: Para aceder a mais dados,\nSegure em Shift quando Editar</str>
|
||||
</group>
|
||||
|
||||
<group name="StageXMLEditScreen" prefix="stageXMLEditScreen.">
|
||||
<str id="win-title">A Editar XML de {0}</str>
|
||||
<str id="title">Dados do XML</str>
|
||||
<str id="attributes">Atributos</str>
|
||||
</group>
|
||||
|
||||
<str id="stageCharacters.requiredPosition">Esta posição é necessária em cenários!</str>
|
||||
<str id="stageCharacters.noDeleteGirlfriend">Não pode apagar a Girlfriend</str>
|
||||
|
||||
<group name="StageElement" prefix="stageElement.">
|
||||
<str id="scale">Tamanho: {0}, {1}</str>
|
||||
<str id="scroll">Deslocamento: {0}, {1}</str>
|
||||
</group>
|
||||
|
||||
<group name="StageSprites" prefix="stageSprites.">
|
||||
<str id="win-title">Sprites do Cenário</str>
|
||||
<str id="sprite">Sprite</str>
|
||||
<str id="box">Caixa</str>
|
||||
<str id="character">Personagem</str>
|
||||
<str id="warnings.not-implemented">Criar caixas ainda não foi implementado!</str>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="PlayTesting" prefix="playtesting.">
|
||||
<str id="chartPlaytesting" notrim="true"> (Teste de mapa)</str>
|
||||
<str id="exitGame">Sair do Jogo</str>
|
||||
<str id="exitToMenu">Sair Para Menu</str>
|
||||
<str id="saveAndExitGame">Guardar e Sair do Jogo</str>
|
||||
<str id="saveAndExitToMenu">Guardar e Sair Para Menu</str>
|
||||
<str id="cancel">Cancelar</str>
|
||||
|
||||
<str id="warningTitle">MUDANÇAS NÃO GUARDADAS!</str>
|
||||
<str id="warningDesc">Quaisquer mudanças serão *perdidas* se não as guardar. (Não serão recuperáveis)\n\n\nGostaria de Cancelar?</str>
|
||||
</group>
|
||||
|
||||
<group name="SaveWarning" prefix="saveWarning.">
|
||||
<str id="warningTitle">Mudanças não guardadas!</str>
|
||||
<str id="warningDesc">Quaisquer mudanças serão perdidas se não as guardar. (Não serão recuperáveis)\n\n\nGostaria de Cancelar?</str>
|
||||
|
||||
<str id="exitGame">Sair do Jogo</str>
|
||||
<str id="exitToMenu">Sair Para Menu</str>
|
||||
<str id="saveAndExitGame">Guardar e Sair do Jogo</str>
|
||||
<str id="saveAndExitToMenu">Guardar e Sair Para Menu</str>
|
||||
<str id="cancel">Cancelar</str>
|
||||
</group>
|
||||
|
||||
<group name="ModConfigWarning" prefix="modConfigWarning.">
|
||||
<str id="warningTitle">Configuração da pasta do mod em falta!</str>
|
||||
<str id="warningDesc">Está a faltar um ficheiro de configurações ao seu mod!\n\nGostaria de criar um automaticamente?\n\n(PS: Se este mod não for seu, por favor desative o Modo de desenvolvedor para fazer esta notificação parar de aparecer.)</str>
|
||||
|
||||
<str id="createdTitle">Config. de mod criada!</str>
|
||||
<str id="createdDesc">As configurações do seu mod foram criadas em {0}!</str>
|
||||
</group>
|
||||
</language>
|
||||
@@ -0,0 +1,104 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<language>
|
||||
<group name="PlayState">
|
||||
<str id="game.score">Pontos:{0}</str>
|
||||
<str id="game.misses">Erros:{0}</str>
|
||||
<str id="game.comboBreaks">Quebras de Combo:{0}</str>
|
||||
<str id="game.accuracy">Precisão:{0} - {1}</str>
|
||||
<str id="game.combo">Combo:{0}</str>
|
||||
|
||||
<str id="game.rating.[N/A]">[N/A]</str>
|
||||
<str id="game.rating.F">F</str>
|
||||
<str id="game.rating.E">E</str>
|
||||
<str id="game.rating.D">D</str>
|
||||
<str id="game.rating.C">C</str>
|
||||
<str id="game.rating.B">B</str>
|
||||
<str id="game.rating.A">A</str>
|
||||
<str id="game.rating.S">S</str>
|
||||
<str id="game.rating.S++">S++</str>
|
||||
</group>
|
||||
|
||||
<group name="StoryMenu">
|
||||
<str id="story.score">PONTUAÇÃO DA SEMANA:{0}</str>
|
||||
<str id="story.tracks">FAIXAS</str>
|
||||
</group>
|
||||
|
||||
<group name="Freeplay">
|
||||
<str id="freeplay.score">RECORDE PESSOAL:{0}</str>
|
||||
<str id="freeplay.solo">Solo</str>
|
||||
<str id="freeplay.opponentMode">Modo Oponente</str>
|
||||
<str id="freeplay.coopMode">Modo Co-Op</str>
|
||||
<str id="freeplay.coopModeSwitched">Modo Co-Op (Trocado)</str>
|
||||
</group>
|
||||
|
||||
<group name="Pause">
|
||||
<group name="PauseOptions">
|
||||
<str id="pause.resume">Continuar</str>
|
||||
<str id="pause.restartSong">Recomeçar Canção</str>
|
||||
<str id="pause.changeControls">Mudar Controlos</str>
|
||||
<str id="pause.changeOptions">Opções</str>
|
||||
<str id="pause.exitToMenu">Sair para menu</str>
|
||||
<str id="pause.exitToCharter">Sair para editor</str>
|
||||
<str id="pause.resumeCutscene">Resumir Cena</str>
|
||||
<str id="pause.skipCutscene">Saltar Cena</str>
|
||||
<str id="pause.restartCutscene">Recomeçar Cena</str>
|
||||
</group>
|
||||
|
||||
<str id="pause.deathCounter">Tomates azuis: {0}</str>
|
||||
<str id="pause.coopMode">MODO CO-OP</str>
|
||||
<str id="pause.opponentMode">MODO OPONENTE </str>
|
||||
</group>
|
||||
|
||||
<group name="Credits">
|
||||
<group name="CreditsCodename">
|
||||
<str id="credits.mainDev" notrim="true"> *- Membro público dos Desenvolvedores!*</str>
|
||||
<str id="credits.totalContributions">Contribuições Totais: ~{0}~ / *{1}* (~{2}%~) - Selecione para abrir a sua conta GitHub</str>
|
||||
<str id="credits.downloadingList">A Descarregar Lista...</str>
|
||||
<str id="credits.allContributors">Todos os contribuidores! Carregue em REINICIAR para atualizar a lista (Uma vez a cada 2 minutos).</str>
|
||||
</group>
|
||||
<group name="CreditsMain">
|
||||
<str id="credits.name">Créditos</str>
|
||||
<str id="credits.madePossible">As pessoas que fizeram isto possível!</str>
|
||||
<str id="credits.selectCodename">Selecione isto para ver todos os contribuidores de Codename Engine!</str>
|
||||
<str id="credits.selectBase">Selecione isto para abrir a página itch.io do jogo original para doar!</str>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="Mods">
|
||||
<str id="mods.disableMods">Desativar Mods</str>
|
||||
</group>
|
||||
|
||||
<group name="MainMenu">
|
||||
<str id="mainMenu.commit">Commit: {0} ({1})</str>
|
||||
<str id="mainMenu.openMods">[{0}] Abrir menu de mods</str>
|
||||
</group>
|
||||
|
||||
<group name="Updater">
|
||||
<group name="UpdateAvailable">
|
||||
<str id="updateAvailable.title">NOVA ATUALIZAÇÃO</str>
|
||||
<str id="updateAvailable.install">INSTALAR</str>
|
||||
<str id="updateAvailable.skip">SALTAR</str>
|
||||
</group>
|
||||
<group name="UpdateScreen">
|
||||
<str id="updateScreen.general-1">A Preparar a instalação...</str>
|
||||
<str id="updateScreen.part-1">A Criar a pasta de instalação e a limpar ficheiros antigos...</str>
|
||||
|
||||
<str id="updateScreen.general-2">A Transferir ficheiros...</str>
|
||||
<str id="updateScreen.part-2">A Transferir ficheiro {0}</str>
|
||||
|
||||
<str id="updateScreen.general-3">A transferir executável novo...</str>
|
||||
<str id="updateScreen.part-3">A Transferir {0}</str>
|
||||
|
||||
<str id="updateScreen.general-4">A instalar ficheiros novos...</str>
|
||||
<str id="updateScreen.part-4">A Instalar {0}</str>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="Difficulties">
|
||||
<str id="diff.easy">Fácil</str>
|
||||
<str id="diff.normal">Normal</str>
|
||||
<str id="diff.hard">Difícil</str>
|
||||
<str id="diff.erect">Ereto</str>
|
||||
<str id="diff.nightmare">Pesadelo</str>
|
||||
</group>
|
||||
</language>
|
||||
@@ -0,0 +1,208 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<language>
|
||||
<str id="optionsMenu.desc-missing">Sem descrição</str>
|
||||
|
||||
<group name="OptionsMenu">
|
||||
<str id="optionsMenu.advanced">Avançado</str>
|
||||
<str id="optionsMenu.header.title">Opções</str>
|
||||
<str id="optionsMenu.header.desc">Selecione uma categoria para continuar.</str>
|
||||
|
||||
<str id="optionsTree.controls-name">Controlos</str>
|
||||
<str id="optionsTree.controls-desc">Mude os Controlos para Jogador 1 e Jogador 2!</str>
|
||||
|
||||
<str id="optionsTree.gameplay-name">Jogo</str>
|
||||
<str id="optionsTree.gameplay-desc">Mude as opções como "Downscroll", Velocidade das notas, Indecência...</str>
|
||||
<str id="optionsTree.gameplay.advanced-desc">Mude as opções mais avançadas como Transmissão de áudio...</str>
|
||||
|
||||
<str id="optionsTree.appearance-name">Aparência</str>
|
||||
<str id="optionsTree.appearance-desc">Mude as opções de aparência como Luzes intermitentes...</str>
|
||||
<str id="optionsTree.appearance.advanced-desc">Mude as opções mais avançadas como Sprites apenas em VRAM, "Antialiasing", "Shaders"</str>
|
||||
|
||||
<str id="optionsTree.language-name">Idioma</str>
|
||||
<str id="optionsTree.language-desc">Mude o idioma que o jogo usa.</str>
|
||||
|
||||
<str id="optionsTree.miscellaneous-name">Outras</str>
|
||||
<str id="optionsTree.miscellaneous-desc">Use este menu para apagar dados ou definições.</str>
|
||||
|
||||
<str id="optionsTree.debug-name">Opções de Depuração</str>
|
||||
<str id="optionsTree.debug-desc">Opções de Depuração para o Modo de Desenvolvedor.</str>
|
||||
</group>
|
||||
|
||||
<group name="KeybindOptions" prefix="KeybindsOptions.">
|
||||
<str id="left">Esquerda</str>
|
||||
<str id="down">Baixo</str>
|
||||
<str id="up">Cima</str>
|
||||
<str id="right">Direita</str>
|
||||
|
||||
<str id="category.notes">Notas</str>
|
||||
|
||||
<str id="category.ui">Interface</str>
|
||||
<group name="ui" prefix="ui.">
|
||||
<str id="accept">Aceitar</str>
|
||||
<str id="back">Cancelar</str>
|
||||
<str id="reset">Reiniciar</str>
|
||||
<str id="pause">Pausa</str>
|
||||
<str id="changeMode">Mudar Modo</str>
|
||||
</group>
|
||||
|
||||
<str id="category.engine">Codename Engine</str>
|
||||
<group name="engine" prefix="engine.">
|
||||
<str id="switchMod">Trocar Mod</str>
|
||||
<str id="fpsCounter">Contador de FPS</str>
|
||||
</group>
|
||||
|
||||
<str id="category.volume">Volume</str>
|
||||
<str id="volume.up">Subir</str>
|
||||
<str id="volume.down">Baixar</str>
|
||||
<str id="volume.mute">Silenciar</str>
|
||||
|
||||
<str id="category.developer">Desenvolvedor</str>
|
||||
<group name="developer" prefix="developer.">
|
||||
<str id="devMenus">Menus Dev.</str>
|
||||
<str id="openConsole">Consola</str>
|
||||
<str id="reloadState">Recarregar</str>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="AppearanceOptions" prefix="AppearanceOptions.">
|
||||
<str id="framerate-name">FPS</str>
|
||||
<str id="framerate-desc">Quadros Por Segundo, se quiser. Explica-se a sí próprio, certo?</str>
|
||||
|
||||
<str id="flashingMenu-name">Luzes Intermitentes</str>
|
||||
<str id="flashingMenu-desc">Se desmarcado, irá desativar as luzes intermitentes quando seleciona algo no Menu Principal, e outras serão abrandadas.</str>
|
||||
|
||||
<str id="colorHealthBar-name">Barra de Vida Colorida</str>
|
||||
<str id="colorHealthBar-desc">Se desmarcado, o jogo irá usar a barra vermelha/verde de versões FNF pré-semana 7.</str>
|
||||
|
||||
<str id="week6PixelPerfect-name">Efeito "Pixel Perfect"</str>
|
||||
<str id="week6PixelPerfect-desc">se marcado, a Semana 6 ou outros cenários "pixel" terão um efeito "pixel perfect", alinhando todos os pixeis ao ecrã.</str>
|
||||
|
||||
<group name="AppearanceOptionsAdvanced" prefix="Advanced.">
|
||||
<str id="quality-name">Qualidade</str>
|
||||
<str id="quality-desc">Modos de qualidade para escolher, "BAIXA" = Desativa todos os efeitos visuais pesados para um jogo mais suave, "ALTA" = Ativa todos os efeitos visuais, ao custo do desempenho, "CUSTOMIZADA" = Permite opções especiais, disponíveis em "Advançado".</str>
|
||||
<str id="quality-low">BAIXA</str>
|
||||
<str id="quality-high">ALTA</str>
|
||||
<str id="quality-custom">CUSTOMIZADA</str>
|
||||
|
||||
<str id="antialiasing-name">"Antialiasing"</str>
|
||||
<str id="antialiasing-desc">Se desmarcado, irá remover "antialiasing" a todos os sprites. Poderá aumentar o desempenho ao custo de sprites menos suaves.</str>
|
||||
|
||||
<str id="lowMemoryMode-name">Memória baixa</str>
|
||||
<str id="lowMemoryMode-desc">Se marcado, irá remover certos elementos de fundo para reduzir o uso de memória.</str>
|
||||
|
||||
<str id="gameplayShaders-name">"Shaders"</str>
|
||||
<str id="gameplayShaders-desc">If desmarcado, "Shaders" (efeitos visuais como a Aberração cromática de "Thorns") não serão carregadas; poderá ser útil em dispositivos fracos.</str>
|
||||
|
||||
<str id="gpuOnlyBitmaps-name">Sprites só em VRAM</str>
|
||||
<str id="gpuOnlyBitmaps-desc">Se marcado, irá apenas guardar os bitmaps na GPU, libertando IMENSA memória (EXPERIMENTAL). Desmarcar isto irá consumir muita memória, especialmente em sprites maiores. Se não tiver a certeza, deixe isto marcado.</str>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="GameplayOptions" prefix="GameplayOptions.">
|
||||
<str id="downscroll-name">"Downscroll"</str>
|
||||
<str id="downscroll-desc">Se marcado, notas irão de cima para baixo em vez de baixo para cima, como se estivessem a cair.</str>
|
||||
|
||||
<str id="ghostTapping-name">Toques Fantasma</str>
|
||||
<str id="ghostTapping-desc">Se desmarcado, bater em teclas que não tem uma nota conta como erro.</str>
|
||||
|
||||
<str id="naughtyness-name">Indecência</str>
|
||||
<str id="naughtyness-desc">Se desmarcado, irá censurar as cenas da Semana 7, ou mais.</str>
|
||||
|
||||
<str id="camZoomOnBeat-name">Zoom na Batida</str>
|
||||
<str id="camZoomOnBeat-desc">Se desmarcado. irá parar a câmara de ampliar a cada 4 batidas.</str>
|
||||
|
||||
<str id="autoPause-name">Auto Pausa</str>
|
||||
<str id="autoPause-desc">Se marcado, mudar de janela pausará o jogo.</str>
|
||||
|
||||
<str id="volumeMusic-name">Volume da Música</str>
|
||||
<str id="volumeMusic-desc">Muda apenas o volume da música em vez de tudo.</str>
|
||||
|
||||
<str id="volumeSFX-name">Volume dos SFX</str>
|
||||
<str id="volumeSFX-desc">Muda apenas o volume dos efeitos sonoros em vez de tudo.</str>
|
||||
|
||||
<str id="songOffset-name">Atraso da Música</str>
|
||||
<str id="songOffset-desc">Muda a posição da música relativamente às notas.</str>
|
||||
|
||||
<group name="GameplayOptionsAdvanced" prefix="Advanced.">
|
||||
<str id="windowSize-name">Tamanho da Janela</str>
|
||||
<str id="windowSize-desc">...</str>
|
||||
|
||||
<str id="streamedMusic-name">Transmissão de Música</str>
|
||||
<str id="streamedMusic-desc">Se marcado, músicas serão transmitidas enquanto tocam, libertando IMENSA memória com o custo de maior uso de CPU se mais sons estiverem a ser transmitidos ao mesmo tempo (EXPERIMENTAL). Desmarcar isto irá consumir muita memória, especialmente em músicas maiores. Se não tiver a certeza, deixe marcado.</str>
|
||||
|
||||
<str id="streamedVocals-name">Transmissão de Vozes</str>
|
||||
<str id="streamedVocals-desc">Se marcado, vozes também serão transmitidas enquanto tocam se "Transmissão de Música" estiver ativada. Irá impactar o desempenho se a canção usar muitas vozes (EXPERIMENTAL). Se não tiver a certeza, deixe marcado.</str>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="LanguageOptions" prefix="LanguageOptions.">
|
||||
<str id="language-name">Idioma</str>
|
||||
<str id="language-desc">Idioma por {0} (Versão: {1})</str>
|
||||
</group>
|
||||
|
||||
<group name="MiscOptions" prefix="MiscOptions.">
|
||||
<str id="forceCrash-name">Forçar "Crash"</str>
|
||||
<str id="forceCrash-desc">Selecione esta opção para forçar o jogo a encravar e travar.</str>
|
||||
|
||||
<str id="betaUpdates-name">Atualizações "Nightly"</str>
|
||||
<str id="betaUpdates-desc">Se marcado, também irá incluir versões "nightly" (a versão mais recente disponível no repositório de GitHub) na verificação de atualizações.</str>
|
||||
|
||||
<str id="checkForUpdates-name">Verificar Atualizações</str>
|
||||
<str id="checkForUpdates-desc">Selecione esta opção para verificar se existem atualizações novas.</str>
|
||||
<str id="checkForUpdates-noUpdateFound">Nenhuma atualização encontrada.</str>
|
||||
|
||||
<str id="devMode-name">Modo Desenvolvedor</str>
|
||||
<str id="devMode-desc">Se marcado, irá poder aceder funções de desenvolvedor como certas teclas, editores, opções de desenvolvedor, recarregamento de estados, consola e mais.</str>
|
||||
|
||||
<str id="allowConfigWarning-name">Aviso de Modpacks</str>
|
||||
<str id="allowConfigWarning-desc">Se marcado, um aviso no início do jogo aparecerá se houver problemas com o modpack, como configurações em falta, versões incompatíveis e mais.</str>
|
||||
|
||||
<str id="resetSaveData-name">Apagar Dados</str>
|
||||
<str id="resetSaveData-desc">Selecione esta opção para apagar todos os dados. Isto irá remover todos os seus recordes.</str>
|
||||
</group>
|
||||
|
||||
<group name="DebugOptions" prefix="DebugOptions.">
|
||||
<str id="title">Opções de Depuração</str>
|
||||
<str id="desc">Use este menu para ativar ou desativar opções de depuração.</str>
|
||||
|
||||
<str id="showConsole-name">Mostrar Consola</str>
|
||||
<str id="showConsole-desc">Selecione isto para mostrar a consola, que contém registos acerca do jogo.</str>
|
||||
|
||||
<str id="editorsResizable-name">Editores Adaptáveis</str>
|
||||
<str id="editorsResizable-desc">Se marcado, irá permitir que os editores utilizem resoluções acima da base 1280x720 de FNF (permitindo mais detalhe e espaço...)</str>
|
||||
|
||||
<str id="bypassEditorsResize-name">Sem Tamanho Mínimo</str>
|
||||
<str id="bypassEditorsResize-desc">Desativa o limite de resolução minimo dos editores (Requer que "Editores Adaptáveis" esteja marcado).</str>
|
||||
|
||||
<str id="editorSFX-name">Sons de Editor</str>
|
||||
<str id="editorSFX-desc">Se marcado, tocará efeitos sonoros nos editores (ex: ao carregar em caixas...)</str>
|
||||
|
||||
<str id="editorCharterPrettyPrint-name">Mapas Legíveis</str>
|
||||
<str id="editorCharterPrettyPrint-desc">Se marcado, os ficheiros guardados no editor de mapas serão formatados para serem fácilmente legíveis.</str>
|
||||
|
||||
<str id="editorCharacterPrettyPrint-name">Personagens Legíveis</str>
|
||||
<str id="editorCharacterPrettyPrint-desc">Se marcado, os ficheiros guardados no editor de personagens serão formatados para serem fácilmente legíveis.</str>
|
||||
|
||||
<str id="editorStagePrettyPrint-name">Cenários Legíveis</str>
|
||||
<str id="editorStagePrettyPrint-desc">Se marcado, os ficheiros guardados no editor de cenários serão formatados para serem fácilmente legíveis.</str>
|
||||
|
||||
<str id="intensiveBlur-name">Desfoque Intensivo</str>
|
||||
<str id="intensiveBlur-desc">Se marcado, irá usar um desfoque mais intensivo. Parece melhor, mas poderá ser mais lento.</str>
|
||||
|
||||
<str id="charterAutoSaves-name">Gravação Automática</str>
|
||||
<str id="charterAutoSaves-desc">Se marcado, irá guardar ficheiros de editor automáticamente, com as definições listadas abaixo.</str>
|
||||
|
||||
<str id="charterAutoSaveTime-name">Tempo de Gravação</str>
|
||||
<str id="charterAutoSaveTime-desc">Isto controla com que frequência o editor gravará o ficheiro (em segundos...)</str>
|
||||
|
||||
<str id="charterAutoSaveWarningTime-name">Tempo de Aviso</str>
|
||||
<str id="charterAutoSaveWarningTime-desc">Isto controla com que antecedência o editor irá avisá-lo antes de guardar (em segundos..., 0 para desativar)</str>
|
||||
|
||||
<str id="charterAutoSavesSeparateFolder-name">Pasta de Gravações</str>
|
||||
<str id="charterAutoSavesSeparateFolder-desc">Se marcado, irá guardar os ficheiros numa pasta separada com a data em vez de substituir o ficheiro atual. (song/autosaves/)</str>
|
||||
|
||||
<str id="songOffsetAffectEditors-name">Atraso no Mapeador</str>
|
||||
<str id="songOffsetAffectEditors-desc">Se marcado, irá ativar o Atraso da Música no Editor de Mapas, também.</str>
|
||||
</group>
|
||||
|
||||
</language>
|
||||
@@ -0,0 +1,3 @@
|
||||
name="Português"
|
||||
credits="Bitto1070"
|
||||
version="1.0.0"
|
||||
@@ -1,19 +1,15 @@
|
||||
import flixel.FlxSprite;
|
||||
|
||||
var tankmanRun:Array<TankmenBG> = [];
|
||||
var grpTankmanRun:FlxTypedGroup<FlxSprite> = [];
|
||||
|
||||
var spawnTimes = []; // [[time, direction]]
|
||||
var tankmanPool = [];
|
||||
|
||||
function recycleTankman() {
|
||||
if(tankmanPool.length == 0) {
|
||||
return new TankmenBG();
|
||||
} else {
|
||||
return tankmanPool.shift(); // can be pop but it causes it to be less random
|
||||
}
|
||||
var tankmanGroup:TankmenGroup = {
|
||||
run: [],
|
||||
pool: [],
|
||||
group: new FlxTypedGroup<FlxSprite>()
|
||||
}
|
||||
|
||||
function recycleTankman()
|
||||
return tankmanGroup.pool.length == 0 ? new TankmenBG(tankmanGroup) : tankmanGroup.pool.shift(); // can be pop but it causes it to be less random
|
||||
|
||||
function getTankman(data:Array<Float>) {
|
||||
var tankman:TankmenBG = recycleTankman();
|
||||
tankman.strumTime = data[0];
|
||||
@@ -22,9 +18,8 @@ function getTankman(data:Array<Float>) {
|
||||
}
|
||||
|
||||
function postCreate() {
|
||||
grpTankmanRun = new FlxTypedGroup();
|
||||
insert(members.indexOf(gf) - 1, grpTankmanRun);
|
||||
if(inCutscene) grpTankmanRun.visible = false;
|
||||
insert(members.indexOf(gf) - 1, tankmanGroup.group);
|
||||
if (inCutscene) tankmanGroup.group.visible = false;
|
||||
|
||||
/*var tempTankman:TankmenBG = recycleTankman();
|
||||
tempTankman.strumTime = 10;
|
||||
@@ -42,9 +37,8 @@ function postCreate() {
|
||||
//spawnTimes.reverse(); // no need to reverse it since the notes are already reversed
|
||||
}
|
||||
|
||||
function onStartCountdown() {
|
||||
if(PlayState.instance.seenCutscene) grpTankmanRun.visible = true;
|
||||
}
|
||||
function onStartCountdown()
|
||||
if (PlayState.instance.seenCutscene) tankmanGroup.group.visible = true;
|
||||
|
||||
function spawnTankmen() {
|
||||
var time = Conductor.songPosition;
|
||||
@@ -54,50 +48,46 @@ function spawnTankmen() {
|
||||
|
||||
//trace("Spawning Tankman", tankmen.sprite.offset, tankmen.goingRight);
|
||||
|
||||
tankmanRun.push(tankmen);
|
||||
grpTankmanRun.add(tankmen.sprite);
|
||||
tankmanGroup.run.push(tankmen);
|
||||
tankmanGroup.group.add(tankmen.sprite);
|
||||
}
|
||||
}
|
||||
|
||||
function update(elapsed) {
|
||||
spawnTankmen();
|
||||
|
||||
var length = tankmanRun.length;
|
||||
for(i in 0...length) {
|
||||
var length = tankmanGroup.run.length;
|
||||
for (i in 0...length) {
|
||||
var reverseIndex = length - i - 1;
|
||||
var tankmen = tankmanRun[reverseIndex];
|
||||
var tankmen = tankmanGroup.run[reverseIndex];
|
||||
tankmen.update(elapsed);
|
||||
}
|
||||
}
|
||||
|
||||
class TankmenBG {
|
||||
public var sprite:FlxSprite;
|
||||
|
||||
var strumTime = 0;
|
||||
var goingRight = false;
|
||||
var tankSpeed = 0.7;
|
||||
|
||||
var endingOffset = null;
|
||||
var sprite = null;
|
||||
|
||||
var endingOffset:Float;
|
||||
var killed = false;
|
||||
var grp:TankmenGroup; // The reference to the current pool
|
||||
|
||||
function new() {
|
||||
this.sprite = new FlxSprite();
|
||||
var sprite = this.sprite;
|
||||
function new(grp:TankmenGroup) {
|
||||
this.grp = grp;
|
||||
|
||||
sprite = new FlxSprite();
|
||||
sprite.frames = Paths.getSparrowAtlas('stages/tank/tankmanKilled1');
|
||||
sprite.antialiasing = true;
|
||||
sprite.animation.addByPrefix('run', 'tankman running', 24, true);
|
||||
|
||||
sprite.animation.play('run');
|
||||
|
||||
sprite.updateHitbox();
|
||||
|
||||
sprite.setGraphicSize(Std.int(sprite.width * 0.8));
|
||||
sprite.updateHitbox();
|
||||
}
|
||||
|
||||
function resetShit(x, y, isGoingRight) {
|
||||
var sprite = this.sprite;
|
||||
function resetShit(x:Float, y:Float, isGoingRight:Bool) {
|
||||
sprite.revive();
|
||||
sprite.setPosition(x, y);
|
||||
sprite.offset.set(0, 0);
|
||||
@@ -114,7 +104,6 @@ class TankmenBG {
|
||||
}
|
||||
|
||||
function update(elapsed) {
|
||||
var sprite = this.sprite;
|
||||
sprite.visible = !(sprite.x >= FlxG.width * 1.5 || sprite.x <= FlxG.width * -0.5);
|
||||
|
||||
if (sprite.animation.curAnim.name == 'run')
|
||||
@@ -124,8 +113,7 @@ class TankmenBG {
|
||||
if (goingRight) {
|
||||
endDirection = (FlxG.width * 0.02) - endingOffset;
|
||||
sprite.x = (endDirection + (Conductor.songPosition - strumTime) * tankSpeed);
|
||||
}
|
||||
else sprite.x = (endDirection - (Conductor.songPosition - strumTime) * tankSpeed);
|
||||
} else sprite.x = (endDirection - (Conductor.songPosition - strumTime) * tankSpeed);
|
||||
}
|
||||
|
||||
if (Conductor.songPosition > strumTime)
|
||||
@@ -133,10 +121,10 @@ class TankmenBG {
|
||||
sprite.animation.play('shot');
|
||||
sprite.animation.finishCallback = function(_) {
|
||||
killed = true;
|
||||
grpTankmanRun.remove(sprite, true);
|
||||
grp.group.remove(sprite, true);
|
||||
sprite.kill();
|
||||
tankmanPool.push(this);
|
||||
tankmanRun.remove(this);
|
||||
grp.pool.push(this);
|
||||
grp.run.remove(this);
|
||||
}
|
||||
|
||||
if (goingRight)
|
||||
@@ -146,4 +134,4 @@ class TankmenBG {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,59 @@
|
||||
# Compiling Codename Engine
|
||||
Do you want to turn your source code into a playable build to play? Then you want to **compile the source code**, follow this guide.
|
||||
> **Open the instructions for your platform.**
|
||||
<details>
|
||||
<summary>Windows</summary>
|
||||
|
||||
1. Install [version 4.3.7 of Haxe](https://haxe.org/download/version/4.3.7/).
|
||||
2. Download and install [`git-scm`](https://git-scm.com/download/win).
|
||||
- Leave all installation options as default.
|
||||
3. Run `setup-windows.bat` using cmd or double-clicking it and wait for the libraries to install.
|
||||
4. Once the libraries are installed, run `haxelib run lime test windows` to compile and launch the game (may take a long time)
|
||||
- ℹ You can run `haxelib run lime setup` to make the lime command global, allowing you to execute `lime test windows` directly.
|
||||
</details>
|
||||
<details>
|
||||
<summary>Linux</summary>
|
||||
|
||||
1. Install [version 4.3.7 of Haxe](https://haxe.org/download/version/4.3.7/).
|
||||
2. Install `libvlc` if not present already.
|
||||
- ℹ On certain Arch based distros installing `vlc-plugins-all` might solve if `libvlc` alone doesn't work.
|
||||
3. Install `g++`, if not present already.
|
||||
4. Download and install [`git-scm`](https://git-scm.com/download/linux) if not present already.
|
||||
5. Run `setup-unix.sh` using the terminal or double-clicking it and wait for the libraries to install.
|
||||
6. Once the libraries are installed, run `haxelib run lime test linux` to compile and launch the game (may take a long time)
|
||||
- ℹ You can run `haxelib run lime setup` to make the lime command global, allowing you to execute `lime test linux` directly.
|
||||
</details>
|
||||
<details>
|
||||
<summary>MacOS</summary>
|
||||
|
||||
1. Install [version 4.3.7 of Haxe](https://haxe.org/download/version/4.3.7/).
|
||||
2. Install `Xcode` to allow C++ app building.
|
||||
3. Download and install [`git-scm`](https://git-scm.com/download/mac).
|
||||
4. Run `setup-unix.sh` using the terminal and wait for the libraries to install.
|
||||
5. Once the libraries are installed, run `haxelib run lime test mac` to compile and launch the game (may take a long time)
|
||||
- ℹ You can run `haxelib run lime setup` to make the lime command global, allowing you to execute `lime test mac` directly.
|
||||
</details>
|
||||
|
||||
> [!TIP]
|
||||
> You can also run `./cne-windows.bat -help` or `./cne-unix.sh -help` (depending on your platform) to check out more useful commands!<br>
|
||||
> For example `./cne-windows test` or `./cne-unix.sh test` builds the game and uses the source assets folder instead of the export one for easier development (although you can still use `lime test` normally).
|
||||
> - If you're running the terminal from the project's main folder, use instead `./building/cne-windows.bat -COMMAND HERE` or `./building/cne-unix.sh -COMMAND HERE` depending on your platform.
|
||||
|
||||
# Generating Codename Engine's API documentation
|
||||
**Mainly recommended if you intend to fork the engine and make your own custom version to publish.**<br>Do you want to generate an API documentation so people can understand and mod your playable build? This documentation can be uploaded to your website.<br>If you just want to compile the engine normally for your hardcoded mod or for yourself you can skip this step.
|
||||
> **Select your platform to continue.**
|
||||
<details>
|
||||
<summary>Windows</summary>
|
||||
|
||||
1. Run `generate-docs-windows.bat` using cmd or double-clicking it and wait for the `doc.xml` to be generated inside the `docs` folder.
|
||||
</details>
|
||||
<details>
|
||||
<summary>MacOS/Linux</summary>
|
||||
|
||||
1. Run `generate-docs-unix.sh` using the terminal or double-clicking it and wait for the `doc.xml` to be generated inside the `docs` folder.
|
||||
</details>
|
||||
|
||||
2. You can use this `doc.xml` file to generate a full HTML documentation (that you can open in your browser for example) using Haxe's [dox](https://github.com/HaxeFoundation/dox) generator; check [Codename Engine's webiste](https://github.com/CodenameCrew/codename-website/tree/main/api-generator) for example.
|
||||
|
||||
> [!CAUTION]
|
||||
> The doc.xml might contain some sensible paths of your computer: make sure to filter the file before publishing it for everyone if you want to keep those paths private!<br>To filter and delete those paths, you may use Codename Engine's website's [doc filter Python script](https://github.com/CodenameCrew/codename-website/blob/main/api-generator/api/filter.py) by simply running it in the same folder of your `doc.xml` file. This script will also delete everything irrelevant to the engine that was generated in your documentation, such as libraries' (like OpenFL or Flixel) APIs.
|
||||
@@ -1,14 +1,17 @@
|
||||
[general]
|
||||
[General]
|
||||
sample-type=float32
|
||||
stereo-mode=speakers
|
||||
stereo-encoding=panpot
|
||||
hrtf=false
|
||||
cf_level=0
|
||||
resampler=fast_bsinc24
|
||||
front-stablizer=false
|
||||
output-limiter=false
|
||||
front-stabilizer=false
|
||||
volume-adjust=0
|
||||
period_size=441
|
||||
sources=512
|
||||
sends=64
|
||||
dither=false
|
||||
|
||||
[decoder]
|
||||
hq-mode=false
|
||||
distance-comp=false
|
||||
hq-mode=true
|
||||
distance-comp=true
|
||||
nfc=false
|
||||
@@ -1 +1,3 @@
|
||||
#!/usr/bin/env sh
|
||||
cd "$(dirname "$0")/.."
|
||||
haxe -cp commandline -D analyzer-optimize --run Main $@
|
||||
@@ -1 +1,2 @@
|
||||
cd /d "%~dp0.."
|
||||
@haxe -cp commandline -D analyzer-optimize --run Main %*
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env sh
|
||||
cd "$(dirname "$0")/.."
|
||||
echo "Generating documentation..."
|
||||
if [ $(uname) == "Darwin" ]; then
|
||||
echo "Platform is macOS"
|
||||
haxelib run lime build mac --haxeflag="-xml docs/doc.xml" -D doc-gen -D DOCUMENTATION --no-output
|
||||
else
|
||||
echo "Platform is not macOS; assuming platform to be Linux compatible"
|
||||
haxelib run lime build linux --haxeflag="-xml docs/doc.xml" -D doc-gen -D DOCUMENTATION --no-output
|
||||
fi
|
||||
|
||||
echo "The XML file for the API documentation has been generated at docs/doc.xml."
|
||||
echo "For updating the API documentation hosted at the website, please replace codename-website/api-generator/api/doc.xml with the file listed above."
|
||||
@@ -0,0 +1,8 @@
|
||||
@ECHO OFF
|
||||
cd /d "%~dp0.."
|
||||
echo Generating documentation...
|
||||
echo Platform is based on Windows
|
||||
haxelib run lime build windows --haxeflag="-xml docs/doc.xml" -D doc-gen -D DOCUMENTATION --no-output
|
||||
|
||||
echo The XML file for the API documentation has been generated at docs/doc.xml.
|
||||
echo For updating the API documentation hosted at the website, please replace codename-website/api-generator/api/doc.xml with the file listed above.
|
||||
@@ -16,8 +16,9 @@
|
||||
<git name="hscript-improved" url="https://github.com/CodenameCrew/hscript-improved" ref="codename-dev" />
|
||||
<git name="flxanimate" url="https://github.com/CodenameCrew/cne-flxanimate" />
|
||||
<git name="hxdiscord_rpc" url="https://github.com/CodenameCrew/cne-hxdiscord_rpc" skipDeps="true" />
|
||||
<git name="funkin-modchart" url="https://github.com/TheoDevelops/FunkinModchart" ref="f30676579d8de7ccac7d12e13b664e8b2c42c6bf" skipDeps="true" />
|
||||
<lib name="funkin-modchart" version="1.2.4" skipDeps="true" />
|
||||
<lib name="hxvlc" version="1.9.3" skipDeps="true" />
|
||||
<git name="bin-serializer" url="https://github.com/CodenameCrew/bin-serializer" />
|
||||
|
||||
<!-- Documentation and other features -->
|
||||
<git name="away3d" url="https://github.com/CodenameCrew/away3d" />
|
||||
@@ -1,2 +1,3 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/env sh
|
||||
cd "$(dirname "$0")/.."
|
||||
haxe -cp commandline -D analyzer-optimize --run Main setup
|
||||
@@ -1 +1,2 @@
|
||||
cd /d "%~dp0.."
|
||||
@haxe -cp commandline -D analyzer-optimize --run Main setup
|
||||
+2
-1
@@ -16,7 +16,7 @@ class Main {
|
||||
dDoc: [
|
||||
"Usage: setup",
|
||||
"",
|
||||
"This command runs through all libraries in libs.xml, and install them.",
|
||||
"This command runs through all libraries in building/libs.xml, and install them.",
|
||||
"If they're already installed, they will be updated.",
|
||||
"",
|
||||
"--all : Reinstall all libraries.",
|
||||
@@ -173,6 +173,7 @@ class Main {
|
||||
Sys.println("Codename Engine Command Line utility");
|
||||
Sys.println('Available commands (${commands.length}):\n');
|
||||
for(line in commands) {
|
||||
if(line.names.contains(null)) line.names.remove(null);
|
||||
Sys.println('${line.names.join(", ")} - ${line.doc}');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ class Setup {
|
||||
FileSystem.createDirectory('.haxelib');
|
||||
}
|
||||
|
||||
var libFile = "./libs.xml";
|
||||
var libFile = "./building/libs.xml";
|
||||
if(args.existsOption("lib")) {
|
||||
libFile = args.getOption("lib");
|
||||
if(libFile == null) {
|
||||
@@ -252,32 +252,32 @@ class Setup {
|
||||
|
||||
// check for outdated haxe
|
||||
final curHaxeVer = [for(v in haxeVer.split(".")) Std.parseInt(v)];
|
||||
final minumumVersion = [4, 2, 5];
|
||||
final minumumVersion = [4, 3, 7];
|
||||
for(i in 0...minumumVersion.length) {
|
||||
if (curHaxeVer[i] > minumumVersion[i]) break;
|
||||
if (curHaxeVer[i] < minumumVersion[i]) {
|
||||
prettyPrint([
|
||||
"!! WARNING !!",
|
||||
"Your current Haxe version is outdated.",
|
||||
'You\'re using ${haxeVer}, whilst the required version is 4.2.5 or newer.',
|
||||
'You\'re using ${haxeVer}, whilst the required version is 4.3.7 or newer.',
|
||||
'The engine may not compile with your current version of Haxe.',
|
||||
'We recommend upgrading to 4.2.5 or newer'
|
||||
'We recommend upgrading to 4.3.7 or newer'
|
||||
].join("\n"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// vswhere.exe its used to find any visual studio related installations on the system, including full visual studio ide installations, visual studio build tools installations, and other related components - Nex
|
||||
if (CHECK_VSTUDIO && Compiler.getBuildTarget().toLowerCase() == "windows" && new Process('"C:/Program Files (x86)/Microsoft Visual Studio/Installer/vswhere.exe" -property catalog_productDisplayVersion').exitCode(true) == 1) {
|
||||
// vswhere.exe is used to find any visual studio related installations on the system, including full visual studio ide installations, visual studio build tools installations, and other related components - Nex
|
||||
if (CHECK_VSTUDIO && Compiler.getBuildTarget().toLowerCase() == "windows" && new Process('"C:/Program Files (x86)/Microsoft Visual Studio/Installer/vswhere.exe" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -requires Microsoft.VisualStudio.Component.Windows10SDK.19041 -property installationPath').exitCode(true) != 0) {
|
||||
prettyPrint("Installing Microsoft Visual Studio Community (Dependency)");
|
||||
|
||||
// thanks to @crowplexus for these two lines! - Nex
|
||||
command("curl -# -O https://download.visualstudio.microsoft.com/download/pr/3105fcfe-e771-41d6-9a1c-fc971e7d03a7/8eb13958dc429a6e6f7e0d6704d43a55f18d02a253608351b6bf6723ffdaf24e/vs_Community.exe");
|
||||
command("vs_Community.exe --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.Windows10SDK.19041 -p");
|
||||
|
||||
FileSystem.deleteFile("vs_Community.exe");
|
||||
prettyPrint('If it didn\'t say it before: Because of this component if you want to compile you have to restart the device.');
|
||||
|
||||
prettyPrint("Because of this component, if you want to compile, you need to restart the device.");
|
||||
Sys.print("Do you wish to do it now [y/n]? ");
|
||||
if(Sys.stdin().readLine().toLowerCase() == "y") command("shutdown /r /t 0 /f");
|
||||
}
|
||||
|
||||
+12
-11
@@ -3,19 +3,16 @@
|
||||
<!-- _________________________ Application Settings _________________________ -->
|
||||
<app
|
||||
title="Friday Night Funkin' - Codename Engine" main="funkin.backend.system.Main"
|
||||
file="CodenameEngine" packageName="com.yoshman29.codenameengine"
|
||||
package="com.yoshman29.codenameengine"
|
||||
version="1.0.1" company="Yoshman29" />
|
||||
file="CodenameEngine" packageName="com.codenamecrew.codenameengine"
|
||||
package="com.codenamecrew.codenameengine"
|
||||
version="1.0.1" company="CodenameCrew" />
|
||||
|
||||
<!--
|
||||
CHANGE THE SAVE PATH & NAME FOR YOUR MOD HERE!
|
||||
CHANGE THE SAVE PATH & NAME FOR YOUR HARDCODED MOD HERE!
|
||||
-->
|
||||
<haxedef name="SAVE_PATH" value="CodenameEngine"/>
|
||||
<haxedef name="SAVE_PATH" value="CodenameCrew/CodenameEngine"/>
|
||||
<haxedef name="SAVE_NAME" value="save-default"/>
|
||||
|
||||
<haxedef name="SAVE_OPTIONS_PATH" value="CodenameEngine"/>
|
||||
<haxedef name="SAVE_OPTIONS_NAME" value="options"/>
|
||||
|
||||
<!--Switch Export with Unique ApplicationID and Icon-->
|
||||
<set name="APP_ID" value="0x0100f6c013bbc000" />
|
||||
|
||||
@@ -50,7 +47,7 @@
|
||||
<!-- _________________________________ Engine Settings _______________________________ -->
|
||||
|
||||
<!-- Comment this out to disable updates !-->
|
||||
<define name="UPDATE_CHECKING" unless="web || hl || neko"/>
|
||||
<define name="UPDATE_CHECKING" unless="web || hl || neko || debug"/>
|
||||
|
||||
<!-- Comment this out to disable Discord RPC !-->
|
||||
<section if="cpp">
|
||||
@@ -131,6 +128,7 @@
|
||||
<haxelib name="away3d" if="THREE_D_SUPPORT" />
|
||||
<haxelib name="format" />
|
||||
<haxelib name="flxanimate" />
|
||||
<haxelib name="bin-serializer" />
|
||||
<haxelib name="nape-haxe4" if="NAPE_ENABLED"/>
|
||||
|
||||
<haxelib name="hscript-improved" />
|
||||
@@ -166,8 +164,8 @@
|
||||
|
||||
<!-- OpenAL config -->
|
||||
<section if="desktop">
|
||||
<assets path="alsoft.txt" rename="plugins/alsoft.ini" type="text" if="windows"/>
|
||||
<assets path="alsoft.txt" rename="plugins/alsoft.conf" type="text" unless="windows"/>
|
||||
<assets path="building/alsoft.txt" rename="plugins/alsoft.ini" type="text" if="windows"/>
|
||||
<assets path="building/alsoft.txt" rename="plugins/alsoft.conf" type="text" unless="windows"/>
|
||||
</section>
|
||||
|
||||
<!-- ______________________________ Haxedefines _____________________________ -->
|
||||
@@ -189,6 +187,9 @@
|
||||
<haxedef name="USE_ADAPTED_ASSETS" if="USE_ADAPTED_ASSETS" />
|
||||
<haxedef name="openfl_dpi_aware" if="openfl_dpi_aware" />
|
||||
|
||||
<!-- Disable it for more concise compilation errors. -->
|
||||
<haxedef name="message.reporting" value="pretty" />
|
||||
|
||||
<!-- _________________________________ Custom _______________________________ -->
|
||||
|
||||
<!--Place custom nodes like icons here (higher priority to override the HaxeFlixel icon)-->
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
{ }:
|
||||
let
|
||||
pkgs = import (builtins.fetchTarball {
|
||||
url = "https://github.com/NixOS/nixpkgs/archive/c407032be28ca2236f45c49cfb2b8b3885294f7f.tar.gz";
|
||||
}) { };
|
||||
|
||||
libs =
|
||||
with pkgs;
|
||||
[
|
||||
SDL2
|
||||
pkg-config
|
||||
openal
|
||||
alsa-lib
|
||||
libvlc
|
||||
libpulseaudio
|
||||
libGL
|
||||
]
|
||||
++ (with xorg; [
|
||||
libX11
|
||||
libXext
|
||||
libXinerama
|
||||
libXi
|
||||
libXrandr
|
||||
]);
|
||||
in
|
||||
pkgs.mkShell {
|
||||
name = "CodenameEngine";
|
||||
|
||||
packages = with pkgs; [
|
||||
haxe
|
||||
neko
|
||||
libsForQt5.qttools
|
||||
];
|
||||
|
||||
buildInputs = libs;
|
||||
|
||||
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath libs;
|
||||
|
||||
shellHook = ''
|
||||
source update.sh
|
||||
'';
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import flixel.math.FlxMath;
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.system.FlxAssets.FlxSoundAsset;
|
||||
import flixel.tweens.FlxTween;
|
||||
import flixel.util.FlxDestroyUtil;
|
||||
import flixel.util.FlxSignal;
|
||||
import flixel.util.FlxStringUtil;
|
||||
import flixel.FlxBasic;
|
||||
@@ -136,11 +137,18 @@ class FlxSound extends FlxBasic {
|
||||
public var radius:Float;
|
||||
|
||||
/**
|
||||
* Whether the proximity alters the pan or not
|
||||
* Whether the proximity alters the pan or not.
|
||||
* @since raltyMod
|
||||
*/
|
||||
public var proximityPan:Bool;
|
||||
|
||||
/**
|
||||
* Controls how much this object is affected by camera scrolling. `0` = no movement (e.g. a static sound),
|
||||
* This is only useful if used with proximity (Initialized once proximity is used).
|
||||
* @since raltyMod
|
||||
*/
|
||||
public var scrollFactor(default, null):FlxPoint;
|
||||
|
||||
/**
|
||||
* Stores for how much channels are in the loaded sound.
|
||||
* @since raltyMod
|
||||
@@ -302,6 +310,8 @@ class FlxSound extends FlxBasic {
|
||||
_lastTime = null;
|
||||
|
||||
if (destroySound) {
|
||||
scrollFactor = FlxDestroyUtil.put(scrollFactor);
|
||||
|
||||
if (group != null) group.remove(this);
|
||||
|
||||
if (_channel != null) {
|
||||
@@ -348,15 +358,24 @@ class FlxSound extends FlxBasic {
|
||||
|
||||
_amplitudeUpdate = true;
|
||||
|
||||
// Distance-based volume control (TODO for Ralty: REDO THIS)
|
||||
// Distance-based volume control
|
||||
if (target != null) {
|
||||
var targetPosition = target.getPosition();
|
||||
var radialMultiplier = targetPosition.distanceTo(FlxPoint.weak(x, y)) / radius;
|
||||
targetPosition.put();
|
||||
radialMultiplier = 1 - FlxMath.bound(radialMultiplier, 0, 1);
|
||||
var targetPosition = target.getPosition(), position = getPosition();
|
||||
var camera = camera;
|
||||
if (camera != null) {
|
||||
targetPosition.subtract(camera.scroll.x * target.scrollFactor.x, camera.scroll.y * target.scrollFactor.y);
|
||||
if (scrollFactor != null) position.subtract(camera.scroll.x * scrollFactor.x, camera.scroll.y * scrollFactor.y);
|
||||
else position.subtract(camera.scroll.x, camera.scroll.y);
|
||||
}
|
||||
|
||||
_volumeAdjust = radialMultiplier;
|
||||
if (proximityPan) _panAdjust = (x - target.x) / radius;
|
||||
var radialMultiplier = targetPosition.distanceTo(position) / radius;
|
||||
|
||||
// Make it so it affects the 3d position of the source and not just the panning?
|
||||
_volumeAdjust = 1 - FlxMath.bound(radialMultiplier, 0, 1);
|
||||
if (proximityPan) _panAdjust = (position.x - targetPosition.x) / radius;
|
||||
|
||||
targetPosition.put();
|
||||
position.put();
|
||||
}
|
||||
else
|
||||
_volumeAdjust = 1.0;
|
||||
@@ -536,12 +555,15 @@ class FlxSound extends FlxBasic {
|
||||
* @param Pan Whether panning should be used in addition to the volume changes.
|
||||
* @return This FlxSound instance (nice for chaining stuff together, if you're into that).
|
||||
*/
|
||||
public function proximity(x = 0.0, y = 0.0, ?targetObject:FlxObject, ?radius:Float, pan = true):FlxSound {
|
||||
public function proximity(x = 0.0, y = 0.0, ?targetObject:FlxObject, ?radius:Float, pan = true, ?scrollFactor:FlxPoint):FlxSound {
|
||||
setPosition(x, y);
|
||||
if (targetObject != null) this.target = targetObject;
|
||||
if (radius != null) this.radius = radius;
|
||||
proximityPan = pan;
|
||||
|
||||
if (this.scrollFactor == null) this.scrollFactor = FlxPoint.get(1, 1);
|
||||
if (scrollFactor != null) this.scrollFactor.copyFrom(scrollFactor);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -549,14 +571,28 @@ class FlxSound extends FlxBasic {
|
||||
* Helper function to set the coordinates of this object.
|
||||
* Sound positioning is used in conjunction with proximity/panning.
|
||||
*
|
||||
* @param x The new x position
|
||||
* @param y The new y position
|
||||
* @param x The new x position
|
||||
* @param y The new y position
|
||||
*/
|
||||
public inline function setPosition(x = 0.0, y = 0.0):Void {
|
||||
public function setPosition(x = 0.0, y = 0.0):Void {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the world position of this object.
|
||||
*
|
||||
* @param result Optional arg for the returning point.
|
||||
* @return The world position of this object.
|
||||
* @since raltyMod
|
||||
*/
|
||||
public function getPosition(?result:FlxPoint):FlxPoint {
|
||||
if (result == null)
|
||||
result = FlxPoint.get();
|
||||
|
||||
return result.set(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this function to play the sound - also works on paused sounds.
|
||||
*
|
||||
@@ -682,7 +718,7 @@ class FlxSound extends FlxBasic {
|
||||
_paused = false;
|
||||
_time = startTime;
|
||||
_lastTime = FlxG.game.getTicks();
|
||||
if (_channel == null || !_channel.__isValid || _source == null #if lime_cffi || _source.__backend.disposed || _source.__backend.handle == null #end)
|
||||
if (_channel == null || !_channel.__isValid || _source == null #if lime_cffi || _source.__backend.disposed #end)
|
||||
makeChannel();
|
||||
|
||||
if (_channel != null) {
|
||||
@@ -733,7 +769,8 @@ class FlxSound extends FlxBasic {
|
||||
_lastTime = FlxG.game.getTicks();
|
||||
_time = loopTime;
|
||||
}
|
||||
else _channel.loops = 999;
|
||||
else if (_source != null)
|
||||
_source.loops = 999;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -763,7 +800,7 @@ class FlxSound extends FlxBasic {
|
||||
}
|
||||
|
||||
inline function get_playing():Bool @:privateAccess
|
||||
return _channel != null && _channel.__isValid && _source.playing;
|
||||
return _source != null && _source.playing;
|
||||
|
||||
inline function get_volume():Float
|
||||
return _volume;
|
||||
@@ -796,12 +833,12 @@ class FlxSound extends FlxBasic {
|
||||
inline function get_buffer():AudioBuffer
|
||||
@:privateAccess return _sound != null ? _sound.__buffer : null;
|
||||
|
||||
function update_amplitude():Void @:privateAccess {
|
||||
if (_channel == null || !_channel.__updatePeaks(get_time()) || !_amplitudeUpdate) return;
|
||||
|
||||
_amplitudeUpdate = false;
|
||||
_amplitudeLeft = _channel.__leftPeak;
|
||||
_amplitudeRight = _channel.__rightPeak;
|
||||
inline function update_amplitude():Void @:privateAccess {
|
||||
if (_channel != null && _channel.__updatePeaks(get_time()) && _amplitudeUpdate) {
|
||||
_amplitudeUpdate = false;
|
||||
_amplitudeLeft = _channel.__leftPeak;
|
||||
_amplitudeRight = _channel.__rightPeak;
|
||||
}
|
||||
}
|
||||
|
||||
inline function get_amplitudeLeft():Float {
|
||||
@@ -829,30 +866,27 @@ class FlxSound extends FlxBasic {
|
||||
inline function get_pitch():Float
|
||||
return _pitch;
|
||||
|
||||
function set_pitch(v:Float):Float {
|
||||
inline function set_pitch(v:Float):Float {
|
||||
_realPitch = (_pitch = v) * _timeScaleAdjust;
|
||||
if (_channel != null) _channel.pitch = _realPitch;
|
||||
if (_source != null) _source.pitch = _realPitch;
|
||||
return _pitch;
|
||||
}
|
||||
#end
|
||||
|
||||
function set_looped(v:Bool):Bool {
|
||||
if (playing) {
|
||||
if (v) _channel.loops = 999;
|
||||
else _channel.loops = 0;
|
||||
}
|
||||
if (playing) _source.loops = v ? 999 : 0;
|
||||
return looped = v;
|
||||
}
|
||||
|
||||
function set_loopTime(v:Float):Float {
|
||||
if (playing) _channel.loopTime = v;
|
||||
if (playing) _source.loopTime = v;
|
||||
return loopTime = v;
|
||||
}
|
||||
|
||||
function set_endTime(v:Null<Float>):Null<Float> {
|
||||
if (playing) {
|
||||
if (v != null && v > 0 && v < _length) _channel.endTime = v;
|
||||
else _channel.endTime = null;
|
||||
if (v != null && v > 0 && v < _length) _source.length = v;
|
||||
else _source.length = null;
|
||||
}
|
||||
return endTime = v;
|
||||
}
|
||||
@@ -864,7 +898,7 @@ class FlxSound extends FlxBasic {
|
||||
return _time;
|
||||
}
|
||||
function get_time():Float {
|
||||
if (_channel == null || @:privateAccess !_channel.__isValid || /*AudioManager.context == null*/funkin.backend.system.Main.audioDisconnected) return _time;
|
||||
if (_source == null || /*AudioManager.context == null*/funkin.backend.system.Main.audioDisconnected) return _time;
|
||||
|
||||
final sourceTime = _source.currentTime - _source.offset - _offset;
|
||||
if (!_source.playing || _realPitch <= 0) {
|
||||
@@ -903,24 +937,21 @@ class FlxSound extends FlxBasic {
|
||||
return _time = time;
|
||||
}
|
||||
|
||||
inline function get_offset():Float return _offset;
|
||||
inline function set_offset(offset:Float):Float {
|
||||
function get_offset():Float return _offset;
|
||||
function set_offset(offset:Float):Float {
|
||||
if (_offset == (_offset = offset)) return offset;
|
||||
//time = time + _offset;
|
||||
return offset;
|
||||
}
|
||||
|
||||
inline function get_length():Float return _length - _offset;
|
||||
function get_length():Float return _length - _offset;
|
||||
|
||||
/*function get_latency():Float {
|
||||
if (_channel != null) return _source.latency;
|
||||
return 0;
|
||||
}*/
|
||||
//function get_latency():Float return _source != null ? _source.latency : 0;
|
||||
|
||||
override function toString():String {
|
||||
return FlxStringUtil.getDebugString([
|
||||
LabelValuePair.weak("playing", playing),
|
||||
LabelValuePair.weak("time", _time),
|
||||
LabelValuePair.weak("time", time),
|
||||
LabelValuePair.weak("length", length),
|
||||
LabelValuePair.weak("volume", volume),
|
||||
LabelValuePair.weak("pitch", pitch)
|
||||
|
||||
@@ -70,6 +70,8 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
@:noCompletion public var atlasPlayingAnim:String;
|
||||
@:noCompletion public var atlasPath:String;
|
||||
|
||||
var _rect2:FlxRect;
|
||||
|
||||
public function new(?X:Float = 0, ?Y:Float = 0, ?SimpleGraphic:FlxGraphicAsset)
|
||||
{
|
||||
super(X, Y);
|
||||
@@ -112,6 +114,7 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
spr.transformMatrix = casted.transformMatrix;
|
||||
spr.matrixExposed = casted.matrixExposed;
|
||||
spr.animOffsets = casted.animOffsets.copy();
|
||||
spr.zoomFactor = casted.zoomFactor;
|
||||
}
|
||||
}
|
||||
return spr;
|
||||
@@ -126,11 +129,16 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
// hate how it looks like but hey at least its optimized and fast - Nex
|
||||
if (!debugMode && isAnimFinished()) {
|
||||
var name = getAnimName() + '-loop';
|
||||
if (hasAnimation(name))
|
||||
if (hasAnim(name))
|
||||
playAnim(name, null, lastAnimContext);
|
||||
}
|
||||
}
|
||||
|
||||
override function initVars() {
|
||||
super.initVars();
|
||||
_rect2 = FlxRect.get();
|
||||
}
|
||||
|
||||
public function loadSprite(path:String, Unique:Bool = false, Key:String = null)
|
||||
{
|
||||
var noExt = Path.withoutExtension(path);
|
||||
@@ -226,6 +234,8 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
animOffsets = null;
|
||||
}
|
||||
super.destroy();
|
||||
|
||||
_rect2 = FlxDestroyUtil.put(_rect2);
|
||||
}
|
||||
#end
|
||||
|
||||
@@ -233,27 +243,40 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
private inline function __shouldDoZoomFactor()
|
||||
return zoomFactorEnabled && zoomFactor != 1;
|
||||
|
||||
private inline function __prepareZoomFactor(?rect:FlxRect, camera:FlxCamera):FlxRect {
|
||||
if (Flags.USE_LEGACY_ZOOM_FACTOR)
|
||||
return (rect ?? FlxRect.get()).set(
|
||||
camera.width * 0.5,
|
||||
camera.height * 0.5,
|
||||
(camera.scaleX > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.scaleX, 1, zoomFactor)),
|
||||
(camera.scaleY > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.scaleY, 1, zoomFactor))
|
||||
);
|
||||
else
|
||||
return (rect ?? FlxRect.get()).set(
|
||||
camera.width * 0.5 + camera.scroll.x * scrollFactor.x,
|
||||
camera.height * 0.5 + camera.scroll.y * scrollFactor.y,
|
||||
(camera.scaleX > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.scaleX, 1, zoomFactor)),
|
||||
(camera.scaleY > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.scaleY, 1, zoomFactor))
|
||||
);
|
||||
}
|
||||
|
||||
public override function getScreenBounds(?newRect:FlxRect, ?camera:FlxCamera):FlxRect
|
||||
{
|
||||
if (camera == null)
|
||||
camera = FlxG.camera;
|
||||
|
||||
var r = super.getScreenBounds(newRect, camera);
|
||||
newRect = super.getScreenBounds(newRect, camera);
|
||||
|
||||
if(__shouldDoZoomFactor()) {
|
||||
r.x -= camera.width / 2;
|
||||
r.y -= camera.height / 2;
|
||||
|
||||
var ratio = (camera.zoom > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.zoom, 1, zoomFactor));
|
||||
r.x *= ratio;
|
||||
r.y *= ratio;
|
||||
r.width *= ratio;
|
||||
r.height *= ratio;
|
||||
|
||||
r.x += camera.width / 2;
|
||||
r.y += camera.height / 2;
|
||||
__prepareZoomFactor(_rect2, camera);
|
||||
newRect.set(
|
||||
(newRect.x - _rect2.x) * _rect2.width + _rect2.x,
|
||||
(newRect.y - _rect2.y) * _rect2.height + _rect2.y,
|
||||
newRect.width * _rect2.width,
|
||||
newRect.height * _rect2.height,
|
||||
);
|
||||
}
|
||||
return r;
|
||||
return newRect;
|
||||
}
|
||||
|
||||
override public function isOnScreen(?camera:FlxCamera):Bool
|
||||
@@ -273,14 +296,16 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
// ZOOM FACTOR RENDERING
|
||||
public override function doAdditionalMatrixStuff(matrix:FlxMatrix, camera:FlxCamera)
|
||||
{
|
||||
super.doAdditionalMatrixStuff(matrix, camera);
|
||||
// no need to...
|
||||
//super.doAdditionalMatrixStuff(matrix, camera);
|
||||
if(__shouldDoZoomFactor()) {
|
||||
matrix.translate(-camera.width / 2, -camera.height / 2);
|
||||
|
||||
var requestedZoom = (camera.zoom >= 0 ? Math.max : Math.min)(FlxMath.lerp(1, camera.zoom, zoomFactor), 0);
|
||||
var diff = requestedZoom / camera.zoom;
|
||||
matrix.scale(diff, diff);
|
||||
matrix.translate(camera.width / 2, camera.height / 2);
|
||||
__prepareZoomFactor(_rect, camera);
|
||||
matrix.setTo(
|
||||
matrix.a * _rect.width, matrix.b * _rect.height,
|
||||
matrix.c * _rect.width, matrix.d * _rect.height,
|
||||
(matrix.tx - _rect.x) * _rect.width + _rect.x,
|
||||
(matrix.ty - _rect.y) * _rect.height + _rect.y,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,7 +332,7 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
|
||||
public function playAnim(AnimName:String, ?Force:Null<Bool>, Context:PlayAnimContext = NONE, Reversed:Bool = false, Frame:Int = 0):Void
|
||||
{
|
||||
if (AnimName == null)
|
||||
if (AnimName == null || (!hasAnim(AnimName) && !debugMode))
|
||||
return;
|
||||
|
||||
if (Force == null) {
|
||||
@@ -318,16 +343,10 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
if (animateAtlas != null)
|
||||
{
|
||||
@:privateAccess
|
||||
// if (!animateAtlas.anim.animsMap.exists(AnimName) && !animateAtlas.anim.symbolDictionary.exists(AnimName)) return;
|
||||
animateAtlas.anim.play(AnimName, Force, Reversed, Frame);
|
||||
atlasPlayingAnim = AnimName;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!animation.exists(AnimName) && !debugMode)
|
||||
return;
|
||||
animation.play(AnimName, Force, Reversed, Frame);
|
||||
}
|
||||
else animation.play(AnimName, Force, Reversed, Frame);
|
||||
|
||||
var daOffset = getAnimOffset(AnimName);
|
||||
frameOffset.set(daOffset.x, daOffset.y);
|
||||
@@ -414,9 +433,9 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
}
|
||||
|
||||
// Backwards compat (the names used to be all different and it sucked, please lets use the same format in the future) - Nex
|
||||
public inline function hasAnimation(AnimName:String) return hasAnim(AnimName);
|
||||
public inline function removeAnimation(name:String) return removeAnim(name);
|
||||
public inline function stopAnimation() return stopAnim();
|
||||
@:dox(hide) public inline function hasAnimation(AnimName:String) return hasAnim(AnimName);
|
||||
@:dox(hide) public inline function removeAnimation(name:String) return removeAnim(name);
|
||||
@:dox(hide) public inline function stopAnimation() return stopAnim();
|
||||
#end
|
||||
|
||||
// Getter / Setters
|
||||
|
||||
@@ -2,11 +2,14 @@ package funkin.backend;
|
||||
|
||||
import flixel.text.FlxText;
|
||||
import flixel.util.FlxColor;
|
||||
import funkin.backend.system.Flags;
|
||||
|
||||
class FunkinText extends FlxText {
|
||||
public function new(X:Float = 0, Y:Float = 0, FieldWidth:Float = 0, ?Text:String, Size:Int = 16, Border:Bool = true) {
|
||||
public function new(X:Float = 0, Y:Float = 0, FieldWidth:Float = 0, ?Text:String, ?Size:Int, Border:Bool = true) {
|
||||
if (Size == null) Size = Flags.DEFAULT_FONT_SIZE;
|
||||
|
||||
super(X, Y, FieldWidth, Text, Size);
|
||||
setFormat(Paths.font("vcr.ttf"), Size, FlxColor.WHITE);
|
||||
setFormat(Paths.font(Flags.DEFAULT_FONT), Size, FlxColor.WHITE);
|
||||
if (Border) {
|
||||
borderStyle = OUTLINE;
|
||||
borderSize = 1;
|
||||
|
||||
@@ -275,6 +275,12 @@ class MusicBeatState extends FlxState implements IBeatCancellableReceiver
|
||||
if (!e.cancelled)
|
||||
super.openSubState(e.substate is FlxSubState ? cast e.substate : subState);
|
||||
}
|
||||
|
||||
public override function closeSubState() {
|
||||
var e = event("onCloseSubState", EventManager.get(StateEvent).recycle(subState));
|
||||
if (!e.cancelled)
|
||||
super.closeSubState();
|
||||
}
|
||||
|
||||
public override function onResize(w:Int, h:Int) {
|
||||
super.onResize(w, h);
|
||||
|
||||
@@ -236,6 +236,12 @@ class MusicBeatSubstate extends FlxSubState implements IBeatCancellableReceiver
|
||||
super.openSubState(e.substate is FlxSubState ? cast e.substate : subState);
|
||||
}
|
||||
|
||||
public override function closeSubState() {
|
||||
var e = event("onCloseSubState", EventManager.get(StateEvent).recycle(subState));
|
||||
if (!e.cancelled)
|
||||
super.closeSubState();
|
||||
}
|
||||
|
||||
public override function onResize(w:Int, h:Int) {
|
||||
super.onResize(w, h);
|
||||
event("onResize", EventManager.get(ResizeEvent).recycle(w, h, null, null));
|
||||
|
||||
@@ -97,6 +97,41 @@ class Chart {
|
||||
data.setFieldDefault("vocalsSuffix", "");
|
||||
data.setFieldDefault("needsVoices", true);
|
||||
data.setFieldDefault("difficulties", []);
|
||||
|
||||
var songNameLower = songName.toLowerCase();
|
||||
var metaPath = Paths.file('songs/${songNameLower}/meta.json');
|
||||
var metaDiffPath = Paths.file('songs/${songNameLower}/meta-${difficulty.toLowerCase()}.json');
|
||||
|
||||
var blacklist:Array<String> = [];
|
||||
var data:ChartMetaData = null;
|
||||
var fromMods:Bool = fromMods;
|
||||
for (path in [metaDiffPath, metaPath]) {
|
||||
if (Assets.exists(path)) {
|
||||
fromMods = Paths.assetsTree.existsSpecific(path, "TEXT", MODS);
|
||||
try {
|
||||
var temp = CoolUtil.parseJson(path);
|
||||
|
||||
// Backwards compatibility (they both can be null so != true) - Nex
|
||||
var coopExlc = false;
|
||||
if (Reflect.hasField(temp, "coopAllowed") && Reflect.field(temp, "coopAllowed") != true) {
|
||||
blacklist = blacklist.concat(["codename.coop", "codename.coop-opponent"]);
|
||||
Reflect.deleteField(temp, "coopAllowed");
|
||||
coopExlc = true;
|
||||
}
|
||||
if (Reflect.hasField(temp, "opponentModeAllowed") && Reflect.field(temp, "opponentModeAllowed") != true) {
|
||||
if (!coopExlc) blacklist.push("codename.coop-opponent");
|
||||
blacklist.push("codename.opponent");
|
||||
Reflect.deleteField(temp, "opponentModeAllowed");
|
||||
}
|
||||
|
||||
data = temp;
|
||||
} catch(e) {
|
||||
Logs.trace('Failed to load song metadata for ${songName} ($path): ${Std.string(e)}', ERROR);
|
||||
}
|
||||
if (data != null) break;
|
||||
}
|
||||
}
|
||||
data.setFieldDefault("excludedGameModes", blacklist);
|
||||
data.setFieldDefault("variants", []);
|
||||
data.setFieldDefault("metas", []);
|
||||
|
||||
@@ -222,7 +257,7 @@ class Chart {
|
||||
}
|
||||
#end
|
||||
|
||||
var loadedMeta = loadChartMeta(songName, variant, base.fromMods, false);
|
||||
var loadedMeta = loadChartMeta(songName, variant, difficulty, base.fromMods, false);
|
||||
if (base.meta == null) base.meta = loadedMeta;
|
||||
else {
|
||||
for (field in Reflect.fields(base.meta)) {
|
||||
@@ -300,6 +335,7 @@ class Chart {
|
||||
var eventsPath = '$songPath/events$variantSuffix.json', events = filterEventsForSaving(chart.events, false, true);
|
||||
|
||||
if (events.length != 0) CoolUtil.safeSaveFile(eventsPath, Json.stringify({events: events}, null, prettyPrint));
|
||||
else if (FileSystem.exists(eventsPath)) FileSystem.deleteFile(eventsPath); // If there's no events to save, then get rid of the file (if it exists already).
|
||||
}
|
||||
#end
|
||||
|
||||
|
||||
@@ -32,8 +32,7 @@ typedef ChartMetaData = {
|
||||
public var ?icon:String;
|
||||
public var ?color:FlxColor;
|
||||
|
||||
public var ?coopAllowed:Bool;
|
||||
public var ?opponentModeAllowed:Bool;
|
||||
public var ?excludedGameModes:Array<String>;
|
||||
|
||||
public var ?metas:Map<String, ChartMetaData>;
|
||||
public var ?instSuffix:String;
|
||||
|
||||
@@ -164,8 +164,10 @@ class EventsData {
|
||||
|
||||
if (fileTxt.trim() == "") continue;
|
||||
|
||||
eventsList.push(eventName);
|
||||
eventsParams.set(eventName, []);
|
||||
if (!eventsList.contains(eventName)) {
|
||||
eventsList.push(eventName);
|
||||
eventsParams.set(eventName, []);
|
||||
}
|
||||
|
||||
try {
|
||||
var data:EventInfoFile = cast Json.parse(fileTxt);
|
||||
@@ -177,7 +179,8 @@ class EventsData {
|
||||
finalParams.push({
|
||||
name: paramData.name,
|
||||
type: hscriptInterp.expr(hscriptParser.parseString(paramData.type)),
|
||||
defValue: paramData.defaultValue
|
||||
defValue: paramData.defaultValue,
|
||||
saveIfDefault: paramData.saveIfDefault
|
||||
});
|
||||
} catch (e) {trace('Error parsing event param ${paramData.name} - ${eventName}: $e'); finalParams.push(null);}
|
||||
}
|
||||
@@ -194,6 +197,7 @@ typedef EventInfoFile = {
|
||||
var name:String;
|
||||
var type:String;
|
||||
var defaultValue:Dynamic;
|
||||
var ?saveIfDefault:Bool;
|
||||
}>;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ class PsychParser {
|
||||
note.time, // TIME
|
||||
note.id, // DATA
|
||||
note.sLen, // SUSTAIN LENGTH
|
||||
chart.noteTypes.getDefault([""])[note.type] // NOTE TYPE
|
||||
chart.noteTypes.getDefault([""])[note.type - 1] // NOTE TYPE
|
||||
];
|
||||
|
||||
if ((swagSection.mustHitSection && strumLine.type == OPPONENT) ||
|
||||
|
||||
@@ -55,9 +55,6 @@ class GlobalScript {
|
||||
reloading = false;
|
||||
MusicBeatState.ALLOW_DEV_RELOAD = _lastAllow_Reload;
|
||||
}
|
||||
|
||||
if (PlayerSettings.solo.controls.DEV_CONSOLE)
|
||||
NativeAPI.allocConsole();
|
||||
});
|
||||
FlxG.signals.preDraw.add(function() {
|
||||
call("preDraw");
|
||||
@@ -106,20 +103,8 @@ class GlobalScript {
|
||||
});
|
||||
}
|
||||
|
||||
public static function event<T:CancellableEvent>(name:String, event:T):T {
|
||||
if (scripts != null)
|
||||
scripts.event(name, event);
|
||||
return event;
|
||||
}
|
||||
|
||||
public static function call(name:String, ?args:Array<Dynamic>) {
|
||||
if (scripts != null)
|
||||
scripts.call(name, args);
|
||||
}
|
||||
|
||||
public static function onModSwitch(newMod:String) {
|
||||
call("destroy");
|
||||
scripts = FlxDestroyUtil.destroy(scripts);
|
||||
destroy();
|
||||
scripts = new ScriptPack("GlobalScript");
|
||||
for (i in funkin.backend.assets.ModsFolder.getLoadedMods()) {
|
||||
var path = Paths.script('data/global/LIB_$i');
|
||||
@@ -132,12 +117,24 @@ class GlobalScript {
|
||||
}
|
||||
}
|
||||
|
||||
public static function beatHit(curBeat:Int) {
|
||||
call("beatHit", [curBeat]);
|
||||
public static inline function event<T:CancellableEvent>(name:String, event:T):T {
|
||||
if (scripts != null)
|
||||
scripts.event(name, event);
|
||||
return event;
|
||||
}
|
||||
|
||||
public static function stepHit(curStep:Int) {
|
||||
public static inline function call(name:String, ?args:Array<Dynamic>)
|
||||
if (scripts != null) scripts.call(name, args);
|
||||
|
||||
public static inline function beatHit(curBeat:Int)
|
||||
call("beatHit", [curBeat]);
|
||||
|
||||
public static inline function stepHit(curStep:Int)
|
||||
call("stepHit", [curStep]);
|
||||
|
||||
public static inline function destroy() if (scripts != null) {
|
||||
call("destroy");
|
||||
scripts = FlxDestroyUtil.destroy(scripts);
|
||||
}
|
||||
}
|
||||
#end
|
||||
@@ -34,6 +34,7 @@ class HScript extends Script {
|
||||
__importedPaths = [path];
|
||||
|
||||
interp.errorHandler = _errorHandler;
|
||||
interp.warnHandler = _warnHandler;
|
||||
interp.importFailedCallback = importFailedCallback;
|
||||
interp.staticVariables = Script.staticVariables;
|
||||
interp.allowStaticVariables = interp.allowPublicVariables = true;
|
||||
@@ -63,7 +64,7 @@ class HScript extends Script {
|
||||
return this;
|
||||
}
|
||||
|
||||
private function importFailedCallback(cl:Array<String>):Bool {
|
||||
private function importFailedCallback(cl:Array<String>, ?asName:String):Bool {
|
||||
if(_importFailedCallback(cl, "source/") || _importFailedCallback(cl, "")) {
|
||||
return true;
|
||||
}
|
||||
@@ -117,6 +118,24 @@ class HScript extends Script {
|
||||
], ERROR);
|
||||
}
|
||||
|
||||
private function _warnHandler(error:Error) {
|
||||
var fileName = error.origin;
|
||||
var oldfn = '$fileName:${error.line}: ';
|
||||
if(remappedNames.exists(fileName))
|
||||
fileName = remappedNames.get(fileName);
|
||||
var fn = '$fileName:${error.line}: ';
|
||||
var err = error.toString();
|
||||
while(err.startsWith(oldfn) || err.startsWith(fn)) {
|
||||
if (err.startsWith(oldfn)) err = err.substr(oldfn.length);
|
||||
if (err.startsWith(fn)) err = err.substr(fn.length);
|
||||
}
|
||||
|
||||
Logs.traceColored([
|
||||
Logs.logText(fn, GREEN),
|
||||
Logs.logText(err, YELLOW)
|
||||
], WARNING);
|
||||
}
|
||||
|
||||
public override function setParent(parent:Dynamic) {
|
||||
interp.scriptObject = parent;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
package funkin.backend.scripting;
|
||||
|
||||
#if ALLOW_MULTITHREADING
|
||||
import sys.thread.Thread;
|
||||
#end
|
||||
|
||||
import hscript.IHScriptCustomBehaviour;
|
||||
|
||||
class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBehaviour {
|
||||
var thread:#if ALLOW_MULTITHREADING Thread #else Dynamic #end;
|
||||
|
||||
/**
|
||||
* Script being ran.
|
||||
*/
|
||||
@@ -46,13 +40,6 @@ class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBe
|
||||
|
||||
script.load();
|
||||
|
||||
#if ALLOW_MULTITHREADING
|
||||
thread = Thread.createWithEventLoop(function() {
|
||||
// Prevent the thread from being auto deleted
|
||||
Thread.current().events.promise();
|
||||
});
|
||||
#end
|
||||
|
||||
__variables = Type.getInstanceFields(Type.getClass(this));
|
||||
}
|
||||
|
||||
@@ -69,7 +56,7 @@ class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBe
|
||||
|
||||
public function call(func:String, args:Array<Dynamic>) {
|
||||
#if ALLOW_MULTITHREADING
|
||||
thread.events.run(function() {
|
||||
funkin.backend.utils.ThreadUtil.execAsync(() -> {
|
||||
callEnded = false;
|
||||
returnValue = script.call(func, args);
|
||||
callEnded = true;
|
||||
@@ -85,13 +72,5 @@ class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBe
|
||||
script.call("destroy");
|
||||
script.destroy();
|
||||
}
|
||||
|
||||
#if ALLOW_MULTITHREADING
|
||||
if (thread != null) {
|
||||
thread.events.runPromised(function() {
|
||||
// close the thing
|
||||
});
|
||||
}
|
||||
#end
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,11 @@ class Script extends FlxBasic implements IFlxDestroyable {
|
||||
"Reflect" => Reflect,
|
||||
"StringTools" => StringTools,
|
||||
"Json" => haxe.Json,
|
||||
"Xml" => Xml,
|
||||
"Type" => Type,
|
||||
"Date" => Date,
|
||||
"Lambda" => Lambda,
|
||||
#if sys "Sys" => Sys, #end
|
||||
|
||||
// OpenFL & Lime related stuff
|
||||
"Assets" => openfl.utils.Assets,
|
||||
@@ -89,6 +94,7 @@ class Script extends FlxBasic implements IFlxDestroyable {
|
||||
"FlxAnimate" => funkin.backend.FlxAnimate,
|
||||
"FunkinSprite" => funkin.backend.FunkinSprite,
|
||||
"Alphabet" => funkin.menus.ui.Alphabet,
|
||||
"Flags" => funkin.backend.system.Flags,
|
||||
|
||||
"CoolUtil" => funkin.backend.utils.CoolUtil,
|
||||
"IniUtil" => funkin.backend.utils.IniUtil,
|
||||
@@ -96,6 +102,7 @@ class Script extends FlxBasic implements IFlxDestroyable {
|
||||
#if sys "ZipUtil" => funkin.backend.utils.ZipUtil, #end
|
||||
"MarkdownUtil" => funkin.backend.utils.MarkdownUtil,
|
||||
"EngineUtil" => funkin.backend.utils.EngineUtil,
|
||||
"ThreadUtil" => funkin.backend.utils.ThreadUtil,
|
||||
"MemoryUtil" => funkin.backend.utils.MemoryUtil,
|
||||
"BitmapUtil" => funkin.backend.utils.BitmapUtil,
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package funkin.backend.scripting.events.menu.freeplay;
|
||||
|
||||
import funkin.menus.FreeplayState.FreeplayGameMode;
|
||||
|
||||
final class FreeplaySongSelectEvent extends CancellableEvent {
|
||||
/**
|
||||
* Song name that is about to be played
|
||||
@@ -14,11 +16,26 @@ final class FreeplaySongSelectEvent extends CancellableEvent {
|
||||
*/
|
||||
public var variant:String;
|
||||
/**
|
||||
* Whenever opponent mode is enabled or not.
|
||||
* Used game mode's data.
|
||||
*/
|
||||
public var opponentMode:Bool;
|
||||
/**
|
||||
* Whenever coop mode is enabled.
|
||||
*/
|
||||
public var coopMode:Bool;
|
||||
public var gameMode:FreeplayGameMode;
|
||||
|
||||
|
||||
// Backwards compat
|
||||
@:noCompletion public var opponentMode(get, set):Bool;
|
||||
@:noCompletion private function get_opponentMode() return gameMode.modeID == "codename.opponent" || gameMode.modeID == "codename.coop-opponent";
|
||||
@:noCompletion private function set_opponentMode(val:Bool) {
|
||||
gameMode = coopMode ?
|
||||
(val ? new FreeplayGameMode("Co-Op Mode (Switched)", "codename.coop-opponent", ["coop-switched", "opponent", "coop"]) : new FreeplayGameMode("Opponent Mode", "codename.opponent", ["opponent"])) :
|
||||
(val ? new FreeplayGameMode("Opponent Mode", "codename.opponent", ["opponent"]) : null);
|
||||
return val;
|
||||
}
|
||||
@:noCompletion public var coopMode(get, set):Bool;
|
||||
@:noCompletion private function get_coopMode() return gameMode.modeID == "codename.coop" || gameMode.modeID == "codename.coop-opponent";
|
||||
@:noCompletion private function set_coopMode(val:Bool) {
|
||||
gameMode = opponentMode ?
|
||||
(val ? new FreeplayGameMode("Co-Op Mode (Switched)", "codename.coop-opponent", ["coop-switched", "opponent", "coop"]) : new FreeplayGameMode("Co-Op Mode", "codename.coop", ["coop"])) :
|
||||
(val ? new FreeplayGameMode("Co-Op Mode", "codename.coop", ["coop"]) : null);
|
||||
return val;
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ final class NoteHitEvent extends CancellableEvent {
|
||||
@:dox(hide) public var unmuteVocals:Bool = true;
|
||||
@:dox(hide) public var enableCamZooming:Bool = true;
|
||||
@:dox(hide) public var autoHitLastSustain:Bool = true;
|
||||
@:dox(hide) public var clipSustain:Bool = true;
|
||||
|
||||
/**
|
||||
* Whenever a miss should be added.
|
||||
@@ -145,6 +146,13 @@ final class NoteHitEvent extends CancellableEvent {
|
||||
deleteNote = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents the sustain from being cut. Only works if the note is a sustain.
|
||||
*/
|
||||
public function preventSustainClip() {
|
||||
clipSustain = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents the vocals volume from being set to 1 after pressing the note.
|
||||
*/
|
||||
|
||||
@@ -30,6 +30,8 @@ class ScriptableShader extends FlxBasic implements IHScriptCustomBehaviour {
|
||||
if((shader is CustomShader)) scriptName = cast(shader, CustomShader).fileName;
|
||||
else throw "Missing name for shader script, please provide a scriptName, or use CustomShader";
|
||||
|
||||
this.shader = shader;
|
||||
|
||||
script = Script.create(Paths.script('shaders/$scriptName'));
|
||||
script.setParent(shader);
|
||||
script.set("shader", shader);
|
||||
|
||||
@@ -25,6 +25,7 @@ enum Control
|
||||
CHANGE_MODE;
|
||||
//CHEAT;
|
||||
SWITCHMOD;
|
||||
FPS_COUNTER;
|
||||
|
||||
// Debugs
|
||||
DEV_ACCESS;
|
||||
@@ -161,6 +162,11 @@ class Controls extends FlxActionSet
|
||||
@:pressed("switchmod") public var SWITCHMOD_HOLD(get, set): Bool;
|
||||
@:justReleased("switchmod") public var SWITCHMOD_R(get, set): Bool;
|
||||
|
||||
@:gamepad([])
|
||||
@:justPressed("fps-counter") public var FPS_COUNTER(get, set): Bool;
|
||||
@:pressed("fps-counter") public var FPS_COUNTER_HOLD(get, set): Bool;
|
||||
@:justReleased("fps-counter") public var FPS_COUNTER_R(get, set): Bool;
|
||||
|
||||
@:devModeOnly
|
||||
@:gamepad([])
|
||||
@:justPressed("dev-access") public var DEV_ACCESS(get, set): Bool;
|
||||
|
||||
@@ -13,16 +13,20 @@ import lime.utils.AssetType;
|
||||
/**
|
||||
* A class that reads the `flags.ini` file, allowing to read settable Flags (customs too).
|
||||
*/
|
||||
@:build(funkin.backend.system.macros.FlagMacro.build())
|
||||
@:build(funkin.backend.system.macros.FlagMacro.build("onReset"))
|
||||
class Flags {
|
||||
public static var overridenFlags:Map<String, Bool> = [];
|
||||
|
||||
// -- Codename's Addon Config --
|
||||
@:bypass public static var addonFlags:Map<String, Dynamic> = [];
|
||||
|
||||
public static var CURRENT_API_VERSION:Int = 2;
|
||||
|
||||
// -- Codename's Mod Config --
|
||||
public static var MOD_NAME:String = "";
|
||||
public static var MOD_DESCRIPTION:String = "";
|
||||
public static var MOD_AUTHOR:String = "";
|
||||
public static var MOD_API_VERSION:Int = 1;
|
||||
@:lazy public static var MOD_API_VERSION:Null<Int> = null;
|
||||
public static var MOD_DOWNLOAD_LINK:String = "";
|
||||
public static var MOD_DEPENDENCIES:Array<String> = [];
|
||||
|
||||
@@ -41,12 +45,11 @@ class Flags {
|
||||
@:lazy public static var SAVE_PATH:String = haxe.macro.Compiler.getDefine("SAVE_PATH");
|
||||
@:lazy public static var SAVE_NAME:String = haxe.macro.Compiler.getDefine("SAVE_NAME");
|
||||
|
||||
public static var CURRENT_API_VERSION:Int = 1;
|
||||
public static var COMMIT_NUMBER:Int = GitCommitMacro.commitNumber;
|
||||
public static var COMMIT_HASH:String = GitCommitMacro.commitHash;
|
||||
public static var COMMIT_MESSAGE:String = 'Commit $COMMIT_NUMBER ($COMMIT_HASH)';
|
||||
|
||||
@:bypass public static var WINDOW_TITLE_USE_MOD_NAME:Bool = false;
|
||||
@:lazy public static var WINDOW_TITLE_USE_MOD_NAME:Null<Bool> = null;
|
||||
@:lazy public static var TITLE:String = Application.current.meta.get('name');
|
||||
@:lazy public static var VERSION:String = Application.current.meta.get('version');
|
||||
|
||||
@@ -125,12 +128,16 @@ class Flags {
|
||||
@:also(funkin.game.PlayState.opponentMode)
|
||||
public static var DEFAULT_OPPONENT_MODE:Bool = false;
|
||||
|
||||
public static var USE_LEGACY_TIMING:Null<Bool> = null;
|
||||
|
||||
public static var DEFAULT_NOTE_MS_LIMIT:Float = 1500;
|
||||
public static var DEFAULT_NOTE_SCALE:Float = 0.7;
|
||||
#if MODCHARTING_FEATURES
|
||||
public static var DEFAULT_MODCHART_HOLD_SUBDIVISIONS:Int = 4;
|
||||
#end
|
||||
|
||||
public static var SUSTAINS_AS_ONE_NOTE:Null<Bool> = null;
|
||||
|
||||
@:also(funkin.game.Character.FALLBACK_DEAD_CHARACTER)
|
||||
public static var DEFAULT_GAMEOVER_CHARACTER:String = "bf-dead";
|
||||
|
||||
@@ -149,6 +156,12 @@ class Flags {
|
||||
public static var DEFAULT_CAM_ZOOM_LERP:Float = 0.05;
|
||||
public static var DEFAULT_HUD_ZOOM_LERP:Float = 0.05;
|
||||
|
||||
public static var USE_LEGACY_ZOOM_FACTOR:Null<Bool> = null;
|
||||
|
||||
// Font configuration
|
||||
public static var DEFAULT_FONT:String = "vcr.ttf";
|
||||
public static var DEFAULT_FONT_SIZE:Int = 16;
|
||||
|
||||
// to translate these you need to convert them into ids
|
||||
// Resume -> pause.resume
|
||||
// Restart Song -> pause.restart
|
||||
@@ -169,6 +182,7 @@ class Flags {
|
||||
public static var DEFAULT_HEALTH:Null<Float> = null;//DEFAULT_MAX_HEALTH / 2.0;
|
||||
public static var DEFAULT_ICONBOP:Bool = true;
|
||||
public static var BOP_ICON_SCALE:Float = 1.2;
|
||||
public static var ICON_DEFAULT_SCALE:Float = 1;
|
||||
public static var ICON_OFFSET:Float = 26;
|
||||
public static var ICON_LERP:Float = 0.33;
|
||||
|
||||
@@ -272,8 +286,6 @@ class Flags {
|
||||
@:bypass public static var customFlags:Map<String, String> = [];
|
||||
|
||||
public static function loadFromData(flags:Map<String, String>, data:String) {
|
||||
WINDOW_TITLE_USE_MOD_NAME = false;
|
||||
|
||||
if (!(data.length > 0)) return;
|
||||
var res = IniUtil.parseString(data);
|
||||
|
||||
@@ -290,26 +302,41 @@ class Flags {
|
||||
else trace('Invalid section $name');
|
||||
}
|
||||
}
|
||||
|
||||
if (!flags.exists("WINDOW_TITLE_USE_MOD_NAME")) WINDOW_TITLE_USE_MOD_NAME = !flags.exists('TITLE') && flags.exists('MOD_NAME');
|
||||
else WINDOW_TITLE_USE_MOD_NAME = parseBool(flags.get("WINDOW_TITLE_USE_MOD_NAME"));
|
||||
|
||||
flags.remove("WINDOW_TITLE_USE_MOD_NAME");
|
||||
}
|
||||
|
||||
public static function loadFromDatas(datas:Array<String>) {
|
||||
private static function loadPost() {
|
||||
if (MOD_API_VERSION == null) MOD_API_VERSION = CURRENT_API_VERSION;
|
||||
if (WINDOW_TITLE_USE_MOD_NAME == null) WINDOW_TITLE_USE_MOD_NAME = !overridenFlags.exists('TITLE') && overridenFlags.exists('MOD_NAME');
|
||||
if (USE_LEGACY_TIMING == null) USE_LEGACY_TIMING = MOD_API_VERSION < 2;
|
||||
if (USE_LEGACY_ZOOM_FACTOR == null) USE_LEGACY_ZOOM_FACTOR = MOD_API_VERSION < 2;
|
||||
if (SUSTAINS_AS_ONE_NOTE == null) SUSTAINS_AS_ONE_NOTE = MOD_API_VERSION >= 2;
|
||||
}
|
||||
|
||||
private static function onReset() {
|
||||
var currentModFolder = ModsFolder.currentModFolder;
|
||||
if (currentModFolder != null) SAVE_NAME = currentModFolder;
|
||||
}
|
||||
|
||||
public static function loadFromDatas(datas:Array<String>):Map<String, String> {
|
||||
var flags:Map<String, String> = [];
|
||||
for(data in datas) {
|
||||
if(data != null)
|
||||
for (data in datas) {
|
||||
if (data != null)
|
||||
loadFromData(flags, data);
|
||||
}
|
||||
loadPost();
|
||||
return flags;
|
||||
}
|
||||
|
||||
public static function parseFlags(flags:Map<String, String>) {
|
||||
for(name=>value in flags)
|
||||
if(!parse(name, value))
|
||||
customFlags.set(name, value);
|
||||
var parsed:Bool;
|
||||
for (name => value in flags) switch (name) {
|
||||
case "MOD_API_VERSION":
|
||||
var version = Std.parseInt(value) ?? CURRENT_API_VERSION;
|
||||
if (version > MOD_API_VERSION || MOD_API_VERSION == null) MOD_API_VERSION = version;
|
||||
default:
|
||||
if (!(parsed = parse(name, value))) customFlags.set(name, value);
|
||||
if (!overridenFlags.exists(name)) overridenFlags.set(name, parsed);
|
||||
}
|
||||
|
||||
Options.modchartingHoldSubdivisions = DEFAULT_MODCHART_HOLD_SUBDIVISIONS;
|
||||
}
|
||||
@@ -360,5 +387,6 @@ class Flags {
|
||||
parseFlags(flags);
|
||||
}
|
||||
}
|
||||
loadPost();
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
package funkin.backend.system;
|
||||
|
||||
import sys.io.File;
|
||||
import sys.FileSystem;
|
||||
import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond;
|
||||
import flixel.addons.transition.FlxTransitionableState;
|
||||
import flixel.addons.transition.TransitionData;
|
||||
@@ -9,21 +7,22 @@ import flixel.graphics.FlxGraphic;
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.math.FlxRect;
|
||||
import flixel.system.ui.FlxSoundTray;
|
||||
import funkin.backend.assets.AssetSource;
|
||||
import funkin.backend.assets.AssetsLibraryList;
|
||||
import funkin.backend.assets.ModsFolder;
|
||||
import funkin.backend.assets.AssetSource;
|
||||
import funkin.backend.system.framerate.Framerate;
|
||||
import funkin.backend.system.framerate.SystemInfo;
|
||||
import funkin.backend.system.modules.*;
|
||||
import funkin.backend.utils.ThreadUtil;
|
||||
import funkin.editors.SaveWarning;
|
||||
import funkin.options.PlayerSettings;
|
||||
import openfl.Assets;
|
||||
import openfl.Lib;
|
||||
import openfl.display.Sprite;
|
||||
import openfl.text.TextFormat;
|
||||
import openfl.utils.AssetLibrary;
|
||||
|
||||
#if ALLOW_MULTITHREADING
|
||||
import sys.thread.Thread;
|
||||
#end
|
||||
import sys.FileSystem;
|
||||
import sys.io.File;
|
||||
#if android
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
@@ -40,7 +39,7 @@ class Main extends Sprite
|
||||
|
||||
public static var scaleMode:FunkinRatioScaleMode;
|
||||
#if !mobile
|
||||
public static var framerateSprite:funkin.backend.system.framerate.Framerate;
|
||||
public static var framerateSprite:Framerate;
|
||||
#end
|
||||
|
||||
var gameWidth:Int = 1280; // Width of the game in pixels (might be less / more in actual pixels).
|
||||
@@ -58,10 +57,6 @@ class Main extends Sprite
|
||||
|
||||
// You can pretty much ignore everything from here on - your code should go in your states.
|
||||
|
||||
#if ALLOW_MULTITHREADING
|
||||
public static var gameThreads:Array<Thread> = [];
|
||||
#end
|
||||
|
||||
public static function preInit() {
|
||||
funkin.backend.utils.NativeAPI.registerAsDPICompatible();
|
||||
funkin.backend.system.CommandLineHandler.parseCommandLine(Sys.args());
|
||||
@@ -79,7 +74,7 @@ class Main extends Sprite
|
||||
addChild(game = new FunkinGame(gameWidth, gameHeight, MainState, Options.framerate, Options.framerate, skipSplash, startFullscreen));
|
||||
|
||||
#if (!mobile && !web)
|
||||
addChild(framerateSprite = new funkin.backend.system.framerate.Framerate());
|
||||
addChild(framerateSprite = new Framerate());
|
||||
SystemInfo.init();
|
||||
#end
|
||||
}
|
||||
@@ -97,16 +92,8 @@ class Main extends Sprite
|
||||
#end;
|
||||
public static var startedFromSource:Bool = #if TEST_BUILD true #else false #end;
|
||||
|
||||
|
||||
private static var __threadCycle:Int = 0;
|
||||
public static function execAsync(func:Void->Void) {
|
||||
#if ALLOW_MULTITHREADING
|
||||
var thread = gameThreads[(__threadCycle++) % gameThreads.length];
|
||||
thread.events.run(func);
|
||||
#else
|
||||
func();
|
||||
#end
|
||||
}
|
||||
// DEPRECATED
|
||||
@:dox(hide) public static function execAsync(func:Void->Void) ThreadUtil.execAsync(func);
|
||||
|
||||
private static function getTimer():Int {
|
||||
return time = Lib.getTimer();
|
||||
@@ -118,10 +105,6 @@ class Main extends Sprite
|
||||
MemoryUtil.init();
|
||||
@:privateAccess
|
||||
FlxG.game.getTimer = getTimer;
|
||||
#if ALLOW_MULTITHREADING
|
||||
for(i in 0...4)
|
||||
gameThreads.push(Thread.createWithEventLoop(function() {Thread.current().events.promise();}));
|
||||
#end
|
||||
FunkinCache.init();
|
||||
Paths.assetsTree = new AssetsLibraryList();
|
||||
|
||||
@@ -156,6 +139,7 @@ class Main extends Sprite
|
||||
FlxG.signals.focusGained.add(onFocus);
|
||||
FlxG.signals.preStateSwitch.add(onStateSwitch);
|
||||
FlxG.signals.postStateSwitch.add(onStateSwitchPost);
|
||||
FlxG.signals.postUpdate.add(onUpdate);
|
||||
|
||||
FlxG.mouse.useSystemCursor = true;
|
||||
#if DARK_MODE_WINDOW
|
||||
@@ -210,6 +194,14 @@ class Main extends Sprite
|
||||
scaleMode.resetSize();
|
||||
}
|
||||
|
||||
public static function onUpdate() {
|
||||
if (PlayerSettings.solo.controls.DEV_CONSOLE)
|
||||
NativeAPI.allocConsole();
|
||||
|
||||
if (PlayerSettings.solo.controls.FPS_COUNTER)
|
||||
Framerate.debugMode = (Framerate.debugMode + 1) % 3;
|
||||
}
|
||||
|
||||
private static function onStateSwitchPost() {
|
||||
// manual asset clearing since base openfl one does'nt clear lime one
|
||||
// does'nt clear bitmaps since flixel fork does it auto
|
||||
|
||||
@@ -66,12 +66,12 @@ class MainState extends FlxState {
|
||||
)
|
||||
];
|
||||
|
||||
for(path in addonPaths) {
|
||||
for (path in addonPaths) {
|
||||
if (path == null) continue;
|
||||
if (!isDirectory(path)) continue;
|
||||
|
||||
for(addon in FileSystem.readDirectory(path)) {
|
||||
if(!FileSystem.isDirectory(path + addon)) {
|
||||
for (addon in FileSystem.readDirectory(path)) {
|
||||
if (!FileSystem.isDirectory(path + addon)) {
|
||||
switch(Path.extension(addon).toLowerCase()) {
|
||||
case 'zip':
|
||||
addon = Path.withoutExtension(addon);
|
||||
@@ -90,7 +90,14 @@ class MainState extends FlxState {
|
||||
else _noPriorityAddons.insert(0, data);
|
||||
}
|
||||
}
|
||||
#end
|
||||
|
||||
#if GLOBAL_SCRIPT
|
||||
funkin.backend.scripting.GlobalScript.destroy();
|
||||
#end
|
||||
funkin.backend.scripting.Script.staticVariables.clear();
|
||||
|
||||
#if MOD_SUPPORT
|
||||
for (addon in _lowPriorityAddons)
|
||||
loadLib(addon.path, ltrim(addon.name, "[LOW]"));
|
||||
|
||||
@@ -143,4 +150,4 @@ class MainState extends FlxState {
|
||||
|
||||
FlxG.switchState(cast Type.createInstance(startState, []));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,12 +8,20 @@ import funkin.backend.assets.IModsAssetLibrary;
|
||||
import funkin.backend.assets.ScriptedAssetLibrary;
|
||||
|
||||
class AssetTreeInfo extends FramerateCategory {
|
||||
private var lastUpdateTime:Float = 1;
|
||||
|
||||
public function new() {
|
||||
super("Asset Libraries Tree Info");
|
||||
}
|
||||
|
||||
public override function __enterFrame(t:Int) {
|
||||
if (alpha <= 0.05) return;
|
||||
|
||||
if ((lastUpdateTime += FlxG.rawElapsed) < 1)
|
||||
return;
|
||||
|
||||
lastUpdateTime = 0;
|
||||
|
||||
var text = 'Not initialized yet\n';
|
||||
if (Paths.assetsTree != null){
|
||||
text = "";
|
||||
|
||||
@@ -53,13 +53,6 @@ class Framerate extends Sprite {
|
||||
x = 10;
|
||||
y = 2;
|
||||
|
||||
FlxG.stage.addEventListener(KeyboardEvent.KEY_UP, function(e:KeyboardEvent) {
|
||||
switch(e.keyCode) {
|
||||
case #if web Keyboard.NUMBER_3 #else Keyboard.F3 #end: // 3 on web or F3 on windows, linux and other things that runs code
|
||||
debugMode = (debugMode + 1) % 3;
|
||||
}
|
||||
});
|
||||
|
||||
if (__bitmap == null)
|
||||
__bitmap = new BitmapData(1, 1, 0xFF000000);
|
||||
|
||||
|
||||
@@ -9,6 +9,13 @@ class FramerateCounter extends Sprite {
|
||||
public var fpsLabel:TextField;
|
||||
public var lastFPS:Float = 0;
|
||||
|
||||
private var frameCount:Int = 0;
|
||||
|
||||
private var accumulatedTime:Float = openfl.Lib.getTimer();
|
||||
|
||||
private final updateInterval:Float = 1 / 15;
|
||||
private var lastUpdateTime:Float = 0;
|
||||
|
||||
public function new() {
|
||||
super();
|
||||
|
||||
@@ -27,15 +34,40 @@ class FramerateCounter extends Sprite {
|
||||
}
|
||||
}
|
||||
|
||||
public function reload() {}
|
||||
public function reload() {
|
||||
lastUpdateTime = 0;
|
||||
}
|
||||
|
||||
public override function __enterFrame(t:Int) {
|
||||
if (alpha <= 0.05) return;
|
||||
|
||||
super.__enterFrame(t);
|
||||
|
||||
lastFPS = CoolUtil.fpsLerp(lastFPS, FlxG.rawElapsed == 0 ? 0 : (1 / FlxG.rawElapsed), 0.25);
|
||||
fpsNum.text = Std.string(Math.floor(lastFPS));
|
||||
frameCount++;
|
||||
|
||||
if ((lastUpdateTime += FlxG.rawElapsed) < updateInterval)
|
||||
{
|
||||
updateLabelPosition();
|
||||
return;
|
||||
}
|
||||
|
||||
final timer = openfl.Lib.getTimer();
|
||||
|
||||
final time = timer - accumulatedTime;
|
||||
|
||||
accumulatedTime = timer;
|
||||
|
||||
lastFPS = FlxMath.lerp(lastFPS, time <= 0 ? 0 : (1000 / time * frameCount), 1.0 - Math.pow(0.75, time * 0.06));
|
||||
|
||||
fpsNum.text = Std.string(Math.round(lastFPS));
|
||||
lastUpdateTime = frameCount = 0;
|
||||
|
||||
updateLabelPosition();
|
||||
}
|
||||
|
||||
private inline function updateLabelPosition():Void
|
||||
{
|
||||
fpsLabel.x = fpsNum.x + fpsNum.width;
|
||||
fpsLabel.y = (fpsNum.y + fpsNum.height) - fpsLabel.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,11 +36,21 @@ class MemoryCounter extends Sprite {
|
||||
if (alpha <= 0.05) return;
|
||||
super.__enterFrame(t);
|
||||
|
||||
memory = MemoryUtil.currentMemUsage();
|
||||
final mem = MemoryUtil.currentMemUsage();
|
||||
|
||||
if (mem == memory) {
|
||||
updateLabelPosition();
|
||||
return;
|
||||
}
|
||||
|
||||
memory = mem;
|
||||
if (memoryPeak < memory) memoryPeak = memory;
|
||||
memoryText.text = CoolUtil.getSizeString(memory);
|
||||
memoryPeakText.text = ' / ${CoolUtil.getSizeString(memoryPeak)}';
|
||||
|
||||
memoryPeakText.x = memoryText.x + memoryText.width;
|
||||
updateLabelPosition();
|
||||
}
|
||||
|
||||
private inline function updateLabelPosition():Void
|
||||
memoryPeakText.x = memoryText.x + memoryText.width;
|
||||
}
|
||||
|
||||
@@ -115,8 +115,7 @@ class SystemInfo extends FramerateCategory {
|
||||
if (vRAMBytes == 1000 || vRAMBytes == 1 || vRAMBytes <= 0)
|
||||
Logs.trace('Unable to grab GPU VRAM', ERROR, RED);
|
||||
else {
|
||||
var vRAMBytesFloat:#if cpp Float64 #else Float #end = vRAMBytes*1024;
|
||||
vRAM = CoolUtil.getSizeString64(vRAMBytesFloat);
|
||||
vRAM = getSizeString(vRAMBytes / 1024);
|
||||
}
|
||||
}
|
||||
} else
|
||||
@@ -155,6 +154,17 @@ class SystemInfo extends FramerateCategory {
|
||||
if (totalMem != "Unknown" && memType != "Unknown") __formattedSysText += '\nTotal MEM: $totalMem $memType';
|
||||
}
|
||||
|
||||
static function getSizeString(size:Float):String {
|
||||
if (size < 1024)
|
||||
return Std.int(size) + " MB";
|
||||
else if (size < 1024 * 1024)
|
||||
return Std.int(size / 1024) + " GB";
|
||||
else {
|
||||
var tb = size / (1024 * 1024);
|
||||
return Std.int(tb) + "." + CoolUtil.addZeros(Std.string(Std.int((tb % 1) * 100)), 2) + " TB";
|
||||
}
|
||||
}
|
||||
|
||||
public function new() {
|
||||
super("System Info");
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ class FlagMacro {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function build():Array<Field> {
|
||||
public static function build(resetCallback:String):Array<Field> {
|
||||
var fields = Context.getBuildFields();
|
||||
|
||||
var clRef = Context.getLocalClass();
|
||||
@@ -248,7 +248,10 @@ class FlagMacro {
|
||||
access: [APublic, AStatic],
|
||||
kind: FFun({
|
||||
args: [],
|
||||
expr: macro $b{resetExprs},
|
||||
expr: macro {
|
||||
$b{resetExprs};
|
||||
$i{resetCallback}();
|
||||
},
|
||||
ret: macro: Void
|
||||
}),
|
||||
pos: Context.currentPos(),
|
||||
|
||||
@@ -58,6 +58,11 @@ class Macros {
|
||||
|
||||
final macroPath = 'funkin.backend.system.macros.Macros';
|
||||
Compiler.addMetadata('@:build($macroPath.buildLimeAssetLibrary())', 'lime.utils.AssetLibrary');
|
||||
|
||||
//Adds Compat for #if hscript blocks when you have hscript improved
|
||||
if (Context.defined("hscript_improved") && !Context.defined("hscript")) {
|
||||
Compiler.define('hscript');
|
||||
}
|
||||
}
|
||||
|
||||
public static function buildLimeAssetLibrary():Array<Field> {
|
||||
|
||||
@@ -2,22 +2,30 @@ package funkin.backend.system.updating;
|
||||
|
||||
import funkin.backend.system.github.GitHub;
|
||||
import funkin.backend.system.github.GitHubRelease;
|
||||
#if ALLOW_MULTITHREADING
|
||||
import funkin.backend.utils.ThreadUtil;
|
||||
#end
|
||||
|
||||
import lime.app.Application;
|
||||
|
||||
import sys.thread.Mutex;
|
||||
import sys.thread.Thread;
|
||||
import sys.FileSystem;
|
||||
|
||||
import haxe.io.Path;
|
||||
|
||||
#if (target.threaded)
|
||||
import sys.thread.Thread;
|
||||
import sys.thread.Mutex;
|
||||
#end
|
||||
|
||||
using funkin.backend.system.github.GitHub;
|
||||
|
||||
class UpdateUtil {
|
||||
public static var lastUpdateCheck:Null<UpdateCheckCallback>;
|
||||
|
||||
#if (target.threaded)
|
||||
private static var __waitCallbacks:Array<UpdateCheckCallback->Void>;
|
||||
private static var __mutex:Mutex;
|
||||
#end
|
||||
|
||||
public static function init() {
|
||||
// deletes old bak file if it exists
|
||||
@@ -26,26 +34,34 @@ class UpdateUtil {
|
||||
if (FileSystem.exists(bakPath)) FileSystem.deleteFile(bakPath);
|
||||
#end
|
||||
|
||||
#if (target.threaded)
|
||||
__waitCallbacks = [];
|
||||
__mutex = new Mutex();
|
||||
Thread.create(checkForUpdates.bind(true, false));
|
||||
|
||||
#if ALLOW_MULTITHREADING ThreadUtil.execAsync #else Thread.create #end(checkForUpdates.bind(true, false));
|
||||
#end
|
||||
}
|
||||
|
||||
public static function waitForUpdates(force = false, callback:UpdateCheckCallback->Void, lazy = false) {
|
||||
#if (target.threaded)
|
||||
if (__mutex.tryAcquire()) {
|
||||
__mutex.release();
|
||||
if (__shouldCheck(lazy) || force) {
|
||||
__waitCallbacks.push(callback);
|
||||
Thread.create(checkForUpdates.bind(force, false));
|
||||
#if ALLOW_MULTITHREADING ThreadUtil.execAsync #else Thread.create #end(checkForUpdates.bind(force, false));
|
||||
}
|
||||
else
|
||||
callback(lastUpdateCheck);
|
||||
}
|
||||
else
|
||||
__waitCallbacks.push(callback);
|
||||
#else
|
||||
callback(checkForUpdates(true, false));
|
||||
#end
|
||||
}
|
||||
|
||||
public static function checkForUpdates(force = false, lazy = false):UpdateCheckCallback {
|
||||
#if (target.threaded)
|
||||
var wasAcquired = !__mutex.tryAcquire();
|
||||
if (wasAcquired) __mutex.acquire();
|
||||
|
||||
@@ -60,8 +76,19 @@ class UpdateUtil {
|
||||
FlxG.signals.preUpdate.addOnce(__callWaitCallbacks);
|
||||
|
||||
return lastUpdateCheck;
|
||||
#else
|
||||
if (!__shouldCheck(lazy)) return lastUpdateCheck;
|
||||
return lastUpdateCheck = __checkForUpdates();
|
||||
#end
|
||||
}
|
||||
|
||||
#if (target.threaded)
|
||||
static function __callWaitCallbacks() {
|
||||
for (callback in __waitCallbacks) callback(lastUpdateCheck);
|
||||
__waitCallbacks.resize(0);
|
||||
}
|
||||
#end
|
||||
|
||||
static function __checkForUpdates():UpdateCheckCallback {
|
||||
var curTag = 'v' + (Flags.VERSION == null ? Application.current.meta.get('version') : Flags.VERSION), error = false;
|
||||
var newUpdates = __doReleaseFiltering(GitHub.getReleases(Flags.REPO_OWNER, Flags.REPO_NAME, (e) -> {
|
||||
@@ -82,11 +109,6 @@ class UpdateUtil {
|
||||
static function __shouldCheck(lazy:Bool):Bool
|
||||
return lastUpdateCheck == null || !lazy && (!lastUpdateCheck.newUpdate || Date.now().getTime() - lastUpdateCheck.date.getTime() > 1800000);
|
||||
|
||||
static function __callWaitCallbacks() {
|
||||
for (callback in __waitCallbacks) callback(lastUpdateCheck);
|
||||
__waitCallbacks.resize(0);
|
||||
}
|
||||
|
||||
static function __doReleaseFiltering(releases:Array<GitHubRelease>, currentVersionTag:String) {
|
||||
releases = releases.filterReleases(Options.betaUpdates, false);
|
||||
if (releases.length <= 0)
|
||||
|
||||
@@ -20,8 +20,7 @@ typedef AudioAnalyzerCallback = Int->Int->Void;
|
||||
* An utility that analyze FlxSounds,
|
||||
* can be used to make waveform or real-time audio visualizer.
|
||||
*
|
||||
* FlxSound.amplitude does work in CNE so if any case if your only checking for peak of current
|
||||
* time, use that instead.
|
||||
* FlxSound.amplitude works so if any case if your only checking for peak of current time, use that instead.
|
||||
*/
|
||||
final class AudioAnalyzer {
|
||||
/**
|
||||
@@ -96,9 +95,9 @@ final class AudioAnalyzer {
|
||||
static var __twiddleImags:Array<Array<Float>> = [];
|
||||
static var __freqReals:Array<Array<Float>> = [];
|
||||
static var __freqImags:Array<Array<Float>> = [];
|
||||
static var __freqCalculating:Int = 0;
|
||||
#if (target.threaded)
|
||||
static var __mutex:Mutex = new Mutex();
|
||||
static var __freqCalculating:Int = 0;
|
||||
#end
|
||||
|
||||
/**
|
||||
@@ -296,7 +295,7 @@ final class AudioAnalyzer {
|
||||
__check();
|
||||
}
|
||||
|
||||
function __check() if (sound.buffer != buffer) {
|
||||
function __check() if (sound != null && sound.buffer != buffer) {
|
||||
byteSize = 1 << ((buffer = sound.buffer).bitsPerSample - 1);
|
||||
|
||||
#if (lime_cffi && lime_vorbis)
|
||||
@@ -324,7 +323,7 @@ final class AudioAnalyzer {
|
||||
* @param maxFreq The maximum frequency to cap (Optional, default 22000.0, Above 23000.0 is not recommended).
|
||||
* @return Output of levels/bars that ranges from 0 to 1.
|
||||
*/
|
||||
public function getLevels(startPos:Float, ?volume:Float, barCount:Int, ?levels:Array<Float>, ?ratio:Float, ?minDb:Float, ?maxDb:Float, ?minFreq:Float, ?maxFreq:Float):Array<Float>
|
||||
public function getLevels(?startPos:Float, ?volume:Float, barCount:Int, ?levels:Array<Float>, ?ratio:Float, ?minDb:Float, ?maxDb:Float, ?minFreq:Float, ?maxFreq:Float):Array<Float>
|
||||
return inline getLevelsFromFrequencies(__frequencies = getFrequencies(startPos, volume, __frequencies), buffer.sampleRate, barCount, levels, ratio, minDb, maxDb, minFreq, maxFreq);
|
||||
|
||||
/**
|
||||
@@ -334,8 +333,8 @@ final class AudioAnalyzer {
|
||||
* @param frequencies The output for getting the frequencies, to avoid memory leaks (Optional).
|
||||
* @return Output of frequencies.
|
||||
*/
|
||||
public function getFrequencies(startPos:Float, ?volume:Float, ?frequencies:Array<Float>):Array<Float>
|
||||
return inline getFrequenciesFromSamples(__freqSamples = getSamples(startPos, fftN, true, -1, volume, __freqSamples), fftN, useWindowingFFT, frequencies);
|
||||
public function getFrequencies(?startPos:Float, ?volume:Float, ?frequencies:Array<Float>):Array<Float>
|
||||
return inline getFrequenciesFromSamples(__freqSamples = getSamples(startPos != null ? startPos : sound.time, fftN, true, -1, volume, __freqSamples), fftN, useWindowingFFT, frequencies);
|
||||
|
||||
/**
|
||||
* Analyzes an attached FlxSound from startPos to endPos in milliseconds to get the amplitudes.
|
||||
@@ -467,36 +466,37 @@ final class AudioAnalyzer {
|
||||
@:privateAccess return sound._source != null && sound._source.__backend != null && sound._source.__backend.playing;
|
||||
|
||||
inline function __readStream(startPos:Float, endPos:Float, callback:AudioAnalyzerCallback):Float @:privateAccess {
|
||||
var backend = sound._source.__backend;
|
||||
var i = backend.bufferSizes.length - backend.queuedBuffers;
|
||||
var time = backend.bufferTimes[i] * 1000;
|
||||
final backend = sound._source.__backend;
|
||||
|
||||
// TODO: Wrap it with try until i figured it out an effective way to do this...
|
||||
// So... sometimes it just uses the decoder even if it looks good?? please help
|
||||
var n = Math.floor((endPos - startPos) * __toBits);
|
||||
if (startPos >= time && startPos < backend.bufferTimes[backend.bufferSizes.length - 1] * 1000) {
|
||||
var pos = Math.floor((startPos - time) * __toBits), buf = backend.bufferDatas[i].buffer, size = backend.bufferSizes[i], c = 0;
|
||||
var i = backend.bufferLengths.length - backend.requestBuffers - 1, time:Float;
|
||||
while (++i < backend.bufferLengths.length) if (startPos >= (time = backend.bufferTimes[i] * 1000)) {
|
||||
var pos = Math.floor((startPos - time) * __toBits), buf = backend.bufferDatas[i].buffer, size = backend.bufferLengths[i], c = 0;
|
||||
while (pos >= size) {
|
||||
if (++i >= backend.bufferSizes.length) {
|
||||
n = 0;
|
||||
break;
|
||||
}
|
||||
if (++i >= backend.bufferLengths.length) break;
|
||||
pos -= size;
|
||||
buf = backend.bufferDatas[i].buffer;
|
||||
size = backend.bufferSizes[i];
|
||||
size = backend.bufferLengths[i];
|
||||
}
|
||||
pos -= pos % __sampleSize;
|
||||
if (i >= backend.bufferLengths.length) break;
|
||||
if ((pos -= pos % __sampleSize) < 0) pos = 0;
|
||||
n -= pos % __sampleSize;
|
||||
|
||||
while (n > 0) {
|
||||
callback(getByte(buf, pos, __wordSize), c);
|
||||
if (++c > buffer.channels) c = 0;
|
||||
if ((pos += __wordSize) >= size) {
|
||||
if (++i >= backend.bufferSizes.length) break;
|
||||
if (++i >= backend.bufferLengths.length) break;
|
||||
pos = 0;
|
||||
buf = backend.bufferDatas[i].buffer;
|
||||
size = backend.bufferSizes[i];
|
||||
size = backend.bufferLengths[i];
|
||||
}
|
||||
n -= __wordSize;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return endPos - (n / __toBits);
|
||||
|
||||
@@ -3,31 +3,15 @@ package funkin.backend.utils;
|
||||
#if cpp
|
||||
import cpp.Float64;
|
||||
#end
|
||||
import flxanimate.data.AnimationData.AnimAtlas;
|
||||
import flixel.graphics.FlxGraphic;
|
||||
import openfl.display.BitmapData;
|
||||
import flixel.graphics.frames.FlxAtlasFrames;
|
||||
import flixel.graphics.frames.FlxFramesCollection;
|
||||
#if sys
|
||||
import sys.FileSystem;
|
||||
#end
|
||||
import flixel.text.FlxText;
|
||||
import funkin.backend.utils.XMLUtil.TextFormat;
|
||||
import flixel.util.typeLimit.OneOfTwo;
|
||||
import flixel.util.typeLimit.OneOfThree;
|
||||
import flixel.tweens.FlxTween;
|
||||
import flixel.system.frontEnds.SoundFrontEnd;
|
||||
import flixel.sound.FlxSound;
|
||||
import funkin.backend.system.Conductor;
|
||||
import flixel.sound.FlxSoundGroup;
|
||||
import haxe.Json;
|
||||
import haxe.io.Path;
|
||||
import haxe.io.Bytes;
|
||||
import haxe.xml.Access;
|
||||
import flixel.input.keyboard.FlxKey;
|
||||
import lime.utils.Assets;
|
||||
import flixel.animation.FlxAnimation;
|
||||
import flixel.graphics.FlxGraphic;
|
||||
import flixel.graphics.frames.FlxAtlasFrames;
|
||||
import flixel.graphics.frames.FlxFramesCollection;
|
||||
import flixel.input.keyboard.FlxKey;
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.sound.FlxSound;
|
||||
import flixel.sound.FlxSoundGroup;
|
||||
import flixel.system.frontEnds.SoundFrontEnd;
|
||||
@@ -35,19 +19,21 @@ import flixel.text.FlxText;
|
||||
import flixel.tweens.FlxTween;
|
||||
import flixel.util.FlxAxes;
|
||||
import flixel.util.FlxColor;
|
||||
import flixel.util.typeLimit.OneOfThree;
|
||||
import flixel.util.typeLimit.OneOfTwo;
|
||||
import flxanimate.data.AnimationData.AnimAtlas;
|
||||
import funkin.backend.system.Conductor;
|
||||
import funkin.backend.utils.XMLUtil.TextFormat;
|
||||
import haxe.CallStack;
|
||||
import haxe.Constraints.IMap;
|
||||
import haxe.EnumTools.EnumValueTools;
|
||||
import haxe.Json;
|
||||
import haxe.io.Bytes;
|
||||
import haxe.io.Path;
|
||||
import haxe.xml.Access;
|
||||
import lime.utils.Assets;
|
||||
import openfl.display.BitmapData;
|
||||
import openfl.geom.ColorTransform;
|
||||
import flixel.math.FlxPoint;
|
||||
import haxe.Constraints.IMap;
|
||||
import haxe.EnumTools.EnumValueTools;
|
||||
|
||||
using StringTools;
|
||||
|
||||
@@ -1509,4 +1495,4 @@ enum abstract CoolSfx(Int) from Int {
|
||||
var CHECKED = 3;
|
||||
var UNCHECKED = 4;
|
||||
var WARNING = 5;
|
||||
}
|
||||
}
|
||||
@@ -541,4 +541,4 @@ typedef DEvents =
|
||||
var ?joinGame:String->Void;
|
||||
var ?spectateGame:String->Void;
|
||||
var ?joinRequest:DUser->Void;
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@ class FunkinParentDisabler extends FlxBasic {
|
||||
for(c in __cameras) c.paused = true;
|
||||
|
||||
// sounds
|
||||
__sounds = [for(s in FlxG.sound.list) if (s.playing) s];
|
||||
__sounds = [for(s in FlxG.sound.list) if (s.playing && !s.persist) s];
|
||||
for(s in __sounds) s.pause();
|
||||
}
|
||||
}
|
||||
@@ -71,4 +71,4 @@ class FunkinParentDisabler extends FlxBasic {
|
||||
for(s in __sounds) s.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +1,97 @@
|
||||
package funkin.backend.utils;
|
||||
|
||||
#if ALLOW_MULTITHREADING
|
||||
#if (target.threaded)
|
||||
import sys.thread.Deque;
|
||||
import sys.thread.Thread;
|
||||
import sys.thread.Mutex;
|
||||
#else
|
||||
private typedef Thread = Dynamic;
|
||||
#end
|
||||
|
||||
#if !macro
|
||||
import funkin.backend.system.Logs;
|
||||
#end
|
||||
|
||||
final class ThreadUtil {
|
||||
inline static function error(text:String) {
|
||||
#if macro
|
||||
trace(text);
|
||||
#else
|
||||
FlxG.signals.preUpdate.addOnce(Logs.error.bind(text));
|
||||
#end
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Thread with an error handler.
|
||||
* @param func Function to execute
|
||||
* @param autoRestart Whenever the thread should auto restart itself after crashing.
|
||||
*/
|
||||
public static function createSafe(func:Void->Void, autoRestart:Bool = false) {
|
||||
if (autoRestart) {
|
||||
return sys.thread.Thread.create(function() {
|
||||
while(true) {
|
||||
try {
|
||||
func();
|
||||
} catch(e) {
|
||||
trace(e.details());
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return sys.thread.Thread.create(function() {
|
||||
try {
|
||||
public static function createSafe(func:Void->Void, autoRestart:Bool = false):Thread {
|
||||
#if (target.threaded)
|
||||
try {
|
||||
return if (autoRestart) Thread.create(() -> {
|
||||
var restart = true;
|
||||
while (restart) try {
|
||||
func();
|
||||
} catch(e) {
|
||||
trace(e.details());
|
||||
restart = false;
|
||||
}
|
||||
catch (e) error(e.details());
|
||||
})
|
||||
else Thread.create(() -> {
|
||||
try {func();}
|
||||
catch (e) error(e.details());
|
||||
});
|
||||
}
|
||||
catch (e) error("Failed to safely create a thread: " + e.details());
|
||||
#end
|
||||
return null;
|
||||
}
|
||||
}
|
||||
#end
|
||||
|
||||
#if ALLOW_MULTITHREADING
|
||||
public static var maxThreads:Int = 4;
|
||||
|
||||
static var __threads:Array<Thread> = [];
|
||||
static var __pendingExecs:Deque<Void->Void> = new Deque();
|
||||
static var __threadMutex:Mutex = new Mutex();
|
||||
static var __threadUsed:Int = 0;
|
||||
|
||||
static function __threadExecAsync() {
|
||||
var callback:Void->Void;
|
||||
while ((callback = __pendingExecs.pop(true)) != null) {
|
||||
__threadMutex.acquire();
|
||||
__threadUsed++;
|
||||
__threadMutex.release();
|
||||
|
||||
callback();
|
||||
|
||||
__threadMutex.acquire();
|
||||
__threadUsed--;
|
||||
__threadMutex.release();
|
||||
}
|
||||
__threadMutex.acquire();
|
||||
__threads.remove(Thread.current());
|
||||
__threadMutex.release();
|
||||
}
|
||||
#end
|
||||
|
||||
public static function execAsync(func:Void->Void) {
|
||||
if (func == null) return;
|
||||
|
||||
#if (ALLOW_MULTITHREADING && !macro)
|
||||
__pendingExecs.add(func);
|
||||
if (__threadUsed >= __threads.length) {
|
||||
if (__threads.length == maxThreads) return;
|
||||
|
||||
__threadMutex.acquire();
|
||||
try {
|
||||
var thread = Thread.create(__threadExecAsync);
|
||||
__threads.push(thread);
|
||||
}
|
||||
catch (e) Logs.warn(e.details());
|
||||
__threadMutex.release();
|
||||
}
|
||||
#else
|
||||
func();
|
||||
#end
|
||||
}
|
||||
}
|
||||
@@ -185,6 +185,16 @@ final class Windows {
|
||||
')
|
||||
public static function setWindowTitleColor(title:String, color:Array<Int>) {}
|
||||
|
||||
@:functionCode('
|
||||
HWND window = GetConsoleWindow();
|
||||
HICON smallIcon = (HICON) LoadImage(NULL, path, IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
|
||||
HICON icon = (HICON) LoadImage(NULL, path, IMAGE_ICON, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE);
|
||||
SendMessage(window, WM_SETICON, ICON_SMALL, (LPARAM)smallIcon);
|
||||
SendMessage(window, WM_SETICON, ICON_BIG, (LPARAM)icon);
|
||||
')
|
||||
public static function setWindowIcon(path:String) {}
|
||||
|
||||
|
||||
@:functionCode('
|
||||
// https://stackoverflow.com/questions/15543571/allocconsole-not-displaying-cout
|
||||
|
||||
@@ -194,6 +204,9 @@ final class Windows {
|
||||
freopen("CONIN$", "r", stdin);
|
||||
freopen("CONOUT$", "w", stdout);
|
||||
freopen("CONOUT$", "w", stderr);
|
||||
|
||||
SetConsoleOutputCP(65001);
|
||||
SetConsoleCP(65001);
|
||||
')
|
||||
public static function allocConsole() {
|
||||
}
|
||||
|
||||
@@ -41,7 +41,8 @@ class Week {
|
||||
weekObj.songs.push({
|
||||
name: name,
|
||||
hide: song.getAtt('hide').getDefault('false') == "true",
|
||||
displayName: song.getAtt('displayName')
|
||||
displayName: song.getAtt('displayName'),
|
||||
variation: song.getAtt('variation')
|
||||
});
|
||||
} catch(e) {
|
||||
Logs.trace('Song at index ${k} in week $weekName cannot contain any other XML nodes in its name.', WARNING);
|
||||
|
||||
@@ -9,7 +9,7 @@ class ModConfigWarning extends UIState {
|
||||
var library:ModsFolderLibrary = null;
|
||||
var goToState:Class<FlxState>;
|
||||
|
||||
public static inline var defaultModConfigText =
|
||||
public static var defaultModConfigText =
|
||||
'[Common] # This section applies the \'MOD_\' prefix to the flags so you don\'t have to.
|
||||
NAME="YOUR MOD NAME HERE"
|
||||
DESCRIPTION="YOUR MOD DESCRIPTION HERE"
|
||||
@@ -17,15 +17,16 @@ AUTHOR="YOU/YOUR TEAM HERE"
|
||||
VERSION="YOUR MOD\'S VERSION HERE"
|
||||
|
||||
# DO NOT EDIT!! this is used to check for version compatibility!
|
||||
API_VERSION=1
|
||||
API_VERSION=${Flags.CURRENT_API_VERSION}
|
||||
|
||||
DOWNLOAD_LINK="YOUR MOD PAGE LINK HERE"
|
||||
|
||||
# Not supported yet
|
||||
;MOD_ICON64="path/to/icon64.png"
|
||||
;MOD_ICON32="path/to/icon32.png"
|
||||
;MOD_ICON16="path/to/icon16.png"
|
||||
ICON="path/to/icon.png"
|
||||
;MOD_ICON64="path/to/icon64"
|
||||
;MOD_ICON32="path/to/icon32"
|
||||
;MOD_ICON16="path/to/icon16"
|
||||
# The path starts in "your-mod/images/", do not add image extension.
|
||||
ICON="path/to/icon"
|
||||
|
||||
[Flags] # This section doesn\'t apply any prefix.
|
||||
DISABLE_WARNING_SCREEN=true
|
||||
@@ -84,4 +85,4 @@ LOGO_TEXT=""
|
||||
], false);
|
||||
openSubState(substate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,11 @@ class AlphabetEditor extends UIState {
|
||||
public var queueReorder:Bool = false;
|
||||
public var componentList:UIButtonList<ComponentButton>;
|
||||
|
||||
public var glyphCreateWindow:UISliceSprite;
|
||||
public var glyphChar:UITextBox;
|
||||
public var confirmGlyph:UIButton;
|
||||
public var deleteGlyph:UIButton;
|
||||
|
||||
public var infoWindow:GlyphInfoWindow;
|
||||
public var curSelectedComponent:AlphabetComponent = null;
|
||||
public var curSelectedData:AlphabetLetterData = null;
|
||||
@@ -83,13 +88,18 @@ class AlphabetEditor extends UIState {
|
||||
{
|
||||
label: translate("topBar.edit"),
|
||||
childs: [
|
||||
{
|
||||
// TODO: add redo and undo
|
||||
/*{
|
||||
label: translate("edit.undo"),
|
||||
// TODO: add undo
|
||||
onSelect: null
|
||||
},
|
||||
{
|
||||
label: translate("edit.redo"),
|
||||
// TODO: add redo
|
||||
onSelect: null
|
||||
},*/
|
||||
{
|
||||
label: translate("glyph.deleteCurGlyph"),
|
||||
|
||||
},
|
||||
{
|
||||
label: "Edit Main Data", // TODO: add translations
|
||||
@@ -97,23 +107,6 @@ class AlphabetEditor extends UIState {
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: translate("topBar.glyph"),
|
||||
childs: [
|
||||
{
|
||||
label: translate("glyph.newGlyph"),
|
||||
//onSelect: _glyph_new
|
||||
},
|
||||
{
|
||||
label: translate("glyph.editGlyph"),
|
||||
//onSelect: _glyph_edit
|
||||
},
|
||||
{
|
||||
label: translate("glyph.deleteGlyph"),
|
||||
//onSelect: _glyph_delete
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: translate("topBar.view"),
|
||||
childs: [
|
||||
@@ -188,6 +181,67 @@ class AlphabetEditor extends UIState {
|
||||
brokenWarning.color = 0xFFFF6969;
|
||||
add(brokenWarning);
|
||||
|
||||
glyphCreateWindow = new UISliceSprite(FlxG.width - 15, topMenuSpr.bHeight + 15, 200, 150, "editors/ui/context-bg");
|
||||
glyphCreateWindow.x -= glyphCreateWindow.bWidth;
|
||||
uiGroup.add(glyphCreateWindow);
|
||||
|
||||
glyphChar = new UITextBox(glyphCreateWindow.x + 15, glyphCreateWindow.y + 15, "", glyphCreateWindow.bWidth - 30);
|
||||
glyphCreateWindow.members.push(glyphChar);
|
||||
|
||||
confirmGlyph = new UIButton(glyphChar.x, glyphChar.y + glyphChar.bHeight + 15, translate("glyph.newGlyph"), function() {
|
||||
if (deleteGlyph.selectable) {
|
||||
curLetter = tape.manualLetters.indexOf(lastChar) + charsForDefault.length;
|
||||
changeLetter(0);
|
||||
} else {
|
||||
tape.manualLetters.push(lastChar);
|
||||
tape.text = "";
|
||||
for (def in charsForDefault)
|
||||
tape.text += def[Std.int(Math.floor(defaultTmr) % def.length)] + " ";
|
||||
tape.text += tape.manualLetters.join(" ");
|
||||
|
||||
for (i in 0...tape.fastGetData(lastChar).components.length) {
|
||||
var anim = bigLetter.text + i;
|
||||
bigLetter.animation.remove(anim);
|
||||
tape.animation.remove(anim);
|
||||
}
|
||||
|
||||
tape.letterData.set(lastChar, {
|
||||
isDefault: false,
|
||||
advance: Math.NaN,
|
||||
advanceEmpty: true,
|
||||
components: [],
|
||||
startIndex: 0
|
||||
});
|
||||
|
||||
curLetter = tape.manualLetters.length - 1 + charsForDefault.length;
|
||||
changeLetter(0);
|
||||
}
|
||||
}, glyphChar.bWidth);
|
||||
confirmGlyph.selectable = false;
|
||||
glyphCreateWindow.members.push(confirmGlyph);
|
||||
|
||||
deleteGlyph = new UIButton(glyphChar.x, confirmGlyph.y + confirmGlyph.bHeight + 5, translate("glyph.deleteGlyph"), function() {
|
||||
final charIdx = tape.manualLetters.indexOf(lastChar);
|
||||
|
||||
tape.manualLetters.splice(charIdx, 1);
|
||||
tape.text = "";
|
||||
for (def in charsForDefault)
|
||||
tape.text += def[Std.int(Math.floor(defaultTmr) % def.length)] + " ";
|
||||
tape.text += tape.manualLetters.join(" ");
|
||||
|
||||
for (i in 0...tape.fastGetData(lastChar).components.length) {
|
||||
var anim = bigLetter.text + i;
|
||||
bigLetter.animation.remove(anim);
|
||||
tape.animation.remove(anim);
|
||||
}
|
||||
tape.letterData.remove(lastChar);
|
||||
|
||||
changeLetter((curLetter >= charIdx + charsForDefault.length) ? -1 : 0);
|
||||
}, glyphChar.bWidth);
|
||||
deleteGlyph.color = FlxColor.RED;
|
||||
deleteGlyph.selectable = false;
|
||||
glyphCreateWindow.members.push(deleteGlyph);
|
||||
|
||||
infoWindow = new GlyphInfoWindow();
|
||||
uiGroup.add(infoWindow);
|
||||
|
||||
@@ -208,7 +262,7 @@ class AlphabetEditor extends UIState {
|
||||
|
||||
scaleX: 1,
|
||||
scaleY: 1,
|
||||
|
||||
|
||||
flipX: false,
|
||||
flipY: false,
|
||||
|
||||
@@ -247,8 +301,29 @@ class AlphabetEditor extends UIState {
|
||||
}
|
||||
}
|
||||
|
||||
var lastChar:String = "";
|
||||
public override function update(elapsed:Float) {
|
||||
super.update(elapsed);
|
||||
|
||||
if (glyphChar.label.text != lastChar) {
|
||||
if (glyphChar.label.text == "") {
|
||||
lastChar = "";
|
||||
confirmGlyph.selectable = false;
|
||||
deleteGlyph.selectable = false;
|
||||
confirmGlyph.field.text = translate("glyph.newGlyph");
|
||||
} else {
|
||||
glyphChar.label.text = lastChar = switch (tape.forceCase) {
|
||||
case UPPER: glyphChar.label.text.charAt(glyphChar.label.text.length - 1).toUpperCase();
|
||||
case LOWER: glyphChar.label.text.charAt(glyphChar.label.text.length - 1).toLowerCase();
|
||||
case NONE: glyphChar.label.text.charAt(glyphChar.label.text.length - 1);
|
||||
};
|
||||
|
||||
confirmGlyph.selectable = true;
|
||||
deleteGlyph.selectable = tape.manualLetters.contains(lastChar);
|
||||
confirmGlyph.field.text = translate(deleteGlyph.selectable ? "glyph.editGlyph" : "glyph.newGlyph");
|
||||
}
|
||||
}
|
||||
|
||||
if (queueReorder) {
|
||||
queueReorder = false;
|
||||
var outlines = [];
|
||||
@@ -344,6 +419,7 @@ class AlphabetEditor extends UIState {
|
||||
curLetter = CoolUtil.positiveModuloInt(curLetter + inc, tape.manualLetters.length + charsForDefault.length);
|
||||
targetX = FlxG.width * 0.5 - tape.defaultAdvance * (0.5 + curLetter * 2);
|
||||
bigLetter.text = (curLetter < charsForDefault.length) ? charsForDefault[curLetter][0] : tape.manualLetters[curLetter - charsForDefault.length];
|
||||
glyphChar.label.text = bigLetter.text;
|
||||
bigLetter.updateHitbox();
|
||||
bigLetter.screenCenter();
|
||||
|
||||
@@ -396,11 +472,17 @@ class AlphabetEditor extends UIState {
|
||||
changeLetter(1);
|
||||
}
|
||||
|
||||
function buildAlphabet() {
|
||||
var tempPrettyPrint = true;
|
||||
var xmlThingYea:String = "<!DOCTYPE codename-engine-alphabet-font>\n" + Printer.print(tape.buildXML(), tempPrettyPrint);
|
||||
return tempPrettyPrint ? xmlThingYea : xmlThingYea.replace("\n", "");
|
||||
}
|
||||
|
||||
function _file_save(_) {
|
||||
#if sys
|
||||
CoolUtil.safeSaveFile(
|
||||
'${Paths.getAssetsRoot()}/data/alphabet/${__typeface}.xml',
|
||||
""//alphabet.buildXML()
|
||||
buildAlphabet()
|
||||
);
|
||||
#else
|
||||
_file_saveas(_);
|
||||
@@ -408,7 +490,7 @@ class AlphabetEditor extends UIState {
|
||||
}
|
||||
|
||||
function _file_saveas(_) {
|
||||
openSubState(new SaveSubstate(""/*alphabet.buildXML()*/, {
|
||||
openSubState(new SaveSubstate(buildAlphabet(), {
|
||||
defaultSaveFile: '${__typeface}.xml'
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -43,14 +43,11 @@ class AlphabetIconOption extends TextOption {
|
||||
var spritesheet = null;
|
||||
for (node in xml.elements()) {
|
||||
if (node.nodeName == "spritesheet") {
|
||||
spritesheet = node.firstChild().nodeValue;
|
||||
spritesheet = node.firstChild().nodeValue.trim();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var useColorOffsets = xml.get("useColorOffsets").getDefault("false") == "true";
|
||||
|
||||
|
||||
// todo fix crash if invalid spritesheet;
|
||||
|
||||
iconSpr = new FlxSprite();
|
||||
@@ -64,7 +61,7 @@ class AlphabetIconOption extends TextOption {
|
||||
}
|
||||
}
|
||||
iconSpr.frame = frameToUse;
|
||||
if (useColorOffsets) {
|
||||
if (xml.get("colorMode") == "offsets") {
|
||||
iconSpr.colorTransform.color = -1;
|
||||
}
|
||||
iconSpr.setPosition(90 - iconSpr.width - 20, (__text.height - iconSpr.height) / 2);
|
||||
|
||||
@@ -10,7 +10,7 @@ class GlyphInfoWindow extends UIWindow {
|
||||
public var scaleYBox:UINumericStepper;
|
||||
public var angleBox:UINumericStepper;
|
||||
public var colorModeDrop:UIDropDown;
|
||||
|
||||
|
||||
public var flipXBox:UICheckbox;
|
||||
public var flipYBox:UICheckbox;
|
||||
|
||||
@@ -60,7 +60,7 @@ class GlyphInfoWindow extends UIWindow {
|
||||
|
||||
xBox = new UINumericStepper(prefixBox.x, prefixBox.y + prefixBox.bHeight + itemMargin + labelOffset, 0, 1, 2, null, null, 80);
|
||||
xBox.onChange = valueSet.bind(xBox, function(val) { // kinda dumb but blame cne ui
|
||||
compon.x = val;
|
||||
compon.x = -val;
|
||||
});
|
||||
members.push(xBox);
|
||||
|
||||
@@ -121,7 +121,7 @@ class GlyphInfoWindow extends UIWindow {
|
||||
members.push(colorModeDrop);
|
||||
addLabelOn(colorModeDrop, "Color Mode");
|
||||
|
||||
outlineCheck = new UICheckbox(colorModeDrop.x + colorModeDrop.bWidth + itemMargin * 2, colorModeDrop.y + 4, "Use Outline?");
|
||||
outlineCheck = new UICheckbox(colorModeDrop.x + colorModeDrop.bWidth + itemMargin * 2, colorModeDrop.y + 10, "Use Outline?");
|
||||
outlineCheck.onChecked = function(val) {
|
||||
targetPercent = val ? 1 : 0;
|
||||
|
||||
@@ -147,7 +147,7 @@ class GlyphInfoWindow extends UIWindow {
|
||||
angle: compon.angle,
|
||||
cos: compon.cos,
|
||||
sin: compon.sin,
|
||||
|
||||
|
||||
flipX: compon.flipX,
|
||||
flipY: compon.flipY,
|
||||
|
||||
@@ -156,15 +156,17 @@ class GlyphInfoWindow extends UIWindow {
|
||||
};
|
||||
|
||||
data.components.insert(AlphabetEditor.instance.outlineIdx, newOutline);
|
||||
++AlphabetEditor.instance.outlineIdx;
|
||||
++data.startIndex;
|
||||
} else {
|
||||
compon.outIndex = null;
|
||||
data.components.splice(AlphabetEditor.instance.outlineIdx - 1, 1);
|
||||
--AlphabetEditor.instance.outlineIdx;
|
||||
--data.startIndex;
|
||||
}
|
||||
}
|
||||
members.push(outlineCheck);
|
||||
|
||||
|
||||
flipXBox = new UICheckbox(outlineCheck.x, outlineCheck.y - outlineCheck.height - 8, "Flip X?");
|
||||
flipXBox.onChecked = function(check:Bool) {
|
||||
compon.flipX = check;
|
||||
@@ -254,7 +256,7 @@ class GlyphInfoWindow extends UIWindow {
|
||||
}
|
||||
|
||||
prefixBox.label.text = com.anim;
|
||||
xBox.value = com.x;
|
||||
xBox.value = -com.x;
|
||||
yBox.value = com.y;
|
||||
scaleXBox.value = com.scaleX;
|
||||
scaleYBox.value = com.scaleY;
|
||||
@@ -276,12 +278,12 @@ class GlyphInfoWindow extends UIWindow {
|
||||
outlineYBox.value = out.y;
|
||||
targetPercent = 1;
|
||||
}
|
||||
|
||||
for (item in members) {
|
||||
if (item is UISprite)
|
||||
cast(item, UISprite).selectable = true;
|
||||
}
|
||||
colorModeDrop.dropButton.selectable = true;
|
||||
|
||||
for (item in [prefixBox, scaleXBox, scaleYBox, angleBox, flipXBox, flipYBox])
|
||||
item.selectable = true;
|
||||
for (item in [xBox, yBox, colorModeDrop, outlineCheck, outlineBox, outlineXBox, outlineYBox])
|
||||
item.selectable = !data.isDefault;
|
||||
colorModeDrop.dropButton.selectable = colorModeDrop.selectable;
|
||||
}
|
||||
|
||||
function valueSet(item:UINumericStepper, func:Dynamic, text:String) {
|
||||
|
||||
@@ -258,6 +258,10 @@ class CharacterAnimButton extends UIButton {
|
||||
parent.displayAnimsFramesList.remove(anim);
|
||||
parent.displayAnimsFramesList.set(newName, displayFrame);
|
||||
|
||||
var animButton = parent.animButtons.get(this.anim);
|
||||
parent.animButtons.remove(this.anim);
|
||||
parent.animButtons.set(newName, animButton);
|
||||
|
||||
this.anim = newName;
|
||||
nameTextBox.label.text = newName;
|
||||
updateText();
|
||||
|
||||
@@ -104,6 +104,7 @@ class CharacterAnimsWindow extends UIButtonList<CharacterAnimButton> {
|
||||
if (character.getAnimName() == button.anim)
|
||||
@:privateAccess CharacterEditor.instance._animation_down(null);
|
||||
|
||||
character.ghosts.remove(button.anim);
|
||||
character.removeAnimation(button.anim);
|
||||
if (character.animOffsets.exists(button.anim)) character.animOffsets.remove(button.anim);
|
||||
if (character.animDatas.exists(button.anim)) character.animDatas.remove(button.anim);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user