Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e540cb454b |
@@ -37,7 +37,4 @@ f8b20774e3f035eeddb9211a28a391b20db74456
|
|||||||
|
|
||||||
# Revert a revert (scripted cutscene path)
|
# Revert a revert (scripted cutscene path)
|
||||||
d73f86d26ec2dbf031c01f588ba4be11842db09c
|
d73f86d26ec2dbf031c01f588ba4be11842db09c
|
||||||
fe0ab0aa454f4ae12ced9502db8a01e7bca3e04c
|
fe0ab0aa454f4ae12ced9502db8a01e7bca3e04c
|
||||||
|
|
||||||
# Forgot the # in the commit message
|
|
||||||
484bbcb22aa8f28b62912abb6d8c89fb58e63889
|
|
||||||
+3
-2
@@ -5,9 +5,10 @@
|
|||||||
pages/** linguist-vendored
|
pages/** linguist-vendored
|
||||||
|
|
||||||
# Include HScript files as Haxe
|
# Include HScript files as Haxe
|
||||||
*.hxs linguist-language=Haxe
|
|
||||||
*.hsc linguist-language=Haxe
|
|
||||||
*.hscript linguist-language=Haxe
|
*.hscript linguist-language=Haxe
|
||||||
|
*.hsc linguist-language=Haxe
|
||||||
|
*.hxs linguist-language=Haxe
|
||||||
|
*.hxp linguist-language=Haxe
|
||||||
|
|
||||||
# Include Shader files as GLSL
|
# Include Shader files as GLSL
|
||||||
*.frag linguist-language=GLSL
|
*.frag linguist-language=GLSL
|
||||||
|
|||||||
@@ -1,23 +1,22 @@
|
|||||||
name: Linux Builds
|
|
||||||
|
|
||||||
|
name: Linux Build
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Linux Build
|
name: Linux Build
|
||||||
permissions: write-all
|
permissions: write-all
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
steps:
|
steps:
|
||||||
- name: Pulling the new commit
|
- name: Pulling the source
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v2
|
||||||
- name: Setting up Haxe
|
- name: Setting up Haxe
|
||||||
uses: krdlab/setup-haxe@v2
|
uses: krdlab/setup-haxe@v2
|
||||||
with:
|
with:
|
||||||
haxe-version: 4.3.7
|
haxe-version: 4.3.7
|
||||||
- name: Restore existing build cache for faster compilation
|
- name: Restore existing build cache for faster compilation
|
||||||
uses: actions/cache@v4.2.3
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
# not caching the bin folder to prevent asset duplication and stuff like that
|
# not caching the bin folder to prevent asset duplication and stuff like that
|
||||||
key: cache-build-linux
|
key: cache-build-linux
|
||||||
@@ -25,8 +24,8 @@ jobs:
|
|||||||
.haxelib/
|
.haxelib/
|
||||||
export/release/linux/haxe/
|
export/release/linux/haxe/
|
||||||
export/release/linux/obj/
|
export/release/linux/obj/
|
||||||
- run: |
|
restore-keys: |
|
||||||
echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV
|
cache-build-linux
|
||||||
- name: Installing LibVLC
|
- name: Installing LibVLC
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install libvlc-dev libvlccore-dev
|
sudo apt-get install libvlc-dev libvlccore-dev
|
||||||
@@ -68,7 +67,7 @@ jobs:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
- name: Uploading new cache
|
- name: Uploading new cache
|
||||||
uses: actions/cache@v4.2.3
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
# caching again since for some reason it doesnt work with the first post cache shit
|
# caching again since for some reason it doesnt work with the first post cache shit
|
||||||
key: cache-build-linux
|
key: cache-build-linux
|
||||||
@@ -76,72 +75,5 @@ jobs:
|
|||||||
.haxelib/
|
.haxelib/
|
||||||
export/release/linux/haxe/
|
export/release/linux/haxe/
|
||||||
export/release/linux/obj/
|
export/release/linux/obj/
|
||||||
|
restore-keys: |
|
||||||
# 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)
|
cache-build-linux
|
||||||
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/
|
|
||||||
|
|||||||
+10
-75
@@ -1,23 +1,22 @@
|
|||||||
name: Mac OS Builds
|
|
||||||
|
|
||||||
|
name: Mac OS Build
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Mac OS Build
|
name: Mac OS Build
|
||||||
permissions: write-all
|
permissions: write-all
|
||||||
runs-on: macos-14
|
runs-on: macos-13
|
||||||
steps:
|
steps:
|
||||||
- name: Pulling the new commit
|
- name: Pulling the new commit
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v2
|
||||||
- name: Setting up Haxe
|
- name: Setting up Haxe
|
||||||
uses: krdlab/setup-haxe@v2
|
uses: krdlab/setup-haxe@v2
|
||||||
with:
|
with:
|
||||||
haxe-version: 4.3.7
|
haxe-version: 4.3.7
|
||||||
- name: Restore existing build cache for faster compilation
|
- name: Restore existing build cache for faster compilation
|
||||||
uses: actions/cache@v4.2.3
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
# not caching the bin folder to prevent asset duplication and stuff like that
|
# not caching the bin folder to prevent asset duplication and stuff like that
|
||||||
key: cache-build-mac
|
key: cache-build-mac
|
||||||
@@ -25,14 +24,14 @@ jobs:
|
|||||||
.haxelib/
|
.haxelib/
|
||||||
export/release/macos/haxe/
|
export/release/macos/haxe/
|
||||||
export/release/macos/obj/
|
export/release/macos/obj/
|
||||||
- run: |
|
restore-keys: |
|
||||||
echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV
|
cache-build-mac
|
||||||
- name: Installing/Updating libraries
|
- name: Installing/Updating libraries
|
||||||
run: |
|
run: |
|
||||||
haxe -cp commandline -D analyzer-optimize --run Main setup -s
|
haxe -cp commandline -D analyzer-optimize --run Main setup -s
|
||||||
- name: Building the game
|
- name: Building the game
|
||||||
run: |
|
run: |
|
||||||
arch -x86_64 haxelib run lime build mac
|
haxelib run lime build mac
|
||||||
- name: Tar files
|
- name: Tar files
|
||||||
run: tar -zcvf CodenameEngine.tar.gz -C export/release/macos/bin .
|
run: tar -zcvf CodenameEngine.tar.gz -C export/release/macos/bin .
|
||||||
- name: Uploading artifact (executable)
|
- name: Uploading artifact (executable)
|
||||||
@@ -65,7 +64,7 @@ jobs:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
- name: Uploading new cache
|
- name: Uploading new cache
|
||||||
uses: actions/cache@v4.2.3
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
# caching again since for some reason it doesnt work with the first post cache shit
|
# caching again since for some reason it doesnt work with the first post cache shit
|
||||||
key: cache-build-mac
|
key: cache-build-mac
|
||||||
@@ -73,69 +72,5 @@ jobs:
|
|||||||
.haxelib/
|
.haxelib/
|
||||||
export/release/macos/haxe/
|
export/release/macos/haxe/
|
||||||
export/release/macos/obj/
|
export/release/macos/obj/
|
||||||
|
restore-keys: |
|
||||||
# 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)
|
cache-build-mac
|
||||||
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/
|
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ jobs:
|
|||||||
name: Release ${{ github.event.inputs.tag_name }}
|
name: Release ${{ github.event.inputs.tag_name }}
|
||||||
draft: true
|
draft: true
|
||||||
prerelease: ${{ github.event.inputs.prerelease }}
|
prerelease: ${{ github.event.inputs.prerelease }}
|
||||||
body: ${{ steps.build_body.outputs.body }}
|
body: ${{ steps.build_body.outputs.body }}
|
||||||
generate_release_notes: true
|
generate_release_notes: true
|
||||||
files: |
|
files: |
|
||||||
renamed/Codename Engine-Windows.zip
|
renamed/Codename Engine-Windows.zip
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
name: Windows Builds
|
|
||||||
|
|
||||||
|
name: Windows Build
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Windows Build
|
name: Windows Build
|
||||||
@@ -11,13 +10,13 @@ jobs:
|
|||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Pulling the new commit
|
- name: Pulling the new commit
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v2
|
||||||
- name: Setting up Haxe
|
- name: Setting up Haxe
|
||||||
uses: krdlab/setup-haxe@v2
|
uses: krdlab/setup-haxe@v2
|
||||||
with:
|
with:
|
||||||
haxe-version: 4.3.7
|
haxe-version: 4.3.7
|
||||||
- name: Restore existing build cache for faster compilation
|
- name: Restore existing build cache for faster compilation
|
||||||
uses: actions/cache@v4.2.3
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
# not caching the bin folder to prevent asset duplication and stuff like that
|
# not caching the bin folder to prevent asset duplication and stuff like that
|
||||||
key: cache-build-windows
|
key: cache-build-windows
|
||||||
@@ -25,8 +24,8 @@ jobs:
|
|||||||
.haxelib/
|
.haxelib/
|
||||||
export/release/windows/haxe/
|
export/release/windows/haxe/
|
||||||
export/release/windows/obj/
|
export/release/windows/obj/
|
||||||
- run: |
|
restore-keys: |
|
||||||
echo "HXCPP_COMPILE_CACHE=~/.hxcpp" >> $GITHUB_ENV
|
cache-build-windows
|
||||||
- name: Installing/Updating libraries
|
- name: Installing/Updating libraries
|
||||||
run: |
|
run: |
|
||||||
haxe -cp commandline -D analyzer-optimize --run Main setup -s --no-vscheck
|
haxe -cp commandline -D analyzer-optimize --run Main setup -s --no-vscheck
|
||||||
@@ -63,7 +62,7 @@ jobs:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
- name: Uploading new cache
|
- name: Uploading new cache
|
||||||
uses: actions/cache@v4.2.3
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
# caching again since for some reason it doesnt work with the first post cache shit
|
# caching again since for some reason it doesnt work with the first post cache shit
|
||||||
key: cache-build-windows
|
key: cache-build-windows
|
||||||
@@ -71,67 +70,5 @@ jobs:
|
|||||||
.haxelib/
|
.haxelib/
|
||||||
export/release/windows/haxe/
|
export/release/windows/haxe/
|
||||||
export/release/windows/obj/
|
export/release/windows/obj/
|
||||||
|
restore-keys: |
|
||||||
# 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)
|
cache-build-windows
|
||||||
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/
|
|
||||||
|
|||||||
Vendored
+4
-1
@@ -1,12 +1,15 @@
|
|||||||
{
|
{
|
||||||
"editor.detectIndentation": false,
|
"editor.detectIndentation": false,
|
||||||
"editor.insertSpaces": false,
|
"editor.insertSpaces": false,
|
||||||
|
"editor.tabSize": 4,
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"*.hx": "haxe",
|
"*.hx": "haxe",
|
||||||
"*.hscript": "haxe",
|
"*.hscript": "haxe",
|
||||||
"*.hsc": "haxe",
|
"*.hsc": "haxe",
|
||||||
"*.hxs": "haxe"
|
"*.hxs": "haxe",
|
||||||
|
"*.hxp": "haxe"
|
||||||
},
|
},
|
||||||
|
"lime.projectFile": "project.hxp",
|
||||||
"lime.targetConfigurations": [
|
"lime.targetConfigurations": [
|
||||||
{
|
{
|
||||||
"label": "Windows (Test Build)",
|
"label": "Windows (Test Build)",
|
||||||
|
|||||||
+2
-2
@@ -71,11 +71,11 @@ _**QOL = Quality of Life**_
|
|||||||
- Characters are located in `data/weeks/characters`.
|
- Characters are located in `data/weeks/characters`.
|
||||||
- Weeks are located in `data/weeks/weeks/`
|
- 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.
|
- If you need to rearrange the weeks in-game, you can use the `data/weeks/weeks.txt` file.
|
||||||
- Editors for Charts and Characters
|
- Editors for Charts and Characters (Stage coming soon)
|
||||||
- Undos/Redos supported
|
- Undos/Redos supported
|
||||||
- Warning on closing unsaved work
|
- Warning on closing unsaved work
|
||||||
- Clean UI (for ocd freaks)
|
- Clean UI (for ocd freaks)
|
||||||
- Mature Chart editor
|
- Mature Chart editor (Character editor rework soon)
|
||||||
- Features not found in other editors!
|
- Features not found in other editors!
|
||||||
- Every single state & substate can be modified via HScript (`data/states/StateName.hx`)
|
- 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.**
|
- **Instances launched via `lime test windows` will automatically use assets from source.**
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ The engine uses [HaxeFlixel](https://haxeflixel.com/) and it mainly features:
|
|||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><h2>How to setup and build the engine and its documentation</h2></summary>
|
<summary><h2>How to setup and build</h2></summary>
|
||||||
|
|
||||||
Check out our guide [HERE](building/README.md)
|
Check out our guide [HERE](building/README.md)
|
||||||
</details>
|
</details>
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
## 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.
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
@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
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
# THIS FILE ISN'T NECESSARY,
|
|
||||||
# BUT YOU CAN USE IT TO SORT AND WHITELIST FREEPLAY SONGS
|
|
||||||
|
|
||||||
test
|
test
|
||||||
tutorial
|
tutorial
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
# THIS FILE ISN'T NECESSARY,
|
|
||||||
# BUT YOU CAN USE IT TO SORT AND WHITELIST GAME MODES
|
|
||||||
|
|
||||||
solo
|
|
||||||
opponent
|
|
||||||
coop
|
|
||||||
coop-switched
|
|
||||||
botplay
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"displayName": "Botplay Mode",
|
|
||||||
"modeID": "codename.botplay"
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
<!DOCTYPE codename-engine-game-mode>
|
|
||||||
<mode name="Botplay Mode" id="codename.botplay"/>
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"displayName": "Co-Op Mode (Switched)",
|
|
||||||
"modeID": "codename.coop-opponent",
|
|
||||||
"scripts": ["opponent", "coop"]
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<!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>
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"displayName": "Co-Op Mode",
|
|
||||||
"modeID": "codename.coop"
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
<!DOCTYPE codename-engine-game-mode>
|
|
||||||
<mode name="Co-Op Mode" id="codename.coop"/>
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
solo
|
|
||||||
opponent
|
|
||||||
coop
|
|
||||||
coop-switched
|
|
||||||
botplay
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"displayName": "Opponent Mode",
|
|
||||||
"modeID": "codename.opponent"
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
<!DOCTYPE codename-engine-game-mode>
|
|
||||||
<mode name="Opponent Mode" id="codename.opponent"/>
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"displayName": "Solo Mode",
|
|
||||||
"modeID": "codename.solo"
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
<!DOCTYPE codename-engine-game-mode>
|
|
||||||
<mode name="Solo Mode" id="codename.solo"/>
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# THIS FILE ISN'T NECESSARY,
|
# THIS FILE ISN'T NECESSARY,
|
||||||
# BUT YOU CAN USE IT TO SORT AND WHITELIST WEEKS
|
# BUT YOU CAN USE IT TO SORT WEEKS
|
||||||
|
|
||||||
tutorial
|
tutorial
|
||||||
week1
|
week1
|
||||||
@@ -48,7 +48,6 @@
|
|||||||
<str id="category.engine">Engine</str>
|
<str id="category.engine">Engine</str>
|
||||||
<group name="engine" prefix="engine.">
|
<group name="engine" prefix="engine.">
|
||||||
<str id="switchMod">Switch Mod</str>
|
<str id="switchMod">Switch Mod</str>
|
||||||
<str id="fpsCounter">FPS Counter</str>
|
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<str id="category.volume">Volume</str>
|
<str id="category.volume">Volume</str>
|
||||||
|
|||||||
@@ -46,9 +46,8 @@
|
|||||||
|
|
||||||
<group name="engine" prefix="engine.">
|
<group name="engine" prefix="engine.">
|
||||||
<str id="switchMod">Cambiar Mod</str>
|
<str id="switchMod">Cambiar Mod</str>
|
||||||
<str id="fpsCounter">Contador de FPS</str>
|
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<str id="category.volume">Volumen</str>
|
<str id="category.volume">Volumen</str>
|
||||||
<str id="volume.up">Arriba</str>
|
<str id="volume.up">Arriba</str>
|
||||||
<str id="volume.down">Abajo</str>
|
<str id="volume.down">Abajo</str>
|
||||||
|
|||||||
@@ -46,7 +46,6 @@
|
|||||||
|
|
||||||
<group name="engine" prefix="engine.">
|
<group name="engine" prefix="engine.">
|
||||||
<str id="switchMod">Cambia Mod</str>
|
<str id="switchMod">Cambia Mod</str>
|
||||||
<str id="fpsCounter">Contatore FPS</str>
|
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<str id="volume.up">Su</str>
|
<str id="volume.up">Su</str>
|
||||||
|
|||||||
@@ -44,9 +44,8 @@
|
|||||||
<str id="category.engine">Silnik</str>
|
<str id="category.engine">Silnik</str>
|
||||||
<group name="engine" prefix="engine.">
|
<group name="engine" prefix="engine.">
|
||||||
<str id="switchMod">Zmień Moda</str>
|
<str id="switchMod">Zmień Moda</str>
|
||||||
<str id="fpsCounter">Licznik FPS</str>
|
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<str id="category.volume">Głośność</str>
|
<str id="category.volume">Głośność</str>
|
||||||
<str id="volume.up">Głóśniej</str>
|
<str id="volume.up">Głóśniej</str>
|
||||||
<str id="volume.down">Ciszej</str>
|
<str id="volume.down">Ciszej</str>
|
||||||
|
|||||||
@@ -48,7 +48,6 @@
|
|||||||
<str id="category.engine">Codename Engine</str>
|
<str id="category.engine">Codename Engine</str>
|
||||||
<group name="engine" prefix="engine.">
|
<group name="engine" prefix="engine.">
|
||||||
<str id="switchMod">Trocar Mod</str>
|
<str id="switchMod">Trocar Mod</str>
|
||||||
<str id="fpsCounter">Contador de FPS</str>
|
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<str id="category.volume">Volume</str>
|
<str id="category.volume">Volume</str>
|
||||||
|
|||||||
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.
+3
-22
@@ -1,6 +1,6 @@
|
|||||||
# Compiling Codename Engine
|
Here's the full guide on how to setup and compile Codename Engine!<br>
|
||||||
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.**
|
> **Open the instructions for your platform**
|
||||||
<details>
|
<details>
|
||||||
<summary>Windows</summary>
|
<summary>Windows</summary>
|
||||||
|
|
||||||
@@ -38,22 +38,3 @@ Do you want to turn your source code into a playable build to play? Then you wan
|
|||||||
> You can also run `./cne-windows.bat -help` or `./cne-unix.sh -help` (depending on your platform) to check out more useful commands!<br>
|
> 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).
|
> 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.
|
> - 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.
|
|
||||||
+6
-9
@@ -1,17 +1,14 @@
|
|||||||
[General]
|
[general]
|
||||||
sample-type=float32
|
sample-type=float32
|
||||||
stereo-mode=speakers
|
stereo-mode=speakers
|
||||||
|
stereo-encoding=panpot
|
||||||
hrtf=false
|
hrtf=false
|
||||||
cf_level=0
|
cf_level=0
|
||||||
|
resampler=fast_bsinc24
|
||||||
|
front-stablizer=false
|
||||||
output-limiter=false
|
output-limiter=false
|
||||||
front-stabilizer=false
|
|
||||||
volume-adjust=0
|
volume-adjust=0
|
||||||
period_size=441
|
|
||||||
sources=512
|
|
||||||
sends=64
|
|
||||||
dither=false
|
|
||||||
|
|
||||||
[decoder]
|
[decoder]
|
||||||
hq-mode=true
|
hq-mode=false
|
||||||
distance-comp=true
|
distance-comp=false
|
||||||
nfc=false
|
nfc=false
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
#!/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."
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
@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.
|
|
||||||
+2
-3
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<!-- OpenFL & Lime (Required for Flixel) -->
|
<!-- OpenFL & Lime (Required for Flixel) -->
|
||||||
<git name="openfl" url="https://github.com/CodenameCrew/cne-openfl" />
|
<git name="openfl" url="https://github.com/CodenameCrew/cne-openfl" />
|
||||||
<lib name="lime" version="8.1.2" />
|
<lib name="lime" version="8.2.0" />
|
||||||
<!-- <git name="lime" url="https://github.com/CodenameCrew/cne-lime" /> disabled for now until fixed -->
|
<!-- <git name="lime" url="https://github.com/CodenameCrew/cne-lime" /> disabled for now until fixed -->
|
||||||
|
|
||||||
<!-- Flixel -->
|
<!-- Flixel -->
|
||||||
@@ -16,9 +16,8 @@
|
|||||||
<git name="hscript-improved" url="https://github.com/CodenameCrew/hscript-improved" ref="codename-dev" />
|
<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="flxanimate" url="https://github.com/CodenameCrew/cne-flxanimate" />
|
||||||
<git name="hxdiscord_rpc" url="https://github.com/CodenameCrew/cne-hxdiscord_rpc" skipDeps="true" />
|
<git name="hxdiscord_rpc" url="https://github.com/CodenameCrew/cne-hxdiscord_rpc" skipDeps="true" />
|
||||||
<lib name="funkin-modchart" version="1.2.4" skipDeps="true" />
|
<git name="funkin-modchart" url="https://github.com/TheoDevelops/FunkinModchart" ref="f30676579d8de7ccac7d12e13b664e8b2c42c6bf" skipDeps="true" />
|
||||||
<lib name="hxvlc" version="1.9.3" 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 -->
|
<!-- Documentation and other features -->
|
||||||
<git name="away3d" url="https://github.com/CodenameCrew/away3d" />
|
<git name="away3d" url="https://github.com/CodenameCrew/away3d" />
|
||||||
|
|||||||
@@ -3,16 +3,19 @@
|
|||||||
<!-- _________________________ Application Settings _________________________ -->
|
<!-- _________________________ Application Settings _________________________ -->
|
||||||
<app
|
<app
|
||||||
title="Friday Night Funkin' - Codename Engine" main="funkin.backend.system.Main"
|
title="Friday Night Funkin' - Codename Engine" main="funkin.backend.system.Main"
|
||||||
file="CodenameEngine" packageName="com.codenamecrew.codenameengine"
|
file="CodenameEngine" packageName="com.yoshman29.codenameengine"
|
||||||
package="com.codenamecrew.codenameengine"
|
package="com.yoshman29.codenameengine"
|
||||||
version="1.0.1" company="CodenameCrew" />
|
version="1.0.1" company="Yoshman29" />
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
CHANGE THE SAVE PATH & NAME FOR YOUR HARDCODED MOD HERE!
|
CHANGE THE SAVE PATH & NAME FOR YOUR MOD HERE!
|
||||||
-->
|
-->
|
||||||
<haxedef name="SAVE_PATH" value="CodenameCrew/CodenameEngine"/>
|
<haxedef name="SAVE_PATH" value="CodenameEngine"/>
|
||||||
<haxedef name="SAVE_NAME" value="save-default"/>
|
<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-->
|
<!--Switch Export with Unique ApplicationID and Icon-->
|
||||||
<set name="APP_ID" value="0x0100f6c013bbc000" />
|
<set name="APP_ID" value="0x0100f6c013bbc000" />
|
||||||
|
|
||||||
@@ -47,7 +50,7 @@
|
|||||||
<!-- _________________________________ Engine Settings _______________________________ -->
|
<!-- _________________________________ Engine Settings _______________________________ -->
|
||||||
|
|
||||||
<!-- Comment this out to disable updates !-->
|
<!-- Comment this out to disable updates !-->
|
||||||
<define name="UPDATE_CHECKING" unless="web || hl || neko || debug"/>
|
<define name="UPDATE_CHECKING" unless="web || hl || neko"/>
|
||||||
|
|
||||||
<!-- Comment this out to disable Discord RPC !-->
|
<!-- Comment this out to disable Discord RPC !-->
|
||||||
<section if="cpp">
|
<section if="cpp">
|
||||||
@@ -128,7 +131,6 @@
|
|||||||
<haxelib name="away3d" if="THREE_D_SUPPORT" />
|
<haxelib name="away3d" if="THREE_D_SUPPORT" />
|
||||||
<haxelib name="format" />
|
<haxelib name="format" />
|
||||||
<haxelib name="flxanimate" />
|
<haxelib name="flxanimate" />
|
||||||
<haxelib name="bin-serializer" />
|
|
||||||
<haxelib name="nape-haxe4" if="NAPE_ENABLED"/>
|
<haxelib name="nape-haxe4" if="NAPE_ENABLED"/>
|
||||||
|
|
||||||
<haxelib name="hscript-improved" />
|
<haxelib name="hscript-improved" />
|
||||||
@@ -170,8 +172,6 @@
|
|||||||
|
|
||||||
<!-- ______________________________ Haxedefines _____________________________ -->
|
<!-- ______________________________ Haxedefines _____________________________ -->
|
||||||
|
|
||||||
<haxeflag name="--macro" value="funkin.backend.system.macros.BuildInfo.printBuildInfo()" />
|
|
||||||
|
|
||||||
<haxedef name="FLX_NO_FOCUS_LOST_SCREEN" />
|
<haxedef name="FLX_NO_FOCUS_LOST_SCREEN" />
|
||||||
|
|
||||||
<!--Disable the Flixel core debugger. Automatically gets set whenever you compile in release mode!-->
|
<!--Disable the Flixel core debugger. Automatically gets set whenever you compile in release mode!-->
|
||||||
@@ -187,9 +187,6 @@
|
|||||||
<haxedef name="USE_ADAPTED_ASSETS" if="USE_ADAPTED_ASSETS" />
|
<haxedef name="USE_ADAPTED_ASSETS" if="USE_ADAPTED_ASSETS" />
|
||||||
<haxedef name="openfl_dpi_aware" if="openfl_dpi_aware" />
|
<haxedef name="openfl_dpi_aware" if="openfl_dpi_aware" />
|
||||||
|
|
||||||
<!-- Disable it for more concise compilation errors. -->
|
|
||||||
<haxedef name="message.reporting" value="pretty" />
|
|
||||||
|
|
||||||
<!-- _________________________________ Custom _______________________________ -->
|
<!-- _________________________________ Custom _______________________________ -->
|
||||||
|
|
||||||
<!--Place custom nodes like icons here (higher priority to override the HaxeFlixel icon)-->
|
<!--Place custom nodes like icons here (higher priority to override the HaxeFlixel icon)-->
|
||||||
+494
@@ -0,0 +1,494 @@
|
|||||||
|
// funkin source classes cannot be imported here
|
||||||
|
import haxe.io.Path;
|
||||||
|
import hxp.*;
|
||||||
|
import lime.tools.*;
|
||||||
|
import sys.FileSystem;
|
||||||
|
import sys.io.Process;
|
||||||
|
|
||||||
|
using StringTools;
|
||||||
|
|
||||||
|
class Project extends HXProject
|
||||||
|
{
|
||||||
|
static final TITLE:String = "Friday Night Funkin' - Codename Engine";
|
||||||
|
static final EXECUTABLE:String = "CodenameEngine";
|
||||||
|
static final VERSION:String = "1.0.1";
|
||||||
|
static final COMPANY:String = "Yoshman29";
|
||||||
|
static final PACKAGE:String = "com.codenamecrew.codenameengine";
|
||||||
|
static final MAIN_CLASS:String = "funkin.backend.system.MainApplication";
|
||||||
|
|
||||||
|
static final PRELOADER:String = "flixel.system.FlxPreloader";
|
||||||
|
static final SOURCE_FOLDERS:Array<String> = ["source"];
|
||||||
|
|
||||||
|
// Compile Flags
|
||||||
|
static final EMBED_ASSETS:CompileFlag = CompileFlag.get("EMBED_ASSETS");
|
||||||
|
static final PRELOAD_ALL:CompileFlag = CompileFlag.get("PRELOAD_ALL");
|
||||||
|
static final STRIPPED_COMPILE:CompileFlag = CompileFlag.get("STRIPPED_COMPILE");
|
||||||
|
static final UPDATE_CHECKING:CompileFlag = CompileFlag.get("UPDATE_CHECKING");
|
||||||
|
static final DISCORD_RPC:CompileFlag = CompileFlag.get("DISCORD_RPC");
|
||||||
|
static final MODCHARTING_FEATURES:CompileFlag = CompileFlag.get("MODCHARTING_FEATURES");
|
||||||
|
static final GITHUB_API:CompileFlag = CompileFlag.get("GITHUB_API");
|
||||||
|
static final COMPILE_ALL_CLASSES:CompileFlag = CompileFlag.get("COMPILE_ALL_CLASSES");
|
||||||
|
static final CUSTOM_CLASSES:CompileFlag = CompileFlag.get("CUSTOM_CLASSES");
|
||||||
|
static final ALLOW_MULTITHREADING:CompileFlag = CompileFlag.get("ALLOW_MULTITHREADING");
|
||||||
|
static final MOD_SUPPORT:CompileFlag = CompileFlag.get("MOD_SUPPORT");
|
||||||
|
static final TRANSLATIONS_SUPPORT:CompileFlag = CompileFlag.get("TRANSLATIONS_SUPPORT");
|
||||||
|
static final GLOBAL_SCRIPT:CompileFlag = CompileFlag.get("GLOBAL_SCRIPT");
|
||||||
|
static final SOFTCODED_STATES:CompileFlag = CompileFlag.get("SOFTCODED_STATES");
|
||||||
|
static final NDLLS_SUPPORTED:CompileFlag = CompileFlag.get("NDLLS_SUPPORTED");
|
||||||
|
static final USE_ADAPTED_ASSETS:CompileFlag = CompileFlag.get("USE_ADAPTED_ASSETS");
|
||||||
|
static final THREE_D_SUPPORT:CompileFlag = CompileFlag.get("THREE_D_SUPPORT");
|
||||||
|
static final NAPE_ENABLED:CompileFlag = CompileFlag.get("NAPE_ENABLED");
|
||||||
|
static final VIDEO_CUTSCENES:CompileFlag = CompileFlag.get("VIDEO_CUTSCENES");
|
||||||
|
static final SHOW_BUILD_ON_FPS:CompileFlag = CompileFlag.get("SHOW_BUILD_ON_FPS");
|
||||||
|
static final DARK_MODE_WINDOW:CompileFlag = CompileFlag.get("DARK_MODE_WINDOW");
|
||||||
|
|
||||||
|
public function new():Void
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
|
||||||
|
CompileFlag.project = this;
|
||||||
|
|
||||||
|
haxe.Log.trace = (v:Dynamic, ?info:haxe.PosInfos) ->
|
||||||
|
{
|
||||||
|
if (!isDisplay())
|
||||||
|
Sys.println(v);
|
||||||
|
};
|
||||||
|
|
||||||
|
doWelcomeHeader();
|
||||||
|
trace("Configuring project...");
|
||||||
|
trace("");
|
||||||
|
configureApp();
|
||||||
|
configureCompileFlags();
|
||||||
|
configureAssets();
|
||||||
|
configureLibs();
|
||||||
|
configureIcons();
|
||||||
|
trace("");
|
||||||
|
trace("Configured project");
|
||||||
|
trace("Starting build...");
|
||||||
|
trace("");
|
||||||
|
}
|
||||||
|
|
||||||
|
function getHaxeVersion():String {
|
||||||
|
var process = new Process("haxe", ["-version"]);
|
||||||
|
var version:String = "";
|
||||||
|
|
||||||
|
try {
|
||||||
|
version = process.stdout.readAll().toString().trim();
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
process.close();
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
function doWelcomeHeader() {
|
||||||
|
var haxeVersion = getHaxeVersion().trim();
|
||||||
|
var sleepChangeVersion = false;
|
||||||
|
|
||||||
|
var width = 60; // total banner width
|
||||||
|
|
||||||
|
inline function centerText(text:String, width:Int):String {
|
||||||
|
var innerWidth = width - 2;
|
||||||
|
var padding = Std.int(Math.max(0, Std.int((innerWidth - text.length) / 2)));
|
||||||
|
var left = StringTools.lpad("", " ", padding);
|
||||||
|
var right = StringTools.lpad("", " ", innerWidth - text.length - padding);
|
||||||
|
return "=" + left + text + right + "=";
|
||||||
|
}
|
||||||
|
|
||||||
|
inline function infoLine(label:String, value:String):String {
|
||||||
|
var innerWidth = width - 2;
|
||||||
|
if (label.length == 0) {
|
||||||
|
// no label: center the value
|
||||||
|
var padding = Std.int(Math.max(0, (innerWidth - value.length) / 2));
|
||||||
|
var left = StringTools.lpad("", " ", padding);
|
||||||
|
var right = StringTools.lpad("", " ", innerWidth - value.length - padding);
|
||||||
|
return "=" + left + value + right + "=";
|
||||||
|
} else {
|
||||||
|
var colonPos = Std.int(innerWidth / 2);
|
||||||
|
var labelPart = StringTools.lpad(label, " ", Std.int(Math.max(0, colonPos - 2)));
|
||||||
|
var valuePart = value;
|
||||||
|
var remainingSpace = Std.int(Math.max(0, innerWidth - (labelPart.length + 3 + valuePart.length)));
|
||||||
|
var rightPad = StringTools.lpad("", " ", remainingSpace);
|
||||||
|
return "=" + labelPart + " : " + valuePart + rightPad + "=";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var unicode = #if (target.unicode) true #else false #end;
|
||||||
|
|
||||||
|
trace('');
|
||||||
|
trace(StringTools.lpad("", "=", width));
|
||||||
|
trace(centerText(TITLE, width));
|
||||||
|
trace(StringTools.lpad("", "=", width));
|
||||||
|
trace(infoLine("Engine Version", 'v${VERSION}'));
|
||||||
|
trace(infoLine("Haxe Version", 'v${haxeVersion}'));
|
||||||
|
trace(StringTools.lpad("", "=", width));
|
||||||
|
|
||||||
|
try {
|
||||||
|
var lastBuiltWith:Null<String> = null;
|
||||||
|
var compiling = isDebug() ? "debug" : "release";
|
||||||
|
var target = isWeb() ? "html5" : (isIOS() ? "ios" : (isAndroid() ? "android" : (isWindows() ? "windows" : (isMac() ? "macos" : (isLinux() ? "linux" : "")))));
|
||||||
|
|
||||||
|
if (target == "") throw "Unknown target";
|
||||||
|
|
||||||
|
var exportPath = Sys.getCwd() + "/export/" + compiling + "/" + target + "/obj/Options.txt";
|
||||||
|
var options = sys.io.File.getContent(exportPath);
|
||||||
|
|
||||||
|
for (option in options.split("\n")) {
|
||||||
|
if (option.startsWith("haxe=")) {
|
||||||
|
lastBuiltWith = option.substr(5).trim();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastBuiltWith != null && lastBuiltWith.length > 0 && lastBuiltWith != haxeVersion) {
|
||||||
|
trace(infoLine("", unicode ? "⚠️ Haxe version mismatch!" : "[WARNING] Haxe version mismatch!"));
|
||||||
|
trace(infoLine("Last Built With", lastBuiltWith));
|
||||||
|
trace(infoLine("Current Version", haxeVersion));
|
||||||
|
trace(StringTools.lpad("", "=", width));
|
||||||
|
trace(infoLine("", "!!! Make sure to DELETE your EXPORT folders !!!"));
|
||||||
|
trace(StringTools.lpad("", "=", width));
|
||||||
|
sleepChangeVersion = true;
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
var targetPlatform = isWeb() ? "Web (HTML5)" : (isIOS() ? "iOS" : (isAndroid() ? "Android" : (isWindows() ? "Windows" : (isMac() ? "Mac" : (isLinux() ? "Linux" : "Unknown")))));
|
||||||
|
|
||||||
|
if (isHashLink())
|
||||||
|
targetPlatform = "Hashlink (" + targetPlatform + ")";
|
||||||
|
|
||||||
|
trace(infoLine("Target Platform", targetPlatform));
|
||||||
|
trace(infoLine("Build Type", isDebug() ? "Debug" : "Release"));
|
||||||
|
trace(infoLine("Build Date", Date.now().toString()));
|
||||||
|
trace(StringTools.lpad("", "=", width));
|
||||||
|
trace('');
|
||||||
|
|
||||||
|
if (sleepChangeVersion)
|
||||||
|
Sys.sleep(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
function configureApp():Void
|
||||||
|
{
|
||||||
|
trace("Configuring game...");
|
||||||
|
meta.title = TITLE;
|
||||||
|
meta.version = VERSION;
|
||||||
|
meta.company = COMPANY;
|
||||||
|
meta.packageName = PACKAGE;
|
||||||
|
|
||||||
|
app.main = MAIN_CLASS;
|
||||||
|
app.file = EXECUTABLE;
|
||||||
|
app.preloader = PRELOADER;
|
||||||
|
|
||||||
|
var buildDir = 'export/${isDebug() ? 'debug' : 'release'}/';
|
||||||
|
trace('Output directory: $buildDir');
|
||||||
|
app.path = buildDir;
|
||||||
|
|
||||||
|
sources = SOURCE_FOLDERS;
|
||||||
|
templatePaths.push(Path.combine(Haxelib.getPath(new Haxelib(#if lime "lime" #else "hxp" #end)), #if lime "templates" #else "" #end));
|
||||||
|
|
||||||
|
window.hardware = true;
|
||||||
|
window.vsync = false;
|
||||||
|
window.allowHighDPI = true;
|
||||||
|
|
||||||
|
if (isWeb())
|
||||||
|
window.resizable = true;
|
||||||
|
|
||||||
|
if (isDesktop())
|
||||||
|
{
|
||||||
|
window.orientation = Orientation.LANDSCAPE;
|
||||||
|
window.fullscreen = false;
|
||||||
|
window.resizable = true;
|
||||||
|
window.vsync = false;
|
||||||
|
} else if (isMobile())
|
||||||
|
{
|
||||||
|
window.orientation = Orientation.LANDSCAPE;
|
||||||
|
window.fullscreen = true;
|
||||||
|
window.resizable = false;
|
||||||
|
window.borderless = true;
|
||||||
|
window.width = 0;
|
||||||
|
window.height = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function configureCompileFlags()
|
||||||
|
{
|
||||||
|
trace("Configuring compile flags...");
|
||||||
|
|
||||||
|
setDefine("disable-version-check");
|
||||||
|
setHaxedef("disable-version-check");
|
||||||
|
setHaxedef("no-deprecation-warnings");
|
||||||
|
|
||||||
|
// DO NOT REMOVE!! ALLOWS ME TO DO REGIONS LIKE IN C# AND KEEP CODE ORGANIZED. REMOVING IT WOULD BREAK THE ENGINE
|
||||||
|
setHaxedef("REGION");
|
||||||
|
|
||||||
|
setHaxedef("SAVE_PATH", EXECUTABLE);
|
||||||
|
setHaxedef("SAVE_NAME", "save-default");
|
||||||
|
setHaxedef("SAVE_OPTIONS_PATH", EXECUTABLE);
|
||||||
|
setHaxedef("SAVE_OPTIONS_NAME", "options");
|
||||||
|
|
||||||
|
PRELOAD_ALL.integrate(!isWeb());
|
||||||
|
EMBED_ASSETS.integrate(false);
|
||||||
|
|
||||||
|
UPDATE_CHECKING.integrate(!isWeb() && !isHashLink());
|
||||||
|
DISCORD_RPC.integrate(isCPP() && isDesktop());
|
||||||
|
STRIPPED_COMPILE.integrate(false); //should be isRelease() if you want to use it
|
||||||
|
MODCHARTING_FEATURES.integrate(STRIPPED_COMPILE.isDisabled());
|
||||||
|
GITHUB_API.integrate(!isWeb() && !isHashLink());
|
||||||
|
COMPILE_ALL_CLASSES.integrate(STRIPPED_COMPILE.isDisabled());
|
||||||
|
CUSTOM_CLASSES.integrate(STRIPPED_COMPILE.isDisabled());
|
||||||
|
ALLOW_MULTITHREADING.integrate(!isWeb());
|
||||||
|
MOD_SUPPORT.integrate(!isWeb());
|
||||||
|
TRANSLATIONS_SUPPORT.integrate(true);
|
||||||
|
GLOBAL_SCRIPT.integrate(true);
|
||||||
|
SOFTCODED_STATES.integrate(true);
|
||||||
|
NDLLS_SUPPORTED.integrate(!isWeb() && !isHashLink());
|
||||||
|
USE_ADAPTED_ASSETS.integrate(!isWeb());
|
||||||
|
THREE_D_SUPPORT.integrate(STRIPPED_COMPILE.isDisabled());
|
||||||
|
NAPE_ENABLED.integrate(STRIPPED_COMPILE.isDisabled());
|
||||||
|
VIDEO_CUTSCENES.integrate(isCPP() && (isDesktop() || isMobile()));
|
||||||
|
SHOW_BUILD_ON_FPS.integrate(true);
|
||||||
|
DARK_MODE_WINDOW.integrate(true);
|
||||||
|
|
||||||
|
setDefine("FLX_NO_GENERIC"); // Disable a optimization, to allow reflection to use more functions
|
||||||
|
|
||||||
|
if (DISCORD_RPC.isEnabled())
|
||||||
|
setHaxedef("DISCORD_DISABLE_IO_THREAD");
|
||||||
|
|
||||||
|
if (MODCHARTING_FEATURES.isEnabled())
|
||||||
|
{
|
||||||
|
setHaxedef("FM_ENGINE", "CODENAME");
|
||||||
|
setHaxedef("FM_ENGINE_VERSION", "1.0");
|
||||||
|
addMacroFlag("modchart.backend.macros.Macro.includeFiles()");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (COMPILE_ALL_CLASSES.isEnabled())
|
||||||
|
{
|
||||||
|
addHaxeFlag("-dce no");
|
||||||
|
addMacroFlag("funkin.backend.system.macros.Macros.addAdditionalClasses()");
|
||||||
|
}
|
||||||
|
|
||||||
|
addMacroFlag("funkin.backend.system.macros.Macros.initMacros()");
|
||||||
|
|
||||||
|
if (isDebug())
|
||||||
|
setHaxedef("HXCPP_DEBUG_LINK");
|
||||||
|
|
||||||
|
environment.set("HAXEPATH", "./");
|
||||||
|
|
||||||
|
setHaxedef("HXCPP_CHECK_POINTER");
|
||||||
|
setHaxedef("HXCPP_STACK_LINE");
|
||||||
|
setHaxedef("HXCPP_CATCH_SEGV");
|
||||||
|
setHaxedef("hscriptPos");
|
||||||
|
setHaxedef("EXPERIMENTAL_FLXGRAPHIC_DESTROY_FIX");
|
||||||
|
setHaxedef("FLX_NO_FOCUS_LOST_SCREEN");
|
||||||
|
|
||||||
|
if (isRelease())
|
||||||
|
{
|
||||||
|
setHaxedef("FLX_NO_DEBUG");
|
||||||
|
setHaxedef("analyzer-optimize");
|
||||||
|
}
|
||||||
|
setHaxedef("openfl_dpi_aware");
|
||||||
|
}
|
||||||
|
|
||||||
|
function configureAssets()
|
||||||
|
{
|
||||||
|
trace("Configuring assets...");
|
||||||
|
|
||||||
|
var shouldPreload = PRELOAD_ALL.isEnabled();
|
||||||
|
var shouldEmbed = EMBED_ASSETS.isEnabled();
|
||||||
|
|
||||||
|
includeAssetLibrary("default", shouldEmbed, shouldPreload);
|
||||||
|
addAssetPath("assets", shouldEmbed);
|
||||||
|
addAsset("art/readme.txt", "do NOT readme.txt", false);
|
||||||
|
|
||||||
|
if (isDesktop())
|
||||||
|
addAsset("building/alsoft.txt", 'plugins/alsoft.${isWindows() ? "ini" : "conf"}', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function configureLibs()
|
||||||
|
{
|
||||||
|
trace("Configuring libraries...");
|
||||||
|
|
||||||
|
includeHaxelib("flixel");
|
||||||
|
includeHaxelib("flixel-addons");
|
||||||
|
includeHaxelib("format");
|
||||||
|
includeHaxelib("flxanimate");
|
||||||
|
includeHaxelib("hscript-improved");
|
||||||
|
includeHaxelib("markdown");
|
||||||
|
|
||||||
|
if (VIDEO_CUTSCENES.isEnabled())
|
||||||
|
includeHaxelib("hxvlc");
|
||||||
|
if (THREE_D_SUPPORT.isEnabled())
|
||||||
|
includeHaxelib("away3d");
|
||||||
|
if (NAPE_ENABLED.isEnabled())
|
||||||
|
includeHaxelib("nape-haxe4");
|
||||||
|
if (DISCORD_RPC.isEnabled())
|
||||||
|
includeHaxelib("hxdiscord_rpc");
|
||||||
|
if (MODCHARTING_FEATURES.isEnabled())
|
||||||
|
includeHaxelib("funkin-modchart");
|
||||||
|
if (isDebug())
|
||||||
|
includeHaxelib("hxcpp-debug-server");
|
||||||
|
}
|
||||||
|
|
||||||
|
function configureIcons()
|
||||||
|
{
|
||||||
|
trace("Configuring app icons...");
|
||||||
|
// TODO: ADD MOBILE ICONS
|
||||||
|
for (size in [16, 32, 64])
|
||||||
|
addIcon('art/icon${size}.png', size);
|
||||||
|
addIcon("art/icons/iconOG.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
function includeHaxelib(name:String, version:String = ""):Void
|
||||||
|
{
|
||||||
|
haxelibs.push(new Haxelib(name, version));
|
||||||
|
}
|
||||||
|
|
||||||
|
function addAsset(path:String, ?rename:String, embed:Bool = false):Void
|
||||||
|
{
|
||||||
|
var asset = new Asset(path, rename, null, embed, true);
|
||||||
|
asset.library = "default";
|
||||||
|
assets.push(asset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addAssetPath(path:String, ?rename:String, embed:Bool = false):Void
|
||||||
|
{
|
||||||
|
if (path == "") return;
|
||||||
|
|
||||||
|
var targetPath = Path.addTrailingSlash(rename ?? path);
|
||||||
|
|
||||||
|
if (!FileSystem.exists(path))
|
||||||
|
trace('[ERROR] Path "${path}" was not found');
|
||||||
|
else if (!FileSystem.isDirectory(path))
|
||||||
|
trace('[ERROR] Path "${path}" needs to be a directory.');
|
||||||
|
|
||||||
|
for (file in FileSystem.readDirectory(path))
|
||||||
|
{
|
||||||
|
if (FileSystem.isDirectory('${path}/${file}'))
|
||||||
|
addAssetPath('${path}/${file}', '${targetPath}${file}', embed);
|
||||||
|
else
|
||||||
|
addAsset('${path}/${file}', '${targetPath}${file}', embed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function includeAssetLibrary(name:String, embed:Bool = false, preload:Bool = false):Void
|
||||||
|
{
|
||||||
|
this.libraries.push(new Library('', name, null, embed, preload, false, ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline function addIcon(icon:String, ?size:Int):Void
|
||||||
|
icons.push(new Icon(icon, size));
|
||||||
|
|
||||||
|
inline function addHaxeFlag(value:String):Void
|
||||||
|
haxeflags.push(value);
|
||||||
|
|
||||||
|
inline function addMacroFlag(value:String):Void
|
||||||
|
addHaxeFlag('--macro ${value}');
|
||||||
|
|
||||||
|
inline function isDebug():Bool
|
||||||
|
return debug;
|
||||||
|
|
||||||
|
inline function isRelease():Bool
|
||||||
|
return !isDebug();
|
||||||
|
|
||||||
|
inline function isDisplay():Bool
|
||||||
|
return command == "display";
|
||||||
|
|
||||||
|
inline function isWeb():Bool
|
||||||
|
return platformType == PlatformType.WEB;
|
||||||
|
|
||||||
|
inline function isMobile():Bool
|
||||||
|
return platformType == PlatformType.MOBILE;
|
||||||
|
|
||||||
|
inline function isDesktop():Bool
|
||||||
|
return platformType == PlatformType.DESKTOP;
|
||||||
|
|
||||||
|
inline function isWindows():Bool
|
||||||
|
return target == Platform.WINDOWS;
|
||||||
|
|
||||||
|
inline function isMac():Bool
|
||||||
|
return target == Platform.MAC;
|
||||||
|
|
||||||
|
inline function isLinux():Bool
|
||||||
|
return target == Platform.LINUX;
|
||||||
|
|
||||||
|
inline function isAndroid():Bool
|
||||||
|
return target == Platform.ANDROID;
|
||||||
|
|
||||||
|
inline function isIOS():Bool
|
||||||
|
return target == Platform.IOS;
|
||||||
|
|
||||||
|
inline function isHashLink():Bool
|
||||||
|
return targetFlags.exists("hl");
|
||||||
|
|
||||||
|
inline function isCPP():Bool
|
||||||
|
return defines.exists("cpp");
|
||||||
|
|
||||||
|
public inline function getHaxedef(name:String):Null<Dynamic>
|
||||||
|
return haxedefs.get(name);
|
||||||
|
|
||||||
|
public inline function setHaxedef(name:String, ?value:String):Void
|
||||||
|
haxedefs.set(name, value ?? "");
|
||||||
|
|
||||||
|
public inline function unsetHaxedef(name:String):Void
|
||||||
|
haxedefs.remove(name);
|
||||||
|
|
||||||
|
public inline function getDefine(name:String):Null<Dynamic>
|
||||||
|
return defines.get(name);
|
||||||
|
|
||||||
|
public inline function setDefine(name:String, ?value:String):Void
|
||||||
|
defines.set(name, value ?? "");
|
||||||
|
|
||||||
|
public inline function unsetDefine(name:String):Void
|
||||||
|
defines.remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
class CompileFlag {
|
||||||
|
public static final INVERSION:String = "NO_";
|
||||||
|
public static var project:Project;
|
||||||
|
|
||||||
|
public static function get(name:String):CompileFlag {
|
||||||
|
return new CompileFlag(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
var name:String;
|
||||||
|
public function new(name:String) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function enable(stopPropagation:Bool = false):Void
|
||||||
|
{
|
||||||
|
project.setHaxedef(name);
|
||||||
|
project.setDefine(name);
|
||||||
|
if (!stopPropagation)
|
||||||
|
getInverse().disable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function disable(stopPropagation:Bool = false):Void
|
||||||
|
{
|
||||||
|
project.unsetHaxedef(name);
|
||||||
|
project.unsetDefine(name);
|
||||||
|
if (!stopPropagation)
|
||||||
|
getInverse().enable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function integrate(defaultEnabled:Bool = false):Void {
|
||||||
|
var inverse = getInverse();
|
||||||
|
|
||||||
|
if (isEnabled()) inverse.disable(true); // Makes sure the inverse is disabled if it wasn't already
|
||||||
|
else if (inverse.isEnabled()) disable(true); // If the inverse is enabled, disable this
|
||||||
|
else (defaultEnabled ? enable : disable)(true); // Set to the default state otherwise
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isEnabled():Bool {
|
||||||
|
return project.haxedefs.exists(name) || project.defines.exists(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isDisabled():Bool {
|
||||||
|
return getInverse().isEnabled() || !isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getInverse():CompileFlag {
|
||||||
|
var inversionName = name;
|
||||||
|
if (!inversionName.startsWith(INVERSION))
|
||||||
|
inversionName = INVERSION + inversionName;
|
||||||
|
return new CompileFlag(inversionName);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,7 +21,6 @@ import flixel.math.FlxMath;
|
|||||||
import flixel.math.FlxPoint;
|
import flixel.math.FlxPoint;
|
||||||
import flixel.system.FlxAssets.FlxSoundAsset;
|
import flixel.system.FlxAssets.FlxSoundAsset;
|
||||||
import flixel.tweens.FlxTween;
|
import flixel.tweens.FlxTween;
|
||||||
import flixel.util.FlxDestroyUtil;
|
|
||||||
import flixel.util.FlxSignal;
|
import flixel.util.FlxSignal;
|
||||||
import flixel.util.FlxStringUtil;
|
import flixel.util.FlxStringUtil;
|
||||||
import flixel.FlxBasic;
|
import flixel.FlxBasic;
|
||||||
@@ -137,18 +136,11 @@ class FlxSound extends FlxBasic {
|
|||||||
public var radius:Float;
|
public var radius:Float;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the proximity alters the pan or not.
|
* Whether the proximity alters the pan or not
|
||||||
* @since raltyMod
|
* @since raltyMod
|
||||||
*/
|
*/
|
||||||
public var proximityPan:Bool;
|
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.
|
* Stores for how much channels are in the loaded sound.
|
||||||
* @since raltyMod
|
* @since raltyMod
|
||||||
@@ -310,8 +302,6 @@ class FlxSound extends FlxBasic {
|
|||||||
_lastTime = null;
|
_lastTime = null;
|
||||||
|
|
||||||
if (destroySound) {
|
if (destroySound) {
|
||||||
scrollFactor = FlxDestroyUtil.put(scrollFactor);
|
|
||||||
|
|
||||||
if (group != null) group.remove(this);
|
if (group != null) group.remove(this);
|
||||||
|
|
||||||
if (_channel != null) {
|
if (_channel != null) {
|
||||||
@@ -358,24 +348,15 @@ class FlxSound extends FlxBasic {
|
|||||||
|
|
||||||
_amplitudeUpdate = true;
|
_amplitudeUpdate = true;
|
||||||
|
|
||||||
// Distance-based volume control
|
// Distance-based volume control (TODO for Ralty: REDO THIS)
|
||||||
if (target != null) {
|
if (target != null) {
|
||||||
var targetPosition = target.getPosition(), position = getPosition();
|
var targetPosition = target.getPosition();
|
||||||
var camera = camera;
|
var radialMultiplier = targetPosition.distanceTo(FlxPoint.weak(x, y)) / radius;
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
targetPosition.put();
|
||||||
position.put();
|
radialMultiplier = 1 - FlxMath.bound(radialMultiplier, 0, 1);
|
||||||
|
|
||||||
|
_volumeAdjust = radialMultiplier;
|
||||||
|
if (proximityPan) _panAdjust = (x - target.x) / radius;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
_volumeAdjust = 1.0;
|
_volumeAdjust = 1.0;
|
||||||
@@ -555,15 +536,12 @@ class FlxSound extends FlxBasic {
|
|||||||
* @param Pan Whether panning should be used in addition to the volume changes.
|
* @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).
|
* @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, ?scrollFactor:FlxPoint):FlxSound {
|
public function proximity(x = 0.0, y = 0.0, ?targetObject:FlxObject, ?radius:Float, pan = true):FlxSound {
|
||||||
setPosition(x, y);
|
setPosition(x, y);
|
||||||
if (targetObject != null) this.target = targetObject;
|
if (targetObject != null) this.target = targetObject;
|
||||||
if (radius != null) this.radius = radius;
|
if (radius != null) this.radius = radius;
|
||||||
proximityPan = pan;
|
proximityPan = pan;
|
||||||
|
|
||||||
if (this.scrollFactor == null) this.scrollFactor = FlxPoint.get(1, 1);
|
|
||||||
if (scrollFactor != null) this.scrollFactor.copyFrom(scrollFactor);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -571,28 +549,14 @@ class FlxSound extends FlxBasic {
|
|||||||
* Helper function to set the coordinates of this object.
|
* Helper function to set the coordinates of this object.
|
||||||
* Sound positioning is used in conjunction with proximity/panning.
|
* Sound positioning is used in conjunction with proximity/panning.
|
||||||
*
|
*
|
||||||
* @param x The new x position
|
* @param x The new x position
|
||||||
* @param y The new y position
|
* @param y The new y position
|
||||||
*/
|
*/
|
||||||
public function setPosition(x = 0.0, y = 0.0):Void {
|
public inline function setPosition(x = 0.0, y = 0.0):Void {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
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.
|
* Call this function to play the sound - also works on paused sounds.
|
||||||
*
|
*
|
||||||
@@ -718,7 +682,7 @@ class FlxSound extends FlxBasic {
|
|||||||
_paused = false;
|
_paused = false;
|
||||||
_time = startTime;
|
_time = startTime;
|
||||||
_lastTime = FlxG.game.getTicks();
|
_lastTime = FlxG.game.getTicks();
|
||||||
if (_channel == null || !_channel.__isValid || _source == null #if lime_cffi || _source.__backend.disposed #end)
|
if (_channel == null || !_channel.__isValid || _source == null #if lime_cffi || _source.__backend.disposed || _source.__backend.handle == null #end)
|
||||||
makeChannel();
|
makeChannel();
|
||||||
|
|
||||||
if (_channel != null) {
|
if (_channel != null) {
|
||||||
@@ -769,8 +733,7 @@ class FlxSound extends FlxBasic {
|
|||||||
_lastTime = FlxG.game.getTicks();
|
_lastTime = FlxG.game.getTicks();
|
||||||
_time = loopTime;
|
_time = loopTime;
|
||||||
}
|
}
|
||||||
else if (_source != null)
|
else _channel.loops = 999;
|
||||||
_source.loops = 999;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -800,7 +763,7 @@ class FlxSound extends FlxBasic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline function get_playing():Bool @:privateAccess
|
inline function get_playing():Bool @:privateAccess
|
||||||
return _source != null && _source.playing;
|
return _channel != null && _channel.__isValid && _source.playing;
|
||||||
|
|
||||||
inline function get_volume():Float
|
inline function get_volume():Float
|
||||||
return _volume;
|
return _volume;
|
||||||
@@ -833,12 +796,12 @@ class FlxSound extends FlxBasic {
|
|||||||
inline function get_buffer():AudioBuffer
|
inline function get_buffer():AudioBuffer
|
||||||
@:privateAccess return _sound != null ? _sound.__buffer : null;
|
@:privateAccess return _sound != null ? _sound.__buffer : null;
|
||||||
|
|
||||||
inline function update_amplitude():Void @:privateAccess {
|
function update_amplitude():Void @:privateAccess {
|
||||||
if (_channel != null && _channel.__updatePeaks(get_time()) && _amplitudeUpdate) {
|
if (_channel == null || !_channel.__updatePeaks(get_time()) || !_amplitudeUpdate) return;
|
||||||
_amplitudeUpdate = false;
|
|
||||||
_amplitudeLeft = _channel.__leftPeak;
|
_amplitudeUpdate = false;
|
||||||
_amplitudeRight = _channel.__rightPeak;
|
_amplitudeLeft = _channel.__leftPeak;
|
||||||
}
|
_amplitudeRight = _channel.__rightPeak;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline function get_amplitudeLeft():Float {
|
inline function get_amplitudeLeft():Float {
|
||||||
@@ -866,27 +829,30 @@ class FlxSound extends FlxBasic {
|
|||||||
inline function get_pitch():Float
|
inline function get_pitch():Float
|
||||||
return _pitch;
|
return _pitch;
|
||||||
|
|
||||||
inline function set_pitch(v:Float):Float {
|
function set_pitch(v:Float):Float {
|
||||||
_realPitch = (_pitch = v) * _timeScaleAdjust;
|
_realPitch = (_pitch = v) * _timeScaleAdjust;
|
||||||
if (_source != null) _source.pitch = _realPitch;
|
if (_channel != null) _channel.pitch = _realPitch;
|
||||||
return _pitch;
|
return _pitch;
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
|
|
||||||
function set_looped(v:Bool):Bool {
|
function set_looped(v:Bool):Bool {
|
||||||
if (playing) _source.loops = v ? 999 : 0;
|
if (playing) {
|
||||||
|
if (v) _channel.loops = 999;
|
||||||
|
else _channel.loops = 0;
|
||||||
|
}
|
||||||
return looped = v;
|
return looped = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
function set_loopTime(v:Float):Float {
|
function set_loopTime(v:Float):Float {
|
||||||
if (playing) _source.loopTime = v;
|
if (playing) _channel.loopTime = v;
|
||||||
return loopTime = v;
|
return loopTime = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
function set_endTime(v:Null<Float>):Null<Float> {
|
function set_endTime(v:Null<Float>):Null<Float> {
|
||||||
if (playing) {
|
if (playing) {
|
||||||
if (v != null && v > 0 && v < _length) _source.length = v;
|
if (v != null && v > 0 && v < _length) _channel.endTime = v;
|
||||||
else _source.length = null;
|
else _channel.endTime = null;
|
||||||
}
|
}
|
||||||
return endTime = v;
|
return endTime = v;
|
||||||
}
|
}
|
||||||
@@ -898,7 +864,7 @@ class FlxSound extends FlxBasic {
|
|||||||
return _time;
|
return _time;
|
||||||
}
|
}
|
||||||
function get_time():Float {
|
function get_time():Float {
|
||||||
if (_source == null || /*AudioManager.context == null*/funkin.backend.system.Main.audioDisconnected) return _time;
|
if (_channel == null || @:privateAccess !_channel.__isValid || /*AudioManager.context == null*/funkin.backend.system.Main.audioDisconnected) return _time;
|
||||||
|
|
||||||
final sourceTime = _source.currentTime - _source.offset - _offset;
|
final sourceTime = _source.currentTime - _source.offset - _offset;
|
||||||
if (!_source.playing || _realPitch <= 0) {
|
if (!_source.playing || _realPitch <= 0) {
|
||||||
@@ -937,21 +903,24 @@ class FlxSound extends FlxBasic {
|
|||||||
return _time = time;
|
return _time = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_offset():Float return _offset;
|
inline function get_offset():Float return _offset;
|
||||||
function set_offset(offset:Float):Float {
|
inline function set_offset(offset:Float):Float {
|
||||||
if (_offset == (_offset = offset)) return offset;
|
if (_offset == (_offset = offset)) return offset;
|
||||||
//time = time + _offset;
|
//time = time + _offset;
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_length():Float return _length - _offset;
|
inline function get_length():Float return _length - _offset;
|
||||||
|
|
||||||
//function get_latency():Float return _source != null ? _source.latency : 0;
|
/*function get_latency():Float {
|
||||||
|
if (_channel != null) return _source.latency;
|
||||||
|
return 0;
|
||||||
|
}*/
|
||||||
|
|
||||||
override function toString():String {
|
override function toString():String {
|
||||||
return FlxStringUtil.getDebugString([
|
return FlxStringUtil.getDebugString([
|
||||||
LabelValuePair.weak("playing", playing),
|
LabelValuePair.weak("playing", playing),
|
||||||
LabelValuePair.weak("time", time),
|
LabelValuePair.weak("time", _time),
|
||||||
LabelValuePair.weak("length", length),
|
LabelValuePair.weak("length", length),
|
||||||
LabelValuePair.weak("volume", volume),
|
LabelValuePair.weak("volume", volume),
|
||||||
LabelValuePair.weak("pitch", pitch)
|
LabelValuePair.weak("pitch", pitch)
|
||||||
|
|||||||
@@ -70,8 +70,6 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
|||||||
@:noCompletion public var atlasPlayingAnim:String;
|
@:noCompletion public var atlasPlayingAnim:String;
|
||||||
@:noCompletion public var atlasPath:String;
|
@:noCompletion public var atlasPath:String;
|
||||||
|
|
||||||
var _rect2:FlxRect;
|
|
||||||
|
|
||||||
public function new(?X:Float = 0, ?Y:Float = 0, ?SimpleGraphic:FlxGraphicAsset)
|
public function new(?X:Float = 0, ?Y:Float = 0, ?SimpleGraphic:FlxGraphicAsset)
|
||||||
{
|
{
|
||||||
super(X, Y);
|
super(X, Y);
|
||||||
@@ -114,7 +112,6 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
|||||||
spr.transformMatrix = casted.transformMatrix;
|
spr.transformMatrix = casted.transformMatrix;
|
||||||
spr.matrixExposed = casted.matrixExposed;
|
spr.matrixExposed = casted.matrixExposed;
|
||||||
spr.animOffsets = casted.animOffsets.copy();
|
spr.animOffsets = casted.animOffsets.copy();
|
||||||
spr.zoomFactor = casted.zoomFactor;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return spr;
|
return spr;
|
||||||
@@ -134,11 +131,6 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override function initVars() {
|
|
||||||
super.initVars();
|
|
||||||
_rect2 = FlxRect.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function loadSprite(path:String, Unique:Bool = false, Key:String = null)
|
public function loadSprite(path:String, Unique:Bool = false, Key:String = null)
|
||||||
{
|
{
|
||||||
var noExt = Path.withoutExtension(path);
|
var noExt = Path.withoutExtension(path);
|
||||||
@@ -234,8 +226,6 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
|||||||
animOffsets = null;
|
animOffsets = null;
|
||||||
}
|
}
|
||||||
super.destroy();
|
super.destroy();
|
||||||
|
|
||||||
_rect2 = FlxDestroyUtil.put(_rect2);
|
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
|
|
||||||
@@ -243,40 +233,27 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
|||||||
private inline function __shouldDoZoomFactor()
|
private inline function __shouldDoZoomFactor()
|
||||||
return zoomFactorEnabled && zoomFactor != 1;
|
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
|
public override function getScreenBounds(?newRect:FlxRect, ?camera:FlxCamera):FlxRect
|
||||||
{
|
{
|
||||||
if (camera == null)
|
if (camera == null)
|
||||||
camera = FlxG.camera;
|
camera = FlxG.camera;
|
||||||
|
|
||||||
newRect = super.getScreenBounds(newRect, camera);
|
var r = super.getScreenBounds(newRect, camera);
|
||||||
|
|
||||||
if(__shouldDoZoomFactor()) {
|
if(__shouldDoZoomFactor()) {
|
||||||
__prepareZoomFactor(_rect2, camera);
|
r.x -= camera.width / 2;
|
||||||
newRect.set(
|
r.y -= camera.height / 2;
|
||||||
(newRect.x - _rect2.x) * _rect2.width + _rect2.x,
|
|
||||||
(newRect.y - _rect2.y) * _rect2.height + _rect2.y,
|
var ratio = (camera.zoom > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.zoom, 1, zoomFactor));
|
||||||
newRect.width * _rect2.width,
|
r.x *= ratio;
|
||||||
newRect.height * _rect2.height,
|
r.y *= ratio;
|
||||||
);
|
r.width *= ratio;
|
||||||
|
r.height *= ratio;
|
||||||
|
|
||||||
|
r.x += camera.width / 2;
|
||||||
|
r.y += camera.height / 2;
|
||||||
}
|
}
|
||||||
return newRect;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
override public function isOnScreen(?camera:FlxCamera):Bool
|
override public function isOnScreen(?camera:FlxCamera):Bool
|
||||||
@@ -296,16 +273,14 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
|||||||
// ZOOM FACTOR RENDERING
|
// ZOOM FACTOR RENDERING
|
||||||
public override function doAdditionalMatrixStuff(matrix:FlxMatrix, camera:FlxCamera)
|
public override function doAdditionalMatrixStuff(matrix:FlxMatrix, camera:FlxCamera)
|
||||||
{
|
{
|
||||||
// no need to...
|
super.doAdditionalMatrixStuff(matrix, camera);
|
||||||
//super.doAdditionalMatrixStuff(matrix, camera);
|
|
||||||
if(__shouldDoZoomFactor()) {
|
if(__shouldDoZoomFactor()) {
|
||||||
__prepareZoomFactor(_rect, camera);
|
matrix.translate(-camera.width / 2, -camera.height / 2);
|
||||||
matrix.setTo(
|
|
||||||
matrix.a * _rect.width, matrix.b * _rect.height,
|
var requestedZoom = (camera.zoom >= 0 ? Math.max : Math.min)(FlxMath.lerp(1, camera.zoom, zoomFactor), 0);
|
||||||
matrix.c * _rect.width, matrix.d * _rect.height,
|
var diff = requestedZoom / camera.zoom;
|
||||||
(matrix.tx - _rect.x) * _rect.width + _rect.x,
|
matrix.scale(diff, diff);
|
||||||
(matrix.ty - _rect.y) * _rect.height + _rect.y,
|
matrix.translate(camera.width / 2, camera.height / 2);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -236,12 +236,6 @@ class MusicBeatSubstate extends FlxSubState implements IBeatCancellableReceiver
|
|||||||
super.openSubState(e.substate is FlxSubState ? cast e.substate : subState);
|
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) {
|
public override function onResize(w:Int, h:Int) {
|
||||||
super.onResize(w, h);
|
super.onResize(w, h);
|
||||||
event("onResize", EventManager.get(ResizeEvent).recycle(w, h, null, null));
|
event("onResize", EventManager.get(ResizeEvent).recycle(w, h, null, null));
|
||||||
|
|||||||
@@ -97,41 +97,6 @@ class Chart {
|
|||||||
data.setFieldDefault("vocalsSuffix", "");
|
data.setFieldDefault("vocalsSuffix", "");
|
||||||
data.setFieldDefault("needsVoices", true);
|
data.setFieldDefault("needsVoices", true);
|
||||||
data.setFieldDefault("difficulties", []);
|
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("variants", []);
|
||||||
data.setFieldDefault("metas", []);
|
data.setFieldDefault("metas", []);
|
||||||
|
|
||||||
@@ -335,7 +300,6 @@ class Chart {
|
|||||||
var eventsPath = '$songPath/events$variantSuffix.json', events = filterEventsForSaving(chart.events, false, true);
|
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));
|
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
|
#end
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ typedef ChartMetaData = {
|
|||||||
public var ?icon:String;
|
public var ?icon:String;
|
||||||
public var ?color:FlxColor;
|
public var ?color:FlxColor;
|
||||||
|
|
||||||
public var ?excludedGameModes:Array<String>;
|
public var ?coopAllowed:Bool;
|
||||||
|
public var ?opponentModeAllowed:Bool;
|
||||||
|
|
||||||
public var ?metas:Map<String, ChartMetaData>;
|
public var ?metas:Map<String, ChartMetaData>;
|
||||||
public var ?instSuffix:String;
|
public var ?instSuffix:String;
|
||||||
|
|||||||
@@ -179,8 +179,7 @@ class EventsData {
|
|||||||
finalParams.push({
|
finalParams.push({
|
||||||
name: paramData.name,
|
name: paramData.name,
|
||||||
type: hscriptInterp.expr(hscriptParser.parseString(paramData.type)),
|
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);}
|
} catch (e) {trace('Error parsing event param ${paramData.name} - ${eventName}: $e'); finalParams.push(null);}
|
||||||
}
|
}
|
||||||
@@ -197,7 +196,6 @@ typedef EventInfoFile = {
|
|||||||
var name:String;
|
var name:String;
|
||||||
var type:String;
|
var type:String;
|
||||||
var defaultValue:Dynamic;
|
var defaultValue:Dynamic;
|
||||||
var ?saveIfDefault:Bool;
|
|
||||||
}>;
|
}>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class PsychParser {
|
|||||||
note.time, // TIME
|
note.time, // TIME
|
||||||
note.id, // DATA
|
note.id, // DATA
|
||||||
note.sLen, // SUSTAIN LENGTH
|
note.sLen, // SUSTAIN LENGTH
|
||||||
chart.noteTypes.getDefault([""])[note.type - 1] // NOTE TYPE
|
chart.noteTypes.getDefault([""])[note.type] // NOTE TYPE
|
||||||
];
|
];
|
||||||
|
|
||||||
if ((swagSection.mustHitSection && strumLine.type == OPPONENT) ||
|
if ((swagSection.mustHitSection && strumLine.type == OPPONENT) ||
|
||||||
|
|||||||
@@ -55,6 +55,9 @@ class GlobalScript {
|
|||||||
reloading = false;
|
reloading = false;
|
||||||
MusicBeatState.ALLOW_DEV_RELOAD = _lastAllow_Reload;
|
MusicBeatState.ALLOW_DEV_RELOAD = _lastAllow_Reload;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PlayerSettings.solo.controls.DEV_CONSOLE)
|
||||||
|
NativeAPI.allocConsole();
|
||||||
});
|
});
|
||||||
FlxG.signals.preDraw.add(function() {
|
FlxG.signals.preDraw.add(function() {
|
||||||
call("preDraw");
|
call("preDraw");
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
package funkin.backend.scripting;
|
package funkin.backend.scripting;
|
||||||
|
|
||||||
|
#if ALLOW_MULTITHREADING
|
||||||
|
import sys.thread.Thread;
|
||||||
|
#end
|
||||||
|
|
||||||
import hscript.IHScriptCustomBehaviour;
|
import hscript.IHScriptCustomBehaviour;
|
||||||
|
|
||||||
class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBehaviour {
|
class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBehaviour {
|
||||||
|
var thread:#if ALLOW_MULTITHREADING Thread #else Dynamic #end;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Script being ran.
|
* Script being ran.
|
||||||
*/
|
*/
|
||||||
@@ -40,6 +46,13 @@ class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBe
|
|||||||
|
|
||||||
script.load();
|
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));
|
__variables = Type.getInstanceFields(Type.getClass(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +69,7 @@ class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBe
|
|||||||
|
|
||||||
public function call(func:String, args:Array<Dynamic>) {
|
public function call(func:String, args:Array<Dynamic>) {
|
||||||
#if ALLOW_MULTITHREADING
|
#if ALLOW_MULTITHREADING
|
||||||
funkin.backend.utils.ThreadUtil.execAsync(() -> {
|
thread.events.run(function() {
|
||||||
callEnded = false;
|
callEnded = false;
|
||||||
returnValue = script.call(func, args);
|
returnValue = script.call(func, args);
|
||||||
callEnded = true;
|
callEnded = true;
|
||||||
@@ -72,5 +85,13 @@ class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBe
|
|||||||
script.call("destroy");
|
script.call("destroy");
|
||||||
script.destroy();
|
script.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ALLOW_MULTITHREADING
|
||||||
|
if (thread != null) {
|
||||||
|
thread.events.runPromised(function() {
|
||||||
|
// close the thing
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#end
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,7 +102,6 @@ class Script extends FlxBasic implements IFlxDestroyable {
|
|||||||
#if sys "ZipUtil" => funkin.backend.utils.ZipUtil, #end
|
#if sys "ZipUtil" => funkin.backend.utils.ZipUtil, #end
|
||||||
"MarkdownUtil" => funkin.backend.utils.MarkdownUtil,
|
"MarkdownUtil" => funkin.backend.utils.MarkdownUtil,
|
||||||
"EngineUtil" => funkin.backend.utils.EngineUtil,
|
"EngineUtil" => funkin.backend.utils.EngineUtil,
|
||||||
"ThreadUtil" => funkin.backend.utils.ThreadUtil,
|
|
||||||
"MemoryUtil" => funkin.backend.utils.MemoryUtil,
|
"MemoryUtil" => funkin.backend.utils.MemoryUtil,
|
||||||
"BitmapUtil" => funkin.backend.utils.BitmapUtil,
|
"BitmapUtil" => funkin.backend.utils.BitmapUtil,
|
||||||
|
|
||||||
@@ -402,4 +401,4 @@ class Script extends FlxBasic implements IFlxDestroyable {
|
|||||||
* Called when the script is loaded.
|
* Called when the script is loaded.
|
||||||
*/
|
*/
|
||||||
public function onLoad() {}
|
public function onLoad() {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package funkin.backend.scripting.events.menu.freeplay;
|
package funkin.backend.scripting.events.menu.freeplay;
|
||||||
|
|
||||||
import funkin.menus.FreeplayState.FreeplayGameMode;
|
|
||||||
|
|
||||||
final class FreeplaySongSelectEvent extends CancellableEvent {
|
final class FreeplaySongSelectEvent extends CancellableEvent {
|
||||||
/**
|
/**
|
||||||
* Song name that is about to be played
|
* Song name that is about to be played
|
||||||
@@ -16,26 +14,11 @@ final class FreeplaySongSelectEvent extends CancellableEvent {
|
|||||||
*/
|
*/
|
||||||
public var variant:String;
|
public var variant:String;
|
||||||
/**
|
/**
|
||||||
* Used game mode's data.
|
* Whenever opponent mode is enabled or not.
|
||||||
*/
|
*/
|
||||||
public var gameMode:FreeplayGameMode;
|
public var opponentMode:Bool;
|
||||||
|
/**
|
||||||
|
* Whenever coop mode is enabled.
|
||||||
// Backwards compat
|
*/
|
||||||
@:noCompletion public var opponentMode(get, set):Bool;
|
public var coopMode: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,7 +11,6 @@ final class NoteHitEvent extends CancellableEvent {
|
|||||||
@:dox(hide) public var unmuteVocals:Bool = true;
|
@:dox(hide) public var unmuteVocals:Bool = true;
|
||||||
@:dox(hide) public var enableCamZooming:Bool = true;
|
@:dox(hide) public var enableCamZooming:Bool = true;
|
||||||
@:dox(hide) public var autoHitLastSustain:Bool = true;
|
@:dox(hide) public var autoHitLastSustain:Bool = true;
|
||||||
@:dox(hide) public var clipSustain:Bool = true;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whenever a miss should be added.
|
* Whenever a miss should be added.
|
||||||
@@ -146,13 +145,6 @@ final class NoteHitEvent extends CancellableEvent {
|
|||||||
deleteNote = true;
|
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.
|
* Prevents the vocals volume from being set to 1 after pressing the note.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ class ScriptableShader extends FlxBasic implements IHScriptCustomBehaviour {
|
|||||||
if((shader is CustomShader)) scriptName = cast(shader, CustomShader).fileName;
|
if((shader is CustomShader)) scriptName = cast(shader, CustomShader).fileName;
|
||||||
else throw "Missing name for shader script, please provide a scriptName, or use CustomShader";
|
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 = Script.create(Paths.script('shaders/$scriptName'));
|
||||||
script.setParent(shader);
|
script.setParent(shader);
|
||||||
script.set("shader", shader);
|
script.set("shader", shader);
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ enum Control
|
|||||||
CHANGE_MODE;
|
CHANGE_MODE;
|
||||||
//CHEAT;
|
//CHEAT;
|
||||||
SWITCHMOD;
|
SWITCHMOD;
|
||||||
FPS_COUNTER;
|
|
||||||
|
|
||||||
// Debugs
|
// Debugs
|
||||||
DEV_ACCESS;
|
DEV_ACCESS;
|
||||||
@@ -162,11 +161,6 @@ class Controls extends FlxActionSet
|
|||||||
@:pressed("switchmod") public var SWITCHMOD_HOLD(get, set): Bool;
|
@:pressed("switchmod") public var SWITCHMOD_HOLD(get, set): Bool;
|
||||||
@:justReleased("switchmod") public var SWITCHMOD_R(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
|
@:devModeOnly
|
||||||
@:gamepad([])
|
@:gamepad([])
|
||||||
@:justPressed("dev-access") public var DEV_ACCESS(get, set): Bool;
|
@:justPressed("dev-access") public var DEV_ACCESS(get, set): Bool;
|
||||||
|
|||||||
@@ -13,20 +13,16 @@ import lime.utils.AssetType;
|
|||||||
/**
|
/**
|
||||||
* A class that reads the `flags.ini` file, allowing to read settable Flags (customs too).
|
* A class that reads the `flags.ini` file, allowing to read settable Flags (customs too).
|
||||||
*/
|
*/
|
||||||
@:build(funkin.backend.system.macros.FlagMacro.build("onReset"))
|
@:build(funkin.backend.system.macros.FlagMacro.build())
|
||||||
class Flags {
|
class Flags {
|
||||||
public static var overridenFlags:Map<String, Bool> = [];
|
|
||||||
|
|
||||||
// -- Codename's Addon Config --
|
// -- Codename's Addon Config --
|
||||||
@:bypass public static var addonFlags:Map<String, Dynamic> = [];
|
@:bypass public static var addonFlags:Map<String, Dynamic> = [];
|
||||||
|
|
||||||
public static var CURRENT_API_VERSION:Int = 2;
|
|
||||||
|
|
||||||
// -- Codename's Mod Config --
|
// -- Codename's Mod Config --
|
||||||
public static var MOD_NAME:String = "";
|
public static var MOD_NAME:String = "";
|
||||||
public static var MOD_DESCRIPTION:String = "";
|
public static var MOD_DESCRIPTION:String = "";
|
||||||
public static var MOD_AUTHOR:String = "";
|
public static var MOD_AUTHOR:String = "";
|
||||||
@:lazy public static var MOD_API_VERSION:Null<Int> = null;
|
public static var MOD_API_VERSION:Int = 1;
|
||||||
public static var MOD_DOWNLOAD_LINK:String = "";
|
public static var MOD_DOWNLOAD_LINK:String = "";
|
||||||
public static var MOD_DEPENDENCIES:Array<String> = [];
|
public static var MOD_DEPENDENCIES:Array<String> = [];
|
||||||
|
|
||||||
@@ -45,11 +41,12 @@ class Flags {
|
|||||||
@:lazy public static var SAVE_PATH:String = haxe.macro.Compiler.getDefine("SAVE_PATH");
|
@: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");
|
@: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_NUMBER:Int = GitCommitMacro.commitNumber;
|
||||||
public static var COMMIT_HASH:String = GitCommitMacro.commitHash;
|
public static var COMMIT_HASH:String = GitCommitMacro.commitHash;
|
||||||
public static var COMMIT_MESSAGE:String = 'Commit $COMMIT_NUMBER ($COMMIT_HASH)';
|
public static var COMMIT_MESSAGE:String = 'Commit $COMMIT_NUMBER ($COMMIT_HASH)';
|
||||||
|
|
||||||
@:lazy public static var WINDOW_TITLE_USE_MOD_NAME:Null<Bool> = null;
|
@:bypass public static var WINDOW_TITLE_USE_MOD_NAME:Bool = false;
|
||||||
@:lazy public static var TITLE:String = Application.current.meta.get('name');
|
@:lazy public static var TITLE:String = Application.current.meta.get('name');
|
||||||
@:lazy public static var VERSION:String = Application.current.meta.get('version');
|
@:lazy public static var VERSION:String = Application.current.meta.get('version');
|
||||||
|
|
||||||
@@ -128,16 +125,12 @@ class Flags {
|
|||||||
@:also(funkin.game.PlayState.opponentMode)
|
@:also(funkin.game.PlayState.opponentMode)
|
||||||
public static var DEFAULT_OPPONENT_MODE:Bool = false;
|
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_MS_LIMIT:Float = 1500;
|
||||||
public static var DEFAULT_NOTE_SCALE:Float = 0.7;
|
public static var DEFAULT_NOTE_SCALE:Float = 0.7;
|
||||||
#if MODCHARTING_FEATURES
|
#if MODCHARTING_FEATURES
|
||||||
public static var DEFAULT_MODCHART_HOLD_SUBDIVISIONS:Int = 4;
|
public static var DEFAULT_MODCHART_HOLD_SUBDIVISIONS:Int = 4;
|
||||||
#end
|
#end
|
||||||
|
|
||||||
public static var SUSTAINS_AS_ONE_NOTE:Null<Bool> = null;
|
|
||||||
|
|
||||||
@:also(funkin.game.Character.FALLBACK_DEAD_CHARACTER)
|
@:also(funkin.game.Character.FALLBACK_DEAD_CHARACTER)
|
||||||
public static var DEFAULT_GAMEOVER_CHARACTER:String = "bf-dead";
|
public static var DEFAULT_GAMEOVER_CHARACTER:String = "bf-dead";
|
||||||
|
|
||||||
@@ -155,9 +148,7 @@ class Flags {
|
|||||||
public static var DEFAULT_HUD_ZOOM_MULT:Float = 0.03;
|
public static var DEFAULT_HUD_ZOOM_MULT:Float = 0.03;
|
||||||
public static var DEFAULT_CAM_ZOOM_LERP:Float = 0.05;
|
public static var DEFAULT_CAM_ZOOM_LERP:Float = 0.05;
|
||||||
public static var DEFAULT_HUD_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
|
// Font configuration
|
||||||
public static var DEFAULT_FONT:String = "vcr.ttf";
|
public static var DEFAULT_FONT:String = "vcr.ttf";
|
||||||
public static var DEFAULT_FONT_SIZE:Int = 16;
|
public static var DEFAULT_FONT_SIZE:Int = 16;
|
||||||
@@ -286,6 +277,8 @@ class Flags {
|
|||||||
@:bypass public static var customFlags:Map<String, String> = [];
|
@:bypass public static var customFlags:Map<String, String> = [];
|
||||||
|
|
||||||
public static function loadFromData(flags:Map<String, String>, data:String) {
|
public static function loadFromData(flags:Map<String, String>, data:String) {
|
||||||
|
WINDOW_TITLE_USE_MOD_NAME = false;
|
||||||
|
|
||||||
if (!(data.length > 0)) return;
|
if (!(data.length > 0)) return;
|
||||||
var res = IniUtil.parseString(data);
|
var res = IniUtil.parseString(data);
|
||||||
|
|
||||||
@@ -302,41 +295,26 @@ class Flags {
|
|||||||
else trace('Invalid section $name');
|
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function loadPost() {
|
public static function loadFromDatas(datas:Array<String>) {
|
||||||
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> = [];
|
var flags:Map<String, String> = [];
|
||||||
for (data in datas) {
|
for(data in datas) {
|
||||||
if (data != null)
|
if(data != null)
|
||||||
loadFromData(flags, data);
|
loadFromData(flags, data);
|
||||||
}
|
}
|
||||||
loadPost();
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function parseFlags(flags:Map<String, String>) {
|
public static function parseFlags(flags:Map<String, String>) {
|
||||||
var parsed:Bool;
|
for(name=>value in flags)
|
||||||
for (name => value in flags) switch (name) {
|
if(!parse(name, value))
|
||||||
case "MOD_API_VERSION":
|
customFlags.set(name, value);
|
||||||
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;
|
Options.modchartingHoldSubdivisions = DEFAULT_MODCHART_HOLD_SUBDIVISIONS;
|
||||||
}
|
}
|
||||||
@@ -387,6 +365,5 @@ class Flags {
|
|||||||
parseFlags(flags);
|
parseFlags(flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
loadPost();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package funkin.backend.system;
|
package funkin.backend.system;
|
||||||
|
|
||||||
|
import sys.io.File;
|
||||||
|
import sys.FileSystem;
|
||||||
import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond;
|
import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond;
|
||||||
import flixel.addons.transition.FlxTransitionableState;
|
import flixel.addons.transition.FlxTransitionableState;
|
||||||
import flixel.addons.transition.TransitionData;
|
import flixel.addons.transition.TransitionData;
|
||||||
@@ -7,22 +9,21 @@ import flixel.graphics.FlxGraphic;
|
|||||||
import flixel.math.FlxPoint;
|
import flixel.math.FlxPoint;
|
||||||
import flixel.math.FlxRect;
|
import flixel.math.FlxRect;
|
||||||
import flixel.system.ui.FlxSoundTray;
|
import flixel.system.ui.FlxSoundTray;
|
||||||
import funkin.backend.assets.AssetSource;
|
|
||||||
import funkin.backend.assets.AssetsLibraryList;
|
import funkin.backend.assets.AssetsLibraryList;
|
||||||
import funkin.backend.assets.ModsFolder;
|
import funkin.backend.assets.ModsFolder;
|
||||||
import funkin.backend.system.framerate.Framerate;
|
import funkin.backend.assets.AssetSource;
|
||||||
import funkin.backend.system.framerate.SystemInfo;
|
import funkin.backend.system.framerate.SystemInfo;
|
||||||
import funkin.backend.system.modules.*;
|
import funkin.backend.system.modules.*;
|
||||||
import funkin.backend.utils.ThreadUtil;
|
|
||||||
import funkin.editors.SaveWarning;
|
import funkin.editors.SaveWarning;
|
||||||
import funkin.options.PlayerSettings;
|
|
||||||
import openfl.Assets;
|
import openfl.Assets;
|
||||||
import openfl.Lib;
|
import openfl.Lib;
|
||||||
import openfl.display.Sprite;
|
import openfl.display.Sprite;
|
||||||
import openfl.text.TextFormat;
|
import openfl.text.TextFormat;
|
||||||
import openfl.utils.AssetLibrary;
|
import openfl.utils.AssetLibrary;
|
||||||
import sys.FileSystem;
|
|
||||||
import sys.io.File;
|
#if ALLOW_MULTITHREADING
|
||||||
|
import sys.thread.Thread;
|
||||||
|
#end
|
||||||
#if android
|
#if android
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@@ -39,7 +40,7 @@ class Main extends Sprite
|
|||||||
|
|
||||||
public static var scaleMode:FunkinRatioScaleMode;
|
public static var scaleMode:FunkinRatioScaleMode;
|
||||||
#if !mobile
|
#if !mobile
|
||||||
public static var framerateSprite:Framerate;
|
public static var framerateSprite:funkin.backend.system.framerate.Framerate;
|
||||||
#end
|
#end
|
||||||
|
|
||||||
var gameWidth:Int = 1280; // Width of the game in pixels (might be less / more in actual pixels).
|
var gameWidth:Int = 1280; // Width of the game in pixels (might be less / more in actual pixels).
|
||||||
@@ -57,6 +58,10 @@ class Main extends Sprite
|
|||||||
|
|
||||||
// You can pretty much ignore everything from here on - your code should go in your states.
|
// 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() {
|
public static function preInit() {
|
||||||
funkin.backend.utils.NativeAPI.registerAsDPICompatible();
|
funkin.backend.utils.NativeAPI.registerAsDPICompatible();
|
||||||
funkin.backend.system.CommandLineHandler.parseCommandLine(Sys.args());
|
funkin.backend.system.CommandLineHandler.parseCommandLine(Sys.args());
|
||||||
@@ -74,7 +79,7 @@ class Main extends Sprite
|
|||||||
addChild(game = new FunkinGame(gameWidth, gameHeight, MainState, Options.framerate, Options.framerate, skipSplash, startFullscreen));
|
addChild(game = new FunkinGame(gameWidth, gameHeight, MainState, Options.framerate, Options.framerate, skipSplash, startFullscreen));
|
||||||
|
|
||||||
#if (!mobile && !web)
|
#if (!mobile && !web)
|
||||||
addChild(framerateSprite = new Framerate());
|
addChild(framerateSprite = new funkin.backend.system.framerate.Framerate());
|
||||||
SystemInfo.init();
|
SystemInfo.init();
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
@@ -92,8 +97,16 @@ class Main extends Sprite
|
|||||||
#end;
|
#end;
|
||||||
public static var startedFromSource:Bool = #if TEST_BUILD true #else false #end;
|
public static var startedFromSource:Bool = #if TEST_BUILD true #else false #end;
|
||||||
|
|
||||||
// DEPRECATED
|
|
||||||
@:dox(hide) public static function execAsync(func:Void->Void) ThreadUtil.execAsync(func);
|
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
|
||||||
|
}
|
||||||
|
|
||||||
private static function getTimer():Int {
|
private static function getTimer():Int {
|
||||||
return time = Lib.getTimer();
|
return time = Lib.getTimer();
|
||||||
@@ -105,6 +118,10 @@ class Main extends Sprite
|
|||||||
MemoryUtil.init();
|
MemoryUtil.init();
|
||||||
@:privateAccess
|
@:privateAccess
|
||||||
FlxG.game.getTimer = getTimer;
|
FlxG.game.getTimer = getTimer;
|
||||||
|
#if ALLOW_MULTITHREADING
|
||||||
|
for(i in 0...4)
|
||||||
|
gameThreads.push(Thread.createWithEventLoop(function() {Thread.current().events.promise();}));
|
||||||
|
#end
|
||||||
FunkinCache.init();
|
FunkinCache.init();
|
||||||
Paths.assetsTree = new AssetsLibraryList();
|
Paths.assetsTree = new AssetsLibraryList();
|
||||||
|
|
||||||
@@ -139,7 +156,6 @@ class Main extends Sprite
|
|||||||
FlxG.signals.focusGained.add(onFocus);
|
FlxG.signals.focusGained.add(onFocus);
|
||||||
FlxG.signals.preStateSwitch.add(onStateSwitch);
|
FlxG.signals.preStateSwitch.add(onStateSwitch);
|
||||||
FlxG.signals.postStateSwitch.add(onStateSwitchPost);
|
FlxG.signals.postStateSwitch.add(onStateSwitchPost);
|
||||||
FlxG.signals.postUpdate.add(onUpdate);
|
|
||||||
|
|
||||||
FlxG.mouse.useSystemCursor = true;
|
FlxG.mouse.useSystemCursor = true;
|
||||||
#if DARK_MODE_WINDOW
|
#if DARK_MODE_WINDOW
|
||||||
@@ -194,14 +210,6 @@ class Main extends Sprite
|
|||||||
scaleMode.resetSize();
|
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() {
|
private static function onStateSwitchPost() {
|
||||||
// manual asset clearing since base openfl one does'nt clear lime one
|
// manual asset clearing since base openfl one does'nt clear lime one
|
||||||
// does'nt clear bitmaps since flixel fork does it auto
|
// does'nt clear bitmaps since flixel fork does it auto
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package funkin.backend.system;
|
||||||
|
|
||||||
|
import lime.app.Application;
|
||||||
|
import funkin.backend.system.Main;
|
||||||
|
|
||||||
|
class MainApplication extends Application {
|
||||||
|
public function new() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
#if openfl
|
||||||
|
openfl.Lib.current.stage.addChild(new Main());
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,20 +8,12 @@ import funkin.backend.assets.IModsAssetLibrary;
|
|||||||
import funkin.backend.assets.ScriptedAssetLibrary;
|
import funkin.backend.assets.ScriptedAssetLibrary;
|
||||||
|
|
||||||
class AssetTreeInfo extends FramerateCategory {
|
class AssetTreeInfo extends FramerateCategory {
|
||||||
private var lastUpdateTime:Float = 1;
|
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
super("Asset Libraries Tree Info");
|
super("Asset Libraries Tree Info");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function __enterFrame(t:Int) {
|
public override function __enterFrame(t:Int) {
|
||||||
if (alpha <= 0.05) return;
|
if (alpha <= 0.05) return;
|
||||||
|
|
||||||
if ((lastUpdateTime += FlxG.rawElapsed) < 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
lastUpdateTime = 0;
|
|
||||||
|
|
||||||
var text = 'Not initialized yet\n';
|
var text = 'Not initialized yet\n';
|
||||||
if (Paths.assetsTree != null){
|
if (Paths.assetsTree != null){
|
||||||
text = "";
|
text = "";
|
||||||
|
|||||||
@@ -53,6 +53,13 @@ class Framerate extends Sprite {
|
|||||||
x = 10;
|
x = 10;
|
||||||
y = 2;
|
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)
|
if (__bitmap == null)
|
||||||
__bitmap = new BitmapData(1, 1, 0xFF000000);
|
__bitmap = new BitmapData(1, 1, 0xFF000000);
|
||||||
|
|
||||||
|
|||||||
@@ -9,13 +9,6 @@ class FramerateCounter extends Sprite {
|
|||||||
public var fpsLabel:TextField;
|
public var fpsLabel:TextField;
|
||||||
public var lastFPS:Float = 0;
|
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() {
|
public function new() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
@@ -34,40 +27,15 @@ class FramerateCounter extends Sprite {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function reload() {
|
public function reload() {}
|
||||||
lastUpdateTime = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override function __enterFrame(t:Int) {
|
public override function __enterFrame(t:Int) {
|
||||||
if (alpha <= 0.05) return;
|
if (alpha <= 0.05) return;
|
||||||
|
|
||||||
super.__enterFrame(t);
|
super.__enterFrame(t);
|
||||||
|
|
||||||
frameCount++;
|
lastFPS = CoolUtil.fpsLerp(lastFPS, FlxG.rawElapsed == 0 ? 0 : (1 / FlxG.rawElapsed), 0.25);
|
||||||
|
fpsNum.text = Std.string(Math.floor(lastFPS));
|
||||||
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.x = fpsNum.x + fpsNum.width;
|
||||||
fpsLabel.y = (fpsNum.y + fpsNum.height) - fpsLabel.height;
|
fpsLabel.y = (fpsNum.y + fpsNum.height) - fpsLabel.height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,21 +36,11 @@ class MemoryCounter extends Sprite {
|
|||||||
if (alpha <= 0.05) return;
|
if (alpha <= 0.05) return;
|
||||||
super.__enterFrame(t);
|
super.__enterFrame(t);
|
||||||
|
|
||||||
final mem = MemoryUtil.currentMemUsage();
|
memory = MemoryUtil.currentMemUsage();
|
||||||
|
|
||||||
if (mem == memory) {
|
|
||||||
updateLabelPosition();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memory = mem;
|
|
||||||
if (memoryPeak < memory) memoryPeak = memory;
|
if (memoryPeak < memory) memoryPeak = memory;
|
||||||
memoryText.text = CoolUtil.getSizeString(memory);
|
memoryText.text = CoolUtil.getSizeString(memory);
|
||||||
memoryPeakText.text = ' / ${CoolUtil.getSizeString(memoryPeak)}';
|
memoryPeakText.text = ' / ${CoolUtil.getSizeString(memoryPeak)}';
|
||||||
|
|
||||||
updateLabelPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
private inline function updateLabelPosition():Void
|
|
||||||
memoryPeakText.x = memoryText.x + memoryText.width;
|
memoryPeakText.x = memoryText.x + memoryText.width;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,7 +115,8 @@ class SystemInfo extends FramerateCategory {
|
|||||||
if (vRAMBytes == 1000 || vRAMBytes == 1 || vRAMBytes <= 0)
|
if (vRAMBytes == 1000 || vRAMBytes == 1 || vRAMBytes <= 0)
|
||||||
Logs.trace('Unable to grab GPU VRAM', ERROR, RED);
|
Logs.trace('Unable to grab GPU VRAM', ERROR, RED);
|
||||||
else {
|
else {
|
||||||
vRAM = getSizeString(vRAMBytes / 1024);
|
var vRAMBytesFloat:#if cpp Float64 #else Float #end = vRAMBytes*1024;
|
||||||
|
vRAM = CoolUtil.getSizeString64(vRAMBytesFloat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
@@ -154,17 +155,6 @@ class SystemInfo extends FramerateCategory {
|
|||||||
if (totalMem != "Unknown" && memType != "Unknown") __formattedSysText += '\nTotal MEM: $totalMem $memType';
|
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() {
|
public function new() {
|
||||||
super("System Info");
|
super("System Info");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
package funkin.backend.system.macros;
|
|
||||||
|
|
||||||
using StringTools;
|
|
||||||
|
|
||||||
#if macro
|
|
||||||
class BuildInfo {
|
|
||||||
public static function printBuildInfo() {
|
|
||||||
if(haxe.macro.Context.defined("display") || haxe.macro.Context.defined("display-details")) return;
|
|
||||||
var haxeVersion = haxe.macro.Context.definedValue("haxe").trim();
|
|
||||||
var sleepChangeVersion = false;
|
|
||||||
|
|
||||||
Sys.println('[ BUILD INFO ]');
|
|
||||||
Sys.println('Haxe Version: ${haxeVersion}');
|
|
||||||
try {
|
|
||||||
var lastBuiltWith:Null<String> = null;
|
|
||||||
var compiling = #if final "release" #elseif debug "debug" #else "release" #end;
|
|
||||||
var target = #if hl "hl"
|
|
||||||
#elseif html5 "html5"
|
|
||||||
#elseif ios "ios"
|
|
||||||
#elseif android "android"
|
|
||||||
#elseif windows "windows"
|
|
||||||
#elseif (mac || macos) "macos"
|
|
||||||
#elseif linux "linux"
|
|
||||||
#else ""
|
|
||||||
#end;
|
|
||||||
if(target == "") throw "Unknown target";
|
|
||||||
var exportPath = Sys.getCwd() + "/export/" + compiling + "/" + target + "/";
|
|
||||||
exportPath += "obj/Options.txt";
|
|
||||||
|
|
||||||
var options = sys.io.File.getContent(exportPath);
|
|
||||||
for(option in options.split("\n")) {
|
|
||||||
if(option.startsWith("haxe=")) {
|
|
||||||
lastBuiltWith = option.substr(5).trim();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(lastBuiltWith != null && lastBuiltWith.length > 0 && lastBuiltWith != haxeVersion) {
|
|
||||||
Sys.println('Last Built With Haxe: ${lastBuiltWith} [!!!! MAKE SURE IF YOU SWITCHED VERSIONS YOU DELETE EXPORT FOLDERS !!!!]');
|
|
||||||
sleepChangeVersion = true;
|
|
||||||
}
|
|
||||||
} catch(e) {}
|
|
||||||
var targetPlatform = #if html5 "Web (HTML5)"
|
|
||||||
#elseif ios "iOS"
|
|
||||||
#elseif android "Android"
|
|
||||||
#elseif windows "Windows"
|
|
||||||
#elseif (mac || macos) "Mac"
|
|
||||||
#elseif linux "Linux"
|
|
||||||
#else "Unknown"
|
|
||||||
#end;
|
|
||||||
|
|
||||||
if(haxe.macro.Context.defined("hl")) {
|
|
||||||
targetPlatform = "Hashlink (" + targetPlatform + ")";
|
|
||||||
}
|
|
||||||
Sys.println('Target Platform: ' + targetPlatform);
|
|
||||||
Sys.println('Build Date: ${Date.now().toString()}');
|
|
||||||
Sys.println('');
|
|
||||||
|
|
||||||
if(sleepChangeVersion) {
|
|
||||||
Sys.println('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
|
|
||||||
Sys.println('!!!! MAKE SURE IF YOU SWITCHED VERSIONS YOU DELETE EXPORT FOLDERS !!!!');
|
|
||||||
Sys.println('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
|
|
||||||
Sys.println('');
|
|
||||||
Sys.sleep(5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#end
|
|
||||||
@@ -19,7 +19,7 @@ class FlagMacro {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function build(resetCallback:String):Array<Field> {
|
public static function build():Array<Field> {
|
||||||
var fields = Context.getBuildFields();
|
var fields = Context.getBuildFields();
|
||||||
|
|
||||||
var clRef = Context.getLocalClass();
|
var clRef = Context.getLocalClass();
|
||||||
@@ -248,10 +248,7 @@ class FlagMacro {
|
|||||||
access: [APublic, AStatic],
|
access: [APublic, AStatic],
|
||||||
kind: FFun({
|
kind: FFun({
|
||||||
args: [],
|
args: [],
|
||||||
expr: macro {
|
expr: macro $b{resetExprs},
|
||||||
$b{resetExprs};
|
|
||||||
$i{resetCallback}();
|
|
||||||
},
|
|
||||||
ret: macro: Void
|
ret: macro: Void
|
||||||
}),
|
}),
|
||||||
pos: Context.currentPos(),
|
pos: Context.currentPos(),
|
||||||
|
|||||||
@@ -58,11 +58,6 @@ class Macros {
|
|||||||
|
|
||||||
final macroPath = 'funkin.backend.system.macros.Macros';
|
final macroPath = 'funkin.backend.system.macros.Macros';
|
||||||
Compiler.addMetadata('@:build($macroPath.buildLimeAssetLibrary())', 'lime.utils.AssetLibrary');
|
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> {
|
public static function buildLimeAssetLibrary():Array<Field> {
|
||||||
|
|||||||
@@ -2,30 +2,22 @@ package funkin.backend.system.updating;
|
|||||||
|
|
||||||
import funkin.backend.system.github.GitHub;
|
import funkin.backend.system.github.GitHub;
|
||||||
import funkin.backend.system.github.GitHubRelease;
|
import funkin.backend.system.github.GitHubRelease;
|
||||||
#if ALLOW_MULTITHREADING
|
|
||||||
import funkin.backend.utils.ThreadUtil;
|
|
||||||
#end
|
|
||||||
|
|
||||||
import lime.app.Application;
|
import lime.app.Application;
|
||||||
|
|
||||||
|
import sys.thread.Mutex;
|
||||||
|
import sys.thread.Thread;
|
||||||
import sys.FileSystem;
|
import sys.FileSystem;
|
||||||
|
|
||||||
import haxe.io.Path;
|
import haxe.io.Path;
|
||||||
|
|
||||||
#if (target.threaded)
|
|
||||||
import sys.thread.Thread;
|
|
||||||
import sys.thread.Mutex;
|
|
||||||
#end
|
|
||||||
|
|
||||||
using funkin.backend.system.github.GitHub;
|
using funkin.backend.system.github.GitHub;
|
||||||
|
|
||||||
class UpdateUtil {
|
class UpdateUtil {
|
||||||
public static var lastUpdateCheck:Null<UpdateCheckCallback>;
|
public static var lastUpdateCheck:Null<UpdateCheckCallback>;
|
||||||
|
|
||||||
#if (target.threaded)
|
|
||||||
private static var __waitCallbacks:Array<UpdateCheckCallback->Void>;
|
private static var __waitCallbacks:Array<UpdateCheckCallback->Void>;
|
||||||
private static var __mutex:Mutex;
|
private static var __mutex:Mutex;
|
||||||
#end
|
|
||||||
|
|
||||||
public static function init() {
|
public static function init() {
|
||||||
// deletes old bak file if it exists
|
// deletes old bak file if it exists
|
||||||
@@ -34,34 +26,26 @@ class UpdateUtil {
|
|||||||
if (FileSystem.exists(bakPath)) FileSystem.deleteFile(bakPath);
|
if (FileSystem.exists(bakPath)) FileSystem.deleteFile(bakPath);
|
||||||
#end
|
#end
|
||||||
|
|
||||||
#if (target.threaded)
|
|
||||||
__waitCallbacks = [];
|
__waitCallbacks = [];
|
||||||
__mutex = new Mutex();
|
__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) {
|
public static function waitForUpdates(force = false, callback:UpdateCheckCallback->Void, lazy = false) {
|
||||||
#if (target.threaded)
|
|
||||||
if (__mutex.tryAcquire()) {
|
if (__mutex.tryAcquire()) {
|
||||||
__mutex.release();
|
__mutex.release();
|
||||||
if (__shouldCheck(lazy) || force) {
|
if (__shouldCheck(lazy) || force) {
|
||||||
__waitCallbacks.push(callback);
|
__waitCallbacks.push(callback);
|
||||||
#if ALLOW_MULTITHREADING ThreadUtil.execAsync #else Thread.create #end(checkForUpdates.bind(force, false));
|
Thread.create(checkForUpdates.bind(force, false));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
callback(lastUpdateCheck);
|
callback(lastUpdateCheck);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
__waitCallbacks.push(callback);
|
__waitCallbacks.push(callback);
|
||||||
#else
|
|
||||||
callback(checkForUpdates(true, false));
|
|
||||||
#end
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function checkForUpdates(force = false, lazy = false):UpdateCheckCallback {
|
public static function checkForUpdates(force = false, lazy = false):UpdateCheckCallback {
|
||||||
#if (target.threaded)
|
|
||||||
var wasAcquired = !__mutex.tryAcquire();
|
var wasAcquired = !__mutex.tryAcquire();
|
||||||
if (wasAcquired) __mutex.acquire();
|
if (wasAcquired) __mutex.acquire();
|
||||||
|
|
||||||
@@ -76,19 +60,8 @@ class UpdateUtil {
|
|||||||
FlxG.signals.preUpdate.addOnce(__callWaitCallbacks);
|
FlxG.signals.preUpdate.addOnce(__callWaitCallbacks);
|
||||||
|
|
||||||
return lastUpdateCheck;
|
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 {
|
static function __checkForUpdates():UpdateCheckCallback {
|
||||||
var curTag = 'v' + (Flags.VERSION == null ? Application.current.meta.get('version') : Flags.VERSION), error = false;
|
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) -> {
|
var newUpdates = __doReleaseFiltering(GitHub.getReleases(Flags.REPO_OWNER, Flags.REPO_NAME, (e) -> {
|
||||||
@@ -109,6 +82,11 @@ class UpdateUtil {
|
|||||||
static function __shouldCheck(lazy:Bool):Bool
|
static function __shouldCheck(lazy:Bool):Bool
|
||||||
return lastUpdateCheck == null || !lazy && (!lastUpdateCheck.newUpdate || Date.now().getTime() - lastUpdateCheck.date.getTime() > 1800000);
|
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) {
|
static function __doReleaseFiltering(releases:Array<GitHubRelease>, currentVersionTag:String) {
|
||||||
releases = releases.filterReleases(Options.betaUpdates, false);
|
releases = releases.filterReleases(Options.betaUpdates, false);
|
||||||
if (releases.length <= 0)
|
if (releases.length <= 0)
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ typedef AudioAnalyzerCallback = Int->Int->Void;
|
|||||||
* An utility that analyze FlxSounds,
|
* An utility that analyze FlxSounds,
|
||||||
* can be used to make waveform or real-time audio visualizer.
|
* can be used to make waveform or real-time audio visualizer.
|
||||||
*
|
*
|
||||||
* FlxSound.amplitude works so if any case if your only checking for peak of current time, use that instead.
|
* FlxSound.amplitude does work in CNE so if any case if your only checking for peak of current
|
||||||
|
* time, use that instead.
|
||||||
*/
|
*/
|
||||||
final class AudioAnalyzer {
|
final class AudioAnalyzer {
|
||||||
/**
|
/**
|
||||||
@@ -95,9 +96,9 @@ final class AudioAnalyzer {
|
|||||||
static var __twiddleImags:Array<Array<Float>> = [];
|
static var __twiddleImags:Array<Array<Float>> = [];
|
||||||
static var __freqReals:Array<Array<Float>> = [];
|
static var __freqReals:Array<Array<Float>> = [];
|
||||||
static var __freqImags:Array<Array<Float>> = [];
|
static var __freqImags:Array<Array<Float>> = [];
|
||||||
static var __freqCalculating:Int = 0;
|
|
||||||
#if (target.threaded)
|
#if (target.threaded)
|
||||||
static var __mutex:Mutex = new Mutex();
|
static var __mutex:Mutex = new Mutex();
|
||||||
|
static var __freqCalculating:Int = 0;
|
||||||
#end
|
#end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -295,7 +296,7 @@ final class AudioAnalyzer {
|
|||||||
__check();
|
__check();
|
||||||
}
|
}
|
||||||
|
|
||||||
function __check() if (sound != null && sound.buffer != buffer) {
|
function __check() if (sound.buffer != buffer) {
|
||||||
byteSize = 1 << ((buffer = sound.buffer).bitsPerSample - 1);
|
byteSize = 1 << ((buffer = sound.buffer).bitsPerSample - 1);
|
||||||
|
|
||||||
#if (lime_cffi && lime_vorbis)
|
#if (lime_cffi && lime_vorbis)
|
||||||
@@ -323,7 +324,7 @@ final class AudioAnalyzer {
|
|||||||
* @param maxFreq The maximum frequency to cap (Optional, default 22000.0, Above 23000.0 is not recommended).
|
* @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.
|
* @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);
|
return inline getLevelsFromFrequencies(__frequencies = getFrequencies(startPos, volume, __frequencies), buffer.sampleRate, barCount, levels, ratio, minDb, maxDb, minFreq, maxFreq);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -333,8 +334,8 @@ final class AudioAnalyzer {
|
|||||||
* @param frequencies The output for getting the frequencies, to avoid memory leaks (Optional).
|
* @param frequencies The output for getting the frequencies, to avoid memory leaks (Optional).
|
||||||
* @return Output of frequencies.
|
* @return Output of frequencies.
|
||||||
*/
|
*/
|
||||||
public function getFrequencies(?startPos:Float, ?volume:Float, ?frequencies:Array<Float>):Array<Float>
|
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);
|
return inline getFrequenciesFromSamples(__freqSamples = getSamples(startPos, fftN, true, -1, volume, __freqSamples), fftN, useWindowingFFT, frequencies);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Analyzes an attached FlxSound from startPos to endPos in milliseconds to get the amplitudes.
|
* Analyzes an attached FlxSound from startPos to endPos in milliseconds to get the amplitudes.
|
||||||
@@ -466,37 +467,36 @@ final class AudioAnalyzer {
|
|||||||
@:privateAccess return sound._source != null && sound._source.__backend != null && sound._source.__backend.playing;
|
@:privateAccess return sound._source != null && sound._source.__backend != null && sound._source.__backend.playing;
|
||||||
|
|
||||||
inline function __readStream(startPos:Float, endPos:Float, callback:AudioAnalyzerCallback):Float @:privateAccess {
|
inline function __readStream(startPos:Float, endPos:Float, callback:AudioAnalyzerCallback):Float @:privateAccess {
|
||||||
final backend = sound._source.__backend;
|
var backend = sound._source.__backend;
|
||||||
|
var i = backend.bufferSizes.length - backend.queuedBuffers;
|
||||||
|
var time = backend.bufferTimes[i] * 1000;
|
||||||
|
|
||||||
// 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);
|
var n = Math.floor((endPos - startPos) * __toBits);
|
||||||
var i = backend.bufferLengths.length - backend.requestBuffers - 1, time:Float;
|
if (startPos >= time && startPos < backend.bufferTimes[backend.bufferSizes.length - 1] * 1000) {
|
||||||
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.bufferSizes[i], c = 0;
|
||||||
var pos = Math.floor((startPos - time) * __toBits), buf = backend.bufferDatas[i].buffer, size = backend.bufferLengths[i], c = 0;
|
|
||||||
while (pos >= size) {
|
while (pos >= size) {
|
||||||
if (++i >= backend.bufferLengths.length) break;
|
if (++i >= backend.bufferSizes.length) {
|
||||||
|
n = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
pos -= size;
|
pos -= size;
|
||||||
buf = backend.bufferDatas[i].buffer;
|
buf = backend.bufferDatas[i].buffer;
|
||||||
size = backend.bufferLengths[i];
|
size = backend.bufferSizes[i];
|
||||||
}
|
}
|
||||||
if (i >= backend.bufferLengths.length) break;
|
pos -= pos % __sampleSize;
|
||||||
if ((pos -= pos % __sampleSize) < 0) pos = 0;
|
|
||||||
n -= pos % __sampleSize;
|
n -= pos % __sampleSize;
|
||||||
|
|
||||||
while (n > 0) {
|
while (n > 0) {
|
||||||
callback(getByte(buf, pos, __wordSize), c);
|
callback(getByte(buf, pos, __wordSize), c);
|
||||||
if (++c > buffer.channels) c = 0;
|
if (++c > buffer.channels) c = 0;
|
||||||
if ((pos += __wordSize) >= size) {
|
if ((pos += __wordSize) >= size) {
|
||||||
if (++i >= backend.bufferLengths.length) break;
|
if (++i >= backend.bufferSizes.length) break;
|
||||||
pos = 0;
|
pos = 0;
|
||||||
buf = backend.bufferDatas[i].buffer;
|
buf = backend.bufferDatas[i].buffer;
|
||||||
size = backend.bufferLengths[i];
|
size = backend.bufferSizes[i];
|
||||||
}
|
}
|
||||||
n -= __wordSize;
|
n -= __wordSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return endPos - (n / __toBits);
|
return endPos - (n / __toBits);
|
||||||
|
|||||||
@@ -1495,4 +1495,4 @@ enum abstract CoolSfx(Int) from Int {
|
|||||||
var CHECKED = 3;
|
var CHECKED = 3;
|
||||||
var UNCHECKED = 4;
|
var UNCHECKED = 4;
|
||||||
var WARNING = 5;
|
var WARNING = 5;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -541,4 +541,4 @@ typedef DEvents =
|
|||||||
var ?joinGame:String->Void;
|
var ?joinGame:String->Void;
|
||||||
var ?spectateGame:String->Void;
|
var ?spectateGame:String->Void;
|
||||||
var ?joinRequest:DUser->Void;
|
var ?joinRequest:DUser->Void;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class FunkinParentDisabler extends FlxBasic {
|
|||||||
for(c in __cameras) c.paused = true;
|
for(c in __cameras) c.paused = true;
|
||||||
|
|
||||||
// sounds
|
// sounds
|
||||||
__sounds = [for(s in FlxG.sound.list) if (s.playing && !s.persist) s];
|
__sounds = [for(s in FlxG.sound.list) if (s.playing) s];
|
||||||
for(s in __sounds) s.pause();
|
for(s in __sounds) s.pause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,4 +71,4 @@ class FunkinParentDisabler extends FlxBasic {
|
|||||||
for(s in __sounds) s.play();
|
for(s in __sounds) s.play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,97 +1,32 @@
|
|||||||
package funkin.backend.utils;
|
package funkin.backend.utils;
|
||||||
|
|
||||||
#if (target.threaded)
|
#if ALLOW_MULTITHREADING
|
||||||
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 {
|
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.
|
* Creates a new Thread with an error handler.
|
||||||
* @param func Function to execute
|
* @param func Function to execute
|
||||||
* @param autoRestart Whenever the thread should auto restart itself after crashing.
|
* @param autoRestart Whenever the thread should auto restart itself after crashing.
|
||||||
*/
|
*/
|
||||||
public static function createSafe(func:Void->Void, autoRestart:Bool = false):Thread {
|
public static function createSafe(func:Void->Void, autoRestart:Bool = false) {
|
||||||
#if (target.threaded)
|
if (autoRestart) {
|
||||||
try {
|
return sys.thread.Thread.create(function() {
|
||||||
return if (autoRestart) Thread.create(() -> {
|
while(true) {
|
||||||
var restart = true;
|
try {
|
||||||
while (restart) try {
|
func();
|
||||||
|
} catch(e) {
|
||||||
|
trace(e.details());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return sys.thread.Thread.create(function() {
|
||||||
|
try {
|
||||||
func();
|
func();
|
||||||
restart = false;
|
} catch(e) {
|
||||||
|
trace(e.details());
|
||||||
}
|
}
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#if ALLOW_MULTITHREADING
|
#end
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -204,9 +204,6 @@ final class Windows {
|
|||||||
freopen("CONIN$", "r", stdin);
|
freopen("CONIN$", "r", stdin);
|
||||||
freopen("CONOUT$", "w", stdout);
|
freopen("CONOUT$", "w", stdout);
|
||||||
freopen("CONOUT$", "w", stderr);
|
freopen("CONOUT$", "w", stderr);
|
||||||
|
|
||||||
SetConsoleOutputCP(65001);
|
|
||||||
SetConsoleCP(65001);
|
|
||||||
')
|
')
|
||||||
public static function allocConsole() {
|
public static function allocConsole() {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,8 +41,7 @@ class Week {
|
|||||||
weekObj.songs.push({
|
weekObj.songs.push({
|
||||||
name: name,
|
name: name,
|
||||||
hide: song.getAtt('hide').getDefault('false') == "true",
|
hide: song.getAtt('hide').getDefault('false') == "true",
|
||||||
displayName: song.getAtt('displayName'),
|
displayName: song.getAtt('displayName')
|
||||||
variation: song.getAtt('variation')
|
|
||||||
});
|
});
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
Logs.trace('Song at index ${k} in week $weekName cannot contain any other XML nodes in its name.', WARNING);
|
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 library:ModsFolderLibrary = null;
|
||||||
var goToState:Class<FlxState>;
|
var goToState:Class<FlxState>;
|
||||||
|
|
||||||
public static var defaultModConfigText =
|
public static inline var defaultModConfigText =
|
||||||
'[Common] # This section applies the \'MOD_\' prefix to the flags so you don\'t have to.
|
'[Common] # This section applies the \'MOD_\' prefix to the flags so you don\'t have to.
|
||||||
NAME="YOUR MOD NAME HERE"
|
NAME="YOUR MOD NAME HERE"
|
||||||
DESCRIPTION="YOUR MOD DESCRIPTION HERE"
|
DESCRIPTION="YOUR MOD DESCRIPTION HERE"
|
||||||
@@ -17,7 +17,7 @@ AUTHOR="YOU/YOUR TEAM HERE"
|
|||||||
VERSION="YOUR MOD\'S VERSION HERE"
|
VERSION="YOUR MOD\'S VERSION HERE"
|
||||||
|
|
||||||
# DO NOT EDIT!! this is used to check for version compatibility!
|
# DO NOT EDIT!! this is used to check for version compatibility!
|
||||||
API_VERSION=${Flags.CURRENT_API_VERSION}
|
API_VERSION=1
|
||||||
|
|
||||||
DOWNLOAD_LINK="YOUR MOD PAGE LINK HERE"
|
DOWNLOAD_LINK="YOUR MOD PAGE LINK HERE"
|
||||||
|
|
||||||
|
|||||||
@@ -104,7 +104,6 @@ class CharacterAnimsWindow extends UIButtonList<CharacterAnimButton> {
|
|||||||
if (character.getAnimName() == button.anim)
|
if (character.getAnimName() == button.anim)
|
||||||
@:privateAccess CharacterEditor.instance._animation_down(null);
|
@:privateAccess CharacterEditor.instance._animation_down(null);
|
||||||
|
|
||||||
character.ghosts.remove(button.anim);
|
|
||||||
character.removeAnimation(button.anim);
|
character.removeAnimation(button.anim);
|
||||||
if (character.animOffsets.exists(button.anim)) character.animOffsets.remove(button.anim);
|
if (character.animOffsets.exists(button.anim)) character.animOffsets.remove(button.anim);
|
||||||
if (character.animDatas.exists(button.anim)) character.animDatas.remove(button.anim);
|
if (character.animDatas.exists(button.anim)) character.animDatas.remove(button.anim);
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class CharacterGhost extends Character {
|
|||||||
alpha = 0.4; color = 0xFFAEAEAE;
|
alpha = 0.4; color = 0xFFAEAEAE;
|
||||||
|
|
||||||
var flxanim:FlxAnimation = animation._animations.get(anim);
|
var flxanim:FlxAnimation = animation._animations.get(anim);
|
||||||
var frameIndex:Int = flxanim.frames.getDefault([0])[flxanim.frames.length - 1];
|
var frameIndex:Int = flxanim.frames.getDefault([0])[0];
|
||||||
frame = frames.frames[frameIndex];
|
frame = frames.frames[frameIndex];
|
||||||
|
|
||||||
setAnimOffset(anim);
|
setAnimOffset(anim);
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ class Charter extends UIState {
|
|||||||
public var metronome:FlxSound;
|
public var metronome:FlxSound;
|
||||||
|
|
||||||
public var vocals:FlxSound;
|
public var vocals:FlxSound;
|
||||||
public var voicesMuted:Bool = false;
|
|
||||||
|
|
||||||
public var quant:Int = 16;
|
public var quant:Int = 16;
|
||||||
public var quants:Array<Int> = [4, 8, 12, 16, 20, 24, 32, 48, 64, 192]; // different quants
|
public var quants:Array<Int> = [4, 8, 12, 16, 20, 24, 32, 48, 64, 192]; // different quants
|
||||||
@@ -1813,9 +1812,9 @@ class Charter extends UIState {
|
|||||||
t.icon = 1 - Std.int(Math.ceil(FlxG.sound.music.volume));
|
t.icon = 1 - Std.int(Math.ceil(FlxG.sound.music.volume));
|
||||||
}
|
}
|
||||||
function _song_mutevoices(t) {
|
function _song_mutevoices(t) {
|
||||||
vocals.volume = (voicesMuted = !voicesMuted) ? 0 : 1;
|
vocals.volume = vocals.volume > 0 ? 0 : 1;
|
||||||
for (strumLine in strumLines.members) strumLine.updateVoicesVolume();
|
for (strumLine in strumLines.members) strumLine.vocals.volume = strumLine.vocals.volume > 0 ? 0 : 1;
|
||||||
t.icon = voicesMuted ? 1 : 0;
|
t.icon = 1 - Std.int(Math.ceil(vocals.volume));
|
||||||
}
|
}
|
||||||
function _playback_back(_) {
|
function _playback_back(_) {
|
||||||
if (FlxG.sound.music.playing) return;
|
if (FlxG.sound.music.playing) return;
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ class CharterEvent extends UISliceSprite implements ICharterSelectable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pack data is a list of 5 strings separated by `________PACKSEP________`
|
* Pack data is a list of 4 strings separated by `________PACKSEP________`
|
||||||
* [0] Event Name
|
* [0] Event Name
|
||||||
* [1] Event Script
|
* [1] Event Script
|
||||||
* [2] Event JSON Info
|
* [2] Event JSON Info
|
||||||
@@ -276,47 +276,10 @@ class CharterEvent extends UISliceSprite implements ICharterSelectable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "Camera Movement":
|
case "Camera Movement":
|
||||||
var shouldDoArrow:Bool = false;
|
// camera movement, use health icon
|
||||||
var icon:Null<FlxSprite> = null;
|
if(event.params != null) {
|
||||||
if (event.params != null) {
|
var icon = getIconFromStrumline(event.params[0]);
|
||||||
shouldDoArrow = event.params[1] && event.params[3] != "CLASSIC"; // is Tweened and isnt Lerped
|
if(icon != null) return icon;
|
||||||
icon = getIconFromStrumline(event.params[0]); // camera movement, use health icon
|
|
||||||
}
|
|
||||||
|
|
||||||
if (icon == null) icon = generateDefaultIcon(event.name);
|
|
||||||
|
|
||||||
if(event.params != null && shouldDoArrow && !inMenu) {
|
|
||||||
var group = new EventIconGroup();
|
|
||||||
group.add(icon);
|
|
||||||
group.members[0].x -= 8;
|
|
||||||
group.members[0].y -= 8;
|
|
||||||
generateEventIconDurationArrow(group, event.params[2]);
|
|
||||||
return group;
|
|
||||||
} else
|
|
||||||
return icon;
|
|
||||||
|
|
||||||
case "Camera Position":
|
|
||||||
var shouldDoArrow:Bool = false;
|
|
||||||
if (event.params != null)
|
|
||||||
shouldDoArrow = event.params[2] && event.params[4] != "CLASSIC"; // is Tweened and isnt Lerped
|
|
||||||
|
|
||||||
if(event.params != null && shouldDoArrow && !inMenu) {
|
|
||||||
var group = new EventIconGroup();
|
|
||||||
group.add(generateDefaultIcon(event.name));
|
|
||||||
generateEventIconDurationArrow(group, event.params[3]);
|
|
||||||
return group;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "Camera Zoom":
|
|
||||||
var shouldDoArrow:Bool = false;
|
|
||||||
if (event.params != null)
|
|
||||||
shouldDoArrow = event.params[0];
|
|
||||||
|
|
||||||
if(event.params != null && shouldDoArrow && !inMenu) {
|
|
||||||
var group = new EventIconGroup();
|
|
||||||
group.add(generateDefaultIcon(event.name));
|
|
||||||
generateEventIconDurationArrow(group, event.params[3]);
|
|
||||||
return group;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return generateDefaultIcon(event.name);
|
return generateDefaultIcon(event.name);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class CharterEventGroup extends FlxTypedGroup<CharterEvent> {
|
|||||||
if (autoSort && members.length != __lastSort)
|
if (autoSort && members.length != __lastSort)
|
||||||
sortEvents();
|
sortEvents();
|
||||||
|
|
||||||
eventsRowText.y = FlxMath.lerp(eventsRowText.y, -40 + (members[0] != null ? Math.min(members[0].y, 0) : 0), 1/10);
|
eventsRowText.y = FlxMath.lerp(eventsRowText.y, -40 + (members[0] != null ? Math.min(members[0].y, 0) : 0), 1/20);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function remove(v:CharterEvent, force:Bool = true):CharterEvent {
|
public override function remove(v:CharterEvent, force:Bool = true):CharterEvent {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package funkin.editors.charter;
|
package funkin.editors.charter;
|
||||||
|
|
||||||
import funkin.game.HealthIcon;
|
|
||||||
import flixel.math.FlxPoint;
|
import flixel.math.FlxPoint;
|
||||||
import funkin.backend.chart.ChartData.ChartMetaData;
|
import funkin.backend.chart.ChartData.ChartMetaData;
|
||||||
import funkin.editors.extra.PropertyButton;
|
import funkin.editors.extra.PropertyButton;
|
||||||
@@ -22,7 +21,8 @@ class CharterMetaDataScreen extends UISubstateWindow {
|
|||||||
public var displayNameTextBox:UITextBox;
|
public var displayNameTextBox:UITextBox;
|
||||||
public var iconTextBox:UITextBox;
|
public var iconTextBox:UITextBox;
|
||||||
public var iconSprite:HealthIcon;
|
public var iconSprite:HealthIcon;
|
||||||
public var excludedGameModesList:UIAutoCompleteButtonList;
|
public var opponentModeCheckbox:UICheckbox;
|
||||||
|
public var coopAllowedCheckbox:UICheckbox;
|
||||||
public var needsVoicesCheckbox:UICheckbox;
|
public var needsVoicesCheckbox:UICheckbox;
|
||||||
public var colorWheel:UIColorwheel;
|
public var colorWheel:UIColorwheel;
|
||||||
public var difficultiesTextBox:UITextBox;
|
public var difficultiesTextBox:UITextBox;
|
||||||
@@ -78,29 +78,25 @@ class CharterMetaDataScreen extends UISubstateWindow {
|
|||||||
add(displayNameTextBox);
|
add(displayNameTextBox);
|
||||||
addLabelOn(displayNameTextBox, translate("displayName"));
|
addLabelOn(displayNameTextBox, translate("displayName"));
|
||||||
|
|
||||||
add(iconSprite = new HealthIcon(metadata.icon));
|
|
||||||
iconSprite.scale.set(0.5, 0.5);
|
|
||||||
iconSprite.updateHitbox();
|
|
||||||
|
|
||||||
iconTextBox = new UITextBox(displayNameTextBox.x + 320 + 26, displayNameTextBox.y, metadata.icon, 150);
|
iconTextBox = new UITextBox(displayNameTextBox.x + 320 + 26, displayNameTextBox.y, metadata.icon, 150);
|
||||||
iconTextBox.onChange = (newIcon:String) -> iconSprite.setIcon(newIcon);
|
iconTextBox.onChange = (newIcon:String) -> {updateIcon(newIcon);}
|
||||||
add(iconTextBox);
|
add(iconTextBox);
|
||||||
addLabelOn(iconTextBox, translate("icon"));
|
addLabelOn(iconTextBox, translate("icon"));
|
||||||
|
|
||||||
updateIcon(metadata.icon);
|
updateIcon(metadata.icon);
|
||||||
|
|
||||||
add(excludedGameModesList = new UIAutoCompleteButtonList(displayNameTextBox.x, iconTextBox.y + 62, Std.int(displayNameTextBox.bWidth), 100, "", [for (mode in funkin.menus.FreeplayState.FreeplayGameMode.get()) mode.modeID]));
|
opponentModeCheckbox = new UICheckbox(displayNameTextBox.x, iconTextBox.y + 10 + 32 + 26, translate("opponentMode"), metadata.opponentModeAllowed);
|
||||||
excludedGameModesList.frames = Paths.getFrames('editors/ui/inputbox');
|
add(opponentModeCheckbox);
|
||||||
excludedGameModesList.cameraSpacing = 0;
|
addLabelOn(opponentModeCheckbox, translate("modesAllowed"));
|
||||||
addLabelOn(excludedGameModesList, "Excluded Game Modes (IDs)");
|
|
||||||
for (mode in metadata.excludedGameModes)
|
coopAllowedCheckbox = new UICheckbox(opponentModeCheckbox.x + 150 + 26, opponentModeCheckbox.y, translate("coopAllowed"), metadata.coopAllowed);
|
||||||
excludedGameModesList.add(new UIAutoCompleteButtonList.UIAutoCompleteButton(0, 0, excludedGameModesList, excludedGameModesList.suggestItems, mode));
|
add(coopAllowedCheckbox);
|
||||||
|
|
||||||
colorWheel = new UIColorwheel(iconTextBox.x, coopAllowedCheckbox.y, metadata.color);
|
colorWheel = new UIColorwheel(iconTextBox.x, coopAllowedCheckbox.y, metadata.color);
|
||||||
add(colorWheel);
|
add(colorWheel);
|
||||||
addLabelOn(colorWheel, translate("color"));
|
addLabelOn(colorWheel, translate("color"));
|
||||||
|
|
||||||
difficultiesTextBox = new UITextBox(excludedGameModesList.x, excludedGameModesList.y + excludedGameModesList.bHeight + 32, metadata.difficulties.join(", "));
|
difficultiesTextBox = new UITextBox(opponentModeCheckbox.x, opponentModeCheckbox.y + 6 + 32 + 26, metadata.difficulties.join(", "));
|
||||||
add(difficultiesTextBox);
|
add(difficultiesTextBox);
|
||||||
addLabelOn(difficultiesTextBox, translate("difficulties"));
|
addLabelOn(difficultiesTextBox, translate("difficulties"));
|
||||||
|
|
||||||
@@ -115,6 +111,9 @@ class CharterMetaDataScreen extends UISubstateWindow {
|
|||||||
add(customPropertiesButtonList);
|
add(customPropertiesButtonList);
|
||||||
addLabelOn(customPropertiesButtonList, translate("customValues"));
|
addLabelOn(customPropertiesButtonList, translate("customValues"));
|
||||||
|
|
||||||
|
for (checkbox in [opponentModeCheckbox, coopAllowedCheckbox])
|
||||||
|
{checkbox.y += 6; checkbox.x += 4;}
|
||||||
|
|
||||||
saveButton = new UIButton(windowSpr.x + windowSpr.bWidth - 20, windowSpr.y + windowSpr.bHeight - 20, TU.translate("editor.saveClose"), function() {
|
saveButton = new UIButton(windowSpr.x + windowSpr.bWidth - 20, windowSpr.y + windowSpr.bHeight - 20, TU.translate("editor.saveClose"), function() {
|
||||||
saveMeta();
|
saveMeta();
|
||||||
close();
|
close();
|
||||||
@@ -162,7 +161,8 @@ class CharterMetaDataScreen extends UISubstateWindow {
|
|||||||
meta.displayName = displayNameTextBox.label.text;
|
meta.displayName = displayNameTextBox.label.text;
|
||||||
meta.icon = iconTextBox.label.text;
|
meta.icon = iconTextBox.label.text;
|
||||||
meta.color = colorWheel.curColor;
|
meta.color = colorWheel.curColor;
|
||||||
meta.excludedGameModes = [for (button in excludedGameModesList.buttons.members) button.textBox.label.text.trim()],
|
meta.opponentModeAllowed = opponentModeCheckbox.checked;
|
||||||
|
meta.coopAllowed = coopAllowedCheckbox.checked;
|
||||||
meta.difficulties = [for (diff in difficultiesTextBox.label.text.split(",")) diff.trim()];
|
meta.difficulties = [for (diff in difficultiesTextBox.label.text.split(",")) diff.trim()];
|
||||||
meta.customValues = customVals;
|
meta.customValues = customVals;
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class CharterSelectionScreen extends EditorTreeMenuScreen {
|
|||||||
var screen = new EditorTreeMenuScreen((first || !isVariant) ? (s.name + (isVariant ? ' (${s.variant})' : '')) : s.variant, getID('selectDifficulty'));
|
var screen = new EditorTreeMenuScreen((first || !isVariant) ? (s.name + (isVariant ? ' (${s.variant})' : '')) : s.variant, getID('selectDifficulty'));
|
||||||
|
|
||||||
for (d in s.difficulties) if (d != '') screen.add(makeChartOption(d, isVariant ? s.variant : null, s.name));
|
for (d in s.difficulties) if (d != '') screen.add(makeChartOption(d, isVariant ? s.variant : null, s.name));
|
||||||
if (s.difficulties.length > 0 && s.variants.length > 0) screen.add(new Separator()); // Create a separator only when there are both difficulty and variant options available.
|
screen.add(new Separator());
|
||||||
for (v in s.variants) if (s.metas.get(v) != null) screen.add(makeVariationOption(s.metas.get(v)));
|
for (v in s.variants) if (s.metas.get(v) != null) screen.add(makeVariationOption(s.metas.get(v)));
|
||||||
|
|
||||||
#if sys
|
#if sys
|
||||||
@@ -48,13 +48,13 @@ class CharterSelectionScreen extends EditorTreeMenuScreen {
|
|||||||
parent.openSubState(new ChartCreationScreen(saveChart));
|
parent.openSubState(new ChartCreationScreen(saveChart));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (!first) screen.curSelected = (s.difficulties.length + s.variants.length) > 0 ? 1 : 0;
|
if (!first) screen.curSelected = 1;
|
||||||
else {
|
else {
|
||||||
cast(screen.members[0], NewOption).itemHeight = 120;
|
cast(screen.members[0], NewOption).itemHeight = 120;
|
||||||
screen.insert(1, new NewOption(getID('newVariation'), getID('newVariationDesc'), () -> {
|
screen.insert(1, new NewOption(getID('newVariation'), getID('newVariationDesc'), () -> {
|
||||||
parent.openSubState(new VariationCreationScreen(s, saveSong));
|
parent.openSubState(new VariationCreationScreen(s, saveSong));
|
||||||
}));
|
}));
|
||||||
screen.curSelected = (s.difficulties.length + s.variants.length) > 0 ? 2 : 1;
|
screen.curSelected = 2;
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ class CharterStrumline extends UISprite {
|
|||||||
public var curMenu:UIContextMenu = null;
|
public var curMenu:UIContextMenu = null;
|
||||||
|
|
||||||
public var vocals:FlxSound;
|
public var vocals:FlxSound;
|
||||||
public var voicesMuted:Bool = false;
|
|
||||||
|
|
||||||
public var keyCount:Int = 4;
|
public var keyCount:Int = 4;
|
||||||
public var startingID(get, null):Int;
|
public var startingID(get, null):Int;
|
||||||
@@ -148,10 +147,6 @@ class CharterStrumline extends UISprite {
|
|||||||
}
|
}
|
||||||
vocals.group = FlxG.sound.defaultMusicGroup;
|
vocals.group = FlxG.sound.defaultMusicGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateVoicesVolume() {
|
|
||||||
vocals.volume = (voicesMuted || (Charter.instance?.voicesMuted ?? false)) ? 0 : 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class CharterStrumlineOptions extends UITopMenuButton {
|
class CharterStrumlineOptions extends UITopMenuButton {
|
||||||
@@ -181,10 +176,9 @@ class CharterStrumlineOptions extends UITopMenuButton {
|
|||||||
{
|
{
|
||||||
label: TU.translate("charter.strumLine.muteVocals"),
|
label: TU.translate("charter.strumLine.muteVocals"),
|
||||||
onSelect: function(_) {
|
onSelect: function(_) {
|
||||||
strLine.voicesMuted = !strLine.voicesMuted;
|
strLine.vocals.volume = strLine.vocals.volume > 0 ? 0 : 1;
|
||||||
strLine.updateVoicesVolume();
|
|
||||||
},
|
},
|
||||||
icon: strLine.voicesMuted ? 1 : 0
|
icon: strLine.vocals.volume > 0 ? 0 : 1
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -287,4 +287,4 @@ class CharacterButton extends UIButton {
|
|||||||
|
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package funkin.editors.charter;
|
package funkin.editors.charter;
|
||||||
|
|
||||||
import funkin.game.HealthIcon;
|
|
||||||
import flixel.group.FlxGroup;
|
import flixel.group.FlxGroup;
|
||||||
import flixel.text.FlxText.FlxTextFormat;
|
import flixel.text.FlxText.FlxTextFormat;
|
||||||
import flixel.text.FlxText.FlxTextFormatMarkerPair;
|
import flixel.text.FlxText.FlxTextFormatMarkerPair;
|
||||||
@@ -38,7 +37,8 @@ class SongCreationScreen extends UISubstateWindow {
|
|||||||
public var displayNameTextBox:UITextBox;
|
public var displayNameTextBox:UITextBox;
|
||||||
public var iconTextBox:UITextBox;
|
public var iconTextBox:UITextBox;
|
||||||
public var iconSprite:HealthIcon;
|
public var iconSprite:HealthIcon;
|
||||||
public var excludedGameModesList:UIAutoCompleteButtonList;
|
public var opponentModeCheckbox:UICheckbox;
|
||||||
|
public var coopAllowedCheckbox:UICheckbox;
|
||||||
public var colorWheel:UIColorwheel;
|
public var colorWheel:UIColorwheel;
|
||||||
public var difficultiesTextBox:UITextBox;
|
public var difficultiesTextBox:UITextBox;
|
||||||
|
|
||||||
@@ -166,19 +166,24 @@ class SongCreationScreen extends UISubstateWindow {
|
|||||||
|
|
||||||
updateIcon("face");
|
updateIcon("face");
|
||||||
|
|
||||||
menuDataGroup.add(excludedGameModesList = new UIAutoCompleteButtonList(displayNameTextBox.x, iconTextBox.y + 62, Std.int(displayNameTextBox.bWidth), 100, "", [for (mode in funkin.menus.FreeplayState.FreeplayGameMode.get()) mode.modeID]));
|
opponentModeCheckbox = new UICheckbox(displayNameTextBox.x, iconTextBox.y + 10 + 32 + 26, translateMeta("opponentMode"), true);
|
||||||
excludedGameModesList.frames = Paths.getFrames('editors/ui/inputbox');
|
menuDataGroup.add(opponentModeCheckbox);
|
||||||
excludedGameModesList.cameraSpacing = 0;
|
addLabelOn(opponentModeCheckbox, translateMeta("modesAllowed"));
|
||||||
addLabelOn(excludedGameModesList, "Excluded Game Modes (IDs)");
|
|
||||||
|
|
||||||
colorWheel = new UIColorwheel(iconTextBox.x, excludedGameModesList.y, 0xFFFFFF);
|
coopAllowedCheckbox = new UICheckbox(opponentModeCheckbox.x + 150 + 26, opponentModeCheckbox.y, translateMeta("coopAllowed"), true);
|
||||||
|
menuDataGroup.add(coopAllowedCheckbox);
|
||||||
|
|
||||||
|
colorWheel = new UIColorwheel(iconTextBox.x, coopAllowedCheckbox.y, 0xFFFFFF);
|
||||||
menuDataGroup.add(colorWheel);
|
menuDataGroup.add(colorWheel);
|
||||||
addLabelOn(colorWheel, translateMeta("color"));
|
addLabelOn(colorWheel, translateMeta("color"));
|
||||||
|
|
||||||
difficultiesTextBox = new UITextBox(excludedGameModesList.x, excludedGameModesList.y + excludedGameModesList.bHeight + 32, "");
|
difficultiesTextBox = new UITextBox(opponentModeCheckbox.x, opponentModeCheckbox.y + 6 + 32 + 26, "");
|
||||||
menuDataGroup.add(difficultiesTextBox);
|
menuDataGroup.add(difficultiesTextBox);
|
||||||
addLabelOn(difficultiesTextBox, translateMeta("difficulties"));
|
addLabelOn(difficultiesTextBox, translateMeta("difficulties"));
|
||||||
|
|
||||||
|
for (checkbox in [opponentModeCheckbox, coopAllowedCheckbox])
|
||||||
|
{checkbox.y += 6; checkbox.x += 4;}
|
||||||
|
|
||||||
var menuTitle:UIText;
|
var menuTitle:UIText;
|
||||||
selectFormatGroup.add(menuTitle = new UIText(windowSpr.x + 20, windowSpr.y + 30 + 16, 0, translate("importSource"), 28));
|
selectFormatGroup.add(menuTitle = new UIText(windowSpr.x + 20, windowSpr.y + 30 + 16, 0, translate("importSource"), 28));
|
||||||
|
|
||||||
@@ -428,8 +433,9 @@ class SongCreationScreen extends UISubstateWindow {
|
|||||||
displayName: displayNameTextBox.label.text,
|
displayName: displayNameTextBox.label.text,
|
||||||
icon: iconTextBox.label.text,
|
icon: iconTextBox.label.text,
|
||||||
color: colorWheel.curColor,
|
color: colorWheel.curColor,
|
||||||
excludedGameModes: [for (button in excludedGameModesList.buttons.members) button.textBox.label.text.trim()],
|
opponentModeAllowed: opponentModeCheckbox.checked,
|
||||||
difficulties: [for (diff in difficultiesTextBox.label.text.split(",")) if (diff.length > 0) diff.trim()]
|
coopAllowed: coopAllowedCheckbox.checked,
|
||||||
|
difficulties: [for (diff in difficultiesTextBox.label.text.split(",")) diff.trim()]
|
||||||
});
|
});
|
||||||
|
|
||||||
if (onSave != null) onSave({
|
if (onSave != null) onSave({
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
package funkin.editors.ui;
|
|
||||||
|
|
||||||
typedef UIAutoCompleteButtonList = UITypedAutoCompleteButtonList<UIAutoCompleteButton>;
|
|
||||||
|
|
||||||
class UITypedAutoCompleteButtonList<T:UIAutoCompleteButton> extends UIButtonList<T> {
|
|
||||||
public var suggestItems(default, set):Array<String> = [];
|
|
||||||
|
|
||||||
private function set_suggestItems(value:Array<String>) {
|
|
||||||
buttons.forEachAlive((button) -> button.textBox.suggestItems = value);
|
|
||||||
return suggestItems = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function new(x:Float, y:Float, width:Int, height:Int, windowName:String, ?suggestItems:Array<String>, ?buttonSize:FlxPoint, ?buttonOffset:FlxPoint, buttonSpacing:Float = 0) {
|
|
||||||
super(x, y, width, height, windowName, buttonSize == null ? FlxPoint.get(width, width * 0.15) : buttonSize, buttonOffset, buttonSpacing);
|
|
||||||
if (suggestItems != null && suggestItems.length > 0) this.suggestItems = suggestItems;
|
|
||||||
addButton.callback = () -> add(cast new UIAutoCompleteButton(0, 0, cast this, this.suggestItems));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class UIAutoCompleteButton extends UIButton {
|
|
||||||
public var textBox:UIAutoCompleteTextBox;
|
|
||||||
public var deleteButton:UIButton;
|
|
||||||
public var deleteIcon:FlxSprite;
|
|
||||||
|
|
||||||
public function new (x:Float, y:Float, parent:UIAutoCompleteButtonList, ?suggestItems:Array<String>, text:String = "", ?w:Int, ?h:Int, multiline:Bool = false) {
|
|
||||||
super(x, y, "", null, w == null ? Std.int(parent.buttonSize.x) : w, h == null ? Std.int(parent.buttonSize.y) : h);
|
|
||||||
|
|
||||||
members.push(textBox = new UIAutoCompleteTextBox(16, bHeight/2 - (32/2), text, Std.int(bWidth - 32 - 36), 32, multiline));
|
|
||||||
if (suggestItems != null && suggestItems.length > 0) textBox.suggestItems = suggestItems;
|
|
||||||
textBox.antialiasing = false;
|
|
||||||
|
|
||||||
members.push(deleteButton = new UIButton(textBox.x + textBox.bWidth + 10, textBox.y, "", () -> { parent.remove(this); destroy(); }, 32));
|
|
||||||
deleteButton.color = 0xFFFF0000;
|
|
||||||
deleteButton.autoAlpha = false;
|
|
||||||
|
|
||||||
members.push(deleteIcon = new FlxSprite(deleteButton.x + (15/2), deleteButton.y + 8).loadGraphic(Paths.image('editors/delete-button')));
|
|
||||||
deleteIcon.antialiasing = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
override function update(elapsed) {
|
|
||||||
deleteButton.y = y + bHeight / 2 - deleteButton.bHeight / 2;
|
|
||||||
textBox.y = y + bHeight/2 - 16;
|
|
||||||
deleteIcon.x = deleteButton.x + (15/2); deleteIcon.y = deleteButton.y + 8;
|
|
||||||
|
|
||||||
textBox.selectable = deleteButton.selectable = selectable;
|
|
||||||
deleteButton.shouldPress = shouldPress;
|
|
||||||
|
|
||||||
super.update(elapsed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -108,19 +108,11 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function swapLeftRightAnimations() {
|
public function swapLeftRightAnimations() {
|
||||||
// Find all "alternate" poses
|
CoolUtil.switchAnimFrames(animation.getByName('singRIGHT'), animation.getByName('singLEFT'));
|
||||||
var variants = ['']; // Pre-fill with empty string
|
CoolUtil.switchAnimFrames(animation.getByName('singRIGHTmiss'), animation.getByName('singLEFTmiss'));
|
||||||
var pose = 'singRIGHT'; // Any "sing" animation string could work, really
|
|
||||||
for (a in xml.nodes.anim) {
|
|
||||||
if (a.att.name != pose && StringTools.startsWith(a.att.name, pose)) {
|
|
||||||
variants.push(a.att.name.substring(pose.length));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i in variants) {
|
switchOffset('singLEFT', 'singRIGHT');
|
||||||
CoolUtil.switchAnimFrames(animation.getByName('singRIGHT$i'), animation.getByName('singLEFT$i'));
|
switchOffset('singLEFTmiss', 'singRIGHTmiss');
|
||||||
switchOffset('singLEFT$i', 'singRIGHT$i');
|
|
||||||
}
|
|
||||||
|
|
||||||
__swappedLeftRightAnims = true;
|
__swappedLeftRightAnims = true;
|
||||||
}
|
}
|
||||||
@@ -588,4 +580,4 @@ class Character extends FunkinSprite implements IBeatReceiver implements IOffset
|
|||||||
list.push(CoolUtil.getFilename(path));
|
list.push(CoolUtil.getFilename(path));
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,15 +60,6 @@ class Note extends FlxSprite
|
|||||||
*/
|
*/
|
||||||
public var sustainParent:Null<Note>;
|
public var sustainParent:Null<Note>;
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of active sustain pieces attached to this note
|
|
||||||
*
|
|
||||||
* Increases by 1 every time a hold piece is initialized.
|
|
||||||
*
|
|
||||||
* Decreases by 1 every time a hold piece gets destroyed.
|
|
||||||
*/
|
|
||||||
public var tailCount:Int = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Name of the splash.
|
* Name of the splash.
|
||||||
*/
|
*/
|
||||||
@@ -83,7 +74,6 @@ class Note extends FlxSprite
|
|||||||
|
|
||||||
public var sustainLength:Float = 0;
|
public var sustainLength:Float = 0;
|
||||||
public var isSustainNote:Bool = false;
|
public var isSustainNote:Bool = false;
|
||||||
public var noSustainClip:Bool = false;
|
|
||||||
public var flipSustain:Bool = true;
|
public var flipSustain:Bool = true;
|
||||||
|
|
||||||
public var noteTypeID:Int = 0;
|
public var noteTypeID:Int = 0;
|
||||||
@@ -114,8 +104,6 @@ class Note extends FlxSprite
|
|||||||
|
|
||||||
public var animSuffix:String = null;
|
public var animSuffix:String = null;
|
||||||
|
|
||||||
// Deprecated?
|
|
||||||
@:dox(hide) public var tripTimer:Float = 0; // ranges from 0 to 1
|
|
||||||
|
|
||||||
private static function customTypePathExists(path:String) {
|
private static function customTypePathExists(path:String) {
|
||||||
if (__customNoteTypeExists.exists(path))
|
if (__customNoteTypeExists.exists(path))
|
||||||
@@ -223,7 +211,6 @@ class Note extends FlxSprite
|
|||||||
public var lastScrollSpeed:Null<Float> = null;
|
public var lastScrollSpeed:Null<Float> = null;
|
||||||
public var gapFix:SingleOrFloat = 0;
|
public var gapFix:SingleOrFloat = 0;
|
||||||
public var useAntialiasingFix(get, set):Bool;
|
public var useAntialiasingFix(get, set):Bool;
|
||||||
|
|
||||||
inline function set_useAntialiasingFix(v:Bool) {
|
inline function set_useAntialiasingFix(v:Bool) {
|
||||||
if(v != useAntialiasingFix) {
|
if(v != useAntialiasingFix) {
|
||||||
gapFix = v ? 1 : 0;
|
gapFix = v ? 1 : 0;
|
||||||
@@ -310,8 +297,8 @@ class Note extends FlxSprite
|
|||||||
updateSustainClip();
|
updateSustainClip();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateSustainClip() if (wasGoodHit && !noSustainClip) {
|
public function updateSustainClip() if (wasGoodHit) {
|
||||||
var t = CoolUtil.bound((Conductor.songPosition - strumTime) / height * 0.45 * lastScrollSpeed, 0, 1);
|
var t = FlxMath.bound((Conductor.songPosition - strumTime) / height * 0.45 * lastScrollSpeed, 0, 1);
|
||||||
var rect = clipRect == null ? FlxRect.get() : clipRect;
|
var rect = clipRect == null ? FlxRect.get() : clipRect;
|
||||||
clipRect = rect.set(0, frameHeight * t, frameWidth, frameHeight * (1 - t));
|
clipRect = rect.set(0, frameHeight * t, frameWidth, frameHeight * (1 - t));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,11 +53,14 @@ class NoteGroup extends FlxTypedGroup<Note> {
|
|||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
i = length-1;
|
i = length-1;
|
||||||
__loopSprite = null;
|
__loopSprite = null;
|
||||||
__time = __getSongPos() + limit;
|
__time = __getSongPos();
|
||||||
while(i >= 0) {
|
while(i >= 0) {
|
||||||
__loopSprite = members[i--];
|
__loopSprite = members[i--];
|
||||||
if (__loopSprite == null || !__loopSprite.exists || !__loopSprite.active) continue;
|
if (__loopSprite == null || !__loopSprite.exists || !__loopSprite.active) {
|
||||||
if (__loopSprite.strumTime > __time) break;
|
continue;
|
||||||
|
}
|
||||||
|
if (__loopSprite.strumTime - __time > limit)
|
||||||
|
break;
|
||||||
__loopSprite.update(elapsed);
|
__loopSprite.update(elapsed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,11 +74,12 @@ class NoteGroup extends FlxTypedGroup<Note> {
|
|||||||
|
|
||||||
i = length-1;
|
i = length-1;
|
||||||
__loopSprite = null;
|
__loopSprite = null;
|
||||||
__time = __getSongPos() + limit;
|
__time = __getSongPos();
|
||||||
while(i >= 0) {
|
while(i >= 0) {
|
||||||
__loopSprite = members[i--];
|
__loopSprite = members[i--];
|
||||||
if (__loopSprite == null || !__loopSprite.exists || !__loopSprite.visible) continue;
|
if (__loopSprite == null || !__loopSprite.exists || !__loopSprite.visible)
|
||||||
if (__loopSprite.strumTime > __time) break;
|
continue;
|
||||||
|
if (__loopSprite.strumTime - __time > limit) break;
|
||||||
__loopSprite.draw();
|
__loopSprite.draw();
|
||||||
}
|
}
|
||||||
__currentlyLooping = oldCur;
|
__currentlyLooping = oldCur;
|
||||||
@@ -93,15 +97,16 @@ class NoteGroup extends FlxTypedGroup<Note> {
|
|||||||
public override function forEach(noteFunc:Note->Void, recursive:Bool = false) {
|
public override function forEach(noteFunc:Note->Void, recursive:Bool = false) {
|
||||||
i = length-1;
|
i = length-1;
|
||||||
__loopSprite = null;
|
__loopSprite = null;
|
||||||
__time = __getSongPos() + limit;
|
__time = __getSongPos();
|
||||||
|
|
||||||
var oldCur = __currentlyLooping;
|
var oldCur = __currentlyLooping;
|
||||||
__currentlyLooping = true;
|
__currentlyLooping = true;
|
||||||
|
|
||||||
while(i >= 0) {
|
while(i >= 0) {
|
||||||
__loopSprite = members[i--];
|
__loopSprite = members[i--];
|
||||||
if (__loopSprite == null || !__loopSprite.exists) continue;
|
if (__loopSprite == null || !__loopSprite.exists)
|
||||||
if (__loopSprite.strumTime > __time) break;
|
continue;
|
||||||
|
if (__loopSprite.strumTime - __time > limit) break;
|
||||||
noteFunc(__loopSprite);
|
noteFunc(__loopSprite);
|
||||||
}
|
}
|
||||||
__currentlyLooping = oldCur;
|
__currentlyLooping = oldCur;
|
||||||
|
|||||||
@@ -29,8 +29,6 @@ import funkin.editors.charter.Charter;
|
|||||||
import funkin.editors.charter.CharterSelection;
|
import funkin.editors.charter.CharterSelection;
|
||||||
import funkin.game.SplashHandler;
|
import funkin.game.SplashHandler;
|
||||||
import funkin.game.cutscenes.*;
|
import funkin.game.cutscenes.*;
|
||||||
import funkin.game.scoring.*;
|
|
||||||
import funkin.game.scoring.RatingManager.Rating;
|
|
||||||
import funkin.menus.*;
|
import funkin.menus.*;
|
||||||
import funkin.backend.week.WeekData;
|
import funkin.backend.week.WeekData;
|
||||||
import funkin.savedata.FunkinSave;
|
import funkin.savedata.FunkinSave;
|
||||||
@@ -332,10 +330,6 @@ class PlayState extends MusicBeatState
|
|||||||
* The total accuracy amount.
|
* The total accuracy amount.
|
||||||
*/
|
*/
|
||||||
public var totalAccuracyAmount:Float = 0;
|
public var totalAccuracyAmount:Float = 0;
|
||||||
/**
|
|
||||||
* Tracks how much of each rating was received.
|
|
||||||
*/
|
|
||||||
public var hits:Map<String, Int> = [];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FunkinText that shows your score.
|
* FunkinText that shows your score.
|
||||||
@@ -368,11 +362,6 @@ class PlayState extends MusicBeatState
|
|||||||
public static var campaignAccuracyTotal:Float = 0;
|
public static var campaignAccuracyTotal:Float = 0;
|
||||||
public static var campaignAccuracyCount:Float = 0;
|
public static var campaignAccuracyCount:Float = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of each rating received for the current week.
|
|
||||||
*/
|
|
||||||
public static var campaignHits:Map<String, Int> = [];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Camera zoom at which the game lerps to.
|
* Camera zoom at which the game lerps to.
|
||||||
*/
|
*/
|
||||||
@@ -540,10 +529,6 @@ class PlayState extends MusicBeatState
|
|||||||
* Group containing all of the combo sprites.
|
* Group containing all of the combo sprites.
|
||||||
*/
|
*/
|
||||||
public var comboGroup:RotatingSpriteGroup;
|
public var comboGroup:RotatingSpriteGroup;
|
||||||
/**
|
|
||||||
* Manager that helps judge note hits to return ratings.
|
|
||||||
*/
|
|
||||||
public var ratingManager:RatingManager = new RatingManager();
|
|
||||||
/**
|
/**
|
||||||
* Whenever the Rating sprites should be shown or not.
|
* Whenever the Rating sprites should be shown or not.
|
||||||
*
|
*
|
||||||
@@ -566,11 +551,10 @@ class PlayState extends MusicBeatState
|
|||||||
public var noteTypesArray:Array<String> = [null];
|
public var noteTypesArray:Array<String> = [null];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hit window, in milliseconds. A Legacy CNE Hit window configuration,
|
* Hit window, in milliseconds. Defaults to 250ms unless changed in options.
|
||||||
* Don't use this, it's for mods that still uses the old judgement timing, instead use ratingManager.
|
* Base game hit window is 175ms.
|
||||||
*/
|
*/
|
||||||
public var hitWindow:Float = Options.hitWindow;
|
public var hitWindow:Float = Options.hitWindow; // is calculated in create(), is safeFrames in milliseconds.
|
||||||
@:noCompletion @:dox(hide) private var _legacyRating:Rating = {name: "", window: 0, accuracy: 0, score: 0};
|
|
||||||
|
|
||||||
@:noCompletion @:dox(hide) private var _startCountdownCalled:Bool = false;
|
@:noCompletion @:dox(hide) private var _startCountdownCalled:Bool = false;
|
||||||
@:noCompletion @:dox(hide) private var _endSongCalled:Bool = false;
|
@:noCompletion @:dox(hide) private var _endSongCalled:Bool = false;
|
||||||
@@ -689,8 +673,6 @@ class PlayState extends MusicBeatState
|
|||||||
|
|
||||||
detailsText = isStoryMode ? ("Story Mode: " + storyWeek.name) : "Freeplay";
|
detailsText = isStoryMode ? ("Story Mode: " + storyWeek.name) : "Freeplay";
|
||||||
|
|
||||||
for (rating in [for (i in ratingManager.ratingData) i.name]) hits.set(rating, 0); // Ensure all keys exist as to prevent null errors.
|
|
||||||
|
|
||||||
// Checks if cutscene files exists
|
// Checks if cutscene files exists
|
||||||
var cutscenePath = Paths.script('songs/${SONG.meta.name}/cutscene');
|
var cutscenePath = Paths.script('songs/${SONG.meta.name}/cutscene');
|
||||||
var endCutscenePath = Paths.script('songs/${SONG.meta.name}/cutscene-end');
|
var endCutscenePath = Paths.script('songs/${SONG.meta.name}/cutscene-end');
|
||||||
@@ -1255,13 +1237,12 @@ class PlayState extends MusicBeatState
|
|||||||
}
|
}
|
||||||
|
|
||||||
@:dox(hide)
|
@:dox(hide)
|
||||||
inline function resyncVocals():Void
|
function resyncVocals():Void
|
||||||
{
|
{
|
||||||
final time = Conductor.songPosition + Conductor.songOffset;
|
var time = Conductor.songPosition + Conductor.songOffset;
|
||||||
|
|
||||||
if (!inst.playing) inst.play(true, time);
|
|
||||||
vocals.play(true, time);
|
|
||||||
for (strumLine in strumLines.members) strumLine.vocals.play(true, time);
|
for (strumLine in strumLines.members) strumLine.vocals.play(true, time);
|
||||||
|
vocals.play(true, time);
|
||||||
|
if (!inst.playing) inst.play(true, time);
|
||||||
|
|
||||||
gameAndCharsCall("onVocalsResync");
|
gameAndCharsCall("onVocalsResync");
|
||||||
}
|
}
|
||||||
@@ -1420,12 +1401,13 @@ class PlayState extends MusicBeatState
|
|||||||
else if (FlxG.sound.music != null && (__vocalSyncTimer -= elapsed) < 0) {
|
else if (FlxG.sound.music != null && (__vocalSyncTimer -= elapsed) < 0) {
|
||||||
__vocalSyncTimer = 1;
|
__vocalSyncTimer = 1;
|
||||||
|
|
||||||
final instTime = FlxG.sound.music.getActualTime();
|
var instTime = FlxG.sound.music.getActualTime();
|
||||||
var isOffsync:Bool = vocals.loaded && Math.abs(instTime - vocals.getActualTime()) > 12;
|
var isOffsync:Bool = vocals.loaded && Math.abs(instTime - vocals.getActualTime()) > 100;
|
||||||
if (!isOffsync)
|
if (!isOffsync) {
|
||||||
for (strumLine in strumLines.members)
|
for (strumLine in strumLines.members) {
|
||||||
if ((isOffsync = strumLine.vocals.loaded && Math.abs(instTime - strumLine.vocals.getActualTime()) > 12))
|
if ((isOffsync = strumLine.vocals.loaded && Math.abs(instTime - strumLine.vocals.getActualTime()) > 100)) break;
|
||||||
break;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isOffsync) resyncVocals();
|
if (isOffsync) resyncVocals();
|
||||||
}
|
}
|
||||||
@@ -1605,13 +1587,11 @@ class PlayState extends MusicBeatState
|
|||||||
var camera:FlxCamera = event.params[1] == "camHUD" ? camHUD : camGame;
|
var camera:FlxCamera = event.params[1] == "camHUD" ? camHUD : camGame;
|
||||||
camera.zoom += event.params[0];
|
camera.zoom += event.params[0];
|
||||||
case "Camera Bop":
|
case "Camera Bop":
|
||||||
if (Options.camZoomOnBeat) {
|
if (useCamZoomMult) {
|
||||||
if (useCamZoomMult) {
|
camZoomingMult += event.params[0];
|
||||||
camZoomingMult += event.params[0];
|
} else {
|
||||||
} else {
|
FlxG.camera.zoom += event.params[0] * camZoomingStrength;
|
||||||
FlxG.camera.zoom += event.params[0] * camZoomingStrength;
|
camHUD.zoom += event.params[0] * camZoomingStrength;
|
||||||
camHUD.zoom += event.params[0] * camZoomingStrength;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case "Camera Zoom":
|
case "Camera Zoom":
|
||||||
var cam = event.params[2] == "camHUD" ? camHUD : camGame;
|
var cam = event.params[2] == "camHUD" ? camHUD : camGame;
|
||||||
@@ -1742,7 +1722,7 @@ class PlayState extends MusicBeatState
|
|||||||
score: songScore,
|
score: songScore,
|
||||||
misses: misses,
|
misses: misses,
|
||||||
accuracy: accuracy,
|
accuracy: accuracy,
|
||||||
hits: hits,
|
hits: [],
|
||||||
date: Date.now().toString()
|
date: Date.now().toString()
|
||||||
}, getSongChanges());
|
}, getSongChanges());
|
||||||
#end
|
#end
|
||||||
@@ -1769,7 +1749,6 @@ class PlayState extends MusicBeatState
|
|||||||
campaignMisses += misses;
|
campaignMisses += misses;
|
||||||
campaignAccuracyTotal += accuracy;
|
campaignAccuracyTotal += accuracy;
|
||||||
campaignAccuracyCount++;
|
campaignAccuracyCount++;
|
||||||
for (k => v in hits) campaignHits[k] += v;
|
|
||||||
storyPlaylist.shift();
|
storyPlaylist.shift();
|
||||||
storyVariations.shift();
|
storyVariations.shift();
|
||||||
|
|
||||||
@@ -1783,7 +1762,7 @@ class PlayState extends MusicBeatState
|
|||||||
score: campaignScore,
|
score: campaignScore,
|
||||||
misses: campaignMisses,
|
misses: campaignMisses,
|
||||||
accuracy: campaignAccuracy,
|
accuracy: campaignAccuracy,
|
||||||
hits: campaignHits,
|
hits: [],
|
||||||
date: Date.now().toString()
|
date: Date.now().toString()
|
||||||
});
|
});
|
||||||
#end
|
#end
|
||||||
@@ -1833,25 +1812,11 @@ class PlayState extends MusicBeatState
|
|||||||
*/
|
*/
|
||||||
public function noteMiss(strumLine:StrumLine, note:Note, ?direction:Int, ?player:Int):Void
|
public function noteMiss(strumLine:StrumLine, note:Note, ?direction:Int, ?player:Int):Void
|
||||||
{
|
{
|
||||||
var hasNote:Bool = note != null;
|
var playerID:Null<Int> = note == null ? player : strumLines.members.indexOf(strumLine);
|
||||||
var playerID:Null<Int> = hasNote ? strumLines.members.indexOf(strumLine) : player;
|
var directionID:Null<Int> = note == null ? direction : note.strumID;
|
||||||
var directionID:Null<Int> = hasNote ? note.strumID : direction;
|
|
||||||
if (playerID == null || directionID == null || playerID == -1) return;
|
if (playerID == null || directionID == null || playerID == -1) return;
|
||||||
|
|
||||||
if (hasNote) {
|
var event:NoteMissEvent = gameAndCharsEvent("onPlayerMiss", EventManager.get(NoteMissEvent).recycle(note, -10, 1, muteVocalsOnMiss, note != null ? -0.0475 : -0.04, Paths.sound(FlxG.random.getObject(Flags.DEFAULT_MISS_SOUNDS)), FlxG.random.float(0.1, 0.2), note == null, combo > 5, "sad", true, true, "miss", strumLines.members[playerID].characters, playerID, note != null ? note.noteType : null, directionID, 0));
|
||||||
if (Flags.SUSTAINS_AS_ONE_NOTE && note.isSustainNote) {
|
|
||||||
strumLine.deleteNote(note);
|
|
||||||
if (note.sustainParent.wasGoodHit) {
|
|
||||||
note.sustainParent.wasGoodHit = false;
|
|
||||||
note.sustainParent.tooLate = true;
|
|
||||||
note = note.sustainParent;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var event:NoteMissEvent = gameAndCharsEvent("onPlayerMiss", EventManager.get(NoteMissEvent).recycle(note, -10, 1, muteVocalsOnMiss, hasNote ? ((note.isSustainNote && Flags.SUSTAINS_AS_ONE_NOTE) ? -0.1425 : -0.0475) : -0.04, Paths.sound(FlxG.random.getObject(Flags.DEFAULT_MISS_SOUNDS)), FlxG.random.float(0.1, 0.2), !hasNote, combo > 5, "sad", true, true, "miss", strumLines.members[playerID].characters, playerID, hasNote ? note.noteType : null, directionID, 0));
|
|
||||||
strumLine.onMiss.dispatch(event);
|
strumLine.onMiss.dispatch(event);
|
||||||
if (event.cancelled) {
|
if (event.cancelled) {
|
||||||
gameAndCharsEvent("onPostPlayerMiss", event);
|
gameAndCharsEvent("onPostPlayerMiss", event);
|
||||||
@@ -1890,7 +1855,7 @@ class PlayState extends MusicBeatState
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.deleteNote && strumLine != null && hasNote)
|
if (event.deleteNote && strumLine != null && note != null)
|
||||||
strumLine.deleteNote(note);
|
strumLine.deleteNote(note);
|
||||||
|
|
||||||
gameAndCharsEvent("onPostPlayerMiss", event);
|
gameAndCharsEvent("onPostPlayerMiss", event);
|
||||||
@@ -1911,49 +1876,43 @@ class PlayState extends MusicBeatState
|
|||||||
|
|
||||||
note.wasGoodHit = true;
|
note.wasGoodHit = true;
|
||||||
|
|
||||||
var noteDiff = Math.abs(Conductor.songPosition - note.strumTime), rating:Rating;
|
/**
|
||||||
if (!Flags.USE_LEGACY_TIMING) rating = ratingManager.judgeNote(noteDiff);
|
* CALCULATES RATING
|
||||||
else {
|
*/
|
||||||
(rating = _legacyRating).splash = false;
|
var noteDiff = Math.abs(Conductor.songPosition - note.strumTime);
|
||||||
if (noteDiff > hitWindow * 0.9) {
|
var daRating:String = "sick";
|
||||||
rating.window = hitWindow;
|
var score:Int = 300;
|
||||||
rating.name = "shit";
|
var accuracy:Float = 1;
|
||||||
rating.score = 50;
|
|
||||||
rating.accuracy = 0.25;
|
if (noteDiff > hitWindow * 0.9)
|
||||||
}
|
{
|
||||||
else if (noteDiff > hitWindow * 0.75) {
|
daRating = 'shit';
|
||||||
rating.window = hitWindow * 0.9;
|
score = 50;
|
||||||
rating.name = "bad";
|
accuracy = 0.25;
|
||||||
rating.score = 100;
|
}
|
||||||
rating.accuracy = 0.45;
|
else if (noteDiff > hitWindow * 0.75)
|
||||||
}
|
{
|
||||||
else if (noteDiff > hitWindow * 0.2) {
|
daRating = 'bad';
|
||||||
rating.window = hitWindow * 0.75;
|
score = 100;
|
||||||
rating.name = "good";
|
accuracy = 0.45;
|
||||||
rating.score = 200;
|
}
|
||||||
rating.accuracy = 0.75;
|
else if (noteDiff > hitWindow * 0.2)
|
||||||
}
|
{
|
||||||
else {
|
daRating = 'good';
|
||||||
rating.window = hitWindow * 0.2;
|
score = 200;
|
||||||
rating.name = "sick";
|
accuracy = 0.75;
|
||||||
rating.score = 300;
|
|
||||||
rating.accuracy = 1;
|
|
||||||
rating.splash = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var event:NoteHitEvent;
|
var event:NoteHitEvent;
|
||||||
if (strumLine != null && !strumLine.cpu)
|
if (strumLine != null && !strumLine.cpu)
|
||||||
event = EventManager.get(NoteHitEvent).recycle(false, !note.isSustainNote, !note.isSustainNote, null, defaultDisplayRating, defaultDisplayCombo, note, strumLine.characters, true, note.noteType, note.animSuffix.getDefault(note.strumID < strumLine.members.length ? strumLine.members[note.strumID].animSuffix : strumLine.animSuffix), "game/score/", "", note.strumID, rating.score, note.isSustainNote ? null : rating.accuracy, 0.023, rating.name, Options.splashesEnabled && !note.isSustainNote && rating.splash, 0.5, true, 0.7, true, true, iconP1);
|
event = EventManager.get(NoteHitEvent).recycle(false, !note.isSustainNote, !note.isSustainNote, null, defaultDisplayRating, defaultDisplayCombo, note, strumLine.characters, true, note.noteType, note.animSuffix.getDefault(note.strumID < strumLine.members.length ? strumLine.members[note.strumID].animSuffix : strumLine.animSuffix), "game/score/", "", note.strumID, score, note.isSustainNote ? null : accuracy, 0.023, daRating, Options.splashesEnabled && !note.isSustainNote && daRating == "sick", 0.5, true, 0.7, true, true, iconP1);
|
||||||
else
|
else
|
||||||
event = EventManager.get(NoteHitEvent).recycle(false, false, false, null, defaultDisplayRating, defaultDisplayCombo, note, strumLine.characters, false, note.noteType, note.animSuffix.getDefault(note.strumID < strumLine.members.length ? strumLine.members[note.strumID].animSuffix : strumLine.animSuffix), "game/score/", "", note.strumID, 0, null, 0, rating.name, false, 0.5, true, 0.7, true, true, iconP2);
|
event = EventManager.get(NoteHitEvent).recycle(false, false, false, null, defaultDisplayRating, defaultDisplayCombo, note, strumLine.characters, false, note.noteType, note.animSuffix.getDefault(note.strumID < strumLine.members.length ? strumLine.members[note.strumID].animSuffix : strumLine.animSuffix), "game/score/", "", note.strumID, 0, null, 0, daRating, false, 0.5, true, 0.7, true, true, iconP2);
|
||||||
event.deleteNote = !note.isSustainNote; // work around, to allow sustain notes to be deleted
|
event.deleteNote = !note.isSustainNote; // work around, to allow sustain notes to be deleted
|
||||||
event = scripts.event(strumLine != null && !strumLine.cpu ? "onPlayerHit" : "onDadHit", event);
|
event = scripts.event(strumLine != null && !strumLine.cpu ? "onPlayerHit" : "onDadHit", event);
|
||||||
strumLine.onHit.dispatch(event);
|
strumLine.onHit.dispatch(event);
|
||||||
gameAndCharsEvent("onNoteHit", event);
|
gameAndCharsEvent("onNoteHit", event);
|
||||||
|
|
||||||
note.noSustainClip = !event.clipSustain;
|
|
||||||
|
|
||||||
if (!event.cancelled) {
|
if (!event.cancelled) {
|
||||||
if (!note.isSustainNote) {
|
if (!note.isSustainNote) {
|
||||||
if (event.countScore) songScore += event.score;
|
if (event.countScore) songScore += event.score;
|
||||||
@@ -1971,7 +1930,6 @@ class PlayState extends MusicBeatState
|
|||||||
displayRating(event.rating, event);
|
displayRating(event.rating, event);
|
||||||
ratingNum += 1;
|
ratingNum += 1;
|
||||||
}
|
}
|
||||||
if (event.player) hits[rating.name] += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strumLine != null) strumLine.addHealth(event.healthGain);
|
if (strumLine != null) strumLine.addHealth(event.healthGain);
|
||||||
@@ -2000,7 +1958,6 @@ class PlayState extends MusicBeatState
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (event.deleteNote) strumLine.deleteNote(note);
|
if (event.deleteNote) strumLine.deleteNote(note);
|
||||||
else note.updateSustainClip();
|
|
||||||
|
|
||||||
gameAndCharsEvent("onPostNoteHit", event);
|
gameAndCharsEvent("onPostNoteHit", event);
|
||||||
}
|
}
|
||||||
@@ -2208,7 +2165,6 @@ class PlayState extends MusicBeatState
|
|||||||
campaignMisses = 0;
|
campaignMisses = 0;
|
||||||
campaignAccuracyTotal = 0;
|
campaignAccuracyTotal = 0;
|
||||||
campaignAccuracyCount = 0;
|
campaignAccuracyCount = 0;
|
||||||
campaignHits = [];
|
|
||||||
chartingMode = coopMode = opponentMode = false;
|
chartingMode = coopMode = opponentMode = false;
|
||||||
__loadSong(storyPlaylist[0], difficulty, storyVariations[0]);
|
__loadSong(storyPlaylist[0], difficulty, storyVariations[0]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ class Strum extends FlxSprite {
|
|||||||
public override function update(elapsed:Float) {
|
public override function update(elapsed:Float) {
|
||||||
super.update(elapsed);
|
super.update(elapsed);
|
||||||
if (cpu) {
|
if (cpu) {
|
||||||
if (lastHit + (Conductor.crochet * 0.5) < Conductor.songPosition && getAnim() == "confirm") {
|
if (lastHit + (Conductor.crochet / 2) < Conductor.songPosition && getAnim() == "confirm") {
|
||||||
playAnim("static");
|
playAnim("static");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,7 +133,7 @@ class Strum extends FlxSprite {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@:noCompletion public static inline final PIX180:Float = 565.4866776461628; // 180 * Math.PI
|
@:noCompletion public static inline final PIX180:Float = 565.4866776461628; // 180 * Math.PI
|
||||||
@:noCompletion public static final N_WIDTHDIV2:Float = Note.swagWidth / 2; // DEPRECATED
|
@:noCompletion public static final N_WIDTHDIV2:Float = Note.swagWidth / 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the position of a note.
|
* Updates the position of a note.
|
||||||
@@ -162,16 +162,16 @@ class Strum extends FlxSprite {
|
|||||||
|
|
||||||
if (shouldX || shouldY) {
|
if (shouldX || shouldY) {
|
||||||
if (daNote.strumRelativePos) {
|
if (daNote.strumRelativePos) {
|
||||||
if (shouldX) daNote.x = (this.width - daNote.width) * 0.5;
|
if (shouldX) daNote.x = (this.width - daNote.width) / 2;
|
||||||
if (shouldY) {
|
if (shouldY) {
|
||||||
daNote.y = (daNote.strumTime - Conductor.songPosition) * (0.45 * getScrollSpeed(daNote));
|
daNote.y = (daNote.strumTime - Conductor.songPosition) * (0.45 * CoolUtil.quantize(getScrollSpeed(daNote), 100));
|
||||||
if (daNote.isSustainNote) daNote.y += height * 0.5;
|
if (daNote.isSustainNote) daNote.y += N_WIDTHDIV2;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var offset = FlxPoint.get(0, (Conductor.songPosition - daNote.strumTime) * (0.45 * getScrollSpeed(daNote)));
|
var offset = FlxPoint.get(0, (Conductor.songPosition - daNote.strumTime) * (0.45 * CoolUtil.quantize(getScrollSpeed(daNote), 100)));
|
||||||
var realOffset = FlxPoint.get(0, 0);
|
var realOffset = FlxPoint.get(0, 0);
|
||||||
|
|
||||||
if (daNote.isSustainNote) offset.y -= height * 0.5;
|
if (daNote.isSustainNote) offset.y -= N_WIDTHDIV2;
|
||||||
|
|
||||||
if (Std.int(daNote.__noteAngle % 360) != 0) {
|
if (Std.int(daNote.__noteAngle % 360) != 0) {
|
||||||
var noteAngleCos = FlxMath.fastCos(daNote.__noteAngle / PIX180);
|
var noteAngleCos = FlxMath.fastCos(daNote.__noteAngle / PIX180);
|
||||||
@@ -257,4 +257,4 @@ class Strum extends FlxSprite {
|
|||||||
public inline function getAnim() {
|
public inline function getAnim() {
|
||||||
return animation.name;
|
return animation.name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,9 +161,6 @@ class StrumLine extends FlxTypedGroup<Strum> {
|
|||||||
curLen = Math.min(len, Conductor.stepCrochet);
|
curLen = Math.min(len, Conductor.stepCrochet);
|
||||||
notes.members[total-(il++)-1] = prev = new Note(this, note, true, curLen, note.sLen - len, prev);
|
notes.members[total-(il++)-1] = prev = new Note(this, note, true, curLen, note.sLen - len, prev);
|
||||||
len -= curLen;
|
len -= curLen;
|
||||||
|
|
||||||
if (prev != null && prev.sustainParent != null)
|
|
||||||
prev.sustainParent.tailCount++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,7 +213,7 @@ class StrumLine extends FlxTypedGroup<Strum> {
|
|||||||
if (__updateNote_event.cancelled) return;
|
if (__updateNote_event.cancelled) return;
|
||||||
|
|
||||||
if (__updateNote_event.__updateHitWindow) {
|
if (__updateNote_event.__updateHitWindow) {
|
||||||
var hitWindow = Flags.USE_LEGACY_TIMING ? PlayState.instance.hitWindow : PlayState.instance.ratingManager.lastHitWindow;
|
var hitWindow = PlayState.instance.hitWindow;
|
||||||
daNote.canBeHit = (daNote.strumTime > __updateNote_songPos - (hitWindow * daNote.latePressWindow)
|
daNote.canBeHit = (daNote.strumTime > __updateNote_songPos - (hitWindow * daNote.latePressWindow)
|
||||||
&& daNote.strumTime < __updateNote_songPos + (hitWindow * daNote.earlyPressWindow));
|
&& daNote.strumTime < __updateNote_songPos + (hitWindow * daNote.earlyPressWindow));
|
||||||
|
|
||||||
@@ -224,10 +221,9 @@ class StrumLine extends FlxTypedGroup<Strum> {
|
|||||||
daNote.tooLate = true;
|
daNote.tooLate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cpu && __updateNote_event.__autoCPUHit && !daNote.avoid && !daNote.wasGoodHit && daNote.strumTime < __updateNote_songPos)
|
if (cpu && __updateNote_event.__autoCPUHit && !daNote.avoid && !daNote.wasGoodHit && daNote.strumTime < __updateNote_songPos) PlayState.instance.goodNoteHit(this, daNote);
|
||||||
PlayState.instance.goodNoteHit(this, daNote);
|
|
||||||
|
|
||||||
if (daNote.wasGoodHit && daNote.isSustainNote && daNote.strumTime + daNote.sustainLength < __updateNote_songPos && !daNote.noSustainClip) {
|
if (daNote.wasGoodHit && daNote.isSustainNote && daNote.strumTime + daNote.sustainLength < __updateNote_songPos) {
|
||||||
deleteNote(daNote);
|
deleteNote(daNote);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -240,38 +236,29 @@ class StrumLine extends FlxTypedGroup<Strum> {
|
|||||||
|
|
||||||
|
|
||||||
if (__updateNote_event.strum == null) return;
|
if (__updateNote_event.strum == null) return;
|
||||||
if (__updateNote_event.__reposNote) __updateNote_event.strum.updateNotePosition(daNote);
|
|
||||||
|
|
||||||
if (daNote.isSustainNote) {
|
if (__updateNote_event.__reposNote) __updateNote_event.strum.updateNotePosition(daNote);
|
||||||
|
if (daNote.isSustainNote)
|
||||||
daNote.updateSustain(__updateNote_event.strum);
|
daNote.updateSustain(__updateNote_event.strum);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var __funcsToExec:Array<Note->Void> = [];
|
||||||
var __pressed:Array<Bool> = [];
|
var __pressed:Array<Bool> = [];
|
||||||
var __justPressed:Array<Bool> = [];
|
var __justPressed:Array<Bool> = [];
|
||||||
var __justReleased:Array<Bool> = [];
|
var __justReleased:Array<Bool> = [];
|
||||||
var __notePerStrum:Array<Note> = [];
|
var __notePerStrum:Array<Note> = [];
|
||||||
|
|
||||||
function __inputProcessPressed(note:Note) {
|
function __inputProcessPressed(note:Note) {
|
||||||
if (__pressed[note.strumID] && note.isSustainNote && note.strumTime < __updateNote_songPos && !note.wasGoodHit && note.sustainParent.wasGoodHit) {
|
if (__pressed[note.strumID] && note.isSustainNote && note.strumTime < __updateNote_songPos && !note.wasGoodHit) {
|
||||||
PlayState.instance.goodNoteHit(this, note);
|
PlayState.instance.goodNoteHit(this, note);
|
||||||
|
note.updateSustainClip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function __inputProcessJustPressed(note:Note) {
|
function __inputProcessJustPressed(note:Note) {
|
||||||
if (__justPressed[note.strumID] && !note.isSustainNote && !note.wasGoodHit && note.canBeHit) {
|
if (__justPressed[note.strumID] && !note.isSustainNote && !note.wasGoodHit && note.canBeHit) {
|
||||||
var cur = __notePerStrum[note.strumID];
|
if (__notePerStrum[note.strumID] == null) __notePerStrum[note.strumID] = note;
|
||||||
var songPos = __updateNote_songPos;
|
else if (Math.abs(__notePerStrum[note.strumID].strumTime - note.strumTime) <= 2) deleteNote(note);
|
||||||
|
else if (note.strumTime < __notePerStrum[note.strumID].strumTime) __notePerStrum[note.strumID] = note;
|
||||||
var noteDist = Math.abs(note.strumTime - songPos);
|
|
||||||
var curDist = cur != null ? Math.abs(cur.strumTime - songPos) : 999999;
|
|
||||||
|
|
||||||
var notePenalty = note.avoid ? 1 : 0;
|
|
||||||
var curPenalty = (cur != null && cur.avoid) ? 1 : 0;
|
|
||||||
|
|
||||||
if (cur == null
|
|
||||||
|| notePenalty < curPenalty
|
|
||||||
|| (notePenalty == curPenalty && noteDist < curDist))
|
|
||||||
__notePerStrum[note.strumID] = note;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,16 +271,15 @@ class StrumLine extends FlxTypedGroup<Strum> {
|
|||||||
|
|
||||||
if (cpu) return;
|
if (cpu) return;
|
||||||
|
|
||||||
if (__pressed.length != members.length) {
|
__funcsToExec.clear();
|
||||||
__pressed.resize(members.length);
|
__pressed.clear();
|
||||||
__justPressed.resize(members.length);
|
__justPressed.clear();
|
||||||
__justReleased.resize(members.length);
|
__justReleased.clear();
|
||||||
}
|
|
||||||
|
|
||||||
for (i in 0...members.length) {
|
for(s in members) {
|
||||||
__pressed[i] = members[i].__getPressed(this);
|
__pressed.push(s.__getPressed(this));
|
||||||
__justPressed[i] = members[i].__getJustPressed(this);
|
__justPressed.push(s.__getJustPressed(this));
|
||||||
__justReleased[i] = members[i].__getJustReleased(this);
|
__justReleased.push(s.__getJustReleased(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
var event = EventManager.get(InputSystemEvent).recycle(__pressed, __justPressed, __justReleased, this, id);
|
var event = EventManager.get(InputSystemEvent).recycle(__pressed, __justPressed, __justReleased, this, id);
|
||||||
@@ -304,31 +290,34 @@ class StrumLine extends FlxTypedGroup<Strum> {
|
|||||||
__justPressed = CoolUtil.getDefault(event.justPressed, []);
|
__justPressed = CoolUtil.getDefault(event.justPressed, []);
|
||||||
__justReleased = CoolUtil.getDefault(event.justReleased, []);
|
__justReleased = CoolUtil.getDefault(event.justReleased, []);
|
||||||
|
|
||||||
__notePerStrum = cast new haxe.ds.Vector(members.length); // [for(_ in 0...members.length) null];
|
__notePerStrum = cast new haxe.ds.Vector(members.length);//[for(_ in 0...members.length) null];
|
||||||
|
|
||||||
|
|
||||||
if (__pressed.contains(true)) {
|
if (__pressed.contains(true)) {
|
||||||
if (__justPressed.contains(true)) {
|
for(c in characters)
|
||||||
notes.forEachAlive(__inputProcessJustPressed);
|
|
||||||
|
|
||||||
if (!ghostTapping) for (k => pr in __justPressed) if (pr && __notePerStrum[k] == null)
|
|
||||||
PlayState.instance.noteMiss(this, null, k, ID); // FUCK YOU
|
|
||||||
|
|
||||||
for (e in __notePerStrum)
|
|
||||||
if (e != null)
|
|
||||||
PlayState.instance.goodNoteHit(this, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (c in characters)
|
|
||||||
if (c.lastAnimContext != DANCE)
|
if (c.lastAnimContext != DANCE)
|
||||||
c.__lockAnimThisFrame = true;
|
c.__lockAnimThisFrame = true;
|
||||||
|
|
||||||
notes.forEachAlive(__inputProcessPressed);
|
__funcsToExec.push(__inputProcessPressed);
|
||||||
|
}
|
||||||
|
if (__justPressed.contains(true))
|
||||||
|
__funcsToExec.push(__inputProcessJustPressed);
|
||||||
|
|
||||||
|
if (__funcsToExec.length > 0) {
|
||||||
|
notes.forEachAlive(function(note:Note) {
|
||||||
|
for(e in __funcsToExec) if (e != null) e(note);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
forEach(function(str:Strum) {
|
if (!ghostTapping) for(k=>pr in __justPressed) if (pr && __notePerStrum[k] == null) {
|
||||||
str.updatePlayerInput(__pressed[str.ID], __justPressed[str.ID], __justReleased[str.ID]);
|
// FUCK YOU
|
||||||
});
|
PlayState.instance.noteMiss(this, null, k, ID);
|
||||||
|
}
|
||||||
|
for(e in __notePerStrum) if (e != null) PlayState.instance.goodNoteHit(this, e);
|
||||||
|
|
||||||
|
forEach(function(str:Strum) {
|
||||||
|
str.updatePlayerInput(str.__getPressed(this), str.__getJustPressed(this), str.__getJustReleased(this));
|
||||||
|
});
|
||||||
PlayState.instance.gameAndCharsCall("onPostInputUpdate");
|
PlayState.instance.gameAndCharsCall("onPostInputUpdate");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,8 +411,6 @@ class StrumLine extends FlxTypedGroup<Strum> {
|
|||||||
var event:SimpleNoteEvent = EventManager.get(SimpleNoteEvent).recycle(note);
|
var event:SimpleNoteEvent = EventManager.get(SimpleNoteEvent).recycle(note);
|
||||||
onNoteDelete.dispatch(event);
|
onNoteDelete.dispatch(event);
|
||||||
if (!event.cancelled) {
|
if (!event.cancelled) {
|
||||||
if (note.isSustainNote && note.sustainParent != null && note.sustainParent.tailCount > 0)
|
|
||||||
note.sustainParent.tailCount--;
|
|
||||||
note.kill();
|
note.kill();
|
||||||
notes.remove(note, true);
|
notes.remove(note, true);
|
||||||
note.destroy();
|
note.destroy();
|
||||||
|
|||||||
@@ -95,20 +95,18 @@ class ScriptedCutscene extends Cutscene {
|
|||||||
script.call("stepHit", [curStep]);
|
script.call("stepHit", [curStep]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function openSubState(subState:FlxSubState)
|
public override function openSubState(sub:FlxSubState)
|
||||||
{
|
{
|
||||||
var event = EventManager.get(StateEvent).recycle(subState);
|
var event = EventManager.get(StateEvent).recycle(sub);
|
||||||
script.call(Flags.MOD_API_VERSION <= 1 ? "onSubstateClose" /*Remove this entirely*/ : "onOpenSubState", [event]);
|
script.call("onSubstateClose", [event]);
|
||||||
if (!event.cancelled)
|
if(!event.cancelled) super.openSubState(event.substate is FlxSubState ? cast event.substate : sub);
|
||||||
super.openSubState(event.substate is FlxSubState ? cast event.substate : subState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function closeSubState()
|
public override function closeSubState()
|
||||||
{
|
{
|
||||||
var event = EventManager.get(StateEvent).recycle(subState);
|
var event = EventManager.get(StateEvent).recycle(subState);
|
||||||
script.call(Flags.MOD_API_VERSION <= 1 ? "onSubstateOpen" /*Remove this entirely*/ : "onCloseSubState", [event]);
|
script.call("onSubstateOpen", [event]);
|
||||||
if (!event.cancelled)
|
if(!event.cancelled) super.closeSubState();
|
||||||
super.closeSubState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function destroy() {
|
public override function destroy() {
|
||||||
|
|||||||
@@ -60,9 +60,7 @@ class VideoCutscene extends Cutscene {
|
|||||||
|
|
||||||
add(video = new FlxVideoSprite());
|
add(video = new FlxVideoSprite());
|
||||||
video.antialiasing = true;
|
video.antialiasing = true;
|
||||||
#if (hxvlc < version("2.0.0"))
|
|
||||||
video.autoPause = false; // Imma handle it better inside this class, mainly because of the pause menu - Nex
|
video.autoPause = false; // Imma handle it better inside this class, mainly because of the pause menu - Nex
|
||||||
#end
|
|
||||||
video.bitmap.onEndReached.add(close);
|
video.bitmap.onEndReached.add(close);
|
||||||
video.bitmap.onFormatSetup.add(function() if (video.bitmap != null && video.bitmap.bitmapData != null) {
|
video.bitmap.onFormatSetup.add(function() if (video.bitmap != null && video.bitmap.bitmapData != null) {
|
||||||
final width = video.bitmap.bitmapData.width;
|
final width = video.bitmap.bitmapData.width;
|
||||||
@@ -207,7 +205,6 @@ class VideoCutscene extends Cutscene {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (hxvlc < version("2.0.0"))
|
|
||||||
@:dox(hide) override public function onFocus() {
|
@:dox(hide) override public function onFocus() {
|
||||||
if(FlxG.autoPause && !paused) video.resume();
|
if(FlxG.autoPause && !paused) video.resume();
|
||||||
super.onFocus();
|
super.onFocus();
|
||||||
@@ -217,7 +214,6 @@ class VideoCutscene extends Cutscene {
|
|||||||
if(FlxG.autoPause && !paused) video.pause();
|
if(FlxG.autoPause && !paused) video.pause();
|
||||||
super.onFocusLost();
|
super.onFocusLost();
|
||||||
}
|
}
|
||||||
#end
|
|
||||||
|
|
||||||
public override function pauseCutscene() {
|
public override function pauseCutscene() {
|
||||||
video.pause();
|
video.pause();
|
||||||
|
|||||||
@@ -1,76 +0,0 @@
|
|||||||
package funkin.game.scoring;
|
|
||||||
|
|
||||||
import haxe.ds.StringMap;
|
|
||||||
|
|
||||||
class HitWindowData
|
|
||||||
{
|
|
||||||
public static function getWindows(preset:WindowPreset):StringMap<Float>
|
|
||||||
{
|
|
||||||
var map = new StringMap<Float>();
|
|
||||||
|
|
||||||
switch (preset) {
|
|
||||||
// Old Codename, really forgiving inputs (hard to get bad ratings)
|
|
||||||
case CNE_CLASSIC:
|
|
||||||
map.set("sick", 50.0);
|
|
||||||
map.set("good", 187.5);
|
|
||||||
map.set("bad", 225.0);
|
|
||||||
map.set("shit", 250.0);
|
|
||||||
// Week 7
|
|
||||||
case FNF_CLASSIC:
|
|
||||||
map.set("sick", 33.334);
|
|
||||||
map.set("good", 125.0025);
|
|
||||||
map.set("bad", 150.003);
|
|
||||||
map.set("shit", 166.67);
|
|
||||||
// V-Slice
|
|
||||||
case FNF_VSLICE:
|
|
||||||
map.set("sick", 45.0);
|
|
||||||
map.set("good", 90.0);
|
|
||||||
map.set("bad", 135.4);
|
|
||||||
map.set("shit", 180.0);
|
|
||||||
// Default, taken from Etterna
|
|
||||||
case _:
|
|
||||||
map.set("sick", 37.8);
|
|
||||||
map.set("good", 75.6);
|
|
||||||
map.set("bad", 113.4);
|
|
||||||
map.set("shit", 180.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static var JUDGE_SCALES:Array<Float> = [1.5, 1.33, 1.16, 1.0, 0.84, 0.66, 0.5, 0.33, 0.2];
|
|
||||||
public static function scaleWindows(windows:StringMap<Float>, scale:Float):StringMap<Float>
|
|
||||||
{
|
|
||||||
var scaled = new StringMap<Float>();
|
|
||||||
for (k in windows.keys())
|
|
||||||
scaled.set(k, windows.get(k) * scale);
|
|
||||||
return scaled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function offsetWindows(windows:StringMap<Float>, offset:Float):StringMap<Float>
|
|
||||||
{
|
|
||||||
var adjusted = new StringMap<Float>();
|
|
||||||
for (k in windows.keys())
|
|
||||||
adjusted.set(k, windows.get(k) + offset);
|
|
||||||
return adjusted;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum abstract WindowPreset(Int) from Int to Int
|
|
||||||
{
|
|
||||||
var DEFAULT = 0;
|
|
||||||
var CNE_CLASSIC = 1;
|
|
||||||
var FNF_CLASSIC = 2;
|
|
||||||
var FNF_VSLICE = 3;
|
|
||||||
|
|
||||||
public function toString():String
|
|
||||||
{
|
|
||||||
return switch (cast this : WindowPreset)
|
|
||||||
{
|
|
||||||
case CNE_CLASSIC: "Codename (Classic)";
|
|
||||||
case FNF_CLASSIC: "Funkin' (Week 7)";
|
|
||||||
case FNF_VSLICE: "Funkin' (V-Slice)";
|
|
||||||
case _: "Default";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
package funkin.game.scoring;
|
|
||||||
|
|
||||||
import funkin.game.scoring.*;
|
|
||||||
import funkin.game.scoring.HitWindowData.WindowPreset;
|
|
||||||
|
|
||||||
import haxe.ds.StringMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Judges note hits and returns a rating.
|
|
||||||
*/
|
|
||||||
class RatingManager
|
|
||||||
{
|
|
||||||
public var hitWindows:StringMap<Float>;
|
|
||||||
public var ratingData:Array<Rating> = [];
|
|
||||||
public var lastHitWindow:Float = -1;
|
|
||||||
|
|
||||||
public function new(?preset:WindowPreset):Void
|
|
||||||
{
|
|
||||||
var usedPreset = preset != null ? preset : WindowPreset.DEFAULT;
|
|
||||||
hitWindows = HitWindowData.getWindows(usedPreset);
|
|
||||||
initDefaultData(hitWindows);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a rating based on a wimdow of time.
|
|
||||||
* @param time The timing window to judge.
|
|
||||||
*/
|
|
||||||
public function judgeNote(time:Float):Rating
|
|
||||||
{
|
|
||||||
for (i => rating in ratingData)
|
|
||||||
{
|
|
||||||
if (rating.hittable && rating.window > -1 && time <= rating.window)
|
|
||||||
{
|
|
||||||
return rating;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ratingData.last();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the default rating data containing the four judgements.
|
|
||||||
*
|
|
||||||
* "Sick", "Good", "Bad", "Shit"
|
|
||||||
*/
|
|
||||||
public function initDefaultData(windows:StringMap<Float>)
|
|
||||||
{
|
|
||||||
inline function getWindow(name:String):Float
|
|
||||||
{
|
|
||||||
return windows.exists(name) ? windows.get(name) : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
addRating({name: "sick", window: getWindow("sick"), accuracy: 1, score: 300, splash: true});
|
|
||||||
addRating({name: "good", window: getWindow("good"), accuracy: 0.75, score: 200});
|
|
||||||
addRating({name: "bad", window: getWindow("bad"), accuracy: 0.45, score: 100});
|
|
||||||
addRating({name: "shit", window: getWindow("shit"), accuracy: 0.25, score: 50});
|
|
||||||
}
|
|
||||||
|
|
||||||
public function addRating(data:Dynamic)
|
|
||||||
{
|
|
||||||
if (data == null || data.name == null) return;
|
|
||||||
|
|
||||||
var name = data.name.toLowerCase();
|
|
||||||
var window = data.window != null
|
|
||||||
? data.window
|
|
||||||
: (hitWindows.exists(name) ? hitWindows.get(name) : -1);
|
|
||||||
|
|
||||||
if (window > lastHitWindow) lastHitWindow = window;
|
|
||||||
|
|
||||||
var newRating:Rating = {
|
|
||||||
name: name,
|
|
||||||
window: window,
|
|
||||||
accuracy: data.accuracy != null ? data.accuracy : 1,
|
|
||||||
score: data.score != null ? data.score : 0,
|
|
||||||
splash: data.splash == true,
|
|
||||||
hittable: data.hittable != null ? data.hittable : true
|
|
||||||
};
|
|
||||||
|
|
||||||
var existingIndex = -1;
|
|
||||||
for (i in 0...ratingData.length)
|
|
||||||
if (ratingData[i].name == name)
|
|
||||||
existingIndex = i;
|
|
||||||
|
|
||||||
if (existingIndex >= 0)
|
|
||||||
ratingData[existingIndex] = newRating;
|
|
||||||
else
|
|
||||||
ratingData.push(newRating);
|
|
||||||
|
|
||||||
ratingData.sort((a, b) -> Reflect.compare(a.window, b.window));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeRating(name:String):Void
|
|
||||||
{
|
|
||||||
if (name == null) return;
|
|
||||||
name = name.toLowerCase();
|
|
||||||
ratingData = ratingData.filter(r -> r.name != name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getHitWindow(name:String):Float
|
|
||||||
{
|
|
||||||
return hitWindows.exists(name) ? hitWindows.get(name) : -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@:structInit
|
|
||||||
final class Rating
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Name of rating.
|
|
||||||
*
|
|
||||||
* Also used for the image file name of the rating.
|
|
||||||
*/
|
|
||||||
public var name:String = "unknown";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Amount of accuracy given when earning this rating.
|
|
||||||
*/
|
|
||||||
public var accuracy:Float = 0.0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MS Timing Window to hit the rating.
|
|
||||||
*/
|
|
||||||
public var window:Float = -1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Amount of score given when earning this rating.
|
|
||||||
*/
|
|
||||||
public var score:Int = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If this rating was hit, a note splash will appear.
|
|
||||||
*/
|
|
||||||
@:optional public var splash:Bool = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the rating is hittable or not.
|
|
||||||
*/
|
|
||||||
@:optional public var hittable:Bool = true;
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user