Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a61abcde2d | ||
|
|
a93a74aede | ||
|
|
9207e46105 | ||
|
|
d113fc40cb | ||
|
|
45a2f28cf6 | ||
|
|
45d47677ac | ||
|
|
a485080c27 | ||
|
|
cb4ecc521f | ||
|
|
0e269ddfc7 | ||
|
|
80ca43b46e | ||
|
|
8f0583958d | ||
|
|
f82c8d7fb7 | ||
|
|
2a413071cd | ||
|
|
3fa3fbda14 | ||
|
|
cd7c9f1afc | ||
|
|
e458e868a4 | ||
|
|
6f8f43d3dc | ||
|
|
a8a5ae7a89 | ||
|
|
e0b5369eb5 | ||
|
|
d874ea0348 | ||
|
|
d80b7b95cf | ||
|
|
270ed6b9b5 | ||
|
|
39968efb19 | ||
|
|
64ea9db1c1 | ||
|
|
5957a55b96 | ||
|
|
3266e22562 | ||
|
|
a7b040152d | ||
|
|
a951e38dbb | ||
|
|
4fe3ba76e3 | ||
|
|
f44d0192af | ||
|
|
f8a06bf94c | ||
|
|
ec2a39995b | ||
|
|
3c15805c80 | ||
|
|
221d9dba1d | ||
|
|
d87ac417f7 | ||
|
|
3e084397a8 | ||
|
|
370d5ede81 | ||
|
|
d7dbe5038d | ||
|
|
6c25431c75 | ||
|
|
37eb193e53 | ||
|
|
0eeef88ac7 | ||
|
|
47a3526178 | ||
|
|
bbb16f4c5c | ||
|
|
5115067b49 | ||
|
|
4d84e65cb5 | ||
|
|
f8f9d6eb4a | ||
|
|
6d3243b256 | ||
|
|
0cfb3e52c5 | ||
|
|
9d9640071c | ||
|
|
8fc1493759 | ||
|
|
69d82f560d | ||
|
|
ccc509ac9f | ||
|
|
ce8e91b361 | ||
|
|
5ac7408af6 | ||
|
|
421ed4ca09 | ||
|
|
bfe152dd8f | ||
|
|
d318ccaca8 | ||
|
|
a87dff7240 | ||
|
|
8873d63067 | ||
|
|
2913d7eea7 | ||
|
|
a89f3509e3 | ||
|
|
cde7d46572 | ||
|
|
d504aa3c35 | ||
|
|
8b449e590f | ||
|
|
e6f1fed96e | ||
|
|
e585de7db5 | ||
|
|
219e95117b | ||
|
|
06e8ba8c18 | ||
|
|
34639d729d | ||
|
|
abf77f72f2 | ||
|
|
4a99e7eda7 | ||
|
|
8bab844e0c | ||
|
|
fb90e2dd96 | ||
|
|
7dcbbc3c64 | ||
|
|
9bd9490c49 | ||
|
|
1b403b2ab2 | ||
|
|
162f1add75 | ||
|
|
6951ac82cd | ||
|
|
56f53c73a9 | ||
|
|
87b825b046 | ||
|
|
cd631c6eda | ||
|
|
eccaa77f0e | ||
|
|
a24de64707 | ||
|
|
7d186d2203 | ||
|
|
86b3fb3ad9 | ||
|
|
82fb0bcf88 | ||
|
|
e6bcb144d9 | ||
|
|
44d134eed0 | ||
|
|
846f2deedb | ||
|
|
deef60b231 | ||
|
|
1d2a391a90 | ||
|
|
e9bd5a52ac | ||
|
|
74343852cf | ||
|
|
fa094580cd | ||
|
|
8cadcd78f6 | ||
|
|
d0bffe825a | ||
|
|
be27447de9 | ||
|
|
a8808be29e | ||
|
|
53aa9cc2e7 | ||
|
|
b7dfce0f70 | ||
|
|
b1de3b1896 | ||
|
|
cdb751e6e1 | ||
|
|
5eddbc59d3 | ||
|
|
15496de225 | ||
|
|
7fc047615f | ||
|
|
535e702bc2 | ||
|
|
31a01bea97 | ||
|
|
5b2a86aace | ||
|
|
43d599acfd | ||
|
|
38c9836dc3 | ||
|
|
a73a51eef3 | ||
|
|
36640c1a43 | ||
|
|
3720bc149c | ||
|
|
8f09809e69 | ||
|
|
5d8a9c71a2 | ||
|
|
bbe3464085 | ||
|
|
3a88e78cec | ||
|
|
4d73ec3477 | ||
|
|
4d8e99f630 | ||
|
|
323c51e42c | ||
|
|
c13a0a2afd | ||
|
|
eecfb619b7 | ||
|
|
c14207236f | ||
|
|
8938665acb | ||
|
|
8369e8fcab | ||
|
|
a465a97c32 | ||
|
|
8506619465 | ||
|
|
3469524d8c | ||
|
|
90e0e5618d | ||
|
|
7a9edf809c | ||
|
|
7719fd6a10 | ||
|
|
95b4d888f0 | ||
|
|
f5dde710e3 | ||
|
|
3220a2e360 | ||
|
|
86839ac6b3 | ||
|
|
dba8200854 | ||
|
|
a296b33c0f | ||
|
|
a3498ce32b | ||
|
|
d358724fd2 | ||
|
|
4ffd164fd2 | ||
|
|
b87c206d45 | ||
|
|
0f8354415e | ||
|
|
0251fe87bb | ||
|
|
b7c932f9a9 | ||
|
|
11b86c389c | ||
|
|
2b66d74b01 | ||
|
|
3b8859120f | ||
|
|
bacd218e0b | ||
|
|
b2049e6285 | ||
|
|
6612fa6205 | ||
|
|
5d63442626 | ||
|
|
2b77d2820c | ||
|
|
071f651d0b | ||
|
|
079fda42fb | ||
|
|
96aac150f0 | ||
|
|
fa135df33d | ||
|
|
ed8a9c6390 | ||
|
|
282fa0376d | ||
|
|
3dbb22667b | ||
|
|
9a2751733e | ||
|
|
734b13904e | ||
|
|
0803e82e58 | ||
|
|
2d6b85365b | ||
|
|
356607f53a | ||
|
|
f9402fe826 | ||
|
|
be1657884e | ||
|
|
e862d72d71 | ||
|
|
43e6aac281 | ||
|
|
157e209f31 | ||
|
|
b8fef83ef1 | ||
|
|
283929b1a2 | ||
|
|
000546e9ff | ||
|
|
7df13ec012 | ||
|
|
68a5dd2482 | ||
|
|
4f834169f3 | ||
|
|
689eda7114 |
@@ -33,4 +33,11 @@ f8b20774e3f035eeddb9211a28a391b20db74456
|
||||
|
||||
# Revert a revert (empty script)
|
||||
392416e00cbd82e1c49e82a9fafdcf2e069a654e
|
||||
159467de832a172681200c463d244a46e295c3c8
|
||||
159467de832a172681200c463d244a46e295c3c8
|
||||
|
||||
# Revert a revert (scripted cutscene path)
|
||||
d73f86d26ec2dbf031c01f588ba4be11842db09c
|
||||
fe0ab0aa454f4ae12ced9502db8a01e7bca3e04c
|
||||
|
||||
# Forgot the # in the commit message
|
||||
484bbcb22aa8f28b62912abb6d8c89fb58e63889
|
||||
@@ -1,79 +0,0 @@
|
||||
|
||||
name: Linux Build
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
build:
|
||||
name: Linux Build
|
||||
permissions: write-all
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Pulling the source
|
||||
uses: actions/checkout@v2
|
||||
- name: Setting up Haxe
|
||||
uses: krdlab/setup-haxe@v1
|
||||
with:
|
||||
haxe-version: 4.2.5
|
||||
- name: Restore existing build cache for faster compilation
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
# not caching the bin folder to prevent asset duplication and stuff like that
|
||||
key: cache-build-linux
|
||||
path: |
|
||||
.haxelib/
|
||||
export/release/linux/haxe/
|
||||
export/release/linux/obj/
|
||||
restore-keys: |
|
||||
cache-build-linux
|
||||
- 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
|
||||
# - name: Tar files
|
||||
# run: tar -zcvf CodenameEngine.tar.gz -C export/release/linux/bin .
|
||||
- name: Uploading artifact (executable)
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Codename Engine (Executable Only)
|
||||
path: export/release/linux/bin/CodenameEngine
|
||||
- name: Uploading artifact (entire build)
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Codename Engine
|
||||
path: export/release/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") {
|
||||
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@v3
|
||||
with:
|
||||
# caching again since for some reason it doesnt work with the first post cache shit
|
||||
key: cache-build-linux
|
||||
path: |
|
||||
.haxelib/
|
||||
export/release/linux/haxe/
|
||||
export/release/linux/obj/
|
||||
restore-keys: |
|
||||
cache-build-linux
|
||||
@@ -1,76 +0,0 @@
|
||||
|
||||
name: Mac OS Build
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
build:
|
||||
name: Mac OS Build
|
||||
permissions: write-all
|
||||
runs-on: macos-13
|
||||
steps:
|
||||
- name: Pulling the new commit
|
||||
uses: actions/checkout@v2
|
||||
- name: Setting up Haxe
|
||||
uses: krdlab/setup-haxe@v1
|
||||
with:
|
||||
haxe-version: 4.2.5
|
||||
- name: Restore existing build cache for faster compilation
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
# not caching the bin folder to prevent asset duplication and stuff like that
|
||||
key: cache-build-mac
|
||||
path: |
|
||||
.haxelib/
|
||||
export/release/macos/haxe/
|
||||
export/release/macos/obj/
|
||||
restore-keys: |
|
||||
cache-build-mac
|
||||
- name: Installing/Updating libraries
|
||||
run: |
|
||||
haxe -cp commandline -D analyzer-optimize --run Main setup -s
|
||||
- name: Building the game
|
||||
run: |
|
||||
haxelib run lime build mac
|
||||
- name: Tar files
|
||||
run: tar -zcvf CodenameEngine.tar.gz -C export/release/macos/bin .
|
||||
- name: Uploading artifact (executable)
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Codename Engine (Executable Only)
|
||||
path: export/release/macos/bin/CodenameEngine.app/Contents/MacOS/CodenameEngine
|
||||
- name: Uploading artifact (entire build)
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Codename Engine
|
||||
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") {
|
||||
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@v3
|
||||
with:
|
||||
# caching again since for some reason it doesnt work with the first post cache shit
|
||||
key: cache-build-mac
|
||||
path: |
|
||||
.haxelib/
|
||||
export/release/macos/haxe/
|
||||
export/release/macos/obj/
|
||||
restore-keys: |
|
||||
cache-build-mac
|
||||
@@ -1,74 +0,0 @@
|
||||
|
||||
name: Windows Build
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
build:
|
||||
name: Windows Build
|
||||
permissions: write-all
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Pulling the new commit
|
||||
uses: actions/checkout@v2
|
||||
- name: Setting up Haxe
|
||||
uses: krdlab/setup-haxe@v1
|
||||
with:
|
||||
haxe-version: 4.2.5
|
||||
- name: Restore existing build cache for faster compilation
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
# not caching the bin folder to prevent asset duplication and stuff like that
|
||||
key: cache-build-windows
|
||||
path: |
|
||||
.haxelib/
|
||||
export/release/windows/haxe/
|
||||
export/release/windows/obj/
|
||||
restore-keys: |
|
||||
cache-build-windows
|
||||
- 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
|
||||
- name: Uploading artifact (executable)
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Codename Engine (Executable Only)
|
||||
path: export/release/windows/bin/CodenameEngine.exe
|
||||
- name: Uploading artifact (entire build)
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Codename Engine
|
||||
path: export/release/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") {
|
||||
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@v3
|
||||
with:
|
||||
# caching again since for some reason it doesnt work with the first post cache shit
|
||||
key: cache-build-windows
|
||||
path: |
|
||||
.haxelib/
|
||||
export/release/windows/haxe/
|
||||
export/release/windows/obj/
|
||||
restore-keys: |
|
||||
cache-build-windows
|
||||
@@ -26,6 +26,7 @@ This changelog lists every change that has been added since the last update (inc
|
||||
- `--fast` for quickly downloading git libraries, but requires you to reinstall it fully when updates happen
|
||||
- Alphabet now allows multiple lines in the text ([d519db0](https://github.com/CodenameCrew/CodenameEngine/commit/d519db011a14aac0ddfc052089836c6b445f7f44))
|
||||
- Allow importing mod root level modules in hscript, instead of only source/ ([7e66ee8](https://github.com/CodenameCrew/CodenameEngine/commit/7e66ee81e24204cd152de20046fa1500bb9d204b))
|
||||
- Made the substate have the possibility to open automatically transitions ([d31454c](https://github.com/CodenameCrew/CodenameEngine/commit/d31454c7ddf4cbf6a681cc8b32cd3f9480f8eacd))
|
||||
- Added a way to force animations in the `Play Animation` event ([d7b6fbe](https://github.com/CodenameCrew/CodenameEngine/commit/d7b6fbe510edeb832112ab5adc8ab19dfe97d77f))
|
||||
- Adde unused boyfriend animations ([be55696](https://github.com/CodenameCrew/CodenameEngine/commit/be55696bbefe537f06ad6550b039278ffcbcfb2f))
|
||||
- Made it display the keybind for the mod menu in main menu ([1ac2e7f](https://github.com/CodenameCrew/CodenameEngine/commit/1ac2e7f53390a9e92aa2a1fea94d147ed50d3694))
|
||||
@@ -197,9 +198,4 @@ This changelog lists every change that has been added since the last update (inc
|
||||
- Cleaned up the controls code ([c3580cf](https://github.com/CodenameCrew/CodenameEngine/commit/c3580cf1413f90386dd52763042e11b20d21ce2d), [c1123b9](https://github.com/CodenameCrew/CodenameEngine/commit/c1123b9e3c3c1887888744e0c62827231abc48be))
|
||||
- Cleaned up unused variables in TitleState ([2779ef3](https://github.com/CodenameCrew/CodenameEngine/commit/2779ef3314471558e371b3ec2f17f8d4df48943a))
|
||||
- Restructured the events folder ([77b7eeb](https://github.com/CodenameCrew/CodenameEngine/commit/77b7eebed1ea077516ff884902528c0ff3d01872))
|
||||
- Reduced the amount of data thats stored for the Github Contributors savefile ([2abc45a](https://github.com/CodenameCrew/CodenameEngine/commit/2abc45a9e416a1c5dd2bd0a5297c664e60c6f1d8))
|
||||
|
||||
|
||||
## Unsorted list
|
||||
|
||||
- @NexIsDumb Please document this i still dont understand it ([d31454c](https://github.com/CodenameCrew/CodenameEngine/commit/d31454c7ddf4cbf6a681cc8b32cd3f9480f8eacd))
|
||||
- Reduced the amount of data thats stored for the Github Contributors savefile ([2abc45a](https://github.com/CodenameCrew/CodenameEngine/commit/2abc45a9e416a1c5dd2bd0a5297c664e60c6f1d8))
|
||||
@@ -1,5 +1,5 @@
|
||||
# Codename Engine features
|
||||
This markdown file contains every single feature Codename has, separated into multiple categories. List may be incomplete.
|
||||
This markdown file contains most of the main features Codename has, separated into multiple categories.
|
||||
|
||||
_**QOL = Quality of Life**_
|
||||
|
||||
@@ -73,7 +73,7 @@ _**QOL = Quality of Life**_
|
||||
- If you need to rearrange the weeks in-game, you can use the `data/weeks/weeks.txt` file.
|
||||
- Editors for Charts and Characters (Stage coming soon)
|
||||
- Undos/Redos supported
|
||||
- Warning on closing unsaved work
|
||||
- Warning on closing unsaved work.
|
||||
- Clean UI (for ocd freaks)
|
||||
- Mature Chart editor (Character editor rework soon)
|
||||
- Features not found in other editors!
|
||||
|
||||
@@ -1,91 +1,104 @@
|
||||
# Friday Night Funkin' - Codename Engine (WIP)
|
||||
# Friday Night Funkin' - Codename Engine
|
||||
|
||||
## PLEASE NOTE - THIS IS STILL IN A BETA STATE
|
||||
### Mods created with beta versions of Codename may not be compatible with the release version
|
||||
Known issues in the beta:
|
||||
- Some options are missing
|
||||

|
||||
|
||||
Build instructions are below. Press TAB on the main menu to switch mods.
|
||||
Codename Engine is a cross platform [Friday Night Funkin'](https://github.com/FunkinCrew/Funkin) Engine aimed at simplifying modding focusing on softcoding, along with extensiblity and ease of use.<br>
|
||||
It is the the official successor of the previously well known [Yoshi Engine](https://github.com/CodenameCrew/YoshiCrafterEngine).
|
||||
|
||||
Also, the command `.\cne test` uses the source assets folder instead of the export one for easier development (Although you can still use `lime test windows` normally).
|
||||
The engine uses [HaxeFlixel](https://haxeflixel.com/) and it mainly features:
|
||||
- A full scripting system with an optimized fork of [Hscript](https://lib.haxe.org/p/hscript/) (its name is [Hscript Improved](https://github.com/CodenameCrew/hscript-improved))
|
||||
- Uses forks of popular libraries tailored specifically for the engine for the goal of better optimization.
|
||||
- Modding system and softcoding is as capable as source coding.
|
||||
- Focuses heavily on optimization, and encourages its users to also take on optimization practices.
|
||||
- Many modding tools without changing the core gameplay and the base to mod on.
|
||||
- Allows modularity using addons and mods that apply on top of the core mod.
|
||||
- Advanced editors which allows for possibly better experience and easiness when creating the mod.
|
||||
- Much more can be read [HERE](FEATURES.md)
|
||||
|
||||
## Codename Engine
|
||||
> [!NOTE]
|
||||
> Please keep in mind that, despite these differences, we do not consider our engine to be any better or worse than the others.
|
||||
|
||||
Codename Engine is a new Friday Night Funkin' Engine aimed at simplifying modding, along with extensiblity and ease of use.<br>
|
||||
### Before making issues or need help with something, check our website [HERE](https://codename-engine.com/) (it contains a wiki of how to mod with EXAMPLES, an api, lists of mods made with Codename Engine and more)!!!
|
||||
#### The Engine includes many new features, as seen [here](FEATURES.md)<br>
|
||||
#### Wanna see the new features added in the most recent update? Click [here](PATCHNOTES.md)<br>
|
||||
---
|
||||
|
||||
## How to download
|
||||
> [!CAUTION]
|
||||
> Want to use this project's code for different purposes or something similar? Check out the ***Usage Info*** part below first, it basically explains what you can do or not do!<br>
|
||||
> We love open source but we also love proper credits for having respect of all the people who worked hard on this project!!
|
||||
|
||||
Latest builds for the engine can be found in the [Actions](https://github.com/CodenameCrew/CodenameEngine/actions) tab.<br>
|
||||
In the future (when the engine won't be a WIP anymore) we're gonna also publish the engine on platforms like Gamebanana; stay tuned!
|
||||
> [!WARNING]
|
||||
> Before making issues or if you need help with something, check our website [HERE](https://codename-engine.com/).<br>
|
||||
> It contains a wiki of how to mod with EXAMPLES, an api, lists of mods made with Codename Engine and more!
|
||||
|
||||
If you don't have a github account please go onto https://codename-engine.com/ and click the download button for the respective operating system.
|
||||
> [!TIP]
|
||||
> Want to stay updated with this project?<br>
|
||||
> Check out our [patch notes](PATCHNOTES.md)!
|
||||
|
||||
---
|
||||
|
||||
<img width="1080" height="146" alt="immagine" src="https://github.com/user-attachments/assets/93604082-6bac-4ffc-99b0-5393b1e340a4" />
|
||||
|
||||
<br><br>
|
||||
|
||||
<img width="1280" height="720" alt="immagine" src="https://github.com/user-attachments/assets/4106f77a-40f8-4159-9f4e-b601cc79e1d0" />
|
||||
<img width="1280" height="720" alt="immagine" src="https://github.com/user-attachments/assets/2c06f5ea-3462-459b-982e-bf4eddf3d099" />
|
||||
<img width="1280" height="720" alt="immagine" src="https://github.com/user-attachments/assets/4979e256-6b99-4857-8a2a-96abd94f9c4e" />
|
||||
<img width="1280" height="720" alt="immagine" src="https://github.com/user-attachments/assets/55a5a710-55b9-4988-bdcc-0977ba1de97a" />
|
||||
<img width="1280" height="720" alt="immagine" src="https://github.com/user-attachments/assets/4676b035-bec7-445b-a303-78e66f11c479" />
|
||||
|
||||
---
|
||||
|
||||
> [!NOTE]
|
||||
> Codename Engine as for now supports **Windows x64**, **Mac OS x64** and **Linux x64**.<br>
|
||||
> More platforms will soon come, stay tuned!<br>
|
||||
> - [ ] **Web (HTML5) Support**
|
||||
> - [ ] **Mobile Support**
|
||||
|
||||
<details>
|
||||
<summary><h2>How to build</h2></summary>
|
||||
<summary><h2>How to download</h2></summary>
|
||||
|
||||
> **Open the instructions for your platform**
|
||||
<details>
|
||||
<summary>Windows</summary>
|
||||
- Stable builds of the engine can be found on our [GameBanana](https://gamebanana.com/mods/598553) or our [itch.io](https://nex-isdumb.itch.io/codename-engine) pages.
|
||||
- Latest *EXPERIMENTAL* builds of the engine can be found in the [Actions](https://github.com/CodenameCrew/CodenameEngine/actions) tab. **REQUIRES A GITHUB ACCOUNT!!**
|
||||
|
||||
##### Tested on Windows 10 21H2
|
||||
1. Install [version 4.2.5 of Haxe](https://haxe.org/download/version/4.2.5/).
|
||||
2. Download and install [`git-scm`](https://git-scm.com/download/win).
|
||||
- Leave all installation options as default.
|
||||
3. Run `update.bat` using cmd or double-clicking it, and wait for the libraries to install.
|
||||
4. Once the libraries are installed, run `haxelib run lime test windows` to compile and launch the game (may take a long time)
|
||||
- ℹ You can run `haxelib run lime setup` to make the lime command global, allowing you to execute `lime test windows` directly.
|
||||
</details>
|
||||
<details>
|
||||
<summary>Linux</summary>
|
||||
|
||||
##### Requires testing
|
||||
1. Install [version 4.2.5 of Haxe](https://haxe.org/download/version/4.2.5/).
|
||||
2. Install `g++`, if not present already.
|
||||
3. Download and install [`git-scm`](https://git-scm.com/download/linux).
|
||||
4. Open a terminal in the Codename Engine source folder, and run `update.sh`.
|
||||
5. Once the libraries are installed, run `haxelib run lime test linux` to compile and launch the game (may take a long time)
|
||||
- ℹ You can run `haxelib run lime setup` to make the lime command global, allowing you to execute `lime test linux` directly.
|
||||
</details>
|
||||
<details>
|
||||
<summary>MacOS</summary>
|
||||
|
||||
##### Requires testing
|
||||
1. Install [version 4.2.5 of Haxe](https://haxe.org/download/version/4.2.5/).
|
||||
2. Install `Xcode` to allow C++ app building.
|
||||
3. Download and install [`git-scm`](https://git-scm.com/download/mac).
|
||||
4. Open a terminal in the Codename Engine source folder, and run `update.sh`.
|
||||
5. Once the libraries are installed, run `haxelib run lime test mac` to compile and launch the game (may take a long time)
|
||||
- ℹ You can run `haxelib run lime setup` to make the lime command global, allowing you to execute `lime test mac` directly.
|
||||
</details>
|
||||
If you don't have a GitHub account to download experimental builds, you can also go onto our [official website](https://codename-engine.com/) and click the download button for the respective operating system under the **Experimental** section.
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><h2>What can you do or not do</h2></summary>
|
||||
<summary><h2>How to mod</h2></summary>
|
||||
|
||||
### You can:
|
||||
Check out our wiki [HERE](https://codename-engine.com/wiki/)
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><h2>How to setup and build the engine and its documentation</h2></summary>
|
||||
|
||||
Check out our guide [HERE](building/README.md)
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><h2>Usage Info</h2></summary>
|
||||
|
||||
### Feel free to:
|
||||
- Download and play the engine with its mods and modpacks
|
||||
- Mod and fork the engine (without using it for illicit purposes)
|
||||
- Contribute to the engine (for example through *Pull Requests*, *Issues*, etc)
|
||||
- Contribute to the engine (for example through *Pull Requests*, *Issues*, etc.)
|
||||
- Create a sub engine with Codename Engine as **TEMPLATE** with **CREDITS** (for example leaving the *credits menu submenu with the GitHub contributors* and putting the *[main devs](https://github.com/CodenameCrew)* in a *README* specifying that it's a *sub engine from Codename Engine*)
|
||||
- Release excutable mods that use Codename Engine as source (Specifing that uses Codename Engine by for example the same way written above this)
|
||||
- Release modpacks
|
||||
- Release excutable mods that use Codename Engine as source (specifing that uses Codename Engine by for example the same way written above this)
|
||||
- Release Codename Engine modpacks
|
||||
|
||||
### You can't:
|
||||
### Please do not:
|
||||
- Create a *side/new/etc* engine (or mod that doesn't use Codename Engine) using Codename Engine's code
|
||||
- Steal code from Codename Engine for another different project that is not Codename Engine related (Codename Engine mods excluded) without properly crediting
|
||||
- Release the entire Codename Engine on platforms (Mods that use Codename Engine as source are fine, if it's specified even better)
|
||||
- Release the entirety of Codename Engine on platforms (mods that use Codename Engine as source are fine)
|
||||
|
||||
#### *If you need more info or feel like asking to do something which is not listed here, ask us directly on our discord (linked on the website)!*
|
||||
#### *If you need more info or feel like asking to do something which is not listed here, ask us directly on our [discord server](https://discord.com/servers/codename-engine-860561967383445535)!*
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><h2>Credits</h2></summary>
|
||||
|
||||
- All main Credits can be seen inside the Engine and specifically [HERE](https://github.com/CodenameCrew/CodenameEngine/graphs/contributors)
|
||||
- Credits to the [FlxAnimate](https://github.com/Dot-Stuff/flxanimate) team for the Animate Atlas support
|
||||
- Credits to Smokey555 for the backup Animate Atlas to spritesheet code
|
||||
- Credits to MAJigsaw77 for [hxvlc](https://github.com/MAJigsaw77/hxvlc) (video cutscene/mp4 support) and [hxdiscord_rpc](https://github.com/MAJigsaw77/hxdiscord_rpc) (discord rpc integration)
|
||||
- Credits to [TheoDev](https://github.com/TheoDevelops) for [FunkinModchart](https://lib.haxe.org/p/funkin-modchart/). ***(library used for modcharting features)***
|
||||
- Credits to [Ninjamuffin99](https://github.com/ninjamuffin99) and the [Funkin Crew](https://github.com/FunkinCrew) for the base game Friday Night Funkin'
|
||||
</details>
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
# Codename Engine Todo List
|
||||
|
||||
## `v1.0.0` - Initial release
|
||||
|
||||
- [x] Remove Herobrine
|
||||
- [ ] Chart Editor
|
||||
- [x] Place & Delete notes
|
||||
- [x] Ctrl+Z & Ctrl+Y
|
||||
- [x] Selection box & dragging
|
||||
- [x] Scroll bar at the right + Song info
|
||||
- [x] Fix the strumlines bar when zooming out
|
||||
- [x] Algorithm to make note placements faster & sorted out
|
||||
- [x] Play here working
|
||||
- [x] Cap zoom in & out
|
||||
- [x] Events (including Camera Movement)
|
||||
- [x] Metadata Editing
|
||||
- [ ] Custom Notetypes
|
||||
- [ ] Reorderable Strumlines
|
||||
- [ ] Step based zooming
|
||||
- [ ] Add Undo to more actions
|
||||
- [ ] New Chart Button
|
||||
- [ ] Bug fixes
|
||||
- [ ] Zooming in causing notes to disappear
|
||||
- [ ] Holds disappear too early
|
||||
- [ ] Time signature fixes
|
||||
- [ ] BPM Changes Events
|
||||
- [ ] Character Editor
|
||||
- [x] Animation Editing
|
||||
- [x] Animation Deletion/Creation
|
||||
- [x] Character Info Editing
|
||||
- [x] Character Saving
|
||||
- [x] Add Undos to Actions
|
||||
- [ ] Change Stage
|
||||
- [ ] New Character Button
|
||||
- [ ] Port Videos to a more stable video lib
|
||||
- [ ] Optimization to Editors
|
||||
- [ ] Fix Ratings Lag
|
||||
- [x] Re-export gf-christmas, gf-car and gf-tankmen with padding
|
||||
- [x] Re-add shader camera stuff
|
||||
- [x] Make update.bat use libs.xml instead of hmm.json
|
||||
- [ ] New Switch Mod menu
|
||||
- [x] Port shader camera stuff over to new flixel fork
|
||||
- [ ] Add note offset
|
||||
- [x] Dialogue
|
||||
- [ ] Finish Base Game port
|
||||
- [x] Add credits
|
||||
- [x] Verbose mode (`--verbose`)
|
||||
- [ ] Tooltips
|
||||
- [ ] Fix bugs
|
||||
|
||||
## `v1.1.0`
|
||||
- [ ] Charter Waveforms (maybe in v1.1.0, don't wanna slow shit down)
|
||||
- [ ] Custom classes
|
||||
- [ ] Proper super overrides (FlxText_HSX doesn't allow overrides for update because of this)
|
||||
- [ ] Custom Class extending Custom Classes
|
||||
- [ ] Statics on Custom Classes
|
||||
- [ ] Fix Bugs
|
||||
- [ ] Full 3D support via stages files
|
||||
- [ ] Multithread sprites and assets loading (for faster load times) ?
|
||||
- [ ] Stage Editor
|
||||
- [ ] Optimize flxanimate isOnScreen
|
||||
@@ -1,10 +0,0 @@
|
||||
## DEV (PRIVATE) REPO INSTRUCTIONS TO SYNC UP WITH IT INSTEAD OF SYNCING WITH THE PUBLIC ONE
|
||||
- Open a Command Prompt window in the public codename repo folder
|
||||
- Type those commands:
|
||||
- `git remote add dev https://www.github.com/YoshiCrafter29/CodenameEngine-Dev`
|
||||
- `git branch --set-upstream-to dev/main`
|
||||
- GitHub desktop should be synchronized with the dev repo now. If you're unsure,
|
||||
- Repo name should still say "CodenameEngine"
|
||||
- Current branch should still say "main"
|
||||
- "Fetch" button should say "Fetch dev"
|
||||
- You shouldn't have any commit to push.
|
||||
@@ -1,8 +0,0 @@
|
||||
@ECHO OFF
|
||||
cd ..
|
||||
echo Building Game...
|
||||
lime build windows --haxeflag="-xml docs/doc.xml" -D doc-gen -D DOCUMENTATION --no-output
|
||||
echo art
|
||||
|
||||
echo Generated the api xml file at docs/doc.xml
|
||||
echo Please put this in codename-website/api-generator/api/doc.xml
|
||||
@@ -47,10 +47,18 @@
|
||||
<anim char="8">character-eight</anim>
|
||||
<anim char="9">character-nine</anim>
|
||||
|
||||
<composite char="ã">
|
||||
<component anim="character-a0" x="0" y="0"/>
|
||||
<component anim="diacritic-tilde-fill" x="11" y="73" outline="diacritic-tilde-outline" outlineX="-1" hasOutline="true"/>
|
||||
</composite>
|
||||
<composite char="ẽ">
|
||||
<component anim="character-e0" x="0" y="0"/>
|
||||
<component anim="diacritic-tilde-fill" x="3" y="73" outline="diacritic-tilde-outline" outlineX="-1" hasOutline="true"/>
|
||||
</composite>
|
||||
<composite char="õ">
|
||||
<component anim="character-o0" x="0" y="0"/>
|
||||
<component anim="diacritic-tilde-fill" x="8" y="73" outline="diacritic-tilde-outline" outlineX="-1" hasOutline="true"/>
|
||||
</composite>
|
||||
<composite char="ñ">
|
||||
<component anim="character-n0" x="0" y="0"/>
|
||||
<component anim="diacritic-tilde-fill" x="3" y="73" outline="diacritic-tilde-outline" outlineX="-1" hasOutline="true"/>
|
||||
@@ -75,6 +83,22 @@
|
||||
<component anim="character-u0" x="0" y="0"/>
|
||||
<component anim="diacritic-acute-fill" x="15" y="60" outline="diacritic-acute-outline" outlineX="-1" hasOutline="true"/>
|
||||
</composite>
|
||||
<composite char="â">
|
||||
<component anim="character-a0" x="0" y="0"/>
|
||||
<component anim="diacritic-circumflex-fill" x="13" y="70" outline="diacritic-circumflex-outline" outlineX="-1" hasOutline="true"/>
|
||||
</composite>
|
||||
<composite char="ê">
|
||||
<component anim="character-e0" x="0" y="0"/>
|
||||
<component anim="diacritic-circumflex-fill" x="6" y="70" outline="diacritic-circumflex-outline" outlineX="-1" hasOutline="true"/>
|
||||
</composite>
|
||||
<composite char="ô">
|
||||
<component anim="character-o0" x="0" y="0"/>
|
||||
<component anim="diacritic-circumflex-fill" x="11" y="70" outline="diacritic-circumflex-outline" outlineX="-1" hasOutline="true"/>
|
||||
</composite>
|
||||
<composite char="à">
|
||||
<component anim="character-a0" x="0" y="0"/>
|
||||
<component anim="diacritic-acute-fill" x="16" y="70" outline="diacritic-acute-outline" outlineX="1" hasOutline="true" flipX="true"/>
|
||||
</composite>
|
||||
<composite char="ą">
|
||||
<component anim="character-a0" x="0" y="0"/>
|
||||
<component anim="diacritic-ogonek-fill" x="34" y="-12" outline="diacritic-ogonek-outline" outlineX="2" outlineY="-2" hasOutline="true"/>
|
||||
@@ -83,6 +107,10 @@
|
||||
<component anim="character-e0" x="0" y="0"/>
|
||||
<component anim="diacritic-ogonek-fill" x="23" y="-14" outline="diacritic-ogonek-outline" outlineX="2" outlineY="-2" hasOutline="true"/>
|
||||
</composite>
|
||||
<composite char="ç">
|
||||
<component anim="character-c0" x="0" y="0"/>
|
||||
<component anim="diacritic-cadilla-fill" x="20" y="-15" outline="diacritic-cadilla-outline" outlineX="3" outlineY="-1" hasOutline="true"/>
|
||||
</composite>
|
||||
<composite char="ć">
|
||||
<component anim="character-c0" x="0" y="0"/>
|
||||
<component anim="diacritic-acute-fill" x="18" y="73" outline="diacritic-acute-outline" outlineX="-1" hasOutline="true"/>
|
||||
|
||||
@@ -2,13 +2,6 @@
|
||||
<character x="115" y="325" sprite="gf-christmas" icon="gf" color="#A5004D">
|
||||
<anim name="danceLeft" anim="GF Dancing Beat" x="0" y="-9" fps="24" loop="false" indices="0..14"/>
|
||||
<anim name="danceRight" anim="GF Dancing Beat" x="0" y="-9" fps="24" loop="false" indices="15..30"/>
|
||||
<anim name="singUP" anim="GF Up Note" x="0" y="-9" fps="24" loop="false"/>
|
||||
<anim name="singDOWN" anim="GF Down Note" x="0" y="-9" fps="24" loop="false"/>
|
||||
<anim name="singLEFT" anim="GF left note" x="0" y="-9" fps="24" loop="false"/>
|
||||
<anim name="singRIGHT" anim="GF Right Note" x="0" y="-9" fps="24" loop="false"/>
|
||||
<anim name="scared" anim="GF FEAR" x="0" y="-9" fps="24" loop="true"/>
|
||||
<anim name="hairBlow" anim="GF Dancing Beat Hair blowing" x="0" y="-9" fps="24" loop="false" indices="0..3"/>
|
||||
<anim name="hairFall" anim="GF Dancing Beat Hair Landing" x="0" y="-9" fps="24" loop="false" indices="0..11"/>
|
||||
<anim name="cheer" anim="GF Cheer" x="0" y="-9" fps="24" loop="false"/>
|
||||
<anim name="sad" anim="gf sad" x="-51" y="306" fps="24" loop="true" indices="0..12"/>
|
||||
</character>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<!DOCTYPE codename-engine-character>
|
||||
<character x="100" y="275" sprite="gf" icon="gf" color="#A5004D">
|
||||
<anim name="cheer" anim="GF Cheer" x="0" y="0" fps="24" loop="false"/>
|
||||
<anim name="singUP" anim="GF Up Note" x="0" y="0" fps="24" loop="false"/>
|
||||
<anim name="singLEFT" anim="GF left note" x="0" y="0" fps="24" loop="false"/>
|
||||
<anim name="singRIGHT" anim="GF Right Note" x="0" y="0" fps="24" loop="false"/>
|
||||
<anim name="singDOWN" anim="GF Down Note" x="0" y="0" fps="24" loop="false"/>
|
||||
<anim name="danceLeft" anim="GF Dancing Beat" x="0" y="0" fps="24" loop="false" indices="0..14"/>
|
||||
<anim name="danceRight" anim="GF Dancing Beat" x="0" y="0" fps="24" loop="false" indices="15..30"/>
|
||||
<anim name="hairBlow" anim="GF Dancing Beat Hair blowing" x="0" y="0" fps="24" loop="true" indices="0,1,2,3"/>
|
||||
<anim name="hairFall" anim="GF Dancing Beat Hair Landing" x="0" y="0" fps="24" loop="false" indices="0..11"/>
|
||||
<anim name="scared" anim="GF FEAR" x="0" y="0" fps="24" loop="true"/>
|
||||
<anim name="sad" anim="gf sad" x="0" y="0" fps="24" loop="true" indices="0..12"/>
|
||||
<character x="100" y="275" color="#A5004D">
|
||||
<anim name="cheer" anim="GF Cheer"/>
|
||||
<anim name="singUP" anim="GF Up Note"/>
|
||||
<anim name="singLEFT" anim="GF left note"/>
|
||||
<anim name="singRIGHT" anim="GF Right Note"/>
|
||||
<anim name="singDOWN" anim="GF Down Note"/>
|
||||
<anim name="danceLeft" anim="GF Dancing Beat" indices="0..14"/>
|
||||
<anim name="danceRight" anim="GF Dancing Beat" indices="15..30"/>
|
||||
<anim name="hairBlow" anim="GF Dancing Beat Hair blowing" loop="true" indices="0..3"/>
|
||||
<anim name="hairFall" anim="GF Dancing Beat Hair Landing" indices="0..11"/>
|
||||
<anim name="scared" anim="GF FEAR " loop="true"/>
|
||||
<anim name="sad" anim="gf sad" x="-51" y="315" loop="true" indices="0..12"/>
|
||||
</character>
|
||||
|
||||
@@ -8,7 +8,7 @@ function onDiscordPresenceUpdate(e) {
|
||||
var data = e.presence;
|
||||
|
||||
if(data.button1Label == null)
|
||||
data.button1Label = "meow"; // "Codename Engine Discord"
|
||||
data.button1Label = "Codename Engine Discord";
|
||||
if(data.button1Url == null)
|
||||
data.button1Url = "https://discord.gg/2NTCdsQvx4";
|
||||
}
|
||||
@@ -33,8 +33,8 @@ function onEditorTreeLoaded(name:String) {
|
||||
DiscordUtil.changePresenceSince("Choosing a Character", null);
|
||||
case "Chart Editor":
|
||||
DiscordUtil.changePresenceSince("Choosing a Chart", null);
|
||||
//case "Stage Editor": // secret for now
|
||||
// DiscordUtil.changePresenceSince("Choosing a Stage", null);
|
||||
case "Stage Editor": // secret for now
|
||||
DiscordUtil.changePresenceSince("Choosing a Stage", null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ function onEditorLoaded(name:String, editingThing:String) {
|
||||
DiscordUtil.changePresenceSince("Editing a Character", editingThing);
|
||||
case "Chart Editor":
|
||||
DiscordUtil.changePresenceSince("Editing a Chart", editingThing);
|
||||
//case "Stage Editor":
|
||||
// DiscordUtil.changePresenceSince("Editing a Stage", editingThing);
|
||||
case "Stage Editor":
|
||||
DiscordUtil.changePresenceSince("Editing a Stage", editingThing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ function onCountdown(event) {
|
||||
};
|
||||
}
|
||||
|
||||
function onPlayerHit(event:NoteHitEvent) {
|
||||
function onRatingsShown(event:RatingsShowEvent) {
|
||||
if (!enablePixelUI) return;
|
||||
event.ratingPrefix = "stages/school/ui/";
|
||||
event.ratingScale = daPixelZoom * 0.7;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<sprite name="fgSnow" x="-600" y="680" sprite="fgSnow"/>
|
||||
|
||||
|
||||
<girlfriend x="540" y="110"/>
|
||||
<girlfriend x="440" y="110"/>
|
||||
<dad/>
|
||||
<boyfriend x="1030" camyoffset="-150" camxoffset="-150"/>
|
||||
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
{"ATLAS": {"SPRITES":[
|
||||
{"SPRITE" : {"name": "0000","x":1636,"y":275,"w":183,"h":115,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0001","x":215,"y":360,"w":84,"h":140,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0002","x":419,"y":358,"w":251,"h":121,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0003","x":1636,"y":394,"w":120,"h":65,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0004","x":4,"y":360,"w":108,"h":126,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0005","x":674,"y":358,"w":102,"h":147,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0006","x":116,"y":360,"w":95,"h":130,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0007","x":2038,"y":4,"w":1,"h":4,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0008","x":4,"y":4,"w":411,"h":352,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0009","x":419,"y":4,"w":398,"h":350,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0010","x":1303,"y":275,"w":329,"h":162,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0011","x":303,"y":360,"w":90,"h":103,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0012","x":1823,"y":4,"w":211,"h":236,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0013","x":1823,"y":244,"w":208,"h":235,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0014","x":821,"y":258,"w":478,"h":262,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0015","x":821,"y":4,"w":521,"h":250,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0016","x":1346,"y":4,"w":473,"h":267,"rotated": false}}
|
||||
]},
|
||||
"meta": {
|
||||
"app": "Adobe Animate",
|
||||
"version": "22.0.5.191",
|
||||
"image": "spritemap1.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {"w":2043,"h":524},
|
||||
"resolution": "1"
|
||||
}
|
||||
{"ATLAS":{"SPRITES":[
|
||||
{"SPRITE":{"name":"0","x":1662,"y":282,"w":194,"h":117,"rotated":false}},
|
||||
{"SPRITE":{"name":"1","x":1790,"y":417,"w":92,"h":136,"rotated":false}},
|
||||
{"SPRITE":{"name":"2","x":1193,"y":539,"w":259,"h":123,"rotated":false}},
|
||||
{"SPRITE":{"name":"3","x":483,"y":553,"w":125,"h":68,"rotated":false}},
|
||||
{"SPRITE":{"name":"4","x":1662,"y":417,"w":110,"h":127,"rotated":false}},
|
||||
{"SPRITE":{"name":"5","x":1886,"y":0,"w":105,"h":149,"rotated":false}},
|
||||
{"SPRITE":{"name":"6","x":1886,"y":167,"w":97,"h":130,"rotated":false}},
|
||||
{"SPRITE":{"name":"7","x":1398,"y":0,"w":470,"h":264,"rotated":false}},
|
||||
{"SPRITE":{"name":"8","x":867,"y":0,"w":513,"h":254,"rotated":false}},
|
||||
{"SPRITE":{"name":"9","x":0,"y":372,"w":465,"h":270,"rotated":false}},
|
||||
{"SPRITE":{"name":"10","x":1900,"y":315,"w":101,"h":118,"rotated":false}},
|
||||
{"SPRITE":{"name":"11","x":867,"y":272,"w":308,"h":367,"rotated":false}},
|
||||
{"SPRITE":{"name":"12","x":483,"y":371,"w":338,"h":164,"rotated":false}},
|
||||
{"SPRITE":{"name":"13","x":0,"y":0,"w":422,"h":354,"rotated":false}},
|
||||
{"SPRITE":{"name":"14","x":440,"y":0,"w":409,"h":353,"rotated":false}},
|
||||
{"SPRITE":{"name":"15","x":1900,"y":451,"w":92,"h":103,"rotated":false}},
|
||||
{"SPRITE":{"name":"16","x":1193,"y":282,"w":218,"h":239,"rotated":false}},
|
||||
{"SPRITE":{"name":"17","x":1429,"y":282,"w":215,"h":237,"rotated":false}}]},
|
||||
"meta":{
|
||||
"app":"Adobe Animate (Better TA Extension)",
|
||||
"version":"24.0.2.12",
|
||||
"image":"spritemap1.png",
|
||||
"format":"RGBA8888",
|
||||
"size":{"w":2031,"h":662},
|
||||
"resolution":"1"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 134 KiB |
@@ -1,58 +1,40 @@
|
||||
{"ATLAS": {"SPRITES":[
|
||||
{"SPRITE" : {"name": "0000","x":994,"y":1029,"w":187,"h":118,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0001","x":1953,"y":524,"w":84,"h":140,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0002","x":471,"y":430,"w":258,"h":137,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0003","x":1300,"y":641,"w":122,"h":66,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0004","x":1825,"y":1078,"w":108,"h":126,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0005","x":360,"y":695,"w":103,"h":149,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0006","x":1945,"y":867,"w":95,"h":130,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0007","x":2034,"y":4,"w":1,"h":4,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0008","x":943,"y":650,"w":309,"h":375,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0009","x":4,"y":4,"w":778,"h":422,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0010","x":786,"y":4,"w":761,"h":393,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0011","x":1551,"y":4,"w":411,"h":352,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0012","x":1551,"y":360,"w":398,"h":350,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0013","x":4,"y":1028,"w":329,"h":162,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0014","x":1945,"y":1001,"w":90,"h":103,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0015","x":1300,"y":401,"w":211,"h":236,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0016","x":782,"y":1029,"w":208,"h":235,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0017","x":782,"y":910,"w":117,"h":83,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0018","x":994,"y":1151,"w":117,"h":83,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0019","x":1937,"y":1108,"w":103,"h":83,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0020","x":1115,"y":1151,"w":117,"h":83,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0021","x":1654,"y":714,"w":287,"h":360,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0022","x":471,"y":571,"w":179,"h":67,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0023","x":654,"y":571,"w":118,"h":75,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0024","x":1966,"y":223,"w":55,"h":112,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0025","x":1966,"y":4,"w":64,"h":106,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0026","x":1185,"y":1029,"w":67,"h":70,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0027","x":337,"y":1182,"w":122,"h":62,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0028","x":1647,"y":1078,"w":174,"h":97,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0029","x":360,"y":870,"w":82,"h":14,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0030","x":1647,"y":1179,"w":128,"h":61,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0031","x":463,"y":1182,"w":124,"h":58,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0032","x":1966,"y":114,"w":59,"h":105,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0033","x":1953,"y":360,"w":87,"h":160,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0034","x":1945,"y":714,"w":92,"h":149,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0035","x":1426,"y":641,"w":104,"h":42,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0036","x":1953,"y":692,"w":73,"h":18,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0037","x":1426,"y":687,"w":72,"h":19,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0038","x":360,"y":848,"w":72,"h":18,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0039","x":1953,"y":668,"w":73,"h":20,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0040","x":471,"y":650,"w":468,"h":256,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0041","x":786,"y":401,"w":510,"h":245,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0042","x":4,"y":430,"w":463,"h":261,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0043","x":360,"y":910,"w":418,"h":268,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0044","x":1256,"y":1008,"w":387,"h":271,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0045","x":1256,"y":714,"w":394,"h":290,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0046","x":4,"y":695,"w":352,"h":329,"rotated": false}}
|
||||
]},
|
||||
"meta": {
|
||||
"app": "Adobe Animate",
|
||||
"version": "22.0.5.191",
|
||||
"image": "spritemap1.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {"w":2044,"h":1283},
|
||||
"resolution": "1"
|
||||
}
|
||||
{"ATLAS":{"SPRITES":[
|
||||
{"SPRITE":{"name":"0","x":349,"y":867,"w":254,"h":136,"rotated":false}},
|
||||
{"SPRITE":{"name":"1","x":1648,"y":328,"w":287,"h":363,"rotated":false}},
|
||||
{"SPRITE":{"name":"2","x":1571,"y":709,"w":185,"h":117,"rotated":false}},
|
||||
{"SPRITE":{"name":"3","x":1686,"y":855,"w":86,"h":136,"rotated":false}},
|
||||
{"SPRITE":{"name":"4","x":349,"y":1021,"w":122,"h":68,"rotated":false}},
|
||||
{"SPRITE":{"name":"5","x":1774,"y":709,"w":110,"h":128,"rotated":false}},
|
||||
{"SPRITE":{"name":"6","x":621,"y":867,"w":105,"h":148,"rotated":false}},
|
||||
{"SPRITE":{"name":"7","x":1571,"y":844,"w":97,"h":131,"rotated":false}},
|
||||
{"SPRITE":{"name":"8","x":800,"y":1,"w":543,"h":308,"rotated":false}},
|
||||
{"SPRITE":{"name":"9","x":800,"y":1,"w":543,"h":308,"rotated":false}},
|
||||
{"SPRITE":{"name":"10","x":800,"y":1,"w":543,"h":308,"rotated":false}},
|
||||
{"SPRITE":{"name":"11","x":800,"y":1,"w":543,"h":308,"rotated":false}},
|
||||
{"SPRITE":{"name":"12","x":800,"y":1,"w":543,"h":308,"rotated":false}},
|
||||
{"SPRITE":{"name":"13","x":800,"y":1,"w":543,"h":308,"rotated":false}},
|
||||
{"SPRITE":{"name":"14","x":800,"y":1,"w":543,"h":308,"rotated":false}},
|
||||
{"SPRITE":{"name":"15","x":800,"y":1,"w":543,"h":308,"rotated":false}},
|
||||
{"SPRITE":{"name":"16","x":1363,"y":1,"w":543,"h":308,"rotated":false}},
|
||||
{"SPRITE":{"name":"17","x":1,"y":444,"w":771,"h":404,"rotated":false}},
|
||||
{"SPRITE":{"name":"18","x":791,"y":700,"w":302,"h":369,"rotated":false}},
|
||||
{"SPRITE":{"name":"19","x":1111,"y":957,"w":120,"h":86,"rotated":false}},
|
||||
{"SPRITE":{"name":"20","x":1790,"y":855,"w":120,"h":86,"rotated":false}},
|
||||
{"SPRITE":{"name":"21","x":1790,"y":959,"w":106,"h":86,"rotated":false}},
|
||||
{"SPRITE":{"name":"22","x":1249,"y":957,"w":120,"h":86,"rotated":false}},
|
||||
{"SPRITE":{"name":"23","x":0,"y":0,"w":781,"h":425,"rotated":false}},
|
||||
{"SPRITE":{"name":"24","x":0,"y":867,"w":331,"h":164,"rotated":false}},
|
||||
{"SPRITE":{"name":"25","x":799,"y":328,"w":413,"h":354,"rotated":false}},
|
||||
{"SPRITE":{"name":"26","x":1230,"y":328,"w":400,"h":353,"rotated":false}},
|
||||
{"SPRITE":{"name":"27","x":1387,"y":954,"w":90,"h":103,"rotated":false}},
|
||||
{"SPRITE":{"name":"28","x":1111,"y":700,"w":213,"h":239,"rotated":false}},
|
||||
{"SPRITE":{"name":"29","x":1342,"y":699,"w":211,"h":237,"rotated":false}}]},
|
||||
"meta":{
|
||||
"app":"Adobe Animate (Better TA Extension)",
|
||||
"version":"24.0.2.12",
|
||||
"image":"spritemap1.png",
|
||||
"format":"RGBA8888",
|
||||
"size":{"w":1965,"h":1089},
|
||||
"resolution":"1"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 228 KiB After Width: | Height: | Size: 453 KiB |
@@ -1,57 +1,55 @@
|
||||
{"ATLAS": {"SPRITES":[
|
||||
{"SPRITE" : {"name": "0000","x":1623,"y":602,"w":287,"h":360,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0001","x":1310,"y":269,"w":309,"h":375,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0002","x":4,"y":4,"w":420,"h":359,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0003","x":428,"y":4,"w":406,"h":358,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0004","x":4,"y":639,"w":336,"h":165,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0005","x":125,"y":808,"w":90,"h":103,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0006","x":1819,"y":4,"w":215,"h":242,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0007","x":1217,"y":648,"w":213,"h":240,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0008","x":606,"y":660,"w":191,"h":120,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0009","x":606,"y":784,"w":90,"h":151,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0010","x":344,"y":660,"w":258,"h":124,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0011","x":448,"y":859,"w":122,"h":67,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0012","x":1914,"y":755,"w":108,"h":126,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0013","x":1914,"y":602,"w":103,"h":149,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0014","x":700,"y":784,"w":95,"h":130,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0015","x":2038,"y":4,"w":1,"h":4,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0016","x":838,"y":253,"w":468,"h":256,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0017","x":838,"y":4,"w":510,"h":245,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0018","x":1352,"y":4,"w":463,"h":261,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0019","x":4,"y":367,"w":418,"h":268,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0020","x":826,"y":513,"w":387,"h":271,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0021","x":428,"y":366,"w":394,"h":290,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0022","x":1623,"y":269,"w":352,"h":329,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0023","x":1143,"y":788,"w":67,"h":70,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0024","x":1033,"y":875,"w":122,"h":62,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0025","x":1217,"y":513,"w":64,"h":106,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0026","x":1979,"y":359,"w":55,"h":112,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0027","x":799,"y":788,"w":98,"h":118,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0028","x":1979,"y":250,"w":59,"h":105,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0029","x":1434,"y":749,"w":87,"h":160,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0030","x":1525,"y":749,"w":92,"h":149,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0031","x":219,"y":887,"w":104,"h":42,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0032","x":527,"y":811,"w":73,"h":18,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0033","x":527,"y":788,"w":72,"h":19,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0034","x":527,"y":833,"w":72,"h":18,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0035","x":1217,"y":623,"w":73,"h":20,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0036","x":344,"y":788,"w":179,"h":67,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0037","x":219,"y":808,"w":118,"h":75,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0038","x":901,"y":875,"w":128,"h":61,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0039","x":1914,"y":885,"w":124,"h":58,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0040","x":901,"y":788,"w":117,"h":83,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0041","x":1022,"y":788,"w":117,"h":83,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0042","x":341,"y":859,"w":103,"h":83,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0043","x":4,"y":808,"w":117,"h":83,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0044","x":1434,"y":648,"w":174,"h":97,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0045","x":1819,"y":250,"w":82,"h":14,"rotated": false}}
|
||||
]},
|
||||
"meta": {
|
||||
"app": "Adobe Animate",
|
||||
"version": "21.0.1.37179",
|
||||
"image": "spritemap1.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {"w":2043,"h":966},
|
||||
"resolution": "1"
|
||||
}
|
||||
{"ATLAS":{"SPRITES":[
|
||||
{"SPRITE":{"name":"0","x":1129,"y":977,"w":86,"h":17,"rotated":false}},
|
||||
{"SPRITE":{"name":"1","x":1690,"y":1012,"w":86,"h":17,"rotated":false}},
|
||||
{"SPRITE":{"name":"2","x":1656,"y":852,"w":126,"h":64,"rotated":false}},
|
||||
{"SPRITE":{"name":"3","x":1915,"y":841,"w":121,"h":77,"rotated":false}},
|
||||
{"SPRITE":{"name":"4","x":1382,"y":980,"w":131,"h":64,"rotated":false}},
|
||||
{"SPRITE":{"name":"5","x":1132,"y":283,"w":420,"h":270,"rotated":false}},
|
||||
{"SPRITE":{"name":"6","x":1570,"y":277,"w":389,"h":273,"rotated":false}},
|
||||
{"SPRITE":{"name":"7","x":0,"y":743,"w":397,"h":292,"rotated":false}},
|
||||
{"SPRITE":{"name":"8","x":431,"y":267,"w":354,"h":332,"rotated":false}},
|
||||
{"SPRITE":{"name":"9","x":1592,"y":568,"w":190,"h":117,"rotated":false}},
|
||||
{"SPRITE":{"name":"10","x":1444,"y":826,"w":86,"h":136,"rotated":false}},
|
||||
{"SPRITE":{"name":"11","x":723,"y":852,"w":260,"h":123,"rotated":false}},
|
||||
{"SPRITE":{"name":"12","x":1548,"y":947,"w":124,"h":68,"rotated":false}},
|
||||
{"SPRITE":{"name":"13","x":1001,"y":852,"w":110,"h":128,"rotated":false}},
|
||||
{"SPRITE":{"name":"14","x":1933,"y":0,"w":106,"h":148,"rotated":false}},
|
||||
{"SPRITE":{"name":"15","x":1129,"y":828,"w":97,"h":131,"rotated":false}},
|
||||
{"SPRITE":{"name":"16","x":803,"y":283,"w":311,"h":369,"rotated":false}},
|
||||
{"SPRITE":{"name":"17","x":1592,"y":703,"w":167,"h":101,"rotated":false}},
|
||||
{"SPRITE":{"name":"18","x":1835,"y":852,"w":57,"h":105,"rotated":false}},
|
||||
{"SPRITE":{"name":"19","x":1977,"y":270,"w":66,"h":104,"rotated":false}},
|
||||
{"SPRITE":{"name":"20","x":1910,"y":936,"w":70,"h":73,"rotated":false}},
|
||||
{"SPRITE":{"name":"21","x":1244,"y":828,"w":182,"h":69,"rotated":false}},
|
||||
{"SPRITE":{"name":"22","x":1690,"y":934,"w":127,"h":60,"rotated":false}},
|
||||
{"SPRITE":{"name":"23","x":418,"y":617,"w":287,"h":363,"rotated":false}},
|
||||
{"SPRITE":{"name":"24","x":1244,"y":915,"w":120,"h":86,"rotated":false}},
|
||||
{"SPRITE":{"name":"25","x":1777,"y":748,"w":120,"h":86,"rotated":false}},
|
||||
{"SPRITE":{"name":"26","x":1933,"y":166,"w":106,"h":86,"rotated":false}},
|
||||
{"SPRITE":{"name":"27","x":1915,"y":737,"w":120,"h":86,"rotated":false}},
|
||||
{"SPRITE":{"name":"28","x":1800,"y":568,"w":89,"h":162,"rotated":false}},
|
||||
{"SPRITE":{"name":"29","x":1907,"y":568,"w":95,"h":151,"rotated":false}},
|
||||
{"SPRITE":{"name":"30","x":1977,"y":392,"w":61,"h":107,"rotated":false}},
|
||||
{"SPRITE":{"name":"31","x":415,"y":998,"w":107,"h":45,"rotated":false}},
|
||||
{"SPRITE":{"name":"32","x":727,"y":993,"w":77,"h":22,"rotated":false}},
|
||||
{"SPRITE":{"name":"33","x":634,"y":998,"w":75,"h":23,"rotated":false}},
|
||||
{"SPRITE":{"name":"34","x":822,"y":993,"w":75,"h":22,"rotated":false}},
|
||||
{"SPRITE":{"name":"35","x":540,"y":998,"w":76,"h":24,"rotated":false}},
|
||||
{"SPRITE":{"name":"36","x":1445,"y":0,"w":470,"h":259,"rotated":false}},
|
||||
{"SPRITE":{"name":"37","x":431,"y":0,"w":513,"h":249,"rotated":false}},
|
||||
{"SPRITE":{"name":"38","x":962,"y":0,"w":465,"h":265,"rotated":false}},
|
||||
{"SPRITE":{"name":"39","x":723,"y":670,"w":331,"h":164,"rotated":false}},
|
||||
{"SPRITE":{"name":"40","x":0,"y":0,"w":413,"h":354,"rotated":false}},
|
||||
{"SPRITE":{"name":"41","x":0,"y":372,"w":400,"h":353,"rotated":false}},
|
||||
{"SPRITE":{"name":"42","x":1548,"y":826,"w":90,"h":103,"rotated":false}},
|
||||
{"SPRITE":{"name":"43","x":1132,"y":571,"w":213,"h":239,"rotated":false}},
|
||||
{"SPRITE":{"name":"44","x":1363,"y":571,"w":211,"h":237,"rotated":false}}]},
|
||||
"meta":{
|
||||
"app":"Adobe Animate (Better TA Extension)",
|
||||
"version":"24.0.2.12",
|
||||
"image":"spritemap1.png",
|
||||
"format":"RGBA8888",
|
||||
"size":{"w":2064,"h":1065},
|
||||
"resolution":"1"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 265 KiB |
@@ -1,60 +1,60 @@
|
||||
{"ATLAS": {"SPRITES":[
|
||||
{"SPRITE" : {"name": "0000","x":4076,"y":2,"w":9,"h":12,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0001","x":1957,"y":2,"w":524,"h":501,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0002","x":716,"y":2,"w":721,"h":621,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0003","x":2331,"y":505,"w":139,"h":109,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0004","x":3244,"y":725,"w":303,"h":170,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0005","x":1691,"y":516,"w":248,"h":277,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0006","x":2495,"y":843,"w":173,"h":229,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0007","x":2,"y":642,"w":262,"h":221,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0008","x":2331,"y":616,"w":118,"h":117,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0009","x":3549,"y":865,"w":261,"h":139,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0010","x":3209,"y":897,"w":202,"h":122,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0011","x":580,"y":913,"w":202,"h":122,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0012","x":2831,"y":304,"w":45,"h":42,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0013","x":1957,"y":505,"w":372,"h":311,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0014","x":1439,"y":516,"w":250,"h":325,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0015","x":716,"y":625,"w":235,"h":286,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0016","x":953,"y":625,"w":245,"h":249,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0017","x":3644,"y":373,"w":136,"h":133,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0018","x":2331,"y":735,"w":150,"h":91,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0019","x":3644,"y":508,"w":151,"h":95,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0020","x":784,"y":913,"w":140,"h":90,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0021","x":3644,"y":605,"w":149,"h":92,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0022","x":2670,"y":932,"w":144,"h":87,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0023","x":2670,"y":843,"w":152,"h":87,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0024","x":4087,"y":2,"w":1,"h":4,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0025","x":2831,"y":373,"w":411,"h":352,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0026","x":3244,"y":373,"w":398,"h":350,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0027","x":266,"y":642,"w":329,"h":162,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0028","x":597,"y":642,"w":90,"h":103,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0029","x":1200,"y":625,"w":211,"h":236,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0030","x":2831,"y":727,"w":208,"h":235,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0031","x":2483,"y":2,"w":738,"h":300,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0032","x":2483,"y":304,"w":346,"h":537,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0033","x":2,"y":865,"w":235,"h":158,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0034","x":3812,"y":865,"w":216,"h":141,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0035","x":2000,"y":818,"w":299,"h":155,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0036","x":1200,"y":863,"w":179,"h":208,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0037","x":1691,"y":818,"w":307,"h":154,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0038","x":3644,"y":702,"w":320,"h":161,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0039","x":266,"y":806,"w":312,"h":155,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0040","x":239,"y":963,"w":224,"h":108,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0041","x":3223,"y":2,"w":580,"h":369,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0042","x":3805,"y":2,"w":269,"h":698,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0043","x":1413,"y":843,"w":205,"h":222,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0044","x":3041,"y":727,"w":166,"h":292,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0045","x":953,"y":876,"w":203,"h":137,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0046","x":1439,"y":2,"w":516,"h":512,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0047","x":2,"y":2,"w":712,"h":638,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0048","x":2301,"y":843,"w":192,"h":227,"rotated": false}}
|
||||
]},
|
||||
"meta": {
|
||||
"app": "Adobe Animate",
|
||||
"version": "21.0.1.37179",
|
||||
"image": "spritemap1.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {"w":4090,"h":1074},
|
||||
"resolution": "1"
|
||||
}
|
||||
{"ATLAS":{"SPRITES":[
|
||||
{"SPRITE":{"name":"0","x":2834,"y":332,"w":12,"h":15,"rotated":false}},
|
||||
{"SPRITE":{"name":"1","x":1476,"y":532,"w":527,"h":503,"rotated":false}},
|
||||
{"SPRITE":{"name":"2","x":733,"y":0,"w":725,"h":623,"rotated":false}},
|
||||
{"SPRITE":{"name":"3","x":0,"y":659,"w":741,"h":304,"rotated":false}},
|
||||
{"SPRITE":{"name":"4","x":2311,"y":0,"w":349,"h":540,"rotated":false}},
|
||||
{"SPRITE":{"name":"5","x":759,"y":641,"w":583,"h":373,"rotated":false}},
|
||||
{"SPRITE":{"name":"6","x":2021,"y":0,"w":272,"h":702,"rotated":false}},
|
||||
{"SPRITE":{"name":"7","x":1476,"y":0,"w":518,"h":514,"rotated":false}},
|
||||
{"SPRITE":{"name":"8","x":0,"y":0,"w":715,"h":641,"rotated":false}},
|
||||
{"SPRITE":{"name":"9","x":619,"y":1032,"w":205,"h":122,"rotated":false}},
|
||||
{"SPRITE":{"name":"10","x":842,"y":1032,"w":205,"h":122,"rotated":false}},
|
||||
{"SPRITE":{"name":"11","x":2311,"y":558,"w":115,"h":112,"rotated":false}},
|
||||
{"SPRITE":{"name":"12","x":2801,"y":947,"w":305,"h":172,"rotated":false}},
|
||||
{"SPRITE":{"name":"13","x":2678,"y":0,"w":375,"h":314,"rotated":false}},
|
||||
{"SPRITE":{"name":"14","x":2870,"y":332,"w":252,"h":328,"rotated":false}},
|
||||
{"SPRITE":{"name":"15","x":3071,"y":0,"w":239,"h":290,"rotated":false}},
|
||||
{"SPRITE":{"name":"16","x":3135,"y":678,"w":220,"h":246,"rotated":false}},
|
||||
{"SPRITE":{"name":"17","x":3597,"y":248,"w":173,"h":231,"rotated":false}},
|
||||
{"SPRITE":{"name":"18","x":3769,"y":0,"w":225,"h":190,"rotated":false}},
|
||||
{"SPRITE":{"name":"19","x":1290,"y":1053,"w":131,"h":81,"rotated":false}},
|
||||
{"SPRITE":{"name":"20","x":3905,"y":814,"w":132,"h":85,"rotated":false}},
|
||||
{"SPRITE":{"name":"21","x":1733,"y":1053,"w":122,"h":80,"rotated":false}},
|
||||
{"SPRITE":{"name":"22","x":3905,"y":917,"w":129,"h":82,"rotated":false}},
|
||||
{"SPRITE":{"name":"23","x":1589,"y":1053,"w":126,"h":78,"rotated":false}},
|
||||
{"SPRITE":{"name":"24","x":1439,"y":1053,"w":132,"h":77,"rotated":false}},
|
||||
{"SPRITE":{"name":"25","x":3778,"y":814,"w":109,"h":107,"rotated":false}},
|
||||
{"SPRITE":{"name":"26","x":3124,"y":1123,"w":3,"h":7,"rotated":false}},
|
||||
{"SPRITE":{"name":"27","x":3145,"y":1123,"w":3,"h":7,"rotated":false}},
|
||||
{"SPRITE":{"name":"28","x":3673,"y":497,"w":260,"h":141,"rotated":false}},
|
||||
{"SPRITE":{"name":"29","x":3788,"y":208,"w":237,"h":161,"rotated":false}},
|
||||
{"SPRITE":{"name":"30","x":3542,"y":660,"w":218,"h":144,"rotated":false}},
|
||||
{"SPRITE":{"name":"31","x":3124,"y":947,"w":301,"h":158,"rotated":false}},
|
||||
{"SPRITE":{"name":"32","x":3371,"y":498,"w":284,"h":144,"rotated":false}},
|
||||
{"SPRITE":{"name":"33","x":0,"y":981,"w":295,"h":150,"rotated":false}},
|
||||
{"SPRITE":{"name":"34","x":313,"y":981,"w":288,"h":145,"rotated":false}},
|
||||
{"SPRITE":{"name":"35","x":3443,"y":942,"w":182,"h":212,"rotated":false}},
|
||||
{"SPRITE":{"name":"36","x":3371,"y":255,"w":208,"h":225,"rotated":false}},
|
||||
{"SPRITE":{"name":"37","x":3373,"y":660,"w":151,"h":264,"rotated":false}},
|
||||
{"SPRITE":{"name":"38","x":3778,"y":656,"w":206,"h":140,"rotated":false}},
|
||||
{"SPRITE":{"name":"39","x":3557,"y":0,"w":194,"h":230,"rotated":false}},
|
||||
{"SPRITE":{"name":"40","x":2678,"y":485,"w":47,"h":44,"rotated":false}},
|
||||
{"SPRITE":{"name":"41","x":2870,"y":678,"w":247,"h":251,"rotated":false}},
|
||||
{"SPRITE":{"name":"42","x":2678,"y":332,"w":138,"h":135,"rotated":false}},
|
||||
{"SPRITE":{"name":"43","x":1065,"y":1053,"w":207,"h":101,"rotated":false}},
|
||||
{"SPRITE":{"name":"44","x":2452,"y":947,"w":331,"h":164,"rotated":false}},
|
||||
{"SPRITE":{"name":"45","x":2021,"y":720,"w":413,"h":354,"rotated":false}},
|
||||
{"SPRITE":{"name":"46","x":2452,"y":558,"w":400,"h":353,"rotated":false}},
|
||||
{"SPRITE":{"name":"47","x":3951,"y":387,"w":90,"h":103,"rotated":false}},
|
||||
{"SPRITE":{"name":"48","x":3140,"y":308,"w":213,"h":239,"rotated":false}},
|
||||
{"SPRITE":{"name":"49","x":3328,"y":0,"w":211,"h":237,"rotated":false}}]},
|
||||
"meta":{
|
||||
"app":"Adobe Animate (Better TA Extension)",
|
||||
"version":"24.0.2.12",
|
||||
"image":"spritemap1.png",
|
||||
"format":"RGBA8888",
|
||||
"size":{"w":4061,"h":1154},
|
||||
"resolution":"1"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 344 KiB After Width: | Height: | Size: 535 KiB |
|
Before Width: | Height: | Size: 804 B After Width: | Height: | Size: 1.0 KiB |
@@ -1,145 +1,241 @@
|
||||
{"ATLAS": {"SPRITES":[
|
||||
{"SPRITE" : {"name": "0000","x":2847,"y":969,"w":327,"h":397,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0001","x":2441,"y":894,"w":110,"h":159,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0002","x":1709,"y":1631,"w":197,"h":185,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0003","x":408,"y":1773,"w":92,"h":155,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0004","x":236,"y":1639,"w":274,"h":132,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0005","x":3427,"y":1495,"w":133,"h":74,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0006","x":3270,"y":540,"w":121,"h":162,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0007","x":359,"y":649,"w":518,"h":294,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0008","x":1957,"y":2,"w":775,"h":483,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0009","x":1014,"y":2,"w":941,"h":607,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0010","x":2,"y":2,"w":1010,"h":645,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0011","x":4059,"y":2,"w":20,"h":142,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0012","x":4035,"y":616,"w":40,"h":83,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0013","x":2755,"y":1508,"w":64,"h":57,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0014","x":3176,"y":1171,"w":91,"h":48,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0015","x":3245,"y":1737,"w":88,"h":41,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0016","x":3064,"y":1368,"w":109,"h":93,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0017","x":3402,"y":2,"w":655,"h":434,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0018","x":1957,"y":487,"w":626,"h":405,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0019","x":3402,"y":438,"w":631,"h":438,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0020","x":1170,"y":1211,"w":393,"h":287,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0021","x":2847,"y":540,"w":421,"h":427,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0022","x":2734,"y":2,"w":666,"h":536,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0023","x":542,"y":1480,"w":224,"h":221,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0024","x":3657,"y":1736,"w":186,"h":175,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0025","x":4035,"y":764,"w":56,"h":52,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0026","x":502,"y":1876,"w":126,"h":104,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0027","x":1709,"y":1818,"w":135,"h":104,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0028","x":2,"y":1440,"w":232,"h":236,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0029","x":3938,"y":1437,"w":139,"h":109,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0030","x":2755,"y":1627,"w":235,"h":158,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0031","x":1147,"y":1500,"w":198,"h":233,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0032","x":2,"y":1860,"w":118,"h":117,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0033","x":1565,"y":1398,"w":262,"h":221,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0034","x":3845,"y":1736,"w":222,"h":145,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0035","x":979,"y":1480,"w":166,"h":292,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0036","x":3657,"y":1592,"w":276,"h":142,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0037","x":925,"y":1774,"w":203,"h":138,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0038","x":236,"y":1467,"w":304,"h":170,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0039","x":4081,"y":2,"w":1,"h":4,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0040","x":2441,"y":1055,"w":135,"h":127,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0041","x":2,"y":1678,"w":195,"h":180,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0042","x":2751,"y":1787,"w":160,"h":144,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0043","x":713,"y":945,"w":243,"h":261,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0044","x":2375,"y":1508,"w":378,"h":121,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0045","x":3064,"y":1495,"w":361,"h":128,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0046","x":713,"y":1211,"w":455,"h":267,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0047","x":2,"y":1112,"w":272,"h":326,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0048","x":3710,"y":878,"w":249,"h":557,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0049","x":2585,"y":540,"w":260,"h":701,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0050","x":1014,"y":611,"w":291,"h":598,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0051","x":1307,"y":611,"w":315,"h":540,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0052","x":2,"y":649,"w":355,"h":461,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0053","x":359,"y":945,"w":352,"h":373,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0054","x":3064,"y":1625,"w":347,"h":110,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0055","x":2039,"y":1248,"w":379,"h":216,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0056","x":2827,"y":1368,"w":235,"h":257,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0057","x":2100,"y":1879,"w":140,"h":92,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0058","x":776,"y":1886,"w":119,"h":79,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0059","x":1565,"y":1249,"w":434,"h":147,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0060","x":276,"y":1320,"w":433,"h":145,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0061","x":3270,"y":878,"w":438,"h":342,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0062","x":3176,"y":1222,"w":385,"h":271,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0063","x":3563,"y":1437,"w":373,"h":153,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0064","x":3245,"y":1786,"w":202,"h":122,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0065","x":3449,"y":1786,"w":202,"h":122,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0066","x":3064,"y":1861,"w":150,"h":91,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0067","x":3938,"y":1548,"w":151,"h":95,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0068","x":3845,"y":1883,"w":140,"h":90,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0069","x":2913,"y":1861,"w":149,"h":92,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0070","x":630,"y":1886,"w":144,"h":87,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0071","x":3935,"y":1645,"w":152,"h":87,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0072","x":2441,"y":1243,"w":384,"h":263,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0073","x":1624,"y":611,"w":248,"h":277,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0074","x":1624,"y":894,"w":413,"h":353,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0075","x":2039,"y":894,"w":400,"h":352,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0076","x":1829,"y":1466,"w":330,"h":163,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0077","x":3987,"y":1883,"w":90,"h":103,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0078","x":2161,"y":1466,"w":212,"h":238,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0079","x":768,"y":1480,"w":209,"h":236,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0080","x":2242,"y":1879,"w":86,"h":84,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0081","x":879,"y":649,"w":126,"h":148,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0082","x":1908,"y":1631,"w":216,"h":168,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0083","x":2575,"y":1631,"w":174,"h":192,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0084","x":1130,"y":1901,"w":106,"h":75,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0085","x":3961,"y":1367,"w":129,"h":63,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0086","x":1829,"y":1398,"w":158,"h":60,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0087","x":3270,"y":704,"w":123,"h":148,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0088","x":3961,"y":878,"w":123,"h":148,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0089","x":199,"y":1773,"w":207,"h":142,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0090","x":1238,"y":1901,"w":91,"h":53,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0091","x":276,"y":1112,"w":65,"h":96,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0092","x":276,"y":1210,"w":65,"h":96,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0093","x":2518,"y":1825,"w":136,"h":102,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0094","x":1537,"y":1857,"w":136,"h":102,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0095","x":3427,"y":1592,"w":228,"h":192,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0096","x":1541,"y":1621,"w":166,"h":234,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0097","x":512,"y":1703,"w":205,"h":171,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0098","x":2126,"y":1706,"w":205,"h":171,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0099","x":719,"y":1718,"w":204,"h":166,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0100","x":1147,"y":1735,"w":206,"h":164,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0101","x":1874,"y":611,"w":79,"h":185,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0102","x":3176,"y":969,"w":83,"h":200,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0103","x":3563,"y":1222,"w":86,"h":180,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0104","x":3961,"y":1028,"w":89,"h":186,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0105","x":2375,"y":1631,"w":198,"h":183,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0106","x":1908,"y":1801,"w":190,"h":120,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0107","x":2656,"y":1825,"w":86,"h":145,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0108","x":1355,"y":1724,"w":180,"h":170,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0109","x":3961,"y":1216,"w":111,"h":149,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0110","x":4035,"y":516,"w":39,"h":98,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0111","x":1307,"y":1153,"w":118,"h":47,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0112","x":1427,"y":1153,"w":120,"h":43,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0113","x":2441,"y":1184,"w":120,"h":41,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0114","x":3216,"y":1910,"w":95,"h":33,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0115","x":3563,"y":1404,"w":95,"h":31,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0116","x":3563,"y":1404,"w":95,"h":31,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0117","x":2330,"y":1906,"w":95,"h":34,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0118","x":2585,"y":487,"w":131,"h":47,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0119","x":4059,"y":258,"w":31,"h":18,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0120","x":1355,"y":1896,"w":122,"h":66,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0121","x":2992,"y":1737,"w":251,"h":122,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0122","x":879,"y":799,"w":114,"h":133,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0123","x":1347,"y":1500,"w":192,"h":222,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0124","x":4035,"y":818,"w":39,"h":34,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0125","x":4035,"y":701,"w":50,"h":61,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0126","x":1874,"y":798,"w":64,"h":78,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0127","x":4035,"y":438,"w":52,"h":76,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0128","x":958,"y":934,"w":46,"h":63,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0129","x":4059,"y":146,"w":30,"h":41,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0130","x":4059,"y":189,"w":23,"h":35,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0131","x":4059,"y":226,"w":20,"h":30,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0132","x":4059,"y":278,"w":17,"h":22,"rotated": false}},
|
||||
{"SPRITE" : {"name": "0133","x":2333,"y":1816,"w":183,"h":88,"rotated": false}}
|
||||
]},
|
||||
"meta": {
|
||||
"app": "Adobe Animate",
|
||||
"version": "21.0.1.37179",
|
||||
"image": "spritemap1.png",
|
||||
"format": "RGBA8888",
|
||||
"size": {"w":4093,"h":1988},
|
||||
"resolution": "1"
|
||||
}
|
||||
{"ATLAS":{"SPRITES":[
|
||||
{"SPRITE":{"name":"0","x":2564,"y":2,"w":23,"h":144,"rotated":false}},
|
||||
{"SPRITE":{"name":"1","x":3024,"y":522,"w":42,"h":85,"rotated":false}},
|
||||
{"SPRITE":{"name":"2","x":2598,"y":1211,"w":67,"h":60,"rotated":false}},
|
||||
{"SPRITE":{"name":"3","x":3964,"y":932,"w":93,"h":51,"rotated":false}},
|
||||
{"SPRITE":{"name":"4","x":3691,"y":1016,"w":91,"h":43,"rotated":false}},
|
||||
{"SPRITE":{"name":"5","x":3877,"y":270,"w":111,"h":95,"rotated":false}},
|
||||
{"SPRITE":{"name":"6","x":3449,"y":1124,"w":113,"h":127,"rotated":false}},
|
||||
{"SPRITE":{"name":"7","x":367,"y":1129,"w":382,"h":123,"rotated":false}},
|
||||
{"SPRITE":{"name":"8","x":2,"y":1122,"w":364,"h":131,"rotated":false}},
|
||||
{"SPRITE":{"name":"9","x":2,"y":1122,"w":364,"h":131,"rotated":false}},
|
||||
{"SPRITE":{"name":"10","x":2437,"y":1136,"w":31,"h":31,"rotated":false}},
|
||||
{"SPRITE":{"name":"11","x":1599,"y":1133,"w":350,"h":113,"rotated":false}},
|
||||
{"SPRITE":{"name":"12","x":1599,"y":1133,"w":350,"h":113,"rotated":false}},
|
||||
{"SPRITE":{"name":"13","x":2670,"y":1175,"w":142,"h":94,"rotated":false}},
|
||||
{"SPRITE":{"name":"14","x":3877,"y":366,"w":122,"h":82,"rotated":false}},
|
||||
{"SPRITE":{"name":"15","x":1162,"y":1112,"w":436,"h":151,"rotated":false}},
|
||||
{"SPRITE":{"name":"16","x":1599,"y":985,"w":435,"h":147,"rotated":false}},
|
||||
{"SPRITE":{"name":"17","x":1599,"y":985,"w":435,"h":147,"rotated":false}},
|
||||
{"SPRITE":{"name":"18","x":779,"y":692,"w":440,"h":344,"rotated":false}},
|
||||
{"SPRITE":{"name":"19","x":1550,"y":711,"w":388,"h":273,"rotated":false}},
|
||||
{"SPRITE":{"name":"20","x":2106,"y":2,"w":376,"h":155,"rotated":false}},
|
||||
{"SPRITE":{"name":"21","x":2,"y":2,"w":932,"h":689,"rotated":false}},
|
||||
{"SPRITE":{"name":"22","x":3907,"y":1171,"w":48,"h":36,"rotated":false}},
|
||||
{"SPRITE":{"name":"23","x":3907,"y":1171,"w":48,"h":36,"rotated":false}},
|
||||
{"SPRITE":{"name":"24","x":3858,"y":1206,"w":48,"h":40,"rotated":false}},
|
||||
{"SPRITE":{"name":"25","x":3762,"y":1093,"w":48,"h":64,"rotated":false}},
|
||||
{"SPRITE":{"name":"26","x":3713,"y":1060,"w":48,"h":66,"rotated":false}},
|
||||
{"SPRITE":{"name":"27","x":3885,"y":1095,"w":48,"h":67,"rotated":false}},
|
||||
{"SPRITE":{"name":"28","x":2106,"y":158,"w":48,"h":69,"rotated":false}},
|
||||
{"SPRITE":{"name":"29","x":2481,"y":498,"w":48,"h":71,"rotated":false}},
|
||||
{"SPRITE":{"name":"30","x":1162,"y":1037,"w":48,"h":73,"rotated":false}},
|
||||
{"SPRITE":{"name":"31","x":4018,"y":188,"w":48,"h":76,"rotated":false}},
|
||||
{"SPRITE":{"name":"32","x":3455,"y":856,"w":48,"h":78,"rotated":false}},
|
||||
{"SPRITE":{"name":"33","x":3785,"y":1011,"w":48,"h":81,"rotated":false}},
|
||||
{"SPRITE":{"name":"34","x":4002,"y":1164,"w":48,"h":82,"rotated":false}},
|
||||
{"SPRITE":{"name":"35","x":3953,"y":1083,"w":48,"h":87,"rotated":false}},
|
||||
{"SPRITE":{"name":"36","x":3904,"y":1004,"w":48,"h":90,"rotated":false}},
|
||||
{"SPRITE":{"name":"37","x":4013,"y":1070,"w":48,"h":93,"rotated":false}},
|
||||
{"SPRITE":{"name":"38","x":3964,"y":984,"w":48,"h":98,"rotated":false}},
|
||||
{"SPRITE":{"name":"39","x":1550,"y":985,"w":48,"h":103,"rotated":false}},
|
||||
{"SPRITE":{"name":"40","x":3848,"y":894,"w":50,"h":109,"rotated":false}},
|
||||
{"SPRITE":{"name":"41","x":3797,"y":894,"w":50,"h":116,"rotated":false}},
|
||||
{"SPRITE":{"name":"42","x":2777,"y":452,"w":50,"h":121,"rotated":false}},
|
||||
{"SPRITE":{"name":"43","x":4002,"y":585,"w":50,"h":119,"rotated":false}},
|
||||
{"SPRITE":{"name":"44","x":3913,"y":886,"w":50,"h":117,"rotated":false}},
|
||||
{"SPRITE":{"name":"45","x":3059,"y":2,"w":52,"h":129,"rotated":false}},
|
||||
{"SPRITE":{"name":"46","x":3964,"y":886,"w":123,"h":45,"rotated":false}},
|
||||
{"SPRITE":{"name":"47","x":1770,"y":228,"w":123,"h":43,"rotated":false}},
|
||||
{"SPRITE":{"name":"48","x":3424,"y":486,"w":99,"h":35,"rotated":false}},
|
||||
{"SPRITE":{"name":"49","x":2979,"y":1141,"w":99,"h":34,"rotated":false}},
|
||||
{"SPRITE":{"name":"50","x":2979,"y":1141,"w":99,"h":34,"rotated":false}},
|
||||
{"SPRITE":{"name":"51","x":2590,"y":360,"w":99,"h":36,"rotated":false}},
|
||||
{"SPRITE":{"name":"52","x":3709,"y":783,"w":35,"h":21,"rotated":false}},
|
||||
{"SPRITE":{"name":"53","x":1220,"y":711,"w":329,"h":400,"rotated":false}},
|
||||
{"SPRITE":{"name":"54","x":3042,"y":979,"w":112,"h":161,"rotated":false}},
|
||||
{"SPRITE":{"name":"55","x":2929,"y":163,"w":199,"h":188,"rotated":false}},
|
||||
{"SPRITE":{"name":"56","x":2175,"y":574,"w":96,"h":158,"rotated":false}},
|
||||
{"SPRITE":{"name":"57","x":1623,"y":570,"w":277,"h":134,"rotated":false}},
|
||||
{"SPRITE":{"name":"58","x":1550,"y":1089,"w":38,"h":22,"rotated":false}},
|
||||
{"SPRITE":{"name":"59","x":3666,"y":152,"w":124,"h":165,"rotated":false}},
|
||||
{"SPRITE":{"name":"60","x":1623,"y":272,"w":309,"h":297,"rotated":false}},
|
||||
{"SPRITE":{"name":"61","x":3801,"y":2,"w":121,"h":91,"rotated":false}},
|
||||
{"SPRITE":{"name":"62","x":3281,"y":522,"w":320,"h":77,"rotated":false}},
|
||||
{"SPRITE":{"name":"63","x":3921,"y":755,"w":17,"h":22,"rotated":false}},
|
||||
{"SPRITE":{"name":"64","x":1351,"y":272,"w":162,"h":74,"rotated":false}},
|
||||
{"SPRITE":{"name":"65","x":3801,"y":94,"w":69,"h":50,"rotated":false}},
|
||||
{"SPRITE":{"name":"66","x":2273,"y":574,"w":277,"h":174,"rotated":false}},
|
||||
{"SPRITE":{"name":"67","x":2261,"y":1136,"w":175,"h":123,"rotated":false}},
|
||||
{"SPRITE":{"name":"68","x":4058,"y":932,"w":32,"h":49,"rotated":false}},
|
||||
{"SPRITE":{"name":"69","x":3791,"y":270,"w":66,"h":38,"rotated":false}},
|
||||
{"SPRITE":{"name":"70","x":3079,"y":1141,"w":71,"h":40,"rotated":false}},
|
||||
{"SPRITE":{"name":"71","x":2690,"y":360,"w":82,"h":29,"rotated":false}},
|
||||
{"SPRITE":{"name":"72","x":3602,"y":516,"w":88,"h":69,"rotated":false}},
|
||||
{"SPRITE":{"name":"73","x":4022,"y":806,"w":69,"h":27,"rotated":false}},
|
||||
{"SPRITE":{"name":"74","x":1894,"y":228,"w":30,"h":40,"rotated":false}},
|
||||
{"SPRITE":{"name":"75","x":3987,"y":654,"w":10,"h":13,"rotated":false}},
|
||||
{"SPRITE":{"name":"76","x":3896,"y":1084,"w":7,"h":7,"rotated":false}},
|
||||
{"SPRITE":{"name":"77","x":3834,"y":1074,"w":9,"h":9,"rotated":false}},
|
||||
{"SPRITE":{"name":"78","x":3885,"y":1084,"w":10,"h":10,"rotated":false}},
|
||||
{"SPRITE":{"name":"79","x":3441,"y":736,"w":12,"h":12,"rotated":false}},
|
||||
{"SPRITE":{"name":"80","x":3811,"y":1128,"w":19,"h":17,"rotated":false}},
|
||||
{"SPRITE":{"name":"81","x":3971,"y":654,"w":15,"h":14,"rotated":false}},
|
||||
{"SPRITE":{"name":"82","x":3858,"y":1150,"w":7,"h":7,"rotated":false}},
|
||||
{"SPRITE":{"name":"83","x":3794,"y":452,"w":5,"h":5,"rotated":false}},
|
||||
{"SPRITE":{"name":"84","x":3326,"y":751,"w":32,"h":57,"rotated":false}},
|
||||
{"SPRITE":{"name":"85","x":2583,"y":147,"w":6,"h":7,"rotated":false}},
|
||||
{"SPRITE":{"name":"86","x":935,"y":617,"w":198,"h":66,"rotated":false}},
|
||||
{"SPRITE":{"name":"87","x":426,"y":692,"w":352,"h":436,"rotated":false}},
|
||||
{"SPRITE":{"name":"88","x":3814,"y":452,"w":156,"h":69,"rotated":false}},
|
||||
{"SPRITE":{"name":"89","x":2829,"y":452,"w":194,"h":197,"rotated":false}},
|
||||
{"SPRITE":{"name":"90","x":2670,"y":733,"w":181,"h":216,"rotated":false}},
|
||||
{"SPRITE":{"name":"91","x":3791,"y":150,"w":93,"h":119,"rotated":false}},
|
||||
{"SPRITE":{"name":"92","x":4000,"y":372,"w":86,"h":75,"rotated":false}},
|
||||
{"SPRITE":{"name":"93","x":3587,"y":320,"w":113,"h":195,"rotated":false}},
|
||||
{"SPRITE":{"name":"94","x":2483,"y":2,"w":80,"h":151,"rotated":false}},
|
||||
{"SPRITE":{"name":"95","x":3493,"y":2,"w":177,"h":149,"rotated":false}},
|
||||
{"SPRITE":{"name":"96","x":3327,"y":183,"w":9,"h":8,"rotated":false}},
|
||||
{"SPRITE":{"name":"97","x":3787,"y":452,"w":6,"h":6,"rotated":false}},
|
||||
{"SPRITE":{"name":"98","x":4002,"y":705,"w":57,"h":48,"rotated":false}},
|
||||
{"SPRITE":{"name":"99","x":2574,"y":147,"w":8,"h":8,"rotated":false}},
|
||||
{"SPRITE":{"name":"100","x":3814,"y":605,"w":8,"h":12,"rotated":false}},
|
||||
{"SPRITE":{"name":"101","x":1589,"y":1089,"w":9,"h":10,"rotated":false}},
|
||||
{"SPRITE":{"name":"102","x":3701,"y":318,"w":85,"h":140,"rotated":false}},
|
||||
{"SPRITE":{"name":"103","x":2,"y":692,"w":423,"h":429,"rotated":false}},
|
||||
{"SPRITE":{"name":"104","x":3533,"y":152,"w":132,"h":167,"rotated":false}},
|
||||
{"SPRITE":{"name":"105","x":3249,"y":961,"w":66,"h":16,"rotated":false}},
|
||||
{"SPRITE":{"name":"106","x":3576,"y":808,"w":52,"h":43,"rotated":false}},
|
||||
{"SPRITE":{"name":"107","x":3858,"y":1163,"w":46,"h":42,"rotated":false}},
|
||||
{"SPRITE":{"name":"108","x":3834,"y":1011,"w":13,"h":62,"rotated":false}},
|
||||
{"SPRITE":{"name":"109","x":3654,"y":1025,"w":34,"h":29,"rotated":false}},
|
||||
{"SPRITE":{"name":"110","x":3811,"y":1150,"w":46,"h":65,"rotated":false}},
|
||||
{"SPRITE":{"name":"111","x":3701,"y":459,"w":112,"h":46,"rotated":false}},
|
||||
{"SPRITE":{"name":"112","x":2035,"y":898,"w":226,"h":223,"rotated":false}},
|
||||
{"SPRITE":{"name":"113","x":3233,"y":351,"w":190,"h":170,"rotated":false}},
|
||||
{"SPRITE":{"name":"114","x":3654,"y":1060,"w":58,"h":55,"rotated":false}},
|
||||
{"SPRITE":{"name":"115","x":3885,"y":94,"w":112,"h":94,"rotated":false}},
|
||||
{"SPRITE":{"name":"116","x":3576,"y":706,"w":132,"h":101,"rotated":false}},
|
||||
{"SPRITE":{"name":"117","x":1939,"y":493,"w":235,"h":239,"rotated":false}},
|
||||
{"SPRITE":{"name":"118","x":3242,"y":1150,"w":141,"h":111,"rotated":false}},
|
||||
{"SPRITE":{"name":"119","x":2822,"y":2,"w":236,"h":160,"rotated":false}},
|
||||
{"SPRITE":{"name":"120","x":2475,"y":749,"w":194,"h":236,"rotated":false}},
|
||||
{"SPRITE":{"name":"121","x":3455,"y":736,"w":120,"h":119,"rotated":false}},
|
||||
{"SPRITE":{"name":"122","x":2551,"y":398,"w":225,"h":189,"rotated":false}},
|
||||
{"SPRITE":{"name":"123","x":3923,"y":2,"w":130,"h":81,"rotated":false}},
|
||||
{"SPRITE":{"name":"124","x":3691,"y":621,"w":132,"h":83,"rotated":false}},
|
||||
{"SPRITE":{"name":"125","x":3531,"y":1025,"w":122,"h":80,"rotated":false}},
|
||||
{"SPRITE":{"name":"126","x":3814,"y":522,"w":129,"h":82,"rotated":false}},
|
||||
{"SPRITE":{"name":"127","x":3709,"y":705,"w":125,"h":77,"rotated":false}},
|
||||
{"SPRITE":{"name":"128","x":3885,"y":189,"w":132,"h":76,"rotated":false}},
|
||||
{"SPRITE":{"name":"129","x":2035,"y":1122,"w":225,"h":142,"rotated":false}},
|
||||
{"SPRITE":{"name":"130","x":2777,"y":187,"w":151,"h":264,"rotated":false}},
|
||||
{"SPRITE":{"name":"131","x":2551,"y":588,"w":277,"h":144,"rotated":false}},
|
||||
{"SPRITE":{"name":"132","x":3327,"y":197,"w":205,"h":140,"rotated":false}},
|
||||
{"SPRITE":{"name":"133","x":2175,"y":401,"w":305,"h":172,"rotated":false}},
|
||||
{"SPRITE":{"name":"134","x":2841,"y":1136,"w":137,"h":129,"rotated":false}},
|
||||
{"SPRITE":{"name":"135","x":3129,"y":172,"w":197,"h":178,"rotated":false}},
|
||||
{"SPRITE":{"name":"136","x":2,"y":1122,"w":364,"h":131,"rotated":false}},
|
||||
{"SPRITE":{"name":"137","x":3424,"y":338,"w":162,"h":147,"rotated":false}},
|
||||
{"SPRITE":{"name":"138","x":1933,"y":228,"w":223,"h":264,"rotated":false}},
|
||||
{"SPRITE":{"name":"139","x":1351,"y":2,"w":418,"h":269,"rotated":false}},
|
||||
{"SPRITE":{"name":"140","x":1599,"y":1133,"w":350,"h":113,"rotated":false}},
|
||||
{"SPRITE":{"name":"141","x":1599,"y":985,"w":435,"h":147,"rotated":false}},
|
||||
{"SPRITE":{"name":"142","x":3921,"y":670,"w":80,"h":84,"rotated":false}},
|
||||
{"SPRITE":{"name":"143","x":2564,"y":147,"w":9,"h":8,"rotated":false}},
|
||||
{"SPRITE":{"name":"144","x":2437,"y":1168,"w":31,"h":27,"rotated":false}},
|
||||
{"SPRITE":{"name":"145","x":3664,"y":808,"w":110,"h":88,"rotated":false}},
|
||||
{"SPRITE":{"name":"146","x":3024,"y":608,"w":43,"h":39,"rotated":false}},
|
||||
{"SPRITE":{"name":"147","x":3563,"y":1106,"w":55,"h":58,"rotated":false}},
|
||||
{"SPRITE":{"name":"148","x":3971,"y":619,"w":19,"h":34,"rotated":false}},
|
||||
{"SPRITE":{"name":"149","x":3416,"y":1250,"w":30,"h":23,"rotated":false}},
|
||||
{"SPRITE":{"name":"150","x":1939,"y":898,"w":82,"h":85,"rotated":false}},
|
||||
{"SPRITE":{"name":"151","x":4054,"y":39,"w":34,"h":41,"rotated":false}},
|
||||
{"SPRITE":{"name":"152","x":3691,"y":516,"w":122,"h":104,"rotated":false}},
|
||||
{"SPRITE":{"name":"153","x":3762,"y":1060,"w":17,"h":32,"rotated":false}},
|
||||
{"SPRITE":{"name":"154","x":3745,"y":783,"w":28,"h":20,"rotated":false}},
|
||||
{"SPRITE":{"name":"155","x":3524,"y":486,"w":45,"h":35,"rotated":false}},
|
||||
{"SPRITE":{"name":"156","x":4000,"y":266,"w":74,"h":105,"rotated":false}},
|
||||
{"SPRITE":{"name":"157","x":3775,"y":836,"w":137,"h":57,"rotated":false}},
|
||||
{"SPRITE":{"name":"158","x":3384,"y":1250,"w":31,"h":23,"rotated":false}},
|
||||
{"SPRITE":{"name":"159","x":3504,"y":908,"w":24,"h":24,"rotated":false}},
|
||||
{"SPRITE":{"name":"160","x":4013,"y":984,"w":55,"h":85,"rotated":false}},
|
||||
{"SPRITE":{"name":"161","x":4054,"y":2,"w":40,"h":36,"rotated":false}},
|
||||
{"SPRITE":{"name":"162","x":3775,"y":783,"w":163,"h":52,"rotated":false}},
|
||||
{"SPRITE":{"name":"163","x":1950,"y":1133,"w":73,"h":115,"rotated":false}},
|
||||
{"SPRITE":{"name":"164","x":3531,"y":962,"w":159,"h":62,"rotated":false}},
|
||||
{"SPRITE":{"name":"165","x":3811,"y":1093,"w":20,"h":34,"rotated":false}},
|
||||
{"SPRITE":{"name":"166","x":4067,"y":230,"w":27,"h":32,"rotated":false}},
|
||||
{"SPRITE":{"name":"167","x":4067,"y":188,"w":24,"h":41,"rotated":false}},
|
||||
{"SPRITE":{"name":"168","x":3504,"y":856,"w":26,"h":51,"rotated":false}},
|
||||
{"SPRITE":{"name":"169","x":2929,"y":352,"w":86,"h":98,"rotated":false}},
|
||||
{"SPRITE":{"name":"170","x":3824,"y":605,"w":146,"h":64,"rotated":false}},
|
||||
{"SPRITE":{"name":"171","x":1589,"y":1100,"w":9,"h":10,"rotated":false}},
|
||||
{"SPRITE":{"name":"172","x":3327,"y":172,"w":8,"h":10,"rotated":false}},
|
||||
{"SPRITE":{"name":"173","x":3939,"y":806,"w":82,"h":27,"rotated":false}},
|
||||
{"SPRITE":{"name":"174","x":3944,"y":522,"w":141,"h":62,"rotated":false}},
|
||||
{"SPRITE":{"name":"175","x":3024,"y":352,"w":208,"h":169,"rotated":false}},
|
||||
{"SPRITE":{"name":"176","x":3129,"y":2,"w":208,"h":169,"rotated":false}},
|
||||
{"SPRITE":{"name":"177","x":3042,"y":814,"w":206,"h":164,"rotated":false}},
|
||||
{"SPRITE":{"name":"178","x":3072,"y":522,"w":208,"h":161,"rotated":false}},
|
||||
{"SPRITE":{"name":"179","x":779,"y":1037,"w":382,"h":218,"rotated":false}},
|
||||
{"SPRITE":{"name":"180","x":935,"y":357,"w":237,"h":259,"rotated":false}},
|
||||
{"SPRITE":{"name":"181","x":3155,"y":979,"w":86,"h":203,"rotated":false}},
|
||||
{"SPRITE":{"name":"182","x":3364,"y":751,"w":90,"h":183,"rotated":false}},
|
||||
{"SPRITE":{"name":"183","x":3357,"y":961,"w":91,"h":188,"rotated":false}},
|
||||
{"SPRITE":{"name":"184","x":2852,"y":814,"w":185,"h":122,"rotated":false}},
|
||||
{"SPRITE":{"name":"185","x":3787,"y":318,"w":89,"h":133,"rotated":false}},
|
||||
{"SPRITE":{"name":"186","x":2590,"y":187,"w":183,"h":172,"rotated":false}},
|
||||
{"SPRITE":{"name":"187","x":3242,"y":979,"w":114,"h":151,"rotated":false}},
|
||||
{"SPRITE":{"name":"188","x":4047,"y":834,"w":42,"h":36,"rotated":false}},
|
||||
{"SPRITE":{"name":"189","x":1134,"y":617,"w":53,"h":63,"rotated":false}},
|
||||
{"SPRITE":{"name":"190","x":3166,"y":1183,"w":67,"h":80,"rotated":false}},
|
||||
{"SPRITE":{"name":"191","x":3848,"y":1004,"w":55,"h":79,"rotated":false}},
|
||||
{"SPRITE":{"name":"192","x":3834,"y":1084,"w":50,"h":65,"rotated":false}},
|
||||
{"SPRITE":{"name":"193","x":3629,"y":808,"w":33,"h":43,"rotated":false}},
|
||||
{"SPRITE":{"name":"194","x":3493,"y":152,"w":26,"h":38,"rotated":false}},
|
||||
{"SPRITE":{"name":"195","x":3971,"y":585,"w":23,"h":33,"rotated":false}},
|
||||
{"SPRITE":{"name":"196","x":2530,"y":498,"w":20,"h":24,"rotated":false}},
|
||||
{"SPRITE":{"name":"197","x":3939,"y":755,"w":121,"h":50,"rotated":false}},
|
||||
{"SPRITE":{"name":"198","x":3913,"y":836,"w":133,"h":49,"rotated":false}},
|
||||
{"SPRITE":{"name":"199","x":3971,"y":449,"w":119,"h":69,"rotated":false}},
|
||||
{"SPRITE":{"name":"200","x":3072,"y":684,"w":253,"h":125,"rotated":false}},
|
||||
{"SPRITE":{"name":"201","x":3441,"y":600,"w":116,"h":135,"rotated":false}},
|
||||
{"SPRITE":{"name":"202","x":2475,"y":986,"w":194,"h":224,"rotated":false}},
|
||||
{"SPRITE":{"name":"203","x":1770,"y":2,"w":335,"h":225,"rotated":false}},
|
||||
{"SPRITE":{"name":"204","x":2157,"y":158,"w":217,"h":242,"rotated":false}},
|
||||
{"SPRITE":{"name":"205","x":3249,"y":810,"w":114,"h":150,"rotated":false}},
|
||||
{"SPRITE":{"name":"206","x":3326,"y":600,"w":114,"h":150,"rotated":false}},
|
||||
{"SPRITE":{"name":"207","x":3835,"y":670,"w":85,"h":87,"rotated":false}},
|
||||
{"SPRITE":{"name":"208","x":3671,"y":2,"w":129,"h":147,"rotated":false}},
|
||||
{"SPRITE":{"name":"209","x":2852,"y":650,"w":219,"h":163,"rotated":false}},
|
||||
{"SPRITE":{"name":"210","x":3338,"y":2,"w":154,"h":194,"rotated":false}},
|
||||
{"SPRITE":{"name":"211","x":1514,"y":272,"w":108,"h":68,"rotated":false}},
|
||||
{"SPRITE":{"name":"212","x":3664,"y":897,"w":132,"h":64,"rotated":false}},
|
||||
{"SPRITE":{"name":"213","x":2437,"y":1211,"w":160,"h":62,"rotated":false}},
|
||||
{"SPRITE":{"name":"214","x":3449,"y":935,"w":81,"h":188,"rotated":false}},
|
||||
{"SPRITE":{"name":"215","x":2841,"y":950,"w":200,"h":185,"rotated":false}},
|
||||
{"SPRITE":{"name":"216","x":3384,"y":1150,"w":63,"h":99,"rotated":false}},
|
||||
{"SPRITE":{"name":"217","x":2481,"y":398,"w":63,"h":99,"rotated":false}},
|
||||
{"SPRITE":{"name":"218","x":3558,"y":600,"w":132,"h":105,"rotated":false}},
|
||||
{"SPRITE":{"name":"219","x":3531,"y":856,"w":132,"h":105,"rotated":false}},
|
||||
{"SPRITE":{"name":"220","x":2590,"y":2,"w":231,"h":184,"rotated":false}},
|
||||
{"SPRITE":{"name":"221","x":2670,"y":950,"w":170,"h":224,"rotated":false}},
|
||||
{"SPRITE":{"name":"222","x":2273,"y":749,"w":198,"h":144,"rotated":false}},
|
||||
{"SPRITE":{"name":"223","x":3691,"y":962,"w":93,"h":53,"rotated":false}},
|
||||
{"SPRITE":{"name":"224","x":2979,"y":1183,"w":186,"h":91,"rotated":false}},
|
||||
{"SPRITE":{"name":"225","x":1939,"y":733,"w":333,"h":164,"rotated":false}},
|
||||
{"SPRITE":{"name":"226","x":935,"y":2,"w":415,"h":354,"rotated":false}},
|
||||
{"SPRITE":{"name":"227","x":1220,"y":357,"w":402,"h":353,"rotated":false}},
|
||||
{"SPRITE":{"name":"228","x":3998,"y":84,"w":90,"h":103,"rotated":false}},
|
||||
{"SPRITE":{"name":"229","x":2375,"y":158,"w":214,"h":239,"rotated":false}},
|
||||
{"SPRITE":{"name":"230","x":2262,"y":898,"w":212,"h":237,"rotated":false}}]},
|
||||
"meta":{
|
||||
"app":"Adobe Animate (Better TA Extension)",
|
||||
"version":"22.0.3.179",
|
||||
"image":"spritemap1.png",
|
||||
"format":"RGBA8888",
|
||||
"size":{"w":4096,"h":1280},
|
||||
"resolution":"1"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 642 KiB After Width: | Height: | Size: 1.2 MiB |
@@ -16,5 +16,5 @@ version="version based on the English config.ini version"
|
||||
|
||||
4. Translate the texts in the copied xml files. The {0} and {1}, and so on are placeholders are used for variables, and should be left as is.
|
||||
|
||||
5. Make a pull request with your changes.
|
||||
5. **If you wanna help us with the language(s) you added in the engine**: Make a pull request with your changes.
|
||||
Make sure the pull request is labeled as `[LANG] Add <language name>` or `[LANG] Update <language name>` or `[LANG] Fix typo in <language name>`, generally anything is allowed but it has to contain the language name.
|
||||
|
||||
@@ -203,6 +203,7 @@
|
||||
<str id="paste">Paste</str>
|
||||
<str id="cut">Cut</str>
|
||||
<str id="delete">Delete</str>
|
||||
<str id="deletestacked">Delete Stacked Notes</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.chart">Chart</str>
|
||||
@@ -223,6 +224,7 @@
|
||||
<str id="resetZoom">Reset Zoom</str>
|
||||
<str id="showSectionsSeparator">Show Sections Separator</str>
|
||||
<str id="showBeatsSeparator">Show Beats Separator</str>
|
||||
<str id="showCameraHighlights">Show Camera Highlights</str>
|
||||
<str id="rainbowWaveforms">Rainbow Waveforms</str>
|
||||
<str id="lowDetailWaveforms">Low Detail Waveforms</str>
|
||||
<str id="scrollLeft">Scroll Left</str>
|
||||
@@ -236,8 +238,9 @@
|
||||
<str id="goEnd">Go forward to the end</str> <!-- used to be "Go to the end" -->
|
||||
<str id="addOpponentCamera">Add camera on Opponent</str>
|
||||
<str id="addPlayerCamera">Add camera on Player</str>
|
||||
<str id="muteInst">Mute instrumental</str>
|
||||
<str id="muteVoices">Mute voices</str>
|
||||
<str id="inst">Instrumental</str>
|
||||
<str id="voices">Voices</str>
|
||||
<str id="hitsounds">Hitsounds</str>
|
||||
</group>
|
||||
|
||||
<group name="BookmarkMenu" prefix="bookmarks.">
|
||||
@@ -250,6 +253,7 @@
|
||||
<str id="editBookmarkListTitle">Bookmark List</str>
|
||||
<str id="editBookmarksTitle">Edit Bookmarks</str>
|
||||
<str id="newBookmarkName">New Bookmark</str>
|
||||
<str id="bookmarkList">Bookmark List</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.note">Note</str>
|
||||
@@ -258,6 +262,7 @@
|
||||
<str id="subtractSustainLength">Subtract sustain length</str>
|
||||
<str id="selectAll">Select all</str>
|
||||
<str id="selectMeasure">Select measure</str>
|
||||
<str id="noteTypesList">Note Types List</str>
|
||||
<str id="editNoteTypesList">Edit Note Types List</str>
|
||||
</group>
|
||||
<str id="topBar.snap">Snap</str>
|
||||
@@ -308,8 +313,9 @@
|
||||
<group name="StrumlineOptions" prefix="strumLine.">
|
||||
<str id="button-name">Options ↓</str>
|
||||
|
||||
<str id="waveforms">Waveforms</str>
|
||||
<str id="hitsounds">Hitsounds</str>
|
||||
<str id="muteVocals">Mute Vocals</str>
|
||||
<str id="vocals">Vocals</str>
|
||||
<str id="edit">Edit</str>
|
||||
<str id="delete">Delete</str>
|
||||
|
||||
@@ -433,6 +439,8 @@
|
||||
<str id="position">Position (X, Y)</str>
|
||||
<str id="fps">FPS</str>
|
||||
<str id="indices">Indices (Frames)</str>
|
||||
<str id="looping">Looping?</str>
|
||||
<str id="label">Label</str>
|
||||
</group>
|
||||
|
||||
<group name="CharacterSpriteScreen" prefix="characterSpriteScreen.">
|
||||
@@ -488,6 +496,7 @@
|
||||
<str id="newGlyph">New Glyph</str>
|
||||
<str id="editGlyph">Edit Glyph</str>
|
||||
<str id="deleteGlyph">Delete Glyph</str>
|
||||
<str id="deleteCurGlyph">Delete Current Glyph</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.offset">Offsets</str>
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
<str id="category.engine">Engine</str>
|
||||
<group name="engine" prefix="engine.">
|
||||
<str id="switchMod">Switch Mod</str>
|
||||
<str id="fpsCounter">FPS Counter</str>
|
||||
</group>
|
||||
|
||||
<str id="category.volume">Volume</str>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<str id="animation">Animación</str>
|
||||
<str id="atlas">Atlas</str>
|
||||
<str id="spritemap">Mapa de sprites</str>
|
||||
|
||||
|
||||
<str id="directory">Ubicación ({0}/)</str>
|
||||
<str id="found">{0} {1} Encontrado</str>
|
||||
<str id="foundplural">{0} {1} Encontrados</str>
|
||||
@@ -188,6 +188,7 @@
|
||||
<str id="paste">Pegar</str>
|
||||
<str id="cut">Cortar</str>
|
||||
<str id="delete">Eliminar</str>
|
||||
<str id="deletestacked">Eliminar Notas Apiladas</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.chart">Chart</str>
|
||||
|
||||
@@ -46,8 +46,9 @@
|
||||
|
||||
<group name="engine" prefix="engine.">
|
||||
<str id="switchMod">Cambiar Mod</str>
|
||||
<str id="fpsCounter">Contador de FPS</str>
|
||||
</group>
|
||||
|
||||
|
||||
<str id="category.volume">Volumen</str>
|
||||
<str id="volume.up">Arriba</str>
|
||||
<str id="volume.down">Abajo</str>
|
||||
|
||||
@@ -194,6 +194,7 @@
|
||||
<str id="paste">Incolla</str>
|
||||
<str id="cut">Taglia</str>
|
||||
<str id="delete">Elimina</str>
|
||||
<str id="deletestacked">Elimina Note Impilate</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.chart">Chart</str>
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
|
||||
<group name="engine" prefix="engine.">
|
||||
<str id="switchMod">Cambia Mod</str>
|
||||
<str id="fpsCounter">Contatore FPS</str>
|
||||
</group>
|
||||
|
||||
<str id="volume.up">Su</str>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<str id="animation">Animacja</str>
|
||||
<str id="atlas">Atlas</str>
|
||||
<str id="spritemap">Mapa sprite'ów</str>
|
||||
|
||||
|
||||
<str id="directory">Folder ({0}/)</str>
|
||||
<str id="found">{0} {1} Znaleziono</str>
|
||||
<str id="foundplural">{0} {1} Znaleziono</str>
|
||||
@@ -87,7 +87,7 @@
|
||||
<group name="CharterEventScreen" prefix="charterEventScreen.">
|
||||
<str id="title-creating">Stwórz Grupę Wydarzeń</str>
|
||||
<str id="title-editing">Edytuj Grupę Wydarzeń</str>
|
||||
|
||||
|
||||
<str id="noEvent">Brak Wydarzenia</str>
|
||||
|
||||
<str id="strumLine.format">Struma #{0} ({1})</str>
|
||||
@@ -197,6 +197,7 @@
|
||||
<str id="paste">Wklej</str>
|
||||
<str id="cut">Wytnij</str>
|
||||
<str id="delete">Usuń</str>
|
||||
<str id="deletestacked">Usuń Notatki Ułożone w Stos</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.chart">Mapa</str>
|
||||
@@ -223,7 +224,7 @@
|
||||
<str id="scrollRight">Przewiń w Prawo</str>
|
||||
<str id="scrollReset">Resetuj Przewinięcie</str>
|
||||
</group>
|
||||
|
||||
|
||||
<str id="topBar.song">Ścieżka</str>
|
||||
<group name="SongMenu" prefix="song.">
|
||||
<str id="goStart">Wróć do początku</str>
|
||||
|
||||
@@ -44,8 +44,9 @@
|
||||
<str id="category.engine">Silnik</str>
|
||||
<group name="engine" prefix="engine.">
|
||||
<str id="switchMod">Zmień Moda</str>
|
||||
<str id="fpsCounter">Licznik FPS</str>
|
||||
</group>
|
||||
|
||||
|
||||
<str id="category.volume">Głośność</str>
|
||||
<str id="volume.up">Głóśniej</str>
|
||||
<str id="volume.down">Ciszej</str>
|
||||
|
||||
@@ -0,0 +1,687 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<language>
|
||||
<group name="General Editor Translations" prefix="editor.">
|
||||
<str id="autosavingIn">Guardando automáticamente em {0} segundos{1}</str>
|
||||
<str id="autosavingCanceledSuffix">(Cancelado)!</str>
|
||||
|
||||
<str id="ok">Ok</str>
|
||||
<str id="cancel">Cancelar</str>
|
||||
<str id="save">Guardar</str>
|
||||
<str id="saveClose">Guardar e Fechar</str>
|
||||
<str id="close">Fechar</str>
|
||||
<str id="notNow">Agora Não</str>
|
||||
<str id="yes">Sim</str>
|
||||
</group>
|
||||
|
||||
<group name="UIImageExplorer" prefix="uiImageExplorer.">
|
||||
<str id="symbol">Simbolo</str>
|
||||
<str id="animation">Animação</str>
|
||||
<str id="atlas">Atlas</str>
|
||||
<str id="spritemap">Mapa de Sprites</str>
|
||||
|
||||
<str id="directory">Diretório ({0}/)</str>
|
||||
<str id="found">{0} {1} Encontrado</str>
|
||||
<str id="foundplural">{0} {1} Encontrado</str>
|
||||
<str id="notFound">#{0}s NÃO Encontrado#</str>
|
||||
<str id="foundAtlas">{0} Mapa de Sprites Encontrado</str>
|
||||
<str id="foundAtlasplural">{0} Mapas de Sprites Encontrados</str>
|
||||
|
||||
<str id="fileAlreadyExists">Os seguintes ficheiros já existem: \n\n{0}\n\nIMPORTANTE: SUBSTITUIR NÃO PODE SER DESFEITO!</str>
|
||||
<str id="override">Substituir Ficheiros</str>
|
||||
<str id="useExisting">Usar Existentes</str>
|
||||
</group>
|
||||
|
||||
<group name="EditorPicker" prefix="editor.">
|
||||
<str id="alphabet.name">Editor de Alfabetos</str>
|
||||
<str id="chart.name">Editor de Mapas</str>
|
||||
<str id="character.name">Editor de Personagens</str>
|
||||
<str id="stage.name">Editor de Cenários</str>
|
||||
<str id="uiDebug.name">Interface de Depuração</str>
|
||||
<str id="wiki.name">Wiki</str>
|
||||
<str id="debugOptions.name">Opções de Depuração</str>
|
||||
</group>
|
||||
|
||||
<group name="ChartEditor">
|
||||
<group name="CharterSelection" prefix="charterSelection.">
|
||||
<str id="desc">Selecione uma canção para modificar os seus mapas.</str>
|
||||
<str id="acceptSong">Carregue em ACEITAR para escolher uma dificuldade para editar.</str>
|
||||
<str id="acceptVariation">Carregue em ACEITAR para escolher uma variação para editar.</str>
|
||||
<str id="acceptDifficulty">Carregue em ACEITAR para editar o mapa para a dificuldade selecionada.</str>
|
||||
<str id="selectDifficulty">Selecione uma dificuldade para continuar.</str>
|
||||
<str id="newDifficulty">Nova Dificuldade</str>
|
||||
<str id="newDifficultyDesc">Carregue em ACEITAR para criar uma dificuldade nova.</str>
|
||||
<str id="newSong">Nova Canção</str>
|
||||
<str id="newSongDesc">Carregue em ACEITAR para criar uma canção nova.</str>
|
||||
<str id="newVariation">Nova Variação</str>
|
||||
<str id="newSongDesc">Carregue em ACEITAR para criar uma variação nova.</str>
|
||||
</group>
|
||||
|
||||
<group name="ChartCreationScreen" prefix="chartCreation.">
|
||||
<str id="title">A Criar um Mapa Novo</str>
|
||||
<str id="info">Info. do Mapa</str>
|
||||
<str id="diffName">Nome da Dificuldade</str>
|
||||
<str id="stage">Cenário</str>
|
||||
<str id="scrollSpeed">Velocidade das Notas</str>
|
||||
|
||||
<str id="strumLineList">Pistas $* Pelo menos 1 Pista Necessária$</str>
|
||||
<str id="strumLine.format">Pistas - #{0}</str>
|
||||
|
||||
<group name="Warnings" prefix="warnings.">
|
||||
<str id="song-exists-title">Criação de Canção: Erro!</str>
|
||||
<str id="song-exists-body">A canção que está a tentar criar já existe, se a quiser substituir apague a canção primeiro!</str>
|
||||
<str id="chart-exists-title">Criação de Mapa: Erro!</str>
|
||||
<str id="chart-exists-body">O mapa que está a tentar criar já existe, se o quiser substituir apague o mapa primeiro!</str>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="ChartDataScreen" prefix="chartDataScreen.">
|
||||
<str id="title">Propriedades do Mapa</str>
|
||||
<str id="editChartData">Editar Dados do Mapa</str>
|
||||
<str id="stage">Cenário</str>
|
||||
<str id="scrollSpeed">Velocidade das Notas</str>
|
||||
</group>
|
||||
|
||||
<group name="SongPosInfo" prefix="songPosInfo.">
|
||||
<str id="step">Passo: {0}</str>
|
||||
<str id="beat">Batida: {0}</str>
|
||||
<str id="measure">Medida: {0}</str>
|
||||
<str id="bpm">BPM: {0}</str>
|
||||
<str id="timeSignature">Compasso: {0}/{1}</str>
|
||||
</group>
|
||||
|
||||
<group name="CharterEventScreen" prefix="charterEventScreen.">
|
||||
<str id="title-creating">Criar Grupo de Eventos</str>
|
||||
<str id="title-editing">Editar Grupo de Eventos</str>
|
||||
|
||||
<str id="noEvent">Sem Eventos</str>
|
||||
|
||||
<str id="strumLine.format">Pista #{0} ({1})</str>
|
||||
</group>
|
||||
|
||||
<group name="CharterEventTypeSelection" prefix="charterEventTypeSelection.">
|
||||
<str id="title">Escolha um tipo de evento...</str>
|
||||
</group>
|
||||
|
||||
<group name="CharterMetaDataScreen" prefix="charterMetaDataScreen.">
|
||||
<str id="title">Editar Metadados</str>
|
||||
|
||||
<str id="songData">Dados da Canção</str>
|
||||
<str id="songName">Nome da Canção</str>
|
||||
<str id="variation">Variação da Canção</str>
|
||||
<str id="bpm">BPM</str>
|
||||
<str id="timeSignature">Compasso</str>
|
||||
<str id="menusData">Dados dos Menus (Jogo Livre/História)</str>
|
||||
<str id="displayName">Nome Exibido</str>
|
||||
<str id="icon">Ícone</str>
|
||||
<str id="modesAllowed">Modos Permitidos</str>
|
||||
<str id="color">Cor</str>
|
||||
<str id="difficulties">Dificuldades</str>
|
||||
<str id="customValues">Valores Especiais (Avançado)</str>
|
||||
<str id="needsVoices">Necessita Vozes</str>
|
||||
|
||||
<str id="opponentMode">Modo Oponente</str>
|
||||
<str id="coopAllowed">Modo Cooperativo</str>
|
||||
</group>
|
||||
|
||||
<group name="CharterNoteTypesList" prefix="charterNoteTypesList.">
|
||||
<str id="title">Editor da Lista de Tipos de Nota</str>
|
||||
|
||||
<str id="editNoteTypes">Editar Tipos de Nota</str>
|
||||
<str id="editType">Tipo de Nota {0}</str>
|
||||
</group>
|
||||
|
||||
<group name="CharterStrumlineScreen" prefix="charterStrumlineScreen.">
|
||||
<str id="win-title-creating">A Criar a pista {0}</str>
|
||||
<str id="win-title-editing">A Editar as propriedades da pista {0}</str>
|
||||
|
||||
<str id="title-creating">Criar Nova Pista</str>
|
||||
<str id="title-editing">Editar Propriedades da Pista</str>
|
||||
</group>
|
||||
|
||||
<group name="SongCreationScreen" prefix="songCreationScreen.">
|
||||
<str id="win-title">A Criar Nova Canção</str>
|
||||
<str id="win-title-importing">A Importar Canção</str>
|
||||
<str id="title">Info. da Canção</str>
|
||||
|
||||
<str id="instAudio">Ficheiro do Instrumental $* Obrigatório*$</str>
|
||||
<str id="voicesAudio">Ficheiro das Vozes</str>
|
||||
|
||||
<str id="importFrom">Importar de...</str>
|
||||
<str id="importSource">Fonte de Importação:</str>
|
||||
<str id="legacyOrPsych">Psych/Legacy FNF</str>
|
||||
<str id="vslice">V-Slice</str>
|
||||
<str id="vsliceProject">Projeto V-Slice (.fnfc)</str>
|
||||
<str id="importChartFormat">Formato de Mapa</str>
|
||||
<str id="importAudios">Adicionar Audios</str>
|
||||
<str id="songFileName">Nome da canção $* Obrigatório$</str>
|
||||
<str id="songDataFile">Ficheiro Dados/Mapa $* Obrigatório$</str>
|
||||
<str id="songMetaFile">Ficheiro dos Metadados $* Obrigatório$</str>
|
||||
|
||||
<str id="back">Atrás</str>
|
||||
<str id="next">Seguinte</str>
|
||||
</group>
|
||||
|
||||
<group name="StrumlineOptions" prefix="charterStrumLine.">
|
||||
<str id="characters">Personagens</str>
|
||||
<str id="newChar">Nova Personagem</str>
|
||||
<str id="type">Tipo</str>
|
||||
<str id="scrollSpeed">Velocidade das Notas</str>
|
||||
<str id="stagePos">Posição no Cenário</str>
|
||||
<str id="scale">Tamanho</str>
|
||||
<str id="spacing">Espaço</str>
|
||||
<str id="hudPos">Posição HUD (X [Rácio 0-1],Y)</str>
|
||||
<str id="visible">Visível?</str>
|
||||
<str id="useChartScrollSpeed">Usa velocidade global?</str>
|
||||
<str id="vocalSuffix">Sufixo Vocal</str>
|
||||
<str id="keyCount">Número de Teclas</str>
|
||||
</group>
|
||||
|
||||
<group name="ChartEditor" prefix="charter.">
|
||||
<!-- Charter.hx -->
|
||||
<group name="TopBar">
|
||||
<str id="topBar.file">Ficheiro</str>
|
||||
<group name="FileMenu" prefix="file.">
|
||||
<str id="new">Novo</str>
|
||||
<str id="save">Guardar</str>
|
||||
<str id="saveAs">Guardar Como...</str>
|
||||
<str id="saveGlobalEvents">Guardar Eventos Globais</str>
|
||||
<str id="saveGlobalEventsAs">Guardar Eventos Globais Como...</str>
|
||||
<str id="saveNoLocalEvents">Guardar Mapa sem Eventos Locais</str>
|
||||
<str id="saveNoLocalEventsAs">Guardar Mapa sem Eventos Locais Como...</str>
|
||||
<str id="saveMeta">Guardar Metadados</str>
|
||||
<str id="saveMetaAs">Guardar Metadados Como...</str>
|
||||
<str id="exportFnfLegacy">Exportar Para FNF Legacy...</str>
|
||||
<str id="exportPsych">Exportar Para Psych Engine...</str>
|
||||
<str id="exit">Sair</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.edit">Editar</str>
|
||||
<group name="EditMenu" prefix="edit.">
|
||||
<str id="undo">Desfazer</str>
|
||||
<str id="redo">Refazer</str>
|
||||
<str id="copy">Copiar</str>
|
||||
<str id="paste">Colar</str>
|
||||
<str id="cut">Cortar</str>
|
||||
<str id="delete">Apagar</str>
|
||||
<str id="deletestacked">Apagar Notas Empilhadas</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.chart">Mapa</str>
|
||||
<group name="ChartMenu" prefix="chart.">
|
||||
<str id="playtest">Testar</str>
|
||||
<str id="playtestHere">Testar aqui</str>
|
||||
<str id="playtestOpponent">Testar como oponente</str>
|
||||
<str id="playtestOpponentHere">Testar como oponente aqui</str>
|
||||
<str id="enableScripts">Ativar scripts durante teste</str>
|
||||
<str id="editChartData">Editar dados do mapa</str>
|
||||
<str id="editMetadata">Editar info. dos metadados</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.view">Vista</str>
|
||||
<group name="ViewMenu" prefix="view.">
|
||||
<str id="zoomIn">Ampliar</str>
|
||||
<str id="zoomOut">Diminuir</str>
|
||||
<str id="resetZoom">Zoom Padrão</str>
|
||||
<str id="showSectionsSeparator">Mostrar Separador de Secções</str>
|
||||
<str id="showBeatsSeparator">Mostrar Separador de Batidas</str>
|
||||
<str id="rainbowWaveforms">Ondas Arcoíris</str>
|
||||
<str id="lowDetailWaveforms">Ondas de Baixo Detalhe</str>
|
||||
<str id="scrollLeft">Deslocar à Esquerda</str>
|
||||
<str id="scrollRight">Deslocar à Direita</str>
|
||||
<str id="scrollReset">Repor Deslocamento</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.song">Canção</str>
|
||||
<group name="SongMenu" prefix="song.">
|
||||
<str id="goStart">Voltar ao início</str>
|
||||
<str id="goEnd">Avançar até o fim</str>
|
||||
<str id="addOpponentCamera">Adicionar camera no Oponente</str>
|
||||
<str id="addPlayerCamera">Adicionar camera no Jogador</str>
|
||||
<str id="muteInst">Silenciar instrumental</str>
|
||||
<str id="muteVoices">Silenciar vozes</str>
|
||||
</group>
|
||||
|
||||
<group name="BookmarkMenu" prefix="bookmarks.">
|
||||
<str id="addBookmarkHere">Adicionar Marcador Aqui</str>
|
||||
<str id="editBookmarkList">Editar Lista de Marcadores</str>
|
||||
<str id="goTo">Ir para "{0}"</str>
|
||||
<str id="createBookmarkTitle">A Criar Marcador Novo...</str>
|
||||
<str id="createBookmarkName">Nome do Marcador:</str>
|
||||
<str id="createBookmarkColor">Cor do Marcador:</str>
|
||||
<str id="editBookmarkListTitle">Lista de Marcadores</str>
|
||||
<str id="editBookmarksTitle">Editar Marcador</str>
|
||||
<str id="newBookmarkName">Novo Marcador</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.note">Notas</str>
|
||||
<group name="NoteMenu" prefix="note.">
|
||||
<str id="addSustainLength">Alargar Nota</str>
|
||||
<str id="subtractSustainLength">Encurtar Nota</str>
|
||||
<str id="selectAll">Selecionar tudo</str>
|
||||
<str id="selectMeasure">Selecionar medida</str>
|
||||
<str id="editNoteTypesList">Editar Lista de Tipos de Nota</str>
|
||||
</group>
|
||||
<str id="topBar.snap">Ajustes</str>
|
||||
<group name="SnapMenu" prefix="snap.">
|
||||
<str id="increaseSnap">↑ Ajuste de Casa</str>
|
||||
<str id="resetSnap">Repor Ajuste de Casa</str>
|
||||
<str id="decreaseSnap">↓ Ajuste de Casa</str>
|
||||
|
||||
<str id="snap">Ajuste de Casa {0}x</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.playback">Reprodução</str>
|
||||
<group name="PlaybackMenu" prefix="playback.">
|
||||
<str id="play">Tocar/Pausar</str>
|
||||
<str id="speedRaise">↑ Velocidade {0}%</str>
|
||||
<str id="speedReset">Repor Velocidade</str>
|
||||
<str id="speedLower">↓ Velocidade {0}%</str>
|
||||
<str id="sectionBack">Voltar uma secção</str>
|
||||
<str id="sectionForward">Avançar uma secção</str>
|
||||
<str id="sectionStart">Voltar ao ínicio da secção</str>
|
||||
<str id="backStep">Voltar um passo</str>
|
||||
<str id="forwardStep">Avançar um passo</str>
|
||||
<str id="metronome">Metrónomo</str>
|
||||
<str id="visualMetronome">Metrónomo visual</str>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="NoteTypes" prefix="noteTypes.">
|
||||
<str id="default">Nota Normal</str>
|
||||
</group>
|
||||
|
||||
<group name="EventTypes" prefix="events.">
|
||||
<!-- You can add your custom event types here! -->
|
||||
<!-- Just need to do some conversion from the raw name to the id -->
|
||||
<!-- Example: HScript Call -> hscriptCall -->
|
||||
<!-- Example: Change Character -> changeCharacter -->
|
||||
<str id="hscriptCall">Chamar HScript</str>
|
||||
<str id="cameraMovement">Mover Câmara</str>
|
||||
<str id="cameraPosition">Posição da Câmara</str>
|
||||
<str id="addCameraZoom">Adicionar Zoom</str>
|
||||
<str id="cameraModuloChange">Mudar Pulso da Câmara</str>
|
||||
<str id="cameraFlash">Flash da Câmara</str>
|
||||
<str id="bpmChange">Mudar BPM</str>
|
||||
<str id="continuousBpmChange">Mudança contínua de BPM</str>
|
||||
<str id="timeSignatureChange">Mudar Compasso</str>
|
||||
<str id="scrollSpeedChange">Mudança de Velocidade das Notas</str>
|
||||
<str id="altAnimationToggle">Animações Alternativas</str>
|
||||
<str id="playAnimation">Reproduzir Animação</str>
|
||||
</group>
|
||||
|
||||
<group name="StrumlineOptions" prefix="strumLine.">
|
||||
<str id="button-name">Opções ↓</str>
|
||||
|
||||
<str id="hitsounds">Som ao Bater</str>
|
||||
<str id="muteVocals">Silenciar Voz</str>
|
||||
<str id="edit">Editar</str>
|
||||
<str id="delete">Apagar</str>
|
||||
|
||||
<str id="noWaveform">Sem onda</str>
|
||||
</group>
|
||||
|
||||
<str id="createNew">Criar Nova</str>
|
||||
<str id="lock-unlock">Trancar/\nDestrancar</str>
|
||||
|
||||
<str id="info.localEvents">Eventos Locais\n(Apenas Esta Dificuldade)</str>
|
||||
<str id="info.globalEvents">Eventos Globais\n(Todas as Dificuldades)</str>
|
||||
<str id="eventType-local">Evento Local</str>
|
||||
<str id="eventType-global">Evento Global</str>
|
||||
|
||||
<!-- CharterEventAdd.hx -->
|
||||
<str id="addEvent">Adicionar Evento</str>
|
||||
<str id="editEvent">Editar Evento</str>
|
||||
<str id="deleteEvent">Apagar Evento</str>
|
||||
|
||||
<group name="Notifications" prefix="popup.">
|
||||
<str id="savedChartAt">Mapa Guardado em {0}!</str>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="CharacterEditor">
|
||||
<group name="CharacterSelection" prefix="characterSelection.">
|
||||
<str id="acceptFolder">Carregue em ACEITAR para editar esta pasta.</str>
|
||||
<str id="acceptCharacter">Carregue em ACEITAR para editar esta personagem.</str>
|
||||
<str id="newCharacter">Nova Personagem</str>
|
||||
<str id="newCharacterDesc">Carregue em ACEITAR para criar uma personagem nova.</str>
|
||||
<str id="desc">Selecione uma personagem para editar</str>
|
||||
<str id="desc-folder">Selecione uma personagem para editar em {0}</str>
|
||||
</group>
|
||||
|
||||
<group name="CharacterInfoScreen" prefix="characterInfoScreen.">
|
||||
<str id="win-title">A Editar Personagem</str>
|
||||
<str id="title">Editar Info. da Personagem</str>
|
||||
<str id="icon">Ícone</str>
|
||||
<str id="iconColor">Cor do Ícone</str>
|
||||
<str id="singDuration">Duração de Canto</str>
|
||||
<str id="useSingDuration">Usar Duração de Canto?</str>
|
||||
<str id="customValues">Valores Especiais (Avançado)</str>
|
||||
</group>
|
||||
|
||||
<group name="CharacterEditor" prefix="characterEditor.">
|
||||
<group name="TopBar">
|
||||
<str id="topBar.file">Ficheiro</str>
|
||||
<group name="FileMenu" prefix="file.">
|
||||
<str id="new">Novo</str>
|
||||
<str id="save">Guardar</str>
|
||||
<str id="saveAs">Guardar Como...</str>
|
||||
<str id="exit">Sair</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.edit">Editar</str>
|
||||
<group name="EditMenu" prefix="edit.">
|
||||
<str id="copyOffset">Copiar Posição</str>
|
||||
<str id="pasteOffset">Colar Posição</str>
|
||||
<str id="undo">Desfazer</str>
|
||||
<str id="redo">Refazer</str>
|
||||
<str id="editInfo">Editar informação</str>
|
||||
<str id="editSprite">Editar imagem fonte</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.offset">Posição</str>
|
||||
<group name="OffsetsMenu" prefix="offset.">
|
||||
<str id="moveLeft">Mover Para a Esquerda</str>
|
||||
<str id="moveUp">Mover Para Cima</str>
|
||||
<str id="moveDown">Mover Para Baixo</str>
|
||||
<str id="moveRight">Mover Para a Direita</str>
|
||||
<str id="moveExtraLeft">Mover Mais Para a Esquerda</str>
|
||||
<str id="moveExtraUp">Mover Mais Para Cima</str>
|
||||
<str id="moveExtraDown">Mover Mais Para Baixo</str>
|
||||
<str id="moveExtraRight">Mover Mais Para a Direita</str>
|
||||
<str id="dragOffsetsMouse">Arrastar Posição Com o Rato?</str>
|
||||
<str id="clearOffsets">Limpar Posições</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.stage">Cenário</str>
|
||||
<group name="StageMenu" prefix="stage.">
|
||||
<str id="useStage">Usar "{0}"</str>
|
||||
<str id="useNone">Não Usar Cenário</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.view">Vista</str>
|
||||
<group name="ViewMenu" prefix="view.">
|
||||
<str id="zoomIn">Ampliar</str>
|
||||
<str id="zoomOut">Diminuir</str>
|
||||
<str id="resetZoom">Zoom Padrão</str>
|
||||
<str id="charHitbox">"Hitbox" da Personagem?</str>
|
||||
<str id="charCam">Câmara da Personagem?</str>
|
||||
<str id="axis">Eixo XY?</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.animation">Animação</str>
|
||||
<group name="AnimationMenu" prefix="animation.">
|
||||
<str id="playAnim">Reproduzir Animação</str>
|
||||
<str id="stopAnim">Parar Animação</str>
|
||||
<str id="changeAnimUp">Mudar Animação ↑</str>
|
||||
<str id="changeAnimDown">Mudar Animação ↓</str>
|
||||
<str id="playAnimOnOffset">Reproduzir Animação Reposicionada?</str>
|
||||
</group>
|
||||
|
||||
<group name="CharacterPropertiesWindow" prefix="characterProperties.">
|
||||
<str id="position">Posição (X, Y)</str>
|
||||
<str id="scale">Tamanho</str>
|
||||
<str id="editInfo">Editar Info.</str>
|
||||
<str id="editSprite">Editar Imagem</str>
|
||||
<str id="camPosition">Posição da Câmara (X, Y)</str>
|
||||
<str id="charFlipped">Espelhado?</str>
|
||||
<str id="antialiased">Suavizado?</str>
|
||||
<str id="testCharAs">Testar Como...</str>
|
||||
<str id="charDesign">Desenhada Como...</str>
|
||||
</group>
|
||||
|
||||
<group name="CharacterAnimButton" prefix="characterAnim.">
|
||||
<str id="defaultAnimName">Nova Animação</str>
|
||||
<str id="name">Nome</str>
|
||||
<str id="anim">Animação</str>
|
||||
<str id="position">Posição (X, Y)</str>
|
||||
<str id="fps">FPS</str>
|
||||
<str id="indices">Índices (Frames)</str>
|
||||
</group>
|
||||
|
||||
<group name="CharacterSpriteScreen" prefix="characterSpriteScreen.">
|
||||
<str id="win-title">Editar imagem da personagem</str>
|
||||
<str id="charImageFile">Imagem da personagem $* Obrigatório$</str>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="CharacterCreationScreen" prefix="characterCreationScreen.">
|
||||
<str id="win-title">A Criar uma Personagem Nova</str>
|
||||
<str id="charName">Nome da Personagem $* Required$</str>
|
||||
<str id="charImgName">Imagem $* Obrigatória$</str>
|
||||
|
||||
<group name="Warnings" prefix="warnings.">
|
||||
<str id="char-exists-title">Criação da Personagem: Erro!</str>
|
||||
<str id="char-exists-body">A personagem que está a tentar criar já existe, se quiser substituir apague a personagem primeiro!</str>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="AlphabetEditor" prefix="editor.alphabet.">
|
||||
<group name="AlphabetSelection" prefix="selection.">
|
||||
<str id="acceptTypeface">Carregue em ACEITAR para editar este tipo de letra.</str>
|
||||
<str id="newTypeface">Novo Tipo de Letra</str>
|
||||
<str id="newTypefaceDesc">Carregue em ACEITAR para criar um tipo de letra novo.</str>
|
||||
<str id="desc">Selecione um tipo de letra para editar</str>
|
||||
|
||||
<group name="Warnings" prefix="warnings.">
|
||||
<str id="notImplemented-title">Novo Tipo de Letra: Função Não Implementada!</str>
|
||||
<str id="notImplemented-body">Esta função ainda não foi implementada. Por favor espere por mais atualizações até ser implementada.\n\n\n- Codename Crew (Equipa Codename)</str>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="AlphabetEditor">
|
||||
<group name="TopBar">
|
||||
<str id="topBar.file">Ficheiro</str>
|
||||
<group name="FileMenu" prefix="file.">
|
||||
<str id="new">Novo</str>
|
||||
<str id="save">Guardar</str>
|
||||
<str id="saveAs">Guardar Como...</str>
|
||||
<str id="exit">Sair</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.edit">Editar</str>
|
||||
<group name="EditMenu" prefix="edit.">
|
||||
<str id="undo">Desfazer</str>
|
||||
<str id="redo">Refazer</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.glyph">Glifo</str>
|
||||
<group name="GlyphMenu" prefix="glyph.">
|
||||
<str id="newGlyph">Novo Glifo</str>
|
||||
<str id="editGlyph">Editar Glifo</str>
|
||||
<str id="deleteGlyph">Apagar Glifo</str>
|
||||
<str id="deleteCurGlyph">Apagar Glifo Atual</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.offset">Posição</str>
|
||||
<group name="OffsetsMenu" prefix="offset.">
|
||||
<str id="moveLeft">Mover Para a Esquerda</str>
|
||||
<str id="moveUp">Mover Para Cima</str>
|
||||
<str id="moveDown">Mover Para Baixo</str>
|
||||
<str id="moveRight">Mover Para a Direita</str>
|
||||
<str id="moveExtraLeft">Mover Mais Para a Esquerda</str>
|
||||
<str id="moveExtraUp">Mover Mais Para Cima</str>
|
||||
<str id="moveExtraDown">Mover Mais Para Baixo</str>
|
||||
<str id="moveExtraRight">Mover Mais Para a Direita</str>
|
||||
<str id="clearOffsets">Limpar Posições</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.view">Vista</str>
|
||||
<group name="ViewMenu" prefix="view.">
|
||||
<str id="zoomIn">Ampliar</str>
|
||||
<str id="zoomOut">Diminuir</str>
|
||||
<str id="resetZoom">Zoom Padrão</str>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="StageEditor">
|
||||
<group name="StageSelection" prefix="stageSelection.">
|
||||
<str id="desc">Selecione um cenário para editar. Cenários HSCRIPT PURO não são suportadas.</str>
|
||||
<str id="acceptStage">Carregue em ACEITAR para editar este cenário.</str>
|
||||
<str id="newStage">Novo Cenário</str>
|
||||
<str id="acceptNewStage">Carregue em ACEITAR para criar um cenário novo.</str>
|
||||
</group>
|
||||
|
||||
<group name="StageEditor" prefix="stageEditor.">
|
||||
<group name="TopBar">
|
||||
<str id="topBar.file">Ficheiro</str>
|
||||
<group name="FileMenu" prefix="file.">
|
||||
<str id="save">Guardar</str>
|
||||
<str id="saveAs">Guardar Como...</str>
|
||||
<str id="exit">Sair</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.edit">Editar</str>
|
||||
<group name="EditMenu" prefix="edit.">
|
||||
<str id="undo">Desfazer</str>
|
||||
<str id="redo">Refazer</str>
|
||||
<str id="editStageInfo">Editar Info. do Cenário</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.select">Seleção</str>
|
||||
<group name="SelectionMenu" prefix="select.">
|
||||
<str id="all">Selecionar Tudo</str>
|
||||
<str id="deselect">Desselecionar</str>
|
||||
<str id="inverse">Inverter Seleção</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.view">Vista</str>
|
||||
<group name="ViewMenu" prefix="view.">
|
||||
<str id="zoomIn">Ampliar</str>
|
||||
<str id="zoomOut">Diminuir</str>
|
||||
<str id="zoomReset">Zoom Padrão</str>
|
||||
<str id="focusDad">Focar no Oponente</str>
|
||||
<str id="focusGF">Focar em GF</str>
|
||||
<str id="focusBF">Focar em BF</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.editor">Editor</str>
|
||||
<group name="EditorMenu" prefix="editor.">
|
||||
<str id="showCharacters">Mostrar Personagens</str>
|
||||
</group>
|
||||
|
||||
<group name="StageSpriteScreen" prefix="stageSpriteScreen.">
|
||||
<str id="win-title">Editar imagem do cenário </str>
|
||||
<str id="stageImageFile">Imagem do Cenário $* Obrigatória$</str>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="StageCreationScreen" prefix="stageCreationScreen.">
|
||||
<str id="win-title">A Criar um Cenário Novo</str>
|
||||
<str id="title">Info. do Cenário</str>
|
||||
<str id="stageName">Nome do Cenário</str>
|
||||
<str id="stagePath">Caminho do Cenário</str>
|
||||
|
||||
<group name="Warnings" prefix="warnings.">
|
||||
<str id="stage-exists-title">Criação de Cenário: Erro!</str>
|
||||
<str id="stage-exists-body">O cenário que está a tentar criar já existe, se quiser substituir apague o cenário primeiro!</str>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="StageInfoScreen" prefix="stageInfoScreen">
|
||||
<str id="win-title">A Editar Info. do Cenário: "{0}"</str>
|
||||
<str id="title">Info. do Cenário</str>
|
||||
<str id="stageName">Nome do Cenário</str>
|
||||
<str id="spritePath">Caminho do Sprite\n(Requer Recarregamento)</str>
|
||||
<str id="startCamPos">Posição inicial da Câmara (X, Y)</str>
|
||||
<str id="zoom">Zoom</str>
|
||||
<str id="customAttributes">Atributos Especiais</str>
|
||||
</group>
|
||||
|
||||
<group name="StageElementEditScreen" prefix="stageElementEditScreen.">
|
||||
<str id="win-character-title">A Editar Personagem: "{0}"</str>
|
||||
<str id="win-sprite-title">A Editar Sprite: "{0}"</str>
|
||||
<str id="win-title">A Editar XML <{0} /></str>
|
||||
|
||||
<str id="character-title">Dados da Personagem</str>
|
||||
<str id="sprite-title">Dados do Sprite</str>
|
||||
<str id="title">Dados do XML</str>
|
||||
|
||||
<str id="elementName">Nome do Elemento</str>
|
||||
<str id="nameID">Nome Identificador</str>
|
||||
<str id="imageFile">Imagem (WIP: precisa recarregar)\nEm (${stage.spritesParentFolder})</str>
|
||||
<str id="scroll">Scroll {0}</str> <!-- it's "scroll" here because "deslocamento" is too big -->
|
||||
<str id="scale">Tamanho {0}</str>
|
||||
<str id="camera">Câmara {0}</str>
|
||||
<str id="spacing">Espaçamento (X, Y)</str>
|
||||
<str id="skew">Incline {0}</str>
|
||||
<str id="alpha">Opacidade</str>
|
||||
<str id="angle">Angulo</str>
|
||||
<str id="zoomFactor">Fator de Zoom</str> <!-- same as for scroll, "fator de ampliação" took too much space -->
|
||||
<str id="positionName">Nome de Posição</str>
|
||||
<str id="flipX">Espelhar X</str>
|
||||
<str id="antialiasing">"Antialiasing"</str>
|
||||
<str id="highMemory">Alta Memória</str>
|
||||
<str id="lowMemory">Baixa Memória</str>
|
||||
<str id="attributes">Atributos</str>
|
||||
<str id="transformPreview">Pré-visualização:</str>
|
||||
<str id="animations">Animações</str>
|
||||
|
||||
<str id="animType">Tipo de Animação</str>
|
||||
<group name="AnimTypeDropdown" prefix="animType.">
|
||||
<str id="none">NENHUM</str>
|
||||
<str id="beat">EM BATIDA</str>
|
||||
<str id="loop">REPETIR</str>
|
||||
</group>
|
||||
<str id="tipCustomProperties">Dica: Para aceder a mais dados,\nSegure em Shift quando Editar</str>
|
||||
</group>
|
||||
|
||||
<group name="StageXMLEditScreen" prefix="stageXMLEditScreen.">
|
||||
<str id="win-title">A Editar XML de {0}</str>
|
||||
<str id="title">Dados do XML</str>
|
||||
<str id="attributes">Atributos</str>
|
||||
</group>
|
||||
|
||||
<str id="stageCharacters.requiredPosition">Esta posição é necessária em cenários!</str>
|
||||
<str id="stageCharacters.noDeleteGirlfriend">Não pode apagar a Girlfriend</str>
|
||||
|
||||
<group name="StageElement" prefix="stageElement.">
|
||||
<str id="scale">Tamanho: {0}, {1}</str>
|
||||
<str id="scroll">Deslocamento: {0}, {1}</str>
|
||||
</group>
|
||||
|
||||
<group name="StageSprites" prefix="stageSprites.">
|
||||
<str id="win-title">Sprites do Cenário</str>
|
||||
<str id="sprite">Sprite</str>
|
||||
<str id="box">Caixa</str>
|
||||
<str id="character">Personagem</str>
|
||||
<str id="warnings.not-implemented">Criar caixas ainda não foi implementado!</str>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="PlayTesting" prefix="playtesting.">
|
||||
<str id="chartPlaytesting" notrim="true"> (Teste de mapa)</str>
|
||||
<str id="exitGame">Sair do Jogo</str>
|
||||
<str id="exitToMenu">Sair Para Menu</str>
|
||||
<str id="saveAndExitGame">Guardar e Sair do Jogo</str>
|
||||
<str id="saveAndExitToMenu">Guardar e Sair Para Menu</str>
|
||||
<str id="cancel">Cancelar</str>
|
||||
|
||||
<str id="warningTitle">MUDANÇAS NÃO GUARDADAS!</str>
|
||||
<str id="warningDesc">Quaisquer mudanças serão *perdidas* se não as guardar. (Não serão recuperáveis)\n\n\nGostaria de Cancelar?</str>
|
||||
</group>
|
||||
|
||||
<group name="SaveWarning" prefix="saveWarning.">
|
||||
<str id="warningTitle">Mudanças não guardadas!</str>
|
||||
<str id="warningDesc">Quaisquer mudanças serão perdidas se não as guardar. (Não serão recuperáveis)\n\n\nGostaria de Cancelar?</str>
|
||||
|
||||
<str id="exitGame">Sair do Jogo</str>
|
||||
<str id="exitToMenu">Sair Para Menu</str>
|
||||
<str id="saveAndExitGame">Guardar e Sair do Jogo</str>
|
||||
<str id="saveAndExitToMenu">Guardar e Sair Para Menu</str>
|
||||
<str id="cancel">Cancelar</str>
|
||||
</group>
|
||||
|
||||
<group name="ModConfigWarning" prefix="modConfigWarning.">
|
||||
<str id="warningTitle">Configuração da pasta do mod em falta!</str>
|
||||
<str id="warningDesc">Está a faltar um ficheiro de configurações ao seu mod!\n\nGostaria de criar um automaticamente?\n\n(PS: Se este mod não for seu, por favor desative o Modo de desenvolvedor para fazer esta notificação parar de aparecer.)</str>
|
||||
|
||||
<str id="createdTitle">Config. de mod criada!</str>
|
||||
<str id="createdDesc">As configurações do seu mod foram criadas em {0}!</str>
|
||||
</group>
|
||||
</language>
|
||||
@@ -0,0 +1,104 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<language>
|
||||
<group name="PlayState">
|
||||
<str id="game.score">Pontos:{0}</str>
|
||||
<str id="game.misses">Erros:{0}</str>
|
||||
<str id="game.comboBreaks">Quebras de Combo:{0}</str>
|
||||
<str id="game.accuracy">Precisão:{0} - {1}</str>
|
||||
<str id="game.combo">Combo:{0}</str>
|
||||
|
||||
<str id="game.rating.[N/A]">[N/A]</str>
|
||||
<str id="game.rating.F">F</str>
|
||||
<str id="game.rating.E">E</str>
|
||||
<str id="game.rating.D">D</str>
|
||||
<str id="game.rating.C">C</str>
|
||||
<str id="game.rating.B">B</str>
|
||||
<str id="game.rating.A">A</str>
|
||||
<str id="game.rating.S">S</str>
|
||||
<str id="game.rating.S++">S++</str>
|
||||
</group>
|
||||
|
||||
<group name="StoryMenu">
|
||||
<str id="story.score">PONTUAÇÃO DA SEMANA:{0}</str>
|
||||
<str id="story.tracks">FAIXAS</str>
|
||||
</group>
|
||||
|
||||
<group name="Freeplay">
|
||||
<str id="freeplay.score">RECORDE PESSOAL:{0}</str>
|
||||
<str id="freeplay.solo">Solo</str>
|
||||
<str id="freeplay.opponentMode">Modo Oponente</str>
|
||||
<str id="freeplay.coopMode">Modo Co-Op</str>
|
||||
<str id="freeplay.coopModeSwitched">Modo Co-Op (Trocado)</str>
|
||||
</group>
|
||||
|
||||
<group name="Pause">
|
||||
<group name="PauseOptions">
|
||||
<str id="pause.resume">Continuar</str>
|
||||
<str id="pause.restartSong">Recomeçar Canção</str>
|
||||
<str id="pause.changeControls">Mudar Controlos</str>
|
||||
<str id="pause.changeOptions">Opções</str>
|
||||
<str id="pause.exitToMenu">Sair para menu</str>
|
||||
<str id="pause.exitToCharter">Sair para editor</str>
|
||||
<str id="pause.resumeCutscene">Resumir Cena</str>
|
||||
<str id="pause.skipCutscene">Saltar Cena</str>
|
||||
<str id="pause.restartCutscene">Recomeçar Cena</str>
|
||||
</group>
|
||||
|
||||
<str id="pause.deathCounter">Tomates azuis: {0}</str>
|
||||
<str id="pause.coopMode">MODO CO-OP</str>
|
||||
<str id="pause.opponentMode">MODO OPONENTE </str>
|
||||
</group>
|
||||
|
||||
<group name="Credits">
|
||||
<group name="CreditsCodename">
|
||||
<str id="credits.mainDev" notrim="true"> *- Membro público dos Desenvolvedores!*</str>
|
||||
<str id="credits.totalContributions">Contribuições Totais: ~{0}~ / *{1}* (~{2}%~) - Selecione para abrir a sua conta GitHub</str>
|
||||
<str id="credits.downloadingList">A Descarregar Lista...</str>
|
||||
<str id="credits.allContributors">Todos os contribuidores! Carregue em REINICIAR para atualizar a lista (Uma vez a cada 2 minutos).</str>
|
||||
</group>
|
||||
<group name="CreditsMain">
|
||||
<str id="credits.name">Créditos</str>
|
||||
<str id="credits.madePossible">As pessoas que fizeram isto possível!</str>
|
||||
<str id="credits.selectCodename">Selecione isto para ver todos os contribuidores de Codename Engine!</str>
|
||||
<str id="credits.selectBase">Selecione isto para abrir a página itch.io do jogo original para doar!</str>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="Mods">
|
||||
<str id="mods.disableMods">Desativar Mods</str>
|
||||
</group>
|
||||
|
||||
<group name="MainMenu">
|
||||
<str id="mainMenu.commit">Commit: {0} ({1})</str>
|
||||
<str id="mainMenu.openMods">[{0}] Abrir menu de mods</str>
|
||||
</group>
|
||||
|
||||
<group name="Updater">
|
||||
<group name="UpdateAvailable">
|
||||
<str id="updateAvailable.title">NOVA ATUALIZAÇÃO</str>
|
||||
<str id="updateAvailable.install">INSTALAR</str>
|
||||
<str id="updateAvailable.skip">SALTAR</str>
|
||||
</group>
|
||||
<group name="UpdateScreen">
|
||||
<str id="updateScreen.general-1">A Preparar a instalação...</str>
|
||||
<str id="updateScreen.part-1">A Criar a pasta de instalação e a limpar ficheiros antigos...</str>
|
||||
|
||||
<str id="updateScreen.general-2">A Transferir ficheiros...</str>
|
||||
<str id="updateScreen.part-2">A Transferir ficheiro {0}</str>
|
||||
|
||||
<str id="updateScreen.general-3">A transferir executável novo...</str>
|
||||
<str id="updateScreen.part-3">A Transferir {0}</str>
|
||||
|
||||
<str id="updateScreen.general-4">A instalar ficheiros novos...</str>
|
||||
<str id="updateScreen.part-4">A Instalar {0}</str>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="Difficulties">
|
||||
<str id="diff.easy">Fácil</str>
|
||||
<str id="diff.normal">Normal</str>
|
||||
<str id="diff.hard">Difícil</str>
|
||||
<str id="diff.erect">Ereto</str>
|
||||
<str id="diff.nightmare">Pesadelo</str>
|
||||
</group>
|
||||
</language>
|
||||
@@ -0,0 +1,208 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<language>
|
||||
<str id="optionsMenu.desc-missing">Sem descrição</str>
|
||||
|
||||
<group name="OptionsMenu">
|
||||
<str id="optionsMenu.advanced">Avançado</str>
|
||||
<str id="optionsMenu.header.title">Opções</str>
|
||||
<str id="optionsMenu.header.desc">Selecione uma categoria para continuar.</str>
|
||||
|
||||
<str id="optionsTree.controls-name">Controlos</str>
|
||||
<str id="optionsTree.controls-desc">Mude os Controlos para Jogador 1 e Jogador 2!</str>
|
||||
|
||||
<str id="optionsTree.gameplay-name">Jogo</str>
|
||||
<str id="optionsTree.gameplay-desc">Mude as opções como "Downscroll", Velocidade das notas, Indecência...</str>
|
||||
<str id="optionsTree.gameplay.advanced-desc">Mude as opções mais avançadas como Transmissão de áudio...</str>
|
||||
|
||||
<str id="optionsTree.appearance-name">Aparência</str>
|
||||
<str id="optionsTree.appearance-desc">Mude as opções de aparência como Luzes intermitentes...</str>
|
||||
<str id="optionsTree.appearance.advanced-desc">Mude as opções mais avançadas como Sprites apenas em VRAM, "Antialiasing", "Shaders"</str>
|
||||
|
||||
<str id="optionsTree.language-name">Idioma</str>
|
||||
<str id="optionsTree.language-desc">Mude o idioma que o jogo usa.</str>
|
||||
|
||||
<str id="optionsTree.miscellaneous-name">Outras</str>
|
||||
<str id="optionsTree.miscellaneous-desc">Use este menu para apagar dados ou definições.</str>
|
||||
|
||||
<str id="optionsTree.debug-name">Opções de Depuração</str>
|
||||
<str id="optionsTree.debug-desc">Opções de Depuração para o Modo de Desenvolvedor.</str>
|
||||
</group>
|
||||
|
||||
<group name="KeybindOptions" prefix="KeybindsOptions.">
|
||||
<str id="left">Esquerda</str>
|
||||
<str id="down">Baixo</str>
|
||||
<str id="up">Cima</str>
|
||||
<str id="right">Direita</str>
|
||||
|
||||
<str id="category.notes">Notas</str>
|
||||
|
||||
<str id="category.ui">Interface</str>
|
||||
<group name="ui" prefix="ui.">
|
||||
<str id="accept">Aceitar</str>
|
||||
<str id="back">Cancelar</str>
|
||||
<str id="reset">Reiniciar</str>
|
||||
<str id="pause">Pausa</str>
|
||||
<str id="changeMode">Mudar Modo</str>
|
||||
</group>
|
||||
|
||||
<str id="category.engine">Codename Engine</str>
|
||||
<group name="engine" prefix="engine.">
|
||||
<str id="switchMod">Trocar Mod</str>
|
||||
<str id="fpsCounter">Contador de FPS</str>
|
||||
</group>
|
||||
|
||||
<str id="category.volume">Volume</str>
|
||||
<str id="volume.up">Subir</str>
|
||||
<str id="volume.down">Baixar</str>
|
||||
<str id="volume.mute">Silenciar</str>
|
||||
|
||||
<str id="category.developer">Desenvolvedor</str>
|
||||
<group name="developer" prefix="developer.">
|
||||
<str id="devMenus">Menus Dev.</str>
|
||||
<str id="openConsole">Consola</str>
|
||||
<str id="reloadState">Recarregar</str>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="AppearanceOptions" prefix="AppearanceOptions.">
|
||||
<str id="framerate-name">FPS</str>
|
||||
<str id="framerate-desc">Quadros Por Segundo, se quiser. Explica-se a sí próprio, certo?</str>
|
||||
|
||||
<str id="flashingMenu-name">Luzes Intermitentes</str>
|
||||
<str id="flashingMenu-desc">Se desmarcado, irá desativar as luzes intermitentes quando seleciona algo no Menu Principal, e outras serão abrandadas.</str>
|
||||
|
||||
<str id="colorHealthBar-name">Barra de Vida Colorida</str>
|
||||
<str id="colorHealthBar-desc">Se desmarcado, o jogo irá usar a barra vermelha/verde de versões FNF pré-semana 7.</str>
|
||||
|
||||
<str id="week6PixelPerfect-name">Efeito "Pixel Perfect"</str>
|
||||
<str id="week6PixelPerfect-desc">se marcado, a Semana 6 ou outros cenários "pixel" terão um efeito "pixel perfect", alinhando todos os pixeis ao ecrã.</str>
|
||||
|
||||
<group name="AppearanceOptionsAdvanced" prefix="Advanced.">
|
||||
<str id="quality-name">Qualidade</str>
|
||||
<str id="quality-desc">Modos de qualidade para escolher, "BAIXA" = Desativa todos os efeitos visuais pesados para um jogo mais suave, "ALTA" = Ativa todos os efeitos visuais, ao custo do desempenho, "CUSTOMIZADA" = Permite opções especiais, disponíveis em "Advançado".</str>
|
||||
<str id="quality-low">BAIXA</str>
|
||||
<str id="quality-high">ALTA</str>
|
||||
<str id="quality-custom">CUSTOMIZADA</str>
|
||||
|
||||
<str id="antialiasing-name">"Antialiasing"</str>
|
||||
<str id="antialiasing-desc">Se desmarcado, irá remover "antialiasing" a todos os sprites. Poderá aumentar o desempenho ao custo de sprites menos suaves.</str>
|
||||
|
||||
<str id="lowMemoryMode-name">Memória baixa</str>
|
||||
<str id="lowMemoryMode-desc">Se marcado, irá remover certos elementos de fundo para reduzir o uso de memória.</str>
|
||||
|
||||
<str id="gameplayShaders-name">"Shaders"</str>
|
||||
<str id="gameplayShaders-desc">If desmarcado, "Shaders" (efeitos visuais como a Aberração cromática de "Thorns") não serão carregadas; poderá ser útil em dispositivos fracos.</str>
|
||||
|
||||
<str id="gpuOnlyBitmaps-name">Sprites só em VRAM</str>
|
||||
<str id="gpuOnlyBitmaps-desc">Se marcado, irá apenas guardar os bitmaps na GPU, libertando IMENSA memória (EXPERIMENTAL). Desmarcar isto irá consumir muita memória, especialmente em sprites maiores. Se não tiver a certeza, deixe isto marcado.</str>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="GameplayOptions" prefix="GameplayOptions.">
|
||||
<str id="downscroll-name">"Downscroll"</str>
|
||||
<str id="downscroll-desc">Se marcado, notas irão de cima para baixo em vez de baixo para cima, como se estivessem a cair.</str>
|
||||
|
||||
<str id="ghostTapping-name">Toques Fantasma</str>
|
||||
<str id="ghostTapping-desc">Se desmarcado, bater em teclas que não tem uma nota conta como erro.</str>
|
||||
|
||||
<str id="naughtyness-name">Indecência</str>
|
||||
<str id="naughtyness-desc">Se desmarcado, irá censurar as cenas da Semana 7, ou mais.</str>
|
||||
|
||||
<str id="camZoomOnBeat-name">Zoom na Batida</str>
|
||||
<str id="camZoomOnBeat-desc">Se desmarcado. irá parar a câmara de ampliar a cada 4 batidas.</str>
|
||||
|
||||
<str id="autoPause-name">Auto Pausa</str>
|
||||
<str id="autoPause-desc">Se marcado, mudar de janela pausará o jogo.</str>
|
||||
|
||||
<str id="volumeMusic-name">Volume da Música</str>
|
||||
<str id="volumeMusic-desc">Muda apenas o volume da música em vez de tudo.</str>
|
||||
|
||||
<str id="volumeSFX-name">Volume dos SFX</str>
|
||||
<str id="volumeSFX-desc">Muda apenas o volume dos efeitos sonoros em vez de tudo.</str>
|
||||
|
||||
<str id="songOffset-name">Atraso da Música</str>
|
||||
<str id="songOffset-desc">Muda a posição da música relativamente às notas.</str>
|
||||
|
||||
<group name="GameplayOptionsAdvanced" prefix="Advanced.">
|
||||
<str id="windowSize-name">Tamanho da Janela</str>
|
||||
<str id="windowSize-desc">...</str>
|
||||
|
||||
<str id="streamedMusic-name">Transmissão de Música</str>
|
||||
<str id="streamedMusic-desc">Se marcado, músicas serão transmitidas enquanto tocam, libertando IMENSA memória com o custo de maior uso de CPU se mais sons estiverem a ser transmitidos ao mesmo tempo (EXPERIMENTAL). Desmarcar isto irá consumir muita memória, especialmente em músicas maiores. Se não tiver a certeza, deixe marcado.</str>
|
||||
|
||||
<str id="streamedVocals-name">Transmissão de Vozes</str>
|
||||
<str id="streamedVocals-desc">Se marcado, vozes também serão transmitidas enquanto tocam se "Transmissão de Música" estiver ativada. Irá impactar o desempenho se a canção usar muitas vozes (EXPERIMENTAL). Se não tiver a certeza, deixe marcado.</str>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group name="LanguageOptions" prefix="LanguageOptions.">
|
||||
<str id="language-name">Idioma</str>
|
||||
<str id="language-desc">Idioma por {0} (Versão: {1})</str>
|
||||
</group>
|
||||
|
||||
<group name="MiscOptions" prefix="MiscOptions.">
|
||||
<str id="forceCrash-name">Forçar "Crash"</str>
|
||||
<str id="forceCrash-desc">Selecione esta opção para forçar o jogo a encravar e travar.</str>
|
||||
|
||||
<str id="betaUpdates-name">Atualizações "Nightly"</str>
|
||||
<str id="betaUpdates-desc">Se marcado, também irá incluir versões "nightly" (a versão mais recente disponível no repositório de GitHub) na verificação de atualizações.</str>
|
||||
|
||||
<str id="checkForUpdates-name">Verificar Atualizações</str>
|
||||
<str id="checkForUpdates-desc">Selecione esta opção para verificar se existem atualizações novas.</str>
|
||||
<str id="checkForUpdates-noUpdateFound">Nenhuma atualização encontrada.</str>
|
||||
|
||||
<str id="devMode-name">Modo Desenvolvedor</str>
|
||||
<str id="devMode-desc">Se marcado, irá poder aceder funções de desenvolvedor como certas teclas, editores, opções de desenvolvedor, recarregamento de estados, consola e mais.</str>
|
||||
|
||||
<str id="allowConfigWarning-name">Aviso de Modpacks</str>
|
||||
<str id="allowConfigWarning-desc">Se marcado, um aviso no início do jogo aparecerá se houver problemas com o modpack, como configurações em falta, versões incompatíveis e mais.</str>
|
||||
|
||||
<str id="resetSaveData-name">Apagar Dados</str>
|
||||
<str id="resetSaveData-desc">Selecione esta opção para apagar todos os dados. Isto irá remover todos os seus recordes.</str>
|
||||
</group>
|
||||
|
||||
<group name="DebugOptions" prefix="DebugOptions.">
|
||||
<str id="title">Opções de Depuração</str>
|
||||
<str id="desc">Use este menu para ativar ou desativar opções de depuração.</str>
|
||||
|
||||
<str id="showConsole-name">Mostrar Consola</str>
|
||||
<str id="showConsole-desc">Selecione isto para mostrar a consola, que contém registos acerca do jogo.</str>
|
||||
|
||||
<str id="editorsResizable-name">Editores Adaptáveis</str>
|
||||
<str id="editorsResizable-desc">Se marcado, irá permitir que os editores utilizem resoluções acima da base 1280x720 de FNF (permitindo mais detalhe e espaço...)</str>
|
||||
|
||||
<str id="bypassEditorsResize-name">Sem Tamanho Mínimo</str>
|
||||
<str id="bypassEditorsResize-desc">Desativa o limite de resolução minimo dos editores (Requer que "Editores Adaptáveis" esteja marcado).</str>
|
||||
|
||||
<str id="editorSFX-name">Sons de Editor</str>
|
||||
<str id="editorSFX-desc">Se marcado, tocará efeitos sonoros nos editores (ex: ao carregar em caixas...)</str>
|
||||
|
||||
<str id="editorCharterPrettyPrint-name">Mapas Legíveis</str>
|
||||
<str id="editorCharterPrettyPrint-desc">Se marcado, os ficheiros guardados no editor de mapas serão formatados para serem fácilmente legíveis.</str>
|
||||
|
||||
<str id="editorCharacterPrettyPrint-name">Personagens Legíveis</str>
|
||||
<str id="editorCharacterPrettyPrint-desc">Se marcado, os ficheiros guardados no editor de personagens serão formatados para serem fácilmente legíveis.</str>
|
||||
|
||||
<str id="editorStagePrettyPrint-name">Cenários Legíveis</str>
|
||||
<str id="editorStagePrettyPrint-desc">Se marcado, os ficheiros guardados no editor de cenários serão formatados para serem fácilmente legíveis.</str>
|
||||
|
||||
<str id="intensiveBlur-name">Desfoque Intensivo</str>
|
||||
<str id="intensiveBlur-desc">Se marcado, irá usar um desfoque mais intensivo. Parece melhor, mas poderá ser mais lento.</str>
|
||||
|
||||
<str id="charterAutoSaves-name">Gravação Automática</str>
|
||||
<str id="charterAutoSaves-desc">Se marcado, irá guardar ficheiros de editor automáticamente, com as definições listadas abaixo.</str>
|
||||
|
||||
<str id="charterAutoSaveTime-name">Tempo de Gravação</str>
|
||||
<str id="charterAutoSaveTime-desc">Isto controla com que frequência o editor gravará o ficheiro (em segundos...)</str>
|
||||
|
||||
<str id="charterAutoSaveWarningTime-name">Tempo de Aviso</str>
|
||||
<str id="charterAutoSaveWarningTime-desc">Isto controla com que antecedência o editor irá avisá-lo antes de guardar (em segundos..., 0 para desativar)</str>
|
||||
|
||||
<str id="charterAutoSavesSeparateFolder-name">Pasta de Gravações</str>
|
||||
<str id="charterAutoSavesSeparateFolder-desc">Se marcado, irá guardar os ficheiros numa pasta separada com a data em vez de substituir o ficheiro atual. (song/autosaves/)</str>
|
||||
|
||||
<str id="songOffsetAffectEditors-name">Atraso no Mapeador</str>
|
||||
<str id="songOffsetAffectEditors-desc">Se marcado, irá ativar o Atraso da Música no Editor de Mapas, também.</str>
|
||||
</group>
|
||||
|
||||
</language>
|
||||
@@ -0,0 +1,3 @@
|
||||
name="Português"
|
||||
credits="Bitto1070"
|
||||
version="1.0.0"
|
||||
@@ -12,7 +12,7 @@ function create() {
|
||||
tankman = new FunkinSprite(game.dad.x + game.dad.globalOffset.x + 520, game.dad.y + game.dad.globalOffset.y + 225);
|
||||
tankman.antialiasing = true;
|
||||
tankman.loadSprite(Paths.image('game/cutscenes/tank/guns-tankman'));
|
||||
tankman.animateAtlas.anim.addBySymbol('tank', 'TANK TALK 2', 0, false);
|
||||
tankman.addAnim('tank', 'TANK TALK 2', 0, false);
|
||||
|
||||
game.insert(game.members.indexOf(game.dad), tankman);
|
||||
game.dad.visible = false;
|
||||
@@ -65,4 +65,4 @@ function destroy() {
|
||||
for(thing in [tankman, tankTalk]) thing.destroy();
|
||||
if(destroyDistorto) distorto.destroy();
|
||||
FlxTween.tween(FlxG.camera, {zoom: game.defaultCamZoom}, 0.7, {ease: FlxEase.quadInOut, startDelay: 0});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,20 +33,20 @@ function create() {
|
||||
tankman = new FunkinSprite(game.dad.x + game.dad.globalOffset.x + 520, game.dad.y + game.dad.globalOffset.y + 225);
|
||||
tankman.antialiasing = true;
|
||||
tankman.loadSprite(Paths.image('game/cutscenes/tank/stress-tankman'));
|
||||
tankman.animateAtlas.anim.addBySymbol('p1', 'TANK TALK 3 P1 UNCUT', 0, false);
|
||||
tankman.animateAtlas.anim.addBySymbol('p2', 'TANK TALK 3 P2 UNCUT', 0, false);
|
||||
tankman.addAnim('p1', 'TANK TALK 3 P1 UNCUT', 0, false);
|
||||
tankman.addAnim('p2', 'TANK TALK 3 P2 UNCUT', 0, false);
|
||||
tankman.playAnim('p1');
|
||||
|
||||
pico = new FunkinSprite(game.gf.x + game.gf.globalOffset.x + 150, game.gf.y + game.gf.globalOffset.y + 395);
|
||||
pico = new FunkinSprite(game.gf.x + game.gf.globalOffset.x - 615, game.gf.y + game.gf.globalOffset.y - 130);
|
||||
pico.antialiasing = true;
|
||||
pico.loadSprite(Paths.image('game/cutscenes/tank/stress-pico'));
|
||||
pico.animateAtlas.anim.addBySymbol('die', 'GF Time to Die sequence', 24, false);
|
||||
pico.animateAtlas.anim.addBySymbol('saves', 'Pico Saves them sequence', 24, false);
|
||||
pico.animateAtlas.anim.addBySymbol('idle', 'Pico Dual Wield on Speaker idle', 24, true);
|
||||
pico.addAnim('die', 'die', 24, false, null, null, 0, 0, null, true);
|
||||
pico.addAnim('saves', 'saves', 24, false, null, null, 0, 0, null, true);
|
||||
pico.addAnim('idle', 'idle', 24, true, null, null, 0, 0, null, true);
|
||||
pico.scrollFactor.set(0.95, 0.95);
|
||||
pico.playAnim("idle");
|
||||
pico.visible = false;
|
||||
game.insert(game.members.indexOf(game.gf) + 1, pico);
|
||||
game.insert(game.members.indexOf(game.gf) + 2, pico);
|
||||
|
||||
game.insert(game.members.indexOf(game.dad) + 1, tankman);
|
||||
game.dad.visible = false;
|
||||
@@ -59,7 +59,11 @@ function update(elapsed) {
|
||||
lipSync(tankman, 0, 16750);
|
||||
if (stressCutscene.time > 15100) {
|
||||
step = 1;
|
||||
focusOn(game.gf);
|
||||
|
||||
//focusOn(game.gf);
|
||||
game.camFollow.x += 350;
|
||||
game.camFollow.y -= 200;
|
||||
|
||||
pico.visible = true;
|
||||
pico.playAnim('die', true);
|
||||
|
||||
@@ -118,7 +122,7 @@ function update(elapsed) {
|
||||
}
|
||||
|
||||
function lipSync(char:FunkinSprite, begin:Float, end:Float) {
|
||||
char.animateAtlas.anim.curFrame = Std.int(FlxMath.remapToRange(stressCutscene.time, begin, end, 0, char.animateAtlas.anim.length-1));
|
||||
char.anim.curAnim.curFrame = Std.int(FlxMath.remapToRange(stressCutscene.time, begin, end, 0, char.anim.curAnim.numFrames - 1));
|
||||
}
|
||||
|
||||
function focusOn(char, snap:Bool = false) {
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
import flixel.FlxSprite;
|
||||
|
||||
var tankmanRun:Array<TankmenBG> = [];
|
||||
var grpTankmanRun:FlxTypedGroup<FlxSprite> = [];
|
||||
|
||||
var spawnTimes = []; // [[time, direction]]
|
||||
var tankmanPool = [];
|
||||
|
||||
function recycleTankman() {
|
||||
if(tankmanPool.length == 0) {
|
||||
return new TankmenBG();
|
||||
} else {
|
||||
return tankmanPool.shift(); // can be pop but it causes it to be less random
|
||||
}
|
||||
var tankmanGroup:TankmenGroup = {
|
||||
run: [],
|
||||
pool: [],
|
||||
group: new FlxTypedGroup<FlxSprite>()
|
||||
}
|
||||
|
||||
function recycleTankman()
|
||||
return tankmanGroup.pool.length == 0 ? new TankmenBG(tankmanGroup) : tankmanGroup.pool.shift(); // can be pop but it causes it to be less random
|
||||
|
||||
function getTankman(data:Array<Float>) {
|
||||
var tankman:TankmenBG = recycleTankman();
|
||||
tankman.strumTime = data[0];
|
||||
@@ -22,9 +18,8 @@ function getTankman(data:Array<Float>) {
|
||||
}
|
||||
|
||||
function postCreate() {
|
||||
grpTankmanRun = new FlxTypedGroup();
|
||||
insert(members.indexOf(gf) - 1, grpTankmanRun);
|
||||
if(inCutscene) grpTankmanRun.visible = false;
|
||||
insert(members.indexOf(gf) - 1, tankmanGroup.group);
|
||||
if (inCutscene) tankmanGroup.group.visible = false;
|
||||
|
||||
/*var tempTankman:TankmenBG = recycleTankman();
|
||||
tempTankman.strumTime = 10;
|
||||
@@ -42,9 +37,8 @@ function postCreate() {
|
||||
//spawnTimes.reverse(); // no need to reverse it since the notes are already reversed
|
||||
}
|
||||
|
||||
function onStartCountdown() {
|
||||
if(PlayState.instance.seenCutscene) grpTankmanRun.visible = true;
|
||||
}
|
||||
function onStartCountdown()
|
||||
if (PlayState.instance.seenCutscene) tankmanGroup.group.visible = true;
|
||||
|
||||
function spawnTankmen() {
|
||||
var time = Conductor.songPosition;
|
||||
@@ -54,50 +48,46 @@ function spawnTankmen() {
|
||||
|
||||
//trace("Spawning Tankman", tankmen.sprite.offset, tankmen.goingRight);
|
||||
|
||||
tankmanRun.push(tankmen);
|
||||
grpTankmanRun.add(tankmen.sprite);
|
||||
tankmanGroup.run.push(tankmen);
|
||||
tankmanGroup.group.add(tankmen.sprite);
|
||||
}
|
||||
}
|
||||
|
||||
function update(elapsed) {
|
||||
spawnTankmen();
|
||||
|
||||
var length = tankmanRun.length;
|
||||
for(i in 0...length) {
|
||||
var length = tankmanGroup.run.length;
|
||||
for (i in 0...length) {
|
||||
var reverseIndex = length - i - 1;
|
||||
var tankmen = tankmanRun[reverseIndex];
|
||||
var tankmen = tankmanGroup.run[reverseIndex];
|
||||
tankmen.update(elapsed);
|
||||
}
|
||||
}
|
||||
|
||||
class TankmenBG {
|
||||
public var sprite:FlxSprite;
|
||||
|
||||
var strumTime = 0;
|
||||
var goingRight = false;
|
||||
var tankSpeed = 0.7;
|
||||
|
||||
var endingOffset = null;
|
||||
var sprite = null;
|
||||
|
||||
var endingOffset:Float;
|
||||
var killed = false;
|
||||
var grp:TankmenGroup; // The reference to the current pool
|
||||
|
||||
function new() {
|
||||
this.sprite = new FlxSprite();
|
||||
var sprite = this.sprite;
|
||||
function new(grp:TankmenGroup) {
|
||||
this.grp = grp;
|
||||
|
||||
sprite = new FlxSprite();
|
||||
sprite.frames = Paths.getSparrowAtlas('stages/tank/tankmanKilled1');
|
||||
sprite.antialiasing = true;
|
||||
sprite.animation.addByPrefix('run', 'tankman running', 24, true);
|
||||
|
||||
sprite.animation.play('run');
|
||||
|
||||
sprite.updateHitbox();
|
||||
|
||||
sprite.setGraphicSize(Std.int(sprite.width * 0.8));
|
||||
sprite.updateHitbox();
|
||||
}
|
||||
|
||||
function resetShit(x, y, isGoingRight) {
|
||||
var sprite = this.sprite;
|
||||
function resetShit(x:Float, y:Float, isGoingRight:Bool) {
|
||||
sprite.revive();
|
||||
sprite.setPosition(x, y);
|
||||
sprite.offset.set(0, 0);
|
||||
@@ -114,7 +104,6 @@ class TankmenBG {
|
||||
}
|
||||
|
||||
function update(elapsed) {
|
||||
var sprite = this.sprite;
|
||||
sprite.visible = !(sprite.x >= FlxG.width * 1.5 || sprite.x <= FlxG.width * -0.5);
|
||||
|
||||
if (sprite.animation.curAnim.name == 'run')
|
||||
@@ -124,8 +113,7 @@ class TankmenBG {
|
||||
if (goingRight) {
|
||||
endDirection = (FlxG.width * 0.02) - endingOffset;
|
||||
sprite.x = (endDirection + (Conductor.songPosition - strumTime) * tankSpeed);
|
||||
}
|
||||
else sprite.x = (endDirection - (Conductor.songPosition - strumTime) * tankSpeed);
|
||||
} else sprite.x = (endDirection - (Conductor.songPosition - strumTime) * tankSpeed);
|
||||
}
|
||||
|
||||
if (Conductor.songPosition > strumTime)
|
||||
@@ -133,10 +121,10 @@ class TankmenBG {
|
||||
sprite.animation.play('shot');
|
||||
sprite.animation.finishCallback = function(_) {
|
||||
killed = true;
|
||||
grpTankmanRun.remove(sprite, true);
|
||||
grp.group.remove(sprite, true);
|
||||
sprite.kill();
|
||||
tankmanPool.push(this);
|
||||
tankmanRun.remove(this);
|
||||
grp.pool.push(this);
|
||||
grp.run.remove(this);
|
||||
}
|
||||
|
||||
if (goingRight)
|
||||
@@ -146,4 +134,4 @@ class TankmenBG {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@ function create() {
|
||||
tankman = new FunkinSprite(game.dad.x + game.dad.globalOffset.x + 520, game.dad.y + game.dad.globalOffset.y + 225);
|
||||
tankman.antialiasing = true;
|
||||
tankman.loadSprite(Paths.image('game/cutscenes/tank/ugh-tankman'));
|
||||
tankman.animateAtlas.anim.addBySymbol('1', 'TANK TALK 1 P1', 0, false);
|
||||
tankman.animateAtlas.anim.addBySymbol('2', 'TANK TALK 1 P2', 0, false);
|
||||
tankman.addAnim('1', 'TANK TALK 1 P1', 0, false);
|
||||
tankman.addAnim('2', 'TANK TALK 1 P2', 0, false);
|
||||
|
||||
game.insert(game.members.indexOf(game.dad), tankman);
|
||||
game.dad.visible = false;
|
||||
@@ -77,4 +77,4 @@ function destroy() {
|
||||
for(timer in timers) timer.cancel();
|
||||
for(thing in [tankTalk1, tankTalk2, bfBeep, tankman]) thing.destroy();
|
||||
if(destroyDistorto) distorto.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
# Compiling Codename Engine
|
||||
Do you want to turn your source code into a playable build to play? Then you want to **compile the source code**, follow this guide.
|
||||
> **Open the instructions for your platform.**
|
||||
<details>
|
||||
<summary>Windows</summary>
|
||||
|
||||
1. Install [version 4.3.7 of Haxe](https://haxe.org/download/version/4.3.7/).
|
||||
2. Download and install [`git-scm`](https://git-scm.com/download/win).
|
||||
- Leave all installation options as default.
|
||||
3. Run `setup-windows.bat` using cmd or double-clicking it and wait for the libraries to install.
|
||||
4. Once the libraries are installed, run `haxelib run lime test windows` to compile and launch the game (may take a long time)
|
||||
- ℹ You can run `haxelib run lime setup` to make the lime command global, allowing you to execute `lime test windows` directly.
|
||||
</details>
|
||||
<details>
|
||||
<summary>Linux</summary>
|
||||
|
||||
1. Install [version 4.3.7 of Haxe](https://haxe.org/download/version/4.3.7/).
|
||||
2. Install `libvlc` if not present already.
|
||||
- ℹ On certain Arch based distros installing `vlc-plugins-all` might solve if `libvlc` alone doesn't work.
|
||||
3. Install `g++`, if not present already.
|
||||
4. Download and install [`git-scm`](https://git-scm.com/download/linux) if not present already.
|
||||
5. Run `setup-unix.sh` using the terminal or double-clicking it and wait for the libraries to install.
|
||||
6. Once the libraries are installed, run `haxelib run lime test linux` to compile and launch the game (may take a long time)
|
||||
- ℹ You can run `haxelib run lime setup` to make the lime command global, allowing you to execute `lime test linux` directly.
|
||||
</details>
|
||||
<details>
|
||||
<summary>MacOS</summary>
|
||||
|
||||
1. Install [version 4.3.7 of Haxe](https://haxe.org/download/version/4.3.7/).
|
||||
2. Install `Xcode` to allow C++ app building.
|
||||
3. Download and install [`git-scm`](https://git-scm.com/download/mac).
|
||||
4. Run `setup-unix.sh` using the terminal and wait for the libraries to install.
|
||||
5. Once the libraries are installed, run `haxelib run lime test mac` to compile and launch the game (may take a long time)
|
||||
- ℹ You can run `haxelib run lime setup` to make the lime command global, allowing you to execute `lime test mac` directly.
|
||||
</details>
|
||||
|
||||
> [!TIP]
|
||||
> You can also run `./cne-windows.bat -help` or `./cne-unix.sh -help` (depending on your platform) to check out more useful commands!<br>
|
||||
> For example `./cne-windows test` or `./cne-unix.sh test` builds the game and uses the source assets folder instead of the export one for easier development (although you can still use `lime test` normally).
|
||||
> - If you're running the terminal from the project's main folder, use instead `./building/cne-windows.bat -COMMAND HERE` or `./building/cne-unix.sh -COMMAND HERE` depending on your platform.
|
||||
|
||||
# Generating Codename Engine's API documentation
|
||||
**Mainly recommended if you intend to fork the engine and make your own custom version to publish.**<br>Do you want to generate an API documentation so people can understand and mod your playable build? This documentation can be uploaded to your website.<br>If you just want to compile the engine normally for your hardcoded mod or for yourself you can skip this step.
|
||||
> **Select your platform to continue.**
|
||||
<details>
|
||||
<summary>Windows</summary>
|
||||
|
||||
1. Run `generate-docs-windows.bat` using cmd or double-clicking it and wait for the `doc.xml` to be generated inside the `docs` folder.
|
||||
</details>
|
||||
<details>
|
||||
<summary>MacOS/Linux</summary>
|
||||
|
||||
1. Run `generate-docs-unix.sh` using the terminal or double-clicking it and wait for the `doc.xml` to be generated inside the `docs` folder.
|
||||
</details>
|
||||
|
||||
2. You can use this `doc.xml` file to generate a full HTML documentation (that you can open in your browser for example) using Haxe's [dox](https://github.com/HaxeFoundation/dox) generator; check [Codename Engine's webiste](https://github.com/CodenameCrew/codename-website/tree/main/api-generator) for example.
|
||||
|
||||
> [!CAUTION]
|
||||
> The doc.xml might contain some sensible paths of your computer: make sure to filter the file before publishing it for everyone if you want to keep those paths private!<br>To filter and delete those paths, you may use Codename Engine's website's [doc filter Python script](https://github.com/CodenameCrew/codename-website/blob/main/api-generator/api/filter.py) by simply running it in the same folder of your `doc.xml` file. This script will also delete everything irrelevant to the engine that was generated in your documentation, such as libraries' (like OpenFL or Flixel) APIs.
|
||||
@@ -1,14 +1,17 @@
|
||||
[general]
|
||||
[General]
|
||||
sample-type=float32
|
||||
stereo-mode=speakers
|
||||
stereo-encoding=panpot
|
||||
hrtf=false
|
||||
cf_level=0
|
||||
resampler=fast_bsinc24
|
||||
front-stablizer=false
|
||||
output-limiter=false
|
||||
front-stabilizer=false
|
||||
volume-adjust=0
|
||||
period_size=441
|
||||
sources=512
|
||||
sends=64
|
||||
dither=false
|
||||
|
||||
[decoder]
|
||||
hq-mode=false
|
||||
distance-comp=false
|
||||
hq-mode=true
|
||||
distance-comp=true
|
||||
nfc=false
|
||||
@@ -1 +1,3 @@
|
||||
#!/usr/bin/env sh
|
||||
cd "$(dirname "$0")/.."
|
||||
haxe -cp commandline -D analyzer-optimize --run Main $@
|
||||
@@ -1 +1,2 @@
|
||||
cd /d "%~dp0.."
|
||||
@haxe -cp commandline -D analyzer-optimize --run Main %*
|
||||
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env sh
|
||||
cd "$(dirname "$0")/.."
|
||||
echo "Generating documentation..."
|
||||
if [ $(uname) == "Darwin" ]; then
|
||||
echo "Platform is macOS"
|
||||
haxelib run lime build mac --haxeflag="-xml docs/doc.xml" -D doc-gen -D DOCUMENTATION --no-output
|
||||
else
|
||||
echo "Platform is not macOS; assuming platform to be Linux compatible"
|
||||
haxelib run lime build linux --haxeflag="-xml docs/doc.xml" -D doc-gen -D DOCUMENTATION --no-output
|
||||
fi
|
||||
|
||||
echo "The XML file for the API documentation has been generated at docs/doc.xml."
|
||||
echo "For updating the API documentation hosted at the website, please replace codename-website/api-generator/api/doc.xml with the file listed above."
|
||||
@@ -0,0 +1,8 @@
|
||||
@ECHO OFF
|
||||
cd /d "%~dp0.."
|
||||
echo Generating documentation...
|
||||
echo Platform is based on Windows
|
||||
haxelib run lime build windows --haxeflag="-xml docs/doc.xml" -D doc-gen -D DOCUMENTATION --no-output
|
||||
|
||||
echo The XML file for the API documentation has been generated at docs/doc.xml.
|
||||
echo For updating the API documentation hosted at the website, please replace codename-website/api-generator/api/doc.xml with the file listed above.
|
||||
@@ -4,19 +4,17 @@
|
||||
<print pretty="true">Preparing installation...</print>
|
||||
|
||||
<!-- 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" ref="old" />
|
||||
<lib name="lime" version="8.1.2" />
|
||||
<!-- <git name="lime" url="https://github.com/CodenameCrew/cne-lime" /> disabled for now until fixed -->
|
||||
|
||||
<!-- Flixel -->
|
||||
<git name="flixel" url="https://github.com/CodenameCrew/cne-flixel" />
|
||||
<git name="flixel-addons" url="https://github.com/CodenameCrew/cne-flixel-addons" />
|
||||
<git name="flixel" url="https://github.com/CodenameCrew/cne-flixel" ref="old" />
|
||||
<git name="flixel-addons" url="https://github.com/CodenameCrew/cne-flixel-addons" ref="old" />
|
||||
|
||||
<!-- Other Libraries -->
|
||||
<git name="hscript-improved" url="https://github.com/CodenameCrew/hscript-improved" ref="codename-dev" />
|
||||
<git name="flxanimate" url="https://github.com/CodenameCrew/cne-flxanimate" />
|
||||
<git name="hxdiscord_rpc" url="https://github.com/CodenameCrew/cne-hxdiscord_rpc" skipDeps="true" />
|
||||
<git name="funkin-modchart" url="https://github.com/TheoDevelops/FunkinModchart" ref="f30676579d8de7ccac7d12e13b664e8b2c42c6bf" skipDeps="true" />
|
||||
<git name="hxdiscord_rpc" url="https://github.com/CodenameCrew/cne-hxdiscord_rpc" ref="old" skipDeps="true" />
|
||||
<lib name="funkin-modchart" skipDeps="true" />
|
||||
<lib name="hxvlc" version="1.9.3" skipDeps="true" />
|
||||
|
||||
<!-- Documentation and other features -->
|
||||
@@ -31,7 +29,9 @@
|
||||
<lib global="true" name="hxp" /> <lib name="hxp" />
|
||||
<lib global="true" name="format" /> <lib name="format" />
|
||||
|
||||
<git name="hxcpp" url="https://github.com/CodenameCrew/cne-hxcpp" />
|
||||
<git name="hxcpp" url="https://github.com/CodenameCrew/cne-hxcpp" ref="old" />
|
||||
|
||||
<git name="flixel-animate" url="https://github.com/CodenameCrew/cne-flixel-animate/" ref="old" skipDeps="true"/>
|
||||
</if>
|
||||
|
||||
<!-- Hxcpp Building -->
|
||||
@@ -1,2 +1,3 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/env sh
|
||||
cd "$(dirname "$0")/.."
|
||||
haxe -cp commandline -D analyzer-optimize --run Main setup
|
||||
@@ -1 +1,2 @@
|
||||
cd /d "%~dp0.."
|
||||
@haxe -cp commandline -D analyzer-optimize --run Main setup
|
||||
@@ -16,7 +16,7 @@ class Main {
|
||||
dDoc: [
|
||||
"Usage: setup",
|
||||
"",
|
||||
"This command runs through all libraries in libs.xml, and install them.",
|
||||
"This command runs through all libraries in building/libs.xml, and install them.",
|
||||
"If they're already installed, they will be updated.",
|
||||
"",
|
||||
"--all : Reinstall all libraries.",
|
||||
@@ -173,6 +173,7 @@ class Main {
|
||||
Sys.println("Codename Engine Command Line utility");
|
||||
Sys.println('Available commands (${commands.length}):\n');
|
||||
for(line in commands) {
|
||||
if(line.names.contains(null)) line.names.remove(null);
|
||||
Sys.println('${line.names.join(", ")} - ${line.doc}');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ class Setup {
|
||||
FileSystem.createDirectory('.haxelib');
|
||||
}
|
||||
|
||||
var libFile = "./libs.xml";
|
||||
var libFile = "./building/libs.xml";
|
||||
if(args.existsOption("lib")) {
|
||||
libFile = args.getOption("lib");
|
||||
if(libFile == null) {
|
||||
@@ -252,32 +252,32 @@ class Setup {
|
||||
|
||||
// check for outdated haxe
|
||||
final curHaxeVer = [for(v in haxeVer.split(".")) Std.parseInt(v)];
|
||||
final minumumVersion = [4, 2, 5];
|
||||
final minumumVersion = [4, 3, 7];
|
||||
for(i in 0...minumumVersion.length) {
|
||||
if (curHaxeVer[i] > minumumVersion[i]) break;
|
||||
if (curHaxeVer[i] < minumumVersion[i]) {
|
||||
prettyPrint([
|
||||
"!! WARNING !!",
|
||||
"Your current Haxe version is outdated.",
|
||||
'You\'re using ${haxeVer}, whilst the required version is 4.2.5 or newer.',
|
||||
'You\'re using ${haxeVer}, whilst the required version is 4.3.7 or newer.',
|
||||
'The engine may not compile with your current version of Haxe.',
|
||||
'We recommend upgrading to 4.2.5 or newer'
|
||||
'We recommend upgrading to 4.3.7 or newer'
|
||||
].join("\n"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// vswhere.exe its used to find any visual studio related installations on the system, including full visual studio ide installations, visual studio build tools installations, and other related components - Nex
|
||||
if (CHECK_VSTUDIO && Compiler.getBuildTarget().toLowerCase() == "windows" && new Process('"C:/Program Files (x86)/Microsoft Visual Studio/Installer/vswhere.exe" -property catalog_productDisplayVersion').exitCode(true) == 1) {
|
||||
// vswhere.exe is used to find any visual studio related installations on the system, including full visual studio ide installations, visual studio build tools installations, and other related components - Nex
|
||||
if (CHECK_VSTUDIO && Compiler.getBuildTarget().toLowerCase() == "windows" && new Process('"C:/Program Files (x86)/Microsoft Visual Studio/Installer/vswhere.exe" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -requires Microsoft.VisualStudio.Component.Windows10SDK.19041 -property installationPath').exitCode(true) != 0) {
|
||||
prettyPrint("Installing Microsoft Visual Studio Community (Dependency)");
|
||||
|
||||
// thanks to @crowplexus for these two lines! - Nex
|
||||
command("curl -# -O https://download.visualstudio.microsoft.com/download/pr/3105fcfe-e771-41d6-9a1c-fc971e7d03a7/8eb13958dc429a6e6f7e0d6704d43a55f18d02a253608351b6bf6723ffdaf24e/vs_Community.exe");
|
||||
command("vs_Community.exe --add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.Windows10SDK.19041 -p");
|
||||
|
||||
FileSystem.deleteFile("vs_Community.exe");
|
||||
prettyPrint('If it didn\'t say it before: Because of this component if you want to compile you have to restart the device.');
|
||||
|
||||
prettyPrint("Because of this component, if you want to compile, you need to restart the device.");
|
||||
Sys.print("Do you wish to do it now [y/n]? ");
|
||||
if(Sys.stdin().readLine().toLowerCase() == "y") command("shutdown /r /t 0 /f");
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
<!-- _________________________________ Engine Settings _______________________________ -->
|
||||
|
||||
<!-- Comment this out to disable updates !-->
|
||||
<define name="UPDATE_CHECKING" unless="web || hl || neko"/>
|
||||
<define name="UPDATE_CHECKING" unless="web || hl || neko || debug"/>
|
||||
|
||||
<!-- Comment this out to disable Discord RPC !-->
|
||||
<section if="cpp">
|
||||
@@ -74,6 +74,9 @@
|
||||
Reduces compilation time at the cost of limited HScript flexibility. !-->
|
||||
<define name="CUSTOM_CLASSES" unless="STRIPPED_COMPILE" />
|
||||
|
||||
<!-- Comment this out to disable abstract support in hscript. !-->
|
||||
<haxedef name="HSCRIPT_ABSTRACT_SUPPORT" unless="STRIPPED_COMPILE" />
|
||||
|
||||
<!-- Comment this out to disable multithreading !-->
|
||||
<haxedef name="ALLOW_MULTITHREADING" unless="web || flash" />
|
||||
|
||||
@@ -130,7 +133,7 @@
|
||||
<haxelib name="hxvlc" if="VIDEO_CUTSCENES" />
|
||||
<haxelib name="away3d" if="THREE_D_SUPPORT" />
|
||||
<haxelib name="format" />
|
||||
<haxelib name="flxanimate" />
|
||||
<haxelib name="flixel-animate" />
|
||||
<haxelib name="nape-haxe4" if="NAPE_ENABLED"/>
|
||||
|
||||
<haxelib name="hscript-improved" />
|
||||
@@ -166,8 +169,8 @@
|
||||
|
||||
<!-- OpenAL config -->
|
||||
<section if="desktop">
|
||||
<assets path="alsoft.txt" rename="plugins/alsoft.ini" type="text" if="windows"/>
|
||||
<assets path="alsoft.txt" rename="plugins/alsoft.conf" type="text" unless="windows"/>
|
||||
<assets path="building/alsoft.txt" rename="plugins/alsoft.ini" type="text" if="windows"/>
|
||||
<assets path="building/alsoft.txt" rename="plugins/alsoft.conf" type="text" unless="windows"/>
|
||||
</section>
|
||||
|
||||
<!-- ______________________________ Haxedefines _____________________________ -->
|
||||
@@ -189,6 +192,9 @@
|
||||
<haxedef name="USE_ADAPTED_ASSETS" if="USE_ADAPTED_ASSETS" />
|
||||
<haxedef name="openfl_dpi_aware" if="openfl_dpi_aware" />
|
||||
|
||||
<!-- Disable it for more concise compilation errors. -->
|
||||
<haxedef name="message.reporting" value="pretty" />
|
||||
|
||||
<!-- _________________________________ Custom _______________________________ -->
|
||||
|
||||
<!--Place custom nodes like icons here (higher priority to override the HaxeFlixel icon)-->
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
{ }:
|
||||
let
|
||||
pkgs = import (builtins.fetchTarball {
|
||||
url = "https://github.com/NixOS/nixpkgs/archive/c407032be28ca2236f45c49cfb2b8b3885294f7f.tar.gz";
|
||||
}) { };
|
||||
|
||||
libs =
|
||||
with pkgs;
|
||||
[
|
||||
SDL2
|
||||
pkg-config
|
||||
openal
|
||||
alsa-lib
|
||||
libvlc
|
||||
libpulseaudio
|
||||
libGL
|
||||
]
|
||||
++ (with xorg; [
|
||||
libX11
|
||||
libXext
|
||||
libXinerama
|
||||
libXi
|
||||
libXrandr
|
||||
]);
|
||||
in
|
||||
pkgs.mkShell {
|
||||
name = "CodenameEngine";
|
||||
|
||||
packages = with pkgs; [
|
||||
haxe
|
||||
neko
|
||||
libsForQt5.qttools
|
||||
];
|
||||
|
||||
buildInputs = libs;
|
||||
|
||||
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath libs;
|
||||
|
||||
shellHook = ''
|
||||
source update.sh
|
||||
'';
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import flixel.math.FlxMath;
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.system.FlxAssets.FlxSoundAsset;
|
||||
import flixel.tweens.FlxTween;
|
||||
import flixel.util.FlxDestroyUtil;
|
||||
import flixel.util.FlxSignal;
|
||||
import flixel.util.FlxStringUtil;
|
||||
import flixel.FlxBasic;
|
||||
@@ -136,11 +137,18 @@ class FlxSound extends FlxBasic {
|
||||
public var radius:Float;
|
||||
|
||||
/**
|
||||
* Whether the proximity alters the pan or not
|
||||
* Whether the proximity alters the pan or not.
|
||||
* @since raltyMod
|
||||
*/
|
||||
public var proximityPan:Bool;
|
||||
|
||||
/**
|
||||
* Controls how much this object is affected by camera scrolling. `0` = no movement (e.g. a static sound),
|
||||
* This is only useful if used with proximity (Initialized once proximity is used).
|
||||
* @since raltyMod
|
||||
*/
|
||||
public var scrollFactor(default, null):FlxPoint;
|
||||
|
||||
/**
|
||||
* Stores for how much channels are in the loaded sound.
|
||||
* @since raltyMod
|
||||
@@ -302,6 +310,8 @@ class FlxSound extends FlxBasic {
|
||||
_lastTime = null;
|
||||
|
||||
if (destroySound) {
|
||||
scrollFactor = FlxDestroyUtil.put(scrollFactor);
|
||||
|
||||
if (group != null) group.remove(this);
|
||||
|
||||
if (_channel != null) {
|
||||
@@ -348,15 +358,24 @@ class FlxSound extends FlxBasic {
|
||||
|
||||
_amplitudeUpdate = true;
|
||||
|
||||
// Distance-based volume control (TODO for Ralty: REDO THIS)
|
||||
// Distance-based volume control
|
||||
if (target != null) {
|
||||
var targetPosition = target.getPosition();
|
||||
var radialMultiplier = targetPosition.distanceTo(FlxPoint.weak(x, y)) / radius;
|
||||
targetPosition.put();
|
||||
radialMultiplier = 1 - FlxMath.bound(radialMultiplier, 0, 1);
|
||||
var targetPosition = target.getPosition(), position = getPosition();
|
||||
var camera = camera;
|
||||
if (camera != null) {
|
||||
targetPosition.subtract(camera.scroll.x * target.scrollFactor.x, camera.scroll.y * target.scrollFactor.y);
|
||||
if (scrollFactor != null) position.subtract(camera.scroll.x * scrollFactor.x, camera.scroll.y * scrollFactor.y);
|
||||
else position.subtract(camera.scroll.x, camera.scroll.y);
|
||||
}
|
||||
|
||||
_volumeAdjust = radialMultiplier;
|
||||
if (proximityPan) _panAdjust = (x - target.x) / radius;
|
||||
var radialMultiplier = targetPosition.distanceTo(position) / radius;
|
||||
|
||||
// Make it so it affects the 3d position of the source and not just the panning?
|
||||
_volumeAdjust = 1 - FlxMath.bound(radialMultiplier, 0, 1);
|
||||
if (proximityPan) _panAdjust = (position.x - targetPosition.x) / radius;
|
||||
|
||||
targetPosition.put();
|
||||
position.put();
|
||||
}
|
||||
else
|
||||
_volumeAdjust = 1.0;
|
||||
@@ -536,12 +555,15 @@ class FlxSound extends FlxBasic {
|
||||
* @param Pan Whether panning should be used in addition to the volume changes.
|
||||
* @return This FlxSound instance (nice for chaining stuff together, if you're into that).
|
||||
*/
|
||||
public function proximity(x = 0.0, y = 0.0, ?targetObject:FlxObject, ?radius:Float, pan = true):FlxSound {
|
||||
public function proximity(x = 0.0, y = 0.0, ?targetObject:FlxObject, ?radius:Float, pan = true, ?scrollFactor:FlxPoint):FlxSound {
|
||||
setPosition(x, y);
|
||||
if (targetObject != null) this.target = targetObject;
|
||||
if (radius != null) this.radius = radius;
|
||||
proximityPan = pan;
|
||||
|
||||
if (this.scrollFactor == null) this.scrollFactor = FlxPoint.get(1, 1);
|
||||
if (scrollFactor != null) this.scrollFactor.copyFrom(scrollFactor);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -549,14 +571,28 @@ class FlxSound extends FlxBasic {
|
||||
* Helper function to set the coordinates of this object.
|
||||
* Sound positioning is used in conjunction with proximity/panning.
|
||||
*
|
||||
* @param x The new x position
|
||||
* @param y The new y position
|
||||
* @param x The new x position
|
||||
* @param y The new y position
|
||||
*/
|
||||
public inline function setPosition(x = 0.0, y = 0.0):Void {
|
||||
public function setPosition(x = 0.0, y = 0.0):Void {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the world position of this object.
|
||||
*
|
||||
* @param result Optional arg for the returning point.
|
||||
* @return The world position of this object.
|
||||
* @since raltyMod
|
||||
*/
|
||||
public function getPosition(?result:FlxPoint):FlxPoint {
|
||||
if (result == null)
|
||||
result = FlxPoint.get();
|
||||
|
||||
return result.set(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this function to play the sound - also works on paused sounds.
|
||||
*
|
||||
@@ -682,7 +718,7 @@ class FlxSound extends FlxBasic {
|
||||
_paused = false;
|
||||
_time = startTime;
|
||||
_lastTime = FlxG.game.getTicks();
|
||||
if (_channel == null || !_channel.__isValid || _source == null #if lime_cffi || _source.__backend.disposed || _source.__backend.handle == null #end)
|
||||
if (_channel == null || !_channel.__isValid || _source == null #if lime_cffi || _source.__backend.disposed #end)
|
||||
makeChannel();
|
||||
|
||||
if (_channel != null) {
|
||||
@@ -733,7 +769,8 @@ class FlxSound extends FlxBasic {
|
||||
_lastTime = FlxG.game.getTicks();
|
||||
_time = loopTime;
|
||||
}
|
||||
else _channel.loops = 999;
|
||||
else if (_source != null)
|
||||
_source.loops = 999;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -763,7 +800,7 @@ class FlxSound extends FlxBasic {
|
||||
}
|
||||
|
||||
inline function get_playing():Bool @:privateAccess
|
||||
return _channel != null && _channel.__isValid && _source.playing;
|
||||
return _source != null && _source.playing;
|
||||
|
||||
inline function get_volume():Float
|
||||
return _volume;
|
||||
@@ -796,12 +833,12 @@ class FlxSound extends FlxBasic {
|
||||
inline function get_buffer():AudioBuffer
|
||||
@:privateAccess return _sound != null ? _sound.__buffer : null;
|
||||
|
||||
function update_amplitude():Void @:privateAccess {
|
||||
if (_channel == null || !_channel.__updatePeaks(get_time()) || !_amplitudeUpdate) return;
|
||||
|
||||
_amplitudeUpdate = false;
|
||||
_amplitudeLeft = _channel.__leftPeak;
|
||||
_amplitudeRight = _channel.__rightPeak;
|
||||
inline function update_amplitude():Void @:privateAccess {
|
||||
if (_channel != null && _channel.__updatePeaks(get_time()) && _amplitudeUpdate) {
|
||||
_amplitudeUpdate = false;
|
||||
_amplitudeLeft = _channel.__leftPeak;
|
||||
_amplitudeRight = _channel.__rightPeak;
|
||||
}
|
||||
}
|
||||
|
||||
inline function get_amplitudeLeft():Float {
|
||||
@@ -829,30 +866,27 @@ class FlxSound extends FlxBasic {
|
||||
inline function get_pitch():Float
|
||||
return _pitch;
|
||||
|
||||
function set_pitch(v:Float):Float {
|
||||
inline function set_pitch(v:Float):Float {
|
||||
_realPitch = (_pitch = v) * _timeScaleAdjust;
|
||||
if (_channel != null) _channel.pitch = _realPitch;
|
||||
if (_source != null) _source.pitch = _realPitch;
|
||||
return _pitch;
|
||||
}
|
||||
#end
|
||||
|
||||
function set_looped(v:Bool):Bool {
|
||||
if (playing) {
|
||||
if (v) _channel.loops = 999;
|
||||
else _channel.loops = 0;
|
||||
}
|
||||
if (playing) _source.loops = v ? 999 : 0;
|
||||
return looped = v;
|
||||
}
|
||||
|
||||
function set_loopTime(v:Float):Float {
|
||||
if (playing) _channel.loopTime = v;
|
||||
if (playing) _source.loopTime = v;
|
||||
return loopTime = v;
|
||||
}
|
||||
|
||||
function set_endTime(v:Null<Float>):Null<Float> {
|
||||
if (playing) {
|
||||
if (v != null && v > 0 && v < _length) _channel.endTime = v;
|
||||
else _channel.endTime = null;
|
||||
if (v != null && v > 0 && v < _length) _source.length = v;
|
||||
else _source.length = null;
|
||||
}
|
||||
return endTime = v;
|
||||
}
|
||||
@@ -864,7 +898,7 @@ class FlxSound extends FlxBasic {
|
||||
return _time;
|
||||
}
|
||||
function get_time():Float {
|
||||
if (_channel == null || @:privateAccess !_channel.__isValid || /*AudioManager.context == null*/funkin.backend.system.Main.audioDisconnected) return _time;
|
||||
if (_source == null || /*AudioManager.context == null*/funkin.backend.system.Main.audioDisconnected) return _time;
|
||||
|
||||
final sourceTime = _source.currentTime - _source.offset - _offset;
|
||||
if (!_source.playing || _realPitch <= 0) {
|
||||
@@ -903,24 +937,21 @@ class FlxSound extends FlxBasic {
|
||||
return _time = time;
|
||||
}
|
||||
|
||||
inline function get_offset():Float return _offset;
|
||||
inline function set_offset(offset:Float):Float {
|
||||
function get_offset():Float return _offset;
|
||||
function set_offset(offset:Float):Float {
|
||||
if (_offset == (_offset = offset)) return offset;
|
||||
//time = time + _offset;
|
||||
return offset;
|
||||
}
|
||||
|
||||
inline function get_length():Float return _length - _offset;
|
||||
function get_length():Float return _length - _offset;
|
||||
|
||||
/*function get_latency():Float {
|
||||
if (_channel != null) return _source.latency;
|
||||
return 0;
|
||||
}*/
|
||||
//function get_latency():Float return _source != null ? _source.latency : 0;
|
||||
|
||||
override function toString():String {
|
||||
return FlxStringUtil.getDebugString([
|
||||
LabelValuePair.weak("playing", playing),
|
||||
LabelValuePair.weak("time", _time),
|
||||
LabelValuePair.weak("time", time),
|
||||
LabelValuePair.weak("length", length),
|
||||
LabelValuePair.weak("volume", volume),
|
||||
LabelValuePair.weak("pitch", pitch)
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
package funkin.backend;
|
||||
|
||||
import flixel.graphics.frames.FlxFrame;
|
||||
import flixel.math.FlxAngle;
|
||||
import flixel.math.FlxMatrix;
|
||||
import openfl.display.BlendMode;
|
||||
import openfl.geom.ColorTransform;
|
||||
|
||||
class FlxAnimate extends flxanimate.FlxAnimate {
|
||||
static var rMatrix = new FlxMatrix();
|
||||
|
||||
override function drawLimb(limb:FlxFrame, _rMatrix:FlxMatrix, ?colorTransform:ColorTransform, ?blendMode:BlendMode)
|
||||
{
|
||||
if (alpha == 0 || colorTransform != null && (colorTransform.alphaMultiplier == 0 || colorTransform.alphaOffset == -255) || limb == null || limb.type == EMPTY)
|
||||
return;
|
||||
|
||||
if (blendMode == null)
|
||||
blendMode = BlendMode.NORMAL;
|
||||
|
||||
for (camera in cameras)
|
||||
{
|
||||
rMatrix.identity();
|
||||
limb.prepareMatrix(rMatrix, FlxFrameAngle.ANGLE_0, _checkFlipX() != camera.flipX, _checkFlipY() != camera.flipY);
|
||||
rMatrix.concat(_rMatrix);
|
||||
if (!camera.visible || !camera.exists || !limbOnScreen(limb, _rMatrix, camera))
|
||||
return;
|
||||
|
||||
getScreenPosition(_point, camera).subtractPoint(offset);
|
||||
rMatrix.translate(-origin.x, -origin.y);
|
||||
if (limb != _pivot) {
|
||||
if (frameOffsetAngle != null && frameOffsetAngle != angle)
|
||||
{
|
||||
var angleOff = (frameOffsetAngle - angle) * FlxAngle.TO_RAD;
|
||||
var cos = Math.cos(angleOff);
|
||||
var sin = Math.sin(angleOff);
|
||||
// cos doesn't need to be negated
|
||||
rMatrix.rotateWithTrig(cos, -sin);
|
||||
rMatrix.translate(-frameOffset.x, -frameOffset.y);
|
||||
rMatrix.rotateWithTrig(cos, sin);
|
||||
}
|
||||
else
|
||||
{
|
||||
rMatrix.translate(-frameOffset.x, -frameOffset.y);
|
||||
}
|
||||
rMatrix.scale(scale.x, scale.y);
|
||||
|
||||
if (!matrixExposed && bakedRotationAngle <= 0)
|
||||
{
|
||||
updateTrig();
|
||||
|
||||
if (angle != 0)
|
||||
rMatrix.rotateWithTrig(_cosAngle, _sinAngle);
|
||||
}
|
||||
}
|
||||
else
|
||||
rMatrix.a = rMatrix.d = 0.7 / camera.zoom;
|
||||
|
||||
if (matrixExposed)
|
||||
{
|
||||
rMatrix.concat(transformMatrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
rMatrix.concat(@:privateAccess flxanimate.FlxAnimate._skewMatrix);
|
||||
}
|
||||
|
||||
_point.addPoint(origin);
|
||||
if (isPixelPerfectRender(camera))
|
||||
{
|
||||
_point.floor();
|
||||
}
|
||||
|
||||
rMatrix.translate(_point.x, _point.y);
|
||||
camera.drawPixels(limb, null, rMatrix, colorTransform, blendMode, antialiasing, shaderEnabled ? shader : null);
|
||||
#if FLX_DEBUG
|
||||
FlxBasic.visibleCount++;
|
||||
#end
|
||||
}
|
||||
|
||||
// doesn't work, needs to be remade
|
||||
// #if FLX_DEBUG
|
||||
// if (FlxG.debugger.drawDebug)
|
||||
// drawDebug();
|
||||
// #end
|
||||
}
|
||||
|
||||
override function limbOnScreen(limb:FlxFrame, m:FlxMatrix, ?Camera:FlxCamera)
|
||||
{
|
||||
// TODO: ACTUAL OPTIMIZATION
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package funkin.backend;
|
||||
|
||||
import animate.FlxAnimate;
|
||||
import animate.FlxAnimateController.FlxAnimateAnimation;
|
||||
import flixel.addons.effects.FlxSkewedSprite;
|
||||
import flixel.animation.FlxAnimation;
|
||||
import flixel.math.FlxMatrix;
|
||||
@@ -7,7 +9,6 @@ import flixel.math.FlxPoint;
|
||||
import flixel.math.FlxRect;
|
||||
import flixel.system.FlxAssets.FlxGraphicAsset;
|
||||
import flixel.util.typeLimit.OneOfTwo;
|
||||
import flxanimate.animate.FlxAnim.FlxSymbolAnimation;
|
||||
import funkin.backend.scripting.events.sprite.PlayAnimContext;
|
||||
import funkin.backend.system.interfaces.IBeatReceiver;
|
||||
import funkin.backend.system.interfaces.IOffsetCompatible;
|
||||
@@ -15,6 +16,10 @@ import funkin.backend.utils.XMLUtil.AnimData;
|
||||
import funkin.backend.utils.XMLUtil.BeatAnim;
|
||||
import funkin.backend.utils.XMLUtil.IXMLEvents;
|
||||
import haxe.io.Path;
|
||||
import flixel.graphics.frames.FlxFrame;
|
||||
import flixel.math.FlxAngle;
|
||||
import animate.internal.RenderTexture;
|
||||
import animate.FlxAnimateFrames;
|
||||
|
||||
enum abstract XMLAnimType(Int)
|
||||
{
|
||||
@@ -43,7 +48,7 @@ enum abstract XMLAnimType(Int)
|
||||
}
|
||||
}
|
||||
|
||||
class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements IOffsetCompatible implements IXMLEvents
|
||||
class FunkinSprite extends FlxAnimate implements IBeatReceiver implements IOffsetCompatible implements IXMLEvents
|
||||
{
|
||||
public var extra:Map<String, Dynamic> = [];
|
||||
|
||||
@@ -56,6 +61,9 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
public var animEnabled:Bool = true;
|
||||
public var zoomFactorEnabled:Bool = true;
|
||||
|
||||
//Backwards compatibility
|
||||
public var animateAtlas(get, never):FunkinSprite;
|
||||
|
||||
public var globalCurFrame(get, set):Int;
|
||||
|
||||
/**
|
||||
@@ -66,9 +74,9 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
public var beatOffset:Int = 0;
|
||||
public var skipNegativeBeats:Bool = false;
|
||||
|
||||
public var animateAtlas:FlxAnimate;
|
||||
@:noCompletion public var atlasPlayingAnim:String;
|
||||
@:noCompletion public var atlasPath:String;
|
||||
public var animateSettings:FlxAnimateSettings = {};
|
||||
|
||||
var _rect2:FlxRect;
|
||||
|
||||
public function new(?X:Float = 0, ?Y:Float = 0, ?SimpleGraphic:FlxGraphicAsset)
|
||||
{
|
||||
@@ -83,6 +91,7 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
}
|
||||
|
||||
moves = false;
|
||||
applyStageMatrix = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,8 +107,6 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
@:privateAccess {
|
||||
spr.setPosition(source.x, source.y);
|
||||
spr.frames = source.frames;
|
||||
if (casted != null && casted.animateAtlas != null && casted.atlasPath != null)
|
||||
spr.loadSprite(casted.atlasPath);
|
||||
spr.animation.copyFrom(source.animation);
|
||||
spr.visible = source.visible;
|
||||
spr.alpha = source.alpha;
|
||||
@@ -109,9 +116,8 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
|
||||
if (casted != null) {
|
||||
spr.skew.set(casted.skew.x, casted.skew.y);
|
||||
spr.transformMatrix = casted.transformMatrix;
|
||||
spr.matrixExposed = casted.matrixExposed;
|
||||
spr.animOffsets = casted.animOffsets.copy();
|
||||
spr.zoomFactor = casted.zoomFactor;
|
||||
}
|
||||
}
|
||||
return spr;
|
||||
@@ -120,29 +126,24 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
public override function update(elapsed:Float)
|
||||
{
|
||||
super.update(elapsed);
|
||||
if (animateAtlas != null)
|
||||
animateAtlas.update(elapsed);
|
||||
|
||||
// hate how it looks like but hey at least its optimized and fast - Nex
|
||||
if (!debugMode && isAnimFinished()) {
|
||||
var name = getAnimName() + '-loop';
|
||||
if (hasAnimation(name))
|
||||
if (hasAnim(name))
|
||||
playAnim(name, null, lastAnimContext);
|
||||
}
|
||||
}
|
||||
|
||||
override function initVars() {
|
||||
super.initVars();
|
||||
_rect2 = FlxRect.get();
|
||||
}
|
||||
|
||||
public function loadSprite(path:String, Unique:Bool = false, Key:String = null)
|
||||
{
|
||||
var noExt = Path.withoutExtension(path);
|
||||
if (Assets.exists('$noExt/Animation.json'))
|
||||
{
|
||||
atlasPath = noExt;
|
||||
animateAtlas = new FlxAnimate(x, y, noExt);
|
||||
}
|
||||
else
|
||||
{
|
||||
frames = Paths.getFrames(path, true);
|
||||
}
|
||||
frames = Paths.getFrames(path, true, null, null, animateSettings);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -172,50 +173,22 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
{
|
||||
}
|
||||
|
||||
// ANIMATE ATLAS DRAWING
|
||||
#if REGION
|
||||
public override function draw()
|
||||
{
|
||||
if (animateAtlas != null)
|
||||
{
|
||||
copyAtlasValues();
|
||||
animateAtlas.draw();
|
||||
}
|
||||
else
|
||||
{
|
||||
super.draw();
|
||||
}
|
||||
public override function draw() {
|
||||
// re-implementing the `onDraw` functionality from `FlxSprite` since `FlxAnimate` didn't have this, so we have to add it back in ourselves
|
||||
if (this.isAnimate && this.__drawOverrided) {
|
||||
this.__drawOverrided = false;
|
||||
this.onDraw(this);
|
||||
this.__drawOverrided = true;
|
||||
return;
|
||||
}
|
||||
super.draw();
|
||||
}
|
||||
|
||||
public function copyAtlasValues()
|
||||
{
|
||||
@:privateAccess {
|
||||
animateAtlas.cameras = cameras; // investigate if we can use _cameras
|
||||
animateAtlas.scrollFactor = scrollFactor;
|
||||
animateAtlas.scale = scale;
|
||||
animateAtlas.offset = offset;
|
||||
animateAtlas.frameOffset = frameOffset;
|
||||
animateAtlas.x = x;
|
||||
animateAtlas.y = y;
|
||||
animateAtlas.angle = angle;
|
||||
animateAtlas.alpha = alpha;
|
||||
animateAtlas.visible = visible;
|
||||
animateAtlas.flipX = flipX;
|
||||
animateAtlas.flipY = flipY;
|
||||
animateAtlas.shader = shader;
|
||||
animateAtlas.shaderEnabled = shaderEnabled;
|
||||
animateAtlas.antialiasing = antialiasing;
|
||||
animateAtlas.skew = skew;
|
||||
animateAtlas.transformMatrix = transformMatrix;
|
||||
animateAtlas.matrixExposed = matrixExposed;
|
||||
animateAtlas.colorTransform = colorTransform;
|
||||
}
|
||||
}
|
||||
// ANIMATE ATLAS DRAWING
|
||||
#if REGION
|
||||
|
||||
public override function destroy()
|
||||
{
|
||||
animateAtlas = FlxDestroyUtil.destroy(animateAtlas);
|
||||
|
||||
if (animOffsets != null) {
|
||||
for (key in animOffsets.keys()) {
|
||||
final point = animOffsets[key];
|
||||
@@ -226,6 +199,8 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
animOffsets = null;
|
||||
}
|
||||
super.destroy();
|
||||
|
||||
_rect2 = FlxDestroyUtil.put(_rect2);
|
||||
}
|
||||
#end
|
||||
|
||||
@@ -233,27 +208,21 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
private inline function __shouldDoZoomFactor()
|
||||
return zoomFactorEnabled && zoomFactor != 1;
|
||||
|
||||
public override function getScreenBounds(?newRect:FlxRect, ?camera:FlxCamera):FlxRect
|
||||
{
|
||||
if (camera == null)
|
||||
camera = FlxG.camera;
|
||||
|
||||
var r = super.getScreenBounds(newRect, camera);
|
||||
|
||||
if(__shouldDoZoomFactor()) {
|
||||
r.x -= camera.width / 2;
|
||||
r.y -= camera.height / 2;
|
||||
|
||||
var ratio = (camera.zoom > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.zoom, 1, zoomFactor));
|
||||
r.x *= ratio;
|
||||
r.y *= ratio;
|
||||
r.width *= ratio;
|
||||
r.height *= ratio;
|
||||
|
||||
r.x += camera.width / 2;
|
||||
r.y += camera.height / 2;
|
||||
}
|
||||
return r;
|
||||
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))
|
||||
);
|
||||
}
|
||||
|
||||
override public function isOnScreen(?camera:FlxCamera):Bool
|
||||
@@ -270,20 +239,6 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
return camera.containsRect(bounds);
|
||||
}
|
||||
|
||||
// ZOOM FACTOR RENDERING
|
||||
public override function doAdditionalMatrixStuff(matrix:FlxMatrix, camera:FlxCamera)
|
||||
{
|
||||
super.doAdditionalMatrixStuff(matrix, camera);
|
||||
if(__shouldDoZoomFactor()) {
|
||||
matrix.translate(-camera.width / 2, -camera.height / 2);
|
||||
|
||||
var requestedZoom = (camera.zoom >= 0 ? Math.max : Math.min)(FlxMath.lerp(1, camera.zoom, zoomFactor), 0);
|
||||
var diff = requestedZoom / camera.zoom;
|
||||
matrix.scale(diff, diff);
|
||||
matrix.translate(camera.width / 2, camera.height / 2);
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSETTING
|
||||
#if REGION
|
||||
public var animOffsets:Map<String, FlxPoint> = new Map<String, FlxPoint>();
|
||||
@@ -307,7 +262,7 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
|
||||
public function playAnim(AnimName:String, ?Force:Null<Bool>, Context:PlayAnimContext = NONE, Reversed:Bool = false, Frame:Int = 0):Void
|
||||
{
|
||||
if (AnimName == null)
|
||||
if (AnimName == null || (!hasAnim(AnimName) && !debugMode))
|
||||
return;
|
||||
|
||||
if (Force == null) {
|
||||
@@ -315,19 +270,7 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
Force = anim != null && anim.forced;
|
||||
}
|
||||
|
||||
if (animateAtlas != null)
|
||||
{
|
||||
@:privateAccess
|
||||
// if (!animateAtlas.anim.animsMap.exists(AnimName) && !animateAtlas.anim.symbolDictionary.exists(AnimName)) return;
|
||||
animateAtlas.anim.play(AnimName, Force, Reversed, Frame);
|
||||
atlasPlayingAnim = AnimName;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!animation.exists(AnimName) && !debugMode)
|
||||
return;
|
||||
animation.play(AnimName, Force, Reversed, Frame);
|
||||
}
|
||||
animation.play(AnimName, Force, Reversed, Frame);
|
||||
|
||||
var daOffset = getAnimOffset(AnimName);
|
||||
frameOffset.set(daOffset.x, daOffset.y);
|
||||
@@ -336,7 +279,7 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
lastAnimContext = Context;
|
||||
}
|
||||
|
||||
public inline function addAnim(name:String, prefix:String, frameRate:Float = 24, ?looped:Bool, ?forced:Bool, ?indices:Array<Int>, x:Float = 0, y:Float = 0, animType:XMLAnimType = NONE)
|
||||
public inline function addAnim(name:String, prefix:String, frameRate:Float = 24, ?looped:Bool, ?forced:Bool, ?indices:Array<Int>, x:Float = 0, y:Float = 0, animType:XMLAnimType = NONE, animateAtlasLabel:Bool = false)
|
||||
{
|
||||
return XMLUtil.addAnimToSprite(this, {
|
||||
name: name,
|
||||
@@ -347,22 +290,16 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
x: x,
|
||||
y: y,
|
||||
indices: indices,
|
||||
forced: forced
|
||||
forced: forced,
|
||||
label: animateAtlasLabel
|
||||
});
|
||||
}
|
||||
|
||||
public inline function removeAnim(name:String)
|
||||
{
|
||||
if (animateAtlas != null)
|
||||
@:privateAccess animateAtlas.anim.animsMap.remove(name);
|
||||
else
|
||||
animation.remove(name);
|
||||
public inline function removeAnim(name:String) {
|
||||
animation.remove(name);
|
||||
}
|
||||
|
||||
public function getAnim(name:String):OneOfTwo<FlxAnimation, FlxSymbolAnimation>
|
||||
{
|
||||
if(animateAtlas != null)
|
||||
return animateAtlas.anim.getByName(name);
|
||||
public function getAnim(name:String):OneOfTwo<FlxAnimation, FlxAnimateAnimation> {
|
||||
return animation.getByName(name);
|
||||
}
|
||||
|
||||
@@ -373,40 +310,26 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
return FlxPoint.weak(0, 0);
|
||||
}
|
||||
|
||||
public inline function hasAnim(AnimName:String):Bool @:privateAccess
|
||||
return animateAtlas != null ? (animateAtlas.anim.animsMap.exists(AnimName)
|
||||
|| animateAtlas.anim.symbolDictionary.exists(AnimName)) : animation.exists(AnimName);
|
||||
public inline function hasAnim(AnimName:String):Bool
|
||||
return animation.exists(AnimName);
|
||||
|
||||
public inline function getAnimName() {
|
||||
return (animateAtlas != null) ? atlasPlayingAnim : animation.name;
|
||||
}
|
||||
public inline function getAnimName()
|
||||
return animation.name;
|
||||
|
||||
public inline function isAnimReversed():Bool {
|
||||
return animateAtlas != null ? animateAtlas.anim.reversed : animation.curAnim != null ? animation.curAnim.reversed : false;
|
||||
}
|
||||
public inline function isAnimReversed():Bool
|
||||
return animation.curAnim?.reversed ?? false;
|
||||
|
||||
public inline function getNameList():Array<String> {
|
||||
if (animateAtlas != null)
|
||||
return [for (name in @:privateAccess animateAtlas.anim.animsMap.keys()) name];
|
||||
else
|
||||
return animation.getNameList();
|
||||
}
|
||||
public inline function getNameList():Array<String>
|
||||
return animation.getNameList();
|
||||
|
||||
public inline function stopAnim()
|
||||
{
|
||||
if (animateAtlas != null)
|
||||
animateAtlas.anim.pause();
|
||||
else
|
||||
animation.stop();
|
||||
}
|
||||
animation.stop();
|
||||
|
||||
public inline function isAnimFinished() {
|
||||
return animateAtlas != null ? animateAtlas.anim.finished : (animation.curAnim != null ? animation.curAnim.finished : true);
|
||||
}
|
||||
public inline function isAnimFinished()
|
||||
return animation.curAnim?.finished ?? true;
|
||||
|
||||
public inline function isAnimAtEnd() {
|
||||
return animateAtlas != null ? animateAtlas.anim.isAtEnd : (animation.curAnim != null ? animation.curAnim.isAtEnd : false);
|
||||
}
|
||||
public inline function isAnimAtEnd()
|
||||
return animation.curAnim?.isAtEnd ?? false;
|
||||
|
||||
override function updateAnimation(elapsed:Float) {
|
||||
if (animEnabled)
|
||||
@@ -414,9 +337,9 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
}
|
||||
|
||||
// Backwards compat (the names used to be all different and it sucked, please lets use the same format in the future) - Nex
|
||||
public inline function hasAnimation(AnimName:String) return hasAnim(AnimName);
|
||||
public inline function removeAnimation(name:String) return removeAnim(name);
|
||||
public inline function stopAnimation() return stopAnim();
|
||||
@:dox(hide) public inline function hasAnimation(AnimName:String) return hasAnim(AnimName);
|
||||
@:dox(hide) public inline function removeAnimation(name:String) return removeAnim(name);
|
||||
@:dox(hide) public inline function stopAnimation() return stopAnim();
|
||||
#end
|
||||
|
||||
// Getter / Setters
|
||||
@@ -428,10 +351,38 @@ class FunkinSprite extends FlxSkewedSprite implements IBeatReceiver implements I
|
||||
return beatInterval = v;
|
||||
}
|
||||
|
||||
@:noCompletion private inline function get_globalCurFrame() {
|
||||
return animateAtlas != null ? (animateAtlas.anim.curFrame) : (animation.curAnim != null ? animation.curAnim.curFrame : 0);
|
||||
}
|
||||
@:noCompletion
|
||||
@:deprecated("`FunkinSprite.animateAtlas` is deprecated, just use `FunkinSprite` instead")
|
||||
public function get_animateAtlas():FunkinSprite
|
||||
return isAnimate ? this : null;
|
||||
|
||||
@:noCompletion private inline function get_globalCurFrame()
|
||||
return animation.curAnim?.curFrame ?? 0;
|
||||
|
||||
@:noCompletion private inline function set_globalCurFrame(val:Int) {
|
||||
return animateAtlas != null ? (animateAtlas.anim.curFrame = val) : (animation.curAnim != null ? animation.curAnim.curFrame = val : val);
|
||||
if (animation.curAnim != null)
|
||||
animation.curAnim.curFrame = val;
|
||||
return val;
|
||||
}
|
||||
|
||||
override function prepareDrawMatrix(matrix:FlxMatrix, camera:FlxCamera):Void {
|
||||
super.prepareDrawMatrix(matrix, camera);
|
||||
|
||||
if (__shouldDoZoomFactor()) {
|
||||
__prepareZoomFactor(_rect2, camera);
|
||||
matrix.setTo(
|
||||
matrix.a * _rect2.width, matrix.b * _rect2.height,
|
||||
matrix.c * _rect2.width, matrix.d * _rect2.height,
|
||||
(matrix.tx - _rect2.x) * _rect2.width + _rect2.x,
|
||||
(matrix.ty - _rect2.y) * _rect2.height + _rect2.y,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
override function checkFlipX() {
|
||||
return super.checkFlipX() != camera.flipX;
|
||||
}
|
||||
override function checkFlipY() {
|
||||
return super.checkFlipY() != camera.flipY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,98 @@
|
||||
package funkin.backend;
|
||||
|
||||
import flixel.FlxCamera;
|
||||
import flixel.FlxG;
|
||||
import flixel.math.FlxMath;
|
||||
import flixel.text.FlxText;
|
||||
import flixel.util.FlxColor;
|
||||
import funkin.backend.system.Flags;
|
||||
|
||||
class FunkinText extends FlxText
|
||||
{
|
||||
public var zoomFactor:Float = 1;
|
||||
public var zoomFactorEnabled:Bool = true;
|
||||
|
||||
public function new(X:Float = 0, Y:Float = 0, FieldWidth:Float = 0, ?Text:String, ?Size:Int, Border:Bool = true)
|
||||
{
|
||||
if (Size == null)
|
||||
Size = Flags.DEFAULT_FONT_SIZE;
|
||||
|
||||
class FunkinText extends FlxText {
|
||||
public function new(X:Float = 0, Y:Float = 0, FieldWidth:Float = 0, ?Text:String, Size:Int = 16, Border:Bool = true) {
|
||||
super(X, Y, FieldWidth, Text, Size);
|
||||
setFormat(Paths.font("vcr.ttf"), Size, FlxColor.WHITE);
|
||||
if (Border) {
|
||||
|
||||
setFormat(Paths.font(Flags.DEFAULT_FONT), Size, FlxColor.WHITE);
|
||||
|
||||
if (Border)
|
||||
{
|
||||
borderStyle = OUTLINE;
|
||||
borderSize = 1;
|
||||
borderColor = 0xFF000000;
|
||||
}
|
||||
}
|
||||
|
||||
private inline function __shouldDoZoomFactor():Bool
|
||||
{
|
||||
return zoomFactorEnabled && zoomFactor != 1;
|
||||
}
|
||||
|
||||
private inline function __getZoomScaleX(camera:FlxCamera):Float
|
||||
{
|
||||
return (camera.scaleX > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.scaleX, 1, zoomFactor));
|
||||
}
|
||||
|
||||
private inline function __getZoomScaleY(camera:FlxCamera):Float
|
||||
{
|
||||
return (camera.scaleY > 0 ? Math.max : Math.min)(0, FlxMath.lerp(1 / camera.scaleY, 1, zoomFactor));
|
||||
}
|
||||
|
||||
private inline function __getZoomAnchorX(camera:FlxCamera):Float
|
||||
{
|
||||
if (Flags.USE_LEGACY_ZOOM_FACTOR)
|
||||
return camera.width * 0.5;
|
||||
|
||||
return camera.width * 0.5 + camera.scroll.x * scrollFactor.x;
|
||||
}
|
||||
|
||||
private inline function __getZoomAnchorY(camera:FlxCamera):Float
|
||||
{
|
||||
if (Flags.USE_LEGACY_ZOOM_FACTOR)
|
||||
return camera.height * 0.5;
|
||||
|
||||
return camera.height * 0.5 + camera.scroll.y * scrollFactor.y;
|
||||
}
|
||||
|
||||
override public function draw():Void
|
||||
{
|
||||
if (!__shouldDoZoomFactor())
|
||||
{
|
||||
super.draw();
|
||||
return;
|
||||
}
|
||||
|
||||
var camera:FlxCamera = this.camera;
|
||||
|
||||
if (camera == null)
|
||||
camera = FlxG.camera;
|
||||
|
||||
var oldX:Float = x;
|
||||
var oldY:Float = y;
|
||||
var oldScaleX:Float = scale.x;
|
||||
var oldScaleY:Float = scale.y;
|
||||
|
||||
var zoomScaleX:Float = __getZoomScaleX(camera);
|
||||
var zoomScaleY:Float = __getZoomScaleY(camera);
|
||||
|
||||
var anchorX:Float = __getZoomAnchorX(camera);
|
||||
var anchorY:Float = __getZoomAnchorY(camera);
|
||||
|
||||
x = (x - anchorX) * zoomScaleX + anchorX;
|
||||
y = (y - anchorY) * zoomScaleY + anchorY;
|
||||
|
||||
scale.set(scale.x * zoomScaleX, scale.y * zoomScaleY);
|
||||
|
||||
super.draw();
|
||||
|
||||
x = oldX;
|
||||
y = oldY;
|
||||
scale.set(oldScaleX, oldScaleY);
|
||||
}
|
||||
}
|
||||
@@ -275,6 +275,12 @@ class MusicBeatState extends FlxState implements IBeatCancellableReceiver
|
||||
if (!e.cancelled)
|
||||
super.openSubState(e.substate is FlxSubState ? cast e.substate : subState);
|
||||
}
|
||||
|
||||
public override function closeSubState() {
|
||||
var e = event("onCloseSubState", EventManager.get(StateEvent).recycle(subState));
|
||||
if (!e.cancelled)
|
||||
super.closeSubState();
|
||||
}
|
||||
|
||||
public override function onResize(w:Int, h:Int) {
|
||||
super.onResize(w, h);
|
||||
|
||||
@@ -236,6 +236,12 @@ class MusicBeatSubstate extends FlxSubState implements IBeatCancellableReceiver
|
||||
super.openSubState(e.substate is FlxSubState ? cast e.substate : subState);
|
||||
}
|
||||
|
||||
public override function closeSubState() {
|
||||
var e = event("onCloseSubState", EventManager.get(StateEvent).recycle(subState));
|
||||
if (!e.cancelled)
|
||||
super.closeSubState();
|
||||
}
|
||||
|
||||
public override function onResize(w:Int, h:Int) {
|
||||
super.onResize(w, h);
|
||||
event("onResize", EventManager.get(ResizeEvent).recycle(w, h, null, null));
|
||||
|
||||
@@ -114,12 +114,8 @@ class MusicBeatTransition extends MusicBeatSubstate {
|
||||
}
|
||||
|
||||
if (transitionSprite != null) {
|
||||
if (transitionSprite.animateAtlas == null) {
|
||||
transitionSprite.setGraphicSize(transitionCamera.width, transitionCamera.height);
|
||||
transitionSprite.updateHitbox();
|
||||
} else {
|
||||
transitionSprite.screenCenter();
|
||||
}
|
||||
transitionSprite.setGraphicSize(transitionCamera.width, transitionCamera.height);
|
||||
transitionSprite.updateHitbox();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,9 +5,22 @@ import funkin.backend.assets.TranslatedAssetLibrary;
|
||||
#end
|
||||
import funkin.backend.assets.IModsAssetLibrary;
|
||||
import lime.utils.AssetLibrary;
|
||||
import haxe.ds.Map;
|
||||
|
||||
class AssetsLibraryList extends AssetLibrary {
|
||||
|
||||
public var libraries:Array<AssetLibrary> = [];
|
||||
public var cleanLibraries(get, never):Array<AssetLibrary>;
|
||||
function get_cleanLibraries():Array<AssetLibrary> {
|
||||
return [for (l in libraries) getCleanLibrary(l)];
|
||||
}
|
||||
|
||||
// is true if any library in `libraries` contains some kind of compressed library.
|
||||
public var hasCompressedLibrary(get, never):Bool;
|
||||
function get_hasCompressedLibrary():Bool {
|
||||
for (l in libraries) if (getCleanLibrary(l).isCompressed) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@:allow(funkin.backend.system.Main)
|
||||
@:allow(funkin.backend.system.MainState)
|
||||
@@ -141,6 +154,16 @@ class AssetsLibraryList extends AssetLibrary {
|
||||
public override inline function getAsset(id:String, type:String):Dynamic
|
||||
return getSpecificAsset(id, type, BOTH);
|
||||
|
||||
public override function list(type:String):Array<String> {
|
||||
// idk if there's a more efficient way tbh, correct if u find better
|
||||
var files:Map<String, Bool> = [];
|
||||
for(k=>l in libraries) {
|
||||
for(f in l.list(type))
|
||||
files.set(f, false);
|
||||
}
|
||||
return [for(k=>e in files) k];
|
||||
}
|
||||
|
||||
public override function isLocal(id:String, type:String) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -83,10 +83,11 @@ class ModsFolder {
|
||||
*/
|
||||
public static function loadModLib(path:String, force:Bool = false, ?modName:String) {
|
||||
#if MOD_SUPPORT
|
||||
if (FileSystem.exists('$path.zip'))
|
||||
return loadLibraryFromZip('$path'.toLowerCase(), '$path.zip', force, modName);
|
||||
else
|
||||
return loadLibraryFromFolder('$path'.toLowerCase(), '$path', force, modName);
|
||||
for (ext in Flags.ALLOWED_ZIP_EXTENSIONS) {
|
||||
if (!FileSystem.exists('$path.$ext')) continue;
|
||||
return loadLibraryFromZip('$path'.toLowerCase(), '$path.$ext', force, modName);
|
||||
}
|
||||
return loadLibraryFromFolder('$path'.toLowerCase(), '$path', force, modName);
|
||||
|
||||
#else
|
||||
return null;
|
||||
@@ -96,27 +97,16 @@ class ModsFolder {
|
||||
public static function getModsList():Array<String> {
|
||||
var mods:Array<String> = [];
|
||||
#if MOD_SUPPORT
|
||||
if (!FileSystem.exists(modsPath)) {
|
||||
// Mods directory does not exist yet, create it
|
||||
FileSystem.createDirectory(modsPath);
|
||||
}
|
||||
// Mods directory does not exist yet, create it
|
||||
if (!FileSystem.exists(modsPath)) FileSystem.createDirectory(modsPath);
|
||||
|
||||
final modsList:Array<String> = FileSystem.readDirectory(modsPath);
|
||||
|
||||
if (modsList == null || modsList.length <= 0)
|
||||
return mods;
|
||||
if (modsList == null || modsList.length <= 0) return mods;
|
||||
|
||||
for (modFolder in modsList) {
|
||||
if (FileSystem.isDirectory(modsPath + modFolder)) {
|
||||
mods.push(modFolder);
|
||||
} else {
|
||||
var ext = Path.extension(modFolder).toLowerCase();
|
||||
switch(ext) {
|
||||
case 'zip':
|
||||
// is a zip mod!!
|
||||
mods.push(Path.withoutExtension(modFolder));
|
||||
}
|
||||
}
|
||||
if (FileSystem.isDirectory(modsPath + modFolder)) mods.push(modFolder);
|
||||
else if (Flags.ALLOWED_ZIP_EXTENSIONS.contains(Path.extension(modFolder))) mods.push(Path.withoutExtension(modFolder));
|
||||
}
|
||||
#end
|
||||
return mods;
|
||||
@@ -128,7 +118,9 @@ class ModsFolder {
|
||||
#if TRANSLATIONS_SUPPORT
|
||||
if(skipTranslated && (l is TranslatedAssetLibrary)) continue;
|
||||
#end
|
||||
if (l is ScriptedAssetLibrary || l is IModsAssetLibrary) libs.push(cast(l, IModsAssetLibrary));
|
||||
// No need to check for it being a `ScriptedAssetLibrary`, if `ScriptedAssetLibrary` extends ModsFolderLibrary, which implements `IModsAssetLibrary`
|
||||
// If you have to revert this change then uhhhhh wasn't me, trust 🙏
|
||||
if (/*l is ScriptedAssetLibrary ||*/ l is IModsAssetLibrary) libs.push(cast(l, IModsAssetLibrary));
|
||||
}
|
||||
return libs;
|
||||
}
|
||||
|
||||
@@ -149,6 +149,22 @@ class ModsFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override function list(type:String):Array<String> {
|
||||
var result = [];
|
||||
__listAppend(result, '');
|
||||
return result;
|
||||
}
|
||||
|
||||
function __listAppend(arr:Array<String>, folder:String) {
|
||||
for(file in FileSystem.readDirectory('$basePath/$folder')) {
|
||||
var fullPath = '$basePath/$folder/$file';
|
||||
if (FileSystem.isDirectory(fullPath))
|
||||
__listAppend(arr, '$folder$file/');
|
||||
else
|
||||
arr.push('$prefix$folder$file');
|
||||
}
|
||||
}
|
||||
#end
|
||||
|
||||
// Backwards compat
|
||||
|
||||
@@ -8,6 +8,7 @@ import funkin.backend.scripting.Script;
|
||||
import haxe.io.Path;
|
||||
import lime.utils.AssetLibrary;
|
||||
import openfl.utils.Assets as OpenFlAssets;
|
||||
import animate.FlxAnimateFrames;
|
||||
|
||||
using StringTools;
|
||||
|
||||
@@ -174,6 +175,9 @@ class Paths
|
||||
inline static public function getSparrowAtlas(key:String, ?library:String, ?ext:String)
|
||||
return FlxAtlasFrames.fromSparrow(image(key, library, ext), file('images/$key.xml', library));
|
||||
|
||||
inline static public function getAnimateAtlasAlt(key:String, ?settings:FlxAnimateSettings)
|
||||
return FlxAnimateFrames.fromAnimate(key, null, null, null, false, settings);
|
||||
|
||||
inline static public function getSparrowAtlasAlt(key:String, ?ext:String)
|
||||
return FlxAtlasFrames.fromSparrow('$key.${ext != null ? ext : Flags.IMAGE_EXT}', '$key.xml');
|
||||
|
||||
@@ -197,7 +201,7 @@ class Paths
|
||||
* @param key Path to the frames
|
||||
* @param library (Additional) library to load the frames from.
|
||||
*/
|
||||
public static function getFrames(key:String, assetsPath:Bool = false, ?library:String, ?ext:String = null) {
|
||||
public static function getFrames(key:String, assetsPath:Bool = false, ?library:String, ?ext:String = null, ?animateSettings:FlxAnimateSettings) {
|
||||
if (tempFramesCache.exists(key)) {
|
||||
var frames = tempFramesCache[key];
|
||||
if (frames != null && frames.parent != null && frames.parent.bitmap != null && frames.parent.bitmap.readable)
|
||||
@@ -205,7 +209,7 @@ class Paths
|
||||
else
|
||||
tempFramesCache.remove(key);
|
||||
}
|
||||
return tempFramesCache[key] = loadFrames(assetsPath ? key : Paths.image(key, library, true, ext), false, null, false, ext);
|
||||
return tempFramesCache[key] = loadFrames(assetsPath ? key : Paths.image(key, library, true, ext), false, null, false, ext, animateSettings);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -242,7 +246,7 @@ class Paths
|
||||
* @param Ext Extension of the image.
|
||||
* @return FlxFramesCollection Frames
|
||||
*/
|
||||
static function loadFrames(path:String, Unique:Bool = false, Key:String = null, SkipAtlasCheck:Bool = false, SkipMultiCheck:Bool = false, ?Ext:String = null):FlxFramesCollection {
|
||||
static function loadFrames(path:String, Unique:Bool = false, Key:String = null, SkipAtlasCheck:Bool = false, SkipMultiCheck:Bool = false, ?Ext:String = null, ?animateSettings:FlxAnimateSettings):FlxFramesCollection {
|
||||
var noExt = Path.withoutExtension(path);
|
||||
var ext = Ext != null ? Ext : Flags.IMAGE_EXT;
|
||||
|
||||
@@ -263,6 +267,8 @@ class Paths
|
||||
cur++;
|
||||
}
|
||||
return finalFrames;
|
||||
} else if (Assets.exists('$noExt/Animation.json')) {
|
||||
return Paths.getAnimateAtlasAlt(noExt, animateSettings);
|
||||
} else if (Assets.exists('$noExt.xml')) {
|
||||
return Paths.getSparrowAtlasAlt(noExt, ext);
|
||||
} else if (Assets.exists('$noExt.txt')) {
|
||||
|
||||
@@ -108,6 +108,8 @@ class TranslatedAssetLibrary extends AssetLibrary implements IModsAssetLibrary {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO: list support for TranslatedAssetLibrary (idk how it works)
|
||||
|
||||
#if MOD_SUPPORT
|
||||
public var _parsedAsset:String = null; // Theres no need to actually make this work - Nex
|
||||
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
package funkin.backend.assets;
|
||||
|
||||
import funkin.backend.system.Flags;
|
||||
|
||||
import haxe.io.Path;
|
||||
import lime.graphics.Image;
|
||||
import lime.media.AudioBuffer;
|
||||
import lime.text.Font;
|
||||
import lime.utils.Bytes;
|
||||
import openfl.utils.AssetLibrary;
|
||||
#if sys
|
||||
import sys.io.File;
|
||||
#end
|
||||
|
||||
#if MOD_SUPPORT
|
||||
import funkin.backend.utils.SysZip.SysZipEntry;
|
||||
@@ -15,15 +20,16 @@ class ZipFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
|
||||
public var basePath:String;
|
||||
public var modName:String;
|
||||
public var libName:String;
|
||||
public var useImageCache:Bool = false;
|
||||
public var prefix = 'assets/';
|
||||
|
||||
|
||||
public var zip:SysZip;
|
||||
public var assets:Map<String, SysZipEntry> = [];
|
||||
public var lowerCaseAssets:Map<String, SysZipEntry> = [];
|
||||
public var nameMap:Map<String, String> = [];
|
||||
|
||||
public function new(basePath:String, libName:String, ?modName:String) {
|
||||
public var PRELOAD_VIDEOS:Bool = true;
|
||||
|
||||
public function new(basePath:String, libName:String, ?modName:String, ?preloadVideos:Bool = true) {
|
||||
this.libName = libName;
|
||||
|
||||
this.basePath = basePath;
|
||||
@@ -31,21 +37,59 @@ class ZipFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
|
||||
this.modName = (modName == null) ? libName : modName;
|
||||
|
||||
zip = SysZip.openFromFile(basePath);
|
||||
zip.read();
|
||||
for(entry in zip.entries) {
|
||||
lowerCaseAssets[entry.fileName.toLowerCase()] = assets[entry.fileName.toLowerCase()] = assets[entry.fileName] = entry;
|
||||
nameMap.set(entry.fileName.toLowerCase(), entry.fileName);
|
||||
if (entry.fileName.length < 0 || entry.fileName.endsWith("/")) continue;
|
||||
|
||||
var name:String = entry.fileName.toLowerCase(); // calling .toLowerCase a million times is never the solution
|
||||
lowerCaseAssets[name] = assets[name] = assets[entry.fileName] = entry;
|
||||
nameMap.set(name, entry.fileName);
|
||||
}
|
||||
|
||||
super();
|
||||
|
||||
isCompressed = true;
|
||||
|
||||
// don't override default value of true if the file exists.
|
||||
// by default `PRELOAD_VIDEOS` is true so you will never need to add this file, but in the case of it being false this is a backup method.
|
||||
PRELOAD_VIDEOS = (!PRELOAD_VIDEOS) ? exists("assets/data/PRECACHE_VIDEOS", "TEXT") : PRELOAD_VIDEOS;
|
||||
|
||||
// if (PRELOAD_VIDEOS) precacheVideos(); // we do this in `MainState` now to handle for `Flags.VIDEO_EXT` :)
|
||||
}
|
||||
|
||||
public function precacheVideos() {
|
||||
_videoExtensions = [Flags.VIDEO_EXT];
|
||||
|
||||
videoCacheRemap = [];
|
||||
for (entry in zip.entries) {
|
||||
var name = entry.fileName.toLowerCase();
|
||||
if (_videoExtensions.contains(Path.extension(name))) getPath(prefix+name);
|
||||
}
|
||||
|
||||
var count:Int = 0;
|
||||
for (_ in videoCacheRemap.keys()) count++;
|
||||
if (count <= 0) return;
|
||||
trace('Precached $count video${(count == 1) ? "" : "s"}');
|
||||
}
|
||||
|
||||
// Now we have supports for videos in ZIP!!
|
||||
public var _videoExtensions:Array<String> = [Flags.VIDEO_EXT];
|
||||
public var videoCacheRemap:Map<String, String> = [];
|
||||
public function getVideoRemap(originalPath:String):String {
|
||||
if (!_videoExtensions.contains(Path.extension(_parsedAsset))) return originalPath;
|
||||
if (videoCacheRemap.exists(originalPath)) return videoCacheRemap.get(originalPath);
|
||||
|
||||
// We adding the length of the string to counteract folder in folder naming duplicates.
|
||||
var newPath = './.temp/${_parsedAsset.length}-zipvideo-${_parsedAsset.split("/").pop()}';
|
||||
File.saveBytes(newPath, unzip(assets[_parsedAsset]));
|
||||
videoCacheRemap.set(originalPath, newPath);
|
||||
return newPath;
|
||||
}
|
||||
|
||||
function toString():String {
|
||||
return '(ZipFolderLibrary: $libName/$modName)';
|
||||
return '(ZipFolderLibrary: $libName/$modName | ${zip.entries.length} entries | Detected Video Extensions: ${_videoExtensions.join(", ")})';
|
||||
}
|
||||
|
||||
public var _parsedAsset:String;
|
||||
|
||||
public override function getAudioBuffer(id:String):AudioBuffer {
|
||||
__parseAsset(id);
|
||||
return AudioBuffer.fromBytes(unzip(assets[_parsedAsset]));
|
||||
@@ -68,15 +112,12 @@ class ZipFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
|
||||
return getAssetPath();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public inline function unzip(f:SysZipEntry)
|
||||
return f == null ? null : zip.unzipEntry(f);
|
||||
public inline function unzip(f:SysZipEntry) return (f == null) ? null : zip.unzipEntry(f);
|
||||
|
||||
public function __parseAsset(asset:String):Bool {
|
||||
if (!asset.startsWith(prefix)) return false;
|
||||
_parsedAsset = asset.substr(prefix.length);
|
||||
if(ModsFolder.useLibFile) {
|
||||
if (ModsFolder.useLibFile) {
|
||||
var file = new haxe.io.Path(_parsedAsset);
|
||||
if(file.file.startsWith("LIB_")) {
|
||||
var library = file.file.substr(4);
|
||||
@@ -87,8 +128,7 @@ class ZipFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
|
||||
}
|
||||
|
||||
_parsedAsset = _parsedAsset.toLowerCase();
|
||||
if(nameMap.exists(_parsedAsset))
|
||||
_parsedAsset = nameMap.get(_parsedAsset);
|
||||
if (nameMap.exists(_parsedAsset)) _parsedAsset = nameMap.get(_parsedAsset);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -103,9 +143,8 @@ class ZipFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
|
||||
return assets[_parsedAsset] != null;
|
||||
}
|
||||
|
||||
private function getAssetPath() {
|
||||
trace('[ZIP]$basePath/$_parsedAsset');
|
||||
return '[ZIP]$basePath/$_parsedAsset';
|
||||
private inline function getAssetPath() {
|
||||
return getVideoRemap('$basePath/$_parsedAsset');
|
||||
}
|
||||
|
||||
// TODO: rewrite this to 1 function, like ModsFolderLibrary
|
||||
@@ -154,14 +193,6 @@ class ZipFolderLibrary extends AssetLibrary implements IModsAssetLibrary {
|
||||
return content;
|
||||
}
|
||||
|
||||
// Backwards compat
|
||||
|
||||
@:noCompletion public var zipPath(get, set):String;
|
||||
@:noCompletion private inline function get_zipPath():String {
|
||||
return basePath;
|
||||
}
|
||||
@:noCompletion private inline function set_zipPath(value:String):String {
|
||||
return basePath = value;
|
||||
}
|
||||
public override function list(type:String):Array<String> { return [for(k=>e in nameMap) '$prefix$e']; }
|
||||
}
|
||||
#end
|
||||
@@ -222,7 +222,7 @@ class Chart {
|
||||
}
|
||||
#end
|
||||
|
||||
var loadedMeta = loadChartMeta(songName, variant, base.fromMods, false);
|
||||
var loadedMeta = loadChartMeta(songName, variant, difficulty, base.fromMods, false);
|
||||
if (base.meta == null) base.meta = loadedMeta;
|
||||
else {
|
||||
for (field in Reflect.fields(base.meta)) {
|
||||
@@ -278,9 +278,13 @@ class Chart {
|
||||
var filteredChart = filterChartForSaving(chart, saveSettings.saveMetaInChart, saveSettings.saveLocalEvents, saveSettings.saveGlobalEvents && saveSettings.seperateGlobalEvents != true);
|
||||
|
||||
#if sys
|
||||
var songPath = saveSettings.songFolder == null ? 'songs/${chart.meta.name}' : saveSettings.songFolder, variantSuffix = variant != null && variant != "" ? '-$variant' : "";
|
||||
var metaPath = 'meta$variantSuffix.json', prettyPrint = saveSettings.prettyPrint == true ? Flags.JSON_PRETTY_PRINT : null, temp:String;
|
||||
if ((temp = Paths.assetsTree.getPath('assets/$songPath/$metaPath')) != null) {
|
||||
var songPath = saveSettings.songFolder == null ? 'songs/${chart.meta.name}' : saveSettings.songFolder, variantSuffix = variant != null && variant != "" ? '-$variant' : "", difficultySuffix = difficulty != null && difficulty != "" ? '-$difficulty' : "";
|
||||
var metaPath = 'meta$variantSuffix.json', altMetaPath = 'meta${variantSuffix}${difficultySuffix}.json', prettyPrint = saveSettings.prettyPrint == true ? Flags.JSON_PRETTY_PRINT : null, temp:String;
|
||||
if ((temp = Paths.assetsTree.getPath('assets/$songPath/$altMetaPath')) != null) { //check for difficulty specific
|
||||
songPath = temp.substr(0, temp.length - altMetaPath.length - 1);
|
||||
metaPath = temp;
|
||||
}
|
||||
else if ((temp = Paths.assetsTree.getPath('assets/$songPath/$metaPath')) != null) {
|
||||
songPath = temp.substr(0, temp.length - metaPath.length - 1);
|
||||
metaPath = temp;
|
||||
}
|
||||
@@ -300,6 +304,7 @@ class Chart {
|
||||
var eventsPath = '$songPath/events$variantSuffix.json', events = filterEventsForSaving(chart.events, false, true);
|
||||
|
||||
if (events.length != 0) CoolUtil.safeSaveFile(eventsPath, Json.stringify({events: events}, null, prettyPrint));
|
||||
else if (FileSystem.exists(eventsPath)) FileSystem.deleteFile(eventsPath); // If there's no events to save, then get rid of the file (if it exists already).
|
||||
}
|
||||
#end
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ class EventsData {
|
||||
defValue: "In"
|
||||
},
|
||||
{name: "Mode", type: TDropDown(['direct', 'stage']), defValue: "direct"},
|
||||
{name: "Multiplicative?", type: TBool, defValue: true}
|
||||
{name: "Multiplicative?", type: TBool, defValue: false}
|
||||
],
|
||||
"Camera Modulo Change" => [
|
||||
{name: "Modulo Interval", type: TInt(1, 9999999, 1), defValue: 4},
|
||||
@@ -164,8 +164,10 @@ class EventsData {
|
||||
|
||||
if (fileTxt.trim() == "") continue;
|
||||
|
||||
eventsList.push(eventName);
|
||||
eventsParams.set(eventName, []);
|
||||
if (!eventsList.contains(eventName)) {
|
||||
eventsList.push(eventName);
|
||||
eventsParams.set(eventName, []);
|
||||
}
|
||||
|
||||
try {
|
||||
var data:EventInfoFile = cast Json.parse(fileTxt);
|
||||
@@ -177,7 +179,8 @@ class EventsData {
|
||||
finalParams.push({
|
||||
name: paramData.name,
|
||||
type: hscriptInterp.expr(hscriptParser.parseString(paramData.type)),
|
||||
defValue: paramData.defaultValue
|
||||
defValue: paramData.defaultValue,
|
||||
saveIfDefault: paramData.saveIfDefault
|
||||
});
|
||||
} catch (e) {trace('Error parsing event param ${paramData.name} - ${eventName}: $e'); finalParams.push(null);}
|
||||
}
|
||||
@@ -194,6 +197,7 @@ typedef EventInfoFile = {
|
||||
var name:String;
|
||||
var type:String;
|
||||
var defaultValue:Dynamic;
|
||||
var ?saveIfDefault:Bool;
|
||||
}>;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ class PsychParser {
|
||||
note.time, // TIME
|
||||
note.id, // DATA
|
||||
note.sLen, // SUSTAIN LENGTH
|
||||
chart.noteTypes.getDefault([""])[note.type] // NOTE TYPE
|
||||
chart.noteTypes.getDefault([""])[note.type - 1] // NOTE TYPE
|
||||
];
|
||||
|
||||
if ((swagSection.mustHitSection && strumLine.type == OPPONENT) ||
|
||||
|
||||
@@ -55,9 +55,6 @@ class GlobalScript {
|
||||
reloading = false;
|
||||
MusicBeatState.ALLOW_DEV_RELOAD = _lastAllow_Reload;
|
||||
}
|
||||
|
||||
if (PlayerSettings.solo.controls.DEV_CONSOLE)
|
||||
NativeAPI.allocConsole();
|
||||
});
|
||||
FlxG.signals.preDraw.add(function() {
|
||||
call("preDraw");
|
||||
@@ -106,38 +103,41 @@ class GlobalScript {
|
||||
});
|
||||
}
|
||||
|
||||
public static function event<T:CancellableEvent>(name:String, event:T):T {
|
||||
if (scripts != null)
|
||||
scripts.event(name, event);
|
||||
return event;
|
||||
}
|
||||
|
||||
public static function call(name:String, ?args:Array<Dynamic>) {
|
||||
if (scripts != null)
|
||||
scripts.call(name, args);
|
||||
}
|
||||
|
||||
public static function onModSwitch(newMod:String) {
|
||||
call("destroy");
|
||||
scripts = FlxDestroyUtil.destroy(scripts);
|
||||
destroy();
|
||||
scripts = new ScriptPack("GlobalScript");
|
||||
for (i in funkin.backend.assets.ModsFolder.getLoadedMods()) {
|
||||
var path = Paths.script('data/global/LIB_$i');
|
||||
for (lib in funkin.backend.assets.ModsFolder.getLoadedModsLibs()) {
|
||||
var modName = lib.modName;
|
||||
var path = Paths.script('data/global/LIB_$modName');
|
||||
var script = Script.create(path);
|
||||
if (script is DummyScript)
|
||||
continue;
|
||||
script.remappedNames.set(script.fileName, '$i:${script.fileName}');
|
||||
if (script is DummyScript) continue;
|
||||
script.remappedNames.set(script.fileName, '$modName:${script.fileName}');
|
||||
// so you can get the current mod's library in GloablScript :)
|
||||
// you should not make this a static variable then all scripts will try to reference the 1 static variable, which will be overwritten :yoikes:
|
||||
script.set("MOD_LIBRARY", lib);
|
||||
scripts.add(script);
|
||||
script.load();
|
||||
}
|
||||
}
|
||||
|
||||
public static function beatHit(curBeat:Int) {
|
||||
call("beatHit", [curBeat]);
|
||||
public static inline function event<T:CancellableEvent>(name:String, event:T):T {
|
||||
if (scripts != null)
|
||||
scripts.event(name, event);
|
||||
return event;
|
||||
}
|
||||
|
||||
public static function stepHit(curStep:Int) {
|
||||
public static inline function call(name:String, ?args:Array<Dynamic>)
|
||||
if (scripts != null) scripts.call(name, args);
|
||||
|
||||
public static inline function beatHit(curBeat:Int)
|
||||
call("beatHit", [curBeat]);
|
||||
|
||||
public static inline function stepHit(curStep:Int)
|
||||
call("stepHit", [curStep]);
|
||||
|
||||
public static inline function destroy() if (scripts != null) {
|
||||
call("destroy");
|
||||
scripts = FlxDestroyUtil.destroy(scripts);
|
||||
}
|
||||
}
|
||||
#end
|
||||
@@ -34,6 +34,7 @@ class HScript extends Script {
|
||||
__importedPaths = [path];
|
||||
|
||||
interp.errorHandler = _errorHandler;
|
||||
interp.warnHandler = _warnHandler;
|
||||
interp.importFailedCallback = importFailedCallback;
|
||||
interp.staticVariables = Script.staticVariables;
|
||||
interp.allowStaticVariables = interp.allowPublicVariables = true;
|
||||
@@ -63,7 +64,7 @@ class HScript extends Script {
|
||||
return this;
|
||||
}
|
||||
|
||||
private function importFailedCallback(cl:Array<String>):Bool {
|
||||
private function importFailedCallback(cl:Array<String>, ?asName:String):Bool {
|
||||
if(_importFailedCallback(cl, "source/") || _importFailedCallback(cl, "")) {
|
||||
return true;
|
||||
}
|
||||
@@ -117,6 +118,24 @@ class HScript extends Script {
|
||||
], ERROR);
|
||||
}
|
||||
|
||||
private function _warnHandler(error:Error) {
|
||||
var fileName = error.origin;
|
||||
var oldfn = '$fileName:${error.line}: ';
|
||||
if(remappedNames.exists(fileName))
|
||||
fileName = remappedNames.get(fileName);
|
||||
var fn = '$fileName:${error.line}: ';
|
||||
var err = error.toString();
|
||||
while(err.startsWith(oldfn) || err.startsWith(fn)) {
|
||||
if (err.startsWith(oldfn)) err = err.substr(oldfn.length);
|
||||
if (err.startsWith(fn)) err = err.substr(fn.length);
|
||||
}
|
||||
|
||||
Logs.traceColored([
|
||||
Logs.logText(fn, GREEN),
|
||||
Logs.logText(err, YELLOW)
|
||||
], WARNING);
|
||||
}
|
||||
|
||||
public override function setParent(parent:Dynamic) {
|
||||
interp.scriptObject = parent;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
package funkin.backend.scripting;
|
||||
|
||||
#if ALLOW_MULTITHREADING
|
||||
import sys.thread.Thread;
|
||||
#end
|
||||
|
||||
import hscript.IHScriptCustomBehaviour;
|
||||
|
||||
class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBehaviour {
|
||||
var thread:#if ALLOW_MULTITHREADING Thread #else Dynamic #end;
|
||||
|
||||
/**
|
||||
* Script being ran.
|
||||
*/
|
||||
@@ -46,13 +40,6 @@ class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBe
|
||||
|
||||
script.load();
|
||||
|
||||
#if ALLOW_MULTITHREADING
|
||||
thread = Thread.createWithEventLoop(function() {
|
||||
// Prevent the thread from being auto deleted
|
||||
Thread.current().events.promise();
|
||||
});
|
||||
#end
|
||||
|
||||
__variables = Type.getInstanceFields(Type.getClass(this));
|
||||
}
|
||||
|
||||
@@ -69,7 +56,7 @@ class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBe
|
||||
|
||||
public function call(func:String, args:Array<Dynamic>) {
|
||||
#if ALLOW_MULTITHREADING
|
||||
thread.events.run(function() {
|
||||
funkin.backend.utils.ThreadUtil.execAsync(() -> {
|
||||
callEnded = false;
|
||||
returnValue = script.call(func, args);
|
||||
callEnded = true;
|
||||
@@ -85,13 +72,5 @@ class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBe
|
||||
script.call("destroy");
|
||||
script.destroy();
|
||||
}
|
||||
|
||||
#if ALLOW_MULTITHREADING
|
||||
if (thread != null) {
|
||||
thread.events.runPromised(function() {
|
||||
// close the thing
|
||||
});
|
||||
}
|
||||
#end
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,11 @@ class Script extends FlxBasic implements IFlxDestroyable {
|
||||
"Reflect" => Reflect,
|
||||
"StringTools" => StringTools,
|
||||
"Json" => haxe.Json,
|
||||
"Xml" => Xml,
|
||||
"Type" => Type,
|
||||
"Date" => Date,
|
||||
"Lambda" => Lambda,
|
||||
#if sys "Sys" => Sys, #end
|
||||
|
||||
// OpenFL & Lime related stuff
|
||||
"Assets" => openfl.utils.Assets,
|
||||
@@ -86,9 +91,10 @@ class Script extends FlxBasic implements IFlxDestroyable {
|
||||
"FunkinShader" => funkin.backend.shaders.FunkinShader,
|
||||
"CustomShader" => funkin.backend.shaders.CustomShader,
|
||||
"FunkinText" => funkin.backend.FunkinText,
|
||||
"FlxAnimate" => funkin.backend.FlxAnimate,
|
||||
"FlxAnimate" => animate.FlxAnimate,
|
||||
"FunkinSprite" => funkin.backend.FunkinSprite,
|
||||
"Alphabet" => funkin.menus.ui.Alphabet,
|
||||
"Flags" => funkin.backend.system.Flags,
|
||||
|
||||
"CoolUtil" => funkin.backend.utils.CoolUtil,
|
||||
"IniUtil" => funkin.backend.utils.IniUtil,
|
||||
@@ -96,6 +102,7 @@ class Script extends FlxBasic implements IFlxDestroyable {
|
||||
#if sys "ZipUtil" => funkin.backend.utils.ZipUtil, #end
|
||||
"MarkdownUtil" => funkin.backend.utils.MarkdownUtil,
|
||||
"EngineUtil" => funkin.backend.utils.EngineUtil,
|
||||
"ThreadUtil" => funkin.backend.utils.ThreadUtil,
|
||||
"MemoryUtil" => funkin.backend.utils.MemoryUtil,
|
||||
"BitmapUtil" => funkin.backend.utils.BitmapUtil,
|
||||
|
||||
@@ -395,4 +402,4 @@ class Script extends FlxBasic implements IFlxDestroyable {
|
||||
* Called when the script is loaded.
|
||||
*/
|
||||
public function onLoad() {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import flixel.util.FlxDestroyUtil.IFlxDestroyable;
|
||||
|
||||
@:allow(funkin.backend.scripting.ScriptPack)
|
||||
@:autoBuild(funkin.backend.system.macros.EventMacro.build())
|
||||
@:noCustomClass
|
||||
class CancellableEvent implements IFlxDestroyable {
|
||||
@:dox(hide) public var cancelled:Bool = false;
|
||||
@:dox(hide) private var __continueCalls:Bool = true;
|
||||
@@ -54,4 +53,4 @@ class CancellableEvent implements IFlxDestroyable {
|
||||
public function destroy() {
|
||||
data = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
package funkin.backend.scripting.events.gameplay;
|
||||
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.tweens.FlxTween;
|
||||
|
||||
final class RatingsShowEvent extends CancellableEvent
|
||||
{
|
||||
/**
|
||||
* Rating sprite (may be null)
|
||||
*/
|
||||
public var ratingSprite:Null<FlxSprite>;
|
||||
/**
|
||||
* Number sprite (may be null)
|
||||
*/
|
||||
public var numberSprite:Null<FlxSprite>;
|
||||
/**
|
||||
* Combo sprite (may be null)
|
||||
*/
|
||||
public var comboSprite:Null<FlxSprite>;
|
||||
/**
|
||||
* Scale of combo numbers. (may be null)
|
||||
*/
|
||||
public var numScale:Null<Float> = 0.5;
|
||||
/**
|
||||
* Whenever antialiasing should be enabled on combo numbers. (may be null)
|
||||
*/
|
||||
public var numAntialiasing:Null<Bool> = true;
|
||||
/**
|
||||
* Scale of the rating sprites. (may be null)
|
||||
*/
|
||||
public var ratingScale:Null<Float> = 0.7;
|
||||
/**
|
||||
* Whenever antialiasing should be enabled on ratings. (may be null)
|
||||
*/
|
||||
public var ratingAntialiasing:Null<Bool> = true;
|
||||
/**
|
||||
* Prefix of the rating sprite path. Defaults to "game/score/"
|
||||
*/
|
||||
public var ratingPrefix:String;
|
||||
/**
|
||||
* Suffix of the rating sprite path.
|
||||
*/
|
||||
public var ratingSuffix:String;
|
||||
/**
|
||||
* The sprite's acceleration.
|
||||
*/
|
||||
public var acceleration:Float;
|
||||
/**
|
||||
* A FlxPoint which x or y properties preposition the sprites current velocity.
|
||||
*/
|
||||
public var velocity:FlxPoint;
|
||||
/**
|
||||
* The duration of the sprite's alpha tween.
|
||||
*/
|
||||
public var tweenDuration:Float;
|
||||
/**
|
||||
* The start delay of the sprite's alpha tween.
|
||||
*/
|
||||
public var startDelay:Float;
|
||||
/**
|
||||
* Whenever the Rating sprites should be shown or not.
|
||||
*/
|
||||
public var displayRating:Bool;
|
||||
/**
|
||||
* Whenever the Rating sprites should be shown or not.
|
||||
*/
|
||||
public var displayNumbers:Bool;
|
||||
/**
|
||||
* Whenever the Combo sprite should be shown or not (like old Week 7 patches).
|
||||
*/
|
||||
public var displayCombo:Bool;
|
||||
/**
|
||||
* Whether the sprite should be tweened or not.
|
||||
*/
|
||||
public var playTween:Bool;
|
||||
/**
|
||||
* The amount of spacing for the combo numbers. (may be null)
|
||||
*/
|
||||
public var numSpacing:Null<Float>;
|
||||
/**
|
||||
* The position of the sprite.
|
||||
*/
|
||||
public var position:FlxPoint;
|
||||
/**
|
||||
* Whether to reset the sprite or not.
|
||||
*/
|
||||
public var resetSprite:Bool;
|
||||
/**
|
||||
* The rating name of the rating sprite. (may be null)
|
||||
*/
|
||||
public var rating:Null<String>;
|
||||
/**
|
||||
* The FlxTween instance. (null before "onPostRatingsShown")
|
||||
*/
|
||||
public var tween:Null<FlxTween>;
|
||||
}
|
||||
@@ -11,6 +11,7 @@ final class NoteHitEvent extends CancellableEvent {
|
||||
@:dox(hide) public var unmuteVocals:Bool = true;
|
||||
@:dox(hide) public var enableCamZooming:Bool = true;
|
||||
@:dox(hide) public var autoHitLastSustain:Bool = true;
|
||||
@:dox(hide) public var clipSustain:Bool = true;
|
||||
|
||||
/**
|
||||
* Whenever a miss should be added.
|
||||
@@ -33,11 +34,11 @@ final class NoteHitEvent extends CancellableEvent {
|
||||
/**
|
||||
* Whenever the Rating sprites should be shown or not.
|
||||
*/
|
||||
public var displayRating:Bool;
|
||||
public var displayRating:Null<Bool>;
|
||||
/**
|
||||
* Whenever the Combo sprite should be shown or not (like old Week 7 patches).
|
||||
*/
|
||||
public var displayCombo:Bool;
|
||||
public var displayCombo:Null<Bool>;
|
||||
/**
|
||||
* Note that has been pressed
|
||||
*/
|
||||
@@ -65,11 +66,11 @@ final class NoteHitEvent extends CancellableEvent {
|
||||
/**
|
||||
* Prefix of the rating sprite path. Defaults to "game/score/"
|
||||
*/
|
||||
public var ratingPrefix:String;
|
||||
public var ratingPrefix:Null<String>;
|
||||
/**
|
||||
* Suffix of the rating sprite path.
|
||||
*/
|
||||
public var ratingSuffix:String;
|
||||
public var ratingSuffix:Null<String>;
|
||||
/**
|
||||
* Direction of the press (0 = Left, 1 = Down, 2 = Up, 3 = Right)
|
||||
*/
|
||||
@@ -97,19 +98,19 @@ final class NoteHitEvent extends CancellableEvent {
|
||||
/**
|
||||
* Scale of combo numbers.
|
||||
*/
|
||||
public var numScale:Float = 0.5;
|
||||
public var numScale:Null<Float>;
|
||||
/**
|
||||
* Whenever antialiasing should be enabled on combo number.
|
||||
*/
|
||||
public var numAntialiasing:Bool = true;
|
||||
public var numAntialiasing:Null<Bool>;
|
||||
/**
|
||||
* Scale of ratings.
|
||||
*/
|
||||
public var ratingScale:Float = 0.7;
|
||||
public var ratingScale:Null<Float>;
|
||||
/**
|
||||
* Whenever antialiasing should be enabled on ratings.
|
||||
*/
|
||||
public var ratingAntialiasing:Bool = true;
|
||||
public var ratingAntialiasing:Null<Bool>;
|
||||
/**
|
||||
* Whenever the animation should be forced to play (if it's null it will be forced based on the sprite's data xml, if it has one).
|
||||
*/
|
||||
@@ -145,6 +146,13 @@ final class NoteHitEvent extends CancellableEvent {
|
||||
deleteNote = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents the sustain from being cut. Only works if the note is a sustain.
|
||||
*/
|
||||
public function preventSustainClip() {
|
||||
clipSustain = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents the vocals volume from being set to 1 after pressing the note.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,766 @@
|
||||
package funkin.backend.shaders;
|
||||
|
||||
import haxe.Timer;
|
||||
import openfl.filters.BitmapFilter;
|
||||
import openfl.filters.BitmapFilterShader;
|
||||
import openfl.display.BitmapData;
|
||||
import openfl.display.DisplayObjectRenderer;
|
||||
import openfl.display.BlendMode;
|
||||
import openfl.display.Shader;
|
||||
import openfl.geom.Point;
|
||||
import openfl.geom.Rectangle;
|
||||
|
||||
/**
|
||||
This BloomEffect was modified by heihua based on openfl.filters.BlurFilter.
|
||||
The BloomEffect class applies a bloom/glow visual effect to display objects.
|
||||
A bloom effect extracts bright areas from an image, blurs them, and combines
|
||||
them back to create a glowing halo around bright objects. This effect is
|
||||
commonly used to simulate intense light, emissive materials, or to add a
|
||||
dreamy, atmospheric quality to scenes.
|
||||
|
||||
The effect consists of three stages:
|
||||
1. Extraction - Bright pixels above a threshold are extracted
|
||||
2. Blurring - The extracted bright areas are blurred horizontally and vertically
|
||||
3. Combination - The blurred result is blended back with the original image
|
||||
**/
|
||||
|
||||
@:noCustomClass
|
||||
class BloomEffect extends BitmapFilter
|
||||
{
|
||||
@:noCompletion private static var __blurShader:BlurShader;
|
||||
@:noCompletion private static var __combineShader:CombineShader;
|
||||
@:noCompletion private static var __extractShader:ExtractShader;
|
||||
@:noCompletion private static var __extractLowShader:ExtractLowShader;
|
||||
|
||||
/**
|
||||
Values that are a power of 2 (such as 2, 4, 8, 16 and 32) are optimized to render
|
||||
more quickly than other values.
|
||||
**/
|
||||
public var blurX(get, set):Float;
|
||||
|
||||
/**
|
||||
Values that are a power of 2 (such as 2, 4, 8, 16 and 32) are optimized to render
|
||||
more quickly than other values.
|
||||
**/
|
||||
public var blurY(get, set):Float;
|
||||
|
||||
/**
|
||||
The downscaling factor for bloom rendering. Higher values significantly reduce
|
||||
GPU performance cost, but setting values too high may cause noticeable flickering.
|
||||
Recommended range is 8-24.
|
||||
**/
|
||||
public var quality(get, set):Float;
|
||||
|
||||
/**
|
||||
The intensity of the bloom effect. Higher values produce more pronounced bloom.
|
||||
**/
|
||||
public var strength(get, set):Float;
|
||||
|
||||
/**
|
||||
The brightness threshold for bloom extraction. Pixels brighter than this value
|
||||
will contribute to the bloom effect. Value range is 0.0 to 1.0.
|
||||
**/
|
||||
public var threshold(get, set):Float;
|
||||
|
||||
/**
|
||||
The smoothness of the threshold transition in blur shader.
|
||||
Higher values create a smoother transition for brightness correction.
|
||||
Value range is 0.0 to 1.0. Default is 0.1.
|
||||
**/
|
||||
public var smoothness(get, set):Float;
|
||||
|
||||
/**
|
||||
Enables extended rendering area to avoid edge artifacts. Enabling this option
|
||||
will increase performance cost. Generally not required when rendering to camera.
|
||||
**/
|
||||
public var extension(get, set):Bool;
|
||||
|
||||
/**
|
||||
Low-quality pixel sampling mode. Disabling it significantly reduces screen flickering,
|
||||
with minimal performance impact on desktop platforms but a higher
|
||||
performance cost on non-desktop platforms.
|
||||
**/
|
||||
public var useLowQualityExtract(get, set):Bool;
|
||||
|
||||
/**
|
||||
The weights for calculating brightness (RGB to grayscale).
|
||||
Order: [Red, Green, Blue]. Default is [0.2126, 0.7152, 0.0722].
|
||||
**/
|
||||
public var weights(get, set):Array<Float>;
|
||||
|
||||
/**
|
||||
The blend mode used when combining the bloom with the original image.
|
||||
BlendMode currently supports: (BlendMode.ADD, BlendMode.ALPHA, BlendMode.HARDLIGHT,
|
||||
BlendMode.LIGHTEN, BlendMode.MULTIPLY, BlendMode.OVERLAY, BlendMode.SCREEN,
|
||||
BlendMode.COLORDODGE, BlendMode.SOFTLIGHT).
|
||||
Default is BlendMode.ADD.
|
||||
**/
|
||||
public var blendMode(get, set):BlendMode;
|
||||
|
||||
@:noCompletion private var __blurX:Float;
|
||||
@:noCompletion private var __blurY:Float;
|
||||
@:noCompletion private var __horizontalPasses:Int;
|
||||
@:noCompletion private var __quality:Float;
|
||||
@:noCompletion private var __verticalPasses:Int;
|
||||
@:noCompletion private var __strength:Float;
|
||||
@:noCompletion private var __threshold:Float;
|
||||
@:noCompletion private var __smoothness:Float;
|
||||
@:noCompletion private var __extension:Bool;
|
||||
@:noCompletion private var __useLowQualityExtract:Bool;
|
||||
@:noCompletion private var __weights:Array<Float>;
|
||||
@:noCompletion private var __blendMode:BlendMode;
|
||||
|
||||
#if openfljs
|
||||
@:noCompletion private static function __init__()
|
||||
{
|
||||
untyped Object.defineProperties(BloomEffect.prototype, {
|
||||
"blurX": {
|
||||
get: untyped #if haxe4 js.Syntax.code #else __js__ #end ("function () { return this.get_blurX (); }"),
|
||||
set: untyped #if haxe4 js.Syntax.code #else __js__ #end ("function (v) { return this.set_blurX (v); }")
|
||||
},
|
||||
"blurY": {
|
||||
get: untyped #if haxe4 js.Syntax.code #else __js__ #end ("function () { return this.get_blurY (); }"),
|
||||
set: untyped #if haxe4 js.Syntax.code #else __js__ #end ("function (v) { return this.set_blurY (v); }")
|
||||
},
|
||||
"quality": {
|
||||
get: untyped #if haxe4 js.Syntax.code #else __js__ #end ("function () { return this.get_quality (); }"),
|
||||
set: untyped #if haxe4 js.Syntax.code #else __js__ #end ("function (v) { return this.set_quality (v); }")
|
||||
},
|
||||
"strength": {
|
||||
get: untyped #if haxe4 js.Syntax.code #else __js__ #end ("function () { return this.get_strength (); }"),
|
||||
set: untyped #if haxe4 js.Syntax.code #else __js__ #end ("function (v) { return this.set_strength (v); }")
|
||||
},
|
||||
"threshold": {
|
||||
get: untyped #if haxe4 js.Syntax.code #else __js__ #end ("function () { return this.get_threshold (); }"),
|
||||
set: untyped #if haxe4 js.Syntax.code #else __js__ #end ("function (v) { return this.set_threshold (v); }")
|
||||
},
|
||||
"useLowQualityExtract": {
|
||||
get: untyped #if haxe4 js.Syntax.code #else __js__ #end ("function () { return this.get_useLowQualityExtract (); }"),
|
||||
set: untyped #if haxe4 js.Syntax.code #else __js__ #end ("function (v) { return this.set_useLowQualityExtract (v); }")
|
||||
},
|
||||
"weights": {
|
||||
get: untyped #if haxe4 js.Syntax.code #else __js__ #end ("function () { return this.get_weights (); }"),
|
||||
set: untyped #if haxe4 js.Syntax.code #else __js__ #end ("function (v) { return this.set_weights (v); }")
|
||||
},
|
||||
"blendMode": {
|
||||
get: untyped #if haxe4 js.Syntax.code #else __js__ #end ("function () { return this.get_blendMode (); }"),
|
||||
set: untyped #if haxe4 js.Syntax.code #else __js__ #end ("function (v) { return this.set_blendMode (v); }")
|
||||
},
|
||||
});
|
||||
}
|
||||
#end
|
||||
|
||||
/**
|
||||
Initializes the bloom filter with the specified parameters.
|
||||
|
||||
@param blurX The amount to blur horizontally.
|
||||
@param blurY The amount to blur vertically.
|
||||
@param quality The downscaling factor for bloom rendering (higher values reduce
|
||||
GPU cost but may cause flickering if too high).
|
||||
@param strength The intensity of the bloom effect.
|
||||
@param threshold The brightness threshold for bloom extraction (0.0 to 1.0).
|
||||
@param smoothness The smoothness of threshold transition in blur (0.0 to 1.0).
|
||||
@param useLowQualityExtract Enables performance-optimized extraction with
|
||||
potentially more flickering.
|
||||
**/
|
||||
public function new(blurX:Float = 50, blurY:Float = 50, quality:Float = 8, strength:Float = 0.6, threshold:Float = 0.6, smoothness:Float = 0.1, useLowQualityExtract:Bool = true)
|
||||
{
|
||||
super();
|
||||
|
||||
if (__blurShader == null) __blurShader = new BlurShader();
|
||||
if (__combineShader == null) __combineShader = new CombineShader();
|
||||
if (__extractShader == null) __extractShader = new ExtractShader();
|
||||
if (__extractLowShader == null) __extractLowShader = new ExtractLowShader();
|
||||
|
||||
this.blurX = blurX;
|
||||
this.blurY = blurY;
|
||||
this.quality = quality;
|
||||
this.strength = strength;
|
||||
this.threshold = threshold;
|
||||
this.smoothness = smoothness;
|
||||
this.extension = false;
|
||||
this.useLowQualityExtract = useLowQualityExtract;
|
||||
this.weights = [0.2126, 0.7152, 0.0722];
|
||||
this.blendMode = BlendMode.ADD;
|
||||
|
||||
__needSecondBitmapData = true;
|
||||
__preserveObject = true;
|
||||
__renderDirty = true;
|
||||
}
|
||||
|
||||
public override function clone():BitmapFilter
|
||||
{
|
||||
var cloned = new BloomEffect(__blurX, __blurY, __quality, __strength, __threshold, __smoothness, __useLowQualityExtract);
|
||||
cloned.weights = __weights != null ? __weights.copy() : [0.2126, 0.7152, 0.0722];
|
||||
cloned.blendMode = __blendMode;
|
||||
return cloned;
|
||||
}
|
||||
|
||||
@:noCompletion private override function __applyFilter(bitmapData:BitmapData, sourceBitmapData:BitmapData, sourceRect:Rectangle, destPoint:Point):BitmapData
|
||||
{
|
||||
trace("Due to technical limitations, I'm unable to implement the bitmapData rendering method. If you know how to implement it, you're welcome to contribute this feature.");
|
||||
return sourceBitmapData;
|
||||
}
|
||||
|
||||
@:noCompletion private override function __initShader(renderer:DisplayObjectRenderer, pass:Int, sourceBitmapData:BitmapData):Shader
|
||||
{
|
||||
final numBlurPasses = __horizontalPasses + __verticalPasses;
|
||||
|
||||
switch pass
|
||||
{
|
||||
case 0:
|
||||
if (__useLowQualityExtract)
|
||||
{
|
||||
__extractLowShader.uThreshold.value[0] = __threshold;
|
||||
__extractLowShader.uSmoothness.value[0] = __smoothness;
|
||||
__extractLowShader.uQuality.value[0] = __quality;
|
||||
__extractLowShader.uWeights.value = __weights;
|
||||
return __extractLowShader;
|
||||
}
|
||||
else
|
||||
{
|
||||
__extractShader.uThreshold.value[0] = __threshold;
|
||||
__extractShader.uSmoothness.value[0] = __smoothness;
|
||||
__extractShader.uQuality.value[0] = __quality;
|
||||
__extractShader.uWeights.value = __weights;
|
||||
return __extractShader;
|
||||
}
|
||||
|
||||
case _ if (pass <= numBlurPasses):
|
||||
final blurPass = pass - 1;
|
||||
final isHorizontal = blurPass < __horizontalPasses;
|
||||
|
||||
final scalePass = isHorizontal ? blurPass : blurPass - __horizontalPasses;
|
||||
|
||||
final scale = Math.pow(0.5, scalePass >> 1);
|
||||
final blurRadius = isHorizontal ? blurX * scale : blurY * scale;
|
||||
|
||||
if (isHorizontal)
|
||||
{
|
||||
__blurShader.uRadius.value[0] = blurRadius / __quality;
|
||||
__blurShader.uRadius.value[1] = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
__blurShader.uRadius.value[0] = 0.0;
|
||||
__blurShader.uRadius.value[1] = blurRadius / __quality;
|
||||
}
|
||||
__blurShader.uQuality.value[0] = __quality;
|
||||
__blurShader.uStrength.value[0] = Math.pow(__strength, 1.0 / numBlurPasses);
|
||||
|
||||
return __blurShader;
|
||||
|
||||
default:
|
||||
__combineShader.sourceBitmap.input = sourceBitmapData;
|
||||
__combineShader.uThreshold.value[0] = __threshold;
|
||||
__combineShader.uQuality.value[0] = __quality;
|
||||
__combineShader.uBlendMode.value[0] = cast __blendMode;
|
||||
return __combineShader;
|
||||
}
|
||||
}
|
||||
|
||||
// Get & Set Methods
|
||||
@:noCompletion private function get_blurX():Float
|
||||
{
|
||||
return __blurX;
|
||||
}
|
||||
|
||||
@:noCompletion private function set_blurX(value:Float):Float
|
||||
{
|
||||
if (value != __blurX)
|
||||
{
|
||||
__blurX = value;
|
||||
__renderDirty = true;
|
||||
|
||||
if (!__extension)
|
||||
{
|
||||
// Setting it to 1 prevents bloom flickering at the screen edges
|
||||
__leftExtension = 1;
|
||||
__rightExtension = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
__leftExtension = (value > 0 ? Math.ceil(value) : 0);
|
||||
__rightExtension = __leftExtension;
|
||||
}
|
||||
|
||||
__horizontalPasses = (value <= 0) ? 0 : Math.ceil(value * 0.0625 / quality) + 1;
|
||||
__numShaderPasses = __horizontalPasses + __verticalPasses + 2;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@:noCompletion private function get_blurY():Float
|
||||
{
|
||||
return __blurY;
|
||||
}
|
||||
|
||||
@:noCompletion private function set_blurY(value:Float):Float
|
||||
{
|
||||
if (value != __blurY)
|
||||
{
|
||||
__blurY = value;
|
||||
__renderDirty = true;
|
||||
|
||||
if (!__extension)
|
||||
{
|
||||
// Setting it to 1 prevents bloom flickering at the screen edges
|
||||
__topExtension = 1;
|
||||
__bottomExtension = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
__topExtension = (value > 0 ? Math.ceil(value) : 0);
|
||||
__bottomExtension = __topExtension;
|
||||
}
|
||||
|
||||
__verticalPasses = (value <= 0) ? 0 : Math.ceil(value * 0.0625 / quality) + 1;
|
||||
__numShaderPasses = __horizontalPasses + __verticalPasses + 2;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@:noCompletion private function get_quality():Float
|
||||
{
|
||||
return __quality;
|
||||
}
|
||||
|
||||
@:noCompletion private function set_quality(value:Float):Float
|
||||
{
|
||||
__horizontalPasses = (__blurX <= 0) ? 0 : Math.round(__blurX * 0.125 / value) + 1;
|
||||
__verticalPasses = (__blurY <= 0) ? 0 : Math.round(__blurY * 0.125 / value) + 1;
|
||||
__numShaderPasses = __horizontalPasses + __verticalPasses + 2;
|
||||
|
||||
if (value != __quality)
|
||||
__renderDirty = true;
|
||||
return __quality = value;
|
||||
}
|
||||
|
||||
@:noCompletion private function get_strength():Float
|
||||
{
|
||||
return __strength;
|
||||
}
|
||||
|
||||
@:noCompletion private function set_strength(value:Float):Float
|
||||
{
|
||||
if (value != __strength)
|
||||
{
|
||||
__strength = value;
|
||||
__renderDirty = true;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@:noCompletion private function get_threshold():Float
|
||||
{
|
||||
return __threshold;
|
||||
}
|
||||
|
||||
@:noCompletion private function set_threshold(value:Float):Float
|
||||
{
|
||||
if (value != __threshold)
|
||||
{
|
||||
__threshold = value;
|
||||
__renderDirty = true;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@:noCompletion private function get_smoothness():Float
|
||||
{
|
||||
return __smoothness;
|
||||
}
|
||||
|
||||
@:noCompletion private function set_smoothness(value:Float):Float
|
||||
{
|
||||
if (value != __smoothness)
|
||||
{
|
||||
__smoothness = value;
|
||||
__renderDirty = true;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@:noCompletion private function get_extension():Bool
|
||||
{
|
||||
return __extension;
|
||||
}
|
||||
|
||||
@:noCompletion private function set_extension(value:Bool):Bool
|
||||
{
|
||||
if (value != __extension)
|
||||
{
|
||||
__extension = value;
|
||||
|
||||
if (!value)
|
||||
__leftExtension = __rightExtension = __topExtension = __bottomExtension = 0;
|
||||
else
|
||||
{
|
||||
__leftExtension = __rightExtension = (__blurX > 0 ? Math.ceil(__blurX) : 0);
|
||||
__topExtension = __bottomExtension = (__blurY > 0 ? Math.ceil(__blurY) : 0);
|
||||
}
|
||||
|
||||
__renderDirty = true;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@:noCompletion private function get_useLowQualityExtract():Bool
|
||||
{
|
||||
return __useLowQualityExtract;
|
||||
}
|
||||
|
||||
@:noCompletion private function set_useLowQualityExtract(value:Bool):Bool
|
||||
{
|
||||
if (value != __useLowQualityExtract)
|
||||
{
|
||||
__useLowQualityExtract = value;
|
||||
__renderDirty = true;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@:noCompletion private function get_weights():Array<Float>
|
||||
{
|
||||
return __weights;
|
||||
}
|
||||
|
||||
@:noCompletion private function set_weights(value:Array<Float>):Array<Float>
|
||||
{
|
||||
if (value != __weights)
|
||||
{
|
||||
__weights = value;
|
||||
__renderDirty = true;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@:noCompletion private function get_blendMode():BlendMode
|
||||
{
|
||||
return __blendMode;
|
||||
}
|
||||
|
||||
@:noCompletion private function set_blendMode(value:BlendMode):BlendMode
|
||||
{
|
||||
if (value != __blendMode)
|
||||
{
|
||||
__blendMode = value;
|
||||
__renderDirty = true;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private class BlurShader extends BitmapFilterShader
|
||||
{
|
||||
@:glFragmentSource("
|
||||
uniform sampler2D openfl_Texture;
|
||||
uniform float uStrength;
|
||||
|
||||
varying mat2 vBlurCoord0;
|
||||
varying mat2 vBlurCoord1;
|
||||
varying vec2 vBlurCoord2;
|
||||
varying mat2 vBlurCoord3;
|
||||
varying mat2 vBlurCoord4;
|
||||
|
||||
varying float invQuality;
|
||||
|
||||
void main(void) {
|
||||
if ((all(greaterThanEqual(vBlurCoord2, vec2(0.0))) && all(lessThanEqual(vBlurCoord2, vec2(1.0)))) == false) return;
|
||||
|
||||
vec4 sum = texture2D(openfl_Texture, clamp(vBlurCoord0[0], 0.0, invQuality)) * 0.028532;
|
||||
sum += texture2D(openfl_Texture, clamp(vBlurCoord0[1], 0.0, invQuality)) * 0.067234;
|
||||
sum += texture2D(openfl_Texture, clamp(vBlurCoord1[0], 0.0, invQuality)) * 0.124009;
|
||||
sum += texture2D(openfl_Texture, clamp(vBlurCoord1[1], 0.0, invQuality)) * 0.179044;
|
||||
sum += texture2D(openfl_Texture, clamp(vBlurCoord2, 0.0, invQuality)) * 0.202360;
|
||||
sum += texture2D(openfl_Texture, clamp(vBlurCoord3[0], 0.0, invQuality)) * 0.179044;
|
||||
sum += texture2D(openfl_Texture, clamp(vBlurCoord3[1], 0.0, invQuality)) * 0.124009;
|
||||
sum += texture2D(openfl_Texture, clamp(vBlurCoord4[0], 0.0, invQuality)) * 0.067234;
|
||||
sum += texture2D(openfl_Texture, clamp(vBlurCoord4[1], 0.0, invQuality)) * 0.028532;
|
||||
gl_FragColor = sum * uStrength;
|
||||
}
|
||||
")
|
||||
@:glVertexSource("
|
||||
attribute vec4 openfl_Position;
|
||||
attribute vec2 openfl_TextureCoord;
|
||||
|
||||
uniform mat4 openfl_Matrix;
|
||||
|
||||
uniform vec2 uRadius;
|
||||
uniform vec2 uTextureSize;
|
||||
uniform float uQuality;
|
||||
|
||||
varying mat2 vBlurCoord0;
|
||||
varying mat2 vBlurCoord1;
|
||||
varying vec2 vBlurCoord2;
|
||||
varying mat2 vBlurCoord3;
|
||||
varying mat2 vBlurCoord4;
|
||||
|
||||
varying float invQuality;
|
||||
|
||||
void main(void) {
|
||||
vec4 pos = openfl_Position;
|
||||
invQuality = 1.0 / uQuality;
|
||||
|
||||
pos.xy *= invQuality;
|
||||
gl_Position = openfl_Matrix * pos;
|
||||
|
||||
vec2 r = uRadius / uTextureSize;
|
||||
vec2 coord = openfl_TextureCoord * invQuality;
|
||||
vBlurCoord0[0] = coord - r;
|
||||
vBlurCoord0[1] = coord - r * 0.25;
|
||||
vBlurCoord1[0] = coord - r * 0.5;
|
||||
vBlurCoord1[1] = coord - r * 0.75;
|
||||
vBlurCoord2 = coord;
|
||||
vBlurCoord3[0] = coord + r * 0.25;
|
||||
vBlurCoord3[1] = coord + r * 0.5;
|
||||
vBlurCoord4[0] = coord + r * 0.75;
|
||||
vBlurCoord4[1] = coord + r;
|
||||
}
|
||||
")
|
||||
public function new()
|
||||
{
|
||||
super();
|
||||
|
||||
uStrength.value = [1.0];
|
||||
uRadius.value = [0, 0];
|
||||
uQuality.value = [8];
|
||||
uTextureSize.value = [1, 1];
|
||||
}
|
||||
|
||||
@:noCompletion private override function __update():Void
|
||||
{
|
||||
#if !macro
|
||||
uTextureSize.value[0] = __texture.input.width;
|
||||
uTextureSize.value[1] = __texture.input.height;
|
||||
#end
|
||||
|
||||
super.__update();
|
||||
}
|
||||
}
|
||||
|
||||
private class ExtractLowShader extends BitmapFilterShader
|
||||
{
|
||||
@:glFragmentSource("
|
||||
uniform sampler2D openfl_Texture;
|
||||
uniform float uThreshold;
|
||||
uniform float uSmoothness;
|
||||
uniform vec3 uWeights;
|
||||
varying vec2 vTexCoord;
|
||||
|
||||
void main(void) {
|
||||
if ((all(greaterThanEqual(vTexCoord, vec2(0.0))) && all(lessThanEqual(vTexCoord, vec2(1.0)))) == false) return;
|
||||
|
||||
vec4 texel = texture2D(openfl_Texture, vTexCoord);
|
||||
float brightness = min(dot(texel.rgb, uWeights), 1.0);
|
||||
float mask = smoothstep(uThreshold, uThreshold + uSmoothness, brightness);
|
||||
gl_FragColor = texel * mask;
|
||||
}
|
||||
")
|
||||
@:glVertexSource("
|
||||
attribute vec4 openfl_Position;
|
||||
attribute vec2 openfl_TextureCoord;
|
||||
uniform mat4 openfl_Matrix;
|
||||
uniform vec2 openfl_TextureSize;
|
||||
uniform float uQuality;
|
||||
varying vec2 vTexCoord;
|
||||
|
||||
void main(void) {
|
||||
vec4 pos = openfl_Position;
|
||||
pos.xy /= uQuality;
|
||||
gl_Position = openfl_Matrix * pos;
|
||||
vTexCoord = openfl_TextureCoord;
|
||||
}
|
||||
")
|
||||
public function new()
|
||||
{
|
||||
super();
|
||||
|
||||
uThreshold.value = [0.6];
|
||||
uSmoothness.value = [0.1];
|
||||
uQuality.value = [8];
|
||||
uWeights.value = [0.2126, 0.7152, 0.0722];
|
||||
}
|
||||
}
|
||||
|
||||
private class ExtractShader extends BitmapFilterShader
|
||||
{
|
||||
@:glFragmentSource("
|
||||
uniform sampler2D openfl_Texture;
|
||||
uniform vec2 openfl_TextureSize;
|
||||
uniform float uThreshold;
|
||||
uniform float uSmoothness;
|
||||
uniform float uQuality;
|
||||
uniform vec3 uWeights;
|
||||
varying vec2 vTexCoord;
|
||||
varying vec4 border;
|
||||
|
||||
void main(void) {
|
||||
if ((all(greaterThanEqual(vTexCoord, border.xy)) && all(lessThanEqual(vTexCoord, border.zw))) == false) return;
|
||||
|
||||
float quality = floor(uQuality) / 2.0;
|
||||
vec2 texelSize = 1.0 / openfl_TextureSize;
|
||||
|
||||
vec4 accumulated = vec4(0.0);
|
||||
int sampleCount = 0;
|
||||
|
||||
|
||||
for (float dx = -quality; dx <= quality; dx += 2.0) {
|
||||
for (float dy = -quality; dy <= quality; dy += 2.0) {
|
||||
vec2 sampleCoord = vTexCoord + vec2(dx, dy) * texelSize;
|
||||
|
||||
vec4 texel = texture2D(openfl_Texture, sampleCoord);
|
||||
float brightness = min(dot(texel.rgb, uWeights), 1.0);
|
||||
float mask = smoothstep(uThreshold, uThreshold + uSmoothness, brightness);
|
||||
accumulated += texel * mask;
|
||||
sampleCount++;
|
||||
}
|
||||
}
|
||||
|
||||
gl_FragColor = accumulated / float(sampleCount);
|
||||
}
|
||||
")
|
||||
@:glVertexSource("
|
||||
attribute vec4 openfl_Position;
|
||||
attribute vec2 openfl_TextureCoord;
|
||||
uniform mat4 openfl_Matrix;
|
||||
uniform vec2 openfl_TextureSize;
|
||||
uniform float uQuality;
|
||||
varying vec2 vTexCoord;
|
||||
varying vec4 border;
|
||||
|
||||
void main(void) {
|
||||
vec4 pos = openfl_Position;
|
||||
pos.xy /= uQuality;
|
||||
|
||||
vec2 size = 1.0 / openfl_TextureSize * uQuality;
|
||||
border = vec4(size, vec2(1.0) - size);
|
||||
|
||||
gl_Position = openfl_Matrix * pos;
|
||||
vTexCoord = openfl_TextureCoord;
|
||||
}
|
||||
")
|
||||
public function new()
|
||||
{
|
||||
super();
|
||||
|
||||
uThreshold.value = [0.6];
|
||||
uSmoothness.value = [0.1];
|
||||
uQuality.value = [8];
|
||||
uWeights.value = [0.2126, 0.7152, 0.0722];
|
||||
}
|
||||
}
|
||||
|
||||
private class CombineShader extends BitmapFilterShader
|
||||
{
|
||||
@:glFragmentSource("
|
||||
uniform sampler2D openfl_Texture;
|
||||
uniform sampler2D sourceBitmap;
|
||||
uniform float uThreshold;
|
||||
uniform int uBlendMode;
|
||||
varying vec4 textureCoords;
|
||||
|
||||
vec4 blendScreen(vec4 src, vec4 bloom) {
|
||||
return vec4(1.0) - (vec4(1.0) - src) * (vec4(1.0) - bloom);
|
||||
}
|
||||
|
||||
vec4 blendMultiply(vec4 src, vec4 bloom) {
|
||||
return src * bloom;
|
||||
}
|
||||
|
||||
vec4 blendLighten(vec4 src, vec4 bloom) {
|
||||
return max(src, bloom);
|
||||
}
|
||||
|
||||
vec4 blendOverlay(vec4 src, vec4 bloom) {
|
||||
vec4 result = vec4(0.0);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (src[i] < 0.5) {
|
||||
result[i] = 2.0 * src[i] * bloom[i];
|
||||
} else {
|
||||
result[i] = 1.0 - 2.0 * (1.0 - src[i]) * (1.0 - bloom[i]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
vec4 blendColorDodge(vec4 src, vec4 bloom) {
|
||||
vec4 result = vec4(0.0);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (bloom[i] < 1.0) {
|
||||
result[i] = min(1.0, src[i] / (1.0 - bloom[i]));
|
||||
} else {
|
||||
result[i] = 1.0;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
vec4 blendSoftLight(vec4 src, vec4 bloom) {
|
||||
vec4 result = vec4(0.0);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (bloom[i] < 0.5) {
|
||||
result[i] = src[i] - (1.0 - 2.0 * bloom[i]) * src[i] * (1.0 - src[i]);
|
||||
} else {
|
||||
float d = (src[i] <= 0.25) ? ((16.0 * src[i] - 12.0) * src[i] + 4.0) * src[i] : sqrt(src[i]);
|
||||
result[i] = src[i] + (2.0 * bloom[i] - 1.0) * (d - src[i]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
vec4 blendAlpha(vec4 src, vec4 bloom) {
|
||||
return src + bloom * (1.0 - src.a);
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
vec4 src = texture2D(sourceBitmap, textureCoords.xy);
|
||||
vec4 bloom = texture2D(openfl_Texture, textureCoords.zw);
|
||||
|
||||
vec4 result;
|
||||
if(uBlendMode == 0)
|
||||
result = src + bloom;
|
||||
else if(uBlendMode == 1)
|
||||
result = blendAlpha(src, bloom);
|
||||
else if(uBlendMode == 5)
|
||||
result = blendOverlay(src, bloom);
|
||||
else if(uBlendMode == 8)
|
||||
result = blendLighten(src, bloom);
|
||||
else if(uBlendMode == 9)
|
||||
result = blendMultiply(src, bloom);
|
||||
else if(uBlendMode == 11)
|
||||
result = blendOverlay(src, bloom);
|
||||
else if(uBlendMode == 12)
|
||||
result = blendScreen(src, bloom);
|
||||
else if(uBlendMode == 15)
|
||||
result = blendColorDodge(src, bloom);
|
||||
else if(uBlendMode == 17)
|
||||
result = blendSoftLight(src, bloom);
|
||||
else
|
||||
result = src + bloom;
|
||||
|
||||
gl_FragColor = result;
|
||||
}
|
||||
")
|
||||
@:glVertexSource("
|
||||
attribute vec4 openfl_Position;
|
||||
attribute vec2 openfl_TextureCoord;
|
||||
uniform mat4 openfl_Matrix;
|
||||
uniform vec2 openfl_TextureSize;
|
||||
uniform float uQuality;
|
||||
varying vec4 textureCoords;
|
||||
|
||||
void main(void) {
|
||||
gl_Position = openfl_Matrix * openfl_Position;
|
||||
textureCoords = vec4(openfl_TextureCoord, openfl_TextureCoord / uQuality);
|
||||
}
|
||||
")
|
||||
public function new()
|
||||
{
|
||||
super();
|
||||
|
||||
uQuality.value = [8];
|
||||
uThreshold.value = [0.6];
|
||||
uBlendMode.value = [0];
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,8 @@ class ScriptableShader extends FlxBasic implements IHScriptCustomBehaviour {
|
||||
if((shader is CustomShader)) scriptName = cast(shader, CustomShader).fileName;
|
||||
else throw "Missing name for shader script, please provide a scriptName, or use CustomShader";
|
||||
|
||||
this.shader = shader;
|
||||
|
||||
script = Script.create(Paths.script('shaders/$scriptName'));
|
||||
script.setParent(shader);
|
||||
script.set("shader", shader);
|
||||
|
||||
@@ -25,6 +25,7 @@ enum Control
|
||||
CHANGE_MODE;
|
||||
//CHEAT;
|
||||
SWITCHMOD;
|
||||
FPS_COUNTER;
|
||||
|
||||
// Debugs
|
||||
DEV_ACCESS;
|
||||
@@ -161,6 +162,11 @@ class Controls extends FlxActionSet
|
||||
@:pressed("switchmod") public var SWITCHMOD_HOLD(get, set): Bool;
|
||||
@:justReleased("switchmod") public var SWITCHMOD_R(get, set): Bool;
|
||||
|
||||
@:gamepad([])
|
||||
@:justPressed("fps-counter") public var FPS_COUNTER(get, set): Bool;
|
||||
@:pressed("fps-counter") public var FPS_COUNTER_HOLD(get, set): Bool;
|
||||
@:justReleased("fps-counter") public var FPS_COUNTER_R(get, set): Bool;
|
||||
|
||||
@:devModeOnly
|
||||
@:gamepad([])
|
||||
@:justPressed("dev-access") public var DEV_ACCESS(get, set): Bool;
|
||||
|
||||
@@ -15,14 +15,20 @@ import lime.utils.AssetType;
|
||||
*/
|
||||
@:build(funkin.backend.system.macros.FlagMacro.build())
|
||||
class Flags {
|
||||
public static var overridenFlags:Map<String, Bool> = [];
|
||||
|
||||
// -- Codename's Addon Config --
|
||||
@:bypass public static var addonFlags:Map<String, Dynamic> = [];
|
||||
public static var CURRENT_API_VERSION:Int = 2;
|
||||
|
||||
// -- Codename's ZipFolderLibrary Config --
|
||||
public static var ALLOWED_ZIP_EXTENSIONS:Array<String> = ["zip"];
|
||||
|
||||
// -- Codename's Mod Config --
|
||||
public static var MOD_NAME:String = "";
|
||||
public static var MOD_DESCRIPTION:String = "";
|
||||
public static var MOD_AUTHOR:String = "";
|
||||
public static var MOD_API_VERSION:Int = 1;
|
||||
@:lazy public static var MOD_API_VERSION:Null<Int> = null;
|
||||
public static var MOD_DOWNLOAD_LINK:String = "";
|
||||
public static var MOD_DEPENDENCIES:Array<String> = [];
|
||||
|
||||
@@ -41,12 +47,11 @@ class Flags {
|
||||
@:lazy public static var SAVE_PATH:String = haxe.macro.Compiler.getDefine("SAVE_PATH");
|
||||
@:lazy public static var SAVE_NAME:String = haxe.macro.Compiler.getDefine("SAVE_NAME");
|
||||
|
||||
public static var CURRENT_API_VERSION:Int = 1;
|
||||
public static var COMMIT_NUMBER:Int = GitCommitMacro.commitNumber;
|
||||
public static var COMMIT_HASH:String = GitCommitMacro.commitHash;
|
||||
public static var COMMIT_MESSAGE:String = 'Commit $COMMIT_NUMBER ($COMMIT_HASH)';
|
||||
|
||||
@:bypass public static var WINDOW_TITLE_USE_MOD_NAME:Bool = false;
|
||||
@:lazy public static var WINDOW_TITLE_USE_MOD_NAME:Null<Bool> = null;
|
||||
@:lazy public static var TITLE:String = Application.current.meta.get('name');
|
||||
@:lazy public static var VERSION:String = Application.current.meta.get('version');
|
||||
|
||||
@@ -101,7 +106,7 @@ class Flags {
|
||||
public static var DEFAULT_BEATS_PER_MEASURE:Int = 4;
|
||||
public static var DEFAULT_STEPS_PER_BEAT:Int = 4;
|
||||
public static var DEFAULT_LOOP_TIME:Float = 0.0;
|
||||
|
||||
public static var ICONS_AUTOPOSITION:Bool = true;
|
||||
public static var SUPPORTED_CHART_RUNTIME_FORMATS:Array<String> = ["Legacy", "Psych Engine"];
|
||||
public static var SUPPORTED_CHART_FORMATS:Array<String> = ["BaseGame"];
|
||||
|
||||
@@ -125,12 +130,19 @@ class Flags {
|
||||
@:also(funkin.game.PlayState.opponentMode)
|
||||
public static var DEFAULT_OPPONENT_MODE:Bool = false;
|
||||
|
||||
public static var EARLY_HIT_WINDOW_RANGE:Float = 1.0; // was 0.5 for easier early hitting, but now 1 to demotivate mashing and getting away with it.
|
||||
public static var LATE_HIT_WINDOW_RANGE:Float = 1.0;
|
||||
public static var SHITS_BREAK_COMBO:Bool = true;
|
||||
public static var USE_LEGACY_TIMING:Null<Bool> = null;
|
||||
|
||||
public static var DEFAULT_NOTE_MS_LIMIT:Float = 1500;
|
||||
public static var DEFAULT_NOTE_SCALE:Float = 0.7;
|
||||
#if MODCHARTING_FEATURES
|
||||
public static var DEFAULT_MODCHART_HOLD_SUBDIVISIONS:Int = 4;
|
||||
#end
|
||||
|
||||
public static var SUSTAINS_AS_ONE_NOTE:Null<Bool> = null;
|
||||
|
||||
@:also(funkin.game.Character.FALLBACK_DEAD_CHARACTER)
|
||||
public static var DEFAULT_GAMEOVER_CHARACTER:String = "bf-dead";
|
||||
|
||||
@@ -149,6 +161,14 @@ class Flags {
|
||||
public static var DEFAULT_CAM_ZOOM_LERP:Float = 0.05;
|
||||
public static var DEFAULT_HUD_ZOOM_LERP:Float = 0.05;
|
||||
|
||||
public static var USE_LEGACY_ZOOM_FACTOR:Null<Bool> = null;
|
||||
|
||||
// Font configuration
|
||||
public static var DEFAULT_FONT:String = "vcr.ttf";
|
||||
public static var DEFAULT_FONT_SIZE:Int = 16;
|
||||
|
||||
public static var DEFAULT_ALT_ANIM_SUFFIX:String = "-alt";
|
||||
|
||||
// to translate these you need to convert them into ids
|
||||
// Resume -> pause.resume
|
||||
// Restart Song -> pause.restart
|
||||
@@ -169,6 +189,7 @@ class Flags {
|
||||
public static var DEFAULT_HEALTH:Null<Float> = null;//DEFAULT_MAX_HEALTH / 2.0;
|
||||
public static var DEFAULT_ICONBOP:Bool = true;
|
||||
public static var BOP_ICON_SCALE:Float = 1.2;
|
||||
public static var ICON_DEFAULT_SCALE:Float = 1;
|
||||
public static var ICON_OFFSET:Float = 26;
|
||||
public static var ICON_LERP:Float = 0.33;
|
||||
|
||||
@@ -272,8 +293,6 @@ class Flags {
|
||||
@:bypass public static var customFlags:Map<String, String> = [];
|
||||
|
||||
public static function loadFromData(flags:Map<String, String>, data:String) {
|
||||
WINDOW_TITLE_USE_MOD_NAME = false;
|
||||
|
||||
if (!(data.length > 0)) return;
|
||||
var res = IniUtil.parseString(data);
|
||||
|
||||
@@ -290,28 +309,39 @@ class Flags {
|
||||
else trace('Invalid section $name');
|
||||
}
|
||||
}
|
||||
|
||||
if (!flags.exists("WINDOW_TITLE_USE_MOD_NAME")) WINDOW_TITLE_USE_MOD_NAME = !flags.exists('TITLE') && flags.exists('MOD_NAME');
|
||||
else WINDOW_TITLE_USE_MOD_NAME = parseBool(flags.get("WINDOW_TITLE_USE_MOD_NAME"));
|
||||
|
||||
flags.remove("WINDOW_TITLE_USE_MOD_NAME");
|
||||
}
|
||||
|
||||
public static function loadFromDatas(datas:Array<String>) {
|
||||
private static function loadPost() {
|
||||
if (MOD_API_VERSION == null) MOD_API_VERSION = CURRENT_API_VERSION;
|
||||
if (WINDOW_TITLE_USE_MOD_NAME == null) WINDOW_TITLE_USE_MOD_NAME = !overridenFlags.exists('TITLE') && overridenFlags.exists('MOD_NAME');
|
||||
if (USE_LEGACY_TIMING == null) USE_LEGACY_TIMING = MOD_API_VERSION < 2;
|
||||
if (USE_LEGACY_ZOOM_FACTOR == null) USE_LEGACY_ZOOM_FACTOR = MOD_API_VERSION < 2;
|
||||
if (SUSTAINS_AS_ONE_NOTE == null) SUSTAINS_AS_ONE_NOTE = MOD_API_VERSION >= 2;
|
||||
}
|
||||
|
||||
public static function loadFromDatas(datas:Array<String>):Map<String, String> {
|
||||
var flags:Map<String, String> = [];
|
||||
for(data in datas) {
|
||||
if(data != null)
|
||||
for (data in datas) {
|
||||
if (data != null)
|
||||
loadFromData(flags, data);
|
||||
}
|
||||
loadPost();
|
||||
return flags;
|
||||
}
|
||||
|
||||
public static function parseFlags(flags:Map<String, String>) {
|
||||
for(name=>value in flags)
|
||||
if(!parse(name, value))
|
||||
customFlags.set(name, value);
|
||||
|
||||
var parsed:Bool;
|
||||
for (name => value in flags) switch (name) {
|
||||
case "MOD_API_VERSION":
|
||||
var version = Std.parseInt(value) ?? CURRENT_API_VERSION;
|
||||
if (version > MOD_API_VERSION || MOD_API_VERSION == null) MOD_API_VERSION = version;
|
||||
default:
|
||||
if (!(parsed = parse(name, value))) customFlags.set(name, value);
|
||||
if (!overridenFlags.exists(name)) overridenFlags.set(name, parsed);
|
||||
}
|
||||
#if MODCHARTING_FEATURES
|
||||
Options.modchartingHoldSubdivisions = DEFAULT_MODCHART_HOLD_SUBDIVISIONS;
|
||||
#end
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -360,5 +390,6 @@ class Flags {
|
||||
parseFlags(flags);
|
||||
}
|
||||
}
|
||||
loadPost();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package funkin.backend.system;
|
||||
|
||||
import sys.io.File;
|
||||
import sys.FileSystem;
|
||||
import flixel.addons.transition.FlxTransitionSprite.GraphicTransTileDiamond;
|
||||
import flixel.addons.transition.FlxTransitionableState;
|
||||
import flixel.addons.transition.TransitionData;
|
||||
@@ -9,20 +7,23 @@ import flixel.graphics.FlxGraphic;
|
||||
import flixel.math.FlxPoint;
|
||||
import flixel.math.FlxRect;
|
||||
import flixel.system.ui.FlxSoundTray;
|
||||
import funkin.backend.assets.AssetSource;
|
||||
import funkin.backend.assets.AssetsLibraryList;
|
||||
import funkin.backend.assets.ModsFolder;
|
||||
import funkin.backend.assets.AssetSource;
|
||||
import funkin.backend.system.framerate.Framerate;
|
||||
import funkin.backend.system.framerate.SystemInfo;
|
||||
import funkin.backend.system.modules.*;
|
||||
import funkin.backend.utils.ThreadUtil;
|
||||
import funkin.editors.SaveWarning;
|
||||
import funkin.options.PlayerSettings;
|
||||
import openfl.Assets;
|
||||
import openfl.Lib;
|
||||
import openfl.display.Sprite;
|
||||
import openfl.text.TextFormat;
|
||||
import openfl.utils.AssetLibrary;
|
||||
|
||||
#if ALLOW_MULTITHREADING
|
||||
import sys.thread.Thread;
|
||||
#if sys
|
||||
import sys.FileSystem;
|
||||
import sys.io.File;
|
||||
#end
|
||||
#if android
|
||||
import android.content.Context;
|
||||
@@ -40,7 +41,7 @@ class Main extends Sprite
|
||||
|
||||
public static var scaleMode:FunkinRatioScaleMode;
|
||||
#if !mobile
|
||||
public static var framerateSprite:funkin.backend.system.framerate.Framerate;
|
||||
public static var framerateSprite:Framerate;
|
||||
#end
|
||||
|
||||
var gameWidth:Int = 1280; // Width of the game in pixels (might be less / more in actual pixels).
|
||||
@@ -58,13 +59,11 @@ class Main extends Sprite
|
||||
|
||||
// You can pretty much ignore everything from here on - your code should go in your states.
|
||||
|
||||
#if ALLOW_MULTITHREADING
|
||||
public static var gameThreads:Array<Thread> = [];
|
||||
#end
|
||||
|
||||
public static function preInit() {
|
||||
funkin.backend.utils.NativeAPI.registerAsDPICompatible();
|
||||
#if sys
|
||||
funkin.backend.system.CommandLineHandler.parseCommandLine(Sys.args());
|
||||
#end
|
||||
funkin.backend.system.Main.fixWorkingDirectory();
|
||||
}
|
||||
|
||||
@@ -79,7 +78,7 @@ class Main extends Sprite
|
||||
addChild(game = new FunkinGame(gameWidth, gameHeight, MainState, Options.framerate, Options.framerate, skipSplash, startFullscreen));
|
||||
|
||||
#if (!mobile && !web)
|
||||
addChild(framerateSprite = new funkin.backend.system.framerate.Framerate());
|
||||
addChild(framerateSprite = new Framerate());
|
||||
SystemInfo.init();
|
||||
#end
|
||||
}
|
||||
@@ -97,16 +96,8 @@ class Main extends Sprite
|
||||
#end;
|
||||
public static var startedFromSource:Bool = #if TEST_BUILD true #else false #end;
|
||||
|
||||
|
||||
private static var __threadCycle:Int = 0;
|
||||
public static function execAsync(func:Void->Void) {
|
||||
#if ALLOW_MULTITHREADING
|
||||
var thread = gameThreads[(__threadCycle++) % gameThreads.length];
|
||||
thread.events.run(func);
|
||||
#else
|
||||
func();
|
||||
#end
|
||||
}
|
||||
// DEPRECATED
|
||||
@:dox(hide) public static function execAsync(func:Void->Void) ThreadUtil.execAsync(func);
|
||||
|
||||
private static function getTimer():Int {
|
||||
return time = Lib.getTimer();
|
||||
@@ -118,10 +109,6 @@ class Main extends Sprite
|
||||
MemoryUtil.init();
|
||||
@:privateAccess
|
||||
FlxG.game.getTimer = getTimer;
|
||||
#if ALLOW_MULTITHREADING
|
||||
for(i in 0...4)
|
||||
gameThreads.push(Thread.createWithEventLoop(function() {Thread.current().events.promise();}));
|
||||
#end
|
||||
FunkinCache.init();
|
||||
Paths.assetsTree = new AssetsLibraryList();
|
||||
|
||||
@@ -156,6 +143,7 @@ class Main extends Sprite
|
||||
FlxG.signals.focusGained.add(onFocus);
|
||||
FlxG.signals.preStateSwitch.add(onStateSwitch);
|
||||
FlxG.signals.postStateSwitch.add(onStateSwitchPost);
|
||||
FlxG.signals.postUpdate.add(onUpdate);
|
||||
|
||||
FlxG.mouse.useSystemCursor = true;
|
||||
#if DARK_MODE_WINDOW
|
||||
@@ -210,6 +198,14 @@ class Main extends Sprite
|
||||
scaleMode.resetSize();
|
||||
}
|
||||
|
||||
public static function onUpdate() {
|
||||
if (PlayerSettings.solo.controls.DEV_CONSOLE)
|
||||
NativeAPI.allocConsole();
|
||||
|
||||
if (PlayerSettings.solo.controls.FPS_COUNTER)
|
||||
Framerate.debugMode = (Framerate.debugMode + 1) % 3;
|
||||
}
|
||||
|
||||
private static function onStateSwitchPost() {
|
||||
// manual asset clearing since base openfl one does'nt clear lime one
|
||||
// does'nt clear bitmaps since flixel fork does it auto
|
||||
|
||||
@@ -7,12 +7,14 @@ import flixel.FlxState;
|
||||
import funkin.backend.assets.AssetsLibraryList;
|
||||
import funkin.backend.assets.ModsFolder;
|
||||
import funkin.backend.assets.ModsFolderLibrary;
|
||||
import funkin.backend.assets.ZipFolderLibrary;
|
||||
import funkin.backend.chart.EventsData;
|
||||
import funkin.backend.system.framerate.Framerate;
|
||||
import funkin.editors.ModConfigWarning;
|
||||
import funkin.menus.TitleState;
|
||||
import haxe.io.Path;
|
||||
|
||||
|
||||
@dox(hide)
|
||||
typedef AddonInfo = {
|
||||
var name:String;
|
||||
@@ -57,27 +59,43 @@ class MainState extends FlxState {
|
||||
var _highPriorityAddons:Array<AddonInfo> = [];
|
||||
var _noPriorityAddons:Array<AddonInfo> = [];
|
||||
|
||||
var quick_modsPath = ModsFolder.modsPath + ModsFolder.currentModFolder;
|
||||
|
||||
// handing if the loading mod (before it's properly loaded) is a compressed mod
|
||||
// we just need to use `Paths.assetsTree.hasCompressedLibrary` to complete valid checks for actual loaded compressed mods
|
||||
var isZipMod = false;
|
||||
|
||||
// If we know it's a compressed mod, then we can check if it's using the `cnemod` folder path.
|
||||
// All it is really is a folder with the mod's name, then a compressed file called "cnemod.[zip|7z|rar|etc]"
|
||||
var isCneMod = false;
|
||||
|
||||
// We are doing it like this because think about it: it's 1 for loop lol
|
||||
// We just need to know if any of these values is true, so if only one is true and we are not close to being done in the loop, that's fine.
|
||||
//
|
||||
for (ext in Flags.ALLOWED_ZIP_EXTENSIONS) {
|
||||
if (FileSystem.exists(quick_modsPath+"."+ext)) isZipMod = true;
|
||||
if (FileSystem.exists(quick_modsPath+"/cnemod."+ext)) isCneMod = true;
|
||||
if (isZipMod && isCneMod) break;
|
||||
}
|
||||
|
||||
// We get the addons folder from relative space (`./`) and then our mod's addons.
|
||||
var addonPaths = [
|
||||
ModsFolder.addonsPath,
|
||||
(
|
||||
ModsFolder.currentModFolder != null ?
|
||||
ModsFolder.modsPath + ModsFolder.currentModFolder + "/addons/" :
|
||||
null
|
||||
// So to check the mod's addons folder, we need to decompress it. Which is impossible* in this stage of the loading library process.
|
||||
// TODO: Write a function when the library is loaded to decompress the contents and then load the libraries :)
|
||||
( (ModsFolder.currentModFolder != null && !isZipMod) ?
|
||||
quick_modsPath + "/addons/" : null
|
||||
)
|
||||
];
|
||||
|
||||
for(path in addonPaths) {
|
||||
for (path in addonPaths) {
|
||||
if (path == null) continue;
|
||||
if (!isDirectory(path)) continue;
|
||||
|
||||
for(addon in FileSystem.readDirectory(path)) {
|
||||
if(!FileSystem.isDirectory(path + addon)) {
|
||||
switch(Path.extension(addon).toLowerCase()) {
|
||||
case 'zip':
|
||||
addon = Path.withoutExtension(addon);
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
for (addon in FileSystem.readDirectory(path)) {
|
||||
if (!FileSystem.isDirectory(path + addon)) {
|
||||
if (Flags.ALLOWED_ZIP_EXTENSIONS.contains(Path.extension(addon))) addon = Path.withoutExtension(addon);
|
||||
else continue;
|
||||
}
|
||||
|
||||
var data:AddonInfo = {
|
||||
@@ -90,12 +108,24 @@ class MainState extends FlxState {
|
||||
else _noPriorityAddons.insert(0, data);
|
||||
}
|
||||
}
|
||||
#end
|
||||
|
||||
#if GLOBAL_SCRIPT
|
||||
funkin.backend.scripting.GlobalScript.destroy();
|
||||
#end
|
||||
funkin.backend.scripting.Script.staticVariables.clear();
|
||||
|
||||
#if MOD_SUPPORT
|
||||
for (addon in _lowPriorityAddons)
|
||||
loadLib(addon.path, ltrim(addon.name, "[LOW]"));
|
||||
|
||||
if (ModsFolder.currentModFolder != null)
|
||||
loadLib(ModsFolder.modsPath + ModsFolder.currentModFolder, ModsFolder.currentModFolder);
|
||||
|
||||
if (ModsFolder.currentModFolder != null) {
|
||||
// isCneMod is a guarentee to be a zip mod because we just checked for it, so this will always load as a CompressedLibrary
|
||||
if (isCneMod)
|
||||
loadLib(quick_modsPath + "/cnemod", ModsFolder.currentModFolder);
|
||||
else
|
||||
loadLib(quick_modsPath, ModsFolder.currentModFolder);
|
||||
}
|
||||
|
||||
for (addon in _noPriorityAddons)
|
||||
loadLib(addon.path, addon.name);
|
||||
@@ -127,9 +157,18 @@ class MainState extends FlxState {
|
||||
CoolUtil.safeAddAttributes('./.temp/', NativeAPI.FileAttribute.HIDDEN);
|
||||
#end
|
||||
|
||||
#if MOD_SUPPORT
|
||||
for (lib in ModsFolder.getLoadedModsLibs()) {
|
||||
if (!(lib is ZipFolderLibrary)) continue;
|
||||
if (cast(lib, ZipFolderLibrary).PRELOAD_VIDEOS) cast(lib, ZipFolderLibrary).precacheVideos();
|
||||
}
|
||||
#end
|
||||
|
||||
var startState:Class<FlxState> = Flags.DISABLE_WARNING_SCREEN ? TitleState : funkin.menus.WarningState;
|
||||
|
||||
if (Options.devMode && Options.allowConfigWarning) {
|
||||
#if MOD_SUPPORT
|
||||
// In this case if the mod we just loaded a compressed modpack, we can't edit or modify files without decompressing it.
|
||||
if (Options.devMode && Options.allowConfigWarning && !isZipMod) {
|
||||
var lib:ModsFolderLibrary;
|
||||
for (e in Paths.assetsTree.libraries) if ((lib = cast AssetsLibraryList.getCleanLibrary(e)) is ModsFolderLibrary
|
||||
&& lib.modName == ModsFolder.currentModFolder)
|
||||
@@ -140,7 +179,8 @@ class MainState extends FlxState {
|
||||
return;
|
||||
}
|
||||
}
|
||||
#end
|
||||
|
||||
FlxG.switchState(cast Type.createInstance(startState, []));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,12 +8,20 @@ import funkin.backend.assets.IModsAssetLibrary;
|
||||
import funkin.backend.assets.ScriptedAssetLibrary;
|
||||
|
||||
class AssetTreeInfo extends FramerateCategory {
|
||||
private var lastUpdateTime:Float = 1;
|
||||
|
||||
public function new() {
|
||||
super("Asset Libraries Tree Info");
|
||||
}
|
||||
|
||||
public override function __enterFrame(t:Int) {
|
||||
if (alpha <= 0.05) return;
|
||||
|
||||
if ((lastUpdateTime += FlxG.rawElapsed) < 1)
|
||||
return;
|
||||
|
||||
lastUpdateTime = 0;
|
||||
|
||||
var text = 'Not initialized yet\n';
|
||||
if (Paths.assetsTree != null){
|
||||
text = "";
|
||||
|
||||