diff --git a/CHANGELOG.md b/CHANGELOG.md index 10bbfe5f7..f5aefb885 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,31 +6,51 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.4.0] - 2024-05-?? ### Added -- 2 new Erect remixes, Eggnog and Satin Panties. Check them out from -- Improvements to the Freeplay screen, with song difficulty ratings and player rank displays. -- Reworked the Results screen, with additional animations and audio based on your performance. +- 2 new Erect remixes, Eggnog and Satin Panties. Check them out from the Freeplay menu! +- Major visual improvements to the Results screen, with additional animations and audio based on your performance. +- Major visual improvements to the Freeplay screen, with song difficulty ratings and player rank displays. + - Freeplay now plays a preview of songs when you hover over them. - Added a Charter field to the chart format, to allow for crediting the creator of a level's chart. - You can see who charted a song from the Pause menu. +- Added a new Scroll Speed chart event to change the note speed mid-song (thanks ) ### Changed - Tweaked the charts for several songs: + - Monster - Winter Horrorland - Stress - Lit Up + - Tutorial (increased the note speed slightly) + - Senpai (increased the note speed) + - Thorns (increased the note speed slightly) +- Favorite songs marked in Freeplay are now stored between sessions. - Custom note styles are now properly supported for songs; add new notestyles via JSON, then select it for use from the Chart Editor Metadata toolbox. (thanks Keoiki!) +- Improved logic for NoteHitScriptEvents, allowing you to view the hit diff and modify whether a note hit is a combo break (thanks nebulazorua!) - Health icons now support a Winning frame without requiring a spritesheet, simply include a third frame in the icon file. (thanks gamerbross!) - Remember that for more complex behaviors such as animations or transitions, you should use an XML file to define each frame. ### Fixed +- Fixed a bug where the game would silently fail to load saves on HTML5 +- Fixed some bugs with the props on the Story Menu not bopping properly +- Additional fixes to the Loading bar on HTML5 (thanks lemz1!) +- Fixed several bugs with the TitleState, including missing music when returning from the Main Menu (thanks gamerbross!) +- Fixed a camera bug in the Main Menu (thanks richTrash21!) +- Fixed a bug where changing difficulties in Story mode wouldn't update the score (thanks sectorA!) +- Fixed a crash in Freeplay caused by a level referencing an invalid song (thanks gamerbross!) - Fixed a bug where pressing the volume keys would stop the Toy commercial (thanks gamerbross!) -- Fixed a bug where the Chart Editor would crash when losing (thanks gamerbross!) +- Fixed a bug where the Chart Editor Playtest would crash when losing (thanks gamerbross!) +- Fixed a bug where hold notes would display improperly in the Chart Editor when downscroll was enabled for gameplay (thanks gamerbross!) +- Fixed a bug where hold notes would be positioned wrong on downscroll (thanks MaybeMaru!) +- Removed a large number of unused imports to optimize builds (thanks Ethan-makes-music!) +- Improved debug logging for unscripted stages (thanks gamerbross!) - Made improvements to compiling documentation (thanks gedehari!) - Fixed a crash on Linux caused by an old version of hxCodec (thanks Noobz4Life!) - Optimized animation handling for characters (thanks richTrash21!) +- Additional bug fixes and optimizations. ## [0.3.3] - 2024-05-14 ### Changed - Cleaned up some code in `PlayAnimationSongEvent.hx` (thanks BurgerBalls!) ### Fixed -- Fix Web Loading Bar (thanks lemz1!) +- Fixes to the Loading bar on HTML5 (thanks lemz1!) - Don't allow any more inputs when exiting freeplay (thanks gamerbros!) - Fixed using mouse wheel to scroll on freeplay (thanks JugieNoob!) - Fixed the reset's of the health icons, score, and notes when re-entering gameplay from gameover (thanks ImCodist!) @@ -38,11 +58,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed camera stutter once a wipe transition to the Main Menu completes (thanks ImCodist!) - Fixed an issue where hold note would be invisible for a single frame (thanks ImCodist!) - Fix tween accumulation on title screen when pressing Y multiple times (thanks TheGaloXx!) -- Fix for a game over easter egg so you don't accidentally exit it when viewing - Fix a crash when querying FlxG.state in the crash handler +- Fix for a game over easter egg so you don't accidentally exit it when viewing - Fix an issue where the Freeplay menu never displays 100% clear +- Fix an issue where Weekend 1 Pico attempted to retrieve a missing asset. +- Fix an issue where duplicate keybinds would be stoed, potentially causing a crash - Chart debug key now properly returns you to the previous chart editor session if you were playtesting a chart (thanks nebulazorua!) -- Hopefully fixed Freeplay crashes on AMD gpu's +- Fix a crash on Freeplay found on AMD graphics cards ## [0.3.2] - 2024-05-03 ### Added diff --git a/assets b/assets index 7a0d92d30..3bfa4e3da 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 7a0d92d3007de42c452b2ea97a917d8c8d114ee7 +Subproject commit 3bfa4e3da87713ea651f60d4f898c283e5d86093 diff --git a/source/funkin/data/song/SongData.hx b/source/funkin/data/song/SongData.hx index bd25139a7..769af8f08 100644 --- a/source/funkin/data/song/SongData.hx +++ b/source/funkin/data/song/SongData.hx @@ -56,6 +56,8 @@ class SongMetadata implements ICloneable @:default(funkin.data.song.SongRegistry.DEFAULT_GENERATEDBY) public var generatedBy:String; + @:optional + @:default(funkin.data.song.SongData.SongTimeFormat.MILLISECONDS) public var timeFormat:SongTimeFormat; public var timeChanges:Array; @@ -115,14 +117,23 @@ class SongMetadata implements ICloneable */ public function serialize(pretty:Bool = true):String { + // Update generatedBy and version before writing. + updateVersionToLatest(); + var ignoreNullOptionals = true; var writer = new json2object.JsonWriter(ignoreNullOptionals); - // I believe @:jignored should be iggnored by the writer? + // I believe @:jignored should be ignored by the writer? // var output = this.clone(); // output.variation = null; // Not sure how to make a field optional on the reader and ignored on the writer. return writer.write(this, pretty ? ' ' : null); } + public function updateVersionToLatest():Void + { + this.version = SongRegistry.SONG_METADATA_VERSION; + this.generatedBy = SongRegistry.DEFAULT_GENERATEDBY; + } + /** * Produces a string representation suitable for debugging. */ @@ -371,6 +382,12 @@ class SongMusicData implements ICloneable this.variation = variation == null ? Constants.DEFAULT_VARIATION : variation; } + public function updateVersionToLatest():Void + { + this.version = SongRegistry.SONG_MUSIC_DATA_VERSION; + this.generatedBy = SongRegistry.DEFAULT_GENERATEDBY; + } + public function clone():SongMusicData { var result:SongMusicData = new SongMusicData(this.songName, this.artist, this.variation); @@ -603,11 +620,20 @@ class SongChartData implements ICloneable */ public function serialize(pretty:Bool = true):String { + // Update generatedBy and version before writing. + updateVersionToLatest(); + var ignoreNullOptionals = true; var writer = new json2object.JsonWriter(ignoreNullOptionals); return writer.write(this, pretty ? ' ' : null); } + public function updateVersionToLatest():Void + { + this.version = SongRegistry.SONG_CHART_DATA_VERSION; + this.generatedBy = SongRegistry.DEFAULT_GENERATEDBY; + } + public function clone():SongChartData { // We have to manually perform the deep clone here because Map.deepClone() doesn't work. diff --git a/source/funkin/data/song/importer/ChartManifestData.hx b/source/funkin/data/song/importer/ChartManifestData.hx index dd0d28479..04b5a1b69 100644 --- a/source/funkin/data/song/importer/ChartManifestData.hx +++ b/source/funkin/data/song/importer/ChartManifestData.hx @@ -61,10 +61,18 @@ class ChartManifestData */ public function serialize(pretty:Bool = true):String { + // Update generatedBy and version before writing. + updateVersionToLatest(); + var writer = new json2object.JsonWriter(); return writer.write(this, pretty ? ' ' : null); } + public function updateVersionToLatest():Void + { + this.version = CHART_MANIFEST_DATA_VERSION; + } + public static function deserialize(contents:String):Null { var parser = new json2object.JsonParser(); diff --git a/source/funkin/data/stage/StageData.hx b/source/funkin/data/stage/StageData.hx index 22b883c75..bebd86d02 100644 --- a/source/funkin/data/stage/StageData.hx +++ b/source/funkin/data/stage/StageData.hx @@ -58,9 +58,17 @@ class StageData */ public function serialize(pretty:Bool = true):String { + // Update generatedBy and version before writing. + updateVersionToLatest(); + var writer = new json2object.JsonWriter(); return writer.write(this, pretty ? ' ' : null); } + + public function updateVersionToLatest():Void + { + this.version = StageRegistry.STAGE_DATA_VERSION; + } } typedef StageDataCharacters = diff --git a/source/funkin/ui/credits/CreditsDataHandler.hx b/source/funkin/ui/credits/CreditsDataHandler.hx index 2240ec50e..844d0f4db 100644 --- a/source/funkin/ui/credits/CreditsDataHandler.hx +++ b/source/funkin/ui/credits/CreditsDataHandler.hx @@ -54,7 +54,7 @@ class CreditsDataHandler body: [ {line: 'ninjamuffin99'}, {line: 'PhantomArcade'}, - {line: 'KawaiSprite'}, + {line: 'Kawai Sprite'}, {line: 'evilsk8r'}, ] } diff --git a/source/funkin/ui/debug/charting/handlers/ChartEditorImportExportHandler.hx b/source/funkin/ui/debug/charting/handlers/ChartEditorImportExportHandler.hx index 0308cd871..e84f7ec43 100644 --- a/source/funkin/ui/debug/charting/handlers/ChartEditorImportExportHandler.hx +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorImportExportHandler.hx @@ -384,17 +384,34 @@ class ChartEditorImportExportHandler if (variationId == '') { var variationMetadata:Null = state.songMetadata.get(variation); - if (variationMetadata != null) zipEntries.push(FileUtil.makeZIPEntry('${state.currentSongId}-metadata.json', variationMetadata.serialize())); + if (variationMetadata != null) + { + variationMetadata.version = funkin.data.song.SongRegistry.SONG_METADATA_VERSION; + variationMetadata.generatedBy = funkin.data.song.SongRegistry.DEFAULT_GENERATEDBY; + zipEntries.push(FileUtil.makeZIPEntry('${state.currentSongId}-metadata.json', variationMetadata.serialize())); + } var variationChart:Null = state.songChartData.get(variation); - if (variationChart != null) zipEntries.push(FileUtil.makeZIPEntry('${state.currentSongId}-chart.json', variationChart.serialize())); + if (variationChart != null) + { + variationChart.version = funkin.data.song.SongRegistry.SONG_CHART_DATA_VERSION; + variationChart.generatedBy = funkin.data.song.SongRegistry.DEFAULT_GENERATEDBY; + zipEntries.push(FileUtil.makeZIPEntry('${state.currentSongId}-chart.json', variationChart.serialize())); + } } else { var variationMetadata:Null = state.songMetadata.get(variation); - if (variationMetadata != null) zipEntries.push(FileUtil.makeZIPEntry('${state.currentSongId}-metadata-$variationId.json', - variationMetadata.serialize())); + if (variationMetadata != null) + { + zipEntries.push(FileUtil.makeZIPEntry('${state.currentSongId}-metadata-$variationId.json', variationMetadata.serialize())); + } var variationChart:Null = state.songChartData.get(variation); - if (variationChart != null) zipEntries.push(FileUtil.makeZIPEntry('${state.currentSongId}-chart-$variationId.json', variationChart.serialize())); + if (variationChart != null) + { + variationChart.version = funkin.data.song.SongRegistry.SONG_CHART_DATA_VERSION; + variationChart.generatedBy = funkin.data.song.SongRegistry.DEFAULT_GENERATEDBY; + zipEntries.push(FileUtil.makeZIPEntry('${state.currentSongId}-chart-$variationId.json', variationChart.serialize())); + } } } diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index f0695e51e..7795a82a5 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -868,7 +868,7 @@ class FreeplayState extends MusicBeatSubState FlxTween.tween(grpCapsules.members[curSelected].ranking, {"scale.x": 1, "scale.y": 1}, 0.1); - grpCapsules.members[curSelected].blurredRanking.animation.play(grpCapsules.members[curSelected].blurredRanking.animation.curAnim.name, true); + grpCapsules.members[curSelected].blurredRanking.animation.play(fromResults.newRank.getFreeplayRankIconAsset(), true); FlxTween.tween(grpCapsules.members[curSelected].blurredRanking, {"scale.x": 1, "scale.y": 1}, 0.1); new FlxTimer().start(0.1, _ -> { diff --git a/source/funkin/util/Constants.hx b/source/funkin/util/Constants.hx index 4e706c612..1e0978839 100644 --- a/source/funkin/util/Constants.hx +++ b/source/funkin/util/Constants.hx @@ -467,7 +467,7 @@ class Constants // % Hit public static final RANK_PERFECT_THRESHOLD:Float = 1.00; public static final RANK_EXCELLENT_THRESHOLD:Float = 0.90; - public static final RANK_GREAT_THRESHOLD:Float = 0.75; + public static final RANK_GREAT_THRESHOLD:Float = 0.80; public static final RANK_GOOD_THRESHOLD:Float = 0.60; // public static final RANK_SHIT_THRESHOLD:Float = 0.00;