Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b2215482c2 | ||
|
|
59dae0f601 | ||
|
|
4d70e13629 | ||
|
|
83bc17970a | ||
|
|
72078e4fec | ||
|
|
f5bd835496 | ||
|
|
f2fe179109 | ||
|
|
b1d91ab5d8 | ||
|
|
f09e89e324 | ||
|
|
3c8f7c08ec | ||
|
|
ee9d492bec | ||
|
|
afc251cde7 | ||
|
|
b7615eb8dd | ||
|
|
d2ead0ce4c | ||
|
|
22297ee6ed | ||
|
|
353473a980 | ||
|
|
9e39b1bfdb | ||
|
|
ab884e1362 | ||
|
|
86c6f95cae | ||
|
|
7a3422bda6 | ||
|
|
fdc73624cf | ||
|
|
ae5654322c | ||
|
|
1cfe8b77a4 | ||
|
|
15bf019c2d | ||
|
|
d47ba73464 | ||
|
|
716aeef72d | ||
|
|
c48a20a03c | ||
|
|
7b2cd882d3 | ||
|
|
954810903c | ||
|
|
7f22a34d7e | ||
|
|
bf6b8eecb8 | ||
|
|
77d829e888 | ||
|
|
f2633bb335 | ||
|
|
de36ca87e8 | ||
|
|
9749402714 | ||
|
|
9e08f9d0bc | ||
|
|
e8d91e0f1f | ||
|
|
87fc681c56 | ||
|
|
709280c9a8 | ||
|
|
20d3e4fb62 | ||
|
|
05c81bc622 | ||
|
|
b42cd4b6e1 | ||
|
|
8bbd7bc466 | ||
|
|
347df2cdea | ||
|
|
4ff781bd3a | ||
|
|
423d80059c | ||
|
|
7bbd0e882b | ||
|
|
f9d8203238 | ||
|
|
a18bab932f | ||
|
|
ade57d9bb7 | ||
|
|
347f7cfecb | ||
|
|
18f5e25496 | ||
|
|
0001be960d | ||
|
|
38c8bc94ca | ||
|
|
d60fe0726f | ||
|
|
2e4115a33c | ||
|
|
bdf51dcd43 | ||
|
|
01d4242392 | ||
|
|
86f2f44b46 | ||
|
|
ac102396d7 | ||
|
|
663e7b307c | ||
|
|
afd27bf183 | ||
|
|
90712bf1e6 | ||
|
|
2a4968115f | ||
|
|
395915cb31 | ||
|
|
5de97f420c | ||
|
|
e51ae1098a | ||
|
|
da1e8e4664 | ||
|
|
1d82546c29 | ||
|
|
f42dcecab6 | ||
|
|
fdf6a3a2c6 | ||
|
|
e60cb6bfc5 | ||
|
|
4de27f4231 | ||
|
|
8f952acf91 | ||
|
|
8b8c1cc489 | ||
|
|
41e10f5f21 | ||
|
|
f18734f0b4 | ||
|
|
6949bd97e4 | ||
|
|
5ed1ef404b | ||
|
|
aa2d6db7e0 | ||
|
|
801074735e | ||
|
|
fe10c0dad6 | ||
|
|
0207197644 | ||
|
|
9730ee1c9e | ||
|
|
093eb708ed | ||
|
|
da1933397a | ||
|
|
47110a34b0 | ||
|
|
4f96d2c070 | ||
|
|
bd23b5c12f | ||
|
|
539048b57b | ||
|
|
7102cda49d | ||
|
|
7bdcd59797 | ||
|
|
957a339676 | ||
|
|
5ee192439b | ||
|
|
c239639ac7 | ||
|
|
1762affd7a | ||
|
|
a62e1c08ab | ||
|
|
0b6198f23a | ||
|
|
eff4bcfdf3 | ||
|
|
f5f2fb0fc8 | ||
|
|
a86ff05f69 | ||
|
|
209cdcff2a | ||
|
|
d25346ee39 | ||
|
|
16376c0897 | ||
|
|
6fe2089bea | ||
|
|
27fd960fb3 | ||
|
|
adbe5ba7cb | ||
|
|
2bb5397c2b | ||
|
|
1fce75feb9 | ||
|
|
83bfccc101 | ||
|
|
f0a5188cb1 | ||
|
|
28cbf3767a | ||
|
|
e7cd38ee85 | ||
|
|
c1be637101 | ||
|
|
6ab6bc62e7 | ||
|
|
8592b44c72 | ||
|
|
01bce88823 | ||
|
|
6aa8bc3ce9 | ||
|
|
840c0431ec | ||
|
|
4ca9a21ec6 | ||
|
|
fec0f66029 | ||
|
|
30efedb930 | ||
|
|
32c507999a | ||
|
|
9f6ea20f3e | ||
|
|
5b892c8814 | ||
|
|
504b22126b | ||
|
|
67aec2464b | ||
|
|
c99d4438db | ||
|
|
ac37968f73 | ||
|
|
3752232e3a | ||
|
|
7d5fa627cb | ||
|
|
4db9d7718c | ||
|
|
cf3e2e05bf | ||
|
|
b97012a10d | ||
|
|
e0af5e282e | ||
|
|
d6ce9e2dff | ||
|
|
c0a483f003 | ||
|
|
179d8294e4 | ||
|
|
c8f2056823 | ||
|
|
89e05e200e | ||
|
|
475c7cbf80 | ||
|
|
92331dd8bf | ||
|
|
eba3c2b2b1 | ||
|
|
0e82016232 | ||
|
|
0969465139 | ||
|
|
0e967ebefb | ||
|
|
8730812cf5 | ||
|
|
d7fc2ebff6 | ||
|
|
e4ed5b9cc8 | ||
|
|
7f8a1ab6d0 | ||
|
|
5e7aaf6894 | ||
|
|
4d501f05c3 | ||
|
|
a25f3e5fb8 | ||
|
|
eb4d9e9323 | ||
|
|
970a29cd5f | ||
|
|
8e20209391 | ||
|
|
05b703e93d | ||
|
|
a079593fdc | ||
|
|
c08a6a86a0 | ||
|
|
dbda7e02ca | ||
|
|
20fc36ea59 | ||
|
|
523b9c16eb | ||
|
|
b75add7c59 | ||
|
|
fabddc93ab | ||
|
|
4abbd9c15c | ||
|
|
a599c6513b | ||
|
|
05f9764236 | ||
|
|
5824529c12 | ||
|
|
54a15c7045 | ||
|
|
2136f6f5c3 | ||
|
|
b50dc69e05 | ||
|
|
fe45b409ef | ||
|
|
9d45aeb6ce | ||
|
|
778bbfd0f5 | ||
|
|
aac8f598d9 | ||
|
|
bde533def5 | ||
|
|
5eaa248451 | ||
|
|
276e8bb248 | ||
|
|
ec4fef6424 | ||
|
|
567aa28905 | ||
|
|
e15d39d102 | ||
|
|
04e120dfc9 | ||
|
|
9d12646452 | ||
|
|
ec59410b68 | ||
|
|
5ecccbf7fc | ||
|
|
e17a0d047a | ||
|
|
afeb263ae1 | ||
|
|
7af0a69584 | ||
|
|
378001f8ea | ||
|
|
824bb306f9 | ||
|
|
496cffdf99 | ||
|
|
d344741f85 | ||
|
|
9f695a28f5 | ||
|
|
5b7e567eb2 | ||
|
|
93ccad566c | ||
|
|
be68ebb920 | ||
|
|
b83672caab | ||
|
|
56dabfd5c9 | ||
|
|
71d7d929b4 | ||
|
|
866055018f | ||
|
|
e4d12d2a5a | ||
|
|
c71b06c9f2 | ||
|
|
72d3d4546f | ||
|
|
17cfd2e2f8 | ||
|
|
71d7fe0cf6 | ||
|
|
1c46c98c84 | ||
|
|
02c49ba645 | ||
|
|
a2cd0ef4ca | ||
|
|
64b99fedcc | ||
|
|
f7d6ce4a98 | ||
|
|
8b3372cdab | ||
|
|
f460b604e2 | ||
|
|
f1aade4b58 | ||
|
|
ccc2383402 | ||
|
|
3250f28217 | ||
|
|
544a531434 | ||
|
|
222eee19bf | ||
|
|
47830ffaf3 | ||
|
|
b582826fba | ||
|
|
5d14e4f667 | ||
|
|
97b09ba966 | ||
|
|
e72b67df70 | ||
|
|
c382cee930 | ||
|
|
d3ad9d9311 | ||
|
|
0b086689e8 | ||
|
|
cc91faaccc | ||
|
|
790e3fb097 | ||
|
|
982e2b72c1 | ||
|
|
e0a6253310 | ||
|
|
134984ea0b | ||
|
|
19610c4309 | ||
|
|
03f6cc1552 | ||
|
|
d6c6d75a45 | ||
|
|
ea4f0a4d28 | ||
|
|
66d191d431 | ||
|
|
bd99345a3c | ||
|
|
cfdbbb81d4 | ||
|
|
7f7197f216 | ||
|
|
2f949d4af0 | ||
|
|
bc06e7fcc1 | ||
|
|
a01b4ce4af | ||
|
|
965d2053cf |
@@ -14,7 +14,7 @@ body:
|
||||
- label: I have read the [Contributing Guide](https://github.com/FunkinCrew/Funkin/blob/main/docs/CONTRIBUTING.md)
|
||||
- label: I have checked the Issues/Discussions pages to see if my issue has already been reported
|
||||
- label: I have properly titled my issue
|
||||
- label: I did not have any mods installed when I encountered this issue
|
||||
- label: I did not have any mods installed when I encountered this issue, or the issue is related to mods
|
||||
|
||||
- type: dropdown
|
||||
attributes:
|
||||
@@ -60,7 +60,7 @@ body:
|
||||
attributes:
|
||||
label: Version
|
||||
description: Which version are you playing on? The game version is in the bottom left corner of the main menu.
|
||||
placeholder: ex. 0.8.4 or 0.8.5
|
||||
placeholder: ex. 0.8.6 or 0.9 Feature Preview 3
|
||||
validations:
|
||||
required: true
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ body:
|
||||
attributes:
|
||||
label: Version
|
||||
description: Which version are you playing on? The game version is in the bottom left corner of the main menu.
|
||||
placeholder: ex. 0.8.4 or 0.8.5
|
||||
placeholder: ex. 0.8.6 or 0.9 Feature Preview 3
|
||||
validations:
|
||||
required: true
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ body:
|
||||
attributes:
|
||||
label: Version
|
||||
description: Which version are you compiling? The game version is in the bottom left corner of the main menu or in the project.hxp file.
|
||||
placeholder: ex. 0.8.4 or 0.8.5
|
||||
placeholder: ex. 0.8.6 or `preview/public-playtest`
|
||||
validations:
|
||||
required: true
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ body:
|
||||
- label: I have read the [Contributing Guide](https://github.com/FunkinCrew/Funkin/blob/main/docs/CONTRIBUTING.md)
|
||||
- label: I have checked the Issues/Discussions pages to see if my issue has already been reported
|
||||
- label: I have properly titled my issue
|
||||
- label: I did not have any mods installed when I encountered this issue
|
||||
- label: I did not have any mods installed when I encountered this issue, or the issue is related to mods
|
||||
|
||||
- type: dropdown
|
||||
attributes:
|
||||
@@ -61,7 +61,7 @@ body:
|
||||
attributes:
|
||||
label: Version
|
||||
description: Which version are you playing on? The game version is in the bottom left corner of the main menu.
|
||||
placeholder: ex. 0.8.4 or 0.8.5
|
||||
placeholder: ex. 0.8.6 or 0.9 Feature Preview 3
|
||||
validations:
|
||||
required: true
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ inputs:
|
||||
haxe:
|
||||
description: 'Version of haxe to install'
|
||||
required: true
|
||||
default: '4.3.6'
|
||||
default: '4.3.7'
|
||||
hxcpp-cache:
|
||||
description: 'Whether to use a shared hxcpp compile cache'
|
||||
required: true
|
||||
@@ -71,7 +71,7 @@ runs:
|
||||
|
||||
- name: Restore cached dependencies
|
||||
id: cache-hmm
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .haxelib
|
||||
key: haxe-hmm-${{ runner.os }}-${{ hashFiles('**/hmm.json') }}
|
||||
@@ -98,7 +98,7 @@ runs:
|
||||
# by default use a shared hxcpp cache
|
||||
- if: ${{ inputs.hxcpp-cache == 'true' }}
|
||||
name: Restore hxcpp cache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ${{ inputs.hxcpp-cache-path }}
|
||||
key: haxe-hxcpp-${{ runner.os }}-${{ github.ref_name }}-${{ github.sha }}
|
||||
@@ -114,7 +114,7 @@ runs:
|
||||
# if it's explicitly disabled, still cache export/ since that then contains the builds
|
||||
- if: ${{ inputs.hxcpp-cache != 'true' }}
|
||||
name: Restore export cache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ${{ inputs.hxcpp-cache-path }}
|
||||
key: haxe-export-${{ runner.os }}-${{ github.ref_name }}-${{ github.sha }}
|
||||
|
||||
@@ -61,7 +61,7 @@ runs:
|
||||
- name: Get latest butler version
|
||||
shell: bash
|
||||
run: |
|
||||
LATEST=$(curl -sfL https://broth.itch.ovh/butler/$OS_AND_ARCH/LATEST)
|
||||
LATEST=$(curl -sfL https://broth.itch.zone/butler/$OS_AND_ARCH/LATEST)
|
||||
echo BUTLER_LATEST=$LATEST >> "$GITHUB_ENV"
|
||||
|
||||
command -v butler \
|
||||
@@ -70,7 +70,7 @@ runs:
|
||||
|
||||
- name: Try to get butler from cache
|
||||
id: cache-butler
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ${{ env.BUTLER_INSTALL_PATH }}
|
||||
key: butler-${{ runner.os }}-${{ env.BUTLER_LATEST }}
|
||||
@@ -88,7 +88,7 @@ runs:
|
||||
mkdir -p $BUTLER_INSTALL_PATH
|
||||
cd $BUTLER_INSTALL_PATH
|
||||
|
||||
curl -L -o butler.zip https://broth.itch.ovh/butler/$OS_AND_ARCH/LATEST/archive/default
|
||||
curl -L -o butler.zip https://broth.itch.zone/butler/$OS_AND_ARCH/LATEST/archive/default
|
||||
unzip butler.zip
|
||||
chmod +x butler
|
||||
|
||||
|
||||
@@ -24,10 +24,10 @@ jobs:
|
||||
trigger-build: ${{ steps.should-trigger.outputs.result }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: funkincrew/ci-checkout@v7.3.3
|
||||
uses: funkincrew/ci-checkout@v7.4
|
||||
with:
|
||||
submodules: false
|
||||
- uses: dorny/paths-filter@v3
|
||||
- uses: dorny/paths-filter@v4
|
||||
id: filter
|
||||
with:
|
||||
base: ${{ github.ref }}
|
||||
@@ -59,7 +59,7 @@ jobs:
|
||||
list: ${{ steps.build-tags.outputs.list }}
|
||||
steps:
|
||||
- name: Gather build tags
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@v8
|
||||
id: build-tags
|
||||
with:
|
||||
script: |
|
||||
@@ -96,17 +96,20 @@ jobs:
|
||||
packages: write
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: funkincrew/ci-checkout@v7.3.3
|
||||
uses: funkincrew/ci-checkout@v7.4
|
||||
with:
|
||||
submodules: false
|
||||
- name: Log into GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@v7
|
||||
env:
|
||||
DOCKER_BUILD_SUMMARY: false
|
||||
DOCKER_BUILD_RECORD_UPLOAD: false
|
||||
with:
|
||||
context: ./build
|
||||
push: true
|
||||
@@ -143,14 +146,14 @@ jobs:
|
||||
run: |
|
||||
git config --global --replace-all safe.directory $GITHUB_WORKSPACE
|
||||
- name: Get checkout token
|
||||
uses: actions/create-github-app-token@v1
|
||||
uses: actions/create-github-app-token@v3
|
||||
id: app_token
|
||||
with:
|
||||
app-id: ${{ vars.APP_ID }}
|
||||
private-key: ${{ secrets.APP_PEM }}
|
||||
owner: ${{ github.repository_owner }}
|
||||
- name: Checkout repo
|
||||
uses: funkincrew/ci-checkout@v7.3.3
|
||||
uses: funkincrew/ci-checkout@v7.4
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
token: ${{ steps.app_token.outputs.token }}
|
||||
@@ -184,7 +187,7 @@ jobs:
|
||||
timeout-minutes: 120
|
||||
- name: Save build artifact to Github Actions
|
||||
if: ${{ github.event.inputs.save-artifact }}
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: build-${{ matrix.target }}
|
||||
path: export/release/${{matrix.target}}/bin/
|
||||
@@ -212,14 +215,14 @@ jobs:
|
||||
BUILD_DEFINES: ${{ github.event.inputs.build-defines || '-DGITHUB_BUILD' }}
|
||||
steps:
|
||||
- name: Get checkout token
|
||||
uses: actions/create-github-app-token@v1
|
||||
uses: actions/create-github-app-token@v3
|
||||
id: app_token
|
||||
with:
|
||||
app-id: ${{ vars.APP_ID }}
|
||||
private-key: ${{ secrets.APP_PEM }}
|
||||
owner: ${{ github.repository_owner }}
|
||||
- name: Checkout repo
|
||||
uses: funkincrew/ci-checkout@v7.3.3
|
||||
uses: funkincrew/ci-checkout@v7.4
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
token: ${{ steps.app_token.outputs.token }}
|
||||
@@ -233,7 +236,7 @@ jobs:
|
||||
echo "HAXEPATH=$(haxelib config)" >> "$GITHUB_ENV"
|
||||
- name: Restore cached dependencies
|
||||
id: cache-hmm
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .haxelib
|
||||
key: haxe-hmm-${{ runner.os }}-${{ hashFiles('**/hmm.json') }}
|
||||
@@ -242,15 +245,35 @@ jobs:
|
||||
run: |
|
||||
git config --global 'url.https://x-access-token:${{ steps.app_token.outputs.token }}@github.com/.insteadOf' https://github.com/
|
||||
git config --global advice.detachedHead false
|
||||
haxelib --global git haxelib https://github.com/FunkinCrew/haxelib.git
|
||||
haxelib --global git hmm https://github.com/FunkinCrew/hmm.git
|
||||
haxelib --global run hmm install -q
|
||||
cd .haxelib/hxcpp/git/tools/hxcpp && haxe compile.hxml
|
||||
haxelib --global fixrepo
|
||||
haxelib --global list
|
||||
pushd .haxelib/hxcpp/git/tools/hxcpp && haxe compile.hxml && popd
|
||||
- if: ${{ matrix.target != 'html5' }}
|
||||
name: Restore hxcpp cache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: /usr/share/hxcpp
|
||||
key: haxe-hxcpp-${{ runner.os }}-${{ github.ref_name }}-${{ github.sha }}
|
||||
restore-keys: haxe-hxcpp-${{ runner.os }}-${{ github.ref_name }}
|
||||
- name: Restore lime rebuild cache
|
||||
id: cache-lime
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .haxelib/lime/git/ndll/Linux64
|
||||
key: haxe-lime-linux64-${{ runner.os }}-${{ hashFiles('**/hmm.json') }}-${{ github.sha }}
|
||||
restore-keys: haxe-lime-linux64-${{ runner.os }}-${{ hashFiles('**/hmm.json') }}
|
||||
- name: Setup lime
|
||||
run: |
|
||||
haxelib --always run lime setup
|
||||
haxelib run lime rebuild hxcpp
|
||||
- if: ${{ steps.cache-lime.outputs.cache-hit != 'true' }}
|
||||
name: Rebuild lime
|
||||
run: |
|
||||
haxelib run lime rebuild cpp -64
|
||||
git -C .haxelib/lime/git status || true
|
||||
- name: Populate .env
|
||||
run: |
|
||||
touch .env
|
||||
@@ -262,7 +285,7 @@ jobs:
|
||||
timeout-minutes: 120
|
||||
- name: Save build artifact to Github Actions
|
||||
if: ${{ github.event.inputs.save-artifact }}
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: build-${{ matrix.target }}
|
||||
path: export/release/${{matrix.target}}/bin/
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Cancel queued workflows for ${{ github.event.pull_request.head.ref }}
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@v8
|
||||
with:
|
||||
result-encoding: string
|
||||
retries: 3
|
||||
|
||||
@@ -27,4 +27,4 @@ jobs:
|
||||
action:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/label-actions@v4
|
||||
- uses: dessant/label-actions@v5
|
||||
|
||||
@@ -7,6 +7,11 @@ on:
|
||||
types:
|
||||
- opened
|
||||
|
||||
# Ensure only one task can execute for a given PR at a time.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref }}
|
||||
queue: max
|
||||
|
||||
|
||||
jobs:
|
||||
# Apply `status: pending triage` to newly created pull requests
|
||||
|
||||
@@ -13,6 +13,10 @@ name: "Pull Request Labeler"
|
||||
on:
|
||||
- pull_request_target
|
||||
|
||||
# Ensure only one task can execute for a given PR at a time.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref }}
|
||||
queue: max
|
||||
|
||||
jobs:
|
||||
# Apply labels to pull requests based on which files were edited
|
||||
@@ -23,7 +27,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set basic labels
|
||||
uses: actions/labeler@v5
|
||||
uses: actions/labeler@v6
|
||||
with:
|
||||
sync-labels: true
|
||||
# Apply labels to pull requests based on how many lines were edited
|
||||
|
||||
@@ -17,6 +17,14 @@ NewgroundsCredentials.hx
|
||||
.idea/
|
||||
*.iml
|
||||
|
||||
# Dox output and types
|
||||
docs/dox/output
|
||||
docs/dox/Windows.xml
|
||||
docs/dox/Mac.xml
|
||||
docs/dox/iOS.xml
|
||||
docs/dox/Linux.xml
|
||||
docs/dox/Android.xml
|
||||
|
||||
# Mobile signing stuff
|
||||
.apple/
|
||||
.env
|
||||
|
||||
Vendored
+8
-2
@@ -72,6 +72,7 @@
|
||||
"haxecheckstyle.externalSourceRoots": [],
|
||||
"haxecheckstyle.configurationFile": "checkstyle.json",
|
||||
"haxecheckstyle.codeSimilarityBufferSize": 100,
|
||||
"lime.projectFile": "project.hxp",
|
||||
"lime.targets": [
|
||||
{ "name": "windows", "enabled": true, "label": "Windows" },
|
||||
{ "name": "mac", "enabled": true, "label": "macOS" },
|
||||
@@ -79,13 +80,13 @@
|
||||
{ "name": "html5", "enabled": true, "label": "HTML5" },
|
||||
{ "name": "android", "enabled": true, "label": "Android" },
|
||||
{ "name": "ios", "enabled": true, "label": "iOS" },
|
||||
{ "name": "hl", "enabled": true, "label": "HashLink" },
|
||||
|
||||
// Disabled targets
|
||||
{ "name": "air", "enabled": false },
|
||||
{ "name": "electron", "enabled": false },
|
||||
{ "name": "flash", "enabled": false },
|
||||
{ "name": "neko", "enabled": false },
|
||||
{ "name": "tvos", "enabled": false }
|
||||
{ "name": "hl", "enabled": false }
|
||||
],
|
||||
"lime.defaultTargetConfiguration": "Windows / Debug",
|
||||
"lime.targetConfigurations": [
|
||||
@@ -143,6 +144,11 @@
|
||||
"target": "windows",
|
||||
"args": ["-debug", "-DLATENCY", "-DFEATURE_DEBUG_FUNCTIONS"]
|
||||
},
|
||||
{
|
||||
"label": "Windows / Debug (No Asset Redirect)",
|
||||
"target": "windows",
|
||||
"args": ["-debug", "-DNO_REDIRECT_ASSETS_FOLDER"]
|
||||
},
|
||||
{
|
||||
"label": "Windows / Debug (Waveform Test)",
|
||||
"target": "windows",
|
||||
|
||||
+142
-38
@@ -4,6 +4,109 @@ All notable changes will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.8.7] - 2026-08-23
|
||||
|
||||
### Fixed
|
||||
|
||||
- [ANDROID] Fixed a crash when opening an FNFC chart file.
|
||||
- [ANDROID] Fixed errors and crashes related to the lime backend.
|
||||
- [ANDROID] Fixed a shader not displaying correctly in some places.
|
||||
|
||||
|
||||
|
||||
## [0.8.6] - 2026-08-12
|
||||
|
||||
### Added
|
||||
|
||||
- Added the ability to toggle Discord RPC statuses and hide song info.
|
||||
- [LINUX] Added support for Wayland, which the game now defaults to. (Thanks Starexify!)
|
||||
- Added the game version as a compilation flag for modders to access. ([e51ae10](https://github.com/FunkinCrew/Funkin/commit/e51ae1098a9392c7ec3a903543f3aa4fc4220da1)) - by @zxcksharks in [#7659](https://github.com/FunkinCrew/Funkin/pull/7659)
|
||||
- Added a shouldBop property to HealthIconData to allow animated icons to bop. ([cc91faa](https://github.com/FunkinCrew/Funkin/commit/cc91faaccc63d2050270723bd49477f8b518ab6f)) - by @Starexify in [#6901](https://github.com/FunkinCrew/Funkin/pull/6901)
|
||||
- Added album and sticker pack fields to the Chart Editor Metadata window. ([790e3fb](https://github.com/FunkinCrew/Funkin/commit/790e3fb097b7054e7cf4010d6b588264414d283a)) - by @Starexify in [#6266](https://github.com/FunkinCrew/Funkin/pull/6266)
|
||||
|
||||
### Changed
|
||||
|
||||
- [HTML5] The “Touch To Play” sprite now smoothly scales when hovered.
|
||||
- Made some improvements to width/height and cliprect functionality for FunkinGroup.
|
||||
- The Chart Editor now consistently exports chart data in the same order. (Thanks TechnikTil!)
|
||||
- Discord RPC images can now be configured in the album and song data files.
|
||||
- Discord RPC now pulls icons based on character icon data. ([bd23b5c](https://github.com/FunkinCrew/Funkin/commit/bd23b5c12f734eae529a8d2d2593fd1d6eb9a27b)) - by @7oltan in [#7643](https://github.com/FunkinCrew/Funkin/pull/7643)
|
||||
- Forced animations for the player character now unmute the player's vocals. ([e0a6253](https://github.com/FunkinCrew/Funkin/commit/e0a625331010a2dddde639a24953dd88f25010b1)) - by @Lasercar in [#4314](https://github.com/FunkinCrew/Funkin/pull/4314)
|
||||
- The Animation Editor now plays the Chart Editor theme music and click sounds. ([f42dcec](https://github.com/FunkinCrew/Funkin/commit/f42dcecab6966f77162308a0564af558616ea81b)) - by @JVNpixels in [#7556](https://github.com/FunkinCrew/Funkin/pull/7556)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Made some niche fixes to Polymod.
|
||||
- Argument count validation no longer crashes the game entirely in some instances. (Thanks Starexify!)
|
||||
- The `cast` keyword no longer throws a parsing error. (Thanks gamerbross!)
|
||||
- Every non-Windows platform is now case-insensitive. (Thanks TechnikTil!)
|
||||
- Preprocessors that span the entire file no longer throw an error. (Thanks KoloInDaCrib!)
|
||||
- Scripted class extending no longer breaks with multiple scripted layers. (Thanks TechnikTil!)
|
||||
- Imports with module names (ex. `funkin.play.character.BaseCharacter.CharacterType`) no longer throw an import error. (Thanks NotHyper-474!)
|
||||
- [iOS] Connecting a keyboard no longer freezes the game.
|
||||
- The Darken blend mode no longer renders with black boxes, fixing the Boyfriend Freeplay DJ Dad animation.
|
||||
- The Open File dialog now opens from the latest directory, not the root directory.
|
||||
- The Chart Editor now exports charts with correct suffixes for vocal tracks.
|
||||
- Clicking the Save Chart button now displays a notification in the Chart Editor.
|
||||
- Disconnecting a controller while in the gamepad controls menu no longer crashes the game. ([6fe2089](https://github.com/FunkinCrew/Funkin/commit/6fe2089beac639124d3561d4c2c1af1ffb7dfe11)) - by @MrMadera in [#7214](https://github.com/FunkinCrew/Funkin/pull/7214)
|
||||
- Hot-reloading and re-entering the Lag Adjustment menu no longer crashes the game. ([adbe5ba](https://github.com/FunkinCrew/Funkin/commit/adbe5ba7cb53f67363ec205c5e555744e69215de)) - by @AnimatingLegend in [#7304](https://github.com/FunkinCrew/Funkin/pull/7304)
|
||||
- `onExit` is now properly called when exiting the game. ([90712bf](https://github.com/FunkinCrew/Funkin/commit/90712bf1e62a20d1201c3da15b4554720e9fff46)) - by @AnimatingLegend in [#7321](https://github.com/FunkinCrew/Funkin/pull/7321)
|
||||
- Focusing into the game with 0 volume and Pause on Unfocus disabled no longer increases the volume. ([18f5e25](https://github.com/FunkinCrew/Funkin/commit/18f5e25496d2cb74fff24e490a95db29a1fb59e3)) - by @ahmed7p in [#7750](https://github.com/FunkinCrew/Funkin/pull/7750)
|
||||
- Save Data prompts no longer allow scrolling the Options menu behind them. ([83bfccc](https://github.com/FunkinCrew/Funkin/commit/83bfccc10115b089f6b8d747c366c2be64c4335c)) - by @Starexify in [#7213](https://github.com/FunkinCrew/Funkin/pull/7213)
|
||||
- Adjusted the Lag Adjustment overlay to fit the whole screen. ([27fd960](https://github.com/FunkinCrew/Funkin/commit/27fd960fb369b2baf3c3377fa317732bf80a5230)) - by @JVNpixels in [#7358](https://github.com/FunkinCrew/Funkin/pull/7358)
|
||||
- Input latency is now calculated correctly when hitting a note late in the Lag Adjustment menu. ([de36ca8](https://github.com/FunkinCrew/Funkin/commit/de36ca87e8b95d8fe4d40d458c355baf52e4d94a)) - by @nykwono in [#7792](https://github.com/FunkinCrew/Funkin/pull/7792)
|
||||
- Weeks with non-default variation songs no longer use default variation scripts. ([2a49681](https://github.com/FunkinCrew/Funkin/commit/2a4968115f0ed5e81d4209bedba3f8bf153aab6a)) - by @requazar in [#7586](https://github.com/FunkinCrew/Funkin/pull/7586)
|
||||
- Scrolling Freeplay after the rank slam animation now properly updates the song preview. ([347f7cf](https://github.com/FunkinCrew/Funkin/commit/347f7cfecbe91fc06e71a502ee58a5d7859be5fc)) - by @AnimatingLegend in [#7230](https://github.com/FunkinCrew/Funkin/pull/7230)
|
||||
- Earning a new rank no longer causes the song title to clip incorrectly. ([0b6198f](https://github.com/FunkinCrew/Funkin/commit/0b6198f23ad7a957d40eaaf6d4af9b976e6e1a36)) - by @KoloInDaCrib in [#7350](https://github.com/FunkinCrew/Funkin/pull/7350)
|
||||
- Selecting a Freeplay song capsule no longer occasionally squashes the text. ([bdf51dc](https://github.com/FunkinCrew/Funkin/commit/bdf51dcd4392a7d99c9837bd3b56b4e6497cf207)) - by @Lasercar in [#6038](https://github.com/FunkinCrew/Funkin/pull/6038)
|
||||
- The Freeplay backing image now respects modified alpha values. ([840c043](https://github.com/FunkinCrew/Funkin/commit/840c0431ecaf3004901bd09a346c126eb8e2f484)) - by @Luscious77 in [#7576](https://github.com/FunkinCrew/Funkin/pull/7576)
|
||||
- Removed clipping from the OST Vol 1 album title sprite. ([90282d7](https://github.com/FunkinCrew/funkin.assets/commit/90282d78c6a326f1c1e05bec3f3638d3f0cd66a9)) - by @LeGooeyy in [funkin.assets#410](https://github.com/FunkinCrew/funkin.assets/pull/410)
|
||||
- The Freeplay change character hint now updates consistently when a gamepad is connected. ([e0af5e2](https://github.com/FunkinCrew/Funkin/commit/e0af5e282e6cf2ad0a63dbf633eb325204fbd649)) - by @MrMadera in [#7409](https://github.com/FunkinCrew/Funkin/pull/7409)
|
||||
- Character Select nametags no longer become stuck pixelated when switching between characters. ([a62e1c0](https://github.com/FunkinCrew/Funkin/commit/a62e1c08ab4a8cbe1f0bc790e4c228b5b64f0071)) - by @NotHyper-474 in [#7217](https://github.com/FunkinCrew/Funkin/pull/7217)
|
||||
- Pressing a note with two different keybinds now properly penalizes health. ([d60fe07](https://github.com/FunkinCrew/Funkin/commit/d60fe0726f1cab3999a35ff497ba32e82afbd1b8)) - by @realvirtu in [#7744](https://github.com/FunkinCrew/Funkin/pull/7744)
|
||||
- Input latency is now calculated correctly when hitting a note late. ([b97012a](https://github.com/FunkinCrew/Funkin/commit/b97012a10d54e222a3f370956d0e42f8d8eaab47)) - by @Lasercar in [#7367](https://github.com/FunkinCrew/Funkin/pull/7367)
|
||||
- Conductor events are no longer dispatched when a substate is active. ([19610c4](https://github.com/FunkinCrew/Funkin/commit/19610c43099dfaf4a8b9ae70dc7f4b1833f420a9)) - by @KoloInDaCrib in [#6886](https://github.com/FunkinCrew/Funkin/pull/6886)
|
||||
- Health icon angles now lerp at the proper rate. ([2bb5397](https://github.com/FunkinCrew/Funkin/commit/2bb5397c2b9e7fcc9d62670c6a86ebce64737f46)) - by @Starexify in [#7222](https://github.com/FunkinCrew/Funkin/pull/7222)
|
||||
- Hold note covers no longer disappear when too many are on screen at once. ([f0a5188](https://github.com/FunkinCrew/Funkin/commit/f0a5188cb11cde3f6646254a39953e7b064dd7e9)) - by @realvirtu in [#7593](https://github.com/FunkinCrew/Funkin/pull/7593)
|
||||
- The notestyle now properly falls back to the default notestyle in PlayState. ([ac10239](https://github.com/FunkinCrew/Funkin/commit/ac102396d71609b61f8864c2dad72b8d4b647dd1)) - by @NotHyper-474 in [#7721](https://github.com/FunkinCrew/Funkin/pull/7721)
|
||||
- Using characters outside of PlayState no longer tries to create health icons. ([da1e8e4](https://github.com/FunkinCrew/Funkin/commit/da1e8e4664dfdd098794aa7187e15c85d020508c)) - by @zxcksharks in [#7646](https://github.com/FunkinCrew/Funkin/pull/7646)
|
||||
- Pausing the game on the same frame a camera event is triggered no longer cancels the event. ([0e967eb](https://github.com/FunkinCrew/Funkin/commit/0e967ebefb61cb007cc84fc2032dc4a1d7c399a5)) - by @realvirtu in [#7472](https://github.com/FunkinCrew/Funkin/pull/7472)
|
||||
- Pausing while a dialogue conversation is fading out now pauses the fade tween. ([c0a483f](https://github.com/FunkinCrew/Funkin/commit/c0a483f003ca901679e7a4a3fe5a9dfacd86ea15)) - by @ahmed7p in [#7359](https://github.com/FunkinCrew/Funkin/pull/7359)
|
||||
- A-Bot's eyes now consistently follow the Focus Camera event. ([0de4f94](https://github.com/FunkinCrew/funkin.assets/commit/0de4f94e10f09f637dca2dedf2538d5ae45dcd97)) - by @ahmed7p in [funkin.assets#408](https://github.com/FunkinCrew/funkin.assets/pull/408)
|
||||
- Doppelganger Pico's vocals are now fully muted after encountering an easter egg. ([09e3b50](https://github.com/FunkinCrew/funkin.assets/commit/09e3b5025268e53c5c9415e9d2c40122c5ec4493)) - by @trayfellow in [funkin.assets#401](https://github.com/FunkinCrew/funkin.assets/pull/401)
|
||||
- The passing car in Week 4 stages no longer floats when the camera is zoomed out. ([baacbaa](https://github.com/FunkinCrew/funkin.assets/commit/baacbaa45469a5497e0ac4e35dc772214beef763)) - by @realvirtu in [funkin.assets#415](https://github.com/FunkinCrew/funkin.assets/pull/415)
|
||||
- Spirit's icon no longer renders behind the health bar in some cases. ([4f96d2c](https://github.com/FunkinCrew/Funkin/commit/4f96d2c070c2768327c6fcd5983dd6a4458f61b3)) - by @NotHyper-474 in [#7676](https://github.com/FunkinCrew/Funkin/pull/7676)
|
||||
- The Stress background tankmen now pause their flickering when the game is paused. ([25c7810](https://github.com/FunkinCrew/funkin.assets/commit/25c781024d4299c15c42a23d2ed788c9e34785fa)) - by @ahmed7p in [funkin.assets#405](https://github.com/FunkinCrew/funkin.assets/pull/405)
|
||||
- Optimized the rimlight shader to improve performance in the Week 7 Erect stage. ([0e82016](https://github.com/FunkinCrew/Funkin/commit/0e8201623240ed189ce8517431e73eb6a0d8b50c)) - by @iLauncherDev in [#7517](https://github.com/FunkinCrew/Funkin/pull/7517)
|
||||
- Selecting between events of different types while searching in the Events window no longer crashes the Chart Editor. ([05c81bc](https://github.com/FunkinCrew/Funkin/commit/05c81bc622fbe8eeaefbc685389c18d8944243b2)) - by @Infinite-SUDO67 in [#7767](https://github.com/FunkinCrew/Funkin/pull/7767)
|
||||
- Selecting between notes with different notekinds while searching in the Notes window no longer crashes the Chart Editor. ([b42cd4b](https://github.com/FunkinCrew/Funkin/commit/b42cd4b6e17ac9bbff9934a69b10c7fbb2e6f5e6)) - by @kiryvajiravuth in [#7761](https://github.com/FunkinCrew/Funkin/pull/7761)
|
||||
- Chart Editor dropdowns no longer lock focus onto them after selecting an item. ([86f2f44](https://github.com/FunkinCrew/Funkin/commit/86f2f44b468a25c060240911765a8b210867418b)) - by @VICK-sys in [#7528](https://github.com/FunkinCrew/Funkin/pull/7528)
|
||||
- Health icons now consistently appear in the Chart Editor. ([1fce75f](https://github.com/FunkinCrew/Funkin/commit/1fce75feb99988a4757f620968f4ab53d68111c7)) - by @Starexify in [#7193](https://github.com/FunkinCrew/Funkin/pull/7193)
|
||||
- Chart Editor Results Screen music no longer persists into gameplay when hot-reloading with F5. ([0b08668](https://github.com/FunkinCrew/Funkin/commit/0b086689e82c6fd6cac0d96b4cdca7b18543659d)) - by @AnimatingLegend in [#7126](https://github.com/FunkinCrew/Funkin/pull/7126)
|
||||
- Chart Editor playtests now only carry over custom playback rates when "Use Editor Audio Settings" is enabled. ([7f8a1ab](https://github.com/FunkinCrew/Funkin/commit/7f8a1ab6d067db0b2cd7d16f75d08cc2bce6731d)) - by @NotHyper-474 in [#7483](https://github.com/FunkinCrew/Funkin/pull/7483)
|
||||
- Packaged song scripts no longer create errors during Chart Editor playtests. ([b75add7](https://github.com/FunkinCrew/Funkin/commit/b75add7c59d338606b7004f5814e976aaa074a8f)) - by @ahmed7p in [#7470](https://github.com/FunkinCrew/Funkin/pull/7470)
|
||||
- Saving a chart or metadata file through the Difficulty toolbox now saves with the correct file name. ([6aa8bc3](https://github.com/FunkinCrew/Funkin/commit/6aa8bc3ce93affbe69bf7b39300c62f60e912cce)) - by @NebulaStellaNova in [#7571](https://github.com/FunkinCrew/Funkin/pull/7571)
|
||||
- The Chart Editor background now scales properly on widescreen resolutions. ([2e4115a](https://github.com/FunkinCrew/Funkin/commit/2e4115a33cee591f28433b92da4ead2e64da90fa)) - by @JVNpixels in [#7741](https://github.com/FunkinCrew/Funkin/pull/7741)
|
||||
- The Stage Editor no longer crashes when loading in Texture Atlas props. ([e8d91e0](https://github.com/FunkinCrew/Funkin/commit/e8d91e0f1f6aff6a62b4946868f5dfe6d6b2d461)) - by @KoloInDaCrib in [#7674](https://github.com/FunkinCrew/Funkin/pull/7674)
|
||||
- Folders in the mod folder without Polymod metadata no longer display an error. ([6ab6bc6](https://github.com/FunkinCrew/Funkin/commit/6ab6bc62e7bd81e218747ed4446089f04a938811)) - by @Starexify in [#7282](https://github.com/FunkinCrew/Funkin/pull/7282)
|
||||
- Enforced the Polymod blacklist in ReflectUtil. ([66d191d](https://github.com/FunkinCrew/Funkin/commit/66d191d43102f75f672478bd2efd9c7e820c1c05)) - by @FuroYT in [#7005](https://github.com/FunkinCrew/Funkin/pull/7005)
|
||||
- Blacklisted a class for security. ([3752232](https://github.com/FunkinCrew/Funkin/commit/3752232e3ab6ed0cb41445cb50729e74f338fa44)) - by @charlesisfeline in [#7512](https://github.com/FunkinCrew/Funkin/pull/7512)
|
||||
|
||||
## New Contributors for 0.8.6
|
||||
|
||||
* @moxie-coder made their first contribution in [#7187](https://github.com/FunkinCrew/Funkin/pull/7187)
|
||||
* @ahmed7p made their first contribution in [#7470](https://github.com/FunkinCrew/Funkin/pull/7470)
|
||||
* @iLauncherDev made their first contribution in [#7517](https://github.com/FunkinCrew/Funkin/pull/7517)
|
||||
* @Luscious77 made their first contribution in [#7576](https://github.com/FunkinCrew/Funkin/pull/7576)
|
||||
* @VICK-sys made their first contribution in [#7528](https://github.com/FunkinCrew/Funkin/pull/7528)
|
||||
* @MRK2009 made their first contribution in [#7686](https://github.com/FunkinCrew/Funkin/pull/7686)
|
||||
* @kiryvajiravuth made their first contribution in [#7761](https://github.com/FunkinCrew/Funkin/pull/7761)
|
||||
* @Infinite-SUDO67 made their first contribution in [#7767](https://github.com/FunkinCrew/Funkin/pull/7767)
|
||||
* @nykwono made their first contribution in [#7792](https://github.com/FunkinCrew/Funkin/pull/7792)
|
||||
* @WizardMantis441 made their first contribution in [funkin.assets#413](https://github.com/FunkinCrew/funkin.assets/pull/413)
|
||||
|
||||
|
||||
|
||||
## [0.8.5] - 2026-04-06
|
||||
|
||||
### Fixed
|
||||
@@ -80,22 +183,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- The Girlfriend Story Mode prop now bops continuously when scrolling through levels. ([84b2d5b](https://github.com/FunkinCrew/Funkin/commit/84b2d5b48d9eb76c918fdba6987ccc1f5da76133)) - by @Redar13 in [#6830](https://github.com/FunkinCrew/Funkin/pull/6830)
|
||||
- The Freeplay new rank slam animation now properly plays its glow effect. ([fcbce0a](https://github.com/FunkinCrew/Funkin/commit/fcbce0a66b75b0c1224c6a0e2907c170b71998ad)) - by @FuroYT in [#7015](https://github.com/FunkinCrew/Funkin/pull/7015)
|
||||
- The Freeplay Random capsule no longer displays BPM and difficulty numbers. ([0ad2d50](https://github.com/FunkinCrew/Funkin/commit/0ad2d507efa9dcb577184e28bfd04091b3424bfb)) - by @Lasercar in [#4927](https://github.com/FunkinCrew/Funkin/pull/4927)
|
||||
- Favoriting a song in Freeplay no longer breaks capsule text cycling. ([ce493a0](https://github.com/FunkinCrew/Funkin/commit/ce493a03c9ffb4c43c2c27885ed0fab0c1c3531d)) - by @VirtuGuy in [#7134](https://github.com/FunkinCrew/Funkin/pull/7134)
|
||||
- Favoriting a song in Freeplay no longer breaks capsule text cycling. ([ce493a0](https://github.com/FunkinCrew/Funkin/commit/ce493a03c9ffb4c43c2c27885ed0fab0c1c3531d)) - by @realvirtu in [#7134](https://github.com/FunkinCrew/Funkin/pull/7134)
|
||||
- Freeplay songs with invalid pixel icons no longer duplicate the icon from the previous song in the list. ([b3eb709](https://github.com/FunkinCrew/Funkin/commit/b3eb709f4ed535ed2544f3bb530ff3724e07be3f)) - by @FuroYT in [#7006](https://github.com/FunkinCrew/Funkin/pull/7006)
|
||||
- A Freeplay clear percent of 100% now properly exits to the right when returning to the Main Menu. ([5974c1a](https://github.com/FunkinCrew/Funkin/commit/5974c1a48293f3185c5f249acb9130ebd6b35ae4)) - by @Trayfellow in [#7183](https://github.com/FunkinCrew/Funkin/pull/7183)
|
||||
- Nudged the Freeplay backing image down by one pixel to align with the bottom of the screen. ([b8c2854](https://github.com/FunkinCrew/Funkin/commit/b8c2854007f36ac7a2b6897eead3f979e11f0ad7)) - by @SuperEric1 in [#6893](https://github.com/FunkinCrew/Funkin/pull/6893)
|
||||
- Improved performance for songs that use a lot of events. ([3b27ec5](https://github.com/FunkinCrew/Funkin/commit/3b27ec5b66b2fa00d59a77f6ec07aff68e440860)) - by @KoloInDaCrib in [#7171](https://github.com/FunkinCrew/Funkin/pull/7171)
|
||||
- Adjusted hit window logic to accurately reflect threshold values for all judgments. ([dcb5b3a](https://github.com/FunkinCrew/Funkin/commit/dcb5b3a9358a9bb126153b57aa2d38dc0684c39d)) - by @Rudyrue in [#7104](https://github.com/FunkinCrew/Funkin/pull/7104)
|
||||
- Adjusted offsets for all health icons to be more consistent. ([83d8134](https://github.com/FunkinCrew/funkin.assets/commit/83d8134f9d0b3cf3b59e9e1d972fa1e200a98ba1)) - by @LeGooeyy in [funkin.assets#278](https://github.com/FunkinCrew/funkin.assets/pull/278)
|
||||
- Hold notes no longer shift upward when hit early. ([d62c8af](https://github.com/FunkinCrew/Funkin/commit/d62c8af20c90ec3d6e4274aba8ddbfb378ab0256)) - by @VirtuGuy in [#7060](https://github.com/FunkinCrew/Funkin/pull/7060)
|
||||
- Hold notes no longer shift upward when hit early. ([d62c8af](https://github.com/FunkinCrew/Funkin/commit/d62c8af20c90ec3d6e4274aba8ddbfb378ab0256)) - by @realvirtu in [#7060](https://github.com/FunkinCrew/Funkin/pull/7060)
|
||||
- The opponent no longer stops singing upon missing if Boyfriend has no vocals file. ([cea54e3](https://github.com/FunkinCrew/Funkin/commit/cea54e394c78544dd0ec0339721faaac140caa65)) - by @FuroYT in [#7007](https://github.com/FunkinCrew/Funkin/pull/7007)
|
||||
- onPause script functions now properly trigger when pausing during a cutscene or dialogue. ([5a0b431](https://github.com/FunkinCrew/Funkin/commit/5a0b4310a2c39b033989e0e36b8f456bdac65a5b)) - by @MightyTheArmiddilo in [#6804](https://github.com/FunkinCrew/Funkin/pull/6804)
|
||||
- Camera events now consistently pause when the Pause Menu is opened. ([e623439](https://github.com/FunkinCrew/Funkin/commit/e6234397f57d2af37035a0ff2504b8241e23949d)) - by @VirtuGuy in [#7145](https://github.com/FunkinCrew/Funkin/pull/7145)
|
||||
- Camera events now consistently pause when the Pause Menu is opened. ([e623439](https://github.com/FunkinCrew/Funkin/commit/e6234397f57d2af37035a0ff2504b8241e23949d)) - by @realvirtu in [#7145](https://github.com/FunkinCrew/Funkin/pull/7145)
|
||||
- The Pause Menu global offset value now adjusts at the same rate across all framerates. ([348647f](https://github.com/FunkinCrew/Funkin/commit/348647f48629a24ee3bd2b759bbfc1bff168fb81)) - by @KolzeYT in [#7147](https://github.com/FunkinCrew/Funkin/pull/7147)
|
||||
- Spirit's trail effect now renders consistently across all framerates. ([75506f7](https://github.com/FunkinCrew/Funkin/commit/75506f71a97d468f516a0232c8be5560afb0682e)) - by @KolzeYT in [#7179](https://github.com/FunkinCrew/Funkin/pull/7179)
|
||||
- The sound tray now appears consistently and plays sound effects at the right volume. ([2b9906d](https://github.com/FunkinCrew/Funkin/commit/2b9906df29660057410d3054e897012896896d6a)) - by @Raltyro in [#7068](https://github.com/FunkinCrew/Funkin/pull/7068)
|
||||
- The sticker transition now properly pauses when losing focus with Pause on Unfocus enabled. ([8a1d74b](https://github.com/FunkinCrew/Funkin/commit/8a1d74b82cceab97e777dc49e7a2117b8d27e59b)) - by @ComedyLost in [#7129](https://github.com/FunkinCrew/Funkin/pull/7129)
|
||||
- [HTML5] Rimlight alt masks now render properly. ([0613e9d](https://github.com/FunkinCrew/Funkin/commit/0613e9d295179e66d30db3d2f6805870eac847d6)) - by @VirtuGuy in [#6900](https://github.com/FunkinCrew/Funkin/pull/6900)
|
||||
- [HTML5] Rimlight alt masks now render properly. ([0613e9d](https://github.com/FunkinCrew/Funkin/commit/0613e9d295179e66d30db3d2f6805870eac847d6)) - by @realvirtu in [#6900](https://github.com/FunkinCrew/Funkin/pull/6900)
|
||||
- The Week 2 Erect stage lightning strike fade now pauses and cancels appropriately. ([cd05267](https://github.com/FunkinCrew/funkin.assets/commit/cd05267023859d04cc8920c787b8280682e5f0f5)) - by @ComedyLost in [funkin.assets#390](https://github.com/FunkinCrew/funkin.assets/pull/390)
|
||||
- A-Bot (Dark)'s frame no longer renders as completely dark in Week 2 Erect. ([a142530](https://github.com/FunkinCrew/funkin.assets/commit/a142530cae6198ca17b560ff73e36d50f1582768)) - by @ComedyLost in [funkin.assets#368](https://github.com/FunkinCrew/funkin.assets/pull/368)
|
||||
- Dying on the same frame as a lightning strike in Week 2 Erect no longer throws a script error. ([ef89bde](https://github.com/FunkinCrew/funkin.assets/commit/ef89bde19c397f15a53b0fda2f64ba93ff96f56f)) - by @KoloInDaCrib in [funkin.assets#363](https://github.com/FunkinCrew/funkin.assets/pull/363)
|
||||
@@ -105,10 +208,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Fine-tuned offsets for pixel characters. ([8b3c268](https://github.com/FunkinCrew/funkin.assets/commit/8b3c2680a6a966e81b62598e783c60f46355c759)) - by @CEliuxJV in [funkin.assets#376](https://github.com/FunkinCrew/funkin.assets/pull/376)
|
||||
- Tankman's game over lines now properly play during game overs in Ugh (Pico Mix) and Guns (Pico Mix). ([b900208](https://github.com/FunkinCrew/funkin.assets/commit/b900208143f980adee25d70db247e0b176dd659c)) - by @hucks5 in [funkin.assets#373](https://github.com/FunkinCrew/funkin.assets/pull/373)
|
||||
- Restarting during the mid-song animation in Stress (Pico Mix) now properly resets the characters' animations. ([2ca92de](https://github.com/FunkinCrew/funkin.assets/commit/2ca92de46eced3f53d305579704fcb7e8c051f3a)) - by @requazar in [funkin.assets#364](https://github.com/FunkinCrew/funkin.assets/pull/364)
|
||||
- The rain shader now properly fades out with the transition to the Results Screen. ([a0caa41](https://github.com/FunkinCrew/Funkin/commit/a0caa41edcb26298e4f8c243a5eed0b4fe93fcf7)) - by @VirtuGuy in [#6776](https://github.com/FunkinCrew/Funkin/pull/6776)
|
||||
- The rain shader now properly fades out with the transition to the Results Screen. ([a0caa41](https://github.com/FunkinCrew/Funkin/commit/a0caa41edcb26298e4f8c243a5eed0b4fe93fcf7)) - by @realvirtu in [#6776](https://github.com/FunkinCrew/Funkin/pull/6776)
|
||||
- Exiting a Chart Editor playtest while using the pixel notestyle no longer crashes the game. ([6c1f380](https://github.com/FunkinCrew/Funkin/commit/6c1f3800dbc9b13fb4b409abce53c1dafc9bbe8f)) - by @Starexify and @KoloInDaCrib in [#7108](https://github.com/FunkinCrew/Funkin/pull/7108)
|
||||
- Chart Editor Edit buttons are now appropriately disabled when nothing is selected. ([6b1fc03](https://github.com/FunkinCrew/Funkin/commit/6b1fc0372bca202d80f4ccf316580b13a5a80879)) - by @Lasercar in [#4386](https://github.com/FunkinCrew/Funkin/pull/4386)
|
||||
- Undoing a Chart Editor event now plays the undo sound. ([f7fd7a5](https://github.com/FunkinCrew/Funkin/commit/f7fd7a57c36f0461f56c2ab627a17d752cb82320)) - by @VirtuGuy in [#6963](https://github.com/FunkinCrew/Funkin/pull/6963)
|
||||
- Undoing a Chart Editor event now plays the undo sound. ([f7fd7a5](https://github.com/FunkinCrew/Funkin/commit/f7fd7a57c36f0461f56c2ab627a17d752cb82320)) - by @realvirtu in [#6963](https://github.com/FunkinCrew/Funkin/pull/6963)
|
||||
- The playback speed audio setting no longer rounds incorrectly upon reopening the Chart Editor. ([3b15873](https://github.com/FunkinCrew/Funkin/commit/3b15873fc7d0c20840c313f1d2cfed91014c664f)) - by @AnimatingLegend in [#7023](https://github.com/FunkinCrew/Funkin/pull/7023)
|
||||
- The Chart Editor easing preview graph now properly displays tweens that exceed start/end values. ([7626700](https://github.com/FunkinCrew/Funkin/commit/7626700495743862caddbf50a7dafef51529a2a6)) - by @echolotl in [#7152](https://github.com/FunkinCrew/Funkin/pull/7152)
|
||||
- The Chart Editor playbar head is no longer draggable during a playtest. ([ccb874e](https://github.com/FunkinCrew/Funkin/commit/ccb874e97a121859c26a8a71b394743d27f6ed37)) - by @ComedyLost in [#6987](https://github.com/FunkinCrew/Funkin/pull/6987)
|
||||
@@ -236,21 +339,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Scrolling really quickly in Freeplay no longer crashes the game. ([76699b2](https://github.com/FunkinCrew/Funkin/commit/76699b235cd5b359bc34e6950cd05bbbb13918f8)) - by @ComedyLost in [#6962](https://github.com/FunkinCrew/Funkin/pull/6962)
|
||||
- Fixed a memory leak in the Freeplay menu. ([910ba65](https://github.com/FunkinCrew/Funkin/commit/910ba650b0c1011802b151b85f4a9d8177ae95c7)) - by @KoloInDaCrib in [#6615](https://github.com/FunkinCrew/Funkin/pull/6615)
|
||||
- Modded difficulty dots and graphics now render correctly in Freeplay. ([90b856d](https://github.com/FunkinCrew/Funkin/commit/90b856d88635ac4e5517e934298e3820b2e5f45c)) - by @ComedyLost in [#6205](https://github.com/FunkinCrew/Funkin/pull/6205)
|
||||
- Freeplay capsules with long song names no longer display too far to the left during the new rank animation. ([17a914c](https://github.com/FunkinCrew/Funkin/commit/17a914c933592cb3ba79881ca6a8d900b8513cbc)) - by @VirtuGuy in [#6690](https://github.com/FunkinCrew/Funkin/pull/6690)
|
||||
- Freeplay capsule BPM values ending in 1 now display with proper spacing. ([e5b4351](https://github.com/FunkinCrew/Funkin/commit/e5b43510dd810a74a7d06f7f02c52892d11d6f8b)) - by @VirtuGuy in [#6696](https://github.com/FunkinCrew/Funkin/pull/6696)
|
||||
- The Freeplay pixel icon now properly plays its confirm animation when mashing the capsule. ([a56bc44](https://github.com/FunkinCrew/Funkin/commit/a56bc4462d1c49e8ec71462b9bd7ff338b743c93)) - by @VirtuGuy in [#6723](https://github.com/FunkinCrew/Funkin/pull/6723)
|
||||
- [HTML5] Scrolling with the mouse now works properly in Story Mode and Freeplay. ([506d80b](https://github.com/FunkinCrew/Funkin/commit/506d80b287b969121dc3601714c2459cc71f7e55)) - by @VirtuGuy in [#6621](https://github.com/FunkinCrew/Funkin/pull/6621)
|
||||
- Freeplay capsules with long song names no longer display too far to the left during the new rank animation. ([17a914c](https://github.com/FunkinCrew/Funkin/commit/17a914c933592cb3ba79881ca6a8d900b8513cbc)) - by @realvirtu in [#6690](https://github.com/FunkinCrew/Funkin/pull/6690)
|
||||
- Freeplay capsule BPM values ending in 1 now display with proper spacing. ([e5b4351](https://github.com/FunkinCrew/Funkin/commit/e5b43510dd810a74a7d06f7f02c52892d11d6f8b)) - by @realvirtu in [#6696](https://github.com/FunkinCrew/Funkin/pull/6696)
|
||||
- The Freeplay pixel icon now properly plays its confirm animation when mashing the capsule. ([a56bc44](https://github.com/FunkinCrew/Funkin/commit/a56bc4462d1c49e8ec71462b9bd7ff338b743c93)) - by @realvirtu in [#6723](https://github.com/FunkinCrew/Funkin/pull/6723)
|
||||
- [HTML5] Scrolling with the mouse now works properly in Story Mode and Freeplay. ([506d80b](https://github.com/FunkinCrew/Funkin/commit/506d80b287b969121dc3601714c2459cc71f7e55)) - by @realvirtu in [#6621](https://github.com/FunkinCrew/Funkin/pull/6621)
|
||||
- Optimized rendering in the Character Select menu. ([2ecebf7](https://github.com/FunkinCrew/Funkin/commit/2ecebf79205a66b64148d64bbb3162c9fc073d85)) - by @MaybeMaru in [#6789](https://github.com/FunkinCrew/Funkin/pull/6789)
|
||||
- [MOBILE] Tapping on a lock in Character Select now plays its reject animation. ([05148f0](https://github.com/FunkinCrew/Funkin/commit/05148f0e5dad4d60089e6074e616b583ba29a5e6)) - by @VirtuGuy in [#6779](https://github.com/FunkinCrew/Funkin/pull/6779)
|
||||
- [MOBILE] Tapping on a lock in Character Select now plays its reject animation. ([05148f0](https://github.com/FunkinCrew/Funkin/commit/05148f0e5dad4d60089e6074e616b583ba29a5e6)) - by @realvirtu in [#6779](https://github.com/FunkinCrew/Funkin/pull/6779)
|
||||
- Hold note covers now follow when the strumline position is modified. ([77c6651](https://github.com/FunkinCrew/Funkin/commit/77c6651e245ea276b1bdf33e5d6732073dcb6037)) - by @MightyTheArmiddilo in [#6746](https://github.com/FunkinCrew/Funkin/pull/6746)
|
||||
- The pause and game over screens no longer sometimes play the wrong character's themes. ([878644a](https://github.com/FunkinCrew/Funkin/commit/878644aee7ba425e482707b94b9f887ec23f6306)) - by @KoloInDaCrib in [#6812](https://github.com/FunkinCrew/Funkin/pull/6812)
|
||||
- The game over camera focus point is now consistent, regardless of which animation was previously playing. ([18cceb4](https://github.com/FunkinCrew/Funkin/commit/18cceb4946a51fda0009d77baae1115437694415)) - by @KoloInDaCrib in [#6705](https://github.com/FunkinCrew/Funkin/pull/6705)
|
||||
- Pico (Pixel) and other pixel characters now use RetroCameraFade as Boyfriend (Pixel) does. ([d1382aa](https://github.com/FunkinCrew/Funkin/commit/d1382aa985f97e3b40b0b629cb3d04301ebfb55e)) - by @afreetoplaynoob in [#6526](https://github.com/FunkinCrew/Funkin/pull/6526)
|
||||
- [MOBILE] The back button can no longer exit during the Boyfriend fakeout death animation. ([9d06018](https://github.com/FunkinCrew/Funkin/commit/9d0601813e912de9e25a851ad9204a654316625a)) - by @ActualMandM in [#6917](https://github.com/FunkinCrew/Funkin/pull/6917)
|
||||
- The song name text is now properly hidden at the beginning of the Results Screen animation. ([a5b15b9](https://github.com/FunkinCrew/Funkin/commit/a5b15b9424f16d8eadc7a92f1c355da647990c3a)) - by @NotHyper-474 and @Trayfellow in [#6931](https://github.com/FunkinCrew/Funkin/pull/6931)
|
||||
- The sticker transition no longer covers the volume soundtray. ([616546d](https://github.com/FunkinCrew/Funkin/commit/616546d298a06c4135a32ffad41483be208552f1)) - by @VirtuGuy in [#6727](https://github.com/FunkinCrew/Funkin/pull/6727)
|
||||
- The sticker transition no longer covers the volume soundtray. ([616546d](https://github.com/FunkinCrew/Funkin/commit/616546d298a06c4135a32ffad41483be208552f1)) - by @realvirtu in [#6727](https://github.com/FunkinCrew/Funkin/pull/6727)
|
||||
- Lightning now appears more regularly during South Erect and South (Pico Mix). ([9ca2092](https://github.com/FunkinCrew/funkin.assets/commit/9ca20929bc3dde6b07d74100c45fb45e48769c35)) - by @JackXson-Real in [funkin.assets#345](https://github.com/FunkinCrew/funkin.assets/pull/345)
|
||||
- [HTML5] The city lights in the Week 3 stages now show up. ([603684f](https://github.com/FunkinCrew/funkin.assets/commit/603684ffb327f03d8216aaeaba143ca5f9cd77f0)) - by @VirtuGuy in [funkin.assets#342](https://github.com/FunkinCrew/funkin.assets/pull/342)
|
||||
- [HTML5] The city lights in the Week 3 stages now show up. ([603684f](https://github.com/FunkinCrew/funkin.assets/commit/603684ffb327f03d8216aaeaba143ca5f9cd77f0)) - by @realvirtu in [funkin.assets#342](https://github.com/FunkinCrew/funkin.assets/pull/342)
|
||||
- The Week 3 Pico doppelganger cutscene background music no longer cuts off at the end. ([8ef58aa](https://github.com/FunkinCrew/funkin.assets/commit/8ef58aabdba8287d4c88808e2f0ecc0ac385b383)) - by @Trayfellow in [funkin.assets#349](https://github.com/FunkinCrew/funkin.assets/pull/349)
|
||||
- The Story Mode cutscene before Stress now properly plays when viewed more than once. ([6ec45ec](https://github.com/FunkinCrew/funkin.assets/commit/6ec45ec82ca77188b1b2b9c58ada172f5c357103)) - by @NotHyper-474 in [funkin.assets#341](https://github.com/FunkinCrew/funkin.assets/pull/341)
|
||||
- Darnell's can sound effects in 2hot no longer play twice with high offsets or when lagging. ([6315e25](https://github.com/FunkinCrew/funkin.assets/commit/6315e25eaaa8be4ca85e9b607f547595c699997a)) - by @JackXson-Real in [funkin.assets#354](https://github.com/FunkinCrew/funkin.assets/pull/354)
|
||||
@@ -263,8 +366,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- The Chart Editor vocal waveforms now display in the proper position regardless of the game's aspect ratio. ([1fb9040](https://github.com/FunkinCrew/Funkin/commit/1fb9040470432528a0441d7938d217e424ce27fd)) - by @Starexify in [#6193](https://github.com/FunkinCrew/Funkin/pull/6193)
|
||||
- The second section number and divider now renders consistently in the Chart Editor. ([ac539bd](https://github.com/FunkinCrew/Funkin/commit/ac539bdf26ee7b5ecdcc52665c7c95287ef491c0)) - by @NotHyper-474 in [#6765](https://github.com/FunkinCrew/Funkin/pull/6765)
|
||||
- The Chart Editor now saves the Show Results Screen setting. ([c893a73](https://github.com/FunkinCrew/Funkin/commit/c893a7320d72abd3743bc5c1ddeaecf073035eb1)) - by @MightyTheArmiddilo in [#6854](https://github.com/FunkinCrew/Funkin/pull/6854)
|
||||
- Closing the game while in the Stage Editor no longer crashes the game. ([99cd4e2](https://github.com/FunkinCrew/Funkin/commit/99cd4e2cbd7fba87249b02b072a1e60f07c2c907)) - by @VirtuGuy in [#6775](https://github.com/FunkinCrew/Funkin/pull/6775)
|
||||
- The onion skin now properly renders as transparent after changing characters in the Animation Editor. ([5c444f1](https://github.com/FunkinCrew/Funkin/commit/5c444f1109e5af04735a4383e577c69682b3713f)) - by @VirtuGuy in [#6545](https://github.com/FunkinCrew/Funkin/pull/6545)
|
||||
- Closing the game while in the Stage Editor no longer crashes the game. ([99cd4e2](https://github.com/FunkinCrew/Funkin/commit/99cd4e2cbd7fba87249b02b072a1e60f07c2c907)) - by @realvirtu in [#6775](https://github.com/FunkinCrew/Funkin/pull/6775)
|
||||
- The onion skin now properly renders as transparent after changing characters in the Animation Editor. ([5c444f1](https://github.com/FunkinCrew/Funkin/commit/5c444f1109e5af04735a4383e577c69682b3713f)) - by @realvirtu in [#6545](https://github.com/FunkinCrew/Funkin/pull/6545)
|
||||
- Blacklisted a class for security. ([3a113c2](https://github.com/FunkinCrew/Funkin/commit/3a113c270f92a6b14dfcda221124742437e1670a)) - by @charlesisfeline in [#6573](https://github.com/FunkinCrew/Funkin/pull/6573)
|
||||
- Even more tiny fixes!
|
||||
|
||||
@@ -349,7 +452,7 @@ The LE SSERAFIM collab update!
|
||||
- Freeplay song previews now fade out before restarting. ([aaf5084](https://github.com/FunkinCrew/Funkin/commit/aaf5084fd9e9c2d3b7e823767a93db82ce908d86)) - by @JVNpixels in [#6094](https://github.com/FunkinCrew/Funkin/pull/6094)
|
||||
- The game's volume is now reduced when unfocused without pausing. ([3040692](https://github.com/FunkinCrew/Funkin/commit/30406928522f88762eab4bbf571fedf1424f7569)) - by @PurSnake in [#6250](https://github.com/FunkinCrew/Funkin/pull/6250)
|
||||
- Optimized the way the windows in Week 3 are handled. ([70d433d](https://github.com/FunkinCrew/funkin.assets/commit/70d433de3027badb39027d295d1b18d20a130741)) - by @CrusherNotDrip in [funkin.assets#291](https://github.com/FunkinCrew/funkin.assets/pull/291)
|
||||
- Script create events now also run after hot-reloading with F5, rather than only during initialization. ([2f865a5](https://github.com/FunkinCrew/Funkin/commit/2f865a5c7f4d8712f1b1e0bc70cb910f4fed08dc)) - by @VirtuGuy in [#6084](https://github.com/FunkinCrew/Funkin/pull/6084)
|
||||
- Script create events now also run after hot-reloading with F5, rather than only during initialization. ([2f865a5](https://github.com/FunkinCrew/Funkin/commit/2f865a5c7f4d8712f1b1e0bc70cb910f4fed08dc)) - by @realvirtu in [#6084](https://github.com/FunkinCrew/Funkin/pull/6084)
|
||||
- Hot-reloading with F5 during a Chart Editor playtest no longer returns to the Chart Editor. ([c1988f1](https://github.com/FunkinCrew/Funkin/commit/c1988f1858344a78a82bf335774d986703cac942)) - by @KoloInDaCrib in [#6275](https://github.com/FunkinCrew/Funkin/pull/6275)
|
||||
- Opening the Chart Editor during a song now places the playhead at the current song position. ([71b4a58](https://github.com/FunkinCrew/Funkin/commit/71b4a58cab821c3b5a530e3a2be6d73966faa2a6)) - by @KoloInDaCrib in [#6210](https://github.com/FunkinCrew/Funkin/pull/6210)
|
||||
- The Easing property for Chart Editor events is now split into two separate dropdowns: type and direction. ([d1d77dd](https://github.com/FunkinCrew/Funkin/commit/d1d77dd85c3daed22ee954353fa41e81279ced3c)) - by @PurSnake in [#5612](https://github.com/FunkinCrew/Funkin/pull/5612)
|
||||
@@ -409,7 +512,7 @@ The LE SSERAFIM collab update!
|
||||
- Pause on Unfocus now properly applies to Chart Editor playtests.
|
||||
- Unfocusing while the Chart Editor is playing audio now pauses the playback.
|
||||
- Fixed a memory leak with the Freeplay backing card scrolling text. ([67846d6](https://github.com/FunkinCrew/Funkin/commit/67846d6c4bfd2f42e002fa129a51772f0717329d)) - by @FuroYT in [#5963](https://github.com/FunkinCrew/Funkin/pull/5963)
|
||||
- Using a static pixel icon in Character Select no longer crashes the game. ([96f8ee8](https://github.com/FunkinCrew/Funkin/commit/96f8ee85e0c2281834b7334b87d1862003e5fa05)) - by @VirtuGuy in [#6171](https://github.com/FunkinCrew/Funkin/pull/6171)
|
||||
- Using a static pixel icon in Character Select no longer crashes the game. ([96f8ee8](https://github.com/FunkinCrew/Funkin/commit/96f8ee85e0c2281834b7334b87d1862003e5fa05)) - by @realvirtu in [#6171](https://github.com/FunkinCrew/Funkin/pull/6171)
|
||||
- A-Bot's visualizer no longer causes a memory leak during gameplay or in Character Select. ([6607645](https://github.com/FunkinCrew/Funkin/commit/6607645786ed8611436fa5f92a35027c2a64f1d0)) - by @FuroYT in [#5908](https://github.com/FunkinCrew/Funkin/pull/5908)
|
||||
- The Credits menu no longer crashes when not using hardcoded credits. ([4366fbe](https://github.com/FunkinCrew/Funkin/commit/4366fbe51274438ad2bc190afcca42e37987386d)) - by @sphis-sinco in [#5982](https://github.com/FunkinCrew/Funkin/pull/5982)
|
||||
- The game no longer lag spikes when Darnell throws his can in 2hot. ([a0bc6d6](https://github.com/FunkinCrew/funkin.assets/commit/a0bc6d61fde5799a7fc619b7fdea691b0d8bae05)) - by @KoloInDaCrib in [funkin.assets#313](https://github.com/FunkinCrew/funkin.assets/pull/313)
|
||||
@@ -419,12 +522,12 @@ The LE SSERAFIM collab update!
|
||||
- [ANDROID] Keyboard detection and strumline positioning now work properly. ([5763ae5](https://github.com/FunkinCrew/Funkin/commit/5763ae5b728359c5639bbc578f15b65a16fa57b1)) - by @NotHyper-474 in [#6328](https://github.com/FunkinCrew/Funkin/pull/6328)
|
||||
- The game now properly parses .json files beginning with a bracket. ([c7367ae](https://github.com/FunkinCrew/Funkin/commit/c7367ae33d7e11f57b821f7d5fbff39a3edc1604)) - by @NotHyper-474 in [#6164](https://github.com/FunkinCrew/Funkin/pull/6164)
|
||||
- The Newgrounds logo no longer covers the intro text. ([28883fb](https://github.com/FunkinCrew/Funkin/commit/28883fb9ed025abf9f9aee2621f365cd6f4d8b6c)) - by @hucks5 in [#6196](https://github.com/FunkinCrew/Funkin/pull/6196)
|
||||
- Exiting from the Save Data Options menu no longer exits the Options Menu as well. ([26b253d](https://github.com/FunkinCrew/Funkin/commit/26b253d8cac97f0dcd09a5ef233f7058cd26008e)) - by @VirtuGuy in [#6036](https://github.com/FunkinCrew/Funkin/pull/6036)
|
||||
- Exiting from the Save Data Options menu no longer exits the Options Menu as well. ([26b253d](https://github.com/FunkinCrew/Funkin/commit/26b253d8cac97f0dcd09a5ef233f7058cd26008e)) - by @realvirtu in [#6036](https://github.com/FunkinCrew/Funkin/pull/6036)
|
||||
- Numeric values in the Options Menu are now rounded to prevent near-zero precision errors. ([934bce7](https://github.com/FunkinCrew/Funkin/commit/934bce7bdc5780e09623d845eda97a27c0ad0ecf)) - by @Starexify in [#6225](https://github.com/FunkinCrew/Funkin/pull/6225)
|
||||
- The Test/Offset Calibration menu no longer starts playing after exiting the Lag Adjustment menu. ([23a38f7](https://github.com/FunkinCrew/Funkin/commit/23a38f76f9c79c5fab5b9af5e2d98e51597e05a8)) - by @VioletSnowLeopard in [#6088](https://github.com/FunkinCrew/Funkin/pull/6088)
|
||||
- [MOBILE] The Back button now fades out when entering a Week in Story Mode. ([1ebce74](https://github.com/FunkinCrew/Funkin/commit/1ebce748d4e3306b4464a7bf82fab56bcb427a62)) - by @VirtuGuy in [#6255](https://github.com/FunkinCrew/Funkin/pull/6255)
|
||||
- [MOBILE] The Back button now fades out when entering a Week in Story Mode. ([1ebce74](https://github.com/FunkinCrew/Funkin/commit/1ebce748d4e3306b4464a7bf82fab56bcb427a62)) - by @realvirtu in [#6255](https://github.com/FunkinCrew/Funkin/pull/6255)
|
||||
- The Freeplay difficulty can now only be changed in one direction at a time. ([95af46c](https://github.com/FunkinCrew/Funkin/commit/95af46cbf72291d9d3226df91ed17f1aa3d3839f)) - by @Starexify in [#6262](https://github.com/FunkinCrew/Funkin/pull/6262)
|
||||
- Pico's backing card now renders properly in widescreen aspect ratios. ([aa29b3d](https://github.com/FunkinCrew/funkin.assets/commit/aa29b3dcc1ee2f8e89d2622c480b2e997410d57d)) - by @VirtuGuy in [funkin.assets#297](https://github.com/FunkinCrew/funkin.assets/pull/297)
|
||||
- Pico's backing card now renders properly in widescreen aspect ratios. ([aa29b3d](https://github.com/FunkinCrew/funkin.assets/commit/aa29b3dcc1ee2f8e89d2622c480b2e997410d57d)) - by @realvirtu in [funkin.assets#297](https://github.com/FunkinCrew/funkin.assets/pull/297)
|
||||
- The album titles in Freeplay are now positioned consistently. ([ed8cca4](https://github.com/FunkinCrew/funkin.assets/commit/ed8cca4694a098ae6aa56c4d2a231587edb9688c)) - by @Donothan73 in [funkin.assets#257](https://github.com/FunkinCrew/funkin.assets/pull/257)
|
||||
- Health icons now bop independently from the framerate. ([8e6fa51](https://github.com/FunkinCrew/Funkin/commit/8e6fa51c27ceaa830efec06bb8a52e281a008255)) - by @PurSnake in [#6035](https://github.com/FunkinCrew/Funkin/pull/6035)
|
||||
- The note resetting animation on song restart is now consistent between Downscroll and Upscroll. ([7b8d657](https://github.com/FunkinCrew/Funkin/commit/7b8d6577eddba568f20c3d23663dded054699090)) - by @FuroYT in [#6220](https://github.com/FunkinCrew/Funkin/pull/6220)
|
||||
@@ -433,19 +536,19 @@ The LE SSERAFIM collab update!
|
||||
- The path for a notestyle's countdown sound is now properly loaded as a sound instead of an image. ([dd5ea77](https://github.com/FunkinCrew/Funkin/commit/dd5ea7748b3b1878139998c209aa06db0fa05e0b)) - by @gamerbross in [#6232](https://github.com/FunkinCrew/Funkin/pull/6232)
|
||||
- The Pause Menu theme no longer plays at maximum volume for a split second when pausing. ([6ba44d6](https://github.com/FunkinCrew/Funkin/commit/6ba44d6cb0c71deb29eb23b82b61f58b2e95193e)) - by @ComedyLost in [#6334](https://github.com/FunkinCrew/Funkin/pull/6334)
|
||||
- The scrolling text in the Results Screen is now positioned consistently. ([200f798](https://github.com/FunkinCrew/Funkin/commit/200f7984379cb1bd911e49de92be312750893420)) - by @NotHyper-474 in [#6595](https://github.com/FunkinCrew/Funkin/pull/6595)
|
||||
- The scrolling text in the Results Screen is now FPS-independent. ([8c43f6f](https://github.com/FunkinCrew/Funkin/commit/8c43f6f67a362bde4de4ad8dbd72966d7c4a9f60)) - by @VirtuGuy in [#6476](https://github.com/FunkinCrew/Funkin/pull/6476)
|
||||
- The scrolling text in the Results Screen is now FPS-independent. ([8c43f6f](https://github.com/FunkinCrew/Funkin/commit/8c43f6f67a362bde4de4ad8dbd72966d7c4a9f60)) - by @realvirtu in [#6476](https://github.com/FunkinCrew/Funkin/pull/6476)
|
||||
- The Results Screen theme now loops more smoothly. ([592bf1a](https://github.com/FunkinCrew/Funkin/commit/592bf1a9221d4dcef53ae421571eddf78ed631e4)) - by @FuroYT in [#6477](https://github.com/FunkinCrew/Funkin/pull/6477)
|
||||
- Transition stickers now render properly with the window resized to any aspect ratio. ([4215b1c](https://github.com/FunkinCrew/Funkin/commit/4215b1c72e4391b2176014825885799b81dde2ba)) - by @PurSnake in [#6156](https://github.com/FunkinCrew/Funkin/pull/6156)
|
||||
- Boyfriend now stands in the same position in the Week 3 and Week 3 Erect stages. ([d2d15f1](https://github.com/FunkinCrew/funkin.assets/commit/d2d15f114256125d53c6331b46415701ae291c1f)) - by @CEliuxJV in [funkin.assets#261](https://github.com/FunkinCrew/funkin.assets/pull/261)
|
||||
- Pico's game over music now properly loops after his explosion death in 2hot. ([f1a1db0](https://github.com/FunkinCrew/Funkin/commit/f1a1db08347c3f9248fd16909cff06027297ad13)) - by @KoloInDaCrib in [#6216](https://github.com/FunkinCrew/Funkin/pull/6216)
|
||||
- 2hot now smoothly transitions into the cutscene. ([462b1b6](https://github.com/FunkinCrew/funkin.assets/commit/462b1b6e6e9b622ad8fd15f15a1f39c7dffa4764)) - by @hucks5 in [funkin.assets#286](https://github.com/FunkinCrew/funkin.assets/pull/286)
|
||||
- Nene now swings her legs during in-game cutscenes. ([6a5d9b2](https://github.com/FunkinCrew/funkin.assets/commit/6a5d9b265732d60da28083fb1c3d7b7b854edf63)) - by @hucks5 in [funkin.assets#289](https://github.com/FunkinCrew/funkin.assets/pull/289)
|
||||
- Nene's 50 combo animation now renders its heart properly. ([bcd96ee](https://github.com/FunkinCrew/funkin.assets/commit/bcd96eeb78b9b03cf7b24dc956ac3bc36438193e)) - by @VirtuGuy in [funkin.assets#296](https://github.com/FunkinCrew/funkin.assets/pull/296)
|
||||
- Nene's 50 combo animation now renders its heart properly. ([bcd96ee](https://github.com/FunkinCrew/funkin.assets/commit/bcd96eeb78b9b03cf7b24dc956ac3bc36438193e)) - by @realvirtu in [funkin.assets#296](https://github.com/FunkinCrew/funkin.assets/pull/296)
|
||||
- A-Bot (Christmas) now properly looks at the opponent. ([f81cc16](https://github.com/FunkinCrew/funkin.assets/commit/f81cc16c8f99655f76b7e27ce221819798c9c94e)) - by @ComedyLost in [funkin.assets#279](https://github.com/FunkinCrew/funkin.assets/pull/279)
|
||||
- Nene (Pixel) now raises and lowers her knife properly. ([1d9f50d](https://github.com/FunkinCrew/funkin.assets/commit/1d9f50d405f202e07efd883aeef5d6c1e9eaaa90)) - by @VirtuGuy in [funkin.assets#274](https://github.com/FunkinCrew/funkin.assets/pull/274)
|
||||
- Nene (Pixel) now raises and lowers her knife properly. ([1d9f50d](https://github.com/FunkinCrew/funkin.assets/commit/1d9f50d405f202e07efd883aeef5d6c1e9eaaa90)) - by @realvirtu in [funkin.assets#274](https://github.com/FunkinCrew/funkin.assets/pull/274)
|
||||
- Pico (Pixel)'s game over theme now plays at the right time. ([e8a4d24](https://github.com/FunkinCrew/funkin.assets/commit/e8a4d2472ca2dc28b03be05953dff3d7b5ec7433)) - by @JackXson-Real and @ComedyLost in [funkin.assets#288](https://github.com/FunkinCrew/funkin.assets/pull/288)
|
||||
- Pico holding Nene's idle animation no longer lasts too long. ([3483345](https://github.com/FunkinCrew/funkin.assets/commit/348334583746ec45f1c6ab2c5e1715a67038cc5c)) - by @JackXson-Real in [funkin.assets#271](https://github.com/FunkinCrew/funkin.assets/pull/271)
|
||||
- The tankmen in Stress no longer briefly appear behind the speakers when restarting. ([7f79ad8](https://github.com/FunkinCrew/funkin.assets/commit/7f79ad8c08d66fb909a9382de2c09f0430b756f1)) - by @VirtuGuy in [funkin.assets#298](https://github.com/FunkinCrew/funkin.assets/pull/298)
|
||||
- The tankmen in Stress no longer briefly appear behind the speakers when restarting. ([7f79ad8](https://github.com/FunkinCrew/funkin.assets/commit/7f79ad8c08d66fb909a9382de2c09f0430b756f1)) - by @realvirtu in [funkin.assets#298](https://github.com/FunkinCrew/funkin.assets/pull/298)
|
||||
- Encountering a Set Health Icon event during Minimal playtesting no longer crashes the Chart Editor. ([9f0a498](https://github.com/FunkinCrew/Funkin/commit/9f0a4988a3cc47581916a9750731bb7e63f168f3)) - by @charlesisfeline in [#6481](https://github.com/FunkinCrew/Funkin/pull/6481)
|
||||
- Typing in Chart Editor text fields no longer triggers bound key functions. ([3b5e589](https://github.com/FunkinCrew/Funkin/commit/3b5e5893c01c2b56036e53626eaea8d41e70f640)) - by @MightyTheArmiddilo in [#6601](https://github.com/FunkinCrew/Funkin/pull/6601)
|
||||
- Clicking between Chart Editor events no longer converts the second event's dropdown values into those of the first. ([c170c25](https://github.com/FunkinCrew/Funkin/commit/c170c256934ae316a735d38620ad5e24c2f15f4d)) - by @NotHyper-474 in [#6211](https://github.com/FunkinCrew/Funkin/pull/6211)
|
||||
@@ -453,19 +556,19 @@ The LE SSERAFIM collab update!
|
||||
- Placing a note and removing it no longer breaks the cursor in the Chart Editor. ([8cb5ed9](https://github.com/FunkinCrew/Funkin/commit/8cb5ed91baf50b6f78eefc2e50612a01195a2742)) - by @Lasercar in [#4237](https://github.com/FunkinCrew/Funkin/pull/4237)
|
||||
- Playtesting in the Chart Editor now properly loads song variation scripts. ([055f620](https://github.com/FunkinCrew/Funkin/commit/055f62026ef44a928876d9065cc388da0905e9f1)) - by @PurSnake in [#6405](https://github.com/FunkinCrew/Funkin/pull/6405)
|
||||
- Playtesting in the Chart Editor no longer sometimes moves on to another song like Story Mode. ([9497378](https://github.com/FunkinCrew/Funkin/commit/9497378600bad44639ff8b3fc92cb329052fd08a)) - by @KoloInDaCrib in [#6192](https://github.com/FunkinCrew/Funkin/pull/6192)
|
||||
- The cursor is now hidden when playtesting through the Chart Editor. ([0471872](https://github.com/FunkinCrew/Funkin/commit/047187257b6712e61bf05fdebab33c7b3e9ac0f6)) - by @VirtuGuy in [#6137](https://github.com/FunkinCrew/Funkin/pull/6137)
|
||||
- The cursor is now hidden when playtesting through the Chart Editor. ([0471872](https://github.com/FunkinCrew/Funkin/commit/047187257b6712e61bf05fdebab33c7b3e9ac0f6)) - by @realvirtu in [#6137](https://github.com/FunkinCrew/Funkin/pull/6137)
|
||||
- The Chart Editor note moving sound no longer plays when dragging outside the grid. ([593456e](https://github.com/FunkinCrew/Funkin/commit/593456e53e02c53e71189fdb154e4a3e4f2b3092)) - by @amyspark-ng in [#4157](https://github.com/FunkinCrew/Funkin/pull/4157)
|
||||
- The Chart Editor music now fades in after a period of silence when enabled. ([960d2f3](https://github.com/FunkinCrew/Funkin/commit/960d2f3cf166400c6fecee212b87961f3df10c2e)) - by @Lasercar in [#4148](https://github.com/FunkinCrew/Funkin/pull/4148)
|
||||
- The Chart Editor Difficulty toolbox no longer displays the incorrect song name. ([dff2a1e](https://github.com/FunkinCrew/Funkin/commit/dff2a1e487dc20f86ef4f526a259083a7726ea6a)) - by @VirtuGuy in [#6547](https://github.com/FunkinCrew/Funkin/pull/6547)
|
||||
- The Chart Editor Difficulty toolbox no longer displays the incorrect song name. ([dff2a1e](https://github.com/FunkinCrew/Funkin/commit/dff2a1e487dc20f86ef4f526a259083a7726ea6a)) - by @realvirtu in [#6547](https://github.com/FunkinCrew/Funkin/pull/6547)
|
||||
- Chart Editor notifications now display a bit higher. ([9e645db](https://github.com/FunkinCrew/Funkin/commit/9e645db0074424ffb2de42b27afb3adaff55de62)) - by @MightyTheArmiddilo in [#6445](https://github.com/FunkinCrew/Funkin/pull/6445)
|
||||
- The Yes and No text in the Chart Editor exit confirmation prompt buttons now always render properly. ([4c0d925](https://github.com/FunkinCrew/Funkin/commit/4c0d92507ae0b81a744d223e5292bf8d27013abd)) - by @NotHyper-474 in [#6173](https://github.com/FunkinCrew/Funkin/pull/6173)
|
||||
- Exiting the Chart Editor now consistently saves your audio preferences. ([2f77ccf](https://github.com/FunkinCrew/Funkin/commit/2f77ccfc6e93fabef27d3e06447f9f6edd8e840d)) - by @VioletSnowLeopard in [#6127](https://github.com/FunkinCrew/Funkin/pull/6127)
|
||||
- The Chart Editor and Stage Editor backup window now properly retrieves the most recently edited backup. ([a8dec0c](https://github.com/FunkinCrew/Funkin/commit/a8dec0cd7053f88865757f30a7d9f0ca5eb0fb02)) - by @Lasercar in [#6119](https://github.com/FunkinCrew/Funkin/pull/6119)
|
||||
- The Chart Editor backup dialog no longer appears if the latest backup is deleted. ([bc1d36d](https://github.com/FunkinCrew/Funkin/commit/bc1d36ddeab81a790e3604598248a9b2fe869cac)) - by @KoloInDaCrib in [#6027](https://github.com/FunkinCrew/Funkin/pull/6027)
|
||||
- Switching between Animation and Spritesheet mode no longer crashes the Animation Editor. ([a61016d](https://github.com/FunkinCrew/Funkin/commit/a61016d2dfc2ac6a50aae230969c036f0753cfaa)) - by @VirtuGuy in [#6114](https://github.com/FunkinCrew/Funkin/pull/6114)
|
||||
- Switching between Animation and Spritesheet mode no longer crashes the Animation Editor. ([a61016d](https://github.com/FunkinCrew/Funkin/commit/a61016d2dfc2ac6a50aae230969c036f0753cfaa)) - by @realvirtu in [#6114](https://github.com/FunkinCrew/Funkin/pull/6114)
|
||||
- The Animation Editor no longer displays a missing object icon next to the dropdown menus. ([b30ea36](https://github.com/FunkinCrew/Funkin/commit/b30ea36fcc982ce4ac0be9143fd4701e180fc684)) - by @KoloInDaCrib in [#6177](https://github.com/FunkinCrew/Funkin/pull/6177)
|
||||
- The Animation Editor onion skin now properly accounts for character scale and offsets. ([a76a868](https://github.com/FunkinCrew/Funkin/commit/a76a868cb6a27c1c76d09177b90cf6df3df29d17)) - by @VirtuGuy in [#6123](https://github.com/FunkinCrew/Funkin/pull/6123)
|
||||
- The debug cursor is now properly hidden when exiting the Animation Editor. ([f2f6b4c](https://github.com/FunkinCrew/Funkin/commit/f2f6b4c8591e1ab4a8c6f0ed998d6d25d7cc9f43)) - by @VirtuGuy in [#6112](https://github.com/FunkinCrew/Funkin/pull/6112)
|
||||
- The Animation Editor onion skin now properly accounts for character scale and offsets. ([a76a868](https://github.com/FunkinCrew/Funkin/commit/a76a868cb6a27c1c76d09177b90cf6df3df29d17)) - by @realvirtu in [#6123](https://github.com/FunkinCrew/Funkin/pull/6123)
|
||||
- The debug cursor is now properly hidden when exiting the Animation Editor. ([f2f6b4c](https://github.com/FunkinCrew/Funkin/commit/f2f6b4c8591e1ab4a8c6f0ed998d6d25d7cc9f43)) - by @realvirtu in [#6112](https://github.com/FunkinCrew/Funkin/pull/6112)
|
||||
- Plenty more tiny fixes.
|
||||
|
||||
## New Contributors for 0.8.0
|
||||
@@ -524,13 +627,13 @@ The LE SSERAFIM collab update!
|
||||
- Freeplay ranks no longer pop out when scrolling through song capsules. ([747446e](https://github.com/FunkinCrew/Funkin/commit/747446e2e420449f422fbc69aafda6128ac8d16e)) - by @VioletSnowLeopard in [#5822](https://github.com/FunkinCrew/Funkin/pull/5822)
|
||||
- The Freeplay intro no longer plays when returning from a sticker transition. ([63ec749](https://github.com/FunkinCrew/Funkin/commit/63ec749c7a3c90d529e9e8f2f3ed1c8913e8f9a1)) - by @PurSnake in [#5942](https://github.com/FunkinCrew/Funkin/pull/5942)
|
||||
- Hot-reloading with F5 after earning a rank no longer crashes Freeplay. ([79e8b5d](https://github.com/FunkinCrew/Funkin/commit/79e8b5d71e052953b77b81b66e0a83a7bbeeeeed)) - by @KoloInDaCrib in [#5971](https://github.com/FunkinCrew/Funkin/pull/5971)
|
||||
- The Main Menu music now fades in consistently when exiting from Freeplay to the Title Screen. ([a10bbf6](https://github.com/FunkinCrew/Funkin/commit/a10bbf60acbbeadfb5a91930745ef4fd338b1a24)) - by @VirtuGuy in [#5855](https://github.com/FunkinCrew/Funkin/pull/5855)
|
||||
- The Main Menu music now fades in consistently when exiting from Freeplay to the Title Screen. ([a10bbf6](https://github.com/FunkinCrew/Funkin/commit/a10bbf60acbbeadfb5a91930745ef4fd338b1a24)) - by @realvirtu in [#5855](https://github.com/FunkinCrew/Funkin/pull/5855)
|
||||
- The game now falls back to default audio files when files specified by the metadata don't exist. ([b5357ac](https://github.com/FunkinCrew/Funkin/commit/b5357acf98bde81a4121a3723061f7c559a0640f)) - by @VioletSnowLeopard in [#5954](https://github.com/FunkinCrew/Funkin/pull/5954)
|
||||
- The cutscene pause menu no longer persists across songs after exiting a video cutscene. ([c2305f3](https://github.com/FunkinCrew/Funkin/commit/c2305f32f0147f6326e8665d21a6b8a793f45033)) - by @KoloInDaCrib in [#5880](https://github.com/FunkinCrew/Funkin/pull/5880)
|
||||
- Mashing to skip the Eggnog Erect cutscene no longer crashes the game. ([5ca3c6a](https://github.com/FunkinCrew/funkin.assets/commit/5ca3c6a5745b61a457db149c289784c08e560ee9)) - by @VioletSnowLeopard in [funkin.assets#258](https://github.com/FunkinCrew/funkin.assets/pull/258)
|
||||
- Stress (Pico Mix) no longer lag spikes when loading in the background tankmen. ([6701405](https://github.com/FunkinCrew/funkin.assets/commit/670140571239ca08c1ae1c5286773d99c2875c2d)) - by @NotHyper-474 and @KoloInDaCrib in [funkin.assets#242](https://github.com/FunkinCrew/funkin.assets/pull/242)
|
||||
- Stress (Pico Mix) no longer lag spikes when Tankman changes sprites. ([aa5956a](https://github.com/FunkinCrew/Funkin/commit/aa5956a30bdc47d53ebebb4b61a7ebb3f04c7dc6)) - by @NotHyper-474 in [#5939](https://github.com/FunkinCrew/Funkin/pull/5939)
|
||||
- The bricks in Stress (Pico Mix) no longer move after restarting the song. ([9cfee03](https://github.com/FunkinCrew/Funkin/commit/9cfee0398a057567f80ad68ff6052964da63af09)) - by @VirtuGuy in [#5875](https://github.com/FunkinCrew/Funkin/pull/5875)
|
||||
- The bricks in Stress (Pico Mix) no longer move after restarting the song. ([9cfee03](https://github.com/FunkinCrew/Funkin/commit/9cfee0398a057567f80ad68ff6052964da63af09)) - by @realvirtu in [#5875](https://github.com/FunkinCrew/Funkin/pull/5875)
|
||||
- Pico now properly shoots after restarting Stress. ([b0ef0d3](https://github.com/FunkinCrew/funkin.assets/commit/b0ef0d352c199e93903652a95ffdf16a3dc2d569)) - by @7oltan in [funkin.assets#254](https://github.com/FunkinCrew/funkin.assets/pull/254)
|
||||
- A-Bot's visualizer now zeroes out when restarting the song. ([ba3a8b0](https://github.com/FunkinCrew/funkin.assets/commit/ba3a8b0cbbf785a0729dcf85e25b6e59c0c12657)) - by @KoloInDaCrib in [funkin.assets#246](https://github.com/FunkinCrew/funkin.assets/pull/246)
|
||||
- Notekinds now properly receive dispatched events last in PlayState. ([89b2b7f](https://github.com/FunkinCrew/Funkin/commit/89b2b7fcc3130db0af1f782594af72ae1f4ce320)) - by @Az989YT in [#5936](https://github.com/FunkinCrew/Funkin/pull/5936)
|
||||
@@ -603,7 +706,7 @@ The LE SSERAFIM collab update!
|
||||
- The HOME and END keys now jump to the top and bottom of the Story Mode menu, respectively. ([d1a96f7](https://github.com/FunkinCrew/Funkin/commit/d1a96f791f2ed35accc1c1e9ff548a75b2b9d7ef)) - by @JVNpixels in [#4591](https://github.com/FunkinCrew/Funkin/pull/4591)
|
||||
- Freeplay favorite songs are now separated by variation. ([b4b2e8d](https://github.com/FunkinCrew/Funkin/commit/b4b2e8da9dde41d730556a41e6bb18b0f3d8d7db)) - by @KoloInDaCrib in [#5154](https://github.com/FunkinCrew/Funkin/pull/5154)
|
||||
- Freeplay preview volumes now play at 70% volume, up from 40%. ([4ecef6d](https://github.com/FunkinCrew/Funkin/commit/4ecef6db744bab7e3fe5de0d680d813cc3bd1ea7)) - by @JackXson-Real in [#5645](https://github.com/FunkinCrew/Funkin/pull/5645)
|
||||
- Selecting a song in the Freeplay menu now plays a fade-out transition. ([705e6b3](https://github.com/FunkinCrew/Funkin/commit/705e6b330806c3157bca7301b1e43cd78acdb23a)) - by @VirtuGuy in [#5626](https://github.com/FunkinCrew/Funkin/pull/5626)
|
||||
- Selecting a song in the Freeplay menu now plays a fade-out transition. ([705e6b3](https://github.com/FunkinCrew/Funkin/commit/705e6b330806c3157bca7301b1e43cd78acdb23a)) - by @realvirtu in [#5626](https://github.com/FunkinCrew/Funkin/pull/5626)
|
||||
- Implemented null safety to PlayState and LoadingState. ([34ce13c](https://github.com/FunkinCrew/Funkin/commit/34ce13c5dfd52760675a1d09efa489bcb108e607)) - by @NotHyper-474 in [#4789](https://github.com/FunkinCrew/Funkin/pull/4789)
|
||||
- Health icons now have an offset variable. ([8bab619](https://github.com/FunkinCrew/Funkin/commit/8bab6196e50420c6586441f2d321bd1c139567c3)) - by @PurSnake in [#5760](https://github.com/FunkinCrew/Funkin/pull/5760)
|
||||
- The "hey" notekind now plays the animation for BF (Christmas). ([91d5970](https://github.com/FunkinCrew/funkin.assets/commit/91d5970e0274aa0a31fc6f2b05c114730256408f)) - by @JackXson-Real in [funkin.assets#225](https://github.com/FunkinCrew/funkin.assets/pull/225)
|
||||
@@ -651,8 +754,8 @@ The LE SSERAFIM collab update!
|
||||
- Fullscreen keybinds now work properly on Web builds. ([1fbb760](https://github.com/FunkinCrew/Funkin/commit/1fbb7604ddf4fb8d311b9b414cbcfa0fd9bab255)) - by @NotHyper-474 in [#5664](https://github.com/FunkinCrew/Funkin/pull/5664)
|
||||
- Corrected the heights of characters in the intro text font. ([90242e2](https://github.com/FunkinCrew/funkin.assets/commit/90242e2e200fca38f5f535986db49b7a53282d1f)) - by @SpritersBlock in [funkin.assets#190](https://github.com/FunkinCrew/funkin.assets/pull/190)
|
||||
- PureColor shaders now properly apply anti-aliasing. ([8d1bfa1](https://github.com/FunkinCrew/Funkin/commit/8d1bfa105c89f68ab1f14a197f8c0a5e4fe7fb14)) - by @MaybeMaru in [#5781](https://github.com/FunkinCrew/Funkin/pull/5781)
|
||||
- The Preferences menu camera now remembers its position when exiting and re-entering. ([3d88fbb](https://github.com/FunkinCrew/Funkin/commit/3d88fbb11fea2b52d399f37cb8154795329c31c2)) - by @VirtuGuy in [#5608](https://github.com/FunkinCrew/Funkin/pull/5608)
|
||||
- The Freeplay DJ no longer flickers between animations. ([1b91f3b](https://github.com/FunkinCrew/Funkin/commit/1b91f3b57cda3310db2f5196650b89c8d88e69be)) - by @VirtuGuy in [#5598](https://github.com/FunkinCrew/Funkin/pull/5598)
|
||||
- The Preferences menu camera now remembers its position when exiting and re-entering. ([3d88fbb](https://github.com/FunkinCrew/Funkin/commit/3d88fbb11fea2b52d399f37cb8154795329c31c2)) - by @realvirtu in [#5608](https://github.com/FunkinCrew/Funkin/pull/5608)
|
||||
- The Freeplay DJ no longer flickers between animations. ([1b91f3b](https://github.com/FunkinCrew/Funkin/commit/1b91f3b57cda3310db2f5196650b89c8d88e69be)) - by @realvirtu in [#5598](https://github.com/FunkinCrew/Funkin/pull/5598)
|
||||
- The Freeplay DJ's turntable lights now glow properly. ([0c5a965](https://github.com/FunkinCrew/funkin.assets/commit/0c5a965400937cbdac55ed9317a2a00a9d4343ae)) - by @Johferson in [funkin.assets#211](https://github.com/FunkinCrew/funkin.assets/pull/211)
|
||||
- The Random capsule now opens the selected song with the correct variation. ([1605514](https://github.com/FunkinCrew/Funkin/commit/160551442453fccc0961c570701bdba7bee95ef0)) - by @PurSnake in [#5611](https://github.com/FunkinCrew/Funkin/pull/5611)
|
||||
- Newly earned Freeplay ranks no longer appear larger than others. ([47813ea](https://github.com/FunkinCrew/Funkin/commit/47813eac3157927f851713cc4c41c5eb5fac2e19)) - by @anysad in [#5768](https://github.com/FunkinCrew/Funkin/pull/5768)
|
||||
@@ -670,7 +773,7 @@ The LE SSERAFIM collab update!
|
||||
- The Week 3 train now consistently plays its sound. ([469ce39](https://github.com/FunkinCrew/funkin.assets/commit/469ce397b8eef3be47f8fadaa61a500e1a87ca3a)) - by @Lasercar in [funkin.assets#212](https://github.com/FunkinCrew/funkin.assets/pull/212)
|
||||
- Nene no longer freezes after playing two animations at once. ([d346ebd](https://github.com/FunkinCrew/funkin.assets/commit/d346ebdbf4781b49a081e0719221cf584fc3fe55)) - by @NotHyper-474 in [funkin.assets#228](https://github.com/FunkinCrew/funkin.assets/pull/228)
|
||||
- The Week 4 car now properly pauses with the game. ([26d1cff](https://github.com/FunkinCrew/funkin.assets/commit/26d1cffe19793c67a89f299b7a60be95c5656282)) - by @NotHyper-474 in [funkin.assets#114](https://github.com/FunkinCrew/funkin.assets/pull/114)
|
||||
- Pressing Reset and Pause at the same time no longer breaks the game over animation in Blazin'. ([8cd3785](https://github.com/FunkinCrew/Funkin/commit/8cd3785e3c3e913ed791204814eba86eb7142a5d)) - by @VirtuGuy in [#5639](https://github.com/FunkinCrew/Funkin/pull/5639)
|
||||
- Pressing Reset and Pause at the same time no longer breaks the game over animation in Blazin'. ([8cd3785](https://github.com/FunkinCrew/Funkin/commit/8cd3785e3c3e913ed791204814eba86eb7142a5d)) - by @realvirtu in [#5639](https://github.com/FunkinCrew/Funkin/pull/5639)
|
||||
- Pico's Blazin' death animation no longer lags and offsets improperly. ([2cb42fe](https://github.com/FunkinCrew/funkin.assets/commit/2cb42fec422313db4e8000c963be0539221c9e21)) - by @KoloInDaCrib in [funkin.assets#217](https://github.com/FunkinCrew/funkin.assets/pull/217)
|
||||
- Pico and Darnell now properly punch with their other arms in Blazin'. ([4fb015f](https://github.com/FunkinCrew/funkin.assets/commit/4fb015f20261995ce41370910989094f4f2f26bb)) - by @Honton129 in [funkin.assets#221](https://github.com/FunkinCrew/funkin.assets/pull/221)
|
||||
- Pico's Perfect Results Screen animation now syncs with the music. ([0531e27](https://github.com/FunkinCrew/funkin.assets/commit/0531e27feed83dcc9a1703b3df654fd3bba1bd8a)) - by @JackXson-Real in [funkin.assets#201](https://github.com/FunkinCrew/funkin.assets/pull/201)
|
||||
@@ -684,12 +787,12 @@ The LE SSERAFIM collab update!
|
||||
- Chart Editor event properties now have minimum values. ([9b81ebc](https://github.com/FunkinCrew/Funkin/commit/9b81ebc4f2c1c70b33d7351210c40c9a0e48ecc8)) - by @Lasercar in [#4110](https://github.com/FunkinCrew/Funkin/pull/4110)
|
||||
- Added missing notekinds to the Chart Editor Notes window. ([b7a5761](https://github.com/FunkinCrew/Funkin/commit/b7a5761730d43f27891dfec1c23fcb5e66daccf1)) - by @Lasercar in [#4286](https://github.com/FunkinCrew/Funkin/pull/4286)
|
||||
- Playback speed is now preserved when a new song or variation is loaded in the Chart Editor. ([3f82f37](https://github.com/FunkinCrew/Funkin/commit/3f82f3792b056a03724a0d1a320b7549a7b59844)) - by @Lasercar in [#4212](https://github.com/FunkinCrew/Funkin/pull/4212)
|
||||
- The Legacy Chart Importer now properly imports scroll speeds. ([2645d56](https://github.com/FunkinCrew/Funkin/commit/2645d56514dd1a27a050ff432c3cd4122f958e10)) - by @VirtuGuy in [#5655](https://github.com/FunkinCrew/Funkin/pull/5655)
|
||||
- The Legacy Chart Importer now properly imports scroll speeds. ([2645d56](https://github.com/FunkinCrew/Funkin/commit/2645d56514dd1a27a050ff432c3cd4122f958e10)) - by @realvirtu in [#5655](https://github.com/FunkinCrew/Funkin/pull/5655)
|
||||
- Opponent characters now play singing animations when selected as the player character. ([8ee24c8](https://github.com/FunkinCrew/funkin.assets/commit/8ee24c84de6aa6e6313699198f35f61991612d04)) - by @Lasercar in [funkin.assets#141](https://github.com/FunkinCrew/funkin.assets/pull/141)
|
||||
- The Chart Editor character selector window no longer opens when clicking while playtesting. ([223e837](https://github.com/FunkinCrew/Funkin/commit/223e837fe8d9ce227e289a38bdfc095e4d81c48a)) - by @Lasercar in [#4350](https://github.com/FunkinCrew/Funkin/pull/4350)
|
||||
- Renamed Nene's pixel variant to Nene (Pixel) in the Chart Editor. ([69a7898](https://github.com/FunkinCrew/funkin.assets/commit/69a78988e3d6042d2e4779c9a4055c5de73ee775)) - by @JVNpixels in [funkin.assets#208](https://github.com/FunkinCrew/funkin.assets/pull/208)
|
||||
- Renamed Tankman's variants in the Chart Editor. ([70c43b7](https://github.com/FunkinCrew/funkin.assets/commit/70c43b792078d913c4c4d9fc019e378249d08b78)) - by @ExtraCode75 in [funkin.assets#209](https://github.com/FunkinCrew/funkin.assets/pull/209)
|
||||
- Pressing F4 in the Chart Editor now properly resets the window title. ([86e69cf](https://github.com/FunkinCrew/Funkin/commit/86e69cfbd1b1bd3daa49181b827fa813cb716703)) - by @VirtuGuy in [#5651](https://github.com/FunkinCrew/Funkin/pull/5651)
|
||||
- Pressing F4 in the Chart Editor now properly resets the window title. ([86e69cf](https://github.com/FunkinCrew/Funkin/commit/86e69cfbd1b1bd3daa49181b827fa813cb716703)) - by @realvirtu in [#5651](https://github.com/FunkinCrew/Funkin/pull/5651)
|
||||
- Saving a character in the Animation Editor no longer crashes the game. ([da5f691](https://github.com/FunkinCrew/Funkin/commit/da5f6918656d4a1ad3e83233b358034db92ca675)) - by @anysad in [#5519](https://github.com/FunkinCrew/Funkin/pull/5519)
|
||||
- The Stage Editor can now properly load modded stages. ([50c601a](https://github.com/FunkinCrew/Funkin/commit/50c601a7f0f27fc0f155e2bfbcb8ef54631aeac7)) - by @KoloInDaCrib in [#5744](https://github.com/FunkinCrew/Funkin/pull/5744)
|
||||
- XML files exported from the Stage Editor now account for rotated frames. ([661ddb1](https://github.com/FunkinCrew/Funkin/commit/661ddb15f72c2dae22f41a922a521740ab3617f0)) - by @KoloInDaCrib in [#5303](https://github.com/FunkinCrew/Funkin/pull/5303)
|
||||
@@ -697,9 +800,10 @@ The LE SSERAFIM collab update!
|
||||
|
||||
## New Contributors for 0.7.4
|
||||
|
||||
* @Trofem made their first contribution in [#5476](https://github.com/FunkinCrew/Funkin/pull/5476)
|
||||
* @ThatOneCalculator made their first contribution in [#5507](https://github.com/FunkinCrew/Funkin/pull/5507)
|
||||
* @SrtHero278 made their first contribution in [#5565](https://github.com/FunkinCrew/Funkin/pull/5565)
|
||||
* @VirtuGuy made their first contribution in [#5598](https://github.com/FunkinCrew/Funkin/pull/5598)
|
||||
* @realvirtu made their first contribution in [#5598](https://github.com/FunkinCrew/Funkin/pull/5598)
|
||||
* @SpritersBlock made their first contribution in [funkin.assets#190](https://github.com/FunkinCrew/funkin.assets/pull/190)
|
||||
* @Johferson made their first contribution in [funkin.assets#211](https://github.com/FunkinCrew/funkin.assets/pull/211)
|
||||
* @Honton129 made their first contribution in [funkin.assets#213](https://github.com/FunkinCrew/funkin.assets/pull/213)
|
||||
|
||||
+1
-1
Submodule assets updated: d1d027d474...724eba9de9
@@ -9,6 +9,10 @@
|
||||
"asset": "assets/preload/images/NOTE_assets.png",
|
||||
"blocksize": "4x4"
|
||||
},
|
||||
{
|
||||
"asset": "assets/shared/images/characters/darnell/spritemap1.png",
|
||||
"blocksize": "4x4"
|
||||
},
|
||||
{
|
||||
"asset": "assets/preload/images/NOTE_hold_assets.png",
|
||||
"blocksize": "4x4"
|
||||
|
||||
+19
-17
@@ -1,8 +1,8 @@
|
||||
FROM ubuntu:noble
|
||||
|
||||
ARG haxe_version=4.3.6
|
||||
ARG haxelib_version=4.1.0
|
||||
ARG neko_version=2.4.0
|
||||
ARG haxe_version=4.3.7
|
||||
ARG haxelib_version=4.2.0
|
||||
ARG neko_version=2.4.1
|
||||
|
||||
# prepare runner
|
||||
ENV GITHUB_HOME="/github/home"
|
||||
@@ -80,11 +80,13 @@ EOF
|
||||
# Haxe native dependencies
|
||||
RUN <<EOF
|
||||
apt-fast install -y --no-install-recommends \
|
||||
libc6-dev libffi-dev \
|
||||
libx11-dev libxi-dev libxext-dev libxinerama-dev libxrandr-dev \
|
||||
libgl-dev libgl1-mesa-dev \
|
||||
build-essential \
|
||||
libc6-dev libffi-dev libdbus-1-dev libudev-dev libgbm-dev \
|
||||
libx11-dev libxi-dev libxext-dev libxinerama-dev libxrandr-dev libxcursor-dev libxss-dev \
|
||||
libgl-dev libgl1-mesa-dev libglu1-mesa-dev libdrm-dev \
|
||||
libasound2-dev libpulse-dev \
|
||||
libvlc-dev libvlccore-dev
|
||||
libvlc-dev libvlccore-dev \
|
||||
gcc-multilib g++-multilib
|
||||
EOF
|
||||
|
||||
# Janky libffi.6 fix
|
||||
@@ -98,11 +100,11 @@ EOF
|
||||
# neko
|
||||
# https://github.com/HaxeFoundation/neko/releases/download/v2-3-0/neko-2.3.0-linux64.tar.gz
|
||||
RUN <<EOF
|
||||
#neko_url=$(curl https://api.github.com/repos/HaxeFoundation/neko/releases -fL \
|
||||
# | jq '.[] | select(.name == "'"$neko_version"'")' \
|
||||
# | jq '.assets[] | select(.name | endswith("linux64.tar.gz"))' \
|
||||
# | jq -r '.browser_download_url')
|
||||
neko_url="https://geo.thei.rs/funkin/neko-2.4.1-linux64.tar.gz"
|
||||
neko_url=$(curl https://api.github.com/repos/HaxeFoundation/neko/releases -fL \
|
||||
| jq '.[] | select(.name == "'"$neko_version"'")' \
|
||||
| jq '.assets[] | select(.name | endswith("linux64.tar.gz"))' \
|
||||
| jq -r '.browser_download_url')
|
||||
#neko_url="https://geo.thei.rs/funkin/neko-2.4.1-linux64.tar.gz"
|
||||
curl -fL "$neko_url" | tar -xz -C /usr/local
|
||||
EOF
|
||||
|
||||
@@ -112,16 +114,16 @@ ln -s "$neko_path" /usr/local/neko
|
||||
EOF
|
||||
|
||||
ENV NEKOPATH="/usr/local/neko"
|
||||
ENV LD_LIBRARY_PATH="$NEKOPATH:$LD_LIBRARY_PATH"
|
||||
ENV LD_LIBRARY_PATH="$NEKOPATH"
|
||||
ENV PATH="$NEKOPATH:$PATH"
|
||||
|
||||
# haxe
|
||||
# https://github.com/HaxeFoundation/haxe/releases/download/4.0.5/haxe-4.0.5-linux64.tar.gz
|
||||
RUN <<EOF
|
||||
#haxe_url=$(curl https://api.github.com/repos/HaxeFoundation/haxe/releases -fL \
|
||||
# | jq '.[] | select(.name == "'"$haxe_version"'")' \
|
||||
# | jq '.assets[] | select(.name | endswith("linux64.tar.gz"))' \
|
||||
# | jq -r '.browser_download_url')
|
||||
haxe_url=$(curl https://api.github.com/repos/HaxeFoundation/haxe/releases -fL \
|
||||
| jq '.[] | select(.name == "'"$haxe_version"'")' \
|
||||
| jq '.assets[] | select(.name | endswith("linux64.tar.gz"))' \
|
||||
| jq -r '.browser_download_url')
|
||||
haxe_url="https://geo.thei.rs/funkin/haxe-4.3.6-linux64.tar.gz"
|
||||
curl -fL "$haxe_url" | tar -xz -C /usr/local
|
||||
EOF
|
||||
|
||||
+133
-30
@@ -33,6 +33,9 @@
|
||||
"allowReturn": true,
|
||||
"allowFunction": true,
|
||||
"allowCurlyBody": true,
|
||||
|
||||
"enforceArrowForNonMemberFunctions": true,
|
||||
|
||||
"severity": "INFO"
|
||||
},
|
||||
"type": "ArrowFunction"
|
||||
@@ -47,6 +50,14 @@
|
||||
"props": { "severity": "INFO" },
|
||||
"type": "AvoidStarImport"
|
||||
},
|
||||
{
|
||||
"comment": "If enabled, prevents ternary operators from being nested.",
|
||||
"props": {
|
||||
"severity": "INFO",
|
||||
"maxDepth": 1
|
||||
},
|
||||
"type": "AvoidTernaryOperator"
|
||||
},
|
||||
{
|
||||
"comment": "If enabled, prevents conditional compilation from crossing blocks. This prevents the case where conditional compilation could potentially create invalid syntax.",
|
||||
"props": { "severity": "INFO" },
|
||||
@@ -64,6 +75,7 @@
|
||||
"comment": "If enabled, flags when large blocks of similar code should be extracted to a function.",
|
||||
"props": {
|
||||
"thresholdSimilar": 120,
|
||||
"severity": "IGNORE",
|
||||
"thresholdIdentical": 60,
|
||||
"severityIdentical": "IGNORE"
|
||||
},
|
||||
@@ -84,11 +96,21 @@
|
||||
"type": "ConditionalCompilation"
|
||||
},
|
||||
{
|
||||
"comment": "Specifies a specific naming format for constant (static) identifiers.",
|
||||
"comment": "Specifies a specific naming format for static var identifiers.",
|
||||
"props": {
|
||||
"ignoreExtern": true,
|
||||
"format": "^?:_[a-zA-Z0-9]+(?:_[a-zA-Z0-9]+)*$",
|
||||
"tokens": ["INLINE", "NOTINLINE"],
|
||||
"tokens": ["INLINE", "NOTINLINE", "NOTFINAL"],
|
||||
"severity": "INFO"
|
||||
},
|
||||
"type": "ConstantName"
|
||||
},
|
||||
{
|
||||
"comment": "Specifies a specific naming format for static final identifiers.",
|
||||
"props": {
|
||||
"ignoreExtern": true,
|
||||
"format": "^[A-Z]([_A-Z0-9]+)*$",
|
||||
"tokens": ["INLINE", "NOTINLINE", "FINAL"],
|
||||
"severity": "INFO"
|
||||
},
|
||||
"type": "ConstantName"
|
||||
@@ -111,7 +133,13 @@
|
||||
},
|
||||
{
|
||||
"comment": "Specifies the format for doc-style comments ().",
|
||||
"props": { "lineStyle": "onestar", "startStyle": "ignore" },
|
||||
"props": {
|
||||
"startStyle": "twostars",
|
||||
"endStyle": "onestar",
|
||||
"lineStyle": "onestar",
|
||||
|
||||
"severity": "INFO"
|
||||
},
|
||||
"type": "DocCommentStyle"
|
||||
},
|
||||
{
|
||||
@@ -188,7 +216,21 @@
|
||||
"fieldType": "BOTH",
|
||||
"requireReturn": true,
|
||||
"ignoreOverride": true,
|
||||
"tokens": ["ABSTRACT_DEF", "CLASS_DEF", "ENUM_DEF", "INTERFACE_DEF"],
|
||||
"tokens": ["ABSTRACT_DEF", "CLASS_DEF", "INTERFACE_DEF"],
|
||||
"modifier": "PUBLIC",
|
||||
"excludeNames": ["new", "toString"],
|
||||
"severity": "INFO"
|
||||
},
|
||||
"type": "FieldDocComment"
|
||||
},
|
||||
{
|
||||
"comment": "If enabled, mandates documentation comments for public fields.",
|
||||
"props": {
|
||||
"requireParams": true,
|
||||
"fieldType": "FUNCTIONS",
|
||||
"requireReturn": true,
|
||||
"ignoreOverride": true,
|
||||
"tokens": ["ENUM_DEF"],
|
||||
"modifier": "PUBLIC",
|
||||
"excludeNames": ["new", "toString"],
|
||||
"severity": "INFO"
|
||||
@@ -240,7 +282,10 @@
|
||||
},
|
||||
{
|
||||
"comment": "If enabled, warns about assignments performed within another expression, like 'if (a=b){}'",
|
||||
"props": { "ignoreReturnAssignments": true, "severity": "WARNING" },
|
||||
"props": {
|
||||
"ignoreReturnAssignments": true,
|
||||
"severity": "WARNING"
|
||||
},
|
||||
"type": "InnerAssignment"
|
||||
},
|
||||
{
|
||||
@@ -270,7 +315,6 @@
|
||||
"SWITCH",
|
||||
"TRY",
|
||||
"CATCH",
|
||||
"REIFICATION",
|
||||
"ARRAY_COMPREHENSION"
|
||||
],
|
||||
"severity": "INFO"
|
||||
@@ -306,24 +350,48 @@
|
||||
"type": "ListenerName"
|
||||
},
|
||||
{
|
||||
"comment": "Specifies a specific naming format for local variables.",
|
||||
"comment": "Specifies a specific naming format for local var variables.",
|
||||
"props": {
|
||||
"ignoreExtern": true,
|
||||
"format": "^[a-z][a-zA-Z0-9]*$",
|
||||
"tokens": [],
|
||||
"tokens": ["NOTFINAL"],
|
||||
"severity": "INFO"
|
||||
},
|
||||
"type": "LocalVariableName"
|
||||
},
|
||||
{
|
||||
"comment": "Specifies a specific naming format for local final variables.",
|
||||
"props": {
|
||||
"ignoreExtern": true,
|
||||
"format": "^[A-Z][_A-Z0-9]*$",
|
||||
"tokens": ["FINAL"],
|
||||
"severity": "INFO"
|
||||
},
|
||||
"type": "LocalVariableName"
|
||||
},
|
||||
{
|
||||
"comment": "Puts a warning on long numbers without separators. 1000000 is invalid and 1_000_000 is valid.",
|
||||
"props": {
|
||||
"severity": "INFO",
|
||||
|
||||
"decimalGroupSize": 3,
|
||||
"fractionalGroupSize": -1,
|
||||
"binaryGroupSize": 8,
|
||||
"hexadecimalGroupSize": 8,
|
||||
|
||||
"decimalMinimum": 10000
|
||||
},
|
||||
"type": "LongNumber"
|
||||
},
|
||||
{
|
||||
"comment": "If enabled, warns when unlabelled numeric values get used. Use named constants instead to improve code clarity.",
|
||||
"props": { "ignoreNumbers": [-1, 0, 1, 2], "severity": "INFO" },
|
||||
"props": { "ignoreNumbers": [-1, 0, 1, 2], "severity": "IGNORE" },
|
||||
"type": "MagicNumber"
|
||||
},
|
||||
{
|
||||
"comment": "Specifies a specific naming format for public abstract member fields.",
|
||||
"props": {
|
||||
"format": "^[_a-zA-Z][a-z][a-zA-Z0-9]*$",
|
||||
"format": "^[a-zA-Z][_a-zA-Z0-9]*$",
|
||||
"tokens": ["PUBLIC", "ABSTRACT"]
|
||||
},
|
||||
"type": "MemberName"
|
||||
@@ -340,7 +408,7 @@
|
||||
{
|
||||
"comment": "Specifies a specific naming format for public class member fields.",
|
||||
"props": {
|
||||
"format": "^[_a-zA-Z][a-z][a-zA-Z0-9]*$",
|
||||
"format": "^[a-zA-Z][a-z][a-zA-Z0-9]*$",
|
||||
"tokens": ["PUBLIC", "CLASS"]
|
||||
},
|
||||
"type": "MemberName"
|
||||
@@ -348,7 +416,7 @@
|
||||
{
|
||||
"comment": "Specifies a specific naming format for private class member fields.",
|
||||
"props": {
|
||||
"format": "^[_a-zA-Z][a-z][a-zA-Z0-9]*$",
|
||||
"format": "^[_a-zA-Z][_a-zA-Z0-9]*$",
|
||||
"tokens": ["PRIVATE", "CLASS"]
|
||||
},
|
||||
"type": "MemberName"
|
||||
@@ -356,8 +424,8 @@
|
||||
{
|
||||
"comment": "Specifies a specific naming format for enum member fields.",
|
||||
"props": {
|
||||
"format": "^[_a-zA-Z][a-z][a-zA-Z0-9]*$",
|
||||
"tokens": ["ENUM"]
|
||||
"format": "^[a-zA-Z][_a-zA-Z0-9]*$",
|
||||
"tokens": ["PUBLIC", "ENUM"]
|
||||
},
|
||||
"type": "MemberName"
|
||||
},
|
||||
@@ -388,9 +456,9 @@
|
||||
"comment": "Specifies a specific naming format for method names.",
|
||||
"props": {
|
||||
"ignoreExtern": true,
|
||||
"format": "^[a-z][a-zA-Z0-9]*$",
|
||||
"format": "^[a-z][_a-zA-Z0-9]*$",
|
||||
"tokens": [],
|
||||
"severity": "IGNORE"
|
||||
"severity": "INFO"
|
||||
},
|
||||
"type": "MethodName"
|
||||
},
|
||||
@@ -398,15 +466,21 @@
|
||||
"comment": "Specifies a specific order for modifiers on fields.",
|
||||
"props": {
|
||||
"modifiers": [
|
||||
"OVERRIDE",
|
||||
"OVERLOAD",
|
||||
|
||||
"PUBLIC_PRIVATE",
|
||||
"STATIC",
|
||||
"MACRO",
|
||||
"OVERRIDE",
|
||||
"ABSTRACT",
|
||||
|
||||
"EXTERN",
|
||||
"INLINE",
|
||||
|
||||
"DYNAMIC",
|
||||
"MACRO",
|
||||
"FINAL"
|
||||
],
|
||||
"severity": "IGNORE"
|
||||
"severity": "INFO"
|
||||
},
|
||||
"type": "ModifierOrder"
|
||||
},
|
||||
@@ -429,15 +503,16 @@
|
||||
"comment": "If enabled, mandates the use of braces on specific block types, unless they fit on a single line.",
|
||||
"props": {
|
||||
"allowSingleLineStatement": true,
|
||||
"tokens": [
|
||||
"FUNCTION",
|
||||
"FOR",
|
||||
"IF",
|
||||
"ELSE_IF",
|
||||
"WHILE",
|
||||
"DO_WHILE",
|
||||
"CATCH"
|
||||
],
|
||||
"tokens": ["FUNCTION", "FOR", "IF", "IF_WITH_ELSE", "ELSE"],
|
||||
"severity": "INFO"
|
||||
},
|
||||
"type": "NeedBraces"
|
||||
},
|
||||
{
|
||||
"comment": "If enabled, mandates the use of braces on specific block types, and prevent them from being placed on a single line.",
|
||||
"props": {
|
||||
"allowSingleLineStatement": false,
|
||||
"tokens": ["IF_WITH_ELSE", "CATCH", "WHILE", "DO_WHILE", "ELSE_IF"],
|
||||
"severity": "INFO"
|
||||
},
|
||||
"type": "NeedBraces"
|
||||
@@ -630,7 +705,11 @@
|
||||
},
|
||||
{
|
||||
"comment": "If enabled, complains about overly complicated boolean expressions.",
|
||||
"props": { "severity": "WARNING" },
|
||||
"props": {
|
||||
"severity": "WARNING",
|
||||
|
||||
"allowEqualsFalse": false
|
||||
},
|
||||
"type": "SimplifyBooleanExpression"
|
||||
},
|
||||
{
|
||||
@@ -661,6 +740,14 @@
|
||||
},
|
||||
"type": "StringLiteral"
|
||||
},
|
||||
{
|
||||
"comment": "If enabled, requires that switch conditions be wrapped in parenthesis.",
|
||||
"props": {
|
||||
"policy": "require",
|
||||
"severity": "INFO"
|
||||
},
|
||||
"type": "SwitchParentheses"
|
||||
},
|
||||
{
|
||||
"comment": "Puts a warning on unresolved TODO/FIXME comments.",
|
||||
"props": {
|
||||
@@ -679,6 +766,16 @@
|
||||
"props": { "severity": "IGNORE" },
|
||||
"type": "Trace"
|
||||
},
|
||||
{
|
||||
"comment": "If enabled, complains about trailing commas at the end of array and object literals.",
|
||||
"props": {
|
||||
"severity": "INFO",
|
||||
"enforceArrayComprehension": false,
|
||||
"enforceArrayLiterals": false,
|
||||
"enforceObjectLiterals": false
|
||||
},
|
||||
"type": "TrailingComma"
|
||||
},
|
||||
{
|
||||
"comment": "If enabled, complains about trailing whitespaces at the end of lines.",
|
||||
"props": { "severity": "INFO" },
|
||||
@@ -692,7 +789,13 @@
|
||||
{
|
||||
"comment": "If enabled, mandates documentation comments on classes and interfaces.",
|
||||
"props": {
|
||||
"tokens": ["CLASS_DEF", "ENUM_DEF", "INTERFACE_DEF", "TYPEDEF_DEF"],
|
||||
"tokens": [
|
||||
"CLASS_DEF",
|
||||
"INTERFACE_DEF",
|
||||
"TYPEDEF_DEF",
|
||||
"ABSTRACT_DEF",
|
||||
"ENUM_DEF"
|
||||
],
|
||||
"severity": "INFO"
|
||||
},
|
||||
"type": "TypeDocComment"
|
||||
|
||||
@@ -12,7 +12,7 @@ Check [COMPILING.md](./COMPILING.md) if you haven’t done that yet.
|
||||
setx ANDROID_HOME "C:\path\to\your\folder" /M
|
||||
```
|
||||
3. Download [Android Studio Command-line Tools](https://developer.android.com/studio#command-line-tools-only).
|
||||
4. Extract the ZIP into your folder from step 1.
|
||||
4. Extract the ZIP into your folder from step 0.
|
||||
5. (Optional) Close and reopen the terminal if needed.
|
||||
6. Run:
|
||||
```bash
|
||||
@@ -69,10 +69,10 @@ Check [COMPILING.md](./COMPILING.md) if you haven’t done that yet.
|
||||
```
|
||||
|
||||
## iOS
|
||||
Note that you can only build the game for iOS on a computer running MacOS.
|
||||
Note that you can only build the game for iOS on a computer running macOS.
|
||||
|
||||
0. Build the game for desktop to make sure everything works. Check [COMPILING.md](./COMPILING.md).
|
||||
1. Get Xcode from the app store on your MacOS Machine.
|
||||
1. Get Xcode from the app store on your macOS Machine.
|
||||
2. Download the iPhone SDK (First thing that pops up in Xcode)
|
||||
3. Open up a terminal tab and run `lime test ios -xcode`
|
||||
4. You will need to sign your own copy in order to run the game with a real iOS device! That requires an Apple Developer account, sorry!
|
||||
@@ -81,11 +81,11 @@ Note that you can only build the game for iOS on a computer running MacOS.
|
||||
### iOS Troubleshooting
|
||||
|
||||
- **A required plugin failed to load. Please ensure system content is up-to-date — try running 'xcodebuild -runFirstLaunch'.**
|
||||
Make sure you have the iOS SDK isntalled, see Step 2.
|
||||
Make sure you have the iOS SDK installed, see Step 2.
|
||||
|
||||
- **error: No Accounts: Add a new account in Accounts settings. (in target 'Funkin' from project 'Funkin')**
|
||||
|
||||
Open XCode, press CMD+, to open Settings, select Accounts, add an Apple ID.
|
||||
Open Xcode, press CMD+, to open Settings, select Accounts, add an Apple ID.
|
||||
|
||||
- error: No Account for Team "Z7G7AVNGSH". Add a new account in Accounts settings or verify that your accounts have valid credentials.
|
||||
|
||||
|
||||
@@ -60,8 +60,8 @@ This section provides guidelines to follow when [opening an issue](https://githu
|
||||
|
||||
## Requirements
|
||||
Make sure you're playing:
|
||||
- the latest version of the game (currently v0.8.5 for Android, v0.8.4 for all other platforms)
|
||||
- without any mods
|
||||
- the latest version of the game (currently v0.8.6, or v0.8.7 for Android) or a public playtest version (v0.9 Feature Preview builds)
|
||||
- without any mods (unless the issue involves mods)
|
||||
- on [Newgrounds](https://www.newgrounds.com/portal/view/770371) or downloaded from [itch.io](https://ninja-muffin24.itch.io/funkin)
|
||||
|
||||
## Rejected Features
|
||||
@@ -86,6 +86,7 @@ Here's a list of commonly suggested features and the reasons why they won't be a
|
||||
| Importing Charts from Psych Engine (and other mod content) | https://github.com/FunkinCrew/Funkin/issues/2586#issuecomment-2125733327 |
|
||||
| Backwards Compatibility for Modding | https://github.com/FunkinCrew/Funkin/issues/3949#issuecomment-2608391329 |
|
||||
| Lua Support | https://github.com/FunkinCrew/Funkin/issues/2643#issuecomment-2143718093 |
|
||||
| Note Hitsounds | https://github.com/FunkinCrew/Funkin/pull/4112#issuecomment-5347549977 |
|
||||
|
||||
## Issue Types
|
||||
Choose the issue template that best suits your needs!
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# Install Dox
|
||||
`haxelib install dox`
|
||||
|
||||
# To generate documentation
|
||||
Run the script for your operating system, and then it will generate docs into `docs/dox/output/`
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "Funkin' Theme",
|
||||
"author": "The Funkin' Crew Inc"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 8.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,332 @@
|
||||
#theme-toggle:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.dark-theme {
|
||||
background-color: #111 !important;
|
||||
color: #ccc;
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
.dark-theme body {
|
||||
background-color: #111 !important;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.dark-theme .navbar-inner {
|
||||
background-color: #222 !important;
|
||||
}
|
||||
|
||||
.dark-theme .brand {
|
||||
color: #CCC !important;
|
||||
}
|
||||
.dark-theme .brand .img {
|
||||
margin-top: -5px;
|
||||
}
|
||||
|
||||
.dark-theme .well {
|
||||
background-color: #222;
|
||||
border: 1px solid #222;
|
||||
}
|
||||
|
||||
.dark-theme .input-append .add-on,
|
||||
.dark-theme .input-prepend .add-on {
|
||||
background-color: #333;
|
||||
border: 1px solid #333;
|
||||
padding: 3px 5px;
|
||||
text-shadow: 0 0 0 #000;
|
||||
}
|
||||
|
||||
.dark-theme h1 {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.dark-theme a {
|
||||
color: #0087ff;
|
||||
}
|
||||
|
||||
.dark-theme a:hover,
|
||||
.dark-theme a:focus {
|
||||
color: #00b7ff;
|
||||
}
|
||||
|
||||
.dark-theme input,
|
||||
.dark-theme textarea {
|
||||
background-color: #151515;
|
||||
border: 1px solid #333;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.dark-theme .btn-group.open .btn.dropdown-toggle {
|
||||
background-color: #202020;
|
||||
}
|
||||
|
||||
.dark-theme .dropdown-menu {
|
||||
background-color: #111;
|
||||
}
|
||||
|
||||
.dark-theme .dropdown-menu>li>a {
|
||||
color: #EEE;
|
||||
}
|
||||
|
||||
.dark-theme .dropdown-menu>li>a:hover,
|
||||
.dark-theme .dropdown-menu>li>a:focus,
|
||||
.dark-theme .dropdown-submenu:hover>a,
|
||||
.dark-theme .dropdown-submenu:focus>a {
|
||||
color: #EEE;
|
||||
background-color: #2f2f2f;
|
||||
background-image: linear-gradient(to bottom, #262626, #2f2f2f);
|
||||
}
|
||||
|
||||
.dark-theme .btn:focus,
|
||||
.dark-theme .btn:hover {
|
||||
background-position: 0 0;
|
||||
}
|
||||
|
||||
.dark-theme .nav>li>a:hover,
|
||||
.dark-theme .nav>li>a:focus {
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
.dark-theme .nav-list>.active>a {
|
||||
background-color: #444;
|
||||
}
|
||||
|
||||
.dark-theme .nav-list>.active>a.treeLink,
|
||||
.dark-theme .nav-list>.active>a.treeLink:hover,
|
||||
.dark-theme .nav-list>.active>a.treeLink:focus {
|
||||
background: #269;
|
||||
}
|
||||
|
||||
.dark-theme .btn {
|
||||
color: #d5d5d5;
|
||||
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75);
|
||||
background-color: #313131;
|
||||
background-image: linear-gradient(to bottom, #313131, #282828);
|
||||
border: 1px solid #424141;
|
||||
border-bottom-color: #393939;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.dark-theme .btn {
|
||||
color: #d5d5d5;
|
||||
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75);
|
||||
background-color: #313131;
|
||||
background-image: linear-gradient(to bottom, #313131, #282828);
|
||||
border: 1px solid #424141;
|
||||
border-bottom-color: rgb(66, 65, 65);
|
||||
border-bottom-color: #393939;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.dark-theme .btn:focus,
|
||||
.dark-theme .btn:hover {
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.dark-theme .btn.active,
|
||||
.dark-theme .btn:active {
|
||||
background-image: none;
|
||||
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
||||
}
|
||||
|
||||
.dark-theme .btn.disabled,
|
||||
.dark-theme .btn[disabled] {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.65;
|
||||
box-shadow: none;
|
||||
border-color: #393939;
|
||||
}
|
||||
|
||||
.dark-theme .btn:focus {
|
||||
color: #d5d5d5;
|
||||
background-color: #313131;
|
||||
border-color: #424141;
|
||||
}
|
||||
|
||||
.dark-theme .btn:active:hover,
|
||||
.dark-theme .btn:focus:hover {
|
||||
color: #fff;
|
||||
background-color: #313131;
|
||||
border-color: #393939;
|
||||
}
|
||||
|
||||
.dark-theme a.btn.disabled {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.dark-theme .section.site-footer {
|
||||
background: #111 !important;
|
||||
}
|
||||
|
||||
.dark-theme .copyright>p {
|
||||
color: #CCC !important;
|
||||
}
|
||||
|
||||
.dark-theme .table th,
|
||||
.dark-theme .table td {
|
||||
border-bottom: 1px solid #222;
|
||||
}
|
||||
|
||||
.dark-theme .table .fa {
|
||||
color: #222;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.dark-theme .alert,
|
||||
.dark-theme .alert h4 {
|
||||
color: #ffc96c;
|
||||
}
|
||||
|
||||
.dark-theme .availability {
|
||||
color: #69b;
|
||||
}
|
||||
|
||||
.dark-theme .section-availability {
|
||||
color: #69b;
|
||||
}
|
||||
|
||||
.dark-theme .alert {
|
||||
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.dark-theme .alert {
|
||||
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.5);
|
||||
background-color: #332b00;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.dark-theme hr {
|
||||
border-top: none;
|
||||
border-bottom: 1px solid #222;
|
||||
}
|
||||
|
||||
.dark-theme .page-header {
|
||||
border-bottom: 1px solid #222;
|
||||
}
|
||||
|
||||
.dark-theme .section {
|
||||
border-bottom: 1px solid #222;
|
||||
}
|
||||
|
||||
.dark-theme .field+.field {
|
||||
border-top: 1px solid #222;
|
||||
}
|
||||
|
||||
.dark-theme code {
|
||||
color: #ddd;
|
||||
background-color: #111;
|
||||
border: 1px solid #222;
|
||||
}
|
||||
|
||||
.dark-theme pre {
|
||||
background-color: #222;
|
||||
border: 1px solid #333;
|
||||
}
|
||||
|
||||
.dark-theme .example code {
|
||||
color: #ddd;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.dark-theme pre code {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.dark-theme pre.example::before {
|
||||
color: #DDD;
|
||||
background: #191919;
|
||||
}
|
||||
|
||||
.dark-theme h3 code {
|
||||
box-shadow: 0 0 15px rgb(20, 20, 20);
|
||||
}
|
||||
|
||||
.dark-theme .label,
|
||||
.dark-theme .badge {
|
||||
color: #DDD;
|
||||
background-color: #404040;
|
||||
}
|
||||
|
||||
.dark-theme .label.label-meta {
|
||||
background: #333379;
|
||||
}
|
||||
|
||||
.dark-theme code .identifier {
|
||||
color: #eff;
|
||||
}
|
||||
|
||||
.dark-theme table.params {
|
||||
border-left: 5px solid #222;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.dark-theme .table-bordered {
|
||||
border: 1px solid #222;
|
||||
}
|
||||
|
||||
.dark-theme table.params th {
|
||||
background: #111;
|
||||
}
|
||||
|
||||
.dark-theme .table-bordered th,
|
||||
.dark-theme .table-bordered td {
|
||||
border-left: 1px solid #222;
|
||||
}
|
||||
|
||||
.dark-theme .indent {
|
||||
border-left: 5px solid #222;
|
||||
}
|
||||
|
||||
|
||||
/* Types without links */
|
||||
|
||||
.dark-theme code .type {
|
||||
color: #29e;
|
||||
}
|
||||
|
||||
|
||||
/* dark code examples (from try-haxe) */
|
||||
|
||||
.dark-theme code,
|
||||
.dark-theme pre {
|
||||
color: #DDD;
|
||||
}
|
||||
|
||||
.dark-theme code a {
|
||||
color: #29e
|
||||
}
|
||||
|
||||
.dark-theme pre .type {
|
||||
color: #DECB6B
|
||||
}
|
||||
|
||||
.dark-theme pre .kwd {
|
||||
color: #C792EA
|
||||
}
|
||||
|
||||
.dark-theme pre .val {
|
||||
color: #FF5370
|
||||
}
|
||||
|
||||
.dark-theme div.pre .str,
|
||||
.dark-theme pre .str,
|
||||
.dark-theme pre .str .kwd,
|
||||
.dark-theme pre .str .type,
|
||||
.dark-theme pre .str .val {
|
||||
color: #C3E88D
|
||||
}
|
||||
|
||||
.dark-theme pre .cmt,
|
||||
.dark-theme pre .cmt .kwd,
|
||||
.dark-theme pre .cmt .str,
|
||||
.dark-theme pre .cmt .type,
|
||||
.dark-theme pre .cmt .val {
|
||||
color: #545454
|
||||
}
|
||||
|
||||
.dark-theme .last-modified {
|
||||
color: #666
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
/** to be overridden in sub-themes */
|
||||
@@ -0,0 +1,189 @@
|
||||
nav.nav {
|
||||
font-family: "Open Sans", sans-serif;
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
nav .fa {
|
||||
color: #777;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
body nav * {
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
nav .navbar-inner {
|
||||
background: #13110f;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
nav .navbar .nav {
|
||||
margin: 0;
|
||||
|
||||
}
|
||||
|
||||
nav .dropdown-menu {
|
||||
background: #2c2722;
|
||||
font-size: 14px;
|
||||
border-radius: 0px 0px 2px 2px;
|
||||
padding: 10px 0px;
|
||||
border: 1px solid #2c2722;
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
nav .navbar .nav>li>a {
|
||||
padding: 14px 12px 15px 12px;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
nav .dropdown-menu li a {
|
||||
color: #b8b5b5;
|
||||
padding: 3px 15px;
|
||||
}
|
||||
|
||||
nav .divider {
|
||||
background-color: transparent;
|
||||
border-right: 1px solid #39332d;
|
||||
margin: 5px 20px 5px 10px;
|
||||
height: 39px;
|
||||
}
|
||||
|
||||
nav .dropdown-menu .divider {
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #39332d;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
nav .navbar-inverse .nav .active>a,
|
||||
nav .navbar-inverse .nav .active>a:hover,
|
||||
nav .navbar-inverse .nav .active>a:focus,
|
||||
nav .navbar-inverse .nav li.dropdown.open>.dropdown-toggle,
|
||||
nav .navbar-inverse .nav li.dropdown.active>.dropdown-toggle,
|
||||
nav .navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle {
|
||||
color: #fff;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
nav .navbar-inverse .nav .active>a:hover {
|
||||
background: #39332d;
|
||||
}
|
||||
|
||||
nav .dropdown-menu>.active>a,
|
||||
nav .dropdown-menu>.active>a:hover,
|
||||
nav .dropdown-menu>.active>a:focus {
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
background-image: none;
|
||||
background: #39332d;
|
||||
}
|
||||
|
||||
nav .dropdown-menu>li>a:hover,
|
||||
.dropdown-menu>li>a:focus,
|
||||
nav .dropdown-submenu:hover>a,
|
||||
nav .dropdown-submenu:focus>a {
|
||||
background: #39332d;
|
||||
}
|
||||
|
||||
nav .navbar .nav>li>.dropdown-menu:after {
|
||||
border-bottom-color: #2c2722;
|
||||
}
|
||||
|
||||
/** MEDIA Q **/
|
||||
|
||||
@media (max-width: 979px) {
|
||||
|
||||
nav .navbar-fixed-top .navbar-inner,
|
||||
nav .navbar-fixed-bottom .navbar-inner {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
nav .navbar-fixed-top {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** SUB BRAND LOGOS **/
|
||||
|
||||
.navbar .brand.haxe-logo {
|
||||
padding-right: 0;
|
||||
margin: 3px 0 0 0px;
|
||||
}
|
||||
|
||||
.navbar .brand.haxe-logo:hover {
|
||||
opacity: .9;
|
||||
}
|
||||
|
||||
.navbar .brand.haxe-logo:after {
|
||||
content: " ";
|
||||
position: absolute;
|
||||
/* create arrow */
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 22px solid transparent;
|
||||
border-bottom: 22px solid transparent;
|
||||
border-left: 7px solid #13110f;
|
||||
/* same color as nav bar */
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.navbar .brand.sub {
|
||||
background: #39332d;
|
||||
/* Old browsers */
|
||||
background: -moz-linear-gradient(top, #39332d 50%, #2c2722 51%);
|
||||
/* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(50%, #39332d), color-stop(51%, #2c2722));
|
||||
/* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, #39332d 50%, #2c2722 51%);
|
||||
/* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, #39332d 50%, #2c2722 51%);
|
||||
/* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, #39332d 50%, #2c2722 51%);
|
||||
/* IE10+ */
|
||||
background: linear-gradient(to bottom, #39332d 50%, #2c2722 51%);
|
||||
/* W3C */
|
||||
padding: 14px 20px 13px 20px;
|
||||
margin: 0 10px 0 0;
|
||||
font: bold 18px "arial black", "open sans";
|
||||
line-height: 22px;
|
||||
color: rgb(255, 255, 255);
|
||||
}
|
||||
|
||||
.navbar .brand.sub:hover {
|
||||
color: rgb(230, 230, 230);
|
||||
background: #2c2722;
|
||||
/* Old browsers */
|
||||
}
|
||||
|
||||
.navbar .brand.sub:before {
|
||||
content: "..";
|
||||
/* two dots */
|
||||
position: absolute;
|
||||
margin-left: -33px;
|
||||
margin-top: -28px;
|
||||
line-height: 0px;
|
||||
font: bold 40px "Open Sans", sans-serif;
|
||||
letter-spacing: 0px;
|
||||
color: #fff200;
|
||||
}
|
||||
|
||||
/** SUB BRAND COLORS **/
|
||||
|
||||
.navbar .brand.sub.try:before {
|
||||
color: #f89c0e;
|
||||
}
|
||||
|
||||
.navbar .brand.sub.api:before {
|
||||
color: #eedc16;
|
||||
}
|
||||
|
||||
.navbar .brand.sub.lib:before {
|
||||
color: #f1471d;
|
||||
}
|
||||
|
||||
.navbar .brand.sub.ide:before {
|
||||
color: #f89c0e;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
Code Highlighting
|
||||
**/
|
||||
html pre,
|
||||
html pre code {
|
||||
font-family: consolas, monospace;
|
||||
white-space: pre;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
code {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
code a {
|
||||
color: #08c;
|
||||
}
|
||||
|
||||
pre {
|
||||
color: #333;
|
||||
margin: 15px 0;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
pre .type {
|
||||
color: #0086b3;
|
||||
}
|
||||
|
||||
pre .kwd {
|
||||
color: #00a;
|
||||
}
|
||||
|
||||
pre .val {
|
||||
color: #44a;
|
||||
}
|
||||
|
||||
pre .str,
|
||||
div.pre .str,
|
||||
pre .str .kwd,
|
||||
pre .str .val,
|
||||
pre .str .type {
|
||||
color: #a00;
|
||||
}
|
||||
|
||||
pre .cmt {
|
||||
color: #008800;
|
||||
color: #998;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* Make sure keywords inside comments are not highlighted*/
|
||||
pre .cmt .kwd,
|
||||
pre .cmt .str,
|
||||
pre .cmt .val,
|
||||
pre .cmt .type {
|
||||
color: #998;
|
||||
}
|
||||
|
||||
.last-modified {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.semantic {
|
||||
display: none;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// highlighter adapted/modified from code.haxe.org
|
||||
(function (console) { "use strict";
|
||||
var EReg = function(r,opt) {
|
||||
opt = opt.split("u").join("");
|
||||
this.r = new RegExp(r,opt);
|
||||
};
|
||||
EReg.prototype = {
|
||||
replace: function(s,by) {
|
||||
return s.replace(this.r,by);
|
||||
}
|
||||
};
|
||||
var Highlighter = function() { };
|
||||
Highlighter.main = function() {
|
||||
var _g = 0;
|
||||
var _g1 = window.document.body.querySelectorAll("pre code");
|
||||
while(_g < _g1.length) {
|
||||
var el = _g1[_g];
|
||||
++_g;
|
||||
if(!Highlighter.hasClass(el,"highlighted")) {
|
||||
el.innerHTML = Highlighter.syntaxHighlight(el.innerHTML);
|
||||
el.className += " highlighted";
|
||||
}
|
||||
}
|
||||
};
|
||||
Highlighter.hasClass = function(el,className) {
|
||||
return el.className.indexOf(className) != -1;
|
||||
};
|
||||
Highlighter.syntaxHighlight = function(html) {
|
||||
var kwds = ["abstract","break","case","cast","catch","class","continue","default","do","dynamic","else","enum","extends","extern","false","final","for","function","if","implements","import","in","inline","interface","macro","new","operator","overload","override","package","private","public","return","static","switch","this","throw","true","try","typedef","untyped","using","var","while"];
|
||||
var kwds1 = new EReg("\\b(" + kwds.join("|") + ")\\b","g");
|
||||
var vals = ["null","true","false","this"];
|
||||
var vals1 = new EReg("\\b(" + vals.join("|") + ")\\b","g");
|
||||
var types = new EReg("\\b([A-Z][a-zA-Z0-9]*)\\b","g");
|
||||
html = kwds1.replace(html,"<span class='kwd'>$1</span>");
|
||||
html = vals1.replace(html,"<span class='val'>$1</span>");
|
||||
html = types.replace(html,"<span class='type'>$1</span>");
|
||||
html = new EReg("(\"[^\"]*\")","g").replace(html,"<span class='str'>$1</span>");
|
||||
html = new EReg("(//.+?)(\n|$)","g").replace(html,"<span class='cmt'>$1</span>$2");
|
||||
html = new EReg("(/\\*\\*?(.|\n)+?\\*?\\*/)","g").replace(html,"<span class='cmt'>$1</span>");
|
||||
return html;
|
||||
};
|
||||
Highlighter.main();
|
||||
})(typeof console != "undefined" ? console : {log:function(){}});
|
||||
@@ -0,0 +1,319 @@
|
||||
function createCookie(name, value) {
|
||||
localStorage.setItem(name, value);
|
||||
}
|
||||
|
||||
function readCookie(name) {
|
||||
return localStorage.getItem(name);
|
||||
}
|
||||
|
||||
function isDarkTheme() {
|
||||
return document.querySelector("html").classList.contains("dark-theme");
|
||||
}
|
||||
|
||||
function toggleTheme() {
|
||||
const htmlTag = document.querySelector("html");
|
||||
let isDark = isDarkTheme();
|
||||
if (isDark) {
|
||||
htmlTag.classList.remove("dark-theme");
|
||||
} else {
|
||||
htmlTag.classList.add("dark-theme");
|
||||
}
|
||||
isDark = isDarkTheme();
|
||||
localStorage.theme = isDark ? "dark" : "light";
|
||||
}
|
||||
|
||||
function toggleInherited(el) {
|
||||
var toggle = $(el).closest(".toggle");
|
||||
toggle.toggleClass("toggle-on");
|
||||
if (toggle.hasClass("toggle-on")) {
|
||||
$("i", toggle).removeClass("fa-folder").addClass("fa-folder-open");
|
||||
} else {
|
||||
$("i", toggle).addClass("fa-folder").removeClass("fa-folder-open");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function toggleCollapsed(el) {
|
||||
var toggle = $(el).closest(".expando");
|
||||
toggle.toggleClass("expanded");
|
||||
|
||||
if (toggle.hasClass("expanded")) {
|
||||
$(toggle).find("i").first().removeClass("fa-folder").addClass("fa-folder-open");
|
||||
} else {
|
||||
$(toggle).find("i").first().addClass("fa-folder").removeClass("fa-folder-open");
|
||||
}
|
||||
updateTreeState();
|
||||
return false;
|
||||
}
|
||||
|
||||
function updateTreeState() {
|
||||
var states = [];
|
||||
$("#nav .expando").each(function (i, e) {
|
||||
states.push($(e).hasClass("expanded") ? 1 : 0);
|
||||
});
|
||||
var treeState = JSON.stringify(states);
|
||||
createCookie("treeState", treeState);
|
||||
}
|
||||
|
||||
function setPlatform(platform) {
|
||||
createCookie("platform", platform);
|
||||
$("#select-platform").val(platform);
|
||||
|
||||
var styles = ".platform { display:none }";
|
||||
var platforms = dox.platforms;
|
||||
if (platform == "flash" || platform == "js") {
|
||||
styles += ".package-sys { display:none; } ";
|
||||
}
|
||||
for (var i = 0; i < platforms.length; i++) {
|
||||
var p = platforms[i];
|
||||
if (platform == "sys") {
|
||||
if (p != "flash" && p != "js") {
|
||||
styles += ".platform-" + p + " { display:inherit } ";
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (platform == "all" || p == platform) {
|
||||
styles += ".platform-" + p + " { display:inherit } ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (platform != "flash" && platform != "js") {
|
||||
styles += ".platform-sys { display:inherit } ";
|
||||
}
|
||||
|
||||
$("#dynamicStylesheet").text(styles);
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
$("#nav").html(navContent);
|
||||
var treeState = readCookie("treeState");
|
||||
|
||||
$("#nav .expando").each(function (i, e) {
|
||||
$("i", e).first().addClass("fa-folder").removeClass("fa-folder-open");
|
||||
});
|
||||
|
||||
$(".treeLink").each(function () {
|
||||
this.href = this.href.replace("::rootPath::", dox.rootPath);
|
||||
});
|
||||
|
||||
if (treeState != null) {
|
||||
var states = JSON.parse(treeState);
|
||||
$("#nav .expando").each(function (i, e) {
|
||||
if (states[i]) {
|
||||
$(e).addClass("expanded");
|
||||
$("i", e).first().removeClass("fa-folder").addClass("fa-folder-open");
|
||||
}
|
||||
});
|
||||
}
|
||||
$("head").append("<style id='dynamicStylesheet'></style>");
|
||||
|
||||
setPlatform(readCookie("platform") == null ? "all" : readCookie("platform"));
|
||||
|
||||
$("#search").on("input", function (e) {
|
||||
searchQuery(e.target.value);
|
||||
});
|
||||
$(document).bind("keyup keydown", function (e) {
|
||||
if (e.ctrlKey && e.keyCode == 80) { // ctrl + p
|
||||
$("#search").focus();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
function getItems() {
|
||||
return $("#search-results-list a").toArray();
|
||||
}
|
||||
$("#search").bind("keyup", function (e) {
|
||||
switch (e.keyCode) {
|
||||
case 27: // escape
|
||||
searchQuery("");
|
||||
$("#search").val("")
|
||||
$("#search").blur();
|
||||
return false;
|
||||
|
||||
case 13: // enter
|
||||
var items = getItems();
|
||||
for (i = 0; i < items.length; i++) {
|
||||
var item = $(items[i]);
|
||||
if (item.hasClass("selected")) {
|
||||
window.location = items[i].href;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
$("#search").bind("keydown", function (e) {
|
||||
function mod(a, b) {
|
||||
var r = a % b;
|
||||
return r < 0 ? r + b : r;
|
||||
}
|
||||
function changeSelection(amount) {
|
||||
var previousSelection = null;
|
||||
var items = getItems();
|
||||
for (i = 0; i < items.length; i++) {
|
||||
var item = $(items[i]);
|
||||
if (item.hasClass("selected")) {
|
||||
item.removeClass("selected");
|
||||
previousSelection = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var newSelection = mod(previousSelection + amount, items.length);
|
||||
$(items[newSelection]).addClass("selected");
|
||||
items[newSelection].scrollIntoView(false);
|
||||
}
|
||||
switch (e.keyCode) {
|
||||
case 38: // up
|
||||
changeSelection(-1);
|
||||
return false;
|
||||
|
||||
case 40: // down
|
||||
changeSelection(1);
|
||||
return false;
|
||||
|
||||
case 13: // enter
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
$("#select-platform").selectpicker().on("change", function (e) {
|
||||
var value = $(":selected", this).val();
|
||||
setPlatform(value);
|
||||
});
|
||||
|
||||
$("#nav a").each(function () {
|
||||
if (this.href == location.href) {
|
||||
$(this.parentElement).addClass("active");
|
||||
}
|
||||
});
|
||||
|
||||
$("a.expand-button").click(function (e) {
|
||||
var container = $(this).parent().next();
|
||||
container.toggle();
|
||||
$("i", this).removeClass("fa-folder-open")
|
||||
.removeClass("fa-folder")
|
||||
.addClass(container.is(":visible") ? "fa-folder-open" : "fa-folder");
|
||||
return false;
|
||||
});
|
||||
|
||||
// Because there is no CSS parent selector
|
||||
$("code.prettyprint").parents("pre").addClass("example");
|
||||
});
|
||||
|
||||
function searchQuery(query) {
|
||||
$("#searchForm").removeAttr("action");
|
||||
query = query.replace(/[&<>"']/g, "");
|
||||
if (!query || query.length < 2) {
|
||||
$("#nav").removeClass("searching");
|
||||
$("#nav li").each(function (index, element) {
|
||||
var e = $(element);
|
||||
e.css("display", "");
|
||||
});
|
||||
$("#nav ul:first-child").css("display", "block");
|
||||
$("#search-results-list").css("display", "none");
|
||||
return;
|
||||
}
|
||||
var queryParts = query.toLowerCase().split(" ");
|
||||
var listItems = [];
|
||||
var bestMatch = 200;
|
||||
$("#nav").addClass("searching");
|
||||
$("#nav ul:first-child").css("display", "none");
|
||||
$("#nav li").each(function (index, element) {
|
||||
var e = $(element);
|
||||
if (!e.hasClass("expando")) {
|
||||
var content = e.attr("data_path");
|
||||
var score = searchMatch(content, queryParts);
|
||||
if (score >= 0) {
|
||||
if (score < bestMatch) {
|
||||
var url = dox.rootPath + e.attr("data_path").split(".").join("/") + ".html";
|
||||
$("#searchForm").attr("action", url);
|
||||
// best match will be form action
|
||||
bestMatch = score;
|
||||
}
|
||||
|
||||
var elLink = $("a", element);
|
||||
// highlight matched parts
|
||||
var elLinkContent = elLink.text().replace(new RegExp("(" + queryParts.join("|").split(".").join("|") + ")", "ig"), "<strong>$1</strong>");
|
||||
var liStyle = (score == 0) ? ("font-weight:bold") : "";
|
||||
listItems.push({ score: score, item: "<li style='" + liStyle + "'><a href='" + elLink.attr("href") + "'>" + elLinkContent + "</a></li>" });
|
||||
}
|
||||
}
|
||||
});
|
||||
if ($("#search-results-list").length == 0) {
|
||||
// append to nav
|
||||
$("#nav").parent().append("<ul id='search-results-list' class='nav nav-list'></ul>");
|
||||
}
|
||||
listItems.sort(function (x, y) { return x.score - y.score; }); // put in order
|
||||
$("#search-results-list").css("display", "block").html(listItems.map(function (x) { return x.item; }).join(""));
|
||||
// pre-select the first item
|
||||
$("#search-results-list a").removeClass("selected");
|
||||
$("#search-results-list a:first").addClass("selected");
|
||||
}
|
||||
|
||||
function match(textParts, query) {
|
||||
var queryParts = query.split(".");
|
||||
if (queryParts.length == 1) {
|
||||
var queryPart = queryParts[0];
|
||||
for (var i = 0; i < textParts.length; ++i) {
|
||||
var textPart = textParts[i];
|
||||
if (textPart.indexOf(queryPart) > -1) {
|
||||
// We don't want to match the same part twice, so let's remove it
|
||||
textParts[i] = textParts[i].split(queryPart).join("");
|
||||
return textPart.length - queryPart.length;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var offset = -1;
|
||||
outer:
|
||||
while (true) {
|
||||
++offset;
|
||||
if (queryParts.length + offset > textParts.length) {
|
||||
return -1;
|
||||
}
|
||||
var scoreSum = 0;
|
||||
for (var i = 0; i < queryParts.length; ++i) {
|
||||
var queryPart = queryParts[i];
|
||||
var textPart = textParts[i + offset];
|
||||
var index = textPart.indexOf(queryPart);
|
||||
if (index != 0) {
|
||||
continue outer;
|
||||
}
|
||||
scoreSum += textPart.length - queryPart.length;
|
||||
}
|
||||
return scoreSum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function searchMatch(text, queryParts) {
|
||||
text = text.toLowerCase();
|
||||
var textParts = text.split(".");
|
||||
var scoreSum = 0;
|
||||
for (var i = 0; i < queryParts.length; ++i) {
|
||||
var score = match(textParts, queryParts[i]);
|
||||
if (score == -1) {
|
||||
return -1;
|
||||
}
|
||||
scoreSum += score + text.length;
|
||||
}
|
||||
return scoreSum;
|
||||
}
|
||||
|
||||
function errorSearch() {
|
||||
var errorURL = "";
|
||||
if (!!window.location.pathname) {
|
||||
errorURL = window.location.pathname;
|
||||
} else if (!!window.location.href) {
|
||||
errorURL = window.location.href;
|
||||
}
|
||||
if (!!errorURL) {
|
||||
var searchTerm = errorURL.split("/").pop();
|
||||
if (searchTerm.indexOf(".html") > -1) { searchTerm = searchTerm.split(".html").join(""); }
|
||||
if (!!searchTerm) {
|
||||
// update filter with search term
|
||||
$("#search").val(searchTerm);
|
||||
searchQuery(searchTerm);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,527 @@
|
||||
.main-content {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.dark {
|
||||
background: rgb(20, 20, 25);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.dark a {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.dark a:hover {
|
||||
color: rgb(200, 200, 200);
|
||||
}
|
||||
|
||||
.dark blockquote {
|
||||
border-left: 3px solid rgb(126, 126, 129);
|
||||
}
|
||||
|
||||
.dark blockquote small {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.dark blockquote small:before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* #nav { */
|
||||
/* float: left; */
|
||||
/* width: 250px; */
|
||||
/* background: green; */
|
||||
/* } */
|
||||
/*#content .header { position:absolute; background:rgba(255,255,255,0.9); left:250px; right:15px; padding:0px 12px; border-bottom:1px solid #EEE;}*/
|
||||
/*#content .body { padding-top:80px;}*/
|
||||
.nav-list {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.nav-list>li>a,
|
||||
.nav-list .nav-header {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.nav-list>li>a.treeLink {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.nav-list a {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 14px;
|
||||
text-shadow: none !important;
|
||||
}
|
||||
|
||||
.nav-list>.active>a.treeLink,
|
||||
.nav-list>.active>a.treeLink:hover,
|
||||
.nav-list>.active>a.treeLink:focus {
|
||||
background: #999;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.nav>li>a.selected,
|
||||
.nav>li>a:hover {
|
||||
background-color: #00000010;
|
||||
}
|
||||
|
||||
.nav-list li i.fa {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
color: rgb(200, 200, 200);
|
||||
font-weight: normal;
|
||||
font-size: 16px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.viewsource {
|
||||
float: right
|
||||
}
|
||||
|
||||
/** Footer sitemap **/
|
||||
footer {
|
||||
font-size: 14px;
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.section.site-footer {
|
||||
border-bottom: 0px;
|
||||
}
|
||||
|
||||
.copyright {
|
||||
padding: 6px;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
margin: 40px 0;
|
||||
}
|
||||
|
||||
.dark .copyright a {
|
||||
color: #F48821;
|
||||
}
|
||||
|
||||
/* .doc { margin-top:16px; } */
|
||||
.toggle-hide {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.toggle-show {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.toggle-on .toggle-hide {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.toggle-on .toggle-show {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.related-types .toggle-hide {
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
/* #nav li { list-style-type: none; } */
|
||||
#nav .expando>ul {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#nav .expando.expanded>ul {
|
||||
display: inherit;
|
||||
}
|
||||
|
||||
/* #nav ul, #nav li li { margin-left: 10px; } */
|
||||
#nav img {
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
#nav .pack {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* .nav .nav li { margin-left: 14px; } */
|
||||
|
||||
.dropdown {
|
||||
padding: 0 9px;
|
||||
}
|
||||
|
||||
#nav.searching .expando>ul {
|
||||
display: inherit;
|
||||
}
|
||||
|
||||
#nav.searching .expando>a {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#nav.searching ul {
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
#nav.searching .pack {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#nav.searching .nav-list .nav-list {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.nav-header {
|
||||
text-transform: none;
|
||||
font-size: 14px;
|
||||
color: #555;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.availability {
|
||||
color: #e48931;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
.section-availability {
|
||||
color: #e48931;
|
||||
}
|
||||
|
||||
h3 code {
|
||||
background: none;
|
||||
box-shadow: 0 0 15px rgb(240, 240, 240);
|
||||
padding: 4px 8px;
|
||||
white-space: inherit;
|
||||
display: inline-block;
|
||||
line-height: 1.5em;
|
||||
margin-left: -10px;
|
||||
}
|
||||
|
||||
h3 span.label,
|
||||
.label-meta {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.label.label-meta {
|
||||
background: #5959AC;
|
||||
}
|
||||
|
||||
/* only show some specific whitelisted metadata */
|
||||
|
||||
.label-meta {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.label-meta-callable,
|
||||
.label-meta-commutative,
|
||||
.label-meta-op,
|
||||
.label-meta-arrayAccess,
|
||||
.label-meta-resolve,
|
||||
.label-meta-to,
|
||||
.label-meta-from,
|
||||
.label-meta-using,
|
||||
.label-meta-forward,
|
||||
.label-meta-forwardStatics {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.alert.alert-deprecated {
|
||||
font-size: 90%;
|
||||
margin-bottom: 10px;
|
||||
padding: 4px 35px 4px 14px;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
|
||||
font-weight: normal;
|
||||
color: #666;
|
||||
background-color: #f7f7f9;
|
||||
border: 1px solid #e1e1e8;
|
||||
white-space: nowrap;
|
||||
border-radius: 3px;
|
||||
padding: 2px 4px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
code .identifier {
|
||||
font-family: bold 14px "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
color: #002b36;
|
||||
padding: 0 0 0 5px;
|
||||
}
|
||||
|
||||
code .identifier,
|
||||
code.type {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* code { background:#FDF6E3; color:#002b36; tab-size:4; } [> light <] */
|
||||
code a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
code a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/*code.dark { background:#272822; color:#F8F8F2; border:none; } */
|
||||
code .type {
|
||||
color: #268bd2;
|
||||
}
|
||||
|
||||
/* code .keyword { color:#dc322f; } */
|
||||
/* code .directive { color:#2aa198; } */
|
||||
/* code .constant { color:#AE81FF; } */
|
||||
/* code .comment { color:#75715E; } */
|
||||
/* code .string { color:#E6DB74; } */
|
||||
/* code .macro { color:#A6E22A; } */
|
||||
/* code .inactive { color:#75715E; } */
|
||||
|
||||
/* .navbar-fixed-top { position: fixed; } */
|
||||
/* .navbar-fixed-top .navbar-inner, */
|
||||
/* .navbar-fixed-bottom .navbar-inner { padding: 0; } */
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
font-size: 16px;
|
||||
font-family: "Open Sans", sans-serif;
|
||||
color: #1e1e1e;
|
||||
line-height: 1.5;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-family: "Source Sans Pro", sans-serif;
|
||||
font-weight: 600;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 36px;
|
||||
color: #171717;
|
||||
}
|
||||
|
||||
h1 small {
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
h5,
|
||||
h5 code {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.sidebar-nav {
|
||||
padding: 9px 0;
|
||||
}
|
||||
|
||||
#explorer {
|
||||
max-height: 70vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#searchForm {
|
||||
padding: 0 9px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#searchForm .control-group {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.indent {
|
||||
margin-left: 20px;
|
||||
border-left: 5px solid #eeeeee;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
table.params {
|
||||
border-left: 5px solid #eeeeee;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
table.params th {
|
||||
background: #fcfcfc;
|
||||
}
|
||||
|
||||
.doc-main {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.section {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.table p {
|
||||
margin: 3px 0;
|
||||
}
|
||||
|
||||
.table th,
|
||||
.table td {
|
||||
border-top: 0;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.table a small {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.table .fa {
|
||||
color: rgb(200, 200, 200);
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.javadoc {
|
||||
/* font-weight: normal; */
|
||||
/* font-size: small; */
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.inline-content * {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stuff for input-block-level:
|
||||
* http://stackoverflow.com/questions/13306670/bootstrap-prepended-and-appended-input-how-to-max-input-field-width
|
||||
*/
|
||||
.input-append.input-block-level,
|
||||
.input-prepend.input-block-level {
|
||||
display: table;
|
||||
}
|
||||
|
||||
.input-append.input-block-level .add-on,
|
||||
.input-prepend.input-block-level .add-on {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.input-append.input-block-level>input,
|
||||
.input-prepend.input-block-level>input {
|
||||
box-sizing: border-box;
|
||||
/* use bootstrap mixin or include vendor variants */
|
||||
-moz-box-sizing: border-box;
|
||||
/* for Firefox */
|
||||
-webkit-box-sizing: border-box;
|
||||
/* for Firefox */
|
||||
-ms-box-sizing: border-box;
|
||||
/* for Firefox */
|
||||
-o-box-sizing: border-box;
|
||||
/* for Firefox */
|
||||
display: table;
|
||||
/* table-cell is not working well in Chrome for small widths */
|
||||
min-height: inherit;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.input-append.input-block-level>input {
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
.input-prepend.input-block-level>input {
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.field {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.field+.field {
|
||||
border-top: 1px solid #eee;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.fields {
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
.field-source {
|
||||
margin-top: 15px;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.field:hover .field-source {
|
||||
visibility: inherit;
|
||||
}
|
||||
|
||||
pre.example {
|
||||
position: relative;
|
||||
padding-top: 34.5px;
|
||||
}
|
||||
|
||||
pre.example:before {
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
|
||||
content: "Example";
|
||||
color: #999;
|
||||
padding: 2px 6px;
|
||||
background: #fff;
|
||||
font-weight: bold;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
|
||||
-moz-border-radius: 4px 0;
|
||||
-ms-border-radius: 4px 0;
|
||||
-webkit-border-radius: 4px 0;
|
||||
border-radius: 4px 0;
|
||||
border: 1px solid rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.inherited-fields {
|
||||
padding: 5px 20px;
|
||||
margin-top: 1em;
|
||||
background: #fcfcfc;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
|
||||
.navbar-fixed-top,
|
||||
.navbar-fixed-bottom,
|
||||
.navbar-static-top {
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.navbar .divider {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
margin-top: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 979px) {
|
||||
.main-content {
|
||||
margin-top: 15px;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
@@ -0,0 +1,12 @@
|
||||
::use 'main.mtt'::
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(errorSearch);
|
||||
</script>
|
||||
|
||||
<h1><small>404</small> Page not found</h1>
|
||||
|
||||
<p>Page not found, sorry.</p>
|
||||
|
||||
::end::
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
::use 'main.mtt'::
|
||||
<div class="page-header">
|
||||
<span ::cond api.hasSourceLink(type):: class="viewsource">
|
||||
<a href="::api.getSourceLink(type)::" class="btn btn-medium"><i class="fa fa-eye"></i> View source</a>
|
||||
</span>
|
||||
<h1><small>::if api.isEnumAbstract(type)::enum ::end::abstract</small> ::api.getPathName(type.path)::$$printTypeParams(::type.params::)::if !api.isCoreType(type)::($$printLinkedType(::type.athis::,::false::))::end::</h1>
|
||||
$$printPackage(::type::)
|
||||
<h4 ::cond (type.from != null || type.to != null)::>
|
||||
::foreach t type.from::
|
||||
::if t.field == null::
|
||||
<small>::if(repeat.t.index==0)::from ::end::$$printLinkedType(::t.t::,::false::)::if((type.from.length!=1)&&(repeat.t.index<type.from.length-1))::, ::end::</small>
|
||||
::end::
|
||||
::end::
|
||||
::foreach t type.to::
|
||||
::if t.field == null::
|
||||
<small>::if(repeat.t.index==0):: to ::end::$$printLinkedType(::t.t::,::false::)::if((type.to.length!=1)&&(repeat.t.index<type.to.length-1))::, ::end::</small>
|
||||
::end::
|
||||
::end::
|
||||
</h4>
|
||||
$$printModule(::type.module::)
|
||||
$$printMeta(::type::)
|
||||
$$printDeprecation(::type::)
|
||||
$$printPlatforms(::type.platforms::,::true::)
|
||||
</div>
|
||||
|
||||
<div class="body">
|
||||
<div class="doc doc-main" ::cond type.doc != null::>
|
||||
::raw type.doc::
|
||||
</div>
|
||||
|
||||
::if type.impl != null::
|
||||
$$printClassBody(::type.impl::)
|
||||
::end::
|
||||
</div>
|
||||
::end::
|
||||
@@ -0,0 +1,68 @@
|
||||
::use 'main.mtt'::
|
||||
<div class="page-header">
|
||||
<span ::cond api.hasSourceLink(type):: class="viewsource">
|
||||
<a href="::api.getSourceLink(type)::" class="btn btn-medium"><i class="fa fa-eye"></i> View source</a>
|
||||
</span>
|
||||
|
||||
<h1>
|
||||
<small>::if type.isFinal::final ::end::::if type.isInterface::interface::else::class::end::</small> ::api.getPathName(type.path)::$$printTypeParams(::type.params::)
|
||||
</h1>
|
||||
$$printPackage(::type::)
|
||||
::if type.superClass != null::
|
||||
<h4>
|
||||
::set inheritedFields = api.getInheritedFields(type)::
|
||||
<small>extends
|
||||
::if (inheritedFields.types.length>0)::
|
||||
::foreach t inheritedFields.types::
|
||||
$$printLinkedPath(::t.path::,::null::,::false::)::if ((inheritedFields.types.length!=1)&&(repeat.t.index<(inheritedFields.types.length-1))):: › ::end::
|
||||
::end::
|
||||
::else::
|
||||
$$printLinkedPath(::type.superClass.path::,::null::,::false::)
|
||||
::end::
|
||||
</small>
|
||||
</h4>
|
||||
::end::
|
||||
|
||||
<h4 ::cond (type.interfaces.length>0)::>
|
||||
<small>::if type.isInterface::extends::else::implements::end::
|
||||
::foreach i type.interfaces::
|
||||
$$printLinkedPath(::i.path::,::i.params::,::false::)::if ((type.interfaces.length!=1)&&(repeat.i.index<(type.interfaces.length-1)))::, ::end::
|
||||
::end::
|
||||
</small>
|
||||
</h4>
|
||||
|
||||
$$printModule(::type.module::)
|
||||
|
||||
<h4 ::cond subClasses !=null::>
|
||||
<small>
|
||||
::set title = "extended by "::
|
||||
::set infos = subClasses::
|
||||
::use "related_types.mtt"::::end::
|
||||
</small>
|
||||
</h4>
|
||||
<h4 ::cond implementors !=null::>
|
||||
<small>
|
||||
::if type.isInterface::
|
||||
::set title = "extended by "::
|
||||
::else::
|
||||
::set title = "implemented by "::
|
||||
::end::
|
||||
::set infos = implementors::
|
||||
::use "related_types.mtt"::::end::
|
||||
</small>
|
||||
</h4>
|
||||
|
||||
$$printMeta(::type::)
|
||||
$$printDeprecation(::type::)
|
||||
|
||||
$$printPlatforms(::type.platforms::,::true::)
|
||||
</div>
|
||||
<div class="body">
|
||||
<div class="doc doc-main" ::cond type.doc != null::>
|
||||
::raw type.doc::
|
||||
</div>
|
||||
$$printClassBody(::type::)
|
||||
|
||||
$$printInheritedFields(::type::)
|
||||
</div>
|
||||
::end::
|
||||
@@ -0,0 +1,27 @@
|
||||
::if (field.doc != null && field.doc != "<p></p>") || !field.isOverride::
|
||||
|
||||
<div class="field ::if (depth == 0 && api.isPlatform(name)) " platform platform-" + name else ""::">
|
||||
::if source_url != null && field.line != null::
|
||||
<a href="::source_url::#L::field.line::" class="field-source pull-right" target="_blank">
|
||||
<i class="fa fa-eye"></i> View source
|
||||
</a>
|
||||
::end::
|
||||
|
||||
<a ::attr name field.name::></a>
|
||||
|
||||
<h3 class="anchor">$$printFieldSignature(::field::,::isStatic::,::type::)</h3>
|
||||
::if field.overloads != null::
|
||||
::foreach field field.overloads::
|
||||
<h3 class="anchor">$$printFieldSignature(::field::,::isStatic::,::type::)</h3>
|
||||
::end::
|
||||
::end::
|
||||
|
||||
$$printDeprecation(::field::)
|
||||
$$printFieldPlatforms(::field::)
|
||||
|
||||
::if field.doc != null::
|
||||
<div class="doc">::raw field.doc::</div>
|
||||
::end::
|
||||
</div>
|
||||
|
||||
::end::
|
||||
@@ -0,0 +1,56 @@
|
||||
::if info.deprecated != null::
|
||||
<div class="alert inline-content">
|
||||
<strong>Deprecated</strong>: ::raw info.deprecated.doc::
|
||||
</div>
|
||||
::end::
|
||||
|
||||
::raw info.doc::
|
||||
|
||||
::if info.params.length > 0::
|
||||
<p class="javadoc">Parameters:</p>
|
||||
<table class="table table-bordered params">
|
||||
::foreach param info.params::
|
||||
<tr><th style="width:25%;"><code>::param.value::</code></th><td>::raw param.doc::</td></tr>
|
||||
::end::
|
||||
</table>
|
||||
::end::
|
||||
|
||||
::if info.returns != null::
|
||||
<p class="javadoc">Returns:</p>
|
||||
<div class="indent inline-content">
|
||||
::raw info.returns.doc::
|
||||
</div>
|
||||
::end::
|
||||
|
||||
::if info.throws.length > 0::
|
||||
<p class="javadoc">Throws:</p>
|
||||
<table class="table table-bordered params">
|
||||
::foreach throws info.throws::
|
||||
<tr class="indent"><th style="width:25%;"><code>::throws.value::</code></th><td>::raw throws.doc::</td></tr>
|
||||
::end::
|
||||
</table>
|
||||
::end::
|
||||
|
||||
::if info.events.length > 0::
|
||||
<p class="javadoc">Events:</p>
|
||||
<table class="table table-bordered params">
|
||||
::foreach event info.events::
|
||||
<tr class="indent"><th style="width:25%;"><code>::event.value::</code></th><td>::raw event.doc::</td></tr>
|
||||
::end::
|
||||
</table>
|
||||
::end::
|
||||
|
||||
::if info.since != null::
|
||||
<div class="javadoc inline-content">
|
||||
Available since ::raw info.since.doc::.
|
||||
</div>
|
||||
::end::
|
||||
|
||||
::if info.sees.length > 0::
|
||||
<p class="javadoc">See also:</p>
|
||||
<ul>
|
||||
::foreach see info.sees::
|
||||
<li><div class="inline-content">::raw see.doc::</div></li>
|
||||
::end::
|
||||
</ul>
|
||||
::end::
|
||||
@@ -0,0 +1,26 @@
|
||||
::use 'main.mtt'::
|
||||
<div class="page-header">
|
||||
<span ::cond api.hasSourceLink(type):: class="viewsource">
|
||||
<a href="::api.getSourceLink(type)::" class="btn btn-medium"><i class="fa fa-eye"></i> View source</a>
|
||||
</span>
|
||||
<h1><small>enum</small> ::api.getPathName(type.path)::$$printTypeParams(::type.params::)</h1>
|
||||
$$printPackage(::type::)
|
||||
$$printModule(::type.module::)
|
||||
$$printMeta(::type::)
|
||||
$$printDeprecation(::type::)
|
||||
$$printPlatforms(::type.platforms::,::true::)
|
||||
</div>
|
||||
<div class="body">
|
||||
<div class="doc doc-main" ::cond type.doc != null::>
|
||||
::raw type.doc::
|
||||
</div>
|
||||
::if type.constructors.length > 0::
|
||||
<h3 class="section">Values</h3>
|
||||
<div class="fields">
|
||||
::foreach ctor type.constructors::
|
||||
::use "enum_field.mtt"::::end::
|
||||
::end::
|
||||
</div>
|
||||
::end::
|
||||
</div>
|
||||
::end::
|
||||
@@ -0,0 +1,19 @@
|
||||
<div class="field">
|
||||
|
||||
<h3>
|
||||
<code>
|
||||
<a name="::ctor.name::" href="#::ctor.name::">
|
||||
<span class="identifier">::ctor.name::</span>
|
||||
</a>
|
||||
::if ctor.args != null::
|
||||
(::foreach arg ctor.args::::arg.name:::$$printLinkedType(::arg.t::,::false::)::if !repeat.arg.last::, ::end::::end::)
|
||||
::end::
|
||||
</code>
|
||||
</h3>
|
||||
$$printDeprecation(::ctor::)
|
||||
$$printFieldPlatforms(::ctor::)
|
||||
|
||||
<div class="doc" ::cond ctor.doc != null::>
|
||||
::raw ctor.doc::
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<footer class="section site-footer" style="background:$$getHexValue(::themeColor::)">
|
||||
<div class="container">
|
||||
<div class="copyright">
|
||||
<p ::cond api.isDefined("version")::>This documentation is generated for version ::api.getValue('version')::</p>
|
||||
<p>© ::api.config.date.getFullYear()::
|
||||
<a ::cond api.isDefined("website"):: ::attr href api.getValue("website")::>The Funkin' Crew Inc</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
@@ -0,0 +1,36 @@
|
||||
<head>
|
||||
<meta charset='utf-8'/>
|
||||
<link href="::api.config.rootPath::bootstrap/css/bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="::api.config.rootPath::bootstrap/css/bootstrap-responsive.min.css" rel="stylesheet" />
|
||||
<link href="::api.config.rootPath::bootstrap/css/bootstrap-select.min.css" rel="stylesheet" />
|
||||
|
||||
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700,700italic,400italic' rel='stylesheet' type='text/css'/>
|
||||
<link href='https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,600,600italic,400' rel='stylesheet' type='text/css'/>
|
||||
<link href='https://netdna.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.css' rel='stylesheet' type='text/css' />
|
||||
|
||||
<script src="::api.config.rootPath::jquery-3.6.0.min.js"></script>
|
||||
<script src="::api.config.rootPath::bootstrap/js/bootstrap.min.js"></script>
|
||||
<script src="::api.config.rootPath::bootstrap/js/bootstrap-select.min.js"></script>
|
||||
<link href="::api.config.rootPath::styles.css" rel="stylesheet" />
|
||||
<link href="::api.config.rootPath::extra-styles.css" rel="stylesheet" />
|
||||
<link href="::api.config.rootPath::haxe-nav.css" rel="stylesheet" />
|
||||
<link href="::api.config.rootPath::dark-mode.css" rel="stylesheet" />
|
||||
<script>var dox = {
|
||||
rootPath: "::api.config.rootPath::",
|
||||
platforms: [
|
||||
::foreach pf api.config.platforms::
|
||||
"::pf::"
|
||||
::if !repeat.pf.last::,::end::
|
||||
::end::
|
||||
]
|
||||
};</script>
|
||||
<script src="::api.config.rootPath::nav.js"></script>
|
||||
<script src="::api.config.rootPath::index.js"></script>
|
||||
<link rel="icon" href="https://funkin.me/img/construction-icon.ico" type="image/x-icon"/>
|
||||
<title>::api.currentPageName::::if api.config.pageTitle !=null:: - ::api.config.pageTitle::::end::</title>
|
||||
|
||||
::set description = api.getShortDesc(type)::
|
||||
::set description = description.substr(3, description.length-7)::
|
||||
<meta name="description" ::cond type.doc!=null && description.length>0:: content="::description::"/>
|
||||
::use "extra-headers.mtt"::::end::
|
||||
</head>
|
||||
@@ -0,0 +1,336 @@
|
||||
<macro name="printTypeParams(params)">
|
||||
::if params.length > 0::
|
||||
<
|
||||
::foreach param params::
|
||||
<span class="type">::param::</span>
|
||||
::if !repeat.param.last::, ::end::
|
||||
::end::
|
||||
>
|
||||
::end::
|
||||
</macro>
|
||||
|
||||
<macro name="getHexValue(value)">::value.split("0x").join("#")::</macro>
|
||||
|
||||
<macro name="printPlatforms(platforms, useSeparator)">
|
||||
::if (useSeparator && api.config.platforms.length>1)::<hr/>::end::
|
||||
<p class="availability" ::cond (api.config.platforms.length>1)::>
|
||||
<em>
|
||||
Available on
|
||||
::if platforms.length == api.config.platforms.length:: all platforms
|
||||
::elseif platforms.length > 1:: ::platforms.join(", ")::
|
||||
::else:: ::platforms.join("")::
|
||||
::end::
|
||||
</em>
|
||||
</p>
|
||||
</macro>
|
||||
|
||||
<macro name="printFieldPlatforms(field)">
|
||||
::if field.platforms.length != type.platforms.length && field.platforms.length > 0 && field.platforms.length < api.config.platforms.length::
|
||||
$$printPlatforms(::field.platforms::,::false::)
|
||||
::end::
|
||||
</macro>
|
||||
|
||||
<macro name="printLinkedPath(path, params, qualified)">
|
||||
::if api.isKnownType(path)::
|
||||
<a class="type" title="::api.getSentenceDesc(api.resolveType(path))::" ::attr href api.pathToUrl(path)::>
|
||||
::if qualified::
|
||||
::path::
|
||||
::else::
|
||||
::api.getPathName(path)::
|
||||
::end::
|
||||
</a>
|
||||
::else::
|
||||
<span class="type">::api.getPathName(path)::</span>
|
||||
::end::
|
||||
::if params != null && params.length > 0::
|
||||
<
|
||||
::foreach param params::
|
||||
$$printLinkedType(::param::,::qualified::)
|
||||
::if !repeat.param.last::, ::end::
|
||||
::end::
|
||||
>
|
||||
::end::
|
||||
</macro>
|
||||
|
||||
<macro name="printLinkedType(ctype, qualified)">
|
||||
::switch ctype::
|
||||
::case::Unknown
|
||||
::case::$$printLinkedPath(::args[0]::,::args[1]::,::qualified::)
|
||||
::case::$$printLinkedPath(::args[0]::,::args[1]::,::qualified::)
|
||||
::case::$$printLinkedPath(::args[0]::,::args[1]::,::qualified::)
|
||||
::case::
|
||||
::if args[0].length != 1 || args[0][0].name != ""::(::end::
|
||||
::foreach arg args[0]::
|
||||
::if arg.name != ""::
|
||||
::arg.name:::
|
||||
::end::
|
||||
$$printLinkedType(::arg.t::,::qualified::)
|
||||
::if !repeat.arg.last::, ::end::
|
||||
::end::
|
||||
::if args[0].length != 1 || args[0][0].name != ""::)::end::
|
||||
‑>
|
||||
$$printLinkedType(::args[1]::,::qualified::)
|
||||
::case::
|
||||
{
|
||||
::foreach field args[0]::
|
||||
::field.name:::$$printLinkedType(::field.type::,::qualified::)
|
||||
::if !repeat.field.last::, ::end::
|
||||
::end::
|
||||
}
|
||||
::case::$$printLinkedPath(::"Dynamic"::,::null::,::qualified::)::if args[0] != null::<$$printLinkedType(::args[0]::,::qualified::)>::end::
|
||||
::case::$$printLinkedPath(::args[0]::,::args[1]::,::qualified::)
|
||||
::end::
|
||||
</macro>
|
||||
|
||||
<macro name="printModule(module)">
|
||||
<h4 ::cond module != null && module != "StdTypes"::><small>import <a ::attr href api.pathToUrl(module)::>::module::</a></small></h4>
|
||||
</macro>
|
||||
|
||||
<macro name="printDeprecation(field)">
|
||||
::if (field.meta != null)::
|
||||
::foreach meta field.meta::
|
||||
::if (meta.name == ":deprecated")::
|
||||
<div class="alert alert-warning alert-deprecated">
|
||||
<strong>Deprecated:</strong>
|
||||
::if (meta.params != null && meta.params.length > 0)::
|
||||
::foreach param meta.params::
|
||||
::param::
|
||||
::if !repeat.param.last::, ::end::
|
||||
::end::
|
||||
::end::
|
||||
</div>
|
||||
::end::
|
||||
::end::
|
||||
::end::
|
||||
</macro>
|
||||
|
||||
<macro name="printMeta(field)">
|
||||
::if (field.meta != null)::
|
||||
::foreach meta field.meta::
|
||||
::if (meta.name != ":deprecated")::::if false::<!--skip deprecation meta, see printDeprecation -->::end::
|
||||
::set metaName = meta.name.substr(1)::
|
||||
::set displayMetaName = "@" + meta.name::
|
||||
<span class="label label-meta label-meta-::metaName::" title="::api.getMetaDesc(meta.name)::">::displayMetaName::
|
||||
::if (meta.params != null && meta.params.length > 0)::(
|
||||
::foreach param meta.params::
|
||||
$$printMetaParam(::param::)
|
||||
::if !repeat.param.last::,::end::
|
||||
::end::
|
||||
)::end::</span>
|
||||
::end::
|
||||
::end::
|
||||
::end::
|
||||
</macro>
|
||||
|
||||
<macro name="printMetaParam(param)">::if (param.substr(0,9) == "<![CDATA[")::::param.substr(9,param.length-3-9)::::else::::param::::end::</macro>
|
||||
|
||||
<macro name="printFieldSignature(field, isStatic, type)">
|
||||
<code>
|
||||
::if !field.isPublic::
|
||||
<span class="label label-private">private</span>
|
||||
::end::
|
||||
|
||||
$$printMeta(::field::)
|
||||
|
||||
::if isStatic::
|
||||
<span class="label label-static">static</span>
|
||||
::end::
|
||||
|
||||
::set fieldInfo = api.getFieldInfo(field)::
|
||||
|
||||
::if fieldInfo.modifiers.isOptional::
|
||||
<span class="label label-optional">optional</span>
|
||||
::end::
|
||||
|
||||
::if fieldInfo.modifiers.isFinal::
|
||||
<span class="label label-final">final</span>
|
||||
::end::
|
||||
|
||||
::if fieldInfo.modifiers.isDynamic::
|
||||
<span class="label label-dynamic">dynamic</span>
|
||||
::end::
|
||||
|
||||
::if fieldInfo.modifiers.isInline::
|
||||
<span class="label label-inline">inline</span>
|
||||
::end::
|
||||
|
||||
::switch fieldInfo.kind::
|
||||
::switch field.set::
|
||||
::case 1::
|
||||
<span class="label">read only</span>
|
||||
::end::
|
||||
::switch field.get::
|
||||
::case 1::
|
||||
<span class="label">write only</span>
|
||||
::end::
|
||||
|
||||
<a href="#::field.name::"><span class="identifier">::field.name::</span></a>:$$printLinkedType(::field.type::,::false::)$$printInitExpr(::field.expr::)
|
||||
|
||||
::case 2::
|
||||
<a href="#::field.name::"><span class="identifier">::field.name::</span></a>
|
||||
$$printTypeParams(::field.params::)(
|
||||
::foreach arg args[0]::
|
||||
<span style="white-space:nowrap">
|
||||
::if arg.opt && (arg.value == null || arg.value == "null")::?::end::
|
||||
::arg.name:::$$printLinkedType(::arg.t::,::false::)
|
||||
::if arg.value != null && arg.value != "null":: = ::arg.value::::end::
|
||||
::if !repeat.arg.last::,::end::
|
||||
</span>
|
||||
::if !repeat.arg.last:: ::end::
|
||||
::end::
|
||||
)
|
||||
::if field.name != "new"::
|
||||
:$$printLinkedType(::args[1]::,::false::)
|
||||
::end::
|
||||
::end::
|
||||
</code>
|
||||
</macro>
|
||||
|
||||
<macro name="printInitExpr(expr)">
|
||||
<span ::cond expr != null::>
|
||||
= ::expr::
|
||||
</span>
|
||||
</macro>
|
||||
|
||||
<macro name="printClassBody(type)">
|
||||
::set showSection = false::
|
||||
::foreach field type.statics::
|
||||
::if !api.isMethod(field)::
|
||||
::eval showSection = true::
|
||||
::end::
|
||||
::end::
|
||||
::if showSection::
|
||||
<h3 class="section">Static variables</h3>
|
||||
<div class="fields">
|
||||
::foreach field type.statics::
|
||||
::set isStatic = true::
|
||||
::if !api.isMethod(field)::
|
||||
::use "class_field.mtt"::::end::
|
||||
::end::
|
||||
::end::
|
||||
</div>
|
||||
::end::
|
||||
|
||||
::set showSection = false::
|
||||
::foreach field type.statics::
|
||||
::if api.isMethod(field)::
|
||||
::eval showSection = true::
|
||||
::end::
|
||||
::end::
|
||||
::if showSection::
|
||||
<h3 class="section">Static methods</h3>
|
||||
<div class="fields">
|
||||
::foreach field type.statics::
|
||||
::set isStatic = true::
|
||||
::if api.isMethod(field)::
|
||||
::use "class_field.mtt"::::end::
|
||||
::end::
|
||||
::end::
|
||||
</div>
|
||||
::end::
|
||||
|
||||
::set showSection = false::
|
||||
::foreach field type.fields::
|
||||
::if field.name == "new" && api.isMethod(field)::
|
||||
::eval showSection = true::
|
||||
::end::
|
||||
::end::
|
||||
::if showSection::
|
||||
<h3 class="section">Constructor</h3>
|
||||
<div class="fields">
|
||||
::foreach field type.fields::
|
||||
::set isStatic = false::
|
||||
::if field.name == "new" && api.isMethod(field)::
|
||||
::use "class_field.mtt"::::end::
|
||||
::end::
|
||||
::end::
|
||||
</div>
|
||||
::end::
|
||||
|
||||
::set showSection = false::
|
||||
::foreach field type.fields::
|
||||
::if !api.isMethod(field)::
|
||||
::eval showSection = true::
|
||||
::end::
|
||||
::end::
|
||||
::if showSection::
|
||||
<h3 class="section">Variables</h3>
|
||||
<div class="fields">
|
||||
::foreach field type.fields::
|
||||
::set isStatic = false::
|
||||
::if !api.isMethod(field)::
|
||||
::use "class_field.mtt"::::end::
|
||||
::end::
|
||||
::end::
|
||||
</div>
|
||||
::end::
|
||||
|
||||
::set showSection = false::
|
||||
::foreach field type.fields::
|
||||
::if field.name != "new" && api.isMethod(field)::
|
||||
::eval showSection = true::
|
||||
::end::
|
||||
::end::
|
||||
::if showSection::
|
||||
<h3 class="section">Methods</h3>
|
||||
<div class="fields">
|
||||
::foreach field type.fields::
|
||||
::set isStatic = false::
|
||||
::if field.name != "new" && api.isMethod(field)::
|
||||
::use "class_field.mtt"::::end::
|
||||
::end::
|
||||
::end::
|
||||
</div>
|
||||
::end::
|
||||
</macro>
|
||||
|
||||
<macro name="printInheritedFields(type)">
|
||||
::if type.superClass != null::
|
||||
::set inheritedFields = api.getInheritedFields(type)::
|
||||
::set hasFields = inheritedFields.fields.keys().hasNext()::
|
||||
::set hasMethods = inheritedFields.methods.keys().hasNext()::
|
||||
|
||||
<div class="inherited-fields well" ::cond hasFields || hasMethods::>
|
||||
<h3 class="section" ::cond hasFields::>Inherited Variables</h3>
|
||||
<div class="fields" ::cond hasFields::>
|
||||
::set fields=inheritedFields.fields::
|
||||
::foreach cl inheritedFields.types::
|
||||
<h4 ::cond fields.get(cl).length>0::><a href="#" class="expand-button"><i class="fa fa-arrow-circle-o-right"></i></a> Defined by $$printLinkedPath(::cl.path::,::null::,::false::)</h4>
|
||||
<div style="display:none">
|
||||
::foreach field fields.get(cl)::
|
||||
::set isStatic = false::
|
||||
::set type=cl::
|
||||
::use "class_field.mtt"::::end::
|
||||
::end::
|
||||
</div>
|
||||
::end::
|
||||
</div>
|
||||
|
||||
<h3 class="section" ::cond hasMethods::>Inherited Methods</h3>
|
||||
<div class="fields" ::cond hasMethods::>
|
||||
::set fields=inheritedFields.methods::
|
||||
::foreach cl inheritedFields.types::
|
||||
<h4 ::cond fields.get(cl).length>0::><a href="#" class="expand-button"><i class="fa fa-arrow-circle-o-right"></i></a> Defined by $$printLinkedPath(::cl.path::,::null::,::false::)</h4>
|
||||
<div style="display:none">
|
||||
::foreach field fields.get(cl)::
|
||||
::set isStatic = false::
|
||||
::if field.name != "new" ::
|
||||
::set type=cl::
|
||||
::use "class_field.mtt"::::end::
|
||||
::end::
|
||||
::end::
|
||||
</div>
|
||||
::end::
|
||||
</div>
|
||||
</div>
|
||||
::end::
|
||||
</macro>
|
||||
|
||||
<macro name="printPackage(type)">
|
||||
::if type.path.indexOf(".", 0) >= 0::
|
||||
::set packagePath = type.path.split(".").slice(0, -1).join(".")::
|
||||
<h4><small>package <a ::attr href api.packageToUrl(packagePath)::>::packagePath::</a></small></h4>
|
||||
::else::
|
||||
<h4><small><a href="./">no package</a></small></h4>
|
||||
::end::
|
||||
</macro>
|
||||
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<!-- use theme color or fallback -->
|
||||
::set themeColor="0xFAFAFA"::
|
||||
::if (api.isDefined("themeColor"))::::set themeColor=api.getValue("themeColor")::::end::
|
||||
|
||||
<!--use textcolor from settings, otherwise create a contrasting color to theme color-->
|
||||
::set textColor="0xFFFFFF"::
|
||||
::if (api.isDefined("textColor"))::::set textColor=api.getValue("textColor")::
|
||||
::elseif (api.std.parseInt(themeColor) > 7829367)::::set textColor="0x000000"::::end::
|
||||
|
||||
::use "header.mtt"::::end::
|
||||
<body>
|
||||
<script>
|
||||
/* Here to prevent flash of unstyled content */
|
||||
let systemDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
if ((!localStorage.theme && systemDarkMode) || localStorage.theme == "dark") {
|
||||
document.body.style.backgroundColor = "#111";
|
||||
document.body.style.opacity = "0";
|
||||
document.addEventListener("DOMContentLoaded", function(event) {
|
||||
toggleTheme();
|
||||
document.body.style.backgroundColor = "";
|
||||
document.body.style.opacity = "";
|
||||
});
|
||||
}
|
||||
</script>
|
||||
::use "topbar.mtt"::::end::
|
||||
<div class="container main-content">
|
||||
<div class="row-fluid">
|
||||
<div class="span3">
|
||||
<div class="well sidebar-nav">
|
||||
<form class="form-search" id="searchForm">
|
||||
<div class="input-prepend input-block-level">
|
||||
<span class="add-on"><i class="fa fa-search"></i></span>
|
||||
<input id="search" type="text" placeholder="Filter (Ctrl+P)" autocomplete="off"/>
|
||||
</div>
|
||||
</form>
|
||||
<div class="dropdown" ::cond (api.config.platforms.length>1)::>
|
||||
<select id="select-platform" class="selectpicker" title="Filter by platform" data-width="100%">
|
||||
<option value="all" selected="selected">All Platforms</option>
|
||||
::foreach i api.config.platforms::
|
||||
<option>::i::</option>
|
||||
::end::
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="well sidebar-nav" id="explorer">
|
||||
<div id="nav"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="span9">::raw __content__::</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
::use "footer.mtt"::::end::
|
||||
|
||||
|
||||
<script src="::api.config.rootPath::highlighter.js"></script>
|
||||
<link href="::api.config.rootPath::highlighter.css" rel="stylesheet" />
|
||||
|
||||
::if (api.isDefined("googleAnalytics"))::
|
||||
::set trackingID=api.getValue("googleAnalytics")::
|
||||
<script async="async" src="https://www.googletagmanager.com/gtag/js?id=::trackingID::"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', '::trackingID::');
|
||||
</script>
|
||||
::end::
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,33 @@
|
||||
<macro name="makeTree(tree,depth)">
|
||||
::switch tree::
|
||||
<li ::attr data_path api.getTreePath(tree)::>
|
||||
::set pack = api.getTreePack(tree)::
|
||||
<a class="treeLink" href="::api.getTreeUrl(tree)::" title=":: pack + "." + api.getTreeName(tree) ::">
|
||||
::api.getTreeName(tree)::
|
||||
::if pack != ""::
|
||||
<span class="pack"> - ::pack::</span>
|
||||
::end::
|
||||
</a>
|
||||
</li>
|
||||
::case::
|
||||
::set name = args[0]::
|
||||
<li ::cond name.charAt(0) != "_"::
|
||||
::attr class "expando " + if (depth == 0 && api.isPlatform(name)) "platform platform-" + name else if (depth == 0) "package-" + name else "" ::>
|
||||
<a class="nav-header" href="#" onclick="return toggleCollapsed(this)">
|
||||
<i class="fa fa-folder"></i>
|
||||
::api.getTreeName(tree)::
|
||||
</a>
|
||||
<ul class="nav nav-list">
|
||||
::foreach sub args[2]::
|
||||
$$makeTree(::sub::,::depth + 1::)
|
||||
::end::
|
||||
</ul>
|
||||
</li>
|
||||
::end::
|
||||
</macro>
|
||||
var navContent='<ul class="nav nav-list">
|
||||
::foreach tree root::
|
||||
$$makeTree(::tree::,::0::)
|
||||
::end::
|
||||
</ul>
|
||||
';
|
||||
@@ -0,0 +1,37 @@
|
||||
::use 'main.mtt'::
|
||||
|
||||
::use 'package_description.mtt'::::end::
|
||||
|
||||
<table class="table table-condensed">
|
||||
<tbody>
|
||||
<tr ::cond full != ""::>
|
||||
<th style="width:200px;">
|
||||
<i class="fa fa-folder-o"></i>
|
||||
<a href="::api.packageToUrl(full.split(".").slice(0,-1).join("."))::" title="::full.split(".").slice(0,-1).join(".")::">..</a>
|
||||
</th>
|
||||
<td></td>
|
||||
</tr>
|
||||
::foreach tree subs::
|
||||
::set name = api.getTreeName(tree)::
|
||||
::set treeType = api.getTreeType(tree)::
|
||||
<tr class="::treeType::" ::cond name.charAt(0) != "_"::>
|
||||
::if (treeType=="package")::
|
||||
<td colspan="2">
|
||||
<i class="fa fa-folder-o"></i>
|
||||
<a href="::api.getTreeUrl(tree)::" title="::full::.::name::">::name::</a>
|
||||
</td>
|
||||
::else::
|
||||
<td style="width:200px;">
|
||||
<a href="::api.getTreeUrl(tree)::" title="::full::.::name::">::name::</a>
|
||||
</td>
|
||||
<td>
|
||||
::raw api.getTreeShortDesc(tree)::
|
||||
</td>
|
||||
::end::
|
||||
</tr>
|
||||
::end::
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
::end::
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
<h1>::api.currentPageName:: <small ::cond api.isDefined("version") && full == ""::>version ::api.getValue('version')::</small></h1>
|
||||
<p ::cond api.isDefined("description")::>::api.getValue("description")::</p>
|
||||
@@ -0,0 +1,4 @@
|
||||
<span class="muted">::title::</span>
|
||||
::foreach info infos::
|
||||
$$printLinkedPath(::info.path::,::null::,::false::)::if !repeat.info.last::, ::end::
|
||||
::end::
|
||||
@@ -0,0 +1,23 @@
|
||||
<style>
|
||||
::raw "
|
||||
.navbar .brand {
|
||||
display: inline-block;
|
||||
float: none;
|
||||
text-shadow: 0 0 0 transparent;
|
||||
}
|
||||
"::
|
||||
</style>
|
||||
<nav class="nav">
|
||||
<div class="navbar">
|
||||
<div class="navbar-inner" style="background:$$getHexValue(::themeColor::); border-bottom:1px solid rgba(0,0,0,.09)">
|
||||
<div class="container">
|
||||
<a href="https://funkin.me/" class="brand"><img alt="The Funkin' Crew Inc main website" src="https://funkin.me/img/api/funkin-api-export.svg" width="150" height="50"/></a>
|
||||
<a href="https://funkin.me/api-reference/" class="brand" style="color:$$getHexValue(::textColor::)">::if api.config.pageTitle!=null::::api.config.pageTitle::::else::API Documentation::end::</a>
|
||||
<div class="brand">
|
||||
<p>|</p>
|
||||
</div>
|
||||
<a href="https://funkin.me/cookbook/" class="brand" style="color:$$getHexValue(::textColor::)">Cookbook</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
@@ -0,0 +1,49 @@
|
||||
::use 'main.mtt'::
|
||||
<div class="page-header">
|
||||
<span ::cond api.hasSourceLink(type):: class="viewsource">
|
||||
<a href="::api.getSourceLink(type)::" class="btn btn-medium"><i class="fa fa-eye"></i> View source</a>
|
||||
</span>
|
||||
<h1><small>typedef</small> ::api.getPathName(type.path)::$$printTypeParams(::type.params::)</h1>
|
||||
$$printPackage(::type::)
|
||||
$$printModule(::type.module::)
|
||||
$$printMeta(::type::)
|
||||
$$printDeprecation(::type::)
|
||||
$$printPlatforms(::type.platforms::,::true::)
|
||||
</div>
|
||||
|
||||
<div class="body">
|
||||
<div class="doc doc-main" ::cond type.doc != null::>
|
||||
::raw type.doc::
|
||||
</div>
|
||||
|
||||
::set multiplePlatforms = api.lambda.array(type.types).length > 1::
|
||||
::foreach platform type.types.keys()::
|
||||
::set platformType = type.types.get(platform)::
|
||||
::if multiplePlatforms::
|
||||
<h4 class="section section-availability">::platform::</h4>
|
||||
::end::
|
||||
::switch platformType::
|
||||
::if !multiplePlatforms::<h3 class="section">Alias</h3>::end::
|
||||
<div class="fields">
|
||||
<div class="field">
|
||||
<em>alias for </em><code>$$printLinkedType(::platformType::,::true::)</code>
|
||||
</div>
|
||||
</div>
|
||||
::case 5::
|
||||
::if !multiplePlatforms::<h3 class="section">Fields</h3>::end::
|
||||
<div class="fields">
|
||||
::switch platformType::
|
||||
::case 5::
|
||||
::if args[0].length == 0::
|
||||
<em>empty structure</em>
|
||||
::else::
|
||||
::foreach field args[0]::
|
||||
::use "class_field.mtt"::::end::
|
||||
::end::
|
||||
::end::
|
||||
::end::
|
||||
</div>
|
||||
::end::
|
||||
::end::
|
||||
</div>
|
||||
::end::
|
||||
@@ -0,0 +1,42 @@
|
||||
cd ../..
|
||||
|
||||
# ask for version
|
||||
$version = Read-Host "Enter version (Will display on the website)"
|
||||
|
||||
# regenerate XML files?
|
||||
$regenerateXml = Read-Host "Regenerate XML files? (y/n)"
|
||||
|
||||
if ($regenerateXml -eq "y") {
|
||||
Write-Host "Regenerating XML files..."
|
||||
echo "Generating docs for version $version..."
|
||||
|
||||
lime build linux -xml -cpp --no-output -Ddoc-gen
|
||||
lime build windows -xml -cpp --no-output -Ddoc-gen
|
||||
|
||||
copy export\release\windows\types.xml docs\dox\Windows.xml
|
||||
copy export\release\linux\types.xml docs\dox\Linux.xml
|
||||
} else {
|
||||
Write-Host "Skipping XML regeneration..."
|
||||
}
|
||||
|
||||
# Then run dox
|
||||
haxelib run dox `
|
||||
-i .\docs\dox\ `
|
||||
-o docs/dox/output `
|
||||
--title "Funkin'" `
|
||||
-theme "docs/dox/funkin-theme" `
|
||||
-D version "$version" `
|
||||
-D source-path "https://github.com/FunkinCrew/Funkin/tree/main/source" `
|
||||
-D website "https://funkin.me/" `
|
||||
-D description "Friday Night Funkin' API Reference" `
|
||||
-in "funkin" `
|
||||
-in "openfl" `
|
||||
-in "lime" `
|
||||
-in "flixel" `
|
||||
-ex "funkin.ui.debug.*" `
|
||||
-ex "funkin.macro.*" `
|
||||
-ex "funkin.save.*" `
|
||||
-ex "funkin.api.*" `
|
||||
-ex "funkin.vis.*"
|
||||
|
||||
cd docs/dox
|
||||
@@ -0,0 +1,44 @@
|
||||
#!/bin/bash
|
||||
cd ../..
|
||||
|
||||
# ask for version
|
||||
read -p "Enter version (Will display on the website): " version
|
||||
|
||||
# regenerate XML files?
|
||||
read -p "Regenerate XML files? (y/n): " regenerateXml
|
||||
|
||||
if [ "$regenerateXml" == "y" ]; then
|
||||
echo "Regenerating XML files..."
|
||||
|
||||
echo "Generating docs for version $version..."
|
||||
|
||||
lime build windows -xml -cpp --no-output -Ddoc-gen
|
||||
lime build linux -xml -cpp --no-output -Ddoc-gen
|
||||
|
||||
cp export/release/linux/types.xml docs/dox/Linux.xml
|
||||
cp export/release/windows/types.xml docs/dox/Windows.xml
|
||||
else
|
||||
echo "Skipping XML regeneration..."
|
||||
fi
|
||||
|
||||
# Then run dox
|
||||
haxelib run dox \
|
||||
-i ./docs/dox/ \
|
||||
-o docs/dox/output \
|
||||
-theme "docs/dox/funkin-theme" \
|
||||
--title "Funkin'" \
|
||||
-D version "$version" \
|
||||
-D source-path "https://github.com/FunkinCrew/Funkin/tree/main/source" \
|
||||
-D website "https://funkin.me/" \
|
||||
-D description "Friday Night Funkin' API Reference" \
|
||||
-in "funkin" \
|
||||
-in "openfl" \
|
||||
-in "lime" \
|
||||
-in "flixel" \
|
||||
-ex "funkin.ui.debug.*" \
|
||||
-ex "funkin.macro.*" \
|
||||
-ex "funkin.save.*" \
|
||||
-ex "funkin.api.*" \
|
||||
-ex "funkin.vis.*"
|
||||
|
||||
cd docs/dox
|
||||
@@ -4,62 +4,73 @@
|
||||
"name": "FlxPartialSound",
|
||||
"type": "git",
|
||||
"dir": null,
|
||||
"ref": "2f984e244f1544ca98c0e03b9b21ae570f07ac55",
|
||||
"ref": "13a0949395250216b9b500ca0731b46841e46085",
|
||||
"url": "https://github.com/FunkinCrew/FlxPartialSound.git"
|
||||
},
|
||||
{
|
||||
"name": "astc-compressor",
|
||||
"type": "git",
|
||||
"dir": null,
|
||||
"ref": "b7a91b3072dc16e785a9bde847f17ba0ef15dd47",
|
||||
"ref": "6c0fa6f46d3547ca58859b6ede87e659018a7ff5",
|
||||
"url": "https://github.com/KarimAkra/astc-compressor"
|
||||
},
|
||||
{
|
||||
"name": "extension-admob",
|
||||
"type": "git",
|
||||
"dir": null,
|
||||
"ref": "5c908b3f7c74115a8b52eddf1e05525f4873f26e",
|
||||
"ref": "68fc73c4090c5765709597b68fbe87389f3548c0",
|
||||
"url": "https://github.com/FunkinCrew/extension-admob"
|
||||
},
|
||||
{
|
||||
"name": "extension-agesignals",
|
||||
"type": "git",
|
||||
"ref": "dd3f56ccbb313a43d40cba8826fca2b1ec7c7e5d",
|
||||
"url": "https://github.com/FunkinCrew/extension-agesignals"
|
||||
},
|
||||
{
|
||||
"name": "extension-androidtools",
|
||||
"type": "haxelib",
|
||||
"version": "2.2.2"
|
||||
},
|
||||
{
|
||||
"name": "extension-haptics",
|
||||
"name": "dox",
|
||||
"type": "haxelib",
|
||||
"version": "1.0.4"
|
||||
"version": "1.6.0"
|
||||
},
|
||||
{
|
||||
"name": "extension-haptics",
|
||||
"type": "git",
|
||||
"ref": "8978b34b437f943a0d164bd6b3d8b69bd0025081",
|
||||
"url": "https://github.com/LimeExtensions/extension-haptics"
|
||||
},
|
||||
{
|
||||
"name": "extension-iapcore",
|
||||
"type": "haxelib",
|
||||
"version": "1.0.4"
|
||||
"type": "git",
|
||||
"ref": "5fbb4a8e56ff0f4d8ffc71b561d57a367419ead8",
|
||||
"url": "https://github.com/LimeExtensions/extension-iapcore"
|
||||
},
|
||||
{
|
||||
"name": "extension-iarcore",
|
||||
"type": "haxelib",
|
||||
"version": "1.0.3"
|
||||
"type": "git",
|
||||
"ref": "a78e49fe69feecef9abcdbcfd08ccc510ed00c6c",
|
||||
"url": "https://github.com/LimeExtensions/extension-iarcore"
|
||||
},
|
||||
{
|
||||
"name": "extension-webviewcore",
|
||||
"type": "git",
|
||||
"dir": null,
|
||||
"ref": "d13109450d65c40678244ca23b1aa88ac18d77e6",
|
||||
"ref": "98c059722491b182ee932ff47c5d7b564c967165",
|
||||
"url": "https://github.com/LimeExtensions/extension-webviewcore"
|
||||
},
|
||||
{
|
||||
"name": "flixel",
|
||||
"type": "git",
|
||||
"dir": null,
|
||||
"ref": "f7b94eebf7dbb452a929d0c67ab31a9cbd71d3a0",
|
||||
"ref": "141f23c400c0508c76d5a09a143f5ce6790f8122",
|
||||
"url": "https://github.com/FunkinCrew/flixel"
|
||||
},
|
||||
{
|
||||
"name": "flixel-addons",
|
||||
"type": "git",
|
||||
"dir": null,
|
||||
"ref": "187f93b34f93c6a405d634a42913c745e443463a",
|
||||
"ref": "7628435364c4a45440d1e5db656741b66a8cd2ec",
|
||||
"url": "https://github.com/FunkinCrew/flixel-addons"
|
||||
},
|
||||
{
|
||||
@@ -72,7 +83,12 @@
|
||||
{
|
||||
"name": "format",
|
||||
"type": "haxelib",
|
||||
"version": "3.5.0"
|
||||
"version": "3.8.0"
|
||||
},
|
||||
{
|
||||
"name": "svg",
|
||||
"type": "haxelib",
|
||||
"version": "1.1.3"
|
||||
},
|
||||
{
|
||||
"name": "funkin.vis",
|
||||
@@ -88,6 +104,11 @@
|
||||
"ref": "6409f3c6d1b4c52176813d3ede86c0d34e8af2c1",
|
||||
"url": "https://github.com/FunkinCrew/grig.audio"
|
||||
},
|
||||
{
|
||||
"name": "tink_core",
|
||||
"type": "haxelib",
|
||||
"version": "1.26.0"
|
||||
},
|
||||
{
|
||||
"name": "hamcrest",
|
||||
"type": "haxelib",
|
||||
@@ -97,7 +118,7 @@
|
||||
"name": "haxeui-core",
|
||||
"type": "git",
|
||||
"dir": null,
|
||||
"ref": "09f2512564b45e92229e21433e6dd482391f7b7d",
|
||||
"ref": "998534fb830450ca1e60c47a9524af5730431145",
|
||||
"url": "https://github.com/FunkinCrew/haxeui-core"
|
||||
},
|
||||
{
|
||||
@@ -110,8 +131,7 @@
|
||||
{
|
||||
"name": "hxcpp",
|
||||
"type": "git",
|
||||
"dir": null,
|
||||
"ref": "450d112e50acff57b1bc9d584dcf1374c9e33995",
|
||||
"ref": "0376e9b19af9a4d91f9d9afc131a358467856a10",
|
||||
"url": "https://github.com/FunkinCrew/hxcpp"
|
||||
},
|
||||
{
|
||||
@@ -146,13 +166,13 @@
|
||||
{
|
||||
"name": "hxvlc",
|
||||
"type": "haxelib",
|
||||
"version": "2.2.6"
|
||||
"version": "2.3.0"
|
||||
},
|
||||
{
|
||||
"name": "json2object",
|
||||
"type": "git",
|
||||
"dir": null,
|
||||
"ref": "59e0467c953d1f26e3cbf2a070f140e2d2e8457d",
|
||||
"ref": "dc945d58c1239a6ab6e37e0a6c128387193c9af5",
|
||||
"url": "https://github.com/FunkinCrew/json2object"
|
||||
},
|
||||
{
|
||||
@@ -168,29 +188,27 @@
|
||||
{
|
||||
"name": "lime",
|
||||
"type": "git",
|
||||
"dir": null,
|
||||
"ref": "826d25199c17329b730ae09838f3df7a2903c471",
|
||||
"ref": "268dacfb2609766e14bef9ea5b669e91501852d2",
|
||||
"url": "https://github.com/FunkinCrew/lime"
|
||||
},
|
||||
{
|
||||
"name": "newgrounds",
|
||||
"type": "git",
|
||||
"dir": null,
|
||||
"ref": "b2b53cd0a5f030af74efd325732951cddbea8826",
|
||||
"ref": "60162762e6ca65da011ffee7a6617f547ea5dff9",
|
||||
"url": "https://github.com/FunkinCrew/Newgrounds"
|
||||
},
|
||||
{
|
||||
"name": "openfl",
|
||||
"type": "git",
|
||||
"dir": null,
|
||||
"ref": "88534506595a32c3f02b21b3987e789a24074ae7",
|
||||
"ref": "74a51908a116d6df74be1083e219abb9fa057636",
|
||||
"url": "https://github.com/FunkinCrew/openfl"
|
||||
},
|
||||
{
|
||||
"name": "polymod",
|
||||
"type": "git",
|
||||
"dir": null,
|
||||
"ref": "fb123758b90127f5647727727f273d27e93cabdb",
|
||||
"ref": "acfdc2e26722f20339a2bc0cc8cd7dd5fe0c6b5e",
|
||||
"url": "https://github.com/FunkinCrew/polymod"
|
||||
},
|
||||
{
|
||||
|
||||
+272
-19
@@ -18,8 +18,8 @@
|
||||
|
||||
"betweenTypes": 1,
|
||||
|
||||
"lineCommentsBetweenTypes": "keep",
|
||||
"lineCommentsBetweenFunctions": "keep",
|
||||
"lineCommentsBetweenTypes": "one",
|
||||
"lineCommentsBetweenFunctions": "one",
|
||||
|
||||
"betweenSingleLineTypes": 0,
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
"betweenVars": 0,
|
||||
"afterVars": 1,
|
||||
"betweenFunctions": 1,
|
||||
"existingBetweenFields": "keep"
|
||||
"existingBetweenFields": "remove"
|
||||
},
|
||||
|
||||
"classEmptyLines": {
|
||||
@@ -54,7 +54,7 @@
|
||||
"afterPrivateFunctions": 1,
|
||||
"betweenFunctions": 1,
|
||||
|
||||
"existingBetweenFields": "keep"
|
||||
"existingBetweenFields": "remove"
|
||||
},
|
||||
|
||||
"macroClassEmptyLines": {
|
||||
@@ -71,7 +71,7 @@
|
||||
"afterPrivateFunctions": 1,
|
||||
"betweenFunctions": 1,
|
||||
|
||||
"existingBetweenFields": "keep"
|
||||
"existingBetweenFields": "remove"
|
||||
},
|
||||
|
||||
"externClassEmptyLines": {
|
||||
@@ -81,7 +81,7 @@
|
||||
"betweenVars": 0,
|
||||
"afterVars": 0,
|
||||
"betweenFunctions": 0,
|
||||
"existingBetweenFields": "keep"
|
||||
"existingBetweenFields": "remove"
|
||||
},
|
||||
|
||||
"abstractEmptyLines": {
|
||||
@@ -98,7 +98,7 @@
|
||||
"afterPrivateFunctions": 1,
|
||||
"betweenFunctions": 1,
|
||||
|
||||
"existingBetweenFields": "keep"
|
||||
"existingBetweenFields": "remove"
|
||||
},
|
||||
|
||||
"interfaceEmptyLines": {
|
||||
@@ -108,7 +108,7 @@
|
||||
"betweenVars": 0,
|
||||
"afterVars": 0,
|
||||
"betweenFunctions": 0,
|
||||
"existingBetweenFields": "keep"
|
||||
"existingBetweenFields": "remove"
|
||||
},
|
||||
|
||||
"enumEmptyLines": {
|
||||
@@ -116,7 +116,7 @@
|
||||
"endType": 0,
|
||||
|
||||
"betweenFields": 0,
|
||||
"existingBetweenFields": "keep"
|
||||
"existingBetweenFields": "remove"
|
||||
},
|
||||
|
||||
"typedefEmptyLines": {
|
||||
@@ -124,7 +124,7 @@
|
||||
"endType": 0,
|
||||
|
||||
"betweenFields": 0,
|
||||
"existingBetweenFields": "keep"
|
||||
"existingBetweenFields": "remove"
|
||||
},
|
||||
|
||||
"conditionalsEmptyLines": {
|
||||
@@ -159,9 +159,9 @@
|
||||
"lineEnds": {
|
||||
"lineEndCharacter": "auto",
|
||||
|
||||
"metadataType": "none",
|
||||
"metadataVar": "none",
|
||||
"metadataFunction": "none",
|
||||
"metadataType": "after",
|
||||
"metadataVar": "forceAfterLast",
|
||||
"metadataFunction": "forceAfterLast",
|
||||
"metadataOther": "none",
|
||||
|
||||
"caseColon": "after",
|
||||
@@ -214,7 +214,7 @@
|
||||
"expressionIf": "same",
|
||||
"expressionIfWithBlocks": false,
|
||||
|
||||
"forBody": "next",
|
||||
"forBody": "same",
|
||||
|
||||
"comprehensionFor": "same",
|
||||
|
||||
@@ -229,7 +229,7 @@
|
||||
"tryCatch": "next",
|
||||
|
||||
"caseBody": "next",
|
||||
"expressionCase": "keep",
|
||||
"expressionCase": "next",
|
||||
"expressionTry": "same",
|
||||
|
||||
"functionBody": "same",
|
||||
@@ -241,9 +241,45 @@
|
||||
},
|
||||
|
||||
"whitespace": {
|
||||
"parenConfig": {},
|
||||
"parenConfig": {
|
||||
"metadataParens": {
|
||||
"openingPolicy": "none",
|
||||
"closingPolicy": "none",
|
||||
"removeInnerWhenEmpty": true
|
||||
}
|
||||
},
|
||||
|
||||
"bracesConfig": {},
|
||||
"bracketConfig": {},
|
||||
|
||||
"bracketConfig": {
|
||||
"arrayLiteralBrackets": {
|
||||
"openingPolicy": "noneAfter",
|
||||
"closingPolicy": "none",
|
||||
"removeInnerWhenEmpty": true
|
||||
},
|
||||
"mapLiteralBrackets": {
|
||||
"openingPolicy": "noneAfter",
|
||||
"closingPolicy": "none",
|
||||
"removeInnerWhenEmpty": true
|
||||
},
|
||||
|
||||
"accessBrackets": {
|
||||
"openingPolicy": "noneAfter",
|
||||
"closingPolicy": "none",
|
||||
"removeInnerWhenEmpty": true
|
||||
},
|
||||
"comprehensionBrackets": {
|
||||
"openingPolicy": "none",
|
||||
"closingPolicy": "none",
|
||||
"removeInnerWhenEmpty": true
|
||||
},
|
||||
|
||||
"unknownBrackets": {
|
||||
"openingPolicy": "noneAfter",
|
||||
"closingPolicy": "none",
|
||||
"removeInnerWhenEmpty": true
|
||||
}
|
||||
},
|
||||
|
||||
"typeParamOpenPolicy": "none",
|
||||
"typeParamClosePolicy": "none",
|
||||
@@ -280,20 +316,237 @@
|
||||
"wrapping": {
|
||||
"maxLineLength": 160,
|
||||
|
||||
"arrayMatrixWrap": "matrixWrapWithAlign",
|
||||
|
||||
"arrayWrap": {
|
||||
"defaultWrap": "noWrap",
|
||||
"defaultLocation": "afterLast",
|
||||
"defaultAdditionalIndent": 0,
|
||||
"rules": [
|
||||
{
|
||||
"type": "noWrap",
|
||||
"conditions": [
|
||||
{
|
||||
"cond": "itemCount <= n",
|
||||
"value": 1
|
||||
},
|
||||
{
|
||||
"cond": "totalItemLength <= n",
|
||||
"value": 160
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "onePerLine",
|
||||
"conditions": [
|
||||
{
|
||||
"cond": "anyItemLength >= n",
|
||||
"value": 32
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "onePerLine",
|
||||
"conditions": [
|
||||
{
|
||||
"cond": "itemCount >= n",
|
||||
"value": 5
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "onePerLine",
|
||||
"conditions": [
|
||||
{
|
||||
"cond": "hasMultilineItems",
|
||||
"value": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "onePerLine",
|
||||
"conditions": [
|
||||
{
|
||||
"cond": "totalItemLength >= n",
|
||||
"value": 160
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"mapWrap": {
|
||||
"defaultWrap": "noWrap",
|
||||
"defaultLocation": "afterLast",
|
||||
"defaultAdditionalIndent": 0,
|
||||
"rules": [
|
||||
{
|
||||
"type": "onePerLine",
|
||||
"conditions": [
|
||||
{
|
||||
"cond": "anyItemLength >= n",
|
||||
"value": 32
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "onePerLine",
|
||||
"conditions": [
|
||||
{
|
||||
"cond": "itemCount >= n",
|
||||
"value": 5
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "onePerLine",
|
||||
"conditions": [
|
||||
{
|
||||
"cond": "hasMultilineItems",
|
||||
"value": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "onePerLine",
|
||||
"conditions": [
|
||||
{
|
||||
"cond": "lineLength >= n",
|
||||
"value": 160
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"methodChain": {
|
||||
"defaultWrap": "noWrap",
|
||||
"defaultLocation": "afterLast",
|
||||
"defaultAdditionalIndent": 0,
|
||||
"rules": [
|
||||
{
|
||||
"additionalIndent": 0,
|
||||
"location": "afterLast",
|
||||
"type": "onePerLine",
|
||||
"conditions": [
|
||||
{
|
||||
"cond": "lineLength >= n",
|
||||
"value": 160
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"callParameter": {
|
||||
"defaultWrap": "noWrap",
|
||||
"defaultLocation": "afterLast",
|
||||
"defaultAdditionalIndent": 0,
|
||||
"rules": [
|
||||
{
|
||||
"additionalIndent": 0,
|
||||
"location": "afterLast",
|
||||
"type": "onePerLine",
|
||||
"conditions": [
|
||||
{
|
||||
"cond": "lineLength >= n",
|
||||
"value": 160
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"objectLiteral": {
|
||||
"defaultWrap": "onePerLine",
|
||||
"defaultLocation": "afterLast",
|
||||
"defaultAdditionalIndent": 0
|
||||
},
|
||||
|
||||
"opBoolChain": {
|
||||
"defaultWrap": "noWrap",
|
||||
"defaultLocation": "beforeLast",
|
||||
"defaultAdditionalIndent": 0,
|
||||
"rules": [
|
||||
{
|
||||
"additionalIndent": 0,
|
||||
"location": "beforeLast",
|
||||
"type": "onePerLine",
|
||||
"conditions": [
|
||||
{
|
||||
"cond": "lineLength >= n",
|
||||
"value": 160
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"opAddSubChain": {
|
||||
"defaultWrap": "noWrap",
|
||||
"defaultLocation": "beforeLast",
|
||||
"defaultAdditionalIndent": 0,
|
||||
"rules": [
|
||||
{
|
||||
"additionalIndent": 0,
|
||||
"location": "beforeLast",
|
||||
"type": "onePerLine",
|
||||
"conditions": [
|
||||
{
|
||||
"cond": "lineLength >= n",
|
||||
"value": 160
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"implementsExtends": {
|
||||
"defaultWrap": "noWrap",
|
||||
"defaultLocation": "afterLast",
|
||||
"defaultAdditionalIndent": 0
|
||||
},
|
||||
|
||||
"mapWrap": {
|
||||
"metadataCallParameter": {
|
||||
"defaultWrap": "noWrap",
|
||||
"defaultLocation": "afterLast",
|
||||
"defaultAdditionalIndent": 0
|
||||
},
|
||||
|
||||
"anonFunctionSignature": {
|
||||
"defaultWrap": "noWrap",
|
||||
"defaultLocation": "afterLast",
|
||||
"defaultAdditionalIndent": 0
|
||||
},
|
||||
|
||||
"anonType": {
|
||||
"defaultWrap": "noWrap",
|
||||
"defaultLocation": "afterLast",
|
||||
"defaultAdditionalIndent": 0
|
||||
},
|
||||
|
||||
"casePattern": {
|
||||
"defaultWrap": "noWrap",
|
||||
"defaultLocation": "afterLast",
|
||||
"defaultAdditionalIndent": 0
|
||||
},
|
||||
|
||||
"functionSignature": {
|
||||
"defaultWrap": "noWrap",
|
||||
"defaultLocation": "afterLast",
|
||||
"defaultAdditionalIndent": 0
|
||||
},
|
||||
|
||||
"multiVar": {
|
||||
"defaultWrap": "noWrap",
|
||||
"defaultLocation": "afterLast",
|
||||
"defaultAdditionalIndent": 0
|
||||
},
|
||||
|
||||
"typeParameter": {
|
||||
"defaultWrap": "noWrap"
|
||||
"defaultWrap": "noWrap",
|
||||
"defaultLocation": "afterLast",
|
||||
"defaultAdditionalIndent": 0
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
+115
-158
@@ -32,13 +32,13 @@ class Project extends HXProject
|
||||
* REMEMBER TO CHANGE THIS WHEN THE GAME UPDATES!
|
||||
* You only have to change it here, the rest of the game will query this value.
|
||||
*/
|
||||
static final VERSION:String = "0.8.5";
|
||||
static final VERSION:String = "0.8.7";
|
||||
|
||||
/**
|
||||
* The build's number and version code.
|
||||
* Used when publishing the game to mobile app stores. Should increment with each patch.
|
||||
*/
|
||||
static final BUILD_NUMBER:Int = 87;
|
||||
static final BUILD_NUMBER:Int = 102;
|
||||
|
||||
/**
|
||||
* The game's name. Used as the default window title.
|
||||
@@ -105,16 +105,13 @@ class Project extends HXProject
|
||||
//
|
||||
|
||||
/**
|
||||
* The app's minimal Android SDK version.
|
||||
* The app's lime Android java extensions.
|
||||
*/
|
||||
static final ANDROID_MINIMUM_SDK_VERSION:Int = 28;
|
||||
|
||||
/**
|
||||
* The app's target Android SDK version.
|
||||
*/
|
||||
static final ANDROID_TARGET_SDK_VERSION:Int = 35;
|
||||
|
||||
static final ANDROID_EXTENSIONS:Array<String> = ["funkin.extensions.CallbackUtil", "funkin.extensions.FNFCExtension", "funkin.extensions.AudioSession"];
|
||||
static final ANDROID_EXTENSIONS:Array<String> = [
|
||||
"funkin.extensions.CallbackUtil",
|
||||
"funkin.extensions.FNFCExtension",
|
||||
"funkin.extensions.AudioSession"
|
||||
];
|
||||
|
||||
/**
|
||||
* The team ID to use for the iOS app. Configured in XCode.
|
||||
@@ -384,10 +381,16 @@ class Project extends HXProject
|
||||
|
||||
/**
|
||||
* `-DFEATURE_MOBILE_WEBVIEW`
|
||||
* If this feature flag is enabled, the user may sometimes be prompted to review the app on their respective store.
|
||||
* If this feature flag is enabled, the game will be able to load WebViews, mainly needed for the Newgrounds impl.
|
||||
*/
|
||||
static final FEATURE_MOBILE_WEBVIEW:FeatureFlag = "FEATURE_MOBILE_WEBVIEW";
|
||||
|
||||
/**
|
||||
* `-DFEATURE_MOBILE_AGESIGNALS`
|
||||
* If this feature flag is enabled, the game will be able to use age singals.
|
||||
*/
|
||||
static final FEATURE_MOBILE_AGESIGNALS:FeatureFlag = "FEATURE_MOBILE_AGESIGNALS";
|
||||
|
||||
/**
|
||||
* `-DFEATURE_NAUGHTYNESS`
|
||||
* If this feature flag is enabled, naughtyness will be a toggleable option in the Options Menu.
|
||||
@@ -531,19 +534,34 @@ class Project extends HXProject
|
||||
{
|
||||
super();
|
||||
|
||||
#if !target.unicode
|
||||
if (isWindowsHost())
|
||||
{
|
||||
// Enable code page 65001 for unicode support
|
||||
Sys.command("chcp 65001 > nul");
|
||||
}
|
||||
#end
|
||||
|
||||
envConfig = readEnvironmentFile("./.env");
|
||||
|
||||
flair();
|
||||
|
||||
displayTarget();
|
||||
|
||||
configureApp();
|
||||
|
||||
displayTarget();
|
||||
configureOutputDir();
|
||||
|
||||
if (isRun() || isInstall())
|
||||
{
|
||||
// These commands dont really need much in order to run so to improve the speed, we return here.
|
||||
return;
|
||||
}
|
||||
|
||||
configureFeatureFlags();
|
||||
configureCompileDefines();
|
||||
configureIncludeMacros();
|
||||
configureCustomMacros();
|
||||
configureOutputDir();
|
||||
configurePolymod();
|
||||
configureHaxelibs();
|
||||
configureASTCTextures();
|
||||
@@ -574,7 +592,7 @@ class Project extends HXProject
|
||||
buildHxCppTools();
|
||||
}
|
||||
|
||||
if (!isDisplay())
|
||||
if (!(isDisplay() || isCleanCommand()))
|
||||
{
|
||||
checkLibraries();
|
||||
}
|
||||
@@ -603,11 +621,6 @@ class Project extends HXProject
|
||||
{
|
||||
this.meta.title = isMobile() ? TITLE_MOBILE : TITLE;
|
||||
|
||||
// ios uses this character code instead of spaces...
|
||||
// We don't have spaces in our title for mobile anymore
|
||||
// But keeping incase anybody source-modding ever does add spaces
|
||||
if (isIOS()) this.meta.title = ~/ /ig.replace(TITLE_MOBILE, "\u2002");
|
||||
|
||||
this.meta.version = VERSION;
|
||||
this.meta.packageName = PACKAGE_NAME;
|
||||
this.meta.company = COMPANY;
|
||||
@@ -633,17 +646,6 @@ class Project extends HXProject
|
||||
// Set the build number, required for publishing the game to mobile stores.
|
||||
this.meta.buildNumber = Std.string(BUILD_NUMBER);
|
||||
|
||||
// These values are only used by the SWF target I think.
|
||||
// this.app.path
|
||||
// this.app.init
|
||||
// this.app.swfVersion
|
||||
// this.app.url
|
||||
|
||||
// These values are only used by... FIREFOX MARKETPLACE WHAT?
|
||||
// this.meta.description = "";
|
||||
// this.meta.companyId = COMPANY;
|
||||
// this.meta.companyUrl = COMPANY;
|
||||
|
||||
// Configure the window.
|
||||
// Automatically configure FPS.
|
||||
this.window.fps = 60;
|
||||
@@ -688,8 +690,28 @@ class Project extends HXProject
|
||||
this.excludeArchitectures.push(Architecture.ARMV7);
|
||||
}
|
||||
|
||||
config.set("android.minimum-sdk-version", ANDROID_MINIMUM_SDK_VERSION);
|
||||
config.set("android.target-sdk-version", ANDROID_TARGET_SDK_VERSION);
|
||||
if (isRelease())
|
||||
{
|
||||
if (envConfig != null)
|
||||
{
|
||||
keystore = new Keystore();
|
||||
keystore.path = Std.string(envConfig.get('KEYSTORE_PATH'));
|
||||
keystore.alias = Std.string(envConfig.get('KEYSTORE_ALIAS'));
|
||||
keystore.password = Std.string(envConfig.get('KEYSTORE_PASSWORD'));
|
||||
}
|
||||
|
||||
if (isBundle())
|
||||
{
|
||||
config.set("android.gradle-project-directory", "bin-bundle");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isIOS())
|
||||
{
|
||||
config.set("ios.non-exempt-encryption", "false");
|
||||
config.set("ios.team-id", IOS_TEAM_ID);
|
||||
config.set("ios.deployment", "16.0");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -723,7 +745,6 @@ class Project extends HXProject
|
||||
// case Platform.PS3:
|
||||
// case Platform.PS4:
|
||||
// case Platform.TIZEN:
|
||||
// case Platform.TVOS:
|
||||
// case Platform.VITA:
|
||||
// case Platform.WEBOS:
|
||||
// case Platform.WIIU:
|
||||
@@ -735,42 +756,22 @@ class Project extends HXProject
|
||||
switch (this.platformType)
|
||||
{
|
||||
case PlatformType.DESKTOP:
|
||||
info('Platform Type: Desktop');
|
||||
info('Target Platform Type: Desktop');
|
||||
case PlatformType.MOBILE:
|
||||
info('Platform Type: Mobile');
|
||||
info('Target Platform Type: Mobile');
|
||||
case PlatformType.WEB:
|
||||
info('Platform Type: Web');
|
||||
info('Target Platform Type: Web');
|
||||
case PlatformType.CONSOLE:
|
||||
info('Platform Type: Console');
|
||||
info('Target Platform Type: Console');
|
||||
default:
|
||||
error('Unknown platform type (got ${platformType})');
|
||||
}
|
||||
|
||||
// Print whether we are using HXCPP, HashLink, or something else.
|
||||
// Print whether we are using HXCPP, JavaScript, or something else.
|
||||
if (isWeb())
|
||||
{
|
||||
info('Target Language: JavaScript (HTML5)');
|
||||
}
|
||||
else if (isHashLink())
|
||||
{
|
||||
info('Target Language: HashLink');
|
||||
}
|
||||
else if (isNeko())
|
||||
{
|
||||
info('Target Language: Neko');
|
||||
}
|
||||
else if (isJava())
|
||||
{
|
||||
info('Target Language: Java');
|
||||
}
|
||||
else if (isNodeJS())
|
||||
{
|
||||
info('Target Language: JavaScript (NodeJS)');
|
||||
}
|
||||
else if (isCSharp())
|
||||
{
|
||||
info('Target Language: C#');
|
||||
}
|
||||
else if (isCPP())
|
||||
{
|
||||
info('Target Language: C++');
|
||||
@@ -786,23 +787,13 @@ class Project extends HXProject
|
||||
switch (arch)
|
||||
{
|
||||
case Architecture.X86:
|
||||
info('Architecture: x86');
|
||||
info('Target Architecture: x86');
|
||||
case Architecture.X64:
|
||||
info('Architecture: x64');
|
||||
case Architecture.ARMV5:
|
||||
info('Architecture: ARMv5');
|
||||
case Architecture.ARMV6:
|
||||
info('Architecture: ARMv6');
|
||||
info('Target Architecture: x64');
|
||||
case Architecture.ARMV7:
|
||||
info('Architecture: ARMv7');
|
||||
case Architecture.ARMV7S:
|
||||
info('Architecture: ARMv7S');
|
||||
info('Target Architecture: ARMv7');
|
||||
case Architecture.ARM64:
|
||||
info('Architecture: ARMx64');
|
||||
case Architecture.MIPS:
|
||||
info('Architecture: MIPS');
|
||||
case Architecture.MIPSEL:
|
||||
info('Architecture: MIPSEL');
|
||||
info('Target Architecture: ARM64');
|
||||
case null:
|
||||
if (!isWeb())
|
||||
{
|
||||
@@ -810,7 +801,7 @@ class Project extends HXProject
|
||||
}
|
||||
else
|
||||
{
|
||||
info('Architecture: Web');
|
||||
info('Target Architecture: Web');
|
||||
}
|
||||
default:
|
||||
error('Unsupported architecture (got ${arch})');
|
||||
@@ -870,8 +861,7 @@ class Project extends HXProject
|
||||
FEATURE_POLYMOD_MODS.apply(this, true);
|
||||
|
||||
// Video playback should be enabled on desktop, web, and mobile.
|
||||
// HXCPP has trouble with iOS simulator builds though...
|
||||
FEATURE_VIDEO_PLAYBACK.apply(this, !(isIOSSimulator() || isHashLink()));
|
||||
FEATURE_VIDEO_PLAYBACK.apply(this, true);
|
||||
|
||||
// Video subtitles only work via using hxvlc.
|
||||
FEATURE_VIDEO_SUBTITLES.apply(this, FEATURE_VIDEO_PLAYBACK.isEnabled(this) && !isWeb());
|
||||
@@ -882,7 +872,7 @@ class Project extends HXProject
|
||||
|
||||
// Should be true on desktop, non-tester builds.
|
||||
// We don't want testers to accidentally leak songs to their Discord friends!
|
||||
FEATURE_DISCORD_RPC.apply(this, isDesktop() && !FEATURE_DEBUG_FUNCTIONS.isEnabled(this) && !isHashLink());
|
||||
FEATURE_DISCORD_RPC.apply(this, isDesktop() && !FEATURE_DEBUG_FUNCTIONS.isEnabled(this));
|
||||
|
||||
FEATURE_LOST_FOCUS_VOLUME.apply(this, isDesktop());
|
||||
|
||||
@@ -906,13 +896,13 @@ class Project extends HXProject
|
||||
// Should be true except on web builds (some asset stuff breaks it)
|
||||
FEATURE_LAG_ADJUSTMENT.apply(this, !isWeb());
|
||||
|
||||
// Should be true except on web and mobile builds.
|
||||
// Screenshots doesn't work there, and mobile has its own screenshots anyway.
|
||||
FEATURE_SCREENSHOTS.apply(this, !(isWeb() || isMobile()));
|
||||
// Should be true only on Desktop builds.
|
||||
// Mobile has its own screenshot methods.
|
||||
// Web has it disabled due to performance cost of `preserveDrawingBuffer`.
|
||||
FEATURE_SCREENSHOTS.apply(this, isDesktop());
|
||||
|
||||
// Should be true except on MacOS and mobile builds.
|
||||
// Dragging and dropping files onto the window doesn't work there.
|
||||
FEATURE_FILE_DROP.apply(this, !(isMac() || isMobile()));
|
||||
// Should be true except on mobile builds.
|
||||
FEATURE_FILE_DROP.apply(this, !isMobile());
|
||||
|
||||
// Audio context issues only exist on web builds.
|
||||
FEATURE_TOUCH_HERE_TO_PLAY.apply(this, isWeb());
|
||||
@@ -922,10 +912,11 @@ class Project extends HXProject
|
||||
FEATURE_TOUCH_CONTROLS.apply(this, isMobile());
|
||||
|
||||
// Should be true only on mobile release builds. Remember you can add the flag manually for testing.
|
||||
FEATURE_MOBILE_ADVERTISEMENTS.apply(this, (isMobile() && isRelease() && !isIOSSimulator()) && envConfig != null);
|
||||
FEATURE_MOBILE_IAP.apply(this, (isMobile() && isRelease() && !isIOSSimulator()) && envConfig != null);
|
||||
FEATURE_MOBILE_IAR.apply(this, isMobile() && isRelease() && !isIOSSimulator());
|
||||
FEATURE_MOBILE_ADVERTISEMENTS.apply(this, (isMobile() && isRelease()) && envConfig != null);
|
||||
FEATURE_MOBILE_IAP.apply(this, (isMobile() && isRelease()) && envConfig != null);
|
||||
FEATURE_MOBILE_IAR.apply(this, isMobile() && isRelease());
|
||||
FEATURE_MOBILE_WEBVIEW.apply(this, isMobile() && FEATURE_NEWGROUNDS.isEnabled(this));
|
||||
FEATURE_MOBILE_AGESIGNALS.apply(this, isMobile() && isRelease());
|
||||
|
||||
// The coveted ghost tapping feature.
|
||||
// Essential on mobile but delayed on desktop.
|
||||
@@ -956,16 +947,6 @@ class Project extends HXProject
|
||||
var unicodeCheck:String = "✓ ";
|
||||
var unicodeCross:String = "× ";
|
||||
|
||||
if (isWindowsHost())
|
||||
{
|
||||
#if (!target.unicode)
|
||||
// lime build tools uses neko (unless compiling with `-eval`), and neko on windows doesn't support UTF8/unicode characters
|
||||
// so we need to remove our cute emoji!
|
||||
unicodeCheck = "o ";
|
||||
unicodeCross = "x ";
|
||||
#end
|
||||
}
|
||||
|
||||
for (flagStr in this.haxedefs.keys())
|
||||
{
|
||||
if (!flagStr.startsWith(FeatureFlag.INVERSE_PREFIX))
|
||||
@@ -1014,6 +995,9 @@ class Project extends HXProject
|
||||
*/
|
||||
function configureCompileDefines()
|
||||
{
|
||||
// Add Funkin's version as a compilation flag so Polymod scripts can use it.
|
||||
setHaxedef("funkin", VERSION);
|
||||
|
||||
// Enable OpenFL's error handler. Required for the crash logger.
|
||||
setHaxedef("openfl-enable-handle-error");
|
||||
|
||||
@@ -1027,8 +1011,6 @@ class Project extends HXProject
|
||||
setHaxedef("HXCPP_STACK_TRACE");
|
||||
setHaxedef("hscriptPos");
|
||||
|
||||
setHaxedef("safeMode");
|
||||
|
||||
if (FEATURE_DEBUG_FUNCTIONS.isDisabled(this))
|
||||
{
|
||||
setHaxedef("FLX_NO_DEBUG"); // If we aren't using the Flixel debugger, strip it out.
|
||||
@@ -1164,22 +1146,6 @@ class Project extends HXProject
|
||||
{
|
||||
javaPaths.push(Path.join([SOURCE_DIR, 'funkin/external/android/java']));
|
||||
|
||||
if (isRelease())
|
||||
{
|
||||
if (envConfig != null)
|
||||
{
|
||||
keystore = new Keystore();
|
||||
keystore.path = Std.string(envConfig.get('KEYSTORE_PATH'));
|
||||
keystore.alias = Std.string(envConfig.get('KEYSTORE_ALIAS'));
|
||||
keystore.password = Std.string(envConfig.get('KEYSTORE_PASSWORD'));
|
||||
}
|
||||
|
||||
if (isBundle())
|
||||
{
|
||||
config.set("android.gradle-project-directory", "bin-bundle");
|
||||
}
|
||||
}
|
||||
|
||||
// Custom android.application XML Children for the AndroidManifest
|
||||
final modsFolderProvider:Xml = Xml.createElement('provider');
|
||||
modsFolderProvider.set('android:authorities', '$PACKAGE_NAME.docprovider');
|
||||
@@ -1266,10 +1232,6 @@ class Project extends HXProject
|
||||
|
||||
function configureIOS()
|
||||
{
|
||||
config.set("ios.non-exempt-encryption", "false");
|
||||
config.set("ios.team-id", IOS_TEAM_ID);
|
||||
config.set("ios.deployment", "16.0");
|
||||
|
||||
// launchStoryboard = new LaunchStoryboard();
|
||||
// launchStoryboard.path = "./LaunchScreen.storyboard";
|
||||
|
||||
@@ -1345,8 +1307,6 @@ class Project extends HXProject
|
||||
|
||||
if ((isDesktop() || isMobile()) && FEATURE_VIDEO_PLAYBACK.isEnabled(this))
|
||||
{
|
||||
// hxvlc doesn't function on HashLink or non-desktop platforms
|
||||
// It's also unnecessary if video playback is disabled
|
||||
addHaxelib('hxvlc'); // Video playback
|
||||
}
|
||||
|
||||
@@ -1405,11 +1365,16 @@ class Project extends HXProject
|
||||
{
|
||||
addHaxelib('extension-webviewcore'); // WebView Extension
|
||||
}
|
||||
|
||||
if (FEATURE_MOBILE_AGESIGNALS.isEnabled(this))
|
||||
{
|
||||
addHaxelib('extension-agesignals'); // WebView Extension
|
||||
}
|
||||
}
|
||||
|
||||
function configureAssets()
|
||||
{
|
||||
if (!isDisplay())
|
||||
if (!(isDisplay() || isCleanCommand()))
|
||||
{
|
||||
// Delete the assets folder from the export folder before adding anything.
|
||||
clearAssets();
|
||||
@@ -1525,7 +1490,7 @@ class Project extends HXProject
|
||||
var exportPath:Null<String> = app.path ?? "";
|
||||
|
||||
// mac target uses `macos` for the export folder instead of `mac`
|
||||
var platform:String = isHashLink() ? 'hl' : (!isMac() ? Std.string(this.target) : 'macos');
|
||||
var platform:String = !isMac() ? Std.string(this.target) : 'macos';
|
||||
var basePath:String = Path.join([exportPath, platform, "bin"]);
|
||||
var assetsPath:String = "";
|
||||
|
||||
@@ -1647,14 +1612,10 @@ class Project extends HXProject
|
||||
*/
|
||||
function configureASTCTextures()
|
||||
{
|
||||
if (!(isDisplay() || isClean()))
|
||||
if (!(isDisplay() && isCleanCommand()) && FEATURE_COMPRESSED_TEXTURES.isEnabled(this))
|
||||
{
|
||||
readASTCExclusion();
|
||||
|
||||
if (FEATURE_COMPRESSED_TEXTURES.isEnabled(this))
|
||||
{
|
||||
runASTCCompressor();
|
||||
}
|
||||
runASTCCompressor();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1760,31 +1721,6 @@ class Project extends HXProject
|
||||
return this.target == Platform.IOS && this.targetFlags.exists("simulator");
|
||||
}
|
||||
|
||||
public function isHashLink():Bool
|
||||
{
|
||||
return this.targetFlags.exists("hl");
|
||||
}
|
||||
|
||||
public function isNeko():Bool
|
||||
{
|
||||
return this.targetFlags.exists("neko");
|
||||
}
|
||||
|
||||
public function isJava():Bool
|
||||
{
|
||||
return this.targetFlags.exists("java");
|
||||
}
|
||||
|
||||
public function isNodeJS():Bool
|
||||
{
|
||||
return this.targetFlags.exists("nodejs");
|
||||
}
|
||||
|
||||
public function isCSharp():Bool
|
||||
{
|
||||
return this.targetFlags.exists("cs");
|
||||
}
|
||||
|
||||
public function isCPP():Bool
|
||||
{
|
||||
return this.defines.exists("cpp");
|
||||
@@ -1795,11 +1731,26 @@ class Project extends HXProject
|
||||
return this.command == "display";
|
||||
}
|
||||
|
||||
public function isClean():Bool
|
||||
public function isCleanCommand():Bool
|
||||
{
|
||||
return this.command == "clean";
|
||||
}
|
||||
|
||||
public function isCleanFlag():Bool
|
||||
{
|
||||
return this.targetFlags.exists("clean");
|
||||
}
|
||||
|
||||
public function isRun():Bool
|
||||
{
|
||||
return this.command == "run";
|
||||
}
|
||||
|
||||
public function isInstall():Bool
|
||||
{
|
||||
return this.command == "install";
|
||||
}
|
||||
|
||||
public function isBuild():Bool
|
||||
{
|
||||
return this.command == "test" || this.command == "build";
|
||||
@@ -2161,8 +2112,8 @@ class Project extends HXProject
|
||||
|
||||
if (haxe.io.Path.isAbsolute(devPath))
|
||||
{
|
||||
Sys.println("- " + libraryName.replace(",", ".") + " (Development Build)".blue().bold());
|
||||
Sys.println((" Path: " + haxe.io.Path.removeTrailingSlashes(devPath)).blue());
|
||||
Sys.println("- " + libraryName.replace(",", ".") + " (Development Build)".bright_cyan());
|
||||
Sys.println((" Path: " + haxe.io.Path.removeTrailingSlashes(devPath)).bright_blue());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2328,7 +2279,7 @@ class Project extends HXProject
|
||||
*/
|
||||
public function info(message:String):Void
|
||||
{
|
||||
if (!(isDisplay() || isClean()))
|
||||
if (!(isDisplay() || isCleanCommand() || isRun() || isInstall()))
|
||||
{
|
||||
Sys.println(' INFO '.bold().bg_blue() + " " + message);
|
||||
}
|
||||
@@ -2339,7 +2290,7 @@ class Project extends HXProject
|
||||
*/
|
||||
public function warn(message:String):Void
|
||||
{
|
||||
if (!(isDisplay() || isClean()))
|
||||
if (!(isDisplay() || isCleanCommand() || isRun() || isInstall()))
|
||||
{
|
||||
Sys.println(' WARNING '.bold().bg_yellow() + " " + message);
|
||||
}
|
||||
@@ -2485,8 +2436,14 @@ class Project extends HXProject
|
||||
info('Compressing ASTC textures...');
|
||||
|
||||
var args:Array<String> = ['run', 'astc-compressor', 'compress-from-json'];
|
||||
|
||||
args = args.concat(['-json', './astc-compression-data.json']);
|
||||
|
||||
if (isCleanFlag())
|
||||
{
|
||||
args = args.concat(['-clean']);
|
||||
}
|
||||
|
||||
Sys.command('haxelib', args);
|
||||
|
||||
info('Done compressing ASTC textures.');
|
||||
|
||||
+9
-10
@@ -31,16 +31,15 @@ class Postbuild
|
||||
else
|
||||
{
|
||||
var bytes:haxe.io.Bytes = haxe.io.Bytes.ofData(sys.io.File.getBytes(path).getData());
|
||||
var entry:haxe.zip.Entry =
|
||||
{
|
||||
fileName: StringTools.replace(path, inDir, ""),
|
||||
fileSize: bytes.length,
|
||||
fileTime: Date.now(),
|
||||
compressed: false,
|
||||
dataSize: sys.FileSystem.stat(path).size,
|
||||
data: bytes,
|
||||
crc32: haxe.crypto.Crc32.make(bytes)
|
||||
};
|
||||
var entry:haxe.zip.Entry = {
|
||||
fileName: StringTools.replace(path, inDir, ""),
|
||||
fileSize: bytes.length,
|
||||
fileTime: Date.now(),
|
||||
compressed: false,
|
||||
dataSize: sys.FileSystem.stat(path).size,
|
||||
data: bytes,
|
||||
crc32: haxe.crypto.Crc32.make(bytes)
|
||||
};
|
||||
entries.push(entry);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ class SongConverter
|
||||
|
||||
// TODO
|
||||
// Update engine shit, to accomodate single file
|
||||
|
||||
static function main()
|
||||
{
|
||||
// trace(Compiler.get);
|
||||
|
||||
+13
-9
@@ -11,6 +11,8 @@ import funkin.util.logging.CrashHandler;
|
||||
import funkin.ui.debug.FunkinDebugDisplay;
|
||||
import funkin.ui.debug.FunkinDebugDisplay.DebugDisplayMode;
|
||||
import funkin.save.Save;
|
||||
import funkin.FunkinMemory;
|
||||
import funkin.audio.FunkinSound;
|
||||
#if hxvlc
|
||||
import hxvlc.util.Handle;
|
||||
#end
|
||||
@@ -87,26 +89,28 @@ class Main extends Sprite
|
||||
removeEventListener(Event.ADDED_TO_STAGE, init);
|
||||
}
|
||||
|
||||
#if (sys && !mobile)
|
||||
#if (!html5 && !mobile)
|
||||
// Force-kill the game to prevent background processing.
|
||||
Lib.current.stage.window.onClose.add(function()
|
||||
openfl.Lib.application.onExit.add((_) ->
|
||||
{
|
||||
trace(' EXITING '.bold().bg_red() + ' Game is exiting, cleaning up resources...');
|
||||
// Dispose of cached audio and textures.
|
||||
funkin.audio.FunkinSound.stopAllAudio(true, true);
|
||||
funkin.FunkinMemory.purgeCache(true);
|
||||
|
||||
#if hxvlc
|
||||
// Clean up VLC threads to prevent memory leaks.
|
||||
hxvlc.util.Handle.dispose();
|
||||
#end
|
||||
// Dispose of any assets still in the OpenFL cache, just incase.
|
||||
openfl.Assets.cache.clear();
|
||||
|
||||
trace(' EXITING '.bold().bg_red() + ' Resources are disposed, Game is closing now.');
|
||||
|
||||
Sys.exit(0);
|
||||
});
|
||||
}, 99);
|
||||
#end
|
||||
|
||||
// Manually crash the game when using a software renderer in order to give a nicer error message.
|
||||
var context = stage.window.context.type;
|
||||
if (context != WEBGL && context != OPENGL && context != OPENGLES)
|
||||
{
|
||||
var tech:String = #if web "WebGL" #elseif desktop "OpenGL" #else "OpenGL ES" #end;
|
||||
var tech:String = #if web 'WebGL' #elseif desktop 'OpenGL' #else 'OpenGL ES' #end;
|
||||
var requiredVersion:String = #if web '$tech 1.0 or newer' #elseif desktop '$tech 3.0 or newer' #else '$tech 2.0 or newer' #end;
|
||||
var desc:String = 'Failed to initialize the $tech rendering context!\n\n';
|
||||
#if web
|
||||
|
||||
+5
-5
@@ -36,7 +36,7 @@ class Postbuild
|
||||
|
||||
static function format(time:Float, decimals:Int = 1):String
|
||||
{
|
||||
var units = [{name: "day", secs: 86400}, {name: "hour", secs: 3600}, {name: "minute", secs: 60}, {name: "second", secs: 1}];
|
||||
var units = [{name: 'day', secs: 86400}, {name: 'hour', secs: 3600}, {name: 'minute', secs: 60}, {name: 'second', secs: 1}];
|
||||
|
||||
var parts:Array<String> = [];
|
||||
var remaining:Float = time;
|
||||
@@ -44,13 +44,13 @@ class Postbuild
|
||||
|
||||
for (u in units)
|
||||
{
|
||||
var value:Float = (u.name == "second") ? Math.round(remaining * factor) / factor : Math.floor(remaining / u.secs);
|
||||
var value:Float = (u.name == 'second') ? Math.round(remaining * factor) / factor : Math.floor(remaining / u.secs);
|
||||
|
||||
if (u.name != "second") remaining %= u.secs;
|
||||
if (u.name != 'second') remaining %= u.secs;
|
||||
|
||||
if (value > 0 || (u.name == "second" && parts.length == 0)) parts.push('${value} ${u.name}${value == 1 ? "" : "s"}');
|
||||
if (value > 0 || (u.name == 'second' && parts.length == 0)) parts.push('${value} ${u.name}${value == 1 ? "" : "s"}');
|
||||
}
|
||||
|
||||
return parts.join(" ");
|
||||
return parts.join(' ');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/**
|
||||
* Pulled from Tracey profiler PR
|
||||
* @see https://github.com/HaxeFoundation/haxe/pull/11772
|
||||
*/
|
||||
@@ -6,7 +6,7 @@
|
||||
package cpp.vm.tracy;
|
||||
|
||||
#if (!HXCPP_TRACY)
|
||||
#error "This class cannot be used without -D HXCPP_TRACY"
|
||||
#error 'This class cannot be used without -D HXCPP_TRACY'
|
||||
#end
|
||||
enum abstract PlotFormatType(cpp.UInt8) from cpp.UInt8 to cpp.UInt8
|
||||
{
|
||||
@@ -19,68 +19,68 @@ enum abstract PlotFormatType(cpp.UInt8) from cpp.UInt8 to cpp.UInt8
|
||||
extern class Native_TracyProfiler
|
||||
{
|
||||
/**
|
||||
Mark a frame. Call this at the end of each frame loop.
|
||||
**/
|
||||
* Mark a frame. Call this at the end of each frame loop.
|
||||
*/
|
||||
@:native('::__hxcpp_tracy_framemark')
|
||||
public static function frameMark():Void;
|
||||
|
||||
/**
|
||||
Mark a named frame. Allows creating multiple frame sets for different timing categories.
|
||||
Each unique name creates a separate frame set in the Tracy timeline.
|
||||
**/
|
||||
* Mark a named frame. Allows creating multiple frame sets for different timing categories.
|
||||
* Each unique name creates a separate frame set in the Tracy timeline.
|
||||
*/
|
||||
@:native('::__hxcpp_tracy_framemark_named')
|
||||
public static function frameMarkNamed(_name:String):Void;
|
||||
|
||||
/**
|
||||
Mark the start of a discontinuous frame. Use for periodic work with gaps.
|
||||
Must be paired with frameMarkEnd() using the same name.
|
||||
**/
|
||||
* Mark the start of a discontinuous frame. Use for periodic work with gaps.
|
||||
* Must be paired with frameMarkEnd() using the same name.
|
||||
*/
|
||||
@:native('::__hxcpp_tracy_framemark_start')
|
||||
public static function frameMarkStart(_name:String):Void;
|
||||
|
||||
/**
|
||||
Mark the end of a discontinuous frame. Use for periodic work with gaps.
|
||||
Must be paired with frameMarkStart() using the same name.
|
||||
**/
|
||||
* Mark the end of a discontinuous frame. Use for periodic work with gaps.
|
||||
* Must be paired with frameMarkStart() using the same name.
|
||||
*/
|
||||
@:native('::__hxcpp_tracy_framemark_end')
|
||||
public static function frameMarkEnd(_name:String):Void;
|
||||
|
||||
/**
|
||||
Print a message into Tracy's log.
|
||||
**/
|
||||
* Print a message into Tracy's log.
|
||||
*/
|
||||
@:native('::__hxcpp_tracy_message')
|
||||
public static function message(_msg:String, ?_color:Int = 0x000000):Void;
|
||||
|
||||
/**
|
||||
Tracy can collect additional information about the profiled application,
|
||||
which will be available in the trace description.
|
||||
This can include data such as the source repository revision,
|
||||
the application’s environment (dev/prod), etc.
|
||||
**/
|
||||
* Tracy can collect additional information about the profiled application,
|
||||
* which will be available in the trace description.
|
||||
* This can include data such as the source repository revision,
|
||||
* the application’s environment (dev/prod), etc.
|
||||
*/
|
||||
@:native('::__hxcpp_tracy_message_app_info')
|
||||
public static function messageAppInfo(_info:String):Void;
|
||||
|
||||
/**
|
||||
Plot a named value to tracy. This will generate a graph in the profiler for you.
|
||||
**/
|
||||
* Plot a named value to tracy. This will generate a graph in the profiler for you.
|
||||
*/
|
||||
@:native('::__hxcpp_tracy_plot')
|
||||
public static function plot(_name:String, _val:cpp.Float32):Void;
|
||||
|
||||
/**
|
||||
Configure how values are plotted and displayed.
|
||||
**/
|
||||
* Configure how values are plotted and displayed.
|
||||
*/
|
||||
@:native('::__hxcpp_tracy_plot_config')
|
||||
public static function plotConfig(_name:String, _format:PlotFormatType, ?_step:Bool = false, ?_fill:Bool = false, ?_color:Int = 0x000000):Void;
|
||||
|
||||
/**
|
||||
Set a name for the current thread this function is called in. Supply an optional groupHint so threads become grouped in Tracy's UI.
|
||||
**/
|
||||
* Set a name for the current thread this function is called in. Supply an optional groupHint so threads become grouped in Tracy's UI.
|
||||
*/
|
||||
@:native('::__hxcpp_tracy_set_thread_name_and_group')
|
||||
public static function setThreadName(_name:String, ?_groupHint:Int = 1):Void;
|
||||
|
||||
/**
|
||||
Create a custom named scoped zone in your code.
|
||||
**/
|
||||
* Create a custom named scoped zone in your code.
|
||||
*/
|
||||
@:native('HXCPP_TRACY_ZONE')
|
||||
public static function zoneScoped(_name:String):Void;
|
||||
}
|
||||
|
||||
@@ -362,7 +362,7 @@ class Conductor
|
||||
static function get_instance():Conductor
|
||||
{
|
||||
if (Conductor._instance == null) set_instance(new Conductor());
|
||||
if (Conductor._instance == null) throw "Could not initialize singleton Conductor!";
|
||||
if (Conductor._instance == null) throw 'Could not initialize singleton Conductor!';
|
||||
return Conductor._instance;
|
||||
}
|
||||
|
||||
@@ -849,7 +849,7 @@ class Conductor
|
||||
* @param type The type of length to return. Either "step", "beat", or "measure" works, along with their first character.
|
||||
* @return The length of a step/beat/measure in milliseconds.
|
||||
*/
|
||||
public function getTypeLengthAtMs(ms:Float, type:String = "beat"):Float
|
||||
public function getTypeLengthAtMs(ms:Float, type:String = 'beat'):Float
|
||||
{
|
||||
if (timeChanges.length == 0) return 0;
|
||||
var wantedTimeChange:SongTimeChange = timeChanges[0];
|
||||
@@ -868,10 +868,14 @@ class Conductor
|
||||
var wantedBeatLengthMs:Float = ((Constants.SECS_PER_MIN / wantedTimeChange.bpm) * Constants.MS_PER_SEC) * (4 / wantedTimeChange.timeSignatureDen);
|
||||
return switch (type.toLowerCase())
|
||||
{
|
||||
case "measure", "m": wantedBeatLengthMs * wantedTimeChange.timeSignatureNum;
|
||||
case "beat", "b": wantedBeatLengthMs;
|
||||
case "step", "s": wantedBeatLengthMs / Constants.STEPS_PER_BEAT;
|
||||
default: wantedBeatLengthMs;
|
||||
case 'measure', 'm':
|
||||
wantedBeatLengthMs * wantedTimeChange.timeSignatureNum;
|
||||
case 'beat', 'b':
|
||||
wantedBeatLengthMs;
|
||||
case 'step', 's':
|
||||
wantedBeatLengthMs / Constants.STEPS_PER_BEAT;
|
||||
default:
|
||||
wantedBeatLengthMs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,12 +20,10 @@ class FunkinMemory
|
||||
static var permanentCachedTextures:Map<String, FlxGraphic> = [];
|
||||
static var currentCachedTextures:Map<String, FlxGraphic> = [];
|
||||
static var previousCachedTextures:Map<String, FlxGraphic> = [];
|
||||
|
||||
static var permanentCachedSounds:Map<String, Sound> = [];
|
||||
static var currentCachedSounds:Map<String, Sound> = [];
|
||||
static var previousCachedSounds:Map<String, Sound> = [];
|
||||
|
||||
static var purgeFilter:Array<String> = ["/week", "/characters", "/charSelect", "/results"];
|
||||
static var purgeFilter:Array<String> = ['/week', '/characters', '/charSelect', '/results'];
|
||||
|
||||
/**
|
||||
* Caches textures that are always required.
|
||||
@@ -36,42 +34,42 @@ class FunkinMemory
|
||||
|
||||
for (file in allImages)
|
||||
{
|
||||
if (!(file.endsWith(".png") #if FEATURE_COMPRESSED_TEXTURES || file.endsWith(".astc") #end)
|
||||
|| file.contains("chart-editor")
|
||||
|| !file.contains("ui/"))
|
||||
if (!(file.endsWith('.png') #if FEATURE_COMPRESSED_TEXTURES || file.endsWith('.astc') #end)
|
||||
|| file.contains('chart-editor')
|
||||
|| !file.contains('ui/'))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
file = file.replace(" ", ""); // Handle stray spaces.
|
||||
file = file.replace(' ', ''); // Handle stray spaces.
|
||||
|
||||
if (file.contains("shared") || Assets.exists('shared:$file', AssetType.IMAGE))
|
||||
if (file.contains('shared') || Assets.exists('shared:$file', AssetType.IMAGE))
|
||||
{
|
||||
file = 'shared:$file';
|
||||
}
|
||||
permanentCacheTexture(file);
|
||||
}
|
||||
|
||||
permanentCacheTexture(Paths.image("healthBar"));
|
||||
permanentCacheTexture(Paths.image("menuDesat"));
|
||||
permanentCacheTexture(Paths.image("notes", "shared"));
|
||||
permanentCacheTexture(Paths.image("noteSplashes", "shared"));
|
||||
permanentCacheTexture(Paths.image("noteStrumline", "shared"));
|
||||
permanentCacheTexture(Paths.image("NOTE_hold_assets"));
|
||||
permanentCacheTexture(Paths.image('healthBar'));
|
||||
permanentCacheTexture(Paths.image('menuDesat'));
|
||||
permanentCacheTexture(Paths.image('notes', 'shared'));
|
||||
permanentCacheTexture(Paths.image('noteSplashes', 'shared'));
|
||||
permanentCacheTexture(Paths.image('noteStrumline', 'shared'));
|
||||
permanentCacheTexture(Paths.image('NOTE_hold_assets'));
|
||||
// dude
|
||||
permanentCacheTexture(Paths.image("fonts/bold", null));
|
||||
permanentCacheTexture(Paths.image("fonts/default", null));
|
||||
permanentCacheTexture(Paths.image("fonts/freeplay-clear", null));
|
||||
permanentCacheTexture(Paths.image('fonts/bold', null));
|
||||
permanentCacheTexture(Paths.image('fonts/default', null));
|
||||
permanentCacheTexture(Paths.image('fonts/freeplay-clear', null));
|
||||
|
||||
var allSounds:Array<String> = Assets.list(AssetType.SOUND);
|
||||
|
||||
for (file in allSounds)
|
||||
{
|
||||
if (!file.endsWith(".ogg") || !file.contains("countdown/")) continue;
|
||||
if (!file.endsWith('.ogg') || !file.contains('countdown/')) continue;
|
||||
|
||||
file = file.replace(" ", "");
|
||||
file = file.replace(' ', '');
|
||||
|
||||
if (file.contains("shared") || Assets.exists('shared:$file', AssetType.SOUND))
|
||||
if (file.contains('shared') || Assets.exists('shared:$file', AssetType.SOUND))
|
||||
{
|
||||
file = 'shared:$file';
|
||||
}
|
||||
@@ -79,19 +77,19 @@ class FunkinMemory
|
||||
permanentCacheSound(file);
|
||||
}
|
||||
|
||||
permanentCacheSound(Paths.sound("cancelMenu"));
|
||||
permanentCacheSound(Paths.sound("confirmMenu"));
|
||||
permanentCacheSound(Paths.sound("screenshot"));
|
||||
permanentCacheSound(Paths.sound("scrollMenu"));
|
||||
permanentCacheSound(Paths.sound("soundtray/Voldown"));
|
||||
permanentCacheSound(Paths.sound("soundtray/VolMAX"));
|
||||
permanentCacheSound(Paths.sound("soundtray/Volup"));
|
||||
permanentCacheSound(Paths.music("freakyMenu/freakyMenu"));
|
||||
permanentCacheSound(Paths.music("offsetsLoop/offsetsLoop"));
|
||||
permanentCacheSound(Paths.music("offsetsLoop/drumsLoop"));
|
||||
permanentCacheSound(Paths.sound("missnote1", "shared"));
|
||||
permanentCacheSound(Paths.sound("missnote2", "shared"));
|
||||
permanentCacheSound(Paths.sound("missnote3", "shared"));
|
||||
permanentCacheSound(Paths.sound('cancelMenu'));
|
||||
permanentCacheSound(Paths.sound('confirmMenu'));
|
||||
permanentCacheSound(Paths.sound('screenshot'));
|
||||
permanentCacheSound(Paths.sound('scrollMenu'));
|
||||
permanentCacheSound(Paths.sound('soundtray/Voldown'));
|
||||
permanentCacheSound(Paths.sound('soundtray/VolMAX'));
|
||||
permanentCacheSound(Paths.sound('soundtray/Volup'));
|
||||
permanentCacheSound(Paths.music('freakyMenu/freakyMenu'));
|
||||
permanentCacheSound(Paths.music('offsetsLoop/offsetsLoop'));
|
||||
permanentCacheSound(Paths.music('offsetsLoop/drumsLoop'));
|
||||
permanentCacheSound(Paths.sound('missnote1', 'shared'));
|
||||
permanentCacheSound(Paths.sound('missnote2', 'shared'));
|
||||
permanentCacheSound(Paths.sound('missnote3', 'shared'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,6 +98,8 @@ class FunkinMemory
|
||||
*/
|
||||
public static inline function purgeCache(callGarbageCollector:Bool = false):Void
|
||||
{
|
||||
trace(' CLEARING CACHE '.bg_bright_lilac().bold() + ' Disposing all cached textures, assets and sounds...');
|
||||
|
||||
preparePurgeTextureCache();
|
||||
purgeTextureCache();
|
||||
preparePurgeSoundCache();
|
||||
@@ -175,7 +175,7 @@ class FunkinMemory
|
||||
/**
|
||||
* Prepares the cache for purging unused textures.
|
||||
*/
|
||||
public inline static function preparePurgeTextureCache():Void
|
||||
public static inline function preparePurgeTextureCache():Void
|
||||
{
|
||||
previousCachedTextures = currentCachedTextures.copy();
|
||||
|
||||
@@ -203,7 +203,7 @@ class FunkinMemory
|
||||
continue;
|
||||
}
|
||||
|
||||
if (graphicKey.contains("fonts")) continue;
|
||||
if (graphicKey.contains('fonts')) continue;
|
||||
|
||||
var graphic:Null<FlxGraphic> = previousCachedTextures.get(graphicKey);
|
||||
if (graphic != null)
|
||||
@@ -227,7 +227,7 @@ class FunkinMemory
|
||||
{
|
||||
var obj:Null<FlxGraphic> = FlxG.bitmap.get(key);
|
||||
|
||||
if (obj == null || (obj.persist && permanentCachedTextures.exists(key)) || key.contains("fonts"))
|
||||
if (obj == null || (obj.persist && permanentCachedTextures.exists(key)) || key.contains('fonts'))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -251,7 +251,7 @@ class FunkinMemory
|
||||
* Forces the GPU to load and upload a FlxGraphic.
|
||||
* @param graphic The graphic to force render.
|
||||
*/
|
||||
private static function forceRender(graphic:FlxGraphic):Void
|
||||
static function forceRender(graphic:FlxGraphic):Void
|
||||
{
|
||||
if (graphic == null) return;
|
||||
|
||||
@@ -286,30 +286,30 @@ class FunkinMemory
|
||||
public static function cacheNoteStyle(style:NoteStyle):Void
|
||||
{
|
||||
// TODO: Texture paths should fall back to the default values.
|
||||
cacheTexture(Paths.image(style.getNoteAssetPath() ?? "note"));
|
||||
cacheTexture(style.getHoldNoteAssetPath() ?? "noteHold");
|
||||
cacheTexture(Paths.image(style.getStrumlineAssetPath() ?? "strumline"));
|
||||
cacheTexture(Paths.image(style.getSplashAssetPath() ?? "noteSplash"));
|
||||
cacheTexture(Paths.image(style.getNoteAssetPath() ?? 'note'));
|
||||
cacheTexture(style.getHoldNoteAssetPath() ?? 'noteHold');
|
||||
cacheTexture(Paths.image(style.getStrumlineAssetPath() ?? 'strumline'));
|
||||
cacheTexture(Paths.image(style.getSplashAssetPath() ?? 'noteSplash'));
|
||||
|
||||
cacheTexture(Paths.image(style.getHoldCoverDirectionAssetPath(LEFT) ?? "LEFT"));
|
||||
cacheTexture(Paths.image(style.getHoldCoverDirectionAssetPath(RIGHT) ?? "RIGHT"));
|
||||
cacheTexture(Paths.image(style.getHoldCoverDirectionAssetPath(UP) ?? "UP"));
|
||||
cacheTexture(Paths.image(style.getHoldCoverDirectionAssetPath(DOWN) ?? "DOWN"));
|
||||
cacheTexture(Paths.image(style.getHoldCoverDirectionAssetPath(LEFT) ?? 'LEFT'));
|
||||
cacheTexture(Paths.image(style.getHoldCoverDirectionAssetPath(RIGHT) ?? 'RIGHT'));
|
||||
cacheTexture(Paths.image(style.getHoldCoverDirectionAssetPath(UP) ?? 'UP'));
|
||||
cacheTexture(Paths.image(style.getHoldCoverDirectionAssetPath(DOWN) ?? 'DOWN'));
|
||||
|
||||
// cacheTexture(Paths.image(style.buildCountdownSpritePath(THREE) ?? "THREE"));
|
||||
cacheTexture(Paths.image(style.buildCountdownSpritePath(TWO) ?? "TWO"));
|
||||
cacheTexture(Paths.image(style.buildCountdownSpritePath(ONE) ?? "ONE"));
|
||||
cacheTexture(Paths.image(style.buildCountdownSpritePath(GO) ?? "GO"));
|
||||
cacheTexture(Paths.image(style.buildCountdownSpritePath(TWO) ?? 'TWO'));
|
||||
cacheTexture(Paths.image(style.buildCountdownSpritePath(ONE) ?? 'ONE'));
|
||||
cacheTexture(Paths.image(style.buildCountdownSpritePath(GO) ?? 'GO'));
|
||||
|
||||
cacheSound(style.getCountdownSoundPath(THREE) ?? "THREE");
|
||||
cacheSound(style.getCountdownSoundPath(TWO) ?? "TWO");
|
||||
cacheSound(style.getCountdownSoundPath(ONE) ?? "ONE");
|
||||
cacheSound(style.getCountdownSoundPath(GO) ?? "GO");
|
||||
cacheSound(style.getCountdownSoundPath(THREE) ?? 'THREE');
|
||||
cacheSound(style.getCountdownSoundPath(TWO) ?? 'TWO');
|
||||
cacheSound(style.getCountdownSoundPath(ONE) ?? 'ONE');
|
||||
cacheSound(style.getCountdownSoundPath(GO) ?? 'GO');
|
||||
|
||||
cacheTexture(Paths.image(style.buildJudgementSpritePath("sick") ?? 'sick'));
|
||||
cacheTexture(Paths.image(style.buildJudgementSpritePath("good") ?? 'good'));
|
||||
cacheTexture(Paths.image(style.buildJudgementSpritePath("bad") ?? 'bad'));
|
||||
cacheTexture(Paths.image(style.buildJudgementSpritePath("shit") ?? 'shit'));
|
||||
cacheTexture(Paths.image(style.buildJudgementSpritePath('sick') ?? 'sick'));
|
||||
cacheTexture(Paths.image(style.buildJudgementSpritePath('good') ?? 'good'));
|
||||
cacheTexture(Paths.image(style.buildJudgementSpritePath('bad') ?? 'bad'));
|
||||
cacheTexture(Paths.image(style.buildJudgementSpritePath('shit') ?? 'shit'));
|
||||
|
||||
cacheTexture(Paths.image(style.buildComboNumSpritePath(0) ?? '0'));
|
||||
cacheTexture(Paths.image(style.buildComboNumSpritePath(1) ?? '1'));
|
||||
@@ -343,9 +343,14 @@ class FunkinMemory
|
||||
}
|
||||
|
||||
var sound:Null<Sound> = Assets.getSound(key, true);
|
||||
if (sound == null) return;
|
||||
if (sound == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentCachedSounds.set(key, sound);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -357,9 +362,14 @@ class FunkinMemory
|
||||
if (permanentCachedSounds.exists(key)) return;
|
||||
|
||||
var sound:Null<Sound> = Assets.getSound(key, true);
|
||||
if (sound == null) return;
|
||||
if (sound == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
permanentCachedSounds.set(key, sound);
|
||||
}
|
||||
|
||||
if (sound != null) currentCachedSounds.set(key, sound);
|
||||
}
|
||||
@@ -402,10 +412,10 @@ class FunkinMemory
|
||||
previousCachedSounds.remove(key);
|
||||
}
|
||||
}
|
||||
Assets.cache.clear("songs");
|
||||
Assets.cache.clear("music");
|
||||
Assets.cache.clear('songs');
|
||||
Assets.cache.clear('music');
|
||||
// Felt lazy.
|
||||
var key = Paths.music("freakyMenu/freakyMenu");
|
||||
var key = Paths.music('freakyMenu/freakyMenu');
|
||||
var sound:Null<Sound> = Assets.getSound(key, true);
|
||||
if (sound != null)
|
||||
{
|
||||
@@ -426,8 +436,8 @@ class FunkinMemory
|
||||
@:privateAccess
|
||||
for (key in FlxG.bitmap._cache.keys())
|
||||
{
|
||||
if (!key.contains("freeplay")) continue;
|
||||
if (permanentCachedTextures.exists(key) || key.contains("fonts")) continue;
|
||||
if (!key.contains('freeplay')) continue;
|
||||
if (permanentCachedTextures.exists(key) || key.contains('fonts')) continue;
|
||||
|
||||
keysToRemove.push(key);
|
||||
}
|
||||
@@ -460,8 +470,8 @@ class FunkinMemory
|
||||
@:privateAccess
|
||||
for (key in FlxG.bitmap._cache.keys())
|
||||
{
|
||||
if (!key.contains("stickers")) continue;
|
||||
if (permanentCachedTextures.exists(key) || key.contains("fonts")) continue;
|
||||
if (!key.contains('stickers')) continue;
|
||||
if (permanentCachedTextures.exists(key) || key.contains('fonts')) continue;
|
||||
|
||||
keysToRemove.push(key);
|
||||
}
|
||||
@@ -485,7 +495,7 @@ class FunkinMemory
|
||||
* Sends a trace with fancy ANSI colors.
|
||||
* @param message The message to log.
|
||||
*/
|
||||
private static function log(message:String):Void
|
||||
static function log(message:String):Void
|
||||
{
|
||||
trace(' MEMORY '.bg_bright_lilac().bold() + ' ${message}');
|
||||
}
|
||||
|
||||
@@ -82,9 +82,7 @@ typedef RawTallies =
|
||||
var good:Int;
|
||||
var sick:Int;
|
||||
var maxCombo:Int;
|
||||
|
||||
var score:Int;
|
||||
|
||||
var isNewHighscore:Bool;
|
||||
|
||||
/**
|
||||
|
||||
+20
-11
@@ -10,7 +10,6 @@ import flixel.math.FlxPoint;
|
||||
import flixel.math.FlxRect;
|
||||
import flixel.system.debug.log.LogStyle;
|
||||
import flixel.util.FlxColor;
|
||||
import funkin.graphics.FunkinSprite;
|
||||
import funkin.data.dialogue.ConversationRegistry;
|
||||
import funkin.data.dialogue.DialogueBoxRegistry;
|
||||
import funkin.data.dialogue.SpeakerRegistry;
|
||||
@@ -67,7 +66,7 @@ class InitState extends FlxState
|
||||
/**
|
||||
* Perform a bunch of game setup, then immediately transition to the title screen.
|
||||
*/
|
||||
public override function create():Void
|
||||
override public function create():Void
|
||||
{
|
||||
// Setup a bunch of important Flixel stuff.
|
||||
setupShit();
|
||||
@@ -125,6 +124,11 @@ class InitState extends FlxState
|
||||
funkin.mobile.util.WebViewUtil.init();
|
||||
#end
|
||||
|
||||
#if FEATURE_MOBILE_AGESIGNALS
|
||||
// Setup AgeSignals
|
||||
funkin.mobile.util.AgeSignalsUtil.init();
|
||||
#end
|
||||
|
||||
#if android
|
||||
// Setup Callback util.
|
||||
funkin.external.android.CallbackUtil.init();
|
||||
@@ -221,7 +225,10 @@ class InitState extends FlxState
|
||||
// DISCORD API SETUP
|
||||
//
|
||||
#if FEATURE_DISCORD_RPC
|
||||
DiscordClient.instance.init();
|
||||
if (Preferences.enabledDiscordRPC)
|
||||
{
|
||||
DiscordClient.instance.init();
|
||||
}
|
||||
|
||||
lime.app.Application.current.onExit.add(function(exitCode)
|
||||
{
|
||||
@@ -237,7 +244,9 @@ class InitState extends FlxState
|
||||
// ANDROID SETUP
|
||||
//
|
||||
#if android
|
||||
FlxG.android.preventDefaultKeys = [flixel.input.android.FlxAndroidKey.BACK];
|
||||
FlxG.android.preventDefaultKeys = [
|
||||
flixel.input.android.FlxAndroidKey.BACK
|
||||
];
|
||||
#end
|
||||
|
||||
//
|
||||
@@ -309,7 +318,8 @@ class InitState extends FlxState
|
||||
}
|
||||
|
||||
#if FEATURE_LOST_FOCUS_VOLUME
|
||||
@:noCompletion var _lastFocusVolume:Null<Float>;
|
||||
@:noCompletion
|
||||
var _lastFocusVolume:Null<Float>;
|
||||
|
||||
function onLostFocus():Void
|
||||
{
|
||||
@@ -335,7 +345,7 @@ class InitState extends FlxState
|
||||
#end
|
||||
|
||||
#if FEATURE_LOST_FOCUS_VOLUME
|
||||
if (FlxG.sound.muted || FlxG.autoPause) return;
|
||||
if (FlxG.sound.muted || FlxG.sound.volume == 0 || FlxG.autoPause) return;
|
||||
if (_lastFocusVolume != null) FlxG.sound.volume = _lastFocusVolume;
|
||||
#end
|
||||
}
|
||||
@@ -383,10 +393,10 @@ class InitState extends FlxState
|
||||
// -DRESULTS
|
||||
FlxG.switchState(() -> new funkin.play.ResultState({
|
||||
storyMode: true,
|
||||
title: "Cum Song Erect by Kawai Sprite",
|
||||
songId: "cum",
|
||||
characterId: "pico",
|
||||
difficultyId: "hard",
|
||||
title: 'Cum Song Erect by Kawai Sprite',
|
||||
songId: 'cum',
|
||||
characterId: 'pico',
|
||||
difficultyId: 'hard',
|
||||
isNewHighscore: true,
|
||||
scoreData: {
|
||||
score: 1_234_567,
|
||||
@@ -457,7 +467,6 @@ class InitState extends FlxState
|
||||
}
|
||||
else
|
||||
{
|
||||
// FlxG.sound.cache(Paths.music('freakyMenu/freakyMenu'));
|
||||
#if mobile
|
||||
funkin.mobile.util.FNFCProvider.onFNFCOpen.add(function(fnfcFile:String)
|
||||
{
|
||||
|
||||
@@ -107,7 +107,7 @@ class Paths implements ConsoleClass
|
||||
return getPath('data/$key.json', TEXT, library);
|
||||
}
|
||||
|
||||
public static function srt(key:String, ?library:String, ?directory:String = "data/"):String
|
||||
public static function srt(key:String, ?library:String, ?directory:String = 'data/'):String
|
||||
{
|
||||
return getPath('$directory$key.srt', TEXT, library);
|
||||
}
|
||||
@@ -181,10 +181,10 @@ class Paths implements ConsoleClass
|
||||
|
||||
public static function getAnimateAtlas(key:String, ?library:String, settings:AtlasSpriteSettings):FlxAnimateFrames
|
||||
{
|
||||
var assetLibrary:String = library ?? "";
|
||||
var graphicKey:String = "";
|
||||
var assetLibrary:String = library ?? '';
|
||||
var graphicKey:String = '';
|
||||
|
||||
if (assetLibrary != "")
|
||||
if (assetLibrary != '')
|
||||
{
|
||||
graphicKey = Paths.animateAtlas(key, assetLibrary);
|
||||
}
|
||||
@@ -229,8 +229,8 @@ class Paths implements ConsoleClass
|
||||
|
||||
enum abstract PathsFunction(String)
|
||||
{
|
||||
var MUSIC;
|
||||
var INST;
|
||||
var VOICES;
|
||||
var SOUND;
|
||||
public var MUSIC;
|
||||
public var INST;
|
||||
public var VOICES;
|
||||
public var SOUND;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ class PlayerSettings
|
||||
public static var player1(default, null):PlayerSettings;
|
||||
@:nullSafety(Off)
|
||||
public static var player2(default, null):PlayerSettings;
|
||||
|
||||
public static var onAvatarAdd(default, null) = new FlxTypedSignal<PlayerSettings->Void>();
|
||||
public static var onAvatarRemove(default, null) = new FlxTypedSignal<PlayerSettings->Void>();
|
||||
|
||||
@@ -45,9 +44,12 @@ class PlayerSettings
|
||||
{
|
||||
return switch (id)
|
||||
{
|
||||
case 1: player1;
|
||||
case 2: player2;
|
||||
default: null;
|
||||
case 1:
|
||||
player1;
|
||||
case 2:
|
||||
player2;
|
||||
default:
|
||||
null;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,9 @@ import funkin.save.Save;
|
||||
import funkin.util.WindowUtil;
|
||||
import funkin.util.HapticUtil.HapticsMode;
|
||||
import funkin.ui.debug.FunkinDebugDisplay.DebugDisplayMode;
|
||||
#if FEATURE_DISCORD_RPC
|
||||
import funkin.api.discord.DiscordClient;
|
||||
#end
|
||||
|
||||
/**
|
||||
* A core class which provides a store of user-configurable, globally relevant values.
|
||||
@@ -158,16 +161,6 @@ class Preferences
|
||||
#if NO_FEATURE_DEBUG_DISPLAY
|
||||
return DebugDisplayMode.Off;
|
||||
#else
|
||||
#if hl
|
||||
// Account for when debugDisplay used to be a boolean
|
||||
var options:Null<SaveDataOptions> = Save.instance?.options;
|
||||
if (options != null && Std.isOfType(options.debugDisplay, Bool))
|
||||
{
|
||||
var convertedDebugDisplay = cast(options.debugDisplay, Bool) ? DebugDisplayMode.Simple : DebugDisplayMode.Off;
|
||||
options.debugDisplay = convertedDebugDisplay;
|
||||
Save.system.flush();
|
||||
}
|
||||
#end
|
||||
return Save?.instance?.options?.debugDisplay ?? 'Off';
|
||||
#end
|
||||
}
|
||||
@@ -215,13 +208,13 @@ class Preferences
|
||||
|
||||
static function get_hapticsMode():HapticsMode
|
||||
{
|
||||
var value = Save?.instance?.options?.hapticsMode ?? "All";
|
||||
var value = Save?.instance?.options?.hapticsMode ?? 'All';
|
||||
|
||||
return switch (value)
|
||||
{
|
||||
case "None":
|
||||
case 'None':
|
||||
HapticsMode.NONE;
|
||||
case "Notes Only":
|
||||
case 'Notes Only':
|
||||
HapticsMode.NOTES_ONLY;
|
||||
default:
|
||||
HapticsMode.ALL;
|
||||
@@ -235,11 +228,11 @@ class Preferences
|
||||
switch (value)
|
||||
{
|
||||
case HapticsMode.NONE:
|
||||
string = "None";
|
||||
string = 'None';
|
||||
case HapticsMode.NOTES_ONLY:
|
||||
string = "Notes Only";
|
||||
string = 'Notes Only';
|
||||
default:
|
||||
string = "All";
|
||||
string = 'All';
|
||||
};
|
||||
|
||||
var save:Save = Save.instance;
|
||||
@@ -347,15 +340,15 @@ class Preferences
|
||||
#if (mobile || web)
|
||||
return lime.ui.WindowVSyncMode.OFF;
|
||||
#else
|
||||
var value = Save?.instance?.options?.vsyncMode ?? "Off";
|
||||
var value = Save?.instance?.options?.vsyncMode ?? 'Off';
|
||||
|
||||
return switch (value)
|
||||
{
|
||||
case "Off":
|
||||
case 'Off':
|
||||
lime.ui.WindowVSyncMode.OFF;
|
||||
case "On":
|
||||
case 'On':
|
||||
lime.ui.WindowVSyncMode.ON;
|
||||
case "Adaptive":
|
||||
case 'Adaptive':
|
||||
lime.ui.WindowVSyncMode.ADAPTIVE;
|
||||
default:
|
||||
lime.ui.WindowVSyncMode.OFF;
|
||||
@@ -373,13 +366,13 @@ class Preferences
|
||||
switch (value)
|
||||
{
|
||||
case lime.ui.WindowVSyncMode.OFF:
|
||||
string = "Off";
|
||||
string = 'Off';
|
||||
case lime.ui.WindowVSyncMode.ON:
|
||||
string = "On";
|
||||
string = 'On';
|
||||
case lime.ui.WindowVSyncMode.ADAPTIVE:
|
||||
string = "Adaptive";
|
||||
string = 'Adaptive';
|
||||
default:
|
||||
string = "Off";
|
||||
string = 'Off';
|
||||
};
|
||||
|
||||
WindowUtil.setVSyncMode(value);
|
||||
@@ -419,6 +412,46 @@ class Preferences
|
||||
#end
|
||||
}
|
||||
|
||||
public static var enabledDiscordRPC(get, set):Bool;
|
||||
|
||||
static function get_enabledDiscordRPC():Bool
|
||||
{
|
||||
return Save?.instance?.options?.enabledDiscordRPC ?? true;
|
||||
}
|
||||
|
||||
static function set_enabledDiscordRPC(value:Bool):Bool
|
||||
{
|
||||
#if FEATURE_DISCORD_RPC
|
||||
toggleDiscordRPC(value);
|
||||
#end
|
||||
|
||||
var save:Save = Save.instance;
|
||||
save.options.enabledDiscordRPC = value;
|
||||
Save.system.flush();
|
||||
return value;
|
||||
}
|
||||
|
||||
#if FEATURE_DISCORD_RPC
|
||||
public static function toggleDiscordRPC(enable:Bool)
|
||||
{
|
||||
if (DiscordClient.instance == null) return;
|
||||
|
||||
if (enable)
|
||||
{
|
||||
DiscordClient.instance.init();
|
||||
|
||||
if (DiscordClient.presenceParamsCache != null)
|
||||
{
|
||||
DiscordClient.instance.setPresence(DiscordClient.presenceParamsCache);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DiscordClient.instance.shutdown();
|
||||
}
|
||||
}
|
||||
#end
|
||||
|
||||
/**
|
||||
* If >0, the game will display a semi-opaque background under the notes.
|
||||
* `0` for no background, `100` for solid black if you're freaky like that
|
||||
@@ -526,13 +559,13 @@ class Preferences
|
||||
|
||||
public static function setDebugDisplayMode(mode:DebugDisplayMode):Void
|
||||
{
|
||||
if (FlxG.game.parent.contains(Main.debugDisplay)) FlxG.game.parent.removeChild(Main.debugDisplay);
|
||||
if (FlxG.game.contains(Main.debugDisplay)) FlxG.game.removeChild(Main.debugDisplay);
|
||||
|
||||
if (mode == DebugDisplayMode.Off) return;
|
||||
|
||||
Main.debugDisplay.isAdvanced = (mode == DebugDisplayMode.Advanced);
|
||||
|
||||
FlxG.game.parent.addChild(Main.debugDisplay);
|
||||
FlxG.game.addChild(Main.debugDisplay);
|
||||
}
|
||||
|
||||
static function setDebugDisplayBGOpacity(value:Float):Void
|
||||
|
||||
@@ -8,25 +8,36 @@ import hxdiscord_rpc.Types.DiscordRichPresence;
|
||||
import hxdiscord_rpc.Types.DiscordUser;
|
||||
import sys.thread.Thread;
|
||||
|
||||
@:build(funkin.util.macro.EnvironmentMacro.build())
|
||||
@:nullSafety
|
||||
/**
|
||||
* Handles integration with the Discord Rich Presence API.
|
||||
*/
|
||||
@:build(funkin.util.macro.EnvironmentMacro.build()) @:nullSafety
|
||||
class DiscordClient
|
||||
{
|
||||
@:envField
|
||||
static final DISCORD_CLIENT_ID:Null<String>;
|
||||
|
||||
/**
|
||||
* The current instance of the singleton Discord client.
|
||||
*/
|
||||
public static var instance(get, never):DiscordClient;
|
||||
|
||||
static var _instance:Null<DiscordClient> = null;
|
||||
|
||||
static function get_instance():DiscordClient
|
||||
{
|
||||
if (DiscordClient._instance == null) _instance = new DiscordClient();
|
||||
if (DiscordClient._instance == null) throw "Could not initialize singleton DiscordClient!";
|
||||
if (DiscordClient._instance == null) throw 'Could not initialize singleton DiscordClient!';
|
||||
return DiscordClient._instance;
|
||||
}
|
||||
|
||||
var handlers:DiscordEventHandlers;
|
||||
|
||||
/**
|
||||
* Latest passed parameters for the presence.
|
||||
*/
|
||||
public static var presenceParamsCache:Null<DiscordClientPresenceParams>;
|
||||
|
||||
private function new()
|
||||
{
|
||||
trace(' DISCORD '.bold().bg_blue() + ' Initializing event handlers...');
|
||||
@@ -44,13 +55,13 @@ class DiscordClient
|
||||
|
||||
if (!hasValidCredentials())
|
||||
{
|
||||
FlxG.log.warn("Tried to initialize Discord connection, but credentials are invalid!");
|
||||
FlxG.log.warn('Tried to initialize Discord connection, but credentials are invalid!');
|
||||
return;
|
||||
}
|
||||
|
||||
@:nullSafety(Off)
|
||||
{
|
||||
Discord.Initialize(DISCORD_CLIENT_ID, cpp.RawPointer.addressOf(handlers), false, "");
|
||||
Discord.Initialize(DISCORD_CLIENT_ID, cpp.RawPointer.addressOf(handlers), false, '');
|
||||
}
|
||||
|
||||
createDaemon();
|
||||
@@ -61,7 +72,7 @@ class DiscordClient
|
||||
*/
|
||||
static function hasValidCredentials():Bool
|
||||
{
|
||||
return !(DISCORD_CLIENT_ID == null || DISCORD_CLIENT_ID == "" || (DISCORD_CLIENT_ID != null && DISCORD_CLIENT_ID.contains(" ")));
|
||||
return !(DISCORD_CLIENT_ID == null || DISCORD_CLIENT_ID == '' || (DISCORD_CLIENT_ID != null && DISCORD_CLIENT_ID.contains(' ')));
|
||||
}
|
||||
|
||||
var daemon:Null<Thread> = null;
|
||||
@@ -93,6 +104,8 @@ class DiscordClient
|
||||
|
||||
public function setPresence(params:DiscordClientPresenceParams):Void
|
||||
{
|
||||
presenceParamsCache = params;
|
||||
|
||||
var presence:DiscordRichPresence = new DiscordRichPresence();
|
||||
|
||||
// Presence should always be playing the game.
|
||||
@@ -102,35 +115,33 @@ class DiscordClient
|
||||
presence.largeImageText = "Friday Night Funkin'";
|
||||
|
||||
// State should be generally what the person is doing, like "In the Menus" or "Pico (Pico Mix) [Freeplay Hard]"
|
||||
presence.state = cast(params.state, Null<String>) ?? "";
|
||||
presence.state = cast(params.state, Null<String>) ?? '';
|
||||
// Details should be what the person is specifically doing, including stuff like timestamps (maybe something like "03:24 elapsed").
|
||||
presence.details = cast(params.details, Null<String>) ?? "";
|
||||
presence.details = cast(params.details, Null<String>) ?? '';
|
||||
|
||||
// The large image displaying what the user is doing.
|
||||
// This should probably be album art.
|
||||
// IMPORTANT NOTE: This can be an asset key uploaded to Discord's developer panel OR any URL you like.
|
||||
presence.largeImageKey = cast(params.largeImageKey, Null<String>) ?? "album-volume1";
|
||||
presence.largeImageKey = cast(params.largeImageKey, Null<String>) ?? 'album-volume1';
|
||||
|
||||
// TODO: Make this use the song's album art.
|
||||
// presence.largeImageKey = "icon";
|
||||
// presence.largeImageKey = "https://f4.bcbits.com/img/a0746694746_16.jpg";
|
||||
|
||||
// The small inset image for what the user is doing.
|
||||
// This can be the opponent's health icon?
|
||||
// NOTE: Like largeImageKey, this can be a URL, or an asset key.
|
||||
presence.smallImageKey = cast(params.smallImageKey, Null<String>) ?? "";
|
||||
presence.smallImageKey = cast(params.smallImageKey, Null<String>) ?? '';
|
||||
|
||||
// NOTE: In previous versions, this showed as "Elapsed", but now shows as playtime and doesn't look good
|
||||
// presence.startTimestamp = time - 10;
|
||||
// presence.endTimestamp = time + 30;
|
||||
|
||||
final button1:DiscordButton = new DiscordButton();
|
||||
button1.label = "Play on Web";
|
||||
button1.label = 'Play on Web';
|
||||
button1.url = Constants.URL_NEWGROUNDS;
|
||||
presence.buttons[0] = button1;
|
||||
|
||||
final button2:DiscordButton = new DiscordButton();
|
||||
button2.label = "Download";
|
||||
button2.label = 'Download';
|
||||
button2.url = Constants.URL_ITCH;
|
||||
presence.buttons[1] = button2;
|
||||
|
||||
@@ -138,6 +149,7 @@ class DiscordClient
|
||||
}
|
||||
|
||||
// TODO: WHAT THE FUCK get this pointer bullfuckery out of here
|
||||
|
||||
private static function onReady(request:cpp.RawConstPointer<DiscordUser>):Void
|
||||
{
|
||||
trace(' DISCORD '.bold().bg_blue() + ' Client has connected!');
|
||||
@@ -166,17 +178,6 @@ class DiscordClient
|
||||
trace(' DISCORD '.bold().bg_blue() + ' Client has received an error! ($errorCode) "${cast (message, String)}"');
|
||||
}
|
||||
|
||||
// public var type(get, set):DiscordActivityType;
|
||||
// public var state(get, set):String;
|
||||
// public var details(get, set):String;
|
||||
// public var startTimestamp(get, set):Int;
|
||||
// public var endTimestamp(get, set):Int;
|
||||
// public var largeImageKey(get, set):String;
|
||||
// public var largeImageText(get, set):String;
|
||||
// public var smallImageKey(get, set):String;
|
||||
// public var smallImageText(get, set):String;
|
||||
//
|
||||
//
|
||||
// public var partyId(get, set)
|
||||
// public var partySize(get, set)
|
||||
// public var partyMax(get, set)
|
||||
|
||||
@@ -3,8 +3,7 @@ package funkin.api.newgrounds;
|
||||
#if FEATURE_NEWGROUNDS_EVENTS
|
||||
import io.newgrounds.Call.CallOutcome;
|
||||
import io.newgrounds.NG;
|
||||
import io.newgrounds.objects.events.Outcome;
|
||||
import io.newgrounds.objects.events.Result;
|
||||
import io.newgrounds.objects.events.Result.LogEventData;
|
||||
#end
|
||||
|
||||
/**
|
||||
@@ -15,7 +14,13 @@ class Events
|
||||
{
|
||||
// Only allow letters, numbers, spaces, dashes, and underscores.
|
||||
static final EVENT_NAME_REGEX:EReg = ~/[^a-zA-Z0-9 -_]/g;
|
||||
static final ERROR_CODE_INVALID_EVENT_NAME:Int = 103;
|
||||
|
||||
/**
|
||||
* Log an analytics event to Newgrounds. Does nothing if the user is not logged in to Newgrounds.
|
||||
*
|
||||
* @param eventName The name of the event to log.
|
||||
*/
|
||||
public static function logEvent(eventName:String):Void
|
||||
{
|
||||
#if (FEATURE_NEWGROUNDS && FEATURE_NEWGROUNDS_EVENTS)
|
||||
@@ -50,7 +55,7 @@ class Events
|
||||
case RESULT(error):
|
||||
switch (error.code)
|
||||
{
|
||||
case 103: // Invalid custom event name
|
||||
case ERROR_CODE_INVALID_EVENT_NAME: // Invalid custom event name
|
||||
trace(' NEWGROUNDS '.bold().bg_orange() + ' Invalid custom event name: ${eventName}');
|
||||
default:
|
||||
trace(' NEWGROUNDS '.bold().bg_orange() + ' Result error (${error.code}) while logging event: ${error.message}');
|
||||
@@ -60,41 +65,80 @@ class Events
|
||||
}
|
||||
#end
|
||||
|
||||
/**
|
||||
* Log an analytics events for the start of the game.
|
||||
*/
|
||||
public static inline function logStartGame():Void
|
||||
{
|
||||
logEvent('start-game');
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an analytics events for the completion of a song.
|
||||
*
|
||||
* @param songId The ID of the song that was played.
|
||||
* @param variation The variation of the song that was played (e.g. 'easy', 'normal', 'hard', 'expert').
|
||||
*/
|
||||
public static inline function logStartSong(songId:String, variation:String):Void
|
||||
{
|
||||
logEvent('start-song_${songId}-${variation}');
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an analytics event for the failure of a song.
|
||||
*
|
||||
* @param songId The ID of the song that was failed.
|
||||
* @param variation The variation of the song that was failed (e.g. 'easy', 'normal', 'hard', 'expert').
|
||||
*/
|
||||
public static inline function logFailSong(songId:String, variation:String):Void
|
||||
{
|
||||
logEvent('blueballs_${songId}-${variation}');
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an analytics event for the completion of a song.
|
||||
*
|
||||
* @param songId The ID of the song that was completed.
|
||||
* @param variation The variation of the song that was completed (e.g. 'easy', 'normal', 'hard', 'expert').
|
||||
*/
|
||||
public static inline function logCompleteSong(songId:String, variation:String):Void
|
||||
{
|
||||
logEvent('complete-song_${songId}-${variation}');
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an analytics event for the start of a level.
|
||||
*
|
||||
* @param levelId The ID of the level that was started.
|
||||
*/
|
||||
public static inline function logStartLevel(levelId:String):Void
|
||||
{
|
||||
logEvent('start-level_${levelId}');
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an analytics event for the completion of a level.
|
||||
*
|
||||
* @param levelId The ID of the level that was completed.
|
||||
*/
|
||||
public static inline function logCompleteLevel(levelId:String):Void
|
||||
{
|
||||
logEvent('complete-level_${levelId}');
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an analytics event for earning a rank.
|
||||
*
|
||||
* @param rankName The name of the rank that was earned.
|
||||
*/
|
||||
public static inline function logEarnRank(rankName:String):Void
|
||||
{
|
||||
logEvent('earn-rank_${rankName}');
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an analytics event for watching a cartoon.
|
||||
*/
|
||||
public static inline function logWatchCartoon():Void
|
||||
{
|
||||
logEvent('watch-cartoon');
|
||||
|
||||
@@ -24,7 +24,7 @@ class Leaderboards
|
||||
var leaderboardList:Null<ScoreBoardList> = NewgroundsClient.instance.leaderboards;
|
||||
if (leaderboardList == null)
|
||||
{
|
||||
trace(' NEWGROUNDS '.bold().bg_orange() + ' Not logged in, cannot fetch medal data!');
|
||||
trace(' NEWGROUNDS '.bold().bg_orange() + ' Not logged in, cannot fetch leaderboard data!');
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ class LeaderboardsSandboxed
|
||||
* @param leaderboard The leaderboard to fetch scores from.
|
||||
* @param params Additional parameters for fetching the score.
|
||||
*/
|
||||
public function requestScores(leaderboard:Leaderboard, params:RequestScoresParams)
|
||||
public static function requestScores(leaderboard:Leaderboard, params:RequestScoresParams)
|
||||
{
|
||||
Leaderboards.requestScores(leaderboard, params);
|
||||
}
|
||||
@@ -217,6 +217,7 @@ typedef RequestScoresParams =
|
||||
/**
|
||||
* An enumeration of Newgrounds leaderboards for the game's levels and songs.
|
||||
*/
|
||||
@SuppressWarnings('checkstyle:FieldDocComment')
|
||||
enum abstract Leaderboard(Int) from Int to Int
|
||||
{
|
||||
/**
|
||||
@@ -236,14 +237,12 @@ enum abstract Leaderboard(Int) from Int to Int
|
||||
public var StoryWeek6 = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 14244 #else 9957 #end;
|
||||
public var StoryWeek7 = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 14245 #else 14682 #end;
|
||||
public var StoryWeekend1 = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 14237 #else 14683 #end;
|
||||
|
||||
// Collab 1 only has one song.
|
||||
//
|
||||
// SONGS
|
||||
//
|
||||
// Tutorial
|
||||
public var Tutorial = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 14249 #else 14684 #end;
|
||||
|
||||
// Week 1
|
||||
public var Bopeebo = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 14246 #else 9603 #end;
|
||||
public var BopeeboErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14685 #end;
|
||||
@@ -254,7 +253,6 @@ enum abstract Leaderboard(Int) from Int to Int
|
||||
public var DadBattle = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 14248 #else 9605 #end;
|
||||
public var DadBattleErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14689 #end;
|
||||
public var DadBattlePicoMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14690 #end;
|
||||
|
||||
// Week 2
|
||||
public var Spookeez = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 9604 #end;
|
||||
public var SpookeezErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14691 #end;
|
||||
@@ -263,7 +261,6 @@ enum abstract Leaderboard(Int) from Int to Int
|
||||
public var SouthErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14693 #end;
|
||||
public var SouthPicoMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14694 #end;
|
||||
public var Monster = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14703 #end;
|
||||
|
||||
// Week 3
|
||||
public var Pico = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 9766 #end;
|
||||
public var PicoErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14695 #end;
|
||||
@@ -274,14 +271,12 @@ enum abstract Leaderboard(Int) from Int to Int
|
||||
public var Blammed = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 9768 #end;
|
||||
public var BlammedErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14704 #end;
|
||||
public var BlammedPicoMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14705 #end;
|
||||
|
||||
// Week 4
|
||||
public var SatinPanties = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 9869 #end;
|
||||
public var SatinPantiesErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14701 #end;
|
||||
public var High = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 9867 #end;
|
||||
public var HighErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14699 #end;
|
||||
public var MILF = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 9868 #end;
|
||||
|
||||
// Week 5
|
||||
public var Cocoa = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14706 #end;
|
||||
public var CocoaErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14707 #end;
|
||||
@@ -290,7 +285,6 @@ enum abstract Leaderboard(Int) from Int to Int
|
||||
public var EggnogErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14711 #end;
|
||||
public var EggnogPicoMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14710 #end;
|
||||
public var WinterHorrorland = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14712 #end;
|
||||
|
||||
// Week 6
|
||||
public var Senpai = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 9958 #end;
|
||||
public var SenpaiErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14713 #end;
|
||||
@@ -300,7 +294,6 @@ enum abstract Leaderboard(Int) from Int to Int
|
||||
public var RosesPicoMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14717 #end;
|
||||
public var Thorns = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 9960 #end;
|
||||
public var ThornsErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14715 #end;
|
||||
|
||||
// Week 7
|
||||
public var Ugh = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14718 #end;
|
||||
public var UghErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14722 #end;
|
||||
@@ -309,7 +302,6 @@ enum abstract Leaderboard(Int) from Int to Int
|
||||
public var GunsPicoMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14723 #end;
|
||||
public var Stress = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14720 #end;
|
||||
public var StressPicoMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14724 #end;
|
||||
|
||||
// Weekend 1
|
||||
public var Darnell = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14725 #end;
|
||||
public var DarnellErect = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14727 #end;
|
||||
@@ -318,7 +310,6 @@ enum abstract Leaderboard(Int) from Int to Int
|
||||
public var LitUpBFMix = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14729 #end;
|
||||
public var TwoHot = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14730 #end; // Variable names can't start with a number!
|
||||
public var Blazin = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 1000000 #else 14731 #end;
|
||||
|
||||
// Collab 1
|
||||
public var Spaghetti = #if FEATURE_NEWGROUNDS_TESTING_MEDALS 15448 #else 15451 #end;
|
||||
|
||||
@@ -340,21 +331,21 @@ enum abstract Leaderboard(Int) from Int to Int
|
||||
{
|
||||
switch (levelId)
|
||||
{
|
||||
case "week1":
|
||||
case 'week1':
|
||||
return StoryWeek1;
|
||||
case "week2":
|
||||
case 'week2':
|
||||
return StoryWeek2;
|
||||
case "week3":
|
||||
case 'week3':
|
||||
return StoryWeek3;
|
||||
case "week4":
|
||||
case 'week4':
|
||||
return StoryWeek4;
|
||||
case "week5":
|
||||
case 'week5':
|
||||
return StoryWeek5;
|
||||
case "week6":
|
||||
case 'week6':
|
||||
return StoryWeek6;
|
||||
case "week7":
|
||||
case 'week7':
|
||||
return StoryWeek7;
|
||||
case "weekend1":
|
||||
case 'weekend1':
|
||||
return StoryWeekend1;
|
||||
// Collab 1 has only one song.
|
||||
default:
|
||||
@@ -380,153 +371,153 @@ enum abstract Leaderboard(Int) from Int to Int
|
||||
}
|
||||
else if (Constants.DEFAULT_DIFFICULTY_LIST_ERECT.contains(difficulty))
|
||||
{
|
||||
variation = "erect";
|
||||
variation = 'erect';
|
||||
}
|
||||
|
||||
switch (variation)
|
||||
{
|
||||
case "pico":
|
||||
case 'pico':
|
||||
switch (songId)
|
||||
{
|
||||
case "bopeebo":
|
||||
case 'bopeebo':
|
||||
return BopeeboPicoMix;
|
||||
case "fresh":
|
||||
case 'fresh':
|
||||
return FreshPicoMix;
|
||||
case "dadbattle":
|
||||
case 'dadbattle':
|
||||
return DadBattlePicoMix;
|
||||
case "spookeez":
|
||||
case 'spookeez':
|
||||
return SpookeezPicoMix;
|
||||
case "south":
|
||||
case 'south':
|
||||
return SouthPicoMix;
|
||||
case "pico":
|
||||
case 'pico':
|
||||
return PicoPicoMix;
|
||||
case "philly-nice":
|
||||
case 'philly-nice':
|
||||
return PhillyNicePicoMix;
|
||||
case "blammed":
|
||||
case 'blammed':
|
||||
return BlammedPicoMix;
|
||||
case "cocoa":
|
||||
case 'cocoa':
|
||||
return CocoaPicoMix;
|
||||
case "eggnog":
|
||||
case 'eggnog':
|
||||
return EggnogPicoMix;
|
||||
case "senpai":
|
||||
case 'senpai':
|
||||
return SenpaiPicoMix;
|
||||
case "roses":
|
||||
case 'roses':
|
||||
return RosesPicoMix;
|
||||
case "ugh":
|
||||
case 'ugh':
|
||||
return UghPicoMix;
|
||||
case "guns":
|
||||
case 'guns':
|
||||
return GunsPicoMix;
|
||||
case "stress":
|
||||
case 'stress':
|
||||
return StressPicoMix;
|
||||
default:
|
||||
return Unknown;
|
||||
}
|
||||
case "bf":
|
||||
case 'bf':
|
||||
switch (songId)
|
||||
{
|
||||
case "darnell":
|
||||
case 'darnell':
|
||||
return DarnellBFMix;
|
||||
case "lit-up":
|
||||
case 'lit-up':
|
||||
return LitUpBFMix;
|
||||
default:
|
||||
return Unknown;
|
||||
}
|
||||
case "erect":
|
||||
case 'erect':
|
||||
switch (songId)
|
||||
{
|
||||
case "bopeebo":
|
||||
case 'bopeebo':
|
||||
return BopeeboErect;
|
||||
case "fresh":
|
||||
case 'fresh':
|
||||
return FreshErect;
|
||||
case "dadbattle":
|
||||
case 'dadbattle':
|
||||
return DadBattleErect;
|
||||
case "spookeez":
|
||||
case 'spookeez':
|
||||
return SpookeezErect;
|
||||
case "south":
|
||||
case 'south':
|
||||
return SouthErect;
|
||||
case "pico":
|
||||
case 'pico':
|
||||
return PicoErect;
|
||||
case "philly-nice":
|
||||
case 'philly-nice':
|
||||
return PhillyNiceErect;
|
||||
case "blammed":
|
||||
case 'blammed':
|
||||
return BlammedErect;
|
||||
case "satin-panties":
|
||||
case 'satin-panties':
|
||||
return SatinPantiesErect;
|
||||
case "high":
|
||||
case 'high':
|
||||
return HighErect;
|
||||
case "cocoa":
|
||||
case 'cocoa':
|
||||
return CocoaErect;
|
||||
case "eggnog":
|
||||
case 'eggnog':
|
||||
return EggnogErect;
|
||||
case "senpai":
|
||||
case 'senpai':
|
||||
return SenpaiErect;
|
||||
case "roses":
|
||||
case 'roses':
|
||||
return RosesErect;
|
||||
case "thorns":
|
||||
case 'thorns':
|
||||
return ThornsErect;
|
||||
case "ugh":
|
||||
case 'ugh':
|
||||
return UghErect;
|
||||
case "darnell":
|
||||
case 'darnell':
|
||||
return DarnellErect;
|
||||
default:
|
||||
return Unknown;
|
||||
}
|
||||
case "default":
|
||||
case 'default':
|
||||
switch (songId)
|
||||
{
|
||||
case "tutorial":
|
||||
case 'tutorial':
|
||||
return Tutorial;
|
||||
case "bopeebo":
|
||||
case 'bopeebo':
|
||||
return Bopeebo;
|
||||
case "fresh":
|
||||
case 'fresh':
|
||||
return Fresh;
|
||||
case "dadbattle":
|
||||
case 'dadbattle':
|
||||
return DadBattle;
|
||||
case "spookeez":
|
||||
case 'spookeez':
|
||||
return Spookeez;
|
||||
case "south":
|
||||
case 'south':
|
||||
return South;
|
||||
case "monster":
|
||||
case 'monster':
|
||||
return Monster;
|
||||
case "pico":
|
||||
case 'pico':
|
||||
return Pico;
|
||||
case "philly-nice":
|
||||
case 'philly-nice':
|
||||
return PhillyNice;
|
||||
case "blammed":
|
||||
case 'blammed':
|
||||
return Blammed;
|
||||
case "satin-panties":
|
||||
case 'satin-panties':
|
||||
return SatinPanties;
|
||||
case "high":
|
||||
case 'high':
|
||||
return High;
|
||||
case "milf":
|
||||
case 'milf':
|
||||
return MILF;
|
||||
case "cocoa":
|
||||
case 'cocoa':
|
||||
return Cocoa;
|
||||
case "eggnog":
|
||||
case 'eggnog':
|
||||
return Eggnog;
|
||||
case "winter-horrorland":
|
||||
case 'winter-horrorland':
|
||||
return WinterHorrorland;
|
||||
case "senpai":
|
||||
case 'senpai':
|
||||
return Senpai;
|
||||
case "roses":
|
||||
case 'roses':
|
||||
return Roses;
|
||||
case "thorns":
|
||||
case 'thorns':
|
||||
return Thorns;
|
||||
case "ugh":
|
||||
case 'ugh':
|
||||
return Ugh;
|
||||
case "guns":
|
||||
case 'guns':
|
||||
return Guns;
|
||||
case "stress":
|
||||
case 'stress':
|
||||
return Stress;
|
||||
case "darnell":
|
||||
case 'darnell':
|
||||
return Darnell;
|
||||
case "lit-up":
|
||||
case 'lit-up':
|
||||
return LitUp;
|
||||
case "2hot":
|
||||
case '2hot':
|
||||
return TwoHot;
|
||||
case "blazin":
|
||||
case 'blazin':
|
||||
return Blazin;
|
||||
case "spaghetti":
|
||||
case 'spaghetti':
|
||||
return Spaghetti;
|
||||
default:
|
||||
return Unknown;
|
||||
|
||||
@@ -58,7 +58,7 @@ class Medals
|
||||
// Play the medal unlock animation, but only if the user has not already unlocked it.
|
||||
#if html5
|
||||
// Web builds support parsing the bitmap data from the URL directly.
|
||||
BitmapData.loadFromFile("https:" + medalData.icon).onComplete(function(bmp:BitmapData)
|
||||
BitmapData.loadFromFile('https:' + medalData.icon).onComplete(function(bmp:BitmapData)
|
||||
{
|
||||
var medalGraphic = FlxGraphic.fromBitmapData(bmp);
|
||||
medalGraphic.persist = true;
|
||||
@@ -78,12 +78,12 @@ class Medals
|
||||
#end
|
||||
})[0];
|
||||
|
||||
if (localMedalData == null) throw "You forgot to encode a Base64 image for medal: " + medal;
|
||||
if (localMedalData == null) throw 'You forgot to encode a Base64 image for medal: ' + medal;
|
||||
|
||||
var str:String = localMedalData.icon;
|
||||
// Lime/OpenFL parses it without the included prefix stuff, so we remove it.
|
||||
str = str.replace("data:image/png;base64,", "").trim();
|
||||
var bitmapData = BitmapData.fromBase64(str, "image/png");
|
||||
str = str.replace('data:image/png;base64,', '').trim();
|
||||
var bitmapData = BitmapData.fromBase64(str, 'image/png');
|
||||
var medalGraphic:Null<FlxGraphic> = null;
|
||||
if (str != null)
|
||||
{
|
||||
@@ -122,8 +122,7 @@ class Medals
|
||||
if (parser.errors.length > 0)
|
||||
{
|
||||
trace(' NEWGROUNDS '.bold().bg_orange() + ' Failed to parse local medal data!');
|
||||
for (error in parser.errors)
|
||||
funkin.data.DataError.printError(error);
|
||||
for (error in parser.errors) funkin.data.DataError.printError(error);
|
||||
medalJSON = [];
|
||||
}
|
||||
else
|
||||
@@ -407,25 +406,25 @@ enum abstract Medal(Int) from Int to Int
|
||||
{
|
||||
switch (levelId)
|
||||
{
|
||||
case "tutorial":
|
||||
case 'tutorial':
|
||||
return StoryTutorial;
|
||||
case "week1":
|
||||
case 'week1':
|
||||
return StoryWeek1;
|
||||
case "week2":
|
||||
case 'week2':
|
||||
return StoryWeek2;
|
||||
case "week3":
|
||||
case 'week3':
|
||||
return StoryWeek3;
|
||||
case "week4":
|
||||
case 'week4':
|
||||
return StoryWeek4;
|
||||
case "week5":
|
||||
case 'week5':
|
||||
return StoryWeek5;
|
||||
case "week6":
|
||||
case 'week6':
|
||||
return StoryWeek6;
|
||||
case "week7":
|
||||
case 'week7':
|
||||
return StoryWeek7;
|
||||
case "weekend1":
|
||||
case 'weekend1':
|
||||
return StoryWeekend1;
|
||||
case "sserafim":
|
||||
case 'sserafim':
|
||||
return StoryCollab1;
|
||||
default:
|
||||
return Unknown;
|
||||
@@ -438,7 +437,27 @@ enum abstract Medal(Int) from Int to Int
|
||||
*/
|
||||
public static function getAllMedals():Array<Medal>
|
||||
{
|
||||
return
|
||||
[StartGame, StoryTutorial, StoryWeek1, StoryWeek2, StoryWeek3, StoryWeek4, StoryWeek5, StoryWeek6, StoryWeek7, StoryWeekend1, CharSelect, FreeplayPicoMix, FreeplayStressPico, LossRating, PerfectRatingHard, GoldPerfectRatingHard, ErectDifficulty, GoldPerfectRatingNightmare, FridayNight, Nice];
|
||||
return [
|
||||
StartGame,
|
||||
StoryTutorial,
|
||||
StoryWeek1,
|
||||
StoryWeek2,
|
||||
StoryWeek3,
|
||||
StoryWeek4,
|
||||
StoryWeek5,
|
||||
StoryWeek6,
|
||||
StoryWeek7,
|
||||
StoryWeekend1,
|
||||
CharSelect,
|
||||
FreeplayPicoMix,
|
||||
FreeplayStressPico,
|
||||
LossRating,
|
||||
PerfectRatingHard,
|
||||
GoldPerfectRatingHard,
|
||||
ErectDifficulty,
|
||||
GoldPerfectRatingNightmare,
|
||||
FridayNight,
|
||||
Nice
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
package funkin.api.newgrounds;
|
||||
|
||||
#if FEATURE_NEWGROUNDS
|
||||
import io.newgrounds.utils.SaveSlotList;
|
||||
import io.newgrounds.objects.SaveSlot;
|
||||
import io.newgrounds.Call.CallError;
|
||||
import io.newgrounds.objects.events.Outcome;
|
||||
import funkin.save.Save;
|
||||
import funkin.save.Save.RawSaveData;
|
||||
|
||||
@:nullSafety
|
||||
@:access(funkin.save.Save)
|
||||
@:nullSafety @:access(funkin.save.Save)
|
||||
class NGSaveSlot
|
||||
{
|
||||
public static var instance(get, never):NGSaveSlot;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package funkin.api.newgrounds;
|
||||
|
||||
import funkin.save.Save;
|
||||
import funkin.api.newgrounds.Medals.Medal;
|
||||
#if FEATURE_NEWGROUNDS
|
||||
import funkin.save.Save;
|
||||
import io.newgrounds.Call.CallError;
|
||||
import io.newgrounds.NG;
|
||||
import io.newgrounds.NGLite;
|
||||
@@ -17,24 +16,20 @@ import io.newgrounds.objects.User;
|
||||
import funkin.mobile.util.WebViewUtil;
|
||||
#end
|
||||
|
||||
@:build(funkin.util.macro.EnvironmentMacro.build())
|
||||
@:nullSafety
|
||||
@:build(funkin.util.macro.EnvironmentMacro.build()) @:nullSafety
|
||||
class NewgroundsClient
|
||||
{
|
||||
@:envField
|
||||
static final API_NG_APP_ID:Null<String>;
|
||||
|
||||
@:envField
|
||||
static final API_NG_ENC_KEY:Null<String>;
|
||||
|
||||
public static var instance(get, never):NewgroundsClient;
|
||||
|
||||
static var _instance:Null<NewgroundsClient> = null;
|
||||
|
||||
static function get_instance():NewgroundsClient
|
||||
{
|
||||
if (NewgroundsClient._instance == null) _instance = new NewgroundsClient();
|
||||
if (NewgroundsClient._instance == null) throw "Could not initialize singleton NewgroundsClient!";
|
||||
if (NewgroundsClient._instance == null) throw 'Could not initialize singleton NewgroundsClient!';
|
||||
return NewgroundsClient._instance;
|
||||
}
|
||||
|
||||
@@ -54,7 +49,7 @@ class NewgroundsClient
|
||||
|
||||
if (!hasValidCredentials())
|
||||
{
|
||||
FlxG.log.warn("Tried to initialize Newgrounds client, but credentials are invalid!");
|
||||
FlxG.log.warn('Tried to initialize Newgrounds client, but credentials are invalid!');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -104,7 +99,7 @@ class NewgroundsClient
|
||||
{
|
||||
if (NG.core == null)
|
||||
{
|
||||
FlxG.log.warn("No Newgrounds client initialized! Are your credentials invalid?");
|
||||
FlxG.log.warn('No Newgrounds client initialized! Are your credentials invalid?');
|
||||
return;
|
||||
}
|
||||
if (NG.core.attemptingLogin)
|
||||
@@ -129,7 +124,7 @@ class NewgroundsClient
|
||||
NG.core.onPassportUrlOpen();
|
||||
}
|
||||
else
|
||||
NG.core.logError("Cannot open passport");
|
||||
NG.core.logError('Cannot open passport');
|
||||
#else
|
||||
NG.core.openPassportUrl();
|
||||
#end
|
||||
@@ -149,7 +144,7 @@ class NewgroundsClient
|
||||
{
|
||||
if (NG.core == null)
|
||||
{
|
||||
FlxG.log.warn("No Newgrounds client initialized! Are your credentials invalid?");
|
||||
FlxG.log.warn('No Newgrounds client initialized! Are your credentials invalid?');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -211,11 +206,11 @@ class NewgroundsClient
|
||||
static function hasValidCredentials():Bool
|
||||
{
|
||||
return !(API_NG_APP_ID == null
|
||||
|| API_NG_APP_ID == ""
|
||||
|| (API_NG_APP_ID != null && API_NG_APP_ID.contains(" "))
|
||||
|| API_NG_APP_ID == ''
|
||||
|| (API_NG_APP_ID != null && API_NG_APP_ID.contains(' '))
|
||||
|| API_NG_ENC_KEY == null
|
||||
|| API_NG_ENC_KEY == ""
|
||||
|| (API_NG_ENC_KEY != null && API_NG_ENC_KEY.contains(" ")));
|
||||
|| API_NG_ENC_KEY == ''
|
||||
|| (API_NG_ENC_KEY != null && API_NG_ENC_KEY.contains(' ')));
|
||||
}
|
||||
|
||||
function onLoginResolved(outcome:LoginOutcome):Void
|
||||
@@ -349,8 +344,6 @@ class NewgroundsClient
|
||||
function onFetchedLeaderboards(outcome:Outcome<CallError>):Void
|
||||
{
|
||||
trace(' NEWGROUNDS '.bold().bg_orange() + ' Fetched leaderboards!');
|
||||
|
||||
// trace(funkin.api.newgrounds.Leaderboards.listLeaderboardData());
|
||||
}
|
||||
|
||||
function onFetchedSaveSlots(outcome:Outcome<CallError>):Void
|
||||
|
||||
@@ -3,7 +3,6 @@ package funkin.api.newgrounds;
|
||||
#if FEATURE_NEWGROUNDS
|
||||
import io.newgrounds.NG;
|
||||
#end
|
||||
import funkin.api.newgrounds.NewgroundsClient;
|
||||
import funkin.util.WindowUtil;
|
||||
|
||||
/**
|
||||
@@ -22,7 +21,7 @@ class Referral
|
||||
if (NewgroundsClient.instance.isLoggedIn())
|
||||
{
|
||||
NG.core?.calls.loader.loadReferral(false)
|
||||
.addComponentParameter("referral_name", referralName)
|
||||
.addComponentParameter('referral_name', referralName)
|
||||
.addResponseHandler(response ->
|
||||
{
|
||||
trace(response);
|
||||
@@ -51,6 +50,6 @@ class Referral
|
||||
*/
|
||||
public static function doMerchReferral():Void
|
||||
{
|
||||
doReferral("merch_link", Constants.URL_MERCH_FALLBACK);
|
||||
doReferral('merch_link', Constants.URL_MERCH_FALLBACK);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package funkin.audio;
|
||||
|
||||
import flixel.group.FlxGroup.FlxTypedGroup;
|
||||
import flixel.math.FlxMath;
|
||||
import flixel.sound.FlxSound;
|
||||
import flixel.system.FlxAssets.FlxSoundAsset;
|
||||
import flixel.tweens.FlxTween;
|
||||
@@ -16,7 +15,6 @@ import funkin.Paths.PathsFunction;
|
||||
import lime.app.Promise;
|
||||
import lime.media.AudioSource;
|
||||
import openfl.events.Event;
|
||||
import openfl.media.Sound;
|
||||
import openfl.media.SoundChannel;
|
||||
import openfl.media.SoundMixer;
|
||||
|
||||
@@ -123,14 +121,14 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
||||
/**
|
||||
* For debug purposes.
|
||||
*/
|
||||
var _label:String = "unknown";
|
||||
var _label:String = 'unknown';
|
||||
|
||||
public function new()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public override function update(elapsedSec:Float)
|
||||
override public function update(elapsedSec:Float)
|
||||
{
|
||||
if (!playing && !_shouldPlay) return;
|
||||
|
||||
@@ -171,7 +169,7 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
||||
return this;
|
||||
}
|
||||
|
||||
public override function play(forceRestart:Bool = false, startTime:Float = 0, ?endTime:Float):FunkinSound
|
||||
override public function play(forceRestart:Bool = false, startTime:Float = 0, ?endTime:Float):FunkinSound
|
||||
{
|
||||
if (!exists) return this;
|
||||
|
||||
@@ -208,7 +206,7 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
||||
}
|
||||
}
|
||||
|
||||
public override function pause():FunkinSound
|
||||
override public function pause():FunkinSound
|
||||
{
|
||||
if (_shouldPlay)
|
||||
{
|
||||
@@ -225,7 +223,7 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
||||
return this;
|
||||
}
|
||||
|
||||
public override function resume():FunkinSound
|
||||
override public function resume():FunkinSound
|
||||
{
|
||||
if (this._time < 0)
|
||||
{
|
||||
@@ -329,9 +327,12 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
||||
var suffix = params.suffix ?? '';
|
||||
var pathToUse = switch (pathsFunction)
|
||||
{
|
||||
case MUSIC: Paths.music('$key/$key');
|
||||
case INST: Paths.inst('$key', suffix);
|
||||
default: Paths.music('$key/$key');
|
||||
case MUSIC:
|
||||
Paths.music('$key/$key');
|
||||
case INST:
|
||||
Paths.inst('$key', suffix);
|
||||
default:
|
||||
Paths.music('$key/$key');
|
||||
}
|
||||
|
||||
var shouldLoadPartial = params.partialParams?.loadPartial ?? false;
|
||||
@@ -401,7 +402,7 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
||||
while (partialQueue.length > 0)
|
||||
{
|
||||
@:nullSafety(Off)
|
||||
partialQueue.pop().error("Cancel loading partial sound");
|
||||
partialQueue.pop().error('Cancel loading partial sound');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,7 +420,7 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
||||
* @param autoPlay Whether to play the sound immediately or wait for a `play()` call.
|
||||
* @param persist Whether to keep this `FunkinSound` between states, or destroy it.
|
||||
* @param onComplete Called when the sound finished playing.
|
||||
* @param onLoad Called when the sound finished loading. Called immediately for succesfully loaded embedded sounds.
|
||||
* @param onLoad Called when the sound finished loading. Called immediately for successfully loaded embedded sounds.
|
||||
* @param important If `true`, the sound channel will forcefully be added onto the channel array, even if full. Use sparingly!
|
||||
* @return A `FunkinSound` object, or `null` if the sound could not be loaded.
|
||||
*/
|
||||
@@ -500,7 +501,7 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
||||
{
|
||||
promise.future.onError(function(e)
|
||||
{
|
||||
soundRequest.error("Sound loading was errored or cancelled");
|
||||
soundRequest.error('Sound loading was errored or cancelled');
|
||||
});
|
||||
|
||||
soundRequest.future.onComplete(function(partialSound)
|
||||
@@ -514,9 +515,8 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
||||
}
|
||||
|
||||
@:nullSafety(Off)
|
||||
public override function destroy():Void
|
||||
override public function destroy():Void
|
||||
{
|
||||
// trace('[FunkinSound] Destroying sound "${this._label}"');
|
||||
super.destroy();
|
||||
if (fadeTween != null)
|
||||
{
|
||||
@@ -528,9 +528,7 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
||||
this._waveformData = null;
|
||||
}
|
||||
|
||||
@:access(openfl.media.Sound)
|
||||
@:access(openfl.media.SoundChannel)
|
||||
@:access(openfl.media.SoundMixer)
|
||||
@:access(openfl.media.Sound) @:access(openfl.media.SoundChannel) @:access(openfl.media.SoundMixer)
|
||||
override function startSound(startTime:Float)
|
||||
{
|
||||
if (!important)
|
||||
@@ -602,7 +600,7 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
|
||||
/**
|
||||
* Produces a string representation suitable for debugging.
|
||||
*/
|
||||
public override function toString():String
|
||||
override public function toString():String
|
||||
{
|
||||
return 'FunkinSound(${this._label})';
|
||||
}
|
||||
|
||||
@@ -11,13 +11,9 @@ import flixel.tweens.FlxTween;
|
||||
class SoundGroup extends FlxTypedGroup<FunkinSound>
|
||||
{
|
||||
public var time(get, set):Float;
|
||||
|
||||
public var volume(get, set):Float;
|
||||
|
||||
public var muted(get, set):Bool;
|
||||
|
||||
public var pitch(get, set):Float;
|
||||
|
||||
public var playing(get, never):Bool;
|
||||
|
||||
public function new()
|
||||
@@ -25,8 +21,8 @@ class SoundGroup extends FlxTypedGroup<FunkinSound>
|
||||
super();
|
||||
}
|
||||
|
||||
@:deprecated("Create sound files and call add() instead")
|
||||
public static function build(song:String, ?files:Array<String> = null):SoundGroup
|
||||
@:deprecated('Create sound files and call add() instead')
|
||||
public static function build(song:String, ?files:Array<String>):SoundGroup
|
||||
{
|
||||
var result = new SoundGroup();
|
||||
|
||||
@@ -73,7 +69,7 @@ class SoundGroup extends FlxTypedGroup<FunkinSound>
|
||||
/**
|
||||
* Add a sound to the group.
|
||||
*/
|
||||
public override function add(sound:FunkinSound):Null<FunkinSound>
|
||||
override public function add(sound:FunkinSound):Null<FunkinSound>
|
||||
{
|
||||
var result:FunkinSound = super.add(sound);
|
||||
|
||||
@@ -83,7 +79,7 @@ class SoundGroup extends FlxTypedGroup<FunkinSound>
|
||||
// else the sound will restart immediately when played.
|
||||
// TODO: Past me experienced that issue but present me didn't? Investigate.
|
||||
// result.play(true, 0.0);
|
||||
// result.pause();
|
||||
|
||||
result.time = this.time;
|
||||
|
||||
result.onComplete = function()
|
||||
@@ -122,7 +118,6 @@ class SoundGroup extends FlxTypedGroup<FunkinSound>
|
||||
{
|
||||
if (sound.length < startTime)
|
||||
{
|
||||
// trace('Queuing sound (${sound.toString()} past its length! Skipping...)');
|
||||
return;
|
||||
}
|
||||
sound.play(forceRestart, startTime, endTime);
|
||||
@@ -178,7 +173,7 @@ class SoundGroup extends FlxTypedGroup<FunkinSound>
|
||||
}
|
||||
}
|
||||
|
||||
public override function destroy():Void
|
||||
override public function destroy():Void
|
||||
{
|
||||
stop();
|
||||
super.destroy();
|
||||
@@ -187,7 +182,7 @@ class SoundGroup extends FlxTypedGroup<FunkinSound>
|
||||
/**
|
||||
* Remove all sounds from the group.
|
||||
*/
|
||||
public override function clear():Void
|
||||
override public function clear():Void
|
||||
{
|
||||
this.stop();
|
||||
|
||||
@@ -242,6 +237,7 @@ class SoundGroup extends FlxTypedGroup<FunkinSound>
|
||||
}
|
||||
|
||||
// in PlayState, adjust the code so that it only mutes the player1 vocal tracks?
|
||||
|
||||
function set_volume(volume:Float):Float
|
||||
{
|
||||
forEachAlive(function(snd:FunkinSound)
|
||||
|
||||
@@ -163,14 +163,14 @@ class VoicesGroup extends SoundGroup
|
||||
return opponentVoices?.members[0]?.length ?? 0.0;
|
||||
}
|
||||
|
||||
public override function clear():Void
|
||||
override public function clear():Void
|
||||
{
|
||||
playerVoices?.clear();
|
||||
opponentVoices?.clear();
|
||||
super.clear();
|
||||
}
|
||||
|
||||
public override function destroy():Void
|
||||
override public function destroy():Void
|
||||
{
|
||||
if (playerVoices != null)
|
||||
{
|
||||
|
||||
@@ -15,7 +15,6 @@ class ABotVis extends FlxTypedSpriteGroup<FlxSprite>
|
||||
// public var vis:VisShit;
|
||||
var analyzer:Null<SpectralAnalyzer> = null;
|
||||
var analyzerLevelsCache:Array<Bar> = new Array<Bar>();
|
||||
|
||||
var volumes:Array<Float> = [];
|
||||
|
||||
public var snd:Null<FlxSound> = null;
|
||||
@@ -23,6 +22,7 @@ class ABotVis extends FlxTypedSpriteGroup<FlxSprite>
|
||||
static final BAR_COUNT:Int = 7;
|
||||
|
||||
// TODO: Make the sprites easier to soft code.
|
||||
|
||||
public function new(snd:FlxSound, pixel:Bool)
|
||||
{
|
||||
super();
|
||||
@@ -35,8 +35,40 @@ class ABotVis extends FlxTypedSpriteGroup<FlxSprite>
|
||||
var visFrms:FlxAtlasFrames = Paths.getSparrowAtlas(pixel ? 'characters/abotPixel/aBotVizPixel' : 'characters/abot/aBotViz');
|
||||
|
||||
// these are the differences in X position, from left to right
|
||||
var positionX:Array<Float> = pixel ? [0, 7 * 6, 8 * 6, 9 * 6, 10 * 6, 6 * 6, 7 * 6] : [0, 59, 56, 66, 54, 52, 51];
|
||||
var positionY:Array<Float> = pixel ? [0, -2 * 6, -1 * 6, 0, 0, 1 * 6, 2 * 6] : [0, -8, -3.5, -0.4, 0.5, 4.7, 7];
|
||||
var positionX:Array<Float> = pixel ? [
|
||||
0,
|
||||
7 * 6,
|
||||
8 * 6,
|
||||
9 * 6,
|
||||
10 * 6,
|
||||
6 * 6,
|
||||
7 * 6
|
||||
] : [
|
||||
0,
|
||||
59,
|
||||
56,
|
||||
66,
|
||||
54,
|
||||
52,
|
||||
51
|
||||
];
|
||||
var positionY:Array<Float> = pixel ? [
|
||||
0,
|
||||
-2 * 6,
|
||||
-1 * 6,
|
||||
0,
|
||||
0,
|
||||
1 * 6,
|
||||
2 * 6
|
||||
] : [
|
||||
0,
|
||||
-8,
|
||||
-3.5,
|
||||
-0.4,
|
||||
0.5,
|
||||
4.7,
|
||||
7
|
||||
];
|
||||
|
||||
for (index in 1...visCount)
|
||||
{
|
||||
@@ -89,9 +121,6 @@ class ABotVis extends FlxTypedSpriteGroup<FlxSprite>
|
||||
analyzer = null;
|
||||
}
|
||||
|
||||
var visTimer:Float = -1;
|
||||
var visTimeMax:Float = 1 / 30;
|
||||
|
||||
override function update(elapsed:Float)
|
||||
{
|
||||
super.update(elapsed);
|
||||
|
||||
@@ -23,7 +23,6 @@ class PolygonSpectogram extends MeshRender
|
||||
|
||||
public var audioData:Int16Array;
|
||||
public var detail:Float = 1;
|
||||
|
||||
public var thickness:Float = 2;
|
||||
public var waveAmplitude:Int = 100;
|
||||
|
||||
@@ -89,7 +88,7 @@ class PolygonSpectogram extends MeshRender
|
||||
|
||||
var funnyPixels:Int = Std.int(daHeight * detail); // sorta redundant but just need it for different var...
|
||||
|
||||
if (prevAudioData == audioData.subarray(startSample, startSample + samplesToGen)) return; // optimize / finish funciton here, no need to re-render
|
||||
if (prevAudioData == audioData.subarray(startSample, startSample + samplesToGen)) return; // optimize / finish function here, no need to re-render
|
||||
|
||||
prevAudioData = audioData.subarray(startSample, samplesToGen);
|
||||
|
||||
|
||||
@@ -92,13 +92,13 @@ class PolygonVisGroup extends FlxTypedGroup<PolygonSpectogram>
|
||||
* @param vis The visualizer to add.
|
||||
* @return The added visualizer.
|
||||
*/
|
||||
public override function add(vis:PolygonSpectogram):PolygonSpectogram
|
||||
override public function add(vis:PolygonSpectogram):PolygonSpectogram
|
||||
{
|
||||
var result:PolygonSpectogram = super.add(vis);
|
||||
return result;
|
||||
}
|
||||
|
||||
public override function destroy():Void
|
||||
override public function destroy():Void
|
||||
{
|
||||
if (playerVis != null)
|
||||
{
|
||||
|
||||
@@ -16,14 +16,11 @@ using flixel.util.FlxSpriteUtil;
|
||||
class SpectogramSprite extends FlxTypedSpriteGroup<FlxSprite>
|
||||
{
|
||||
var sampleRate:Int;
|
||||
|
||||
var lengthOfShit:Int = 500;
|
||||
|
||||
public var visType:VISTYPE = UPDATED;
|
||||
|
||||
public var col:Int = FlxColor.WHITE;
|
||||
public var daHeight:Float = FlxG.height;
|
||||
|
||||
public var vis:VisShit;
|
||||
|
||||
public function new(daSound:FlxSound, ?col:FlxColor = FlxColor.WHITE, ?height:Float = 720, ?amnt:Int = 500)
|
||||
@@ -193,8 +190,7 @@ class SpectogramSprite extends FlxTypedSpriteGroup<FlxSprite>
|
||||
|
||||
var freqPower:Float = 0;
|
||||
|
||||
for (pow in 0...freqShit.length)
|
||||
freqPower += freqShit[pow][remappedFreq];
|
||||
for (pow in 0...freqShit.length) freqPower += freqShit[pow][remappedFreq];
|
||||
|
||||
freqPower /= freqShit.length;
|
||||
var freqIDK:Float = FlxMath.remapToRange(freqPower, 0, 0.000005, 0, 50);
|
||||
|
||||
@@ -64,7 +64,9 @@ class VisShit
|
||||
while (c < samples.length)
|
||||
{
|
||||
// take a chunk (zero-padded if needed) and apply the window
|
||||
final chunk = [for (n in 0...fftN) (c + n < samples.length ? samples[c + n] : 0.0) * window(n)];
|
||||
final chunk = [
|
||||
for (n in 0...fftN) (c + n < samples.length ? samples[c + n] : 0.0) * window(n)
|
||||
];
|
||||
|
||||
// compute positive spectrum with sampling correction and BP filter
|
||||
final freqs = FFT.rfft(chunk).map(z -> z.scale(1 / fftN).magnitude).mapi(melodicBandPass);
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package funkin.audio.visualize.dsp;
|
||||
|
||||
/**
|
||||
Complex number representation.
|
||||
**/
|
||||
@:forward(real, imag) @:notNull @:pure
|
||||
@:nullSafety
|
||||
* Complex number representation.
|
||||
*/
|
||||
@:forward(real, imag) @:notNull @:pure @:nullSafety
|
||||
abstract Complex({
|
||||
final real:Float;
|
||||
final imag:Float;
|
||||
@@ -13,21 +12,21 @@ abstract Complex({
|
||||
public inline function new(real:Float, imag:Float) this = {real: real, imag: imag};
|
||||
|
||||
/**
|
||||
Makes a Complex number with the given Float as its real part and a zero imag part.
|
||||
**/
|
||||
* Makes a Complex number with the given Float as its real part and a zero imag part.
|
||||
*/
|
||||
@:from
|
||||
public static inline function fromReal(r:Float) return new Complex(r, 0);
|
||||
|
||||
/**
|
||||
Complex argument, in radians.
|
||||
**/
|
||||
* Complex argument, in radians.
|
||||
*/
|
||||
public var angle(get, never):Float;
|
||||
|
||||
inline function get_angle() return Math.atan2(this.imag, this.real);
|
||||
|
||||
/**
|
||||
Complex module.
|
||||
**/
|
||||
* Complex module.
|
||||
*/
|
||||
public var magnitude(get, never):Float;
|
||||
|
||||
inline function get_magnitude() return Math.sqrt(this.real * this.real + this.imag * this.imag);
|
||||
@@ -42,29 +41,29 @@ abstract Complex({
|
||||
public inline function mult(rhs:Complex):Complex return new Complex(this.real * rhs.real - this.imag * rhs.imag, this.real * rhs.imag + this.imag * rhs.real);
|
||||
|
||||
/**
|
||||
Returns the complex conjugate, does not modify this object.
|
||||
**/
|
||||
* Returns the complex conjugate, does not modify this object.
|
||||
*/
|
||||
public inline function conj():Complex return new Complex(this.real, -this.imag);
|
||||
|
||||
/**
|
||||
Multiplication by a real factor, does not modify this object.
|
||||
**/
|
||||
* Multiplication by a real factor, does not modify this object.
|
||||
*/
|
||||
public inline function scale(k:Float):Complex return new Complex(this.real * k, this.imag * k);
|
||||
|
||||
public inline function copy():Complex return new Complex(this.real, this.imag);
|
||||
|
||||
/**
|
||||
The imaginary unit.
|
||||
**/
|
||||
* The imaginary unit.
|
||||
*/
|
||||
public static final im = new Complex(0, 1);
|
||||
|
||||
/**
|
||||
The complex zero.
|
||||
**/
|
||||
* The complex zero.
|
||||
*/
|
||||
public static final zero = new Complex(0, 0);
|
||||
|
||||
/**
|
||||
Computes the complex exponential `e^(iw)`.
|
||||
**/
|
||||
* Computes the complex exponential `e^(iw)`.
|
||||
*/
|
||||
public static inline function exp(w:Float) return new Complex(Math.cos(w), Math.sin(w));
|
||||
}
|
||||
|
||||
@@ -6,27 +6,27 @@ using funkin.audio.visualize.dsp.Signal;
|
||||
// these are only used for testing, down in FFT.main()
|
||||
|
||||
/**
|
||||
Fast/Finite Fourier Transforms.
|
||||
**/
|
||||
* Fast/Finite Fourier Transforms.
|
||||
*/
|
||||
@:nullSafety
|
||||
class FFT
|
||||
{
|
||||
/**
|
||||
Computes the Discrete Fourier Transform (DFT) of a `Complex` sequence.
|
||||
|
||||
If the input has N data points (N should be a power of 2 or padding will be added)
|
||||
from a signal sampled at intervals of 1/Fs, the result will be a sequence of N
|
||||
samples from the Discrete-Time Fourier Transform (DTFT) - which is Fs-periodic -
|
||||
with a spacing of Fs/N Hz between them and a scaling factor of Fs.
|
||||
**/
|
||||
* Computes the Discrete Fourier Transform (DFT) of a `Complex` sequence.
|
||||
*
|
||||
* If the input has N data points (N should be a power of 2 or padding will be added)
|
||||
* from a signal sampled at intervals of 1/Fs, the result will be a sequence of N
|
||||
* samples from the Discrete-Time Fourier Transform (DTFT) - which is Fs-periodic -
|
||||
* with a spacing of Fs/N Hz between them and a scaling factor of Fs.
|
||||
*/
|
||||
public static function fft(input:Array<Complex>):Array<Complex> return do_fft(input, false);
|
||||
|
||||
/**
|
||||
Like `fft`, but for a real (Float) sequence input.
|
||||
|
||||
Since the input time signal is real, its frequency representation is
|
||||
Hermitian-symmetric so we only return the positive frequencies.
|
||||
**/
|
||||
* Like `fft`, but for a real (Float) sequence input.
|
||||
*
|
||||
* Since the input time signal is real, its frequency representation is
|
||||
* Hermitian-symmetric so we only return the positive frequencies.
|
||||
*/
|
||||
public static function rfft(input:Array<Float>):Array<Complex>
|
||||
{
|
||||
final s = fft(input.map(Complex.fromReal));
|
||||
@@ -34,19 +34,22 @@ class FFT
|
||||
}
|
||||
|
||||
/**
|
||||
Computes the Inverse DFT of a periodic input sequence.
|
||||
|
||||
If the input contains N (a power of 2) DTFT samples, each spaced Fs/N Hz
|
||||
from each other, the result will consist of N data points as sampled
|
||||
from a time signal at intervals of 1/Fs with a scaling factor of 1/Fs.
|
||||
**/
|
||||
* Computes the Inverse DFT of a periodic input sequence.
|
||||
*
|
||||
* If the input contains N (a power of 2) DTFT samples, each spaced Fs/N Hz
|
||||
* from each other, the result will consist of N data points as sampled
|
||||
* from a time signal at intervals of 1/Fs with a scaling factor of 1/Fs.
|
||||
*/
|
||||
public static function ifft(input:Array<Complex>):Array<Complex> return do_fft(input, true);
|
||||
|
||||
// Handles padding and scaling for forwards and inverse FFTs.
|
||||
|
||||
static function do_fft(input:Array<Complex>, inverse:Bool):Array<Complex>
|
||||
{
|
||||
final n = nextPow2(input.length);
|
||||
var ts = [for (i in 0...n) if (i < input.length) input[i] else Complex.zero];
|
||||
var ts = [
|
||||
for (i in 0...n) if (i < input.length) input[i] else Complex.zero
|
||||
];
|
||||
var fs = [for (_ in 0...n) Complex.zero];
|
||||
ditfft2(ts, 0, fs, 0, n, 1, inverse);
|
||||
return inverse ? fs.map(z -> z.scale(1 / n)) : fs;
|
||||
@@ -54,6 +57,7 @@ class FFT
|
||||
}
|
||||
|
||||
// Radix-2 Decimation-In-Time variant of Cooley–Tukey's FFT, recursive.
|
||||
|
||||
static function ditfft2(time:Array<Complex>, t:Int, freq:Array<Complex>, f:Int, n:Int, step:Int, inverse:Bool):Void
|
||||
{
|
||||
if (n == 1)
|
||||
@@ -77,6 +81,7 @@ class FFT
|
||||
}
|
||||
|
||||
// Naive O(n^2) DFT, used for testing purposes.
|
||||
|
||||
static function dft(ts:Array<Complex>, ?inverse:Bool):Array<Complex>
|
||||
{
|
||||
if (inverse == null) inverse = false;
|
||||
@@ -96,8 +101,8 @@ class FFT
|
||||
}
|
||||
|
||||
/**
|
||||
Finds the power of 2 that is equal to or greater than the given natural.
|
||||
**/
|
||||
* Finds the power of 2 that is equal to or greater than the given natural.
|
||||
*/
|
||||
static function nextPow2(x:Int):Int
|
||||
{
|
||||
if (x < 2) return 1;
|
||||
@@ -110,6 +115,7 @@ class FFT
|
||||
}
|
||||
|
||||
// testing, but also acts like an example
|
||||
|
||||
static function main()
|
||||
{
|
||||
// sampling and buffer parameters
|
||||
@@ -119,15 +125,21 @@ class FFT
|
||||
|
||||
// build a time signal as a sum of sinusoids
|
||||
final freqs = [5919.911];
|
||||
final ts = [for (n in 0...N) freqs.map(f -> Math.sin(2 * Math.PI * f * n / Fs)).sum()];
|
||||
final ts = [
|
||||
for (n in 0...N) freqs.map(f -> Math.sin(2 * Math.PI * f * n / Fs)).sum()
|
||||
];
|
||||
|
||||
// get positive spectrum and use its symmetry to reconstruct negative domain
|
||||
final fs_pos = rfft(ts);
|
||||
final fs_fft = new OffsetArray([for (k in -(halfN - 1)...0) fs_pos[-k].conj()].concat(fs_pos), -(halfN - 1));
|
||||
final fs_fft = new OffsetArray([
|
||||
for (k in -(halfN - 1)...0) fs_pos[-k].conj()
|
||||
].concat(fs_pos), -(halfN - 1));
|
||||
|
||||
// double-check with naive DFT
|
||||
final fs_dft = new OffsetArray(dft(ts.map(Complex.fromReal)).circShift(halfN - 1), -(halfN - 1));
|
||||
final fs_err = [for (k in -(halfN - 1)...halfN) fs_fft[k] - fs_dft[k]];
|
||||
final fs_err = [
|
||||
for (k in -(halfN - 1)...halfN) fs_fft[k] - fs_dft[k]
|
||||
];
|
||||
final max_fs_err = fs_err.map(z -> z.magnitude).max();
|
||||
if (max_fs_err > 1e-6) haxe.Log.trace('FT Error: ${max_fs_err}', null);
|
||||
// else for (k => s in fs_fft) haxe.Log.trace('${k * Fs / N};${s.scale(1 / Fs).magnitude}', null);
|
||||
@@ -143,14 +155,18 @@ class FFT
|
||||
}
|
||||
else
|
||||
{
|
||||
final freqs_err = [for (i in 0...freqs.length) freqis[i] - freqs[i]];
|
||||
final freqs_err = [
|
||||
for (i in 0...freqs.length) freqis[i] - freqs[i]
|
||||
];
|
||||
final max_freqs_err = freqs_err.map(Math.abs).max();
|
||||
if (max_freqs_err > Fs / N) trace('Frequency Errors: ${freqs_err}');
|
||||
}
|
||||
|
||||
// recover time signal from the frequency domain
|
||||
final ts_ifft = ifft(fs_fft.array.circShift(-(halfN - 1)).map(z -> z.scale(1 / Fs)));
|
||||
final ts_err = [for (n in 0...N) ts_ifft[n].scale(Fs).real - ts[n]];
|
||||
final ts_err = [
|
||||
for (n in 0...N) ts_ifft[n].scale(Fs).real - ts[n]
|
||||
];
|
||||
final max_ts_err = ts_err.map(Math.abs).max();
|
||||
if (max_ts_err > 1e-6) haxe.Log.trace('IFT Error: ${max_ts_err}', null);
|
||||
// else for (n in 0...ts_ifft.length) haxe.Log.trace('${n / Fs};${ts_ifft[n].scale(Fs).real}', null);
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package funkin.audio.visualize.dsp;
|
||||
|
||||
/**
|
||||
A view into an Array with an indexing offset.
|
||||
|
||||
Usages include 1-indexed sequences or zero-centered buffers with negative indexing.
|
||||
**/
|
||||
@:forward(array, offset)
|
||||
@:nullSafety
|
||||
* A view into an Array with an indexing offset.
|
||||
*
|
||||
* Usages include 1-indexed sequences or zero-centered buffers with negative indexing.
|
||||
*/
|
||||
@:forward(array, offset) @:nullSafety
|
||||
abstract OffsetArray<T>({
|
||||
final array:Array<T>;
|
||||
final offset:Int;
|
||||
@@ -25,32 +24,46 @@ abstract OffsetArray<T>({
|
||||
public inline function set(index:Int, value:T):Void this.array[index - this.offset] = value;
|
||||
|
||||
/**
|
||||
Iterates through items in their original order while providing the altered indexes as keys.
|
||||
**/
|
||||
* Iterates through items in their original order while providing the altered indexes as keys.
|
||||
*/
|
||||
public inline function keyValueIterator():KeyValueIterator<Int, T> return new OffsetArrayIterator(this.array, this.offset);
|
||||
|
||||
@:from
|
||||
static inline function fromArray<T>(array:Array<T>) return new OffsetArray(array, 0);
|
||||
static inline function fromArray<T>(array:Array<T>):OffsetArray<T>
|
||||
{
|
||||
return new OffsetArray(array, 0);
|
||||
}
|
||||
|
||||
@:to
|
||||
inline function toArray() return this.array;
|
||||
inline function toArray():Array<T>
|
||||
{
|
||||
return this.array;
|
||||
}
|
||||
|
||||
/**
|
||||
Makes a shifted version of the given `array`, where elements are in the
|
||||
same order but shifted by `n` positions (to the right if positive and to
|
||||
the left if negative) in **circular** fashion (no elements discarded).
|
||||
**/
|
||||
* Makes a shifted version of the given `array`, where elements are in the
|
||||
* same order but shifted by `n` positions (to the right if positive and to
|
||||
* the left if negative) in **circular** fashion (no elements discarded).
|
||||
*
|
||||
* @param array The array to shift
|
||||
* @param n The number of positions to shift
|
||||
* @return The resulting offset array
|
||||
*/
|
||||
public static function circShift<T>(array:Array<T>, n:Int):Array<T>
|
||||
{
|
||||
if (n < 0) return circShift(array, array.length + n);
|
||||
|
||||
var shifted = new Array<T>();
|
||||
var shifted = [];
|
||||
|
||||
n = n % array.length;
|
||||
for (i in array.length - n...array.length)
|
||||
{
|
||||
shifted.push(array[i]);
|
||||
}
|
||||
for (i in 0...array.length - n)
|
||||
{
|
||||
shifted.push(array[i]);
|
||||
}
|
||||
|
||||
return shifted;
|
||||
}
|
||||
@@ -72,9 +85,12 @@ private class OffsetArrayIterator<T>
|
||||
public inline function next():
|
||||
{key:Int, value:T}
|
||||
{
|
||||
final i = this.enumeration++;
|
||||
var i = this.enumeration++;
|
||||
return {key: i + this.offset, value: this.array[i]};
|
||||
}
|
||||
|
||||
public inline function hasNext():Bool return this.enumeration < this.array.length;
|
||||
public inline function hasNext():Bool
|
||||
{
|
||||
return this.enumeration < this.array.length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,14 @@ package funkin.audio.visualize.dsp;
|
||||
using Lambda;
|
||||
|
||||
/**
|
||||
Signal processing miscellaneous utilities.
|
||||
**/
|
||||
* Signal processing miscellaneous utilities.
|
||||
*/
|
||||
@:nullSafety
|
||||
class Signal
|
||||
{
|
||||
/**
|
||||
Returns a smoothed version of the input array using a moving average.
|
||||
**/
|
||||
* Returns a smoothed version of the input array using a moving average.
|
||||
*/
|
||||
public static function smooth(y:Array<Float>, n:Int):Null<Array<Float>>
|
||||
{
|
||||
if (n <= 0)
|
||||
@@ -35,11 +35,11 @@ class Signal
|
||||
}
|
||||
|
||||
/**
|
||||
Finds indexes of peaks in the order they appear in the input sequence.
|
||||
|
||||
@param threshold Minimal peak height wrt. its neighbours, defaults to 0.
|
||||
@param minHeight Minimal peak height wrt. the whole input, defaults to global minimum.
|
||||
**/
|
||||
* Finds indexes of peaks in the order they appear in the input sequence.
|
||||
*
|
||||
* @param threshold Minimal peak height wrt. its neighbours, defaults to 0.
|
||||
* @param minHeight Minimal peak height wrt. the whole input, defaults to global minimum.
|
||||
*/
|
||||
public static function findPeaks(y:Array<Float>, ?threshold:Float, ?minHeight:Float):Array<Int>
|
||||
{
|
||||
threshold = threshold == null ? 0.0 : Math.abs(threshold);
|
||||
@@ -47,7 +47,9 @@ class Signal
|
||||
|
||||
var peaks = new Array<Int>();
|
||||
|
||||
final dy = [for (i in 1...y.length) y[i] - y[i - 1]];
|
||||
final dy = [
|
||||
for (i in 1...y.length) y[i] - y[i - 1]
|
||||
];
|
||||
for (i in 1...dy.length)
|
||||
{
|
||||
// peak: function growth positive to its left and negative to its right
|
||||
@@ -60,11 +62,11 @@ class Signal
|
||||
return peaks;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the sum of all the elements of a given array.
|
||||
|
||||
This function tries to minimize floating-point precision errors.
|
||||
**/
|
||||
/***
|
||||
* Returns the sum of all the elements of a given array.
|
||||
*
|
||||
* This function tries to minimize floating-point precision errors.
|
||||
*/
|
||||
public static function sum(array:Array<Float>):Float
|
||||
{
|
||||
// Neumaier's "improved Kahan-Babuska algorithm":
|
||||
@@ -84,27 +86,27 @@ class Signal
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the average value of an array.
|
||||
**/
|
||||
* Returns the average value of an array.
|
||||
*/
|
||||
public static function mean(y:Array<Float>):Float return sum(y) / y.length;
|
||||
|
||||
/**
|
||||
Returns the global maximum.
|
||||
**/
|
||||
* Returns the global maximum.
|
||||
*/
|
||||
public static function max(y:Array<Float>):Float return y.fold(Math.max, y[0]);
|
||||
|
||||
/**
|
||||
Returns the global maximum's index.
|
||||
**/
|
||||
* Returns the global maximum's index.
|
||||
*/
|
||||
public static function maxi(y:Array<Float>):Int return y.foldi((yi, m, i) -> yi > y[m] ? i : m, 0);
|
||||
|
||||
/**
|
||||
Returns the global minimum.
|
||||
**/
|
||||
* Returns the global minimum.
|
||||
*/
|
||||
public static function min(y:Array<Float>):Float return y.fold(Math.min, y[0]);
|
||||
|
||||
/**
|
||||
Returns the global minimum's index.
|
||||
**/
|
||||
* Returns the global minimum's index.
|
||||
*/
|
||||
public static function mini(y:Array<Float>):Int return y.foldi((yi, m, i) -> yi < y[m] ? i : m, 0);
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ class WaveformData
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new WaveformData whose data represents the two waveforms overlayed.
|
||||
* Create a new WaveformData whose data represents the two waveforms overlaid.
|
||||
*/
|
||||
public function merge(that:WaveformData):WaveformData
|
||||
{
|
||||
@@ -217,7 +217,7 @@ class WaveformData
|
||||
/**
|
||||
* Create a new WaveformData whose parameters match the current object.
|
||||
*/
|
||||
public function clone(?newData:Array<Int> = null):WaveformData
|
||||
public function clone(?newData:Array<Int>):WaveformData
|
||||
{
|
||||
if (newData == null)
|
||||
{
|
||||
|
||||
@@ -3,14 +3,13 @@ package funkin.audio.waveform;
|
||||
@:nullSafety
|
||||
class WaveformDataParser
|
||||
{
|
||||
@:native("int16_max")
|
||||
@:native('int16_max')
|
||||
static final INT16_MAX:Int = 32767;
|
||||
@:native("int16_min")
|
||||
@:native('int16_min')
|
||||
static final INT16_MIN:Int = -32768;
|
||||
|
||||
@:native("int8_max")
|
||||
@:native('int8_max')
|
||||
static final INT8_MAX:Int = 127;
|
||||
@:native("int8_min")
|
||||
@:native('int8_min')
|
||||
static final INT8_MIN:Int = -128;
|
||||
|
||||
public static function interpretFlxSound(sound:Null<flixel.sound.FlxSound>):Null<WaveformData>
|
||||
@@ -82,7 +81,9 @@ class WaveformDataParser
|
||||
{
|
||||
for (channelIndex in 0...channels)
|
||||
{
|
||||
var sampleValue:Int = soundData[sampleIndex * channels + channelIndex];
|
||||
var sampleValue:Int = soundData[
|
||||
sampleIndex * channels + channelIndex
|
||||
];
|
||||
|
||||
if (sampleValue < minValues[channelIndex]) minValues[channelIndex] = sampleValue;
|
||||
if (sampleValue > maxValues[channelIndex]) maxValues[channelIndex] = sampleValue;
|
||||
@@ -94,7 +95,9 @@ class WaveformDataParser
|
||||
for (channelIndex in 0...channels)
|
||||
{
|
||||
outputData[baseIndex + channelIndex * 2] = minValues[channelIndex];
|
||||
outputData[baseIndex + channelIndex * 2 + 1] = maxValues[channelIndex];
|
||||
outputData[
|
||||
baseIndex + channelIndex * 2 + 1
|
||||
] = maxValues[channelIndex];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,6 +132,8 @@ class WaveformDataParser
|
||||
trace('[WAVEFORM] Failed to parse waveform data: ${id}');
|
||||
|
||||
for (error in errors)
|
||||
{
|
||||
funkin.data.DataError.printError(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ class WaveformSprite extends MeshRender
|
||||
isWaveformDirty = true;
|
||||
}
|
||||
|
||||
public override function update(elapsed:Float):Void
|
||||
override public function update(elapsed:Float):Void
|
||||
{
|
||||
super.update(elapsed);
|
||||
|
||||
@@ -197,7 +197,7 @@ class WaveformSprite extends MeshRender
|
||||
makeGraphic(1, 1, this.waveformColor);
|
||||
}
|
||||
|
||||
public override function draw():Void
|
||||
override public function draw():Void
|
||||
{
|
||||
super.draw();
|
||||
}
|
||||
|
||||
@@ -16,9 +16,7 @@ typedef EntryConstructorFunction = (String, ?Dynamic) -> Void;
|
||||
* @param J The type of the JSON data used when constructing.
|
||||
* @param P The type of the parameters used for `fetchEntry()`.
|
||||
*/
|
||||
@:nullSafety
|
||||
@:generic
|
||||
@:autoBuild(funkin.util.macro.RegistryMacro.buildRegistry())
|
||||
@:nullSafety @:generic @:autoBuild(funkin.util.macro.RegistryMacro.buildRegistry())
|
||||
abstract class BaseRegistry<T:(IRegistryEntry<J> & Constructible<EntryConstructorFunction>), J, P>
|
||||
{
|
||||
/**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user