Merge branch 'rewrite/master' into funkin-mobile/main

This commit is contained in:
EliteMasterEric
2025-05-01 21:46:20 -04:00
33 changed files with 347 additions and 124 deletions
+1 -1
View File
@@ -48,7 +48,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.6.2
placeholder: ex. 0.6.3
validations:
required: true
+1 -1
View File
@@ -46,7 +46,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.6.2
placeholder: ex. 0.6.3
validations:
required: true
+1 -1
View File
@@ -34,7 +34,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.6.2
placeholder: ex. 0.6.3
validations:
required: true
+1 -1
View File
@@ -46,7 +46,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.6.2
placeholder: ex. 0.6.3
validations:
required: true
+1
View File
@@ -6,6 +6,7 @@ dump/
temp/
docs/temp/
export/
project/
astc-textures/
RECOVER_*.fla
shitAudio/
+2 -2
View File
@@ -1,6 +1,6 @@
[submodule "assets"]
path = assets
url = https://github.com/FunkinCrew/Funkin-assets-secret
url = https://github.com/FunkinCrew/Funkin.assets
[submodule "art"]
path = art
url = https://github.com/FunkinCrew/Funkin-art-secret
url = https://github.com/FunkinCrew/Funkin.art
+88 -7
View File
@@ -6,6 +6,77 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.6.3] - 2025-04-25
### Added
- New option in the Preferences menu: VSync!
- Set it to Off, On, or Adaptive
- Adaptive turns VSync off during FPS drops, which is better if supported by your graphics card.
- Doesn't work on Mac, sorry!
- Otis now has muzzle flashes when shooting.
- Overhauled the sticker system to allow modders to easily add custom sticker sets. ([cdc468b](https://github.com/FunkinCrew/Funkin/commit/cdc468ba15683b3c0f54015e337673c77ddd7962)) - by @AbnormalPoof in [#4003](https://github.com/FunkinCrew/Funkin/pull/4003)
- Implemented a macro to optimize registries and entries. ([1497521](https://github.com/FunkinCrew/Funkin/commit/14975212a918adb1a5d96a349ec9e8e63c9fc64b)) - by @lemz1 in [#3694](https://github.com/FunkinCrew/Funkin/pull/3694)
- The macro is now used to retrieve base game assets. ([963e2ec](https://github.com/FunkinCrew/Funkin/commit/963e2ecd630fae24dae4206d315618cf4c4be6db)) - by @lemz1 in [#4707](https://github.com/FunkinCrew/Funkin/pull/4707)
- The Chart Editor now displays the current beat and step of the playhead. ([83bb3bb](https://github.com/FunkinCrew/Funkin/commit/83bb3bb5074ecb5f50ee21979711efcda9d8017d)) - by @NotHyper-474 in [#4649](https://github.com/FunkinCrew/Funkin/pull/4649)
### Changed
- The mod API version is now 0.6.3.
- Be sure to update the version in your mods' metadata, then ensure they are still working!
- Eric's scoring rebalance update!
- Misses (not ghost misses) are now worth -100 points, up from -10.
- Hold note trails now grant 20% less health.
- Dropping a hold note early now plays the miss animation and deducts health and score.
- Made a LOT of charting changes!
- Many missing, extra, and mistimed notes have been corrected.
- Stacked notes that were preventing full combos have been removed.
- Camera events have been adjusted to stay within the boundaries of the stage.
- Some songs have been recharted.
- The Freeplay menu can now always switch between variations.
- The nearest song with an Erect variation will be selected when switching.
- Switching difficulties now always plays the capsule jump-in animation.
- The "Random" capsule now plays animations consistent with other capsules.
- The Eggnog Erect cutscene can now be skipped. ([0303a03](https://github.com/FunkinCrew/funkin.assets/commit/1202651db8ea938fe11b6b734fbf7884d101e6ad)) - by @ShadzXD in [#62](https://github.com/FunkinCrew/funkin.assets/pull/62)
- Swapped the positions of “skip” and “restart” items in the dialogue pause menu for consistency. ([1f88a3b](https://github.com/FunkinCrew/Funkin/commit/1f88a3b6e13e9283ad680805deab5e27ba141d96)) - by @VioletSnowLeopard in [#4553](https://github.com/FunkinCrew/Funkin/pull/4553)
- The Controls menu now prevents unbinding essential UI controls to safeguard against softlocking save files. ([7eebce4](https://github.com/FunkinCrew/Funkin/commit/7eebce432d7627a1cf0bbd43f22a6f9bcb63ff65)) - by @VioletSnowLeopard in [#4382](https://github.com/FunkinCrew/Funkin/pull/4382)
- Renamed “Auto Pause” preference to “Pause on Unfocus” for clarity. ([52be941](https://github.com/FunkinCrew/Funkin/commit/52be941b4503da0ac76918e2482ab1804866f2cf)) - by @JackXson-Real in [#4346](https://github.com/FunkinCrew/Funkin/pull/4346)
- Overhauled `FileUtil`, introducing various fixes, new functions, and sandboxing. ([95ade2a](https://github.com/FunkinCrew/Funkin/commit/95ade2a08b7709e8208ec1b3e123bf5b4308ba10)) - by @cyn0x8 in [#3032](https://github.com/FunkinCrew/Funkin/pull/3032)
- The Freeplay menu no longer displays songs without Erect variations when returning from an Erect variation song.
- Fixed Freeplay DJ animations for Boyfriend and Pico when idling (properly this time).
- Alternate instrumentals for Cocoa, Senpai, Roses, and Stress are now locked until their Pico Mix is beaten.
- The Roses Pico alternate instrumental is now offset to align with the original song's voices.
- Entering Stress or Stress (Pico Mix) a second time no longer crashes the game.
- Restarting Stress or Stress (Pico Mix) no longer spawns too many Tankmen in the background.
- Pico's game over animation now displays properly on Ugh (Pico Mix) and Guns (Pico Mix).
- Tankman's death lines now play for Boyfriend in Ugh, Guns, and Ugh Erect.
- Week 6 dialogue no longer plays for all non-default variations when entered through Freeplay.
- Nene (Pixel) now plays her knife raising animation when the player has low health.
- A-Bot's visualizer is now blank before the song starts.
- Debug editor tooltips no longer display behind windows.
- Clearing save data no longer crashes the game.
- Adding custom parameters to note kinds no longer crashes the Chart Editor. ([0a7bd31](https://github.com/FunkinCrew/Funkin/commit/0a7bd3111f59efbecfe097f8bbcfdefa5ace299d)) - by @Lasercar in [#136](https://github.com/FunkinCrew/funkin.assets/pull/136)
- Improved performance in the Freeplay menu before entering a song. ([2b7254f](https://github.com/FunkinCrew/Funkin/commit/2b7254fbd2356e9da91e216f178a88f17874a6eb)) - by @superpowers04 in [#4729](https://github.com/FunkinCrew/Funkin/pull/4729)
- Prevented a crash by capping Freeplay and Results screen score displays at their largest possible values (actual scores are not capped). ([51324e9](https://github.com/FunkinCrew/Funkin/commit/51324e9c283c43ca861d3369ba9b3e1db9c89765)) - by @KoloInDaCrib in [#3634](https://github.com/FunkinCrew/Funkin/pull/3634)
- The Animation Editor no longer crashes when opened. ([b40b4b0](https://github.com/FunkinCrew/Funkin/commit/b40b4b03692910afceff361cf6ca3298fd787e3c)) - by @sector-a in [#4582](https://github.com/FunkinCrew/Funkin/pull/4582)
- Disabled navigation in the Options menu while the Clear Save Data prompt is open. ([855deb5](https://github.com/FunkinCrew/Funkin/commit/855deb58280e850c0ad1581807c70f05d6b6a2cb)) - by @KoloInDaCrib in [#4703](https://github.com/FunkinCrew/Funkin/pull/4703)
- Save data is no longer wiped after failing to load the current save. ([068c9fb](https://github.com/FunkinCrew/Funkin/commit/068c9fb43d49ff6ea13e5a73f77a42207954be2c)) - by @KoloInDaCrib in [#4574](https://github.com/FunkinCrew/Funkin/pull/4574)
- Selecting a different type of event in the Chart Editor no longer crashes or resets the event to its default values. ([71ed154](https://github.com/FunkinCrew/Funkin/commit/71ed154b81abbd002d78c09c2dada8a2ad3fa73e)) - by @KoloInDaCrib in [#3913](https://github.com/FunkinCrew/Funkin/pull/3913)
- Deleting a stacked event in the Chart Editor now properly removes the deleted event’s sprite. ([3ad14ba](https://github.com/FunkinCrew/Funkin/commit/3ad14bac32096e45259997ab9957bec5fecf296f)) - by @NotHyper-474 in [#4724](https://github.com/FunkinCrew/Funkin/pull/4724)
- Patched a security vulnerability. ([53dec05](https://github.com/FunkinCrew/Funkin/commit/53dec057bee0a913d60e0c70d45dbb59a58620b0)) - by @nebulazorua in [#4740](https://github.com/FunkinCrew/Funkin/pull/4740)
- Added null safety to a bunch of classes.
- Even more tiny bug fixes.
## New Contributors for 0.6.3
* @JackXson-Real made their first contribution in [#4346](https://github.com/FunkinCrew/Funkin/pull/4346)
* @VioletSnowLeopard made their first contribution in [#4382](https://github.com/FunkinCrew/Funkin/pull/4382)
* @superpowers04 made their first contribution in [#4729](https://github.com/FunkinCrew/Funkin/pull/4729)
* @ShadzXD made their first contribution in [#62](https://github.com/FunkinCrew/Funkin/pull/4729)
## [0.6.2] - 2025-03-31
### Added
@@ -58,7 +129,7 @@ The Pit Stop 2 update!
- Added an option to launch the game in fullscreen. ([ee53ccd](https://github.com/FunkinCrew/Funkin/commit/ee53ccd32721e0790adfe82c60d4aca419db0a7f)) - by @AbnormalPoof in [#3738](https://github.com/FunkinCrew/Funkin/pull/3738)
- Added on-screen descriptions for each item in the Preferences menu. ([a17b0e8](https://github.com/FunkinCrew/Funkin/commit/a17b0e8b3cc1d56fcdc0b51eaca9fd57cdb5bce0)) - by @anysad in [#3872](https://github.com/FunkinCrew/Funkin/pull/3872)
- Added precise scrolling in the Chart Editor using Ctrl-Mouse Wheel. ([0d8e4a5](https://github.com/FunkinCrew/Funkin/commit/0d8e4a53305d6d069454812766300122f3581e31)) - by @ninjamuffin99 in [#3806](https://github.com/FunkinCrew/Funkin/pull/3806)
- Added a “None” option to the character selector in the Chart Editor. ([d9637d3](https://github.com/FunkinCrew/Funkin/commit/d9637d3a19466b9fc68a102676c46a74ef504909)) - by @Lasercar in [#4279](https://github.com/FunkinCrew/Funkin/pull/4279)
- Added a “None” option to the character selector in the Chart Editor. ([9c2ef02](https://github.com/FunkinCrew/Funkin/commit/9c2ef0236818883ad1275571dac49eab70ca0ea0)) - by @Lasercar in [#4279](https://github.com/FunkinCrew/Funkin/pull/4279)
- Added the ability to flip the character in the Animation Editor. ([de02137](https://github.com/FunkinCrew/Funkin/commit/de02137d7c7d1779e85aeda34743f506a5b9cc27)) - by @AbnormalPoof in [#3028](https://github.com/FunkinCrew/Funkin/pull/3028)
- Added offsets support for album titles. ([69d8570](https://github.com/FunkinCrew/Funkin/commit/69d8570a9eb06011ed6dd95fcbef83d90f7f8684)) - by @AbnormalPoof in [#3618](https://github.com/FunkinCrew/Funkin/pull/3618)
- Added three new properties to stage data: `angle`, `scroll`, and `alpha`. ([ff56b19](https://github.com/FunkinCrew/Funkin/commit/ff56b1948aef42bbb6bb4ede4f9b2012d49ab044)) - by @AbnormalPoof in [#3720](https://github.com/FunkinCrew/Funkin/pull/3720)
@@ -77,7 +148,7 @@ The Pit Stop 2 update!
- For example, the Zoom Camera event can now be set to 0.9857.
- Lots of improvements to GitHub issue and pull request organization. - by @Hundrec and @AbnormalPoof
- Overhauled the Changelog to improve readability and properly credit contributors. ([4383fcf](https://github.com/FunkinCrew/Funkin/commit/4383fcf32c280a1c0ee7b9c80d255611d497cabc)) - by @Hundrec in [#4296](https://github.com/FunkinCrew/Funkin/pull/4296) and [#4298](https://github.com/FunkinCrew/Funkin/pull/4298)
- Made various improvements to the screenshot function. ([9ce7bbc](https://github.com/FunkinCrew/Funkin/commit/9ce7bbcfbb8f30ae120c876194f89bc4c787f585)) - by @Lasercar in [#4082](https://github.com/FunkinCrew/Funkin/pull/4082)
- Made various improvements to the screenshot plugin. ([868932c](https://github.com/FunkinCrew/Funkin/commit/868932cd138fad4be5b541cbea3110e30479057b)) - by @Lasercar in [#4082](https://github.com/FunkinCrew/Funkin/pull/4082)
- Accept keybinds (Z and Space by default) can now be used to exit the Results screen. ([edb270d](https://github.com/FunkinCrew/Funkin/commit/edb270d15e41784dccbf75639ac731840e80fe23)) - by @JVNpixels in [#3799](https://github.com/FunkinCrew/Funkin/pull/3799)
- Reordered UI keybinds in the controls menu for consistency. ([a01bcc3](https://github.com/FunkinCrew/Funkin/commit/a01bcc3da836ec52851ca9de13ef459daf61269a)) - by @lemz1 in [#3027](https://github.com/FunkinCrew/Funkin/pull/3027)
- New save files now have default Freeplay controls for gamepads. ([2b7f62e](https://github.com/FunkinCrew/Funkin/commit/2b7f62edd33de5527e259d9e5643f926d35da734)) - by @MrMadera in [#3934](https://github.com/FunkinCrew/Funkin/pull/3934)
@@ -98,20 +169,30 @@ The Pit Stop 2 update!
- Reduced stuttering when resyncing instrumental and voices tracks. ([22d41d2](https://github.com/FunkinCrew/Funkin/commit/22d41d21b88acb7422a0afcda8414682710bd2ed)) - by @TechnikTil in [#3955](https://github.com/FunkinCrew/Funkin/pull/3955)
- Songs with only instrumental tracks no longer stutter. ([dfe02ec](https://github.com/FunkinCrew/Funkin/commit/dfe02ec668b61d6308f459c978d12a7487f9dc28)) - by @KoloInDaCrib in [#3861](https://github.com/FunkinCrew/Funkin/pull/3861)
- The debug mouse cursor no longer flickers before the Title Screen loads. ([1c12b84](https://github.com/FunkinCrew/Funkin/commit/1c12b8467eca350eb28138473360d5358fa620e2)) - by @sphis-Sinco in [#3881](https://github.com/FunkinCrew/Funkin/pull/3881)
- Unbound keys now display as [N/A] instead of crashing the game. ([94e5d3c](https://github.com/FunkinCrew/Funkin/commit/94e5d3ca258cbaa5d9ab6f0cb26feda83b3433a2)) - by @NotHyper-474 in [#4355](https://github.com/FunkinCrew/Funkin/pull/4355)
- Unbound keys now display as [N/A] instead of crashing the game. ([099c309](https://github.com/FunkinCrew/Funkin/commit/099c309f9babdc1ea99b7dbed3fdccf1e952fc8e)) - by @NotHyper-474 in [#4355](https://github.com/FunkinCrew/Funkin/pull/4355)
- Songs can no longer be spam-selected after selecting an instrumental in Freeplay. ([0e0c4ae](https://github.com/FunkinCrew/Funkin/commit/0e0c4aeb7745cfb9479685ccbb635cf3743cddbb)) - by @AbnormalPoof in [#3866](https://github.com/FunkinCrew/Funkin/pull/3866)
- The Random capsule can now switch to Erect/Nightmare difficulties in Freeplay. ([6f32747](https://github.com/FunkinCrew/Funkin/commit/6f327474f30374f50774f432ea3ccb6d02579445)) - by @KoloInDaCrib in [#3838](https://github.com/FunkinCrew/Funkin/pull/3838)
- The Random capsule can now switch to Erect/Nightmare difficulties in Freeplay. ([a90b911](https://github.com/FunkinCrew/Funkin/commit/a90b911653a1beaba57d64b1f05b840109fec42b)) - by @KoloInDaCrib in [#3838](https://github.com/FunkinCrew/Funkin/pull/3838)
- Fixed a rare bug where a song would not register as beaten. ([a3e2373](https://github.com/FunkinCrew/Funkin/commit/a3e23733db104b1ef00cfcff17db3a5d032a4d67)) - by @AbnormalPoof in [#3820](https://github.com/FunkinCrew/Funkin/pull/3820)
- The difficulty graphic on the Results screen no longer cuts off incorrectly. ([b13bf05](https://github.com/FunkinCrew/Funkin/commit/b13bf05d16ff2977309e0c7ba3f049c0134e8902)) - by @AbnormalPoof in [#4161](https://github.com/FunkinCrew/Funkin/pull/4161)
- Four-digit long Total Notes values in the Results screen no longer overflow to the right. ([2be4c0c](https://github.com/FunkinCrew/Funkin/commit/2be4c0c7196e018a43f9697f015179f3efc3fcdb)) - by @Hundrec in [#4356](https://github.com/FunkinCrew/Funkin/pull/4356)
- Four-digit long Total Notes values in the Results screen no longer overflow to the right. ([91a594c](https://github.com/FunkinCrew/Funkin/commit/91a594cc858ed086cd2146a1ac5d2379c6fdd27a)) - by @Hundrec in [#4356](https://github.com/FunkinCrew/Funkin/pull/4356)
- The Character Select screen no longer plays the unlock animation for some locked characters. ([7058126](https://github.com/FunkinCrew/Funkin/commit/7058126e99adb55e43f5f487b007d3efa9f324d5)) - by @AbnormalPoof in [#3748](https://github.com/FunkinCrew/Funkin/pull/3748)
- All time signatures in the Chart Editor now display the correct number of beat/step tick lines. ([e570dfb](https://github.com/FunkinCrew/Funkin/commit/e570dfb8e754f9cb29ac2d8fff6e8513bc68b630)) - by @Keoiki in [#2860](https://github.com/FunkinCrew/Funkin/pull/2860)
- The Debug menu now opens with the correct camera position. ([090ddd1](https://github.com/FunkinCrew/Funkin/commit/090ddd1f1c2aa48fdb83127b2235041643c99af5)) - by @ninjamuffin99 in [#3769](https://github.com/FunkinCrew/Funkin/pull/3769)
- Removed some Freeplay variables left over from legacy versions. ([6f6529f](https://github.com/FunkinCrew/Funkin/commit/6f6529f3c460721755dfdd0a7a26578c0de429d2)) - by @AbnormalPoof in [#4370](https://github.com/FunkinCrew/Funkin/pull/4370)
- Removed an unused Freeplay class left over from legacy versions. ([abe4ac8](https://github.com/FunkinCrew/Funkin/commit/abe4ac8485539cbebe527a9a75698950232b68d2)) - by @AbnormalPoof in [#4370](https://github.com/FunkinCrew/Funkin/pull/4370)
- Blacklisted an additional class for security. ([3492d41](https://github.com/FunkinCrew/Funkin/commit/3492d412c65c7f3fd61e6fc6c9410d8467122ab0)) - by @AbnormalPoof in [#4074](https://github.com/FunkinCrew/Funkin/pull/4074)
- Removed an unused class from Polymod blacklist. ([06c12e3](https://github.com/FunkinCrew/Funkin/commit/06c12e36c6bd6df4e2be32a3bec540172e79e162)) - by @AbnormalPoof in [#3729](https://github.com/FunkinCrew/Funkin/pull/3729)
- Many additional small bug fixes.
### Fixed
* @PatoFlamejanteTV made their first contribution in [#3843](https://github.com/FunkinCrew/Funkin/pull/3843)
* @sphis-Sinco made their first contribution in [#3881](https://github.com/FunkinCrew/Funkin/pull/3881)
* @MrMadera made their first contribution in [#3934](https://github.com/FunkinCrew/Funkin/pull/3934)
* @MidyGamy made their first contribution in [#4068](https://github.com/FunkinCrew/Funkin/pull/4068)
* @Lasercar made their first contribution in [#4082](https://github.com/FunkinCrew/Funkin/pull/4082)
* @MrScottyPieey made their first contribution in [#4085](https://github.com/FunkinCrew/Funkin/pull/4085)
## New Contributors for 0.6.0
* @PatoFlamejanteTV made their first contribution in [#3843](https://github.com/FunkinCrew/Funkin/pull/3843)
@@ -397,7 +478,7 @@ The Playable Pico Update!
- Botplay mode now handles the player's animations properly during hold notes. ([thanks Hundrec!](https://github.com/FunkinCrew/Funkin/pull/2683))
- Camera movement now pauses when the game is paused. ([thanks Matriculaso!](https://github.com/FunkinCrew/Funkin/pull/2684))
- Pico's gameplay sprite no longer appears on the gameover screen when dying from an explosion in 2hot.
- Freeplay previews now properly fade in volume during the BF idle animation.
- Freeplay previews now properly fade in volume during the DJ's idle animation.
- DadBattle no longer incorrectly appears as DadBattle Erect when returning to Freeplay on Hard.
- 2hot now appears under the "#" category in Freeplay menu.
- The Chart Editor no longer crashes when selecting an event with the Event toolbox open.
+1 -1
Submodule art updated: e5eafbad4a...0f19677c1e
+1 -1
Submodule assets updated: 223c5040d3...a42401ffd3
+7 -6
View File
@@ -13,19 +13,20 @@
- NOTE: By performing this operation, you are downloading Content which is proprietary and protected by national and international copyright and trademark laws. See [the LICENSE.md file for the Funkin.assets](https://github.com/FunkinCrew/funkin.assets/blob/main/LICENSE.md) repo for more information.
5. Run `haxelib --global install hmm` and then `haxelib --global run hmm setup` to install hmm.json
6. Run `hmm install` to install all haxelibs of the current branch
7. Run `haxelib run lime setup` to set up Lime
8. Perform additional platform setup
- If you have issues installing Lime, try utilizing Funkin's patched libraries for hmm and haxelib: `haxelib --global git haxelib https://github.com/FunkinCrew/haxelib.git` and `haxelib --global git hmm https://github.com/FunkinCrew/hmm.git`
8. Run `haxelib run lime setup` to set up Lime
9. Perform additional platform setup
- For Windows, download the [Visual Studio Build Tools](https://aka.ms/vs/17/release/vs_BuildTools.exe)
- When prompted, select "Individual Components" and make sure to download the following:
- MSVC v143 VS 2022 C++ x64/x86 build tools
- Windows 10/11 SDK
- Mac: [`lime setup mac` Documentation](https://lime.openfl.org/docs/advanced-setup/macos/)
- Linux: [`lime setup linux` Documentation](https://lime.openfl.org/docs/advanced-setup/linux/)
- Note: Funkin's fork currently doesn't come with the necessary binaries so you'll have to rebuild Lime. See [Troubleshooting](TROUBLESHOOTING.md#lime-related-issues).
- One of Funkin's dependencies uses libVLC, which requires you to install some packages to be able to compile: `sudo apt install libvlc-dev libvlccore-dev libvlccore9`
- One of Funkin's dependencies uses libVLC, which requires you to install some development packages to be able to compile.
Command for Ubuntu/Debian based systems: `sudo apt install libvlc-dev libvlccore-dev libvlccore9`
- HTML5: Compiles without any extra setup
9. If you are targeting for native, you may need to run `lime rebuild <PLATFORM>` and `lime rebuild <PLATFORM> -debug`
10. `lime test <PLATFORM>` to build and launch the game for your platform (for example, `lime test windows`)
10. If you are targeting for native, you may need to run `lime rebuild <PLATFORM>` and `lime rebuild <PLATFORM> -debug`
11. `lime test <PLATFORM>` to build and launch the game for your platform (for example, `lime test windows`)
## Build Flags
+20 -14
View File
@@ -74,6 +74,7 @@ Here's a list of commonly suggested features and the reasons why they won't be a
| Toggleable Ghost Tapping | https://github.com/FunkinCrew/Funkin/pull/2564#issuecomment-2119701802 |
| Perfectly Centered Strumlines | _same as above^_ |
| MultiKey, 9k, More than 4 keys, etc. | https://github.com/FunkinCrew/Funkin/issues/4243#issuecomment-2692371969 |
| Flashy Combo Milestones | https://github.com/FunkinCrew/Funkin/pull/4700#issuecomment-2798916579 |
| Losing Icons for DD and Parents | https://github.com/FunkinCrew/Funkin/issues/3048#issuecomment-2243491536 |
| Playable GF / Speaker BF / Speaker Pico | https://github.com/FunkinCrew/Funkin/issues/2953#issuecomment-2216985230 |
| Fresh (Chill Mix) as Title Screen Music | https://github.com/FunkinCrew/Funkin/pull/4282#issuecomment-2709334718 |
@@ -154,11 +155,23 @@ Choose the `develop` branch if you modify:
Choosing the right base branch helps keep your commit history clean and avoid merge conflicts.
Once you’re satisfied with the changes you’ve made, open a PR and base it on the same branch you previously chose.
## Merge conflicts and rebasing
## Maintaining your pull request
Keeping your pull request clean and easy to review increases the chance that it will be accepted!
Our maintenance policy is as follows:
- If we require changes to your PR, we will label your PR `status: needs revision`.
- We may also leave a comment under your PR specifying what changes you should make.
- If you receive a comment, you have 90 days to implement the requested changes.
- After this period, your PR will be closed due to inactivity and labeled `status: stale`.
- Even after your PR is closed, you may request for us to reopen it. Just be sure to address the issues!
This policy ensures that PRs awaiting review are up to date and ready to merge.
### Merge conflicts and rebasing
Some game updates introduce significant breaking changes that may create merge conflicts in your PR. To resolve them, you will need to update or rebase your PR.
Most merge conflicts are small and will only require you to modify a few files to resolve them.
However, some changes are so big that your commit history will look like a mess!
However, some changes are so big that your commit history will be a total mess!
In this case, you will have to perform a [**rebase**](https://docs.github.com/en/get-started/using-git/about-git-rebase).
This process reapplies your changes on top of the updated branch and cleanly resolves the merge conflicts.
@@ -392,22 +405,15 @@ If you simultaneously modify files from both repositories, then open two separat
Be sure to choose `main` as the base branch for `funkin.assets` PRs, as no `develop` branch exists for that repository.
### Charting PRs
Charting PRs make changes such as **adding/removing notes** or **adjusting the placement of song events**.
Charting PRs make changes such as **adjusting chart metadata**.
This involves modifying one or several of the `funkin.assets` repository's `.json` chart files, found in the `preload/data/songs/` directory.
These PRs should only be opened in the `funkin.assets` repository.
This involves modifying one or several of the `funkin.assets` repository's `*-metadata.json` files, found in the `preload/data/songs/` directory.
> [!CAUTION]
> **No Major Recharts!** Any PR that makes major chart modifications will be rejected.
> Keep your PRs to small tweaks and fixes.
> We **do not** accept changes to the chart `.json` file itself.
> If you find an error in the game's charts, please open an issue in the `Funkin` repo, and the Funkin' Crew will review it and make tweaks themselves as necessary.
Here are some guidelines for opening a Charting PR:
- **Explain the issue.** Which song, variation, difficulty, and section/timestamp is the problem in? Help us understand with screenshots and videos.
- **Show your changes.** How does the chart look with your changes? Provide screenshots and videos here as well.
- **Minimize the diff.** If your changes are very small (e.g. a few notes), do not re-export the chart using the Chart Editor. Instead, manually edit the `.json` chart files to help GitHub display your changes cleanly.
If your PR is accepted, you will be credited as a GitHub contributor (but not as a charter in the Pause Menu).
These PRs should only be opened in the `funkin.assets` repository.
# Closing
Thank you for reading the Contributing Guide.
-5
View File
@@ -12,9 +12,6 @@ Most of this functionality is only available on debug builds of the game!
- `CTRL-SHIFT-L`: ***FORCE CRASH***: Immediately crash the game with a detailed crash log and a stack trace.
## Loading State
- `SPACE`: Trace callbacks.
## **Play State**
- `H`: ***HIDE UI***: Makes the user interface invisible. Works in Pause Menu, great for screenshots.
- `1`: ***END SONG***: Immediately ends the song and moves to Results Screen on Freeplay, or next song on Story Mode.
@@ -31,8 +28,6 @@ Most of this functionality is only available on debug builds of the game!
- `T`: ***TEST RANK ANIMATION***: Play the Gold Perfect rank animation on the currently selected song.
- `SHIFT-ACCEPT`: ***BOTPLAY MODE***: Start a song with Botplay mode enabled.
- `CTRL-Switch Song`: Play the first unlocked alternate instrumental as the song preview.
- `CTRL-LEFT`/`RIGHT`/`UP`/`DOWN`: ***OFFSET BF DJ IN CARTOON STATE***: While BF DJ's TV animation is playing, offset the DJ by 1 pixel in the opposite direction. `SHIFT` to move 10 pixels, `ALT` to move 0.1 pixels.
- `CTRL-C`: ***TRIGGER DJ CARTOON***: Play the Freeplay DJ's cartoon animation. Press again to return to its regular animation.
## **Title State**
- `ESCAPE`: ***QUIT***: Quit the game.
+5 -2
View File
@@ -36,7 +36,8 @@
(NOTE: Make sure you do this via `hmm` (e.g `hmm reinstall -f lime`) to guarantee you get Funkin's version of Lime.)
- `Uncaught exception - Could not find lime.ndll.` ... `Advanced users may run "lime rebuild cpp" instead.`
- Usually specific to Linux. Running the commands below should fix it.
- If on Linux:
- The binaries GLibC version might more recent than the one your system supports. Running the commands below should fix it.
```
cd .haxelib/lime/git
git submodule init
@@ -47,4 +48,6 @@
sudo apt install libgl1-mesa-dev libglu1-mesa-dev g++ g++-multilib gcc-multilib libasound2-dev libx11-dev libxext-dev libxi-dev libxrandr-dev libxinerama-dev libpulse-dev
lime rebuild cpp -64 -release -clean
```
For Windows or MacOS you can download pre-built binaries from [Funkin's Lime](https://github.com/FunkinCrew/lime/tree/dev-funkin/ndll).
- The binaries are missing for some reason. You can download pre-built binaries from [Funkin's Lime](https://github.com/FunkinCrew/lime/tree/dev-funkin/ndll).
You should copy them to `.haxelib/lime/git/ndll/<PLATFORM>64/`, where `<PLATFORM>` is the current platform you're on, which can be either Windows, Linux or MacOS.
+1 -2
View File
@@ -969,13 +969,12 @@ class Project extends HXProject {
addAssetLibrary("weekend1", shouldEmbed, shouldPreload);
addAssetPath("assets/weekend1", "assets/weekend1", "weekend1", ["*"], exclude, shouldEmbed, "assets");
// Art asset library (where README and CHANGELOG pull from)
// Art asset library (where README pulls from)
var shouldEmbedArt = false;
var shouldPreloadArt = false;
addAssetLibrary("art", shouldEmbedArt, shouldPreloadArt);
addAsset("art/readme.txt", "do NOT readme.txt", "art", shouldEmbedArt);
addAsset("LICENSE.md", "LICENSE.md", "art", shouldEmbedArt);
addAsset("CHANGELOG.md", "CHANGELOG.md", "art", shouldEmbedArt);
info('Done configuring assets.');
}
+9 -8
View File
@@ -74,14 +74,6 @@ class Main extends Sprite
function init(?event:Event):Void
{
#if web
// set this variable (which is a function) from the lime version at lime/_internal/backend/html5/HTML5Application.hx
// The framerate cap will more thoroughly initialize via Preferences in InitState.hx
funkin.Preferences.lockedFramerateFunction = untyped js.Syntax.code("window.requestAnimationFrame");
#end
WindowUtil.setVSyncMode(funkin.Preferences.vsyncMode);
if (hasEventListener(Event.ADDED_TO_STAGE))
{
removeEventListener(Event.ADDED_TO_STAGE, init);
@@ -125,6 +117,15 @@ class Main extends Sprite
// George recommends binding the save before FlxGame is created.
Save.load();
// Don't call anything from the preferences until the save is loaded!
#if web
// set this variable (which is a function) from the lime version at lime/_internal/backend/html5/HTML5Application.hx
// The framerate cap will more thoroughly initialize via Preferences in InitState.hx
funkin.Preferences.lockedFramerateFunction = untyped js.Syntax.code("window.requestAnimationFrame");
#end
WindowUtil.setVSyncMode(funkin.Preferences.vsyncMode);
var game:FlxGame = new FlxGame(gameWidth, gameHeight, initialState, Preferences.framerate, Preferences.framerate, skipSplash, startFullscreen);
// FlxG.game._customSoundTray wants just the class, it calls new from
+28 -2
View File
@@ -213,15 +213,41 @@ class Preferences
static function get_vsyncMode():lime.ui.WindowVSyncMode
{
return Save?.instance?.options?.vsyncMode ?? lime.ui.WindowVSyncMode.OFF;
var value = Save?.instance?.options?.vsyncMode ?? "Off";
return switch (value)
{
case "Off":
lime.ui.WindowVSyncMode.OFF;
case "On":
lime.ui.WindowVSyncMode.ON;
case "Adaptive":
lime.ui.WindowVSyncMode.ADAPTIVE;
default:
lime.ui.WindowVSyncMode.OFF;
};
}
static function set_vsyncMode(value:lime.ui.WindowVSyncMode):lime.ui.WindowVSyncMode
{
var string;
switch (value)
{
case lime.ui.WindowVSyncMode.OFF:
string = "Off";
case lime.ui.WindowVSyncMode.ON:
string = "On";
case lime.ui.WindowVSyncMode.ADAPTIVE:
string = "Adaptive";
default:
string = "Off";
};
WindowUtil.setVSyncMode(value);
var save:Save = Save.instance;
save.options.vsyncMode = value;
save.options.vsyncMode = string;
save.flush();
return value;
}
+1 -1
View File
@@ -67,7 +67,7 @@ class Medals
NewgroundsMedalPlugin.play(medalData.value, medalData.name, medalGraphic);
});
#else
if (medalJSON == null) loadMedalJSON();
if ((medalJSON?.length ?? 0) == 0) loadMedalJSON();
// We have to use a medal image from the game files. We use a Base64 encoded image that NG spits out.
// TODO: Wait, don't they give us the medal icon?
+58 -4
View File
@@ -14,6 +14,10 @@ import funkin.util.tools.ICloneable;
import funkin.util.flixel.sound.FlxPartialSound;
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;
/**
@@ -105,6 +109,11 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
return _waveformData;
}
/**
* If true, the game will forcefully add this sound's channel to the list of playing sounds.
*/
public var important:Bool = false;
/**
* Are we in a state where the song should play but time is negative?
*/
@@ -142,6 +151,14 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
else
{
super.update(elapsedSec);
@:privateAccess
{
if (important && _channel != null && !SoundMixer.__soundChannels.contains(_channel))
{
SoundMixer.__soundChannels.push(_channel);
}
}
}
}
@@ -428,13 +445,14 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
* @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 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.
*/
public static function load(embeddedSound:FlxSoundAsset, volume:Float = 1.0, looped:Bool = false, autoDestroy:Bool = false, autoPlay:Bool = false,
persist:Bool = false, ?onComplete:Void->Void, ?onLoad:Void->Void):Null<FunkinSound>
persist:Bool = false, ?onComplete:Void->Void, ?onLoad:Void->Void, important:Bool = false):Null<FunkinSound>
{
@:privateAccess
if (SoundMixer.__soundChannels.length >= SoundMixer.MAX_ACTIVE_CHANNELS)
if (SoundMixer.__soundChannels.length >= SoundMixer.MAX_ACTIVE_CHANNELS && !important)
{
FlxG.log.error('FunkinSound could not play sound, channels exhausted! Found ${SoundMixer.__soundChannels.length} active sound channels.');
return null;
@@ -459,6 +477,7 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
sound.volume = volume;
sound.group = FlxG.sound.defaultSoundGroup;
sound.persist = persist;
sound.important = important;
// Make sure to add the sound to the list.
// If it's already in, it won't get re-added.
@@ -531,15 +550,50 @@ class FunkinSound extends FlxSound implements ICloneable<FunkinSound>
this._label = 'unknown';
}
@:access(openfl.media.Sound)
@:access(openfl.media.SoundChannel)
@:access(openfl.media.SoundMixer)
override function startSound(startTime:Float)
{
if (!important)
{
super.startSound(startTime);
return;
}
_time = startTime;
_paused = false;
if (_sound == null) return;
// Create a channel manually if the sound is considered important.
var pan:Float = FlxMath.bound(SoundMixer.__soundTransform.pan + _transform.pan, -1, 1);
var volume:Float = FlxMath.bound(SoundMixer.__soundTransform.volume * _transform.volume, 0, MAX_VOLUME);
var audioSource:AudioSource = new AudioSource(_sound.__buffer);
audioSource.offset = Std.int(startTime);
audioSource.gain = volume;
var position:lime.math.Vector4 = audioSource.position;
position.x = pan;
position.z = -1 * Math.sqrt(1 - Math.pow(pan, 2));
audioSource.position = position;
_channel = new SoundChannel(_sound, audioSource, _transform);
_channel.addEventListener(Event.SOUND_COMPLETE, stopped);
pitch = _pitch;
active = true;
}
/**
* Play a sound effect once, then destroy it.
* @param key
* @param volume
* @return A `FunkinSound` object, or `null` if the sound could not be loaded.
*/
public static function playOnce(key:String, volume:Float = 1.0, ?onComplete:Void->Void, ?onLoad:Void->Void):Null<FunkinSound>
public static function playOnce(key:String, volume:Float = 1.0, ?onComplete:Void->Void, ?onLoad:Void->Void, important:Bool = false):Null<FunkinSound>
{
var result:Null<FunkinSound> = FunkinSound.load(key, volume, false, true, true, false, onComplete, onLoad);
var result:Null<FunkinSound> = FunkinSound.load(key, volume, false, true, true, false, onComplete, onLoad, important);
return result;
}
+1 -1
View File
@@ -255,7 +255,7 @@ class Countdown
var path = noteStyle.getCountdownSoundPath(step);
if (path == null) return null;
return FunkinSound.playOnce(path, Constants.COUNTDOWN_VOLUME);
return FunkinSound.playOnce(path, Constants.COUNTDOWN_VOLUME, null, null, true);
}
public static function decrement(step:CountdownStep):CountdownStep
+7 -10
View File
@@ -961,14 +961,8 @@ class PlayState extends MusicBeatSubState
});
// Reset the health icons.
if (currentStage.getBoyfriend() != null)
{
currentStage.getBoyfriend().initHealthIcon(false);
}
if (currentStage.getDad() != null)
{
currentStage.getDad().initHealthIcon(true);
}
currentStage?.getBoyfriend()?.initHealthIcon(false);
currentStage?.getDad()?.initHealthIcon(true);
needsReset = false;
}
@@ -1518,9 +1512,10 @@ class PlayState extends MusicBeatSubState
*/
override function reloadAssets():Void
{
performCleanup();
funkin.modding.PolymodHandler.forceReloadAssets();
lastParams.targetSong = SongRegistry.instance.fetchEntry(currentSong.id);
this.remove(currentStage);
LoadingState.loadPlayState(lastParams);
}
@@ -2577,7 +2572,7 @@ class PlayState extends MusicBeatSubState
dispatchEvent(event);
trace('Penalizing score by ${event.score} and health by ${event.healthChange} for dropping hold note (is combo break: ${event.isComboBreak})!');
applyScore(event.score, 'miss', event.healthChange, event.isComboBreak);
applyScore(event.score, '', event.healthChange, event.isComboBreak);
// Play the miss sound.
vocals.playerVolume = 0;
@@ -2923,6 +2918,8 @@ class PlayState extends MusicBeatSubState
Highscore.tallies.shit += 1;
case 'miss':
Highscore.tallies.missed += 1;
default:
// Nothing!
}
health += healthChange;
if (isComboBreak)
+2 -1
View File
@@ -510,7 +510,8 @@ class ResultState extends MusicBeatSubState
FlxTween.tween(bgFlash, {alpha: 0}, 5 / 24);
// NOTE: Only divide if totalNotes > 0 to prevent divide-by-zero errors.
var clearPercentFloat = params.scoreData.tallies.totalNotes == 0 ? 0.0 : (params.scoreData.tallies.sick +
params.scoreData.tallies.good) / params.scoreData.tallies.totalNotes * 100;
params.scoreData.tallies.good
- params.scoreData.tallies.missed) / params.scoreData.tallies.totalNotes * 100;
clearPercentTarget = Math.floor(clearPercentFloat);
// Prevent off-by-one errors.
@@ -65,7 +65,7 @@ class ClearPercentCounter extends FlxTypedSpriteGroup<FlxSprite>
var seperatedScore:Array<Int> = [];
var tempCombo:Int = Math.round(curNumber);
while (tempCombo != 0)
while (tempCombo > 0 && tempCombo != 0)
{
seperatedScore.push(tempCombo % 10);
tempCombo = Math.floor(tempCombo / 10);
+1 -1
View File
@@ -384,7 +384,7 @@ class Scoring
// Final Grade = (Sick + Good - Miss) / (Total Notes)
var grade = (scoreData.tallies.sick + scoreData.tallies.good) / scoreData.tallies.totalNotes;
var grade = (scoreData.tallies.sick + scoreData.tallies.good - scoreData.tallies.missed) / scoreData.tallies.totalNotes;
if (grade == Constants.RANK_PERFECT_THRESHOLD)
{
+8 -3
View File
@@ -801,7 +801,7 @@ class SongDifficulty
{
var suffix:String = (instId != '') ? '-$instId' : '';
FlxG.sound.music = FunkinSound.load(Paths.inst(this.song.id, suffix), volume, looped, false, true);
FlxG.sound.music = FunkinSound.load(Paths.inst(this.song.id, suffix), volume, looped, false, true, false, null, null, true);
// Workaround for a bug where FlxG.sound.music.update() was being called twice.
FlxG.sound.list.remove(FlxG.sound.music);
@@ -948,16 +948,21 @@ class SongDifficulty
for (playerVoice in playerVoiceList)
{
if (!Assets.exists(playerVoice)) continue;
result.addPlayerVoice(FunkinSound.load(playerVoice));
result.addPlayerVoice(FunkinSound.load(playerVoice, 1.0, false, false, false, false, null, null, true));
}
// Add opponent vocals.
for (opponentVoice in opponentVoiceList)
{
if (!Assets.exists(opponentVoice)) continue;
result.addOpponentVoice(FunkinSound.load(opponentVoice));
result.addOpponentVoice(FunkinSound.load(opponentVoice, 1.0, false, false, false, false, null, null, true));
}
// Sometimes the sounds don't set their important value to true, so we have to do this manually.
result.forEach(function(snd:FunkinSound) {
snd.important = true;
});
result.playerVoicesOffset = offsets.getVocalOffset(characters.player, instId);
result.opponentVoicesOffset = offsets.getVocalOffset(characters.opponent, instId);
+3 -3
View File
@@ -123,7 +123,7 @@ class Save
debugDisplay: false,
vibration: true,
autoPause: true,
vsyncMode: lime.ui.WindowVSyncMode.OFF,
vsyncMode: 'Off',
strumlineBackgroundOpacity: 0,
autoFullscreen: false,
inputOffset: 0,
@@ -1450,9 +1450,9 @@ typedef SaveDataOptions =
/**
* If enabled, the game will utilize VSync (or adaptive VSync) on startup.
* @default `OFF`
* @default `Off`
*/
var vsyncMode:lime.ui.WindowVSyncMode;
var vsyncMode:String;
/**
* If >0, the game will display a semi-opaque background under the notes.
@@ -1334,7 +1334,6 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
result = [];
trace('Initializing blank chart for difficulty ' + selectedDifficulty);
currentSongChartData.notes.set(selectedDifficulty, result);
currentSongMetadata.playData.difficulties.pushUnique(selectedDifficulty);
return result;
}
return result;
@@ -1343,7 +1342,6 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
function set_currentSongChartNoteData(value:Array<SongNoteData>):Array<SongNoteData>
{
currentSongChartData.notes.set(selectedDifficulty, value);
currentSongMetadata.playData.difficulties.pushUnique(selectedDifficulty);
return value;
}
@@ -1636,9 +1634,6 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
noteTooltipsDirty = true;
notePreviewViewportBoundsDirty = true;
// Make sure the difficulty we selected is in the list of difficulties.
currentSongMetadata.playData.difficulties.pushUnique(selectedDifficulty);
return selectedDifficulty;
}
@@ -117,6 +117,12 @@ class ChartEditorImportExportHandler
{
state.songMetadata = newSongMetadata;
state.songChartData = newSongChartData;
state.selectedDifficulty = state.availableDifficulties[0];
if (!newSongMetadata.exists(state.selectedVariation))
{
state.selectedVariation = Constants.DEFAULT_VARIATION;
}
Conductor.instance.forceBPM(null); // Disable the forced BPM.
Conductor.instance.instrumentalOffset = state.currentInstrumentalOffset; // Loads from the metadata.
@@ -343,6 +349,12 @@ class ChartEditorImportExportHandler
var variations = state.availableVariations;
if (state.currentSongMetadata.playData.difficulties.pushUnique(state.selectedDifficulty))
{
// Just in case the user deleted all or didn't add a difficulty
state.difficultySelectDirty = true;
}
for (variation in variations)
{
var variationId:String = variation;
@@ -29,6 +29,10 @@ class CapsuleOptionsMenu extends FlxSpriteGroup
var leftArrow:InstrumentalSelector;
var rightArrow:InstrumentalSelector;
var leftArrow:InstrumentalSelector;
var rightArrow:InstrumentalSelector;
public function new(parent:FreeplayState, x:Float = 0, y:Float = 0, instIds:Array<String>):Void
{
super(x, y);
@@ -126,6 +130,8 @@ class CapsuleOptionsMenu extends FlxSpriteGroup
{
// Play in reverse.
capsuleMenuBG.animation.play('open', true, true);
if (leftArrow.moveShitDownTimer != null) leftArrow.moveShitDownTimer.cancel();
if (rightArrow.moveShitDownTimer != null) rightArrow.moveShitDownTimer.cancel();
capsuleMenuBG.animation.finishCallback = function(_) {
parent.cleanupCapsuleOptionsMenu();
queueDestroy = true;
@@ -153,6 +159,8 @@ class InstrumentalSelector extends FunkinSprite
var baseScale:Float = 0.6;
public var moveShitDownTimer:FlxTimer;
public function new(parent:FreeplayState, x:Float, y:Float, flipped:Bool, controls:Controls)
{
super(x, y);
@@ -191,7 +199,7 @@ class InstrumentalSelector extends FunkinSprite
scale.x = scale.y = 0.5 * baseScale;
new FlxTimer().start(2 / 24, function(tmr) {
moveShitDownTimer = new FlxTimer().start(2 / 24, function(tmr) {
scale.x = scale.y = 1 * baseScale;
whiteShader.colorSet = false;
updateHitbox();
+2
View File
@@ -168,6 +168,8 @@ class CapsuleText extends FlxSpriteGroup
public function resetText():Void
{
scale.x = 1;
scale.y = 1;
if (moveTween != null) moveTween.cancel();
if (moveTimer != null) moveTimer.cancel();
whiteText.offset.x = 0;
+1 -1
View File
@@ -87,7 +87,7 @@ class FreeplayDJ extends FlxAtlasSprite
case Intro:
// Play the intro animation then leave this state immediately.
var animPrefix = playableCharData.getAnimationPrefix('intro');
if (getCurrentAnimation() != animPrefix) playFlashAnimation(animPrefix, true);
if (getCurrentAnimation() != animPrefix || !this.anim.isPlaying) playFlashAnimation(animPrefix, true);
timeIdling = 0;
case Idle:
// We are in this state the majority of the time.
+40 -26
View File
@@ -576,10 +576,10 @@ class FreeplayState extends MusicBeatSubState
generateSongList({filterType: REGEXP, filterData: str}, true);
}
// If the current song is still in the list (aka not null?), we'll land on it
// If the current song is still in the list, or if it was random, we'll land on it
// Otherwise we want to land on the first song of the group, rather than random song when changing letter sorts
// that is, only if there's more than one song in the group!
if (curSong != null && currentFilteredSongs.length > 1)
if (curSong == null || currentFilteredSongs.contains(curSong))
{
changeSelection();
}
@@ -733,7 +733,8 @@ class FreeplayState extends MusicBeatSubState
allDifficulties = SongRegistry.instance.listAllDifficulties(currentCharacterId);
// Generates song list with the starter params (who our current character is, last remembered difficulty, etc.)
generateSongList(null, false);
// Set this to false if you prefer the 50% transparency on the capsules when they first appear.
generateSongList(null, true);
// dedicated camera for the state so we don't need to fuk around with camera scrolls from the mainmenu / elsewhere
funnyCam.bgColor = FlxColor.TRANSPARENT;
@@ -835,10 +836,10 @@ class FreeplayState extends MusicBeatSubState
// Initialize the random capsule, with empty/blank info (which we display once bf/pico does his hand)
var randomCapsule:SongMenuItem = grpCapsules.recycle(SongMenuItem);
randomCapsule.initPosition(FlxG.width, 0);
randomCapsule.initData(null, styleData);
randomCapsule.initData(null, styleData, 1);
randomCapsule.y = randomCapsule.intendedY(0) + 10;
randomCapsule.targetPos.x = randomCapsule.x;
randomCapsule.alpha = 0;
randomCapsule.alpha = 0.5;
randomCapsule.songText.visible = false;
randomCapsule.favIcon.visible = false;
randomCapsule.favIconBlurred.visible = false;
@@ -850,8 +851,7 @@ class FreeplayState extends MusicBeatSubState
if (fromCharSelect) randomCapsule.forcePosition();
else
{
// randomCapsule.initJumpIn(0, force);
randomCapsule.forcePosition();
randomCapsule.initJumpIn(0, force);
}
var hsvShader:HSVShader = new HSVShader();
@@ -866,7 +866,7 @@ class FreeplayState extends MusicBeatSubState
var funnyMenu:SongMenuItem = grpCapsules.recycle(SongMenuItem);
funnyMenu.initPosition(FlxG.width, 0);
funnyMenu.initData(tempSong, styleData);
funnyMenu.initData(tempSong, styleData, i + 1);
funnyMenu.onConfirm = function() {
capsuleOnOpenDefault(funnyMenu);
};
@@ -877,10 +877,10 @@ class FreeplayState extends MusicBeatSubState
funnyMenu.hsvShader = hsvShader;
funnyMenu.newText.animation.curAnim.curFrame = 45 - ((i * 4) % 45);
// This stops the bounce-in animation.
funnyMenu.forcePosition();
// funnyMenu.initJumpIn(0, force);
// Stop the bounce-in animation when returning to freeplay from the character selection screen.
if (fromCharSelect) funnyMenu.forcePosition();
else
funnyMenu.initJumpIn(0, force);
grpCapsules.add(funnyMenu);
// add(funnyMenu.theActualHitbox);
@@ -1983,14 +1983,14 @@ class FreeplayState extends MusicBeatSubState
if (change != 0) FunkinSound.playOnce(Paths.sound('scrollMenu'), 0.4);
var previousVariation:String = currentVariation;
var daSong:Null<FreeplaySongData> = grpCapsules.members[curSelected].freeplayData;
// Available variations for current character. We get this since bf is usually `default` variation, and `pico` is `pico`
// but sometimes pico can be the default variation (weekend 1 songs), and bf can be `bf` variation (darnell)
var characterVariations:Array<String> = grpCapsules.members[curSelected].freeplayData?.data.getVariationsByCharacter(currentCharacter) ?? Constants.DEFAULT_VARIATION_LIST;
var characterVariations:Array<String> = daSong?.data.getVariationsByCharacter(currentCharacter) ?? Constants.DEFAULT_VARIATION_LIST;
var difficultiesAvailable:Array<String> = allDifficulties;
// Gets all available difficulties for our character, via our available variations
var songDifficulties:Array<String> = grpCapsules.members[curSelected].freeplayData?.data.listDifficulties(null,
characterVariations) ?? Constants.DEFAULT_DIFFICULTY_LIST;
var songDifficulties:Array<String> = daSong?.data.listDifficulties(null, characterVariations) ?? Constants.DEFAULT_DIFFICULTY_LIST;
var currentDifficultyIndex:Int = difficultiesAvailable.indexOf(currentDifficulty);
@@ -2003,15 +2003,16 @@ class FreeplayState extends MusicBeatSubState
// Update the current difficulty
currentDifficulty = difficultiesAvailable[currentDifficultyIndex];
// For when we change the difficulty, but the song doesn't have that difficulty!
if (!songDifficulties.contains(difficultiesAvailable[currentDifficultyIndex]))
if (daSong != null && !songDifficulties.contains(difficultiesAvailable[currentDifficultyIndex]))
{
curSelected = findClosestDiff(characterVariations, difficultiesAvailable[currentDifficultyIndex]);
rememberedSongId = grpCapsules.members[curSelected].freeplayData?.data.id;
daSong = grpCapsules.members[curSelected].freeplayData;
rememberedSongId = daSong?.data.id;
}
for (variation in characterVariations)
{
if (grpCapsules.members[curSelected].freeplayData?.data.hasDifficulty(currentDifficulty, variation) ?? false)
if (daSong?.data.hasDifficulty(currentDifficulty, variation) ?? false)
{
currentVariation = variation;
rememberedVariation = variation;
@@ -2019,7 +2020,6 @@ class FreeplayState extends MusicBeatSubState
}
}
var daSong:Null<FreeplaySongData> = grpCapsules.members[curSelected].freeplayData;
if (daSong != null)
{
var targetSong:Null<Song> = SongRegistry.instance.fetchEntry(daSong.data.id);
@@ -2033,7 +2033,7 @@ class FreeplayState extends MusicBeatSubState
intendedScore = songScore?.score ?? 0;
intendedCompletion = songScore == null ? 0.0 : ((songScore.tallies.sick + songScore.tallies.good) / songScore.tallies.totalNotes);
rememberedDifficulty = currentDifficulty;
grpCapsules.members[curSelected].refreshDisplay();
grpCapsules.members[curSelected].refreshDisplay((prepForNewRank == true) ? false : true);
}
else
{
@@ -2172,11 +2172,15 @@ class FreeplayState extends MusicBeatSubState
*/
function capsuleOnOpenDefault(cap:SongMenuItem):Void
{
busy = true;
letterSort.inputEnabled = false;
var targetSongId:String = cap?.freeplayData?.data.id ?? 'unknown';
var targetSongNullable:Null<Song> = SongRegistry.instance.fetchEntry(targetSongId);
if (targetSongNullable == null)
{
FlxG.log.warn('WARN: could not find song with id (${targetSongId})');
busy = false;
letterSort.inputEnabled = true;
return;
}
var targetSong:Song = targetSongNullable;
@@ -2190,6 +2194,8 @@ class FreeplayState extends MusicBeatSubState
if (targetDifficulty == null)
{
FlxG.log.warn('WARN: could not find difficulty with id (${targetDifficultyId})');
busy = false;
letterSort.inputEnabled = true;
return;
}
@@ -2219,9 +2225,7 @@ class FreeplayState extends MusicBeatSubState
function openInstrumentalList(cap:SongMenuItem, instrumentalIds:Array<String>):Void
{
busy = true;
capsuleOptionsMenu = new CapsuleOptionsMenu(this, cap.x + 175, cap.y + 115, instrumentalIds);
capsuleOptionsMenu = new CapsuleOptionsMenu(this, cap.targetPos.x + 175, cap.targetPos.y + 115, instrumentalIds);
capsuleOptionsMenu.cameras = [funnyCam];
capsuleOptionsMenu.zIndex = 10000;
add(capsuleOptionsMenu);
@@ -2236,6 +2240,7 @@ class FreeplayState extends MusicBeatSubState
public function cleanupCapsuleOptionsMenu():Void
{
this.busy = false;
letterSort.inputEnabled = true;
if (capsuleOptionsMenu != null)
{
@@ -2261,6 +2266,8 @@ class FreeplayState extends MusicBeatSubState
if (targetSongNullable == null)
{
FlxG.log.warn('WARN: could not find song with id (${targetSongId})');
busy = false;
letterSort.inputEnabled = true;
return;
}
var targetSong:Song = targetSongNullable;
@@ -2272,6 +2279,8 @@ class FreeplayState extends MusicBeatSubState
if (targetDifficulty == null)
{
FlxG.log.warn('WARN: could not find difficulty with id (${currentDifficulty})');
busy = false;
letterSort.inputEnabled = true;
return;
}
@@ -2414,10 +2423,11 @@ class FreeplayState extends MusicBeatSubState
{
var songScore:Null<SaveScoreData> = Save.instance.getSongScore(daSongCapsule.freeplayData.data.id, currentDifficulty, currentVariation);
intendedScore = songScore?.score ?? 0;
intendedCompletion = songScore == null ? 0.0 : ((songScore.tallies.sick + songScore.tallies.good) / songScore.tallies.totalNotes);
intendedCompletion = songScore == null ? 0.0 : ((songScore.tallies.sick +
songScore.tallies.good - songScore.tallies.missed) / songScore.tallies.totalNotes);
rememberedSongId = daSongCapsule.freeplayData.data.id;
changeDiff();
daSongCapsule.refreshDisplay();
daSongCapsule.refreshDisplay((prepForNewRank == true) ? false : true);
}
else
{
@@ -2425,6 +2435,8 @@ class FreeplayState extends MusicBeatSubState
intendedCompletion = 0.0;
rememberedSongId = null;
albumRoll.albumId = null;
changeDiff();
daSongCapsule.refreshDisplay();
}
for (index => capsule in grpCapsules.members)
@@ -2434,8 +2446,10 @@ class FreeplayState extends MusicBeatSubState
capsule.forceHighlight = false;
capsule.selected = index == curSelected + 1;
capsule.curSelected = curSelected;
capsule.targetPos.y = capsule.intendedY(index - curSelected);
capsule.targetPos.x = (270 + (60 * (Math.sin(index - curSelected)))) + (CUTOUT_WIDTH * SONGS_POS_MULTI);
capsule.targetPos.x = capsule.intendedX(index - curSelected) + (CUTOUT_WIDTH * SONGS_POS_MULTI);
if (index < curSelected) capsule.targetPos.y -= 100; // another 100 for good measure
}
+4 -1
View File
@@ -284,6 +284,9 @@ class FreeplayLetter extends FlxAtlasSprite
this.anim.play(animLetters[letterInd] + " move");
this.anim.pause();
curLetter = letterInd;
this.anim.onComplete.add(function() {
this.anim.play(animLetters[curLetter] + " move");
});
}
}
@@ -311,7 +314,7 @@ class FreeplayLetter extends FlxAtlasSprite
animName = "T move";
}
this.anim.play(animName);
this.anim.play(animName, true);
if (curSelection != curLetter)
{
this.anim.pause();
+30 -11
View File
@@ -82,6 +82,10 @@ class SongMenuItem extends FlxSpriteGroup
public var theActualHitbox:FlxObject;
var index:Int;
public var curSelected:Int;
public function new(x:Float, y:Float)
{
super(x, y);
@@ -402,7 +406,7 @@ class SongMenuItem extends FlxSpriteGroup
return evilTrail.color;
}
public function refreshDisplay():Void
public function refreshDisplay(updateRank:Bool = true):Void
{
if (freeplayData == null)
{
@@ -420,7 +424,7 @@ class SongMenuItem extends FlxSpriteGroup
pixelIcon.visible = true;
updateBPM(Std.int(freeplayData.songStartingBpm) ?? 0);
updateDifficultyRating(freeplayData.difficultyRating ?? 0);
updateScoringRank(freeplayData.scoringRank);
if (updateRank) updateScoringRank(freeplayData.scoringRank);
newText.visible = freeplayData.isNew;
favIcon.visible = freeplayData.isFav;
favIconBlurred.visible = freeplayData.isFav;
@@ -501,7 +505,7 @@ class SongMenuItem extends FlxSpriteGroup
spr.visible = value;
}
if (value) textAppear();
textAppear();
updateSelected();
}
@@ -512,10 +516,12 @@ class SongMenuItem extends FlxSpriteGroup
this.y = y;
}
public function initData(freeplayData:Null<FreeplaySongData>, ?styleData:FreeplayStyle = null):Void
public function initData(freeplayData:Null<FreeplaySongData>, ?styleData:FreeplayStyle = null, index:Int = null):Void
{
this.freeplayData = freeplayData;
if (index != null) this.index = index;
// im so mad i have to do this but im pretty sure with the capsules recycling i cant call the new function properly :/
// if thats possible someone Please change the new function to be something like
// capsule.frames = Paths.getSparrowAtlas(styleData == null ? 'freeplay/freeplayCapsule/capsule/freeplayCapsule' : styleData.getCapsuleAssetKey()); thank u luv u
@@ -543,7 +549,7 @@ class SongMenuItem extends FlxSpriteGroup
var frameOutTypeBeat:Int = 0;
var xFrames:Array<Float> = [1.7, 1.8, 0.85, 0.85, 0.97, 0.97, 1];
var xPosLerpLol:Array<Float> = [0.9, 0.4, 0.16, 0.16, 0.22, 0.22, 0.245]; // NUMBERS ARE JANK CUZ THE SCALING OR WHATEVER
var xPosLerpLol:Array<Float> = [0, 0, 0.16, 0.16, 0.22, 0.22, 0.245]; // NUMBERS ARE JANK CUZ THE SCALING OR WHATEVER
var xPosOutLerpLol:Array<Float> = [0.245, 0.75, 0.98, 0.98, 1.2]; // NUMBERS ARE JANK CUZ THE SCALING OR WHATEVER
public var realScaled:Float = 0.8;
@@ -554,9 +560,6 @@ class SongMenuItem extends FlxSpriteGroup
new FlxTimer().start((1 / 24) * maxTimer, function(doShit) {
doJumpIn = true;
});
new FlxTimer().start((0.09 * maxTimer) + 0.85, function(lerpTmr) {
doLerp = true;
});
@@ -617,12 +620,19 @@ class SongMenuItem extends FlxSpriteGroup
capsule.scale.x = xFrames[frameInTypeBeat];
capsule.scale.y = 1 / xFrames[frameInTypeBeat];
x = FlxG.width * xPosLerpLol[Std.int(Math.min(frameInTypeBeat, xPosLerpLol.length - 1))];
targetPos.x = FlxG.width * xPosLerpLol[Std.int(Math.min(frameInTypeBeat, xPosLerpLol.length - 1))];
capsule.scale.x *= realScaled;
capsule.scale.y *= realScaled;
frameInTypeBeat += 1;
// Move the targetPos set to the if statement below if you want them to shift to their target positions after jumping in instead
// I have no idea why this if instead of frameInTypeBeat == xFrames.length works even though they're the same thing
if (targetPos.x <= 320) targetPos.x = intendedX(index - curSelected);
}
else if (frameInTypeBeat == xFrames.length)
{
doJumpIn = false;
}
}
@@ -636,13 +646,17 @@ class SongMenuItem extends FlxSpriteGroup
capsule.scale.x = xFrames[frameOutTypeBeat];
capsule.scale.y = 1 / xFrames[frameOutTypeBeat];
x = FlxG.width * xPosOutLerpLol[Std.int(Math.min(frameOutTypeBeat, xPosOutLerpLol.length - 1))];
this.x = FlxG.width * xPosOutLerpLol[Std.int(Math.min(frameOutTypeBeat, xPosOutLerpLol.length - 1))];
capsule.scale.x *= realScaled;
capsule.scale.y *= realScaled;
frameOutTypeBeat += 1;
}
else if (frameOutTypeBeat == xFrames.length)
{
doJumpOut = false;
}
}
if (doLerp)
@@ -669,7 +683,12 @@ class SongMenuItem extends FlxSpriteGroup
}
}
public function intendedY(index:Float):Float
public function intendedX(index:Int):Float
{
return 270 + (60 * (Math.sin(index)));
}
public function intendedY(index:Int):Float
{
return (index * ((height * realScaled) + 10)) + 120;
}