From 2eaea3cdc556928cc359fec446fa656386cd135c Mon Sep 17 00:00:00 2001 From: nebulazorua Date: Wed, 8 May 2024 20:26:17 +0800 Subject: [PATCH 001/266] Apply judgements through a seperate function to applyScore Also adds more to the HitNoteScriptEvent, such as the noteDiff and also isComboBreak. noteDiff is important as it lets you create stuff like notes with reduced hitboxes (i.e mines/"hurt notes") or millisecond hit displays. isComboBreak lets you set whether the judge combo broke, so you could in theory create custom judgements in scripts now with these changes (killer reimplementation in scripts? more likely than you'd think!) --- source/funkin/modding/events/ScriptEvent.hx | 17 +++- source/funkin/play/PlayState.hx | 91 ++++++++----------- .../ui/debug/charting/ChartEditorState.hx | 2 +- 3 files changed, 55 insertions(+), 55 deletions(-) diff --git a/source/funkin/modding/events/ScriptEvent.hx b/source/funkin/modding/events/ScriptEvent.hx index 8d625290d3..ece7870fd7 100644 --- a/source/funkin/modding/events/ScriptEvent.hx +++ b/source/funkin/modding/events/ScriptEvent.hx @@ -140,16 +140,29 @@ class HitNoteScriptEvent extends NoteScriptEvent */ public var score:Int; - public function new(note:NoteSprite, healthChange:Float, score:Int, judgement:String, comboCount:Int = 0):Void + /** + * Whether the judgement caused a combo break. + */ + public var isComboBreak:Bool = false; + + /** + * The time difference when the player hit the note + */ + public var hitDiff:Float = 0; + + public function new(note:NoteSprite, healthChange:Float, score:Int, judgement:String, isComboBreak:Bool, comboCount:Int = 0, hitDiff:Float = 0):Void { super(NOTE_HIT, note, healthChange, comboCount, true); this.score = score; this.judgement = judgement; + this.isComboBreak = isComboBreak; + this.hitDiff = hitDiff; } public override function toString():String { - return 'HitNoteScriptEvent(note=' + note + ', comboCount=' + comboCount + ', judgement=' + judgement + ', score=' + score + ')'; + return 'HitNoteScriptEvent(note=' + note + ', comboCount=' + comboCount + ', judgement=' + judgement + ', score=' + score + ', isComboBreak=' + + isComboBreak + ', hitDiff=' + hitDiff + ')'; } } diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 0ba4e17ec9..8ba48a1b57 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -2080,7 +2080,8 @@ class PlayState extends MusicBeatSubState // Call an event to allow canceling the note hit. // NOTE: This is what handles the character animations! - var event:NoteScriptEvent = new HitNoteScriptEvent(note, 0.0, 0, 'perfect', 0); + + var event:NoteScriptEvent = new HitNoteScriptEvent(note, 0.0, 0, 'perfect', false, 0); dispatchEvent(event); // Calling event.cancelEvent() skips all the other logic! Neat! @@ -2176,7 +2177,7 @@ class PlayState extends MusicBeatSubState // Call an event to allow canceling the note hit. // NOTE: This is what handles the character animations! - var event:NoteScriptEvent = new HitNoteScriptEvent(note, 0.0, 0, 'perfect', 0); + var event:NoteScriptEvent = new HitNoteScriptEvent(note, 0.0, 0, 'perfect', false, 0); dispatchEvent(event); // Calling event.cancelEvent() skips all the other logic! Neat! @@ -2381,27 +2382,40 @@ class PlayState extends MusicBeatSubState var daRating = Scoring.judgeNote(noteDiff, PBOT1); var healthChange = 0.0; + var isComboBreak = false; switch (daRating) { case 'sick': healthChange = Constants.HEALTH_SICK_BONUS; + isComboBreak = Constants.JUDGEMENT_SICK_COMBO_BREAK; case 'good': healthChange = Constants.HEALTH_GOOD_BONUS; + isComboBreak = Constants.JUDGEMENT_GOOD_COMBO_BREAK; case 'bad': healthChange = Constants.HEALTH_BAD_BONUS; + isComboBreak = Constants.JUDGEMENT_BAD_COMBO_BREAK; case 'shit': + isComboBreak = Constants.JUDGEMENT_SHIT_COMBO_BREAK; healthChange = Constants.HEALTH_SHIT_BONUS; } // Send the note hit event. - var event:HitNoteScriptEvent = new HitNoteScriptEvent(note, healthChange, score, daRating, Highscore.tallies.combo + 1); + var event:HitNoteScriptEvent = new HitNoteScriptEvent(note, healthChange, score, daRating, isComboBreak, Highscore.tallies.combo + 1, noteDiff); dispatchEvent(event); // Calling event.cancelEvent() skips all the other logic! Neat! if (event.eventCanceled) return; + Highscore.tallies.totalNotesHit++; + // Display the hit on the strums + playerStrumline.hitNote(note, !isComboBreak); + if (daRating == 'sick') playerStrumline.playNoteSplash(note.noteData.getDirection()); + if (note.isHoldNote && note.holdNoteSprite != null) playerStrumline.playNoteHoldCover(note.holdNoteSprite); + vocals.playerVolume = 1; + // Display the combo meter and add the calculation to the score. - popUpScore(note, event.score, event.judgement, event.healthChange); + applyScore(event.score, event.judgement, event.healthChange, event.isComboBreak); + popUpScore(event.judgement); } /** @@ -2412,9 +2426,6 @@ class PlayState extends MusicBeatSubState { // If we are here, we already CALLED the onNoteMiss script hook! - health += healthChange; - songScore -= 10; - if (!isPracticeMode) { // messy copy paste rn lol @@ -2454,14 +2465,9 @@ class PlayState extends MusicBeatSubState } vocals.playerVolume = 0; - Highscore.tallies.missed++; + if (Highscore.tallies.combo != 0) if (Highscore.tallies.combo >= 10) comboPopUps.displayCombo(0); - if (Highscore.tallies.combo != 0) - { - // Break the combo. - if (Highscore.tallies.combo >= 10) comboPopUps.displayCombo(0); - Highscore.tallies.combo = 0; - } + applyScore(-10, 'miss', healthChange, true); if (playSound) { @@ -2593,46 +2599,24 @@ class PlayState extends MusicBeatSubState } /** - * Handles health, score, and rating popups when a note is hit. + * Handles applying health, score, and ratings. */ - function popUpScore(daNote:NoteSprite, score:Int, daRating:String, healthChange:Float):Void + function applyScore(score:Int, daRating:String, healthChange:Float, isComboBreak:Bool) { - if (daRating == 'miss') - { - // If daRating is 'miss', that means we made a mistake and should not continue. - FlxG.log.warn('popUpScore judged a note as a miss!'); - // TODO: Remove this. - // comboPopUps.displayRating('miss'); - return; - } - - vocals.playerVolume = 1; - - var isComboBreak = false; switch (daRating) { case 'sick': Highscore.tallies.sick += 1; - Highscore.tallies.totalNotesHit++; - isComboBreak = Constants.JUDGEMENT_SICK_COMBO_BREAK; case 'good': Highscore.tallies.good += 1; - Highscore.tallies.totalNotesHit++; - isComboBreak = Constants.JUDGEMENT_GOOD_COMBO_BREAK; case 'bad': Highscore.tallies.bad += 1; - Highscore.tallies.totalNotesHit++; - isComboBreak = Constants.JUDGEMENT_BAD_COMBO_BREAK; case 'shit': Highscore.tallies.shit += 1; - Highscore.tallies.totalNotesHit++; - isComboBreak = Constants.JUDGEMENT_SHIT_COMBO_BREAK; - default: - FlxG.log.error('Wuh? Buh? Guh? Note hit judgement was $daRating!'); + case 'miss': + Highscore.tallies.missed += 1; } - health += healthChange; - if (isComboBreak) { // Break the combo, but don't increment tallies.misses. @@ -2644,15 +2628,23 @@ class PlayState extends MusicBeatSubState Highscore.tallies.combo++; if (Highscore.tallies.combo > Highscore.tallies.maxCombo) Highscore.tallies.maxCombo = Highscore.tallies.combo; } + songScore += score; + } - playerStrumline.hitNote(daNote, !isComboBreak); - - if (daRating == 'sick') + /** + * Handles rating popups when a note is hit. + */ + function popUpScore(daRating:String, ?combo:Int):Void + { + if (daRating == 'miss') { - playerStrumline.playNoteSplash(daNote.noteData.getDirection()); + // If daRating is 'miss', that means we made a mistake and should not continue. + FlxG.log.warn('popUpScore judged a note as a miss!'); + // TODO: Remove this. + // comboPopUps.displayRating('miss'); + return; } - - songScore += score; + if (combo == null) combo = Highscore.tallies.combo; if (!isPracticeMode) { @@ -2692,12 +2684,7 @@ class PlayState extends MusicBeatSubState } } comboPopUps.displayRating(daRating); - if (Highscore.tallies.combo >= 10 || Highscore.tallies.combo == 0) comboPopUps.displayCombo(Highscore.tallies.combo); - - if (daNote.isHoldNote && daNote.holdNoteSprite != null) - { - playerStrumline.playNoteHoldCover(daNote.holdNoteSprite); - } + if (combo >= 10 || combo == 0) comboPopUps.displayCombo(combo); vocals.playerVolume = 1; } diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index b75cd8bf1f..d28ca87d59 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -6304,7 +6304,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState var tempNote:NoteSprite = new NoteSprite(NoteStyleRegistry.instance.fetchDefault()); tempNote.noteData = noteData; tempNote.scrollFactor.set(0, 0); - var event:NoteScriptEvent = new HitNoteScriptEvent(tempNote, 0.0, 0, 'perfect', 0); + var event:NoteScriptEvent = new HitNoteScriptEvent(tempNote, 0.0, 0, 'perfect', false, 0); dispatchEvent(event); // Calling event.cancelEvent() skips all the other logic! Neat! From 4b500f78e19218e33c65b693f1d928195d75efef Mon Sep 17 00:00:00 2001 From: nebulazorua Date: Wed, 8 May 2024 20:30:47 +0800 Subject: [PATCH 002/266] Revert change because i forgot to do it in a new branch oriignally lol --- source/funkin/play/PlayState.hx | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 8ba48a1b57..cdd8c7d71c 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -2555,20 +2555,12 @@ class PlayState extends MusicBeatSubState // Redirect to the chart editor playing the current song. if (controls.DEBUG_CHART) { - if (isChartingMode) - { - if (FlxG.sound.music != null) FlxG.sound.music.pause(); // Don't reset song position! - this.close(); // This only works because PlayState is a substate! - } - else - { - disableKeys = true; - persistentUpdate = false; - FlxG.switchState(() -> new ChartEditorState( - { - targetSongId: currentSong.id, - })); - } + disableKeys = true; + persistentUpdate = false; + FlxG.switchState(() -> new ChartEditorState( + { + targetSongId: currentSong.id, + })); } #end From 1b6febf01c9a7826ec65004d3d4e46780792116f Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Thu, 18 Apr 2024 20:23:03 -0400 Subject: [PATCH 003/266] initial freeplay songs loading --- Project.xml | 1 + checkstyle.json | 2 +- hmm.json | 9 +- source/funkin/Paths.hx | 20 ++++- source/funkin/audio/FunkinSound.hx | 95 ++++++++++++++++++++-- source/funkin/ui/freeplay/FreeplayState.hx | 23 +++--- 6 files changed, 126 insertions(+), 24 deletions(-) diff --git a/Project.xml b/Project.xml index fcfcfb9f35..87608bb88b 100644 --- a/Project.xml +++ b/Project.xml @@ -126,6 +126,7 @@ + diff --git a/checkstyle.json b/checkstyle.json index dc89409da9..41f0a79986 100644 --- a/checkstyle.json +++ b/checkstyle.json @@ -79,7 +79,7 @@ { "props": { "ignoreExtern": true, - "format": "^[a-z][A-Z][A-Z0-9]*(_[A-Z0-9_]+)*$", + "format": "^[a-zA-Z0-9]+(?:_[a-zA-Z0-9]+)*$", "tokens": ["INLINE", "NOTINLINE"] }, "type": "ConstantName" diff --git a/hmm.json b/hmm.json index a6e4467a91..6b119c52fb 100644 --- a/hmm.json +++ b/hmm.json @@ -1,5 +1,12 @@ { "dependencies": [ + { + "name": "FlxPartialSound", + "type": "git", + "dir": null, + "ref": "main", + "url": "https://github.com/FunkinCrew/FlxPartialSound.git" + }, { "name": "discord_rpc", "type": "git", @@ -171,4 +178,4 @@ "url": "https://github.com/FunkinCrew/thx.semver" } ] -} +} \ No newline at end of file diff --git a/source/funkin/Paths.hx b/source/funkin/Paths.hx index 54a4b7acfa..b0a97c4faf 100644 --- a/source/funkin/Paths.hx +++ b/source/funkin/Paths.hx @@ -123,9 +123,17 @@ class Paths return 'songs:assets/songs/${song.toLowerCase()}/Voices$suffix.${Constants.EXT_SOUND}'; } - public static function inst(song:String, ?suffix:String = ''):String + /** + * Gets the path to an `Inst.mp3/ogg` song instrumental from songs:assets/songs/`song`/ + * @param song name of the song to get instrumental for + * @param suffix any suffix to add to end of song name, used for `-erect` variants usually + * @param withExtension if it should return with the audio file extension `.mp3` or `.ogg`. + * @return String + */ + public static function inst(song:String, ?suffix:String = '', ?withExtension:Bool = true):String { - return 'songs:assets/songs/${song.toLowerCase()}/Inst$suffix.${Constants.EXT_SOUND}'; + var ext:String = withExtension ? '.${Constants.EXT_SOUND}' : ''; + return 'songs:assets/songs/${song.toLowerCase()}/Inst$suffix$ext'; } public static function image(key:String, ?library:String):String @@ -153,3 +161,11 @@ class Paths return FlxAtlasFrames.fromSpriteSheetPacker(image(key, library), file('images/$key.txt', library)); } } + +enum abstract PathsFunction(String) +{ + var MUSIC; + var INST; + var VOICES; + var SOUND; +} diff --git a/source/funkin/audio/FunkinSound.hx b/source/funkin/audio/FunkinSound.hx index df05cc3ef6..728a06a325 100644 --- a/source/funkin/audio/FunkinSound.hx +++ b/source/funkin/audio/FunkinSound.hx @@ -11,7 +11,11 @@ import funkin.audio.waveform.WaveformDataParser; import funkin.data.song.SongData.SongMusicData; import funkin.data.song.SongRegistry; import funkin.util.tools.ICloneable; +import funkin.util.flixel.sound.FlxPartialSound; +import funkin.Paths.PathsFunction; import openfl.Assets; +import lime.app.Future; +import lime.app.Promise; import openfl.media.SoundMixer; #if (openfl >= "8.0.0") import openfl.utils.AssetType; @@ -342,20 +346,52 @@ class FunkinSound extends FlxSound implements ICloneable FlxG.log.warn('Tried and failed to find music metadata for $key'); } } + var pathsFunction = params.pathsFunction ?? MUSIC; + var pathToUse = switch (pathsFunction) + { + case MUSIC: Paths.music('$key/$key'); + case INST: Paths.inst('$key'); + default: Paths.music('$key/$key'); + } - var music = FunkinSound.load(Paths.music('$key/$key'), params?.startingVolume ?? 1.0, params.loop ?? true, false, true); - if (music != null) + var shouldLoadPartial = params.partialParams?.loadPartial ?? false; + + if (shouldLoadPartial) { - FlxG.sound.music = music; + var music = FunkinSound.loadPartial(pathToUse, params.partialParams?.start ?? 0, params.partialParams?.end ?? 1, params?.startingVolume ?? 1.0, + params.loop ?? true, false, true); - // Prevent repeat update() and onFocus() calls. - FlxG.sound.list.remove(FlxG.sound.music); + if (music != null) + { + music.onComplete(function(partialMusic:Null) { + @:nullSafety(Off) + FlxG.sound.music = partialMusic; + FlxG.sound.list.remove(FlxG.sound.music); + }); - return true; + return true; + } + else + { + return false; + } } else { - return false; + var music = FunkinSound.load(pathToUse, params?.startingVolume ?? 1.0, params.loop ?? true, false, true); + if (music != null) + { + FlxG.sound.music = music; + + // Prevent repeat update() and onFocus() calls. + FlxG.sound.list.remove(FlxG.sound.music); + + return true; + } + else + { + return false; + } } } @@ -415,6 +451,36 @@ class FunkinSound extends FlxSound implements ICloneable return sound; } + /** + * Will load a section of a sound file, useful for Freeplay where we don't want to load all the bytes of a song + * @param path The path to the sound file + * @param start The start time of the sound file + * @param end The end time of the sound file + * @param volume Volume to start at + * @param looped Whether the sound file should loop + * @param autoDestroy Whether the sound file should be destroyed after it finishes playing + * @param autoPlay Whether the sound file should play immediately + * @return A FunkinSound object + */ + public static function loadPartial(path:String, start:Float = 0, end:Float = 1, volume:Float = 1.0, looped:Bool = false, autoDestroy:Bool = false, + autoPlay:Bool = true, ?onComplete:Void->Void, ?onLoad:Void->Void):Future> + { + var promise:lime.app.Promise> = new lime.app.Promise>(); + + // split the path and get only after first : + // we are bypassing the openfl/lime asset library fuss + path = Paths.stripLibrary(path); + + var soundRequest = FlxPartialSound.partialLoadFromFile(path, start, end); + + soundRequest.onComplete(function(partialSound) { + var snd = FunkinSound.load(partialSound, volume, looped, autoDestroy, autoPlay, onComplete, onLoad); + promise.complete(snd); + }); + + return promise.future; + } + @:nullSafety(Off) public override function destroy():Void { @@ -498,4 +564,19 @@ typedef FunkinSoundPlayMusicParams = * @default `true` */ var ?mapTimeChanges:Bool; + + /** + * Which Paths function to use to load a song + * @default `MUSIC` + */ + var ?pathsFunction:PathsFunction; + + var ?partialParams:PartialSoundParams; +} + +typedef PartialSoundParams = +{ + var loadPartial:Bool; + var start:Float; + var end:Float; } diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 7b7543845a..c290e65534 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -1244,22 +1244,19 @@ class FreeplayState extends MusicBeatSubState else { // TODO: Stream the instrumental of the selected song? - var didReplace:Bool = FunkinSound.playMusic('freakyMenu', + FunkinSound.playMusic(daSongCapsule.songData.songId, { - startingVolume: 0.0, + startingVolume: 0.5, overrideExisting: true, - restartTrack: false + restartTrack: false, + pathsFunction: INST, + partialParams: + { + loadPartial: true, + start: 0, + end: 0.1 + } }); - if (didReplace) - { - FunkinSound.playMusic('freakyMenu', - { - startingVolume: 0.0, - overrideExisting: true, - restartTrack: false - }); - FlxG.sound.music.fadeIn(2, 0, 0.8); - } } grpCapsules.members[curSelected].selected = true; } From f2a06ad37b79c76566ab62f8244a84ac864155a0 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Thu, 9 May 2024 01:56:52 -0400 Subject: [PATCH 004/266] fading in and erect track loading --- source/funkin/audio/FunkinSound.hx | 14 ++++++++++++-- source/funkin/ui/freeplay/FreeplayState.hx | 9 +++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/source/funkin/audio/FunkinSound.hx b/source/funkin/audio/FunkinSound.hx index 728a06a325..5a49e29eea 100644 --- a/source/funkin/audio/FunkinSound.hx +++ b/source/funkin/audio/FunkinSound.hx @@ -347,10 +347,11 @@ class FunkinSound extends FlxSound implements ICloneable } } var pathsFunction = params.pathsFunction ?? MUSIC; + var suffix = params.suffix ?? ''; var pathToUse = switch (pathsFunction) { case MUSIC: Paths.music('$key/$key'); - case INST: Paths.inst('$key'); + case INST: Paths.inst('$key', suffix); default: Paths.music('$key/$key'); } @@ -359,7 +360,7 @@ class FunkinSound extends FlxSound implements ICloneable if (shouldLoadPartial) { var music = FunkinSound.loadPartial(pathToUse, params.partialParams?.start ?? 0, params.partialParams?.end ?? 1, params?.startingVolume ?? 1.0, - params.loop ?? true, false, true); + params.loop ?? true, false, true, params.onComplete, params.onLoad); if (music != null) { @@ -541,6 +542,12 @@ typedef FunkinSoundPlayMusicParams = */ var ?startingVolume:Float; + /** + * The suffix of the music file to play. Usually for "-erect" tracks when loading an INST file + * @default `` + */ + var ?suffix:String; + /** * Whether to override music if a different track is already playing. * @default `false` @@ -572,6 +579,9 @@ typedef FunkinSoundPlayMusicParams = var ?pathsFunction:PathsFunction; var ?partialParams:PartialSoundParams; + + var ?onComplete:Void->Void; + var ?onLoad:Void->Void; } typedef PartialSoundParams = diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index c290e65534..d0183bf8e2 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -1243,19 +1243,24 @@ class FreeplayState extends MusicBeatSubState } else { + var potentiallyErect:String = (currentDifficulty == "erect") || (currentDifficulty == "nightmare") ? "-erect" : ""; // TODO: Stream the instrumental of the selected song? FunkinSound.playMusic(daSongCapsule.songData.songId, { - startingVolume: 0.5, + startingVolume: 0.0, overrideExisting: true, restartTrack: false, pathsFunction: INST, + suffix: potentiallyErect, partialParams: { loadPartial: true, start: 0, end: 0.1 - } + }, + onLoad: function() { + FlxG.sound.music.fadeIn(2, 0, 0.4); + } }); } grpCapsules.members[curSelected].selected = true; From edfde606a145e42af36eacbea826a17b663ffd90 Mon Sep 17 00:00:00 2001 From: Burgerballs <107233412+Burgerballs@users.noreply.github.com> Date: Thu, 9 May 2024 17:51:03 +0100 Subject: [PATCH 005/266] magical machine of death --- source/funkin/play/PlayState.hx | 48 +++++- .../play/event/AdditiveScrollSpeedEvent.hx | 138 ++++++++++++++++++ source/funkin/play/notes/Strumline.hx | 17 ++- source/funkin/play/notes/SustainTrail.hx | 31 +++- .../components/ChartEditorHoldNoteSprite.hx | 4 +- 5 files changed, 227 insertions(+), 11 deletions(-) create mode 100644 source/funkin/play/event/AdditiveScrollSpeedEvent.hx diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 0ba4e17ec9..0b76ec6ee2 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -236,6 +236,11 @@ class PlayState extends MusicBeatSubState */ public var cameraZoomTween:FlxTween; + /** + * An FlxTween that changes the additive speed to the desired amount. + */ + public var additiveScrollSpeedTween:FlxTween; + /** * The camera follow point from the last stage. * Used to persist the position of the `cameraFollowPosition` between levels. @@ -1179,6 +1184,11 @@ class PlayState extends MusicBeatSubState cameraZoomTween.active = false; cameraTweensPausedBySubState.add(cameraZoomTween); } + if (additiveScrollSpeedTween != null && additiveScrollSpeedTween.active) + { + additiveScrollSpeedTween.active = false; + cameraTweensPausedBySubState.add(additiveScrollSpeedTween); + } // Pause the countdown. Countdown.pauseCountdown(); @@ -3023,8 +3033,9 @@ class PlayState extends MusicBeatSubState // Stop camera zooming on beat. cameraZoomRate = 0; - // Cancel camera tweening if it's active. + // Cancel camera and scroll tweening if it's active. cancelAllCameraTweens(); + cancelAdditiveScrollSpeedTween(); // If the opponent is GF, zoom in on the opponent. // Else, if there is no GF, zoom in on BF. @@ -3244,6 +3255,41 @@ class PlayState extends MusicBeatSubState cancelCameraZoomTween(); } + /** + * The magical function that shall tween the additive scroll speed. + */ + public function tweenAdditiveScrollSpeed(?speed:Float, ?duration:Float, ?ease:NullFloat>):Void + { + // Cancel the current tween if it's active. + cancelAdditiveScrollSpeedTween(); + var strumLineTargets:Array = [ + playerStrumline.scrollSpeedAdditive + speed, + opponentStrumline.scrollSpeedAdditive + speed + ]; + + if (duration == 0) + { + playerStrumline.scrollSpeedAdditive = strumLineTargets[0]; + opponentStrumline.scrollSpeedAdditive = strumLineTargets[1]; + } + else + { + additiveScrollSpeedTween = FlxTween.tween(this, + { + "playerStrumline.scrollSpeedAdditive": strumLineTargets[0], + "opponentStrumline.scrollSpeedAdditive": strumLineTargets[1] + }, duration, {ease: ease}); + } + } + + public function cancelAdditiveScrollSpeedTween() + { + if (additiveScrollSpeedTween != null) + { + additiveScrollSpeedTween.cancel(); + } + } + #if (debug || FORCE_DEBUG_VERSION) /** * Jumps forward or backward a number of sections in the song. diff --git a/source/funkin/play/event/AdditiveScrollSpeedEvent.hx b/source/funkin/play/event/AdditiveScrollSpeedEvent.hx new file mode 100644 index 0000000000..f66f3b2571 --- /dev/null +++ b/source/funkin/play/event/AdditiveScrollSpeedEvent.hx @@ -0,0 +1,138 @@ +package funkin.play.event; + +import flixel.tweens.FlxTween; +import flixel.FlxCamera; +import flixel.tweens.FlxEase; +// Data from the chart +import funkin.data.song.SongData; +import funkin.data.song.SongData.SongEventData; +// Data from the event schema +import funkin.play.event.SongEvent; +import funkin.data.event.SongEventSchema; +import funkin.data.event.SongEventSchema.SongEventFieldType; + +/** + * This class represents a handler for scroll speed events. + * + * Example: Scroll speed change of both strums from 1x to 1.3x: + * ``` + * { + * 'e': 'AdditiveScrollSpeed', + * "v": { + * "scroll": "0.3", + * "duration": "4", + * "ease": "linear" + * } + * } + * ``` + */ +class AdditiveScrollSpeedEvent extends SongEvent +{ + public function new() + { + super('AdditiveScrollSpeed'); + } + + static final DEFAULT_SCROLL:Float = 0; + static final DEFAULT_DURATION:Float = 4.0; + static final DEFAULT_EASE:String = 'linear'; + + public override function handleEvent(data:SongEventData):Void + { + // Does nothing if there is no PlayState camera or stage. + if (PlayState.instance == null || PlayState.instance.currentStage == null) return; + + var scroll:Float = data.getFloat('scroll') ?? DEFAULT_SCROLL; + + var duration:Float = data.getFloat('duration') ?? DEFAULT_DURATION; + + var ease:String = data.getString('ease') ?? DEFAULT_EASE; + + // If it's a string, check the value. + switch (ease) + { + case 'INSTANT': + PlayState.instance.tweenAdditiveScrollSpeed(scroll, 0); + default: + var durSeconds = Conductor.instance.stepLengthMs * duration / 1000; + var easeFunction:NullFloat> = Reflect.field(FlxEase, ease); + if (easeFunction == null) + { + trace('Invalid ease function: $ease'); + return; + } + + PlayState.instance.tweenAdditiveScrollSpeed(scroll, durSeconds, easeFunction); + } + } + + public override function getTitle():String + { + return 'Additive Scroll Speed'; + } + + /** + * ``` + * { + * 'scroll': FLOAT, // Target additive scroll level. + * 'duration': FLOAT, // Duration in steps. + * 'ease': ENUM, // Easing function. + * } + * @return SongEventSchema + */ + public override function getEventSchema():SongEventSchema + { + return new SongEventSchema([ + { + name: 'scroll', + title: 'Additive Scroll Amount', + defaultValue: 0.0, + step: 0.1, + type: SongEventFieldType.FLOAT, + units: 'x' + }, + { + name: 'duration', + title: 'Duration', + defaultValue: 4.0, + step: 0.5, + type: SongEventFieldType.FLOAT, + units: 'steps' + }, + { + name: 'ease', + title: 'Easing Type', + defaultValue: 'linear', + type: SongEventFieldType.ENUM, + keys: [ + 'Linear' => 'linear', + 'Instant' => 'INSTANT', + 'Sine In' => 'sineIn', + 'Sine Out' => 'sineOut', + 'Sine In/Out' => 'sineInOut', + 'Quad In' => 'quadIn', + 'Quad Out' => 'quadOut', + 'Quad In/Out' => 'quadInOut', + 'Cube In' => 'cubeIn', + 'Cube Out' => 'cubeOut', + 'Cube In/Out' => 'cubeInOut', + 'Quart In' => 'quartIn', + 'Quart Out' => 'quartOut', + 'Quart In/Out' => 'quartInOut', + 'Quint In' => 'quintIn', + 'Quint Out' => 'quintOut', + 'Quint In/Out' => 'quintInOut', + 'Expo In' => 'expoIn', + 'Expo Out' => 'expoOut', + 'Expo In/Out' => 'expoInOut', + 'Smooth Step In' => 'smoothStepIn', + 'Smooth Step Out' => 'smoothStepOut', + 'Smooth Step In/Out' => 'smoothStepInOut', + 'Elastic In' => 'elasticIn', + 'Elastic Out' => 'elasticOut', + 'Elastic In/Out' => 'elasticInOut' + ] + } + ]); + } +} diff --git a/source/funkin/play/notes/Strumline.hx b/source/funkin/play/notes/Strumline.hx index 95e0668be2..bd0c8a1be8 100644 --- a/source/funkin/play/notes/Strumline.hx +++ b/source/funkin/play/notes/Strumline.hx @@ -52,6 +52,15 @@ class Strumline extends FlxSpriteGroup */ public var conductorInUse(get, set):Conductor; + // Used in-game to control the scroll speed within a song, for example if a song has an additive scroll speed of 1 and the base scroll speed is 1, it will be 2 - burgerballs + public var scrollSpeedAdditive:Float = 0; + public var scrollSpeed(get, never):Float; + + function get_scrollSpeed():Float + { + return (PlayState.instance?.currentChart?.scrollSpeed ?? 1.0) + scrollSpeedAdditive; + } + var _conductorInUse:Null; function get_conductorInUse():Conductor @@ -208,6 +217,11 @@ class Strumline extends FlxSpriteGroup return null; } + public function resetScrollSpeed():Void + { + scrollSpeedAdditive = 0; + } + public function getHoldNoteSprite(noteData:SongNoteData):SustainTrail { if (noteData == null || ((noteData.length ?? 0.0) <= 0.0)) return null; @@ -283,7 +297,6 @@ class Strumline extends FlxSpriteGroup // var vwoosh:Float = (strumTime < Conductor.songPosition) && vwoosh ? 2.0 : 1.0; // ^^^ commented this out... do NOT make it move faster as it moves offscreen! var vwoosh:Float = 1.0; - var scrollSpeed:Float = PlayState.instance?.currentChart?.scrollSpeed ?? 1.0; return Constants.PIXELS_PER_MS * (conductorInUse.songPosition - strumTime - Conductor.instance.inputOffset) * scrollSpeed * vwoosh * (Preferences.downscroll ? 1 : -1); @@ -539,6 +552,7 @@ class Strumline extends FlxSpriteGroup { playStatic(dir); } + scrollSpeedAdditive = 0; } public function applyNoteData(data:Array):Void @@ -705,6 +719,7 @@ class Strumline extends FlxSpriteGroup if (holdNoteSprite != null) { + holdNoteSprite.parentStrumline = this; holdNoteSprite.noteData = note; holdNoteSprite.strumTime = note.time; holdNoteSprite.noteDirection = note.getDirection(); diff --git a/source/funkin/play/notes/SustainTrail.hx b/source/funkin/play/notes/SustainTrail.hx index 056a6a5a99..b358d7f033 100644 --- a/source/funkin/play/notes/SustainTrail.hx +++ b/source/funkin/play/notes/SustainTrail.hx @@ -32,6 +32,7 @@ class SustainTrail extends FlxSprite public var sustainLength(default, set):Float = 0; // millis public var fullSustainLength:Float = 0; public var noteData:Null; + public var parentStrumline:Strumline; public var cover:NoteHoldCover = null; @@ -119,7 +120,7 @@ class SustainTrail extends FlxSprite // CALCULATE SIZE graphicWidth = graphic.width / 8 * zoom; // amount of notes * 2 - graphicHeight = sustainHeight(sustainLength, getScrollSpeed()); + graphicHeight = sustainHeight(sustainLength, parentStrumline?.scrollSpeed ?? 1.0); // instead of scrollSpeed, PlayState.SONG.speed flipY = Preferences.downscroll; @@ -135,9 +136,21 @@ class SustainTrail extends FlxSprite this.active = true; // This NEEDS to be true for the note to be drawn! } - function getScrollSpeed():Float + function getBaseScrollSpeed() { - return PlayState?.instance?.currentChart?.scrollSpeed ?? 1.0; + return (PlayState.instance?.currentChart?.scrollSpeed ?? 1.0); + } + + var previousScrollSpeed:Float = 1; + + override function update(elapsed) + { + super.update(elapsed); + if (previousScrollSpeed != (parentStrumline?.scrollSpeed ?? 1.0)) + { + triggerRedraw(); + } + previousScrollSpeed = parentStrumline?.scrollSpeed ?? 1.0; } /** @@ -155,12 +168,16 @@ class SustainTrail extends FlxSprite if (s < 0.0) s = 0.0; if (sustainLength == s) return s; - - graphicHeight = sustainHeight(s, getScrollSpeed()); this.sustainLength = s; + triggerRedraw(); + return this.sustainLength; + } + + function triggerRedraw() + { + graphicHeight = sustainHeight(sustainLength, parentStrumline?.scrollSpeed ?? 1.0); updateClipping(); updateHitbox(); - return this.sustainLength; } public override function updateHitbox():Void @@ -178,7 +195,7 @@ class SustainTrail extends FlxSprite */ public function updateClipping(songTime:Float = 0):Void { - var clipHeight:Float = FlxMath.bound(sustainHeight(sustainLength - (songTime - strumTime), getScrollSpeed()), 0, graphicHeight); + var clipHeight:Float = FlxMath.bound(sustainHeight(sustainLength - (songTime - strumTime), parentStrumline?.scrollSpeed ?? 1.0), 0, graphicHeight); if (clipHeight <= 0.1) { visible = false; diff --git a/source/funkin/ui/debug/charting/components/ChartEditorHoldNoteSprite.hx b/source/funkin/ui/debug/charting/components/ChartEditorHoldNoteSprite.hx index aeb6dd0e4a..663f2bbf47 100644 --- a/source/funkin/ui/debug/charting/components/ChartEditorHoldNoteSprite.hx +++ b/source/funkin/ui/debug/charting/components/ChartEditorHoldNoteSprite.hx @@ -58,11 +58,11 @@ class ChartEditorHoldNoteSprite extends SustainTrail { if (lerp) { - sustainLength = FlxMath.lerp(sustainLength, h / (getScrollSpeed() * Constants.PIXELS_PER_MS), 0.25); + sustainLength = FlxMath.lerp(sustainLength, h / (getBaseScrollSpeed() * Constants.PIXELS_PER_MS), 0.25); } else { - sustainLength = h / (getScrollSpeed() * Constants.PIXELS_PER_MS); + sustainLength = h / (getBaseScrollSpeed() * Constants.PIXELS_PER_MS); } fullSustainLength = sustainLength; From e5ee6efdf4cf052c33333ecb937617c231bd19e8 Mon Sep 17 00:00:00 2001 From: Burgerballs <107233412+Burgerballs@users.noreply.github.com> Date: Thu, 9 May 2024 20:01:26 +0100 Subject: [PATCH 006/266] redundancy is bad!!!! --- source/funkin/play/notes/SustainTrail.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/play/notes/SustainTrail.hx b/source/funkin/play/notes/SustainTrail.hx index b358d7f033..9155c9b0a7 100644 --- a/source/funkin/play/notes/SustainTrail.hx +++ b/source/funkin/play/notes/SustainTrail.hx @@ -168,6 +168,7 @@ class SustainTrail extends FlxSprite if (s < 0.0) s = 0.0; if (sustainLength == s) return s; + graphicHeight = sustainHeight(s, parentStrumline?.scrollSpeed ?? 1.0); this.sustainLength = s; triggerRedraw(); return this.sustainLength; @@ -175,7 +176,6 @@ class SustainTrail extends FlxSprite function triggerRedraw() { - graphicHeight = sustainHeight(sustainLength, parentStrumline?.scrollSpeed ?? 1.0); updateClipping(); updateHitbox(); } From 6fc5e8cc2f7e5c9855be1950a75be6b0c4c15c05 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Thu, 9 May 2024 22:36:39 -0400 Subject: [PATCH 007/266] Fixed up some metadata --- example_mods/introMod/_polymod_meta.json | 2 +- example_mods/testing123/_polymod_meta.json | 2 +- tests/unit/assets/shared/images/arrows.png | Bin 4806 -> 0 bytes tests/unit/assets/shared/images/arrows.xml | 27 --------------------- 4 files changed, 2 insertions(+), 29 deletions(-) delete mode 100644 tests/unit/assets/shared/images/arrows.png delete mode 100644 tests/unit/assets/shared/images/arrows.xml diff --git a/example_mods/introMod/_polymod_meta.json b/example_mods/introMod/_polymod_meta.json index e0b03f1cd3..4dc0cd8044 100644 --- a/example_mods/introMod/_polymod_meta.json +++ b/example_mods/introMod/_polymod_meta.json @@ -3,7 +3,7 @@ "description": "An introductory mod.", "contributors": [ { - "name": "MasterEric" + "name": "EliteMasterEric" } ], "api_version": "0.1.0", diff --git a/example_mods/testing123/_polymod_meta.json b/example_mods/testing123/_polymod_meta.json index 4c0f177f9b..0a2ed042c6 100644 --- a/example_mods/testing123/_polymod_meta.json +++ b/example_mods/testing123/_polymod_meta.json @@ -3,7 +3,7 @@ "description": "Newgrounds? More like OLDGROUNDS lol.", "contributors": [ { - "name": "MasterEric" + "name": "EliteMasterEric" } ], "api_version": "0.1.0", diff --git a/tests/unit/assets/shared/images/arrows.png b/tests/unit/assets/shared/images/arrows.png deleted file mode 100644 index a443684327b409e3297d9456cb28afddd889b499..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4806 zcmai2XEYp6yj`pygdov-7k%|!cGXp)6MuaLK|-P>EP||(5G_IU5sY@60Hmk>6#_e#O;P}WCQuimZWfrip8@wZoBrMxN~^)i^X@p2BQX*PrgnR4 zB`_5RX(P^C<+|v4=n}&Oq;pdb3KA044U4U`06wI5QmZ+_)Z1EZ%Hw02Y^tV11u68 zJ2jL>z*K3A!K|AAY9;ySFApP`fNCAt%76>#jpNA`+3`t0;OWgJ2Y%4{3cs4xp9K-X zuk;WPYl|@U`Mev<*fjuFg{H|RxdFzZ(tg_Rs1mR4p3oBo<9BP*w@RjoxDNvHqD)e4 ztURd&;4}cu&0>c1qz7uzQ{<<*-#NJ%1Sf8b2-=4I;YtdehK2P|Jv|g#vP6cxQ9Ih_ z{VR}zOPayta1izIO2I=#USlH(^S1zAUjxAAiRu*jH zCxCb)me;|vmA7-2>pFMT+%!IvbDwODcJQRYbFGGc^ zvkBh)&`1%|@PdkAaWYi%RH0^)6Eo+(T~gk`>;J}$iXP;8L`~2xiS79LUBo42o0kEOhm~wnZWboa@C6=Xu^((8{it zr_`G#e0=cJZxcP838zUT=_ncdWL1-)f*^;y4m@YK*zT&ad(R{d0Z7y60v6 zrRyc}q1A%(sqQXe=gtqNnTM4`4$4MRc6oV{4?4GHS7gfXvW4~pzVdEsd1$Cfuv7y? zP`m?^tW9bzH_~jOMbe_iRfV__Y}^Nc)%A8G>r6}X&N2@Eo*s(N<&46X#O{_U&rCkQ z{MDpKX3Z(#i(qQAFMYBpRB$fD3wZ~56l*pWe%Gw6Olm0nZh_svUBv6$srLaw)Bm{& znlnl~V-w)ikJ=j<7TP9IBEImfm_ZR-4VUZj1TB9w6t@#;&Uf#diLn6rk{Z)C^^v&6-p0DR z^o((zocBd_Gszpl9a`J307h3M4gn7XmGTDeYcwx=eJc;7q`O{oiAc$dTKnEqnzil` zdM2eb&!2F=R2Ke%@UseG_8Ib@?oL`iKDG-wdcG1#9Qw0{hOn^^5}wCs2m?%oI6hz{ zgF2EKr56swk`rJsA5gmqqfT{ji$98)R`xEl|c0K5^zGqE6 zhL;VbcI!OC+F?e*E~)jveC8@jUso~z2_x-S7(YN#5P#B=;`l_-Y>aLBs=> z?(F!MJQzBxUv5QaxGP_QO??*hp>ib4W?wmHTYi>W*qb@?=v-Wx$df=(jb2F!Ii z^hQ?)w04-c)zXlphQ=7s>X3+(PXl-FX9|%YI&z z*yl79kRE>rf0ov!Q$i#Bv*00+U{)+>8TC-CyDA;o-fqFIQN@wxL-> zzkeg2IlF)SK{@{Co`GNEbfYkuCA|_bFdgWuhKeQFU#I~3E4QNl%cE>FdDyw% zfdcLNx50w9CVVSb~ zfJ|kRk^kBy zF=rh1f}TuYBl1Jk*03xJ520y_Q8mC!ex(;~R8Tn8GdEeH7(=Nr{I8mog9?`_T4v_d z=ItzYGTKvv)X;y%t%4jSz*hMp9lS(hgdG6aj}YIACP9sIuvU#HC%_Umma*H@Njv;pJcQO!d0o~nKg>4hVz9969g z6+=2ZPiM&KZZ~;SWvX~;ugM}m;IvoVp$JOOz3%XibPXKlWQE{uGiMeJM zsY9xszm^hj^MkTLC;|M+WwEqRORGvL4~@-z!sj9%IMJF!SICcA@{a_v-+vAEK(4z- zrBNb;KmAwobwlIZSA!~AMOM_cBBA%iafoFobg$4J%JGHEaXwIO;~`WYB=UB*78&5iv%wd@6!p1}A6O zOM1`a@@`i}p9Te+)N6t(A+qD%717s;vdP&Kp9s+Tau!|>9a(8YG*tmy3$}c}5!wGD zVlJTlE}@Y4#zi4t|Y>qsc*-Fc#o!5Ay zu#GxIN~s86Fs~{;VoqiFtBFo8XS)@Ubl(#&>0cpspf*=j7jZ8;feaQtkJq>Ci)AjP zV5ap*GWl!Z)#-C=w30FMDexb!|FJ@>ci=Iv#0ft)o-i5+eLjVnx+D}C1m>q>_Sd95 zxmqZ_*ihdSo1y=WRO^mgOuGIdUafyG8o0yq1X&d>dyIN!cSO097tbb~l1Vw$`MY-v zO#^#+T9`h1qsPnt2r*r1Mm{~V>9E{}jG_~KhQ7S*p^!RYZE*R?l4gDf$}u+XYHj;0}w=Io=ifu619 zXA_&;l*tjY&RDNU#d@V4gO)GLQfkrC{#G$gypKBQ{0ycucspiFn$Yqg0vU7mrDC!I zXJ~1t`^C1s`FzjK;PZ2<{15GtZ&aS1c-7kk@+)^=w!l}m9v24kXXKE%kIz)di!^6n z>6hCgx8-^iI8 zFZi9ps4vHt9Xeo-9rZhe@Z+jvalVO z!sJ1MK)$U(MW$gz7gd4B-KD;nNxOR+t9pU2UjUsQe zN5aA!Z~YP2S934`MV8YuJ)i?(=GKcR;5KK!82sZU@S>+yI?bASp-2SRAPouT22c(^ zDmXYfWZ7mS?EJM~h=nnpu-%YTHl#^YJLhO@^GowM@ijM7szQv6PvmvZHIyg%O zVuds4rignBEoTS}SWg07v@JeZh7GBDQR%FpVdX;K+*?vCz8=Iis80q!e~XrfI9M=l z%{DxCYZFpALGM>I-B^~Kj8sPi^pfvZv~*pu^u^7F|6z4ol0qMapSP{}rz>S=GQ5zQ zU#eZKOfPcA^Bj%m`StAsfNesX4R!4<1bVLR~_cC<*;g?2zg5f8pAFLamqR9I)&gq+N)=1*e5&>)!NV53s zuvyF3i_7F~(3h9~=74hpgWMqp%(}H{bJj;02K(TjSHE6v`v_ye4Iikc*U}sGq=lg0 z4-qCB7CQPiMNe5x%hdl4RygaC8FL&-^VU@~J4}&VcO^_Vm7B0%wV2E@ z32zQcMwlC}RO*pVI>vx5M=nsi<71>}+8=1>T9fVO+3%LYU0gyvTDV)2Z5s$d&T$l8 z>{Wz)TjoOl%=ffPfzvKH z+dbk18I=8{<0;H$G8P%Y4Od!LkVn@l^9l=70X_3`e8t=*K}+-=oim^#7xM1+TO; zz3S2HnZ=votfeo!V&b<*V_u#}9xxwo@4fK3A)uzP0T071yG@-N1i;wnmfZ3|mdLMl zDAFg#r*#Oa20Z|+;Ji}hN5zF^m<=qN_8L8kcK%-noqT)enY>N^z5Wyn{KphPSJMzu Iso@a*KZ!k4q5uE@ diff --git a/tests/unit/assets/shared/images/arrows.xml b/tests/unit/assets/shared/images/arrows.xml deleted file mode 100644 index 96a73a3888..0000000000 --- a/tests/unit/assets/shared/images/arrows.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - From a243b167b2b1a76c70a7b68296d7e27f4410cff4 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Thu, 9 May 2024 22:37:01 -0400 Subject: [PATCH 008/266] Fix up more credits --- source/funkin/play/components/HealthIcon.hx | 2 +- source/funkin/ui/debug/charting/ChartEditorState.hx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/funkin/play/components/HealthIcon.hx b/source/funkin/play/components/HealthIcon.hx index 957daa43c9..2d7099e8ac 100644 --- a/source/funkin/play/components/HealthIcon.hx +++ b/source/funkin/play/components/HealthIcon.hx @@ -24,7 +24,7 @@ import funkin.util.MathUtil; * - i.e. `PlayState.instance.iconP1.playAnimation("losing")` * - Scripts can also utilize all functionality that a normal FlxSprite would have access to, such as adding supplimental animations. * - i.e. `PlayState.instance.iconP1.animation.addByPrefix("jumpscare", "jumpscare", 24, false);` - * @author MasterEric + * @author EliteMasterEric */ @:nullSafety class HealthIcon extends FunkinSprite diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index b75cd8bf1f..a313981f45 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -137,7 +137,7 @@ using Lambda; * * Some functionality is split into handler classes to help maintain my sanity. * - * @author MasterEric + * @author EliteMasterEric */ // @:nullSafety From 5d5cf740204ac0b57712483a5e2a9fb0491b6eba Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Thu, 9 May 2024 22:37:21 -0400 Subject: [PATCH 009/266] Reimplement rank-based results animations. --- README.md | 2 +- assets | 2 +- source/funkin/play/ResultState.hx | 332 +++++++++++++++++++++--------- source/funkin/util/Constants.hx | 11 + 4 files changed, 245 insertions(+), 102 deletions(-) diff --git a/README.md b/README.md index 39c098af5e..5728a6cb37 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Please check out our [Contributor's guide](./CONTRIBUTORS.md) on how you can act ## Programming - [ninjamuffin99](https://twitter.com/ninja_muffin99) - Lead Programmer -- [MasterEric](https://twitter.com/EliteMasterEric) - Programmer +- [EliteMasterEric](https://twitter.com/EliteMasterEric) - Programmer - [MtH](https://twitter.com/emmnyaa) - Charting and Additional Programming - [GeoKureli](https://twitter.com/Geokureli/) - Additional Programming - Our contributors on GitHub diff --git a/assets b/assets index fe52d20de7..6115eb6837 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit fe52d20de7025d90cadb429dbdedf6d986727088 +Subproject commit 6115eb6837e97b8b3ad82f3ccd2a49a4383ed35b diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx index 56dd1e80fc..7f8bdd77ab 100644 --- a/source/funkin/play/ResultState.hx +++ b/source/funkin/play/ResultState.hx @@ -26,6 +26,7 @@ import funkin.play.components.TallyCounter; /** * The state for the results screen after a song or week is finished. */ +@:nullSafety class ResultState extends MusicBeatSubState { final params:ResultsStateParams; @@ -42,91 +43,45 @@ class ResultState extends MusicBeatSubState super(); this.params = params; + + resultsVariation = calculateVariation(params); + + var fontLetters:String = "AaBbCcDdEeFfGgHhiIJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz:1234567890"; + songName = new FlxBitmapText(FlxBitmapFont.fromMonospace(Paths.image("resultScreen/tardlingSpritesheet"), fontLetters, FlxPoint.get(49, 62))); + songName.text = params.title; + songName.letterSpacing = -15; + songName.angle = -4.4; + songName.zIndex = 1000; + + difficulty = new FlxSprite(555); + difficulty.zIndex = 1000; } override function create():Void { - /* - if (params.scoreData.sick == params.scoreData.totalNotesHit - && params.scoreData.maxCombo == params.scoreData.totalNotesHit) resultsVariation = PERFECT; - else if (params.scoreData.missed + params.scoreData.bad + params.scoreData.shit >= params.scoreData.totalNotes * 0.50) - resultsVariation = SHIT; // if more than half of your song was missed, bad, or shit notes, you get shit ending! - else - resultsVariation = NORMAL; - */ - resultsVariation = NORMAL; - - FunkinSound.playMusic('results$resultsVariation', + FunkinSound.playMusic(resultsVariation.getMusicPath(), { startingVolume: 1.0, overrideExisting: true, restartTrack: true, - loop: resultsVariation != SHIT + loop: resultsVariation.shouldMusicLoop() }); // Reset the camera zoom on the results screen. FlxG.camera.zoom = 1.0; - // TEMP-ish, just used to sorta "cache" the 3000x3000 image! - var cacheBullShit:FlxSprite = new FlxSprite().loadGraphic(Paths.image("resultScreen/soundSystem")); - add(cacheBullShit); - - var dumb:FlxSprite = new FlxSprite().loadGraphic(Paths.image("resultScreen/scorePopin")); - add(dumb); - var bg:FlxSprite = FlxGradient.createGradientFlxSprite(FlxG.width, FlxG.height, [0xFFFECC5C, 0xFFFDC05C], 90); bg.scrollFactor.set(); + bg.zIndex = 10; add(bg); var bgFlash:FlxSprite = FlxGradient.createGradientFlxSprite(FlxG.width, FlxG.height, [0xFFFFEB69, 0xFFFFE66A], 90); bgFlash.scrollFactor.set(); bgFlash.visible = false; + bg.zIndex = 20; add(bgFlash); - // var bfGfExcellent:FlxAtlasSprite = new FlxAtlasSprite(380, -170, Paths.animateAtlas("resultScreen/resultsBoyfriendExcellent", "shared")); - // bfGfExcellent.visible = false; - // add(bfGfExcellent); - // - // var bfPerfect:FlxAtlasSprite = new FlxAtlasSprite(370, -180, Paths.animateAtlas("resultScreen/resultsBoyfriendPerfect", "shared")); - // bfPerfect.visible = false; - // add(bfPerfect); - // - // var bfSHIT:FlxAtlasSprite = new FlxAtlasSprite(0, 20, Paths.animateAtlas("resultScreen/resultsBoyfriendSHIT", "shared")); - // bfSHIT.visible = false; - // add(bfSHIT); - // - // bfGfExcellent.anim.onComplete = () -> { - // bfGfExcellent.anim.curFrame = 28; - // bfGfExcellent.anim.play(); // unpauses this anim, since it's on PlayOnce! - // }; - // - // bfPerfect.anim.onComplete = () -> { - // bfPerfect.anim.curFrame = 136; - // bfPerfect.anim.play(); // unpauses this anim, since it's on PlayOnce! - // }; - // - // bfSHIT.anim.onComplete = () -> { - // bfSHIT.anim.curFrame = 150; - // bfSHIT.anim.play(); // unpauses this anim, since it's on PlayOnce! - // }; - - var gf:FlxSprite = FunkinSprite.createSparrow(625, 325, 'resultScreen/resultGirlfriendGOOD'); - gf.animation.addByPrefix("clap", "Girlfriend Good Anim", 24, false); - gf.visible = false; - gf.animation.finishCallback = _ -> { - gf.animation.play('clap', true, false, 9); - }; - add(gf); - - var boyfriend:FlxSprite = FunkinSprite.createSparrow(640, -200, 'resultScreen/resultBoyfriendGOOD'); - boyfriend.animation.addByPrefix("fall", "Boyfriend Good Anim0", 24, false); - boyfriend.visible = false; - boyfriend.animation.finishCallback = function(_) { - boyfriend.animation.play('fall', true, false, 14); - }; - - add(boyfriend); - + // The sound system which falls into place behind the score text. Plays every time! var soundSystem:FlxSprite = FunkinSprite.createSparrow(-15, -180, 'resultScreen/soundSystem'); soundSystem.animation.addByPrefix("idle", "sound system", 24, false); soundSystem.visible = false; @@ -134,9 +89,66 @@ class ResultState extends MusicBeatSubState soundSystem.animation.play("idle"); soundSystem.visible = true; }); + soundSystem.zIndex = 1100; add(soundSystem); - difficulty = new FlxSprite(555); + var bfPerfect:Null = null; + var bfExcellent:Null = null; + var bfGood:Null = null; + var gfGood:Null = null; + var bfShit:Null = null; + + switch (resultsVariation) + { + case PERFECT | PERFECT_GOLD | PERFECT_PLATINUM: + bfPerfect = new FlxAtlasSprite(370, -180, Paths.animateAtlas("resultScreen/results-bf/resultsPERFECT", "shared")); + bfPerfect.visible = false; + bfPerfect.zIndex = 500; + add(bfPerfect); + + bfPerfect.anim.onComplete = () -> { + bfPerfect.anim.curFrame = 136; + bfPerfect.anim.play(); // unpauses this anim, since it's on PlayOnce! + }; + + case EXCELLENT: + bfExcellent = new FlxAtlasSprite(380, -170, Paths.animateAtlas("resultScreen/results-bf/resultsEXCELLENT", "shared")); + bfExcellent.visible = false; + bfExcellent.zIndex = 500; + add(bfExcellent); + + bfExcellent.onAnimationFinish.add((animName) -> { + bfExcellent.playAnimation('Loop Start'); + }); + + case GOOD | GREAT: + gfGood = FunkinSprite.createSparrow(625, 325, 'resultScreen/results-bf/resultsGOOD/resultGirlfriendGOOD'); + gfGood.animation.addByPrefix("clap", "Girlfriend Good Anim", 24, false); + gfGood.visible = false; + gfGood.zIndex = 500; + gfGood.animation.finishCallback = _ -> { + gfGood.animation.play('clap', true, false, 9); + }; + add(gfGood); + + bfGood = FunkinSprite.createSparrow(640, -200, 'resultScreen/results-bf/resultsGOOD/resultBoyfriendGOOD'); + bfGood.animation.addByPrefix("fall", "Boyfriend Good Anim0", 24, false); + bfGood.visible = false; + bfGood.zIndex = 501; + bfGood.animation.finishCallback = function(_) { + bfGood.animation.play('fall', true, false, 14); + }; + add(bfGood); + + case SHIT: + bfShit = new FlxAtlasSprite(0, 20, Paths.animateAtlas("resultScreen/results-bf/resultsSHIT", "shared")); + bfShit.visible = false; + bfShit.zIndex = 500; + add(bfShit); + bfShit.onAnimationFinish.add((animName) -> { + bfShit.playAnimation('Loop Start'); + }); + } var diffSpr:String = switch (PlayState.instance.currentDifficulty) { @@ -157,11 +169,6 @@ class ResultState extends MusicBeatSubState difficulty.loadGraphic(Paths.image("resultScreen/" + diffSpr)); add(difficulty); - var fontLetters:String = "AaBbCcDdEeFfGgHhiIJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz:1234567890"; - songName = new FlxBitmapText(FlxBitmapFont.fromMonospace(Paths.image("resultScreen/tardlingSpritesheet"), fontLetters, FlxPoint.get(49, 62))); - songName.text = params.title; - songName.letterSpacing = -15; - songName.angle = -4.4; add(songName); var angleRad = songName.angle * Math.PI / 180; @@ -179,21 +186,25 @@ class ResultState extends MusicBeatSubState var blackTopBar:FlxSprite = new FlxSprite().loadGraphic(Paths.image("resultScreen/topBarBlack")); blackTopBar.y = -blackTopBar.height; FlxTween.tween(blackTopBar, {y: 0}, 0.4, {ease: FlxEase.quartOut, startDelay: 0.5}); + blackTopBar.zIndex = 1010; add(blackTopBar); var resultsAnim:FunkinSprite = FunkinSprite.createSparrow(-200, -10, "resultScreen/results"); resultsAnim.animation.addByPrefix("result", "results instance 1", 24, false); resultsAnim.animation.play("result"); + resultsAnim.zIndex = 1200; add(resultsAnim); var ratingsPopin:FunkinSprite = FunkinSprite.createSparrow(-150, 120, "resultScreen/ratingsPopin"); ratingsPopin.animation.addByPrefix("idle", "Categories", 24, false); ratingsPopin.visible = false; + ratingsPopin.zIndex = 1200; add(ratingsPopin); var scorePopin:FunkinSprite = FunkinSprite.createSparrow(-180, 520, "resultScreen/scorePopin"); scorePopin.animation.addByPrefix("score", "tally score", 24, false); scorePopin.visible = false; + scorePopin.zIndex = 1200; add(scorePopin); var highscoreNew:FlxSprite = new FlxSprite(310, 570); @@ -202,11 +213,13 @@ class ResultState extends MusicBeatSubState highscoreNew.visible = false; highscoreNew.setGraphicSize(Std.int(highscoreNew.width * 0.8)); highscoreNew.updateHitbox(); + highscoreNew.zIndex = 1200; add(highscoreNew); var hStuf:Int = 50; var ratingGrp:FlxTypedGroup = new FlxTypedGroup(); + ratingGrp.zIndex = 1200; add(ratingGrp); /** @@ -238,6 +251,7 @@ class ResultState extends MusicBeatSubState var score:ResultScore = new ResultScore(35, 305, 10, params.scoreData.score); score.visible = false; + score.zIndex = 1200; add(score); for (ind => rating in ratingGrp.members) @@ -275,40 +289,72 @@ class ResultState extends MusicBeatSubState switch (resultsVariation) { - // case SHIT: - // bfSHIT.visible = true; - // bfSHIT.playAnimation(""); - - case NORMAL: - boyfriend.animation.play('fall'); - boyfriend.visible = true; - - new FlxTimer().start((1 / 24) * 12, _ -> { - bgFlash.visible = true; - FlxTween.tween(bgFlash, {alpha: 0}, 0.4); - new FlxTimer().start((1 / 24) * 2, _ -> - { - // bgFlash.alpha = 0.5; - - // bgFlash.visible = false; - }); - }); - - new FlxTimer().start((1 / 24) * 22, _ -> { - // plays about 22 frames (at 24fps timing) after bf spawns in - gf.animation.play('clap', true); - gf.visible = true; - }); - // case PERFECT: - // bfPerfect.visible = true; - // bfPerfect.playAnimation(""); - - // bfGfExcellent.visible = true; - // bfGfExcellent.playAnimation(""); + case PERFECT | PERFECT_GOLD | PERFECT_PLATINUM: + if (bfPerfect == null) + { + trace("Could not build PERFECT animation!"); + } + else + { + bfPerfect.visible = true; + bfPerfect.playAnimation(''); + } + + case EXCELLENT: + if (bfExcellent == null) + { + trace("Could not build EXCELLENT animation!"); + } + else + { + bfExcellent.visible = true; + bfExcellent.playAnimation('Intro'); + } + + case SHIT: + if (bfShit == null) + { + trace("Could not build SHIT animation!"); + } + else + { + bfShit.visible = true; + bfShit.playAnimation('Intro'); + } + + case GREAT | GOOD: + if (bfGood == null || gfGood == null) + { + trace("Could not build GOOD animation!"); + } + else + { + bfGood.animation.play('fall'); + bfGood.visible = true; + + new FlxTimer().start((1 / 24) * 12, _ -> { + bgFlash.visible = true; + FlxTween.tween(bgFlash, {alpha: 0}, 0.4); + new FlxTimer().start((1 / 24) * 2, _ -> + { + // bgFlash.alpha = 0.5; + + // bgFlash.visible = false; + }); + }); + + new FlxTimer().start((1 / 24) * 22, _ -> { + // plays about 22 frames (at 24fps timing) after bf spawns in + gfGood.animation.play('clap', true); + gfGood.visible = true; + }); + } default: } }); + refresh(); + super.create(); } @@ -401,14 +447,100 @@ class ResultState extends MusicBeatSubState super.update(elapsed); } + + public static function calculateVariation(params:ResultsStateParams):ResultVariations + { + // Perfect (Platinum) is a Sick Full Clear + var isPerfectPlat = (params.scoreData.tallies.sick + params.scoreData.tallies.good) == params.scoreData.tallies.totalNotes + && params.scoreData.tallies.sick / params.scoreData.tallies.totalNotes >= Constants.RANK_PERFECT_PLAT_THRESHOLD; + if (isPerfectPlat) return ResultVariations.PERFECT_PLATINUM; + + // Perfect (Gold) is an 85% Sick Full Clear + var isPerfectGold = (params.scoreData.tallies.sick + params.scoreData.tallies.good) == params.scoreData.tallies.totalNotes + && params.scoreData.tallies.sick / params.scoreData.tallies.totalNotes >= Constants.RANK_PERFECT_GOLD_THRESHOLD; + if (isPerfectGold) return ResultVariations.PERFECT_GOLD; + + // Else, use the standard grades + + // Clear % (including bad and shit). 1.00 is a full clear but not a full combo + var clear = (params.scoreData.tallies.totalNotesHit) / params.scoreData.tallies.totalNotes; + + if (clear == Constants.RANK_PERFECT_THRESHOLD) + { + return ResultVariations.PERFECT; + } + else if (clear >= Constants.RANK_EXCELLENT_THRESHOLD) + { + return ResultVariations.EXCELLENT; + } + else if (clear >= Constants.RANK_GREAT_THRESHOLD) + { + return ResultVariations.GREAT; + } + else if (clear >= Constants.RANK_GOOD_THRESHOLD) + { + return ResultVariations.GOOD; + } + else + { + return ResultVariations.SHIT; + } + } } enum abstract ResultVariations(String) { + var PERFECT_PLATINUM; + var PERFECT_GOLD; var PERFECT; var EXCELLENT; - var NORMAL; + var GREAT; + var GOOD; var SHIT; + + public function getMusicPath():String + { + switch (abstract) + { + case PERFECT_PLATINUM: + return 'resultsPERFECT'; + case PERFECT_GOLD: + return 'resultsPERFECT'; + case PERFECT: + return 'resultsPERFECT'; + case EXCELLENT: + return 'resultsNORMAL'; + case GREAT: + return 'resultsNORMAL'; + case GOOD: + return 'resultsNORMAL'; + case SHIT: + return 'resultsSHIT'; + } + } + + public function shouldMusicLoop():Bool + { + switch (abstract) + { + case PERFECT_PLATINUM: + return true; + case PERFECT_GOLD: + return true; + case PERFECT: + return true; + case EXCELLENT: + return true; + case GREAT: + return true; + case GOOD: + return true; + case SHIT: + return false; + default: + return false; + } + } } typedef ResultsStateParams = diff --git a/source/funkin/util/Constants.hx b/source/funkin/util/Constants.hx index c50f17697b..2f3b570b3b 100644 --- a/source/funkin/util/Constants.hx +++ b/source/funkin/util/Constants.hx @@ -455,6 +455,17 @@ class Constants public static final JUDGEMENT_BAD_COMBO_BREAK:Bool = true; public static final JUDGEMENT_SHIT_COMBO_BREAK:Bool = true; + // % Sick + public static final RANK_PERFECT_PLAT_THRESHOLD:Float = 1.0; // % Sick + public static final RANK_PERFECT_GOLD_THRESHOLD:Float = 0.85; // % Sick + + // % 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_GOOD_THRESHOLD:Float = 0.60; + + // public static final RANK_SHIT_THRESHOLD:Float = 0.00; /** * FILE EXTENSIONS */ From 98cf37b642292fcd7eb8a5913db5c7e08a43b82a Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Thu, 9 May 2024 22:38:01 -0400 Subject: [PATCH 010/266] Update assets to add music. --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 6115eb6837..7df2e55273 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 6115eb6837e97b8b3ad82f3ccd2a49a4383ed35b +Subproject commit 7df2e552738f8f2278538513a7495cb96d5ed118 From a5700b37e10e35f6fc338b646951903887c221a6 Mon Sep 17 00:00:00 2001 From: Burgerballs <107233412+Burgerballs@users.noreply.github.com> Date: Fri, 10 May 2024 21:23:35 +0100 Subject: [PATCH 011/266] awesome shit (see desc) No longer Additive, it just sets the scroll speed Now you can set it to either strumline --- source/funkin/play/PlayState.hx | 60 ++++++++++--------- ...crollSpeedEvent.hx => ScrollSpeedEvent.hx} | 51 ++++++++++++---- source/funkin/play/notes/Strumline.hx | 17 ++---- 3 files changed, 77 insertions(+), 51 deletions(-) rename source/funkin/play/event/{AdditiveScrollSpeedEvent.hx => ScrollSpeedEvent.hx} (69%) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 0b76ec6ee2..b4c733ee3e 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -239,7 +239,7 @@ class PlayState extends MusicBeatSubState /** * An FlxTween that changes the additive speed to the desired amount. */ - public var additiveScrollSpeedTween:FlxTween; + public var scrollSpeedTweens:Array = []; /** * The camera follow point from the last stage. @@ -1184,10 +1184,14 @@ class PlayState extends MusicBeatSubState cameraZoomTween.active = false; cameraTweensPausedBySubState.add(cameraZoomTween); } - if (additiveScrollSpeedTween != null && additiveScrollSpeedTween.active) + + for (tween in scrollSpeedTweens) { - additiveScrollSpeedTween.active = false; - cameraTweensPausedBySubState.add(additiveScrollSpeedTween); + if (tween != null && tween.active) + { + tween.active = false; + cameraTweensPausedBySubState.add(tween); + } } // Pause the countdown. @@ -3035,7 +3039,7 @@ class PlayState extends MusicBeatSubState // Cancel camera and scroll tweening if it's active. cancelAllCameraTweens(); - cancelAdditiveScrollSpeedTween(); + cancelScrollSpeedTweens(); // If the opponent is GF, zoom in on the opponent. // Else, if there is no GF, zoom in on BF. @@ -3256,37 +3260,39 @@ class PlayState extends MusicBeatSubState } /** - * The magical function that shall tween the additive scroll speed. + * The magical function that shall tween the scroll speed. */ - public function tweenAdditiveScrollSpeed(?speed:Float, ?duration:Float, ?ease:NullFloat>):Void + public function tweenScrollSpeed(?speed:Float, ?duration:Float, ?ease:NullFloat>, strumlines:Array):Void { // Cancel the current tween if it's active. - cancelAdditiveScrollSpeedTween(); - var strumLineTargets:Array = [ - playerStrumline.scrollSpeedAdditive + speed, - opponentStrumline.scrollSpeedAdditive + speed - ]; - - if (duration == 0) + cancelScrollSpeedTweens(); + for (i in strumlines) { - playerStrumline.scrollSpeedAdditive = strumLineTargets[0]; - opponentStrumline.scrollSpeedAdditive = strumLineTargets[1]; - } - else - { - additiveScrollSpeedTween = FlxTween.tween(this, - { - "playerStrumline.scrollSpeedAdditive": strumLineTargets[0], - "opponentStrumline.scrollSpeedAdditive": strumLineTargets[1] - }, duration, {ease: ease}); + var value:Float = speed; + var strum:Strumline = Reflect.getProperty(this, i); + + if (duration == 0) + { + strum.scrollSpeed = value; + } + else + { + scrollSpeedTweens.push(FlxTween.tween(strum, + { + 'scrollSpeed': value + }, duration, {ease: ease})); + } } } - public function cancelAdditiveScrollSpeedTween() + public function cancelScrollSpeedTweens() { - if (additiveScrollSpeedTween != null) + for (tween in scrollSpeedTweens) { - additiveScrollSpeedTween.cancel(); + if (tween != null) + { + tween.cancel(); + } } } diff --git a/source/funkin/play/event/AdditiveScrollSpeedEvent.hx b/source/funkin/play/event/ScrollSpeedEvent.hx similarity index 69% rename from source/funkin/play/event/AdditiveScrollSpeedEvent.hx rename to source/funkin/play/event/ScrollSpeedEvent.hx index f66f3b2571..22da45b0cb 100644 --- a/source/funkin/play/event/AdditiveScrollSpeedEvent.hx +++ b/source/funkin/play/event/ScrollSpeedEvent.hx @@ -17,30 +17,31 @@ import funkin.data.event.SongEventSchema.SongEventFieldType; * Example: Scroll speed change of both strums from 1x to 1.3x: * ``` * { - * 'e': 'AdditiveScrollSpeed', + * 'e': 'ScrollSpeed', * "v": { - * "scroll": "0.3", + * "scroll": "1.3", * "duration": "4", * "ease": "linear" * } * } * ``` */ -class AdditiveScrollSpeedEvent extends SongEvent +class ScrollSpeedEvent extends SongEvent { public function new() { - super('AdditiveScrollSpeed'); + super('ScrollSpeed'); } - static final DEFAULT_SCROLL:Float = 0; + static final DEFAULT_SCROLL:Float = 1; static final DEFAULT_DURATION:Float = 4.0; static final DEFAULT_EASE:String = 'linear'; + static final DEFAULT_STRUMLINE:String = 'both'; // my special little trick public override function handleEvent(data:SongEventData):Void { - // Does nothing if there is no PlayState camera or stage. - if (PlayState.instance == null || PlayState.instance.currentStage == null) return; + // Does nothing if there is no PlayState. + if (PlayState.instance == null) return; var scroll:Float = data.getFloat('scroll') ?? DEFAULT_SCROLL; @@ -48,11 +49,28 @@ class AdditiveScrollSpeedEvent extends SongEvent var ease:String = data.getString('ease') ?? DEFAULT_EASE; + var strumline:String = data.getString('strumline') ?? DEFAULT_STRUMLINE; + + var strumlineNames:Array = []; + + if (scroll == 0) + { + // if the parameter is set to 0, reset the scroll speed to normal. + scroll = PlayState.instance?.currentChart?.scrollSpeed ?? 1.0; + } + + switch (strumline) + { + case 'both': + strumlineNames = ['playerStrumline', 'opponentStrumline']; + default: + strumlineNames = [strumline + 'Strumline']; + } // If it's a string, check the value. switch (ease) { case 'INSTANT': - PlayState.instance.tweenAdditiveScrollSpeed(scroll, 0); + PlayState.instance.tweenScrollSpeed(scroll, 0, null, strumlineNames); default: var durSeconds = Conductor.instance.stepLengthMs * duration / 1000; var easeFunction:NullFloat> = Reflect.field(FlxEase, ease); @@ -62,19 +80,19 @@ class AdditiveScrollSpeedEvent extends SongEvent return; } - PlayState.instance.tweenAdditiveScrollSpeed(scroll, durSeconds, easeFunction); + PlayState.instance.tweenScrollSpeed(scroll, durSeconds, easeFunction, strumlineNames); } } public override function getTitle():String { - return 'Additive Scroll Speed'; + return 'Scroll Speed'; } /** * ``` * { - * 'scroll': FLOAT, // Target additive scroll level. + * 'scroll': FLOAT, // Target scroll level. * 'duration': FLOAT, // Duration in steps. * 'ease': ENUM, // Easing function. * } @@ -85,7 +103,7 @@ class AdditiveScrollSpeedEvent extends SongEvent return new SongEventSchema([ { name: 'scroll', - title: 'Additive Scroll Amount', + title: 'Scroll Amount', defaultValue: 0.0, step: 0.1, type: SongEventFieldType.FLOAT, @@ -106,7 +124,7 @@ class AdditiveScrollSpeedEvent extends SongEvent type: SongEventFieldType.ENUM, keys: [ 'Linear' => 'linear', - 'Instant' => 'INSTANT', + 'Instant (Ignores Duration)' => 'INSTANT', 'Sine In' => 'sineIn', 'Sine Out' => 'sineOut', 'Sine In/Out' => 'sineInOut', @@ -132,6 +150,13 @@ class AdditiveScrollSpeedEvent extends SongEvent 'Elastic Out' => 'elasticOut', 'Elastic In/Out' => 'elasticInOut' ] + }, + { + name: 'strumline', + title: 'Target Strumline', + defaultValue: 'both', + type: SongEventFieldType.ENUM, + keys: ['Both' => 'both', 'Player' => 'player', 'Opponent' => 'opponent'] } ]); } diff --git a/source/funkin/play/notes/Strumline.hx b/source/funkin/play/notes/Strumline.hx index bd0c8a1be8..dbc8569c58 100644 --- a/source/funkin/play/notes/Strumline.hx +++ b/source/funkin/play/notes/Strumline.hx @@ -52,13 +52,12 @@ class Strumline extends FlxSpriteGroup */ public var conductorInUse(get, set):Conductor; - // Used in-game to control the scroll speed within a song, for example if a song has an additive scroll speed of 1 and the base scroll speed is 1, it will be 2 - burgerballs - public var scrollSpeedAdditive:Float = 0; - public var scrollSpeed(get, never):Float; + // Used in-game to control the scroll speed within a song + public var scrollSpeed:Float = 1.0; - function get_scrollSpeed():Float + public function resetScrollSpeed():Void { - return (PlayState.instance?.currentChart?.scrollSpeed ?? 1.0) + scrollSpeedAdditive; + scrollSpeed = PlayState.instance?.currentChart?.scrollSpeed ?? 1.0; } var _conductorInUse:Null; @@ -143,6 +142,7 @@ class Strumline extends FlxSpriteGroup this.refresh(); this.onNoteIncoming = new FlxTypedSignalVoid>(); + resetScrollSpeed(); for (i in 0...KEY_COUNT) { @@ -217,11 +217,6 @@ class Strumline extends FlxSpriteGroup return null; } - public function resetScrollSpeed():Void - { - scrollSpeedAdditive = 0; - } - public function getHoldNoteSprite(noteData:SongNoteData):SustainTrail { if (noteData == null || ((noteData.length ?? 0.0) <= 0.0)) return null; @@ -552,7 +547,7 @@ class Strumline extends FlxSpriteGroup { playStatic(dir); } - scrollSpeedAdditive = 0; + resetScrollSpeed(); } public function applyNoteData(data:Array):Void From 5fd2ea0bcf0c60ed4ea654b34485df86c34a88fc Mon Sep 17 00:00:00 2001 From: Burgerballs <107233412+Burgerballs@users.noreply.github.com> Date: Fri, 10 May 2024 21:37:46 +0100 Subject: [PATCH 012/266] optimization of the cleary boy (: --- source/funkin/play/PlayState.hx | 1 + 1 file changed, 1 insertion(+) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index b4c733ee3e..4ce778fc1c 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -3294,6 +3294,7 @@ class PlayState extends MusicBeatSubState tween.cancel(); } } + scrollSpeedTweens = []; } #if (debug || FORCE_DEBUG_VERSION) From 83c3ff478c27bdc096e7dfcea190753df97526b5 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 10 May 2024 22:09:09 -0400 Subject: [PATCH 013/266] Added Clear % tally to results. --- assets | 2 +- source/funkin/play/ResultState.hx | 371 +++++++++++++++++++++--------- 2 files changed, 261 insertions(+), 112 deletions(-) diff --git a/assets b/assets index 7df2e55273..927578f482 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 7df2e552738f8f2278538513a7495cb96d5ed118 +Subproject commit 927578f482b23dc4511fd8203560d631442d91a8 diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx index 7f8bdd77ab..df3134b9d5 100644 --- a/source/funkin/play/ResultState.hx +++ b/source/funkin/play/ResultState.hx @@ -12,6 +12,8 @@ import funkin.ui.MusicBeatSubState; import flixel.math.FlxRect; import flixel.text.FlxBitmapText; import funkin.ui.freeplay.FreeplayScore; +import flixel.text.FlxText; +import flixel.util.FlxColor; import flixel.tweens.FlxEase; import funkin.ui.freeplay.FreeplayState; import flixel.tweens.FlxTween; @@ -31,12 +33,27 @@ class ResultState extends MusicBeatSubState { final params:ResultsStateParams; - var resultsVariation:ResultVariations; - var songName:FlxBitmapText; - var difficulty:FlxSprite; + final rank:ResultRank; + final songName:FlxBitmapText; + final difficulty:FlxSprite; - var maskShaderSongName:LeftMaskShader = new LeftMaskShader(); - var maskShaderDifficulty:LeftMaskShader = new LeftMaskShader(); + final maskShaderSongName:LeftMaskShader = new LeftMaskShader(); + final maskShaderDifficulty:LeftMaskShader = new LeftMaskShader(); + + final resultsAnim:FunkinSprite; + final ratingsPopin:FunkinSprite; + final scorePopin:FunkinSprite; + + final bgFlash:FlxSprite; + + final highscoreNew:FlxSprite; + final score:ResultScore; + + var bfPerfect:Null = null; + var bfExcellent:Null = null; + var bfGood:Null = null; + var gfGood:Null = null; + var bfShit:Null = null; public function new(params:ResultsStateParams) { @@ -44,7 +61,11 @@ class ResultState extends MusicBeatSubState this.params = params; - resultsVariation = calculateVariation(params); + rank = calculateRank(params); + // rank = SHIT; + + // We build a lot of this stuff in the constructor, then place it in create(). + // This prevents having to do `null` checks everywhere. var fontLetters:String = "AaBbCcDdEeFfGgHhiIJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz:1234567890"; songName = new FlxBitmapText(FlxBitmapFont.fromMonospace(Paths.image("resultScreen/tardlingSpritesheet"), fontLetters, FlxPoint.get(49, 62))); @@ -55,18 +76,22 @@ class ResultState extends MusicBeatSubState difficulty = new FlxSprite(555); difficulty.zIndex = 1000; + + bgFlash = FlxGradient.createGradientFlxSprite(FlxG.width, FlxG.height, [0xFFFFEB69, 0xFFFFE66A], 90); + + resultsAnim = FunkinSprite.createSparrow(-200, -10, "resultScreen/results"); + + ratingsPopin = FunkinSprite.createSparrow(-150, 120, "resultScreen/ratingsPopin"); + + scorePopin = FunkinSprite.createSparrow(-180, 520, "resultScreen/scorePopin"); + + highscoreNew = new FlxSprite(310, 570); + + score = new ResultScore(35, 305, 10, params.scoreData.score); } override function create():Void { - FunkinSound.playMusic(resultsVariation.getMusicPath(), - { - startingVolume: 1.0, - overrideExisting: true, - restartTrack: true, - loop: resultsVariation.shouldMusicLoop() - }); - // Reset the camera zoom on the results screen. FlxG.camera.zoom = 1.0; @@ -75,10 +100,9 @@ class ResultState extends MusicBeatSubState bg.zIndex = 10; add(bg); - var bgFlash:FlxSprite = FlxGradient.createGradientFlxSprite(FlxG.width, FlxG.height, [0xFFFFEB69, 0xFFFFE66A], 90); bgFlash.scrollFactor.set(); bgFlash.visible = false; - bg.zIndex = 20; + bgFlash.zIndex = 20; add(bgFlash); // The sound system which falls into place behind the score text. Plays every time! @@ -92,13 +116,7 @@ class ResultState extends MusicBeatSubState soundSystem.zIndex = 1100; add(soundSystem); - var bfPerfect:Null = null; - var bfExcellent:Null = null; - var bfGood:Null = null; - var gfGood:Null = null; - var bfShit:Null = null; - - switch (resultsVariation) + switch (rank) { case PERFECT | PERFECT_GOLD | PERFECT_PLATINUM: bfPerfect = new FlxAtlasSprite(370, -180, Paths.animateAtlas("resultScreen/results-bf/resultsPERFECT", "shared")); @@ -107,8 +125,11 @@ class ResultState extends MusicBeatSubState add(bfPerfect); bfPerfect.anim.onComplete = () -> { - bfPerfect.anim.curFrame = 136; - bfPerfect.anim.play(); // unpauses this anim, since it's on PlayOnce! + if (bfPerfect != null) + { + bfPerfect.anim.curFrame = 137; + bfPerfect.anim.play(); // unpauses this anim, since it's on PlayOnce! + } }; case EXCELLENT: @@ -118,7 +139,10 @@ class ResultState extends MusicBeatSubState add(bfExcellent); bfExcellent.onAnimationFinish.add((animName) -> { - bfExcellent.playAnimation('Loop Start'); + if (bfExcellent != null) + { + bfExcellent.playAnimation('Loop Start'); + } }); case GOOD | GREAT: @@ -127,7 +151,10 @@ class ResultState extends MusicBeatSubState gfGood.visible = false; gfGood.zIndex = 500; gfGood.animation.finishCallback = _ -> { - gfGood.animation.play('clap', true, false, 9); + if (gfGood != null) + { + gfGood.animation.play('clap', true, false, 9); + } }; add(gfGood); @@ -136,7 +163,10 @@ class ResultState extends MusicBeatSubState bfGood.visible = false; bfGood.zIndex = 501; bfGood.animation.finishCallback = function(_) { - bfGood.animation.play('fall', true, false, 14); + if (bfGood != null) + { + bfGood.animation.play('fall', true, false, 14); + } }; add(bfGood); @@ -146,7 +176,10 @@ class ResultState extends MusicBeatSubState bfShit.zIndex = 500; add(bfShit); bfShit.onAnimationFinish.add((animName) -> { - bfShit.playAnimation('Loop Start'); + if (bfShit != null) + { + bfShit.playAnimation('Loop Start'); + } }); } @@ -189,25 +222,21 @@ class ResultState extends MusicBeatSubState blackTopBar.zIndex = 1010; add(blackTopBar); - var resultsAnim:FunkinSprite = FunkinSprite.createSparrow(-200, -10, "resultScreen/results"); resultsAnim.animation.addByPrefix("result", "results instance 1", 24, false); resultsAnim.animation.play("result"); resultsAnim.zIndex = 1200; add(resultsAnim); - var ratingsPopin:FunkinSprite = FunkinSprite.createSparrow(-150, 120, "resultScreen/ratingsPopin"); ratingsPopin.animation.addByPrefix("idle", "Categories", 24, false); ratingsPopin.visible = false; ratingsPopin.zIndex = 1200; add(ratingsPopin); - var scorePopin:FunkinSprite = FunkinSprite.createSparrow(-180, 520, "resultScreen/scorePopin"); scorePopin.animation.addByPrefix("score", "tally score", 24, false); scorePopin.visible = false; scorePopin.zIndex = 1200; add(scorePopin); - var highscoreNew:FlxSprite = new FlxSprite(310, 570); highscoreNew.frames = Paths.getSparrowAtlas("resultScreen/highscoreNew"); highscoreNew.animation.addByPrefix("new", "NEW HIGHSCORE", 24); highscoreNew.visible = false; @@ -249,7 +278,6 @@ class ResultState extends MusicBeatSubState var tallyMissed:TallyCounter = new TallyCounter(260, (hStuf * 9) + extraYOffset, params.scoreData.tallies.missed, 0xFFC68AE6); ratingGrp.add(tallyMissed); - var score:ResultScore = new ResultScore(35, 305, 10, params.scoreData.score); score.visible = false; score.zIndex = 1200; add(score); @@ -263,7 +291,68 @@ class ResultState extends MusicBeatSubState }); } - new FlxTimer().start(0.5, _ -> { + startRankTallySequence(); + + refresh(); + + super.create(); + } + + var rankTallyTimer:Null = null; + var clearPercentTarget:Int = 100; + var clearPercentLerp:Int = 0; + + function startRankTallySequence():Void + { + clearPercentTarget = Math.floor((params.scoreData.tallies.totalNotesHit) / params.scoreData.tallies.totalNotes * 100); + // clearPercentTarget = 97; + + var clearPercentText = new FlxText(FlxG.width / 2, FlxG.height / 2, 0, 'CLEAR: ${clearPercentLerp}%'); + clearPercentText.setFormat(Paths.font('vcr.ttf'), 64, FlxColor.BLACK, FlxTextAlign.RIGHT); + clearPercentText.zIndex = 1000; + add(clearPercentText); + + rankTallyTimer = new FlxTimer().start(1 / 24, _ -> { + // Tick up. + if (clearPercentLerp < clearPercentTarget) + { + clearPercentLerp++; + + clearPercentText.text = 'CLEAR: ${clearPercentLerp}%'; + FunkinSound.playOnce(Paths.sound('scrollMenu')); + } + + // Don't overshoot. + if (clearPercentLerp > clearPercentTarget) + { + clearPercentLerp = clearPercentTarget; + } + + if (clearPercentLerp == clearPercentTarget) + { + if (rankTallyTimer != null) + { + rankTallyTimer.destroy(); + rankTallyTimer = null; + } + + // Play confirm sound. + FunkinSound.playOnce(Paths.sound('confirmMenu')); + + new FlxTimer().start(1.0, _ -> { + remove(clearPercentText); + + afterRankTallySequence(); + }); + } + }, 0); // 0 = Loop until stopped + + if (ratingsPopin == null) + { + trace("Could not build ratingsPopin!"); + } + else + { ratingsPopin.animation.play("idle"); ratingsPopin.visible = true; @@ -286,76 +375,139 @@ class ResultState extends MusicBeatSubState highscoreNew.visible = false; } }; + } - switch (resultsVariation) + refresh(); + } + + function afterRankTallySequence():Void + { + FunkinSound.playMusic(rank.getMusicPath(), { - case PERFECT | PERFECT_GOLD | PERFECT_PLATINUM: - if (bfPerfect == null) - { - trace("Could not build PERFECT animation!"); - } - else - { - bfPerfect.visible = true; - bfPerfect.playAnimation(''); - } + startingVolume: 1.0, + overrideExisting: true, + restartTrack: true, + loop: rank.shouldMusicLoop() + }); - case EXCELLENT: - if (bfExcellent == null) - { - trace("Could not build EXCELLENT animation!"); - } - else + FlxG.sound.music.onComplete = () -> { + if (rank == SHIT) + { + FunkinSound.playMusic('bluu', { - bfExcellent.visible = true; - bfExcellent.playAnimation('Intro'); - } + startingVolume: 0.0, + overrideExisting: true, + restartTrack: true, + loop: true + }); + FlxG.sound.music.fadeIn(10.0, 0.0, 1.0); + } + } - case SHIT: - if (bfShit == null) - { - trace("Could not build SHIT animation!"); - } - else - { - bfShit.visible = true; - bfShit.playAnimation('Intro'); - } + switch (rank) + { + case PERFECT | PERFECT_GOLD | PERFECT_PLATINUM: + if (bfPerfect == null) + { + trace("Could not build PERFECT animation!"); + } + else + { + bfPerfect.visible = true; + bfPerfect.playAnimation(''); + + new FlxTimer().start((1 / 24) * 12, _ -> { + bgFlash.visible = true; + FlxTween.tween(bgFlash, {alpha: 0}, 0.4); + new FlxTimer().start((1 / 24) * 2, _ -> + { + // bgFlash.alpha = 0.5; + + // bgFlash.visible = false; + }); + }); + } - case GREAT | GOOD: - if (bfGood == null || gfGood == null) - { - trace("Could not build GOOD animation!"); - } - else - { - bfGood.animation.play('fall'); - bfGood.visible = true; - - new FlxTimer().start((1 / 24) * 12, _ -> { - bgFlash.visible = true; - FlxTween.tween(bgFlash, {alpha: 0}, 0.4); - new FlxTimer().start((1 / 24) * 2, _ -> - { - // bgFlash.alpha = 0.5; - - // bgFlash.visible = false; - }); - }); - - new FlxTimer().start((1 / 24) * 22, _ -> { - // plays about 22 frames (at 24fps timing) after bf spawns in - gfGood.animation.play('clap', true); - gfGood.visible = true; - }); - } - default: - } - }); + case EXCELLENT: + if (bfExcellent == null) + { + trace("Could not build EXCELLENT animation!"); + } + else + { + bfExcellent.visible = true; + bfExcellent.playAnimation('Intro'); + + new FlxTimer().start((1 / 24) * 12, _ -> { + bgFlash.visible = true; + FlxTween.tween(bgFlash, {alpha: 0}, 0.4); + new FlxTimer().start((1 / 24) * 2, _ -> + { + // bgFlash.alpha = 0.5; + + // bgFlash.visible = false; + }); + }); + } - refresh(); + case SHIT: + if (bfShit == null) + { + trace("Could not build SHIT animation!"); + } + else + { + bfShit.visible = true; + bfShit.playAnimation('Intro'); + + new FlxTimer().start((1 / 24) * 12, _ -> { + bgFlash.visible = true; + FlxTween.tween(bgFlash, {alpha: 0}, 0.4); + new FlxTimer().start((1 / 24) * 2, _ -> + { + // bgFlash.alpha = 0.5; + + // bgFlash.visible = false; + }); + }); + } - super.create(); + case GREAT | GOOD: + if (bfGood == null) + { + trace("Could not build GOOD animation!"); + } + else + { + bfGood.animation.play('fall'); + bfGood.visible = true; + + new FlxTimer().start((1 / 24) * 12, _ -> { + bgFlash.visible = true; + FlxTween.tween(bgFlash, {alpha: 0}, 0.4); + new FlxTimer().start((1 / 24) * 2, _ -> + { + // bgFlash.alpha = 0.5; + + // bgFlash.visible = false; + }); + }); + + new FlxTimer().start((1 / 24) * 22, _ -> { + // plays about 22 frames (at 24fps timing) after bf spawns in + if (gfGood != null) + { + gfGood.animation.play('clap', true); + gfGood.visible = true; + } + else + { + trace("Could not build GOOD animation!"); + } + }); + } + default: + } } function timerThenSongName():Void @@ -391,11 +543,8 @@ class ResultState extends MusicBeatSubState { super.draw(); - if (songName != null) - { - songName.clipRect = FlxRect.get(Math.max(0, 540 - songName.x), 0, FlxG.width, songName.height); - // PROBABLY SHOULD FIX MEMORY FREE OR WHATEVER THE PUT() FUNCTION DOES !!!! FEELS LIKE IT STUTTERS!!! - } + songName.clipRect = FlxRect.get(Math.max(0, 540 - songName.x), 0, FlxG.width, songName.height); + // PROBABLY SHOULD FIX MEMORY FREE OR WHATEVER THE PUT() FUNCTION DOES !!!! FEELS LIKE IT STUTTERS!!! // if (songName != null && songName.frame != null) // maskShaderSongName.frameUV = songName.frame.uv; @@ -448,17 +597,17 @@ class ResultState extends MusicBeatSubState super.update(elapsed); } - public static function calculateVariation(params:ResultsStateParams):ResultVariations + public static function calculateRank(params:ResultsStateParams):ResultRank { // Perfect (Platinum) is a Sick Full Clear var isPerfectPlat = (params.scoreData.tallies.sick + params.scoreData.tallies.good) == params.scoreData.tallies.totalNotes && params.scoreData.tallies.sick / params.scoreData.tallies.totalNotes >= Constants.RANK_PERFECT_PLAT_THRESHOLD; - if (isPerfectPlat) return ResultVariations.PERFECT_PLATINUM; + if (isPerfectPlat) return ResultRank.PERFECT_PLATINUM; // Perfect (Gold) is an 85% Sick Full Clear var isPerfectGold = (params.scoreData.tallies.sick + params.scoreData.tallies.good) == params.scoreData.tallies.totalNotes && params.scoreData.tallies.sick / params.scoreData.tallies.totalNotes >= Constants.RANK_PERFECT_GOLD_THRESHOLD; - if (isPerfectGold) return ResultVariations.PERFECT_GOLD; + if (isPerfectGold) return ResultRank.PERFECT_GOLD; // Else, use the standard grades @@ -467,28 +616,28 @@ class ResultState extends MusicBeatSubState if (clear == Constants.RANK_PERFECT_THRESHOLD) { - return ResultVariations.PERFECT; + return ResultRank.PERFECT; } else if (clear >= Constants.RANK_EXCELLENT_THRESHOLD) { - return ResultVariations.EXCELLENT; + return ResultRank.EXCELLENT; } else if (clear >= Constants.RANK_GREAT_THRESHOLD) { - return ResultVariations.GREAT; + return ResultRank.GREAT; } else if (clear >= Constants.RANK_GOOD_THRESHOLD) { - return ResultVariations.GOOD; + return ResultRank.GOOD; } else { - return ResultVariations.SHIT; + return ResultRank.SHIT; } } } -enum abstract ResultVariations(String) +enum abstract ResultRank(String) { var PERFECT_PLATINUM; var PERFECT_GOLD; From 6c2d18c72c7350ccefc4d9b15577c6092d663bed Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Sat, 11 May 2024 01:05:51 -0400 Subject: [PATCH 014/266] Resurrected difficulty stars, fixed flame animation, fixed Random showing an album. --- assets | 2 +- source/funkin/play/song/Song.hx | 21 ++++ source/funkin/ui/freeplay/AlbumRoll.hx | 44 ++++---- source/funkin/ui/freeplay/DifficultyStars.hx | 106 +++++++++++++++++++ source/funkin/ui/freeplay/FreeplayFlames.hx | 21 +++- source/funkin/ui/freeplay/FreeplayState.hx | 23 ++-- source/funkin/ui/freeplay/SongMenuItem.hx | 2 +- 7 files changed, 183 insertions(+), 36 deletions(-) create mode 100644 source/funkin/ui/freeplay/DifficultyStars.hx diff --git a/assets b/assets index 927578f482..fd112e293e 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 927578f482b23dc4511fd8203560d631442d91a8 +Subproject commit fd112e293ee0f823ee98d5b8bd8a85e934f772f6 diff --git a/source/funkin/play/song/Song.hx b/source/funkin/play/song/Song.hx index e71ae3213e..23d8d21986 100644 --- a/source/funkin/play/song/Song.hx +++ b/source/funkin/play/song/Song.hx @@ -399,6 +399,27 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry + { + if (charId == null) charId = Constants.DEFAULT_CHARACTER; + + if (variations.contains(charId)) + { + return [charId]; + } + else + { + // TODO: How to exclude character variations while keeping other custom variations? + return variations; + } + } + /** * List all the difficulties in this song. * diff --git a/source/funkin/ui/freeplay/AlbumRoll.hx b/source/funkin/ui/freeplay/AlbumRoll.hx index 35facf131f..50f4a432c8 100644 --- a/source/funkin/ui/freeplay/AlbumRoll.hx +++ b/source/funkin/ui/freeplay/AlbumRoll.hx @@ -38,7 +38,7 @@ class AlbumRoll extends FlxSpriteGroup var newAlbumArt:FlxAtlasSprite; - // var difficultyStars:DifficultyStars; + var difficultyStars:DifficultyStars; var _exitMovers:Null; var albumData:Album; @@ -65,9 +65,9 @@ class AlbumRoll extends FlxSpriteGroup add(newAlbumArt); - // difficultyStars = new DifficultyStars(140, 39); - // difficultyStars.stars.visible = false; - // add(difficultyStars); + difficultyStars = new DifficultyStars(140, 39); + difficultyStars.stars.visible = false; + add(difficultyStars); } function onAlbumFinish(animName:String):Void @@ -86,9 +86,14 @@ class AlbumRoll extends FlxSpriteGroup { if (albumId == null) { - // difficultyStars.stars.visible = false; + this.visible = false; + difficultyStars.stars.visible = false; return; } + else + { + this.visible = true; + } albumData = AlbumRegistry.instance.fetchEntry(albumId); @@ -144,10 +149,10 @@ class AlbumRoll extends FlxSpriteGroup newAlbumArt.visible = true; newAlbumArt.playAnimation(animNames.get('$albumId-active'), false, false, false); - // difficultyStars.stars.visible = false; + difficultyStars.stars.visible = false; new FlxTimer().start(0.75, function(_) { // showTitle(); - // showStars(); + showStars(); }); } @@ -156,16 +161,17 @@ class AlbumRoll extends FlxSpriteGroup newAlbumArt.playAnimation(animNames.get('$albumId-trans'), false, false, false); } - // public function setDifficultyStars(?difficulty:Int):Void - // { - // if (difficulty == null) return; - // difficultyStars.difficulty = difficulty; - // } - // /** - // * Make the album stars visible. - // */ - // public function showStars():Void - // { - // difficultyStars.stars.visible = false; // true; - // } + public function setDifficultyStars(?difficulty:Int):Void + { + if (difficulty == null) return; + difficultyStars.difficulty = difficulty; + } + + /** + * Make the album stars visible. + */ + public function showStars():Void + { + difficultyStars.stars.visible = true; // true; + } } diff --git a/source/funkin/ui/freeplay/DifficultyStars.hx b/source/funkin/ui/freeplay/DifficultyStars.hx new file mode 100644 index 0000000000..51526bcbec --- /dev/null +++ b/source/funkin/ui/freeplay/DifficultyStars.hx @@ -0,0 +1,106 @@ +package funkin.ui.freeplay; + +import flixel.group.FlxSpriteGroup; +import funkin.graphics.adobeanimate.FlxAtlasSprite; +import funkin.graphics.shaders.HSVShader; + +class DifficultyStars extends FlxSpriteGroup +{ + /** + * Internal handler var for difficulty... ranges from 0... to 15 + * 0 is 1 star... 15 is 0 stars! + */ + var curDifficulty(default, set):Int = 0; + + /** + * Range between 0 and 15 + */ + public var difficulty(default, set):Int = 1; + + public var stars:FlxAtlasSprite; + + var flames:FreeplayFlames; + + var hsvShader:HSVShader; + + public function new(x:Float, y:Float) + { + super(x, y); + + hsvShader = new HSVShader(); + + flames = new FreeplayFlames(0, 0); + add(flames); + + stars = new FlxAtlasSprite(0, 0, Paths.animateAtlas("freeplay/freeplayStars")); + stars.anim.play("diff stars"); + add(stars); + + stars.shader = hsvShader; + + for (memb in flames.members) + memb.shader = hsvShader; + } + + override function update(elapsed:Float):Void + { + super.update(elapsed); + + // "loops" the current animation + // for clarity, the animation file looks like + // frame : stars + // 0-99: 1 star + // 100-199: 2 stars + // ...... + // 1300-1499: 15 stars + // 1500 : 0 stars + if (curDifficulty < 15 && stars.anim.curFrame >= (curDifficulty + 1) * 100) + { + stars.anim.play("diff stars", true, false, curDifficulty * 100); + } + } + + function set_difficulty(value:Int):Int + { + difficulty = value; + + if (difficulty <= 0) + { + difficulty = 0; + curDifficulty = 15; + } + else if (difficulty <= 15) + { + difficulty = value; + curDifficulty = difficulty - 1; + } + else + { + difficulty = 15; + curDifficulty = difficulty - 1; + } + + if (difficulty > 10) flames.flameCount = difficulty - 10; + else + flames.flameCount = 0; + + return difficulty; + } + + function set_curDifficulty(value:Int):Int + { + curDifficulty = value; + if (curDifficulty == 15) + { + stars.anim.play("diff stars", true, false, 1500); + stars.anim.pause(); + } + else + { + stars.anim.curFrame = Std.int(curDifficulty * 100); + stars.anim.play("diff stars", true, false, curDifficulty * 100); + } + + return curDifficulty; + } +} diff --git a/source/funkin/ui/freeplay/FreeplayFlames.hx b/source/funkin/ui/freeplay/FreeplayFlames.hx index c20d858989..f6b6f5c3d4 100644 --- a/source/funkin/ui/freeplay/FreeplayFlames.hx +++ b/source/funkin/ui/freeplay/FreeplayFlames.hx @@ -50,8 +50,19 @@ class FreeplayFlames extends FlxSpriteGroup } } + var timers:Array = []; + function set_flameCount(value:Int):Int { + // Stop all existing timers. + // This fixes a bug where quickly switching difficulties would show flames. + for (timer in timers) + { + timer.active = false; + timer.destroy(); + timers.remove(timer); + } + this.flameCount = value; var visibleCount:Int = 0; for (i in 0...5) @@ -62,10 +73,18 @@ class FreeplayFlames extends FlxSpriteGroup { if (!flame.visible) { - new FlxTimer().start(flameTimer * visibleCount, function(_) { + var nextTimer:FlxTimer = new FlxTimer().start(flameTimer * visibleCount, function(currentTimer:FlxTimer) { + if (i >= this.flameCount) + { + trace('EARLY EXIT'); + return; + } + timers.remove(currentTimer); flame.animation.play("flame", true); flame.visible = true; }); + timers.push(nextTimer); + visibleCount++; } } diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 7b7543845a..2390682889 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -120,8 +120,6 @@ class FreeplayState extends MusicBeatSubState var curCapsule:SongMenuItem; var curPlaying:Bool = false; - var displayedVariations:Array; - var dj:DJBoyfriend; var ostName:FlxText; @@ -184,10 +182,6 @@ class FreeplayState extends MusicBeatSubState // Add a null entry that represents the RANDOM option songs.push(null); - // TODO: This makes custom variations disappear from Freeplay. Figure out a better solution later. - // Default character (BF) shows default and Erect variations. Pico shows only Pico variations. - displayedVariations = (currentCharacter == 'bf') ? [Constants.DEFAULT_VARIATION, 'erect'] : [currentCharacter]; - // programmatically adds the songs via LevelRegistry and SongRegistry for (levelId in LevelRegistry.instance.listSortedLevelIds()) { @@ -195,7 +189,8 @@ class FreeplayState extends MusicBeatSubState { var song:Song = SongRegistry.instance.fetchEntry(songId); - // Only display songs which actually have available charts for the current character. + // Only display songs which actually have available difficulties for the current character. + var displayedVariations = song.getVariationsByCharId(currentCharacter); var availableDifficultiesForSong:Array = song.listDifficulties(displayedVariations, false); if (availableDifficultiesForSong.length == 0) continue; @@ -488,10 +483,6 @@ class FreeplayState extends MusicBeatSubState albumRoll.playIntro(); - new FlxTimer().start(0.75, function(_) { - // albumRoll.showTitle(); - }); - FlxTween.tween(grpDifficulties, {x: 90}, 0.6, {ease: FlxEase.quartOut}); diffSelLeft.visible = true; @@ -1072,6 +1063,9 @@ class FreeplayState extends MusicBeatSubState albumRoll.albumId = newAlbumId; albumRoll.skipIntro(); } + + // Set difficulty star count. + albumRoll.setDifficultyStars(daSong?.difficultyRating); } // Clears the cache of songs, frees up memory, they' ll have to be loaded in later tho function clearDaCache(actualSongTho:String) @@ -1383,11 +1377,12 @@ class FreeplaySongData public var songName(default, null):String = ''; public var songCharacter(default, null):String = ''; - public var songRating(default, null):Int = 0; + public var difficultyRating(default, null):Int = 0; public var albumId(default, null):Null = null; public var currentDifficulty(default, set):String = Constants.DEFAULT_DIFFICULTY; - public var displayedVariations(default, null):Array = [Constants.DEFAULT_VARIATION]; + + var displayedVariations:Array = [Constants.DEFAULT_VARIATION]; function set_currentDifficulty(value:String):String { @@ -1417,7 +1412,7 @@ class FreeplaySongData if (songDifficulty == null) return; this.songName = songDifficulty.songName; this.songCharacter = songDifficulty.characters.opponent; - this.songRating = songDifficulty.difficultyRating; + this.difficultyRating = songDifficulty.difficultyRating; if (songDifficulty.album == null) { FlxG.log.warn('No album for: ${songDifficulty.songName}'); diff --git a/source/funkin/ui/freeplay/SongMenuItem.hx b/source/funkin/ui/freeplay/SongMenuItem.hx index f6d85e56e2..cf9b524827 100644 --- a/source/funkin/ui/freeplay/SongMenuItem.hx +++ b/source/funkin/ui/freeplay/SongMenuItem.hx @@ -168,7 +168,7 @@ class SongMenuItem extends FlxSpriteGroup songText.text = songData?.songName ?? 'Random'; // Update capsule character. if (songData?.songCharacter != null) setCharacter(songData.songCharacter); - updateDifficultyRating(songData?.songRating ?? 0); + updateDifficultyRating(songData?.difficultyRating ?? 0); // Update opacity, offsets, etc. updateSelected(); } From fa4fa8116c7e07487e8b9f6fc4e71be2e0007703 Mon Sep 17 00:00:00 2001 From: nebulazorua Date: Sat, 11 May 2024 16:51:27 +0800 Subject: [PATCH 015/266] abstract enum pagename should make adding modded optionspages better and easier makes it so you dont have to leech off an unused PageName or write your own code for making modded options, helping with compatibility between mods. --- source/funkin/ui/options/OptionsState.hx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/funkin/ui/options/OptionsState.hx b/source/funkin/ui/options/OptionsState.hx index 81331b266f..57ba3f3d45 100644 --- a/source/funkin/ui/options/OptionsState.hx +++ b/source/funkin/ui/options/OptionsState.hx @@ -266,11 +266,11 @@ class OptionsMenu extends Page #end } -enum PageName +enum abstract PageName(String) { - Options; - Controls; - Colors; - Mods; - Preferences; + var Options = "options"; + var Controls = "controls"; + var Colors = "colors"; + var Mods = "mods"; + var Preferences = "preferences"; } From c0485fd1a23f0f683b79935245bc89af18d15e4a Mon Sep 17 00:00:00 2001 From: gamerbross Date: Sat, 11 May 2024 20:11:51 +0200 Subject: [PATCH 016/266] Fix Freeplay Crash when song is invalid --- source/funkin/ui/freeplay/FreeplayState.hx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 7b7543845a..a359010d34 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -29,6 +29,7 @@ import funkin.graphics.shaders.StrokeShader; import funkin.input.Controls; import funkin.play.PlayStatePlaylist; import funkin.play.song.Song; +import funkin.ui.story.Level; import funkin.save.Save; import funkin.save.Save.SaveScoreData; import funkin.ui.AtlasText; @@ -191,10 +192,24 @@ class FreeplayState extends MusicBeatSubState // programmatically adds the songs via LevelRegistry and SongRegistry for (levelId in LevelRegistry.instance.listSortedLevelIds()) { - for (songId in LevelRegistry.instance.parseEntryData(levelId).songs) + var level:Level = LevelRegistry.instance.fetchEntry(levelId); + + if (level == null) + { + trace('[WARN] Could not find level with id (${levelId})'); + continue; + } + + for (songId in level.getSongs()) { var song:Song = SongRegistry.instance.fetchEntry(songId); + if (song == null) + { + trace('[WARN] Could not find song with id (${songId})'); + continue; + } + // Only display songs which actually have available charts for the current character. var availableDifficultiesForSong:Array = song.listDifficulties(displayedVariations, false); if (availableDifficultiesForSong.length == 0) continue; From ccd1a23a4c6fe3dcbcf1d2e075be3028709befb3 Mon Sep 17 00:00:00 2001 From: MadBear422 Date: Sat, 11 May 2024 15:45:27 -0700 Subject: [PATCH 017/266] Un-hardcoded Pixel Icon Data Pixel icon data is now accessed through character metadata and is no longer hard-coded to assign specific icons to specific characters --- source/funkin/play/character/CharacterData.hx | 142 ++++++++++++++---- source/funkin/ui/freeplay/SongMenuItem.hx | 36 ++--- 2 files changed, 123 insertions(+), 55 deletions(-) diff --git a/source/funkin/play/character/CharacterData.hx b/source/funkin/play/character/CharacterData.hx index 7d3d6cfb92..340607e712 100644 --- a/source/funkin/play/character/CharacterData.hx +++ b/source/funkin/play/character/CharacterData.hx @@ -281,39 +281,64 @@ class CharacterDataParser } /** - * TODO: Hardcode this. + * Fetches the character's pixel icon data. + * @param charId The character to load. + * @return The pixel icon data, or null if validation failed. */ - public static function getCharPixelIconAsset(char:String):String + public static function getCharPixelIconData(charId:String):Null { - var icon:String = char; - - switch (icon) - { - case "bf-christmas" | "bf-car" | "bf-pixel" | "bf-holding-gf": - icon = "bf"; - case "monster-christmas": - icon = "monster"; - case "mom" | "mom-car": - icon = "mommy"; - case "pico-blazin" | "pico-playable" | "pico-speaker": - icon = "pico"; - case "gf-christmas" | "gf-car" | "gf-pixel" | "gf-tankmen": - icon = "gf"; - case "dad": - icon = "daddy"; - case "darnell-blazin": - icon = "darnell"; - case "senpai-angry": - icon = "senpai"; - case "tankman" | "tankman-atlas": - icon = "tankmen"; - } - - var path = Paths.image("freeplay/icons/" + icon + "pixel"); - if (Assets.exists(path)) return path; - - // TODO: Hardcode some additional behavior or a fallback. - return null; + if (charId == null || charId == '' || !characterCache.exists(charId)) + { + trace('Failed to fetch pixel icon, character not found in cache: ${charId}'); + return null; + } + + var charData:CharacterData = characterCache.get(charId); + + if (charData != null && charData.pixelIcon != null) + { + return charData.pixelIcon; + } + else + { + trace('Pixel icon data not found for character: ${charId}'); + return null; + } + } + + /** + * Fetches the character's pixel icon path. + * @param charId The character to load. + * @return The pixel icon path, or null if validation failed. + */ + public static function getCharPixelIconAsset(charId:String):String + { + if (charId == null || charId == '' || !characterCache.exists(charId)) + { + trace('Failed to fetch pixel icon, character not found in cache: ${charId}'); + return null; + } + + var charData:CharacterData = characterCache.get(charId); + var path = Paths.image("freeplay/icons/" + charData.pixelIcon.id + "pixel"); + + if (charData != null && charData.pixelIcon != null) + { + if (Assets.exists(path)) + { + return path; + } + else + { + trace('Pixel icon file does not exist: ${path}'); + return null; + } + } + else + { + trace('Pixel icon data not found for character: ${charId}'); + return null; + } } /** @@ -394,6 +419,7 @@ class CharacterDataParser static final DEFAULT_NAME:String = 'Untitled Character'; static final DEFAULT_OFFSETS:Array = [0, 0]; static final DEFAULT_HEALTHICON_OFFSETS:Array = [0, 25]; + static final DEFAULT_PIXELICON_ORIGIN:Array = [100, 0]; static final DEFAULT_RENDERTYPE:CharacterRenderType = CharacterRenderType.Sparrow; static final DEFAULT_SCALE:Float = 1; static final DEFAULT_SCROLL:Array = [0, 0]; @@ -485,6 +511,31 @@ class CharacterDataParser input.healthIcon.offsets = DEFAULT_OFFSETS; } + if (input.pixelIcon == null) + { + input.pixelIcon = + { + id: null, + flipX: null, + origin: null + }; + } + + if (input.pixelIcon.id == null) + { + input.pixelIcon.id = id; + } + + if (input.pixelIcon.flipX == null) + { + input.pixelIcon.flipX = DEFAULT_FLIPX; + } + + if (input.pixelIcon.origin == null) + { + input.pixelIcon.origin = DEFAULT_PIXELICON_ORIGIN; + } + if (input.startingAnimation == null) { input.startingAnimation = DEFAULT_STARTINGANIM; @@ -641,6 +692,11 @@ typedef CharacterData = */ var healthIcon:Null; + /** + * Optional data about the pixel icon for the character. + */ + var pixelIcon:Null; + var death:Null; /** @@ -736,6 +792,30 @@ typedef HealthIconData = var offsets:Null>; } +/** + * The JSON data schema used to define the pixel icon for a character. + */ +typedef PixelIconData = +{ + /** + * The ID to use for the pixel icon. + * @default The character's ID + */ + var id:Null; + + /** + * Whether to flip the pixel icon horizontally. + * @default false + */ + var flipX:Null; + + /** + * The origin of the pixel icon, in pixels. + * @default [100, 0] + */ + var origin:Null>; +} + typedef DeathData = { /** diff --git a/source/funkin/ui/freeplay/SongMenuItem.hx b/source/funkin/ui/freeplay/SongMenuItem.hx index f6d85e56e2..4cdc5b90f6 100644 --- a/source/funkin/ui/freeplay/SongMenuItem.hx +++ b/source/funkin/ui/freeplay/SongMenuItem.hx @@ -5,6 +5,8 @@ import funkin.graphics.shaders.HSVShader; import funkin.graphics.shaders.GaussianBlurShader; import flixel.group.FlxGroup; import flixel.FlxSprite; +import funkin.play.character.CharacterData; +import funkin.play.character.CharacterData.CharacterDataParser; import flixel.graphics.frames.FlxAtlasFrames; import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; import flixel.group.FlxSpriteGroup; @@ -182,24 +184,15 @@ class SongMenuItem extends FlxSpriteGroup { var charPath:String = "freeplay/icons/"; - // TODO: Put this in the character metadata where it belongs. - // TODO: Also, can use CharacterDataParser.getCharPixelIconAsset() - switch (char) + var charPixelIconData = CharacterDataParser.getCharPixelIconData(char); + if (charPixelIconData == null) { - case 'monster-christmas': - charPath += 'monsterpixel'; - case 'mom-car': - charPath += 'mommypixel'; - case 'dad': - charPath += 'daddypixel'; - case 'darnell-blazin': - charPath += 'darnellpixel'; - case 'senpai-angry': - charPath += 'senpaipixel'; - default: - charPath += '${char}pixel'; + trace('[WARN] Character ${char} has no pixel icon data.'); + return; } + charPath += '${charPixelIconData.id}pixel'; + if (!openfl.utils.Assets.exists(Paths.image(charPath))) { trace('[WARN] Character ${char} has no freeplay icon.'); @@ -209,15 +202,10 @@ class SongMenuItem extends FlxSpriteGroup pixelIcon.loadGraphic(Paths.image(charPath)); pixelIcon.scale.x = pixelIcon.scale.y = 2; - switch (char) - { - case 'parents-christmas': - pixelIcon.origin.x = 140; - default: - pixelIcon.origin.x = 100; - } - // pixelIcon.origin.x = capsule.origin.x; - // pixelIcon.offset.x -= pixelIcon.origin.x; + // Set the pixel icon x origin for position adjustments + pixelIcon.origin.x = charPixelIconData.origin[0]; + // Set whether or not to flip the pixel icon + pixelIcon.flipX = charPixelIconData.flipX; } var frameInTicker:Float = 0; From 07a647453941e4d4c9636d3929e24302f55b741c Mon Sep 17 00:00:00 2001 From: MadBear422 Date: Sat, 11 May 2024 15:45:56 -0700 Subject: [PATCH 018/266] Pixel Icon Metadata --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 962130b224..3ca9798429 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 962130b2243a839106607d08a11599b1857bf8b3 +Subproject commit 3ca9798429fd4413b88dc600a3453f741a6010ca From 9c867b1dac8464fdd565ff39df1d8fec4385b0a0 Mon Sep 17 00:00:00 2001 From: MadBear422 Date: Sat, 11 May 2024 16:00:37 -0700 Subject: [PATCH 019/266] Typo Corrections --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 3ca9798429..3782539773 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 3ca9798429fd4413b88dc600a3453f741a6010ca +Subproject commit 37825397730f03e89277791af54e8482bde43e70 From 6d5c688027327ed8922840a50524479258476d70 Mon Sep 17 00:00:00 2001 From: MadBear422 Date: Sat, 11 May 2024 16:42:50 -0700 Subject: [PATCH 020/266] Make icon origin add with offsets instead of being explicitly set --- assets | 2 +- source/funkin/play/character/CharacterData.hx | 14 +++++++------- source/funkin/ui/freeplay/SongMenuItem.hx | 8 ++++++-- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/assets b/assets index 3782539773..9c98b21f6b 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 37825397730f03e89277791af54e8482bde43e70 +Subproject commit 9c98b21f6b05c640522ca537bb173eef12523e34 diff --git a/source/funkin/play/character/CharacterData.hx b/source/funkin/play/character/CharacterData.hx index 340607e712..1b8d0ce897 100644 --- a/source/funkin/play/character/CharacterData.hx +++ b/source/funkin/play/character/CharacterData.hx @@ -419,7 +419,7 @@ class CharacterDataParser static final DEFAULT_NAME:String = 'Untitled Character'; static final DEFAULT_OFFSETS:Array = [0, 0]; static final DEFAULT_HEALTHICON_OFFSETS:Array = [0, 25]; - static final DEFAULT_PIXELICON_ORIGIN:Array = [100, 0]; + static final DEFAULT_PIXELICON_ORIGIN_OFFSETS:Array = [0, 0]; static final DEFAULT_RENDERTYPE:CharacterRenderType = CharacterRenderType.Sparrow; static final DEFAULT_SCALE:Float = 1; static final DEFAULT_SCROLL:Array = [0, 0]; @@ -517,7 +517,7 @@ class CharacterDataParser { id: null, flipX: null, - origin: null + originOffsets: null }; } @@ -531,9 +531,9 @@ class CharacterDataParser input.pixelIcon.flipX = DEFAULT_FLIPX; } - if (input.pixelIcon.origin == null) + if (input.pixelIcon.originOffsets == null) { - input.pixelIcon.origin = DEFAULT_PIXELICON_ORIGIN; + input.pixelIcon.originOffsets = DEFAULT_PIXELICON_ORIGIN_OFFSETS; } if (input.startingAnimation == null) @@ -810,10 +810,10 @@ typedef PixelIconData = var flipX:Null; /** - * The origin of the pixel icon, in pixels. - * @default [100, 0] + * The origin offsets of the pixel icon, in pixels. + * @default [0, 0] */ - var origin:Null>; + var originOffsets:Null>; } typedef DeathData = diff --git a/source/funkin/ui/freeplay/SongMenuItem.hx b/source/funkin/ui/freeplay/SongMenuItem.hx index 4cdc5b90f6..65032228bb 100644 --- a/source/funkin/ui/freeplay/SongMenuItem.hx +++ b/source/funkin/ui/freeplay/SongMenuItem.hx @@ -202,8 +202,12 @@ class SongMenuItem extends FlxSpriteGroup pixelIcon.loadGraphic(Paths.image(charPath)); pixelIcon.scale.x = pixelIcon.scale.y = 2; - // Set the pixel icon x origin for position adjustments - pixelIcon.origin.x = charPixelIconData.origin[0]; + // Set to 100 for default position + pixelIcon.origin.x = 100; + + // Add the pixel icon origin with offsets for position adjustments + pixelIcon.origin.x += charPixelIconData.originOffsets[0]; + pixelIcon.origin.y += charPixelIconData.originOffsets[1]; // Set whether or not to flip the pixel icon pixelIcon.flipX = charPixelIconData.flipX; } From aa4a5b5f344ca19c09789b9adb6b65fe9f61ae0d Mon Sep 17 00:00:00 2001 From: MadBear422 Date: Sat, 11 May 2024 16:52:22 -0700 Subject: [PATCH 021/266] GF Car Typo Correction --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 9c98b21f6b..b69ba22ca5 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 9c98b21f6b05c640522ca537bb173eef12523e34 +Subproject commit b69ba22ca5069aed0e8545e1c2e79cadc39cac56 From b22dd4d7d44bdd9fda401ac50727e1cf6aae2c28 Mon Sep 17 00:00:00 2001 From: MaybeMaru <97055307+MaybeMaru@users.noreply.github.com> Date: Mon, 13 May 2024 02:18:57 +0200 Subject: [PATCH 022/266] Update Strumline.hx --- source/funkin/play/notes/Strumline.hx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/funkin/play/notes/Strumline.hx b/source/funkin/play/notes/Strumline.hx index 95e0668be2..b520f7b703 100644 --- a/source/funkin/play/notes/Strumline.hx +++ b/source/funkin/play/notes/Strumline.hx @@ -406,7 +406,7 @@ class Strumline extends FlxSpriteGroup if (Preferences.downscroll) { - holdNote.y = this.y + calculateNoteYPos(holdNote.strumTime, vwoosh) - holdNote.height + STRUMLINE_SIZE / 2; + holdNote.y = this.y - INITIAL_OFFSET + calculateNoteYPos(holdNote.strumTime, vwoosh) - holdNote.height + STRUMLINE_SIZE / 2; } else { @@ -435,7 +435,7 @@ class Strumline extends FlxSpriteGroup if (Preferences.downscroll) { - holdNote.y = this.y - holdNote.height + STRUMLINE_SIZE / 2; + holdNote.y = this.y - holdNote.height - INITIAL_OFFSET + STRUMLINE_SIZE / 2; // + STRUMLINE_SIZE / 2; } else { @@ -450,7 +450,7 @@ class Strumline extends FlxSpriteGroup if (Preferences.downscroll) { - holdNote.y = this.y + calculateNoteYPos(holdNote.strumTime, vwoosh) - holdNote.height + STRUMLINE_SIZE / 2; + holdNote.y = this.y - INITIAL_OFFSET + calculateNoteYPos(holdNote.strumTime, vwoosh) - holdNote.height + STRUMLINE_SIZE / 2; } else { From c270f61cac9b6fc5acca79206f7ccf5732d63dea Mon Sep 17 00:00:00 2001 From: MaybeMaru <97055307+MaybeMaru@users.noreply.github.com> Date: Mon, 13 May 2024 02:21:43 +0200 Subject: [PATCH 023/266] Update Strumline.hx --- source/funkin/play/notes/Strumline.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/play/notes/Strumline.hx b/source/funkin/play/notes/Strumline.hx index b520f7b703..a7a051a665 100644 --- a/source/funkin/play/notes/Strumline.hx +++ b/source/funkin/play/notes/Strumline.hx @@ -435,7 +435,7 @@ class Strumline extends FlxSpriteGroup if (Preferences.downscroll) { - holdNote.y = this.y - holdNote.height - INITIAL_OFFSET + STRUMLINE_SIZE / 2; // + STRUMLINE_SIZE / 2; + holdNote.y = this.y - holdNote.height - INITIAL_OFFSET + STRUMLINE_SIZE / 2; } else { From 0322a8388262ec8cda1eda8b69ceccd57652b6ef Mon Sep 17 00:00:00 2001 From: NotHyper-474 Date: Sun, 12 May 2024 23:16:12 -0300 Subject: [PATCH 024/266] Fix "Invalid argument '&'" error --- source/funkin/util/WindowUtil.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/util/WindowUtil.hx b/source/funkin/util/WindowUtil.hx index 763d84853e..9930d688c3 100644 --- a/source/funkin/util/WindowUtil.hx +++ b/source/funkin/util/WindowUtil.hx @@ -24,7 +24,7 @@ class WindowUtil { #if CAN_OPEN_LINKS #if linux - Sys.command('/usr/bin/xdg-open', [targetUrl, '&']); + Sys.command('/usr/bin/xdg-open ' + targetUrl + ' &'); #else // This should work on Windows and HTML5. FlxG.openURL(targetUrl); From 24933f5bb9bc725b90b95db6a4b2782f0f71b9d5 Mon Sep 17 00:00:00 2001 From: Hyper_ Date: Mon, 13 May 2024 17:16:49 -0300 Subject: [PATCH 025/266] Replace concatenation with string interpolation --- source/funkin/util/WindowUtil.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/util/WindowUtil.hx b/source/funkin/util/WindowUtil.hx index 9930d688c3..07f6bc13ad 100644 --- a/source/funkin/util/WindowUtil.hx +++ b/source/funkin/util/WindowUtil.hx @@ -24,7 +24,7 @@ class WindowUtil { #if CAN_OPEN_LINKS #if linux - Sys.command('/usr/bin/xdg-open ' + targetUrl + ' &'); + Sys.command('/usr/bin/xdg-open $targetUrl &'); #else // This should work on Windows and HTML5. FlxG.openURL(targetUrl); From c5caa0331e4f167d632065e2a265b96def506bd9 Mon Sep 17 00:00:00 2001 From: MaybeMaru <97055307+MaybeMaru@users.noreply.github.com> Date: Mon, 13 May 2024 22:17:47 +0200 Subject: [PATCH 026/266] Update Strumline.hx --- source/funkin/play/notes/Strumline.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/play/notes/Strumline.hx b/source/funkin/play/notes/Strumline.hx index a7a051a665..07d4ab69b0 100644 --- a/source/funkin/play/notes/Strumline.hx +++ b/source/funkin/play/notes/Strumline.hx @@ -435,7 +435,7 @@ class Strumline extends FlxSpriteGroup if (Preferences.downscroll) { - holdNote.y = this.y - holdNote.height - INITIAL_OFFSET + STRUMLINE_SIZE / 2; + holdNote.y = this.y - INITIAL_OFFSET - holdNote.height + STRUMLINE_SIZE / 2; } else { From 3810662f9fd55400be6d96808256b3c5e94be4ab Mon Sep 17 00:00:00 2001 From: rich <87835336+richTrash21@users.noreply.github.com> Date: Tue, 14 May 2024 04:20:23 +0400 Subject: [PATCH 027/266] freeplay optimization --- source/funkin/ui/freeplay/FreeplayState.hx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 7b7543845a..bdaa87ede3 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -527,6 +527,9 @@ class FreeplayState extends MusicBeatSubState orangeBackShit.visible = true; alsoOrangeLOL.visible = true; grpTxtScrolls.visible = true; + + // render optimisation + _parentState.persistentDraw = false; }); generateSongList(null, false); @@ -985,6 +988,8 @@ class FreeplayState extends MusicBeatSubState { clearDaCache(daSong.songName); } + // remove and destroy freeplay camera + FlxG.cameras.remove(FlxG.cameras.list[FlxG.cameras.list.length - 1]); } function changeDiff(change:Int = 0, force:Bool = false):Void From 59e409f8e65387a6000710046670c6d8262ad203 Mon Sep 17 00:00:00 2001 From: rich <87835336+richTrash21@users.noreply.github.com> Date: Tue, 14 May 2024 04:30:36 +0400 Subject: [PATCH 028/266] ensure that only freeplay camera gets destroyed --- source/funkin/ui/freeplay/FreeplayState.hx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index bdaa87ede3..0a2674c8ad 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -131,6 +131,7 @@ class FreeplayState extends MusicBeatSubState var exitMovers:ExitMoverData = new Map(); var stickerSubState:StickerSubState; + var funnyCam:FunkinCamera; public static var rememberedDifficulty:Null = Constants.DEFAULT_DIFFICULTY; public static var rememberedSongId:Null = 'tutorial'; @@ -535,7 +536,7 @@ class FreeplayState extends MusicBeatSubState generateSongList(null, false); // dedicated camera for the state so we don't need to fuk around with camera scrolls from the mainmenu / elsewhere - var funnyCam:FunkinCamera = new FunkinCamera('freeplayFunny', 0, 0, FlxG.width, FlxG.height); + funnyCam = new FunkinCamera('freeplayFunny', 0, 0, FlxG.width, FlxG.height); funnyCam.bgColor = FlxColor.TRANSPARENT; FlxG.cameras.add(funnyCam, false); @@ -989,7 +990,7 @@ class FreeplayState extends MusicBeatSubState clearDaCache(daSong.songName); } // remove and destroy freeplay camera - FlxG.cameras.remove(FlxG.cameras.list[FlxG.cameras.list.length - 1]); + FlxG.cameras.remove(funnyCam); } function changeDiff(change:Int = 0, force:Bool = false):Void From e462b04b59e564ec5c10c1cd495484178736fcbf Mon Sep 17 00:00:00 2001 From: nebulazorua Date: Wed, 15 May 2024 20:46:08 +0800 Subject: [PATCH 029/266] does notesplash --- source/funkin/modding/events/ScriptEvent.hx | 13 ++++++++++--- source/funkin/play/PlayState.hx | 5 +++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/source/funkin/modding/events/ScriptEvent.hx b/source/funkin/modding/events/ScriptEvent.hx index ece7870fd7..dd55de23b0 100644 --- a/source/funkin/modding/events/ScriptEvent.hx +++ b/source/funkin/modding/events/ScriptEvent.hx @@ -141,7 +141,7 @@ class HitNoteScriptEvent extends NoteScriptEvent public var score:Int; /** - * Whether the judgement caused a combo break. + * If the hit causes a combo break. */ public var isComboBreak:Bool = false; @@ -150,19 +150,26 @@ class HitNoteScriptEvent extends NoteScriptEvent */ public var hitDiff:Float = 0; - public function new(note:NoteSprite, healthChange:Float, score:Int, judgement:String, isComboBreak:Bool, comboCount:Int = 0, hitDiff:Float = 0):Void + /** + * If the hit causes a notesplash + */ + public var doesNotesplash:Bool = false; + + public function new(note:NoteSprite, healthChange:Float, score:Int, judgement:String, isComboBreak:Bool, comboCount:Int = 0, hitDiff:Float = 0, + doesNotesplash:Bool = false):Void { super(NOTE_HIT, note, healthChange, comboCount, true); this.score = score; this.judgement = judgement; this.isComboBreak = isComboBreak; + this.doesNotesplash = doesNotesplash; this.hitDiff = hitDiff; } public override function toString():String { return 'HitNoteScriptEvent(note=' + note + ', comboCount=' + comboCount + ', judgement=' + judgement + ', score=' + score + ', isComboBreak=' - + isComboBreak + ', hitDiff=' + hitDiff + ')'; + + isComboBreak + ', hitDiff=' + hitDiff + ', doesNotesplash=' + doesNotesplash + ')'; } } diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index cdd8c7d71c..f563c8d2e7 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -2400,7 +2400,8 @@ class PlayState extends MusicBeatSubState } // Send the note hit event. - var event:HitNoteScriptEvent = new HitNoteScriptEvent(note, healthChange, score, daRating, isComboBreak, Highscore.tallies.combo + 1, noteDiff); + var event:HitNoteScriptEvent = new HitNoteScriptEvent(note, healthChange, score, daRating, isComboBreak, Highscore.tallies.combo + 1, noteDiff, + daRating == 'sick'); dispatchEvent(event); // Calling event.cancelEvent() skips all the other logic! Neat! @@ -2409,7 +2410,7 @@ class PlayState extends MusicBeatSubState Highscore.tallies.totalNotesHit++; // Display the hit on the strums playerStrumline.hitNote(note, !isComboBreak); - if (daRating == 'sick') playerStrumline.playNoteSplash(note.noteData.getDirection()); + if (event.doesNotesplash) playerStrumline.playNoteSplash(note.noteData.getDirection()); if (note.isHoldNote && note.holdNoteSprite != null) playerStrumline.playNoteHoldCover(note.holdNoteSprite); vocals.playerVolume = 1; From 96de434d75d459ebeb13fdfc1aba7adf57b9d705 Mon Sep 17 00:00:00 2001 From: Burgerballs <107233412+Burgerballs@users.noreply.github.com> Date: Wed, 15 May 2024 17:17:09 +0100 Subject: [PATCH 030/266] multiplicative added!! + sum tween fixes --- source/funkin/play/PlayState.hx | 16 ++++++++++++++++ source/funkin/play/event/ScrollSpeedEvent.hx | 19 ++++++++++++++----- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 4ce778fc1c..d63854d3f3 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -3259,6 +3259,8 @@ class PlayState extends MusicBeatSubState cancelCameraZoomTween(); } + var prevScrollTargets:Array = []; // used to snap scroll speed when things go unruely + /** * The magical function that shall tween the scroll speed. */ @@ -3266,6 +3268,18 @@ class PlayState extends MusicBeatSubState { // Cancel the current tween if it's active. cancelScrollSpeedTweens(); + + // Snap to previous event value to prevent the tween breaking when another event cancels the previous tween. + for (i in prevScrollTargets) + { + var value:Float = i[1]; + var strum:Strumline = Reflect.getProperty(this, i[0]); + strum.scrollSpeed = value; + } + + // for next event, clean array. + prevScrollTargets = []; + for (i in strumlines) { var value:Float = speed; @@ -3282,6 +3296,8 @@ class PlayState extends MusicBeatSubState 'scrollSpeed': value }, duration, {ease: ease})); } + // make sure charts dont break if the charter is dumb and stupid + prevScrollTargets.push([value, i]); } } diff --git a/source/funkin/play/event/ScrollSpeedEvent.hx b/source/funkin/play/event/ScrollSpeedEvent.hx index 22da45b0cb..9abd4be90a 100644 --- a/source/funkin/play/event/ScrollSpeedEvent.hx +++ b/source/funkin/play/event/ScrollSpeedEvent.hx @@ -36,6 +36,7 @@ class ScrollSpeedEvent extends SongEvent static final DEFAULT_SCROLL:Float = 1; static final DEFAULT_DURATION:Float = 4.0; static final DEFAULT_EASE:String = 'linear'; + static final DEFAULT_ABSOLUTE:Bool = false; static final DEFAULT_STRUMLINE:String = 'both'; // my special little trick public override function handleEvent(data:SongEventData):Void @@ -51,12 +52,14 @@ class ScrollSpeedEvent extends SongEvent var strumline:String = data.getString('strumline') ?? DEFAULT_STRUMLINE; + var absolute:Bool = data.getBool('absolute') ?? DEFAULT_ABSOLUTE; + var strumlineNames:Array = []; - if (scroll == 0) + if (!absolute) { - // if the parameter is set to 0, reset the scroll speed to normal. - scroll = PlayState.instance?.currentChart?.scrollSpeed ?? 1.0; + // If absolute is set to false, do the awesome multiplicative thing + scroll = scroll * (PlayState.instance?.currentChart?.scrollSpeed ?? 1.0); } switch (strumline) @@ -103,8 +106,8 @@ class ScrollSpeedEvent extends SongEvent return new SongEventSchema([ { name: 'scroll', - title: 'Scroll Amount', - defaultValue: 0.0, + title: 'Target Value', + defaultValue: 1.0, step: 0.1, type: SongEventFieldType.FLOAT, units: 'x' @@ -157,6 +160,12 @@ class ScrollSpeedEvent extends SongEvent defaultValue: 'both', type: SongEventFieldType.ENUM, keys: ['Both' => 'both', 'Player' => 'player', 'Opponent' => 'opponent'] + }, + { + name: 'absolute', + title: 'Absolute', + defaultValue: false, + type: SongEventFieldType.BOOL, } ]); } From eaf998adf71a0e9060f6604dd23e070f3036d8f4 Mon Sep 17 00:00:00 2001 From: Burgerballs <107233412+Burgerballs@users.noreply.github.com> Date: Wed, 15 May 2024 17:24:04 +0100 Subject: [PATCH 031/266] curse burgerballs --- source/funkin/play/PlayState.hx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index d63854d3f3..176f3817c2 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -827,6 +827,8 @@ class PlayState extends MusicBeatSubState { if (!assertChartExists()) return; + prevScrollTargets = []; + dispatchEvent(new ScriptEvent(SONG_RETRY)); resetCamera(); @@ -3272,8 +3274,8 @@ class PlayState extends MusicBeatSubState // Snap to previous event value to prevent the tween breaking when another event cancels the previous tween. for (i in prevScrollTargets) { - var value:Float = i[1]; - var strum:Strumline = Reflect.getProperty(this, i[0]); + var value:Float = i[0]; + var strum:Strumline = Reflect.getProperty(this, i[1]); strum.scrollSpeed = value; } From 21333ee8dc5a65600e5b886f608bd76de8967233 Mon Sep 17 00:00:00 2001 From: Burgerballs <107233412+Burgerballs@users.noreply.github.com> Date: Wed, 15 May 2024 17:26:03 +0100 Subject: [PATCH 032/266] burgerbugs require burgerfixes --- source/funkin/play/notes/SustainTrail.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/play/notes/SustainTrail.hx b/source/funkin/play/notes/SustainTrail.hx index 9155c9b0a7..b358d7f033 100644 --- a/source/funkin/play/notes/SustainTrail.hx +++ b/source/funkin/play/notes/SustainTrail.hx @@ -168,7 +168,6 @@ class SustainTrail extends FlxSprite if (s < 0.0) s = 0.0; if (sustainLength == s) return s; - graphicHeight = sustainHeight(s, parentStrumline?.scrollSpeed ?? 1.0); this.sustainLength = s; triggerRedraw(); return this.sustainLength; @@ -176,6 +175,7 @@ class SustainTrail extends FlxSprite function triggerRedraw() { + graphicHeight = sustainHeight(sustainLength, parentStrumline?.scrollSpeed ?? 1.0); updateClipping(); updateHitbox(); } From b10872e8e89b7e9ab404c57a26a7d8646b1921b9 Mon Sep 17 00:00:00 2001 From: gamerbross <55158797+gamerbross@users.noreply.github.com> Date: Fri, 17 May 2024 23:51:07 +0200 Subject: [PATCH 033/266] Fix TitleState late start + enter spam crash --- source/funkin/ui/title/TitleState.hx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/funkin/ui/title/TitleState.hx b/source/funkin/ui/title/TitleState.hx index 49bef5e4a4..c9b3619e93 100644 --- a/source/funkin/ui/title/TitleState.hx +++ b/source/funkin/ui/title/TitleState.hx @@ -67,9 +67,11 @@ class TitleState extends MusicBeatState // DEBUG BULLSHIT // netConnection.addEventListener(MouseEvent.MOUSE_DOWN, overlay_onMouseDown); - new FlxTimer().start(1, function(tmr:FlxTimer) { + if (!initialized) new FlxTimer().start(1, function(tmr:FlxTimer) { startIntro(); }); + else + startIntro(); } function client_onMetaData(metaData:Dynamic) @@ -118,7 +120,7 @@ class TitleState extends MusicBeatState function startIntro():Void { - playMenuMusic(); + if (!initialized || FlxG.sound.music == null) playMenuMusic(); persistentUpdate = true; @@ -231,7 +233,7 @@ class TitleState extends MusicBeatState overrideExisting: true, restartTrack: true }); - // Fade from 0.0 to 0.7 over 4 seconds + // Fade from 0.0 to 1 over 4 seconds if (shouldFadeIn) FlxG.sound.music.fadeIn(4.0, 0.0, 1.0); } From b6b93bb0c6686b3a89100c3b625dfd912380cda6 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 17 May 2024 20:26:34 -0400 Subject: [PATCH 034/266] Added clear percent, rank name, and background text. --- .vscode/launch.json | 9 +- .vscode/settings.json | 5 + assets | 2 +- source/funkin/InitState.hx | 24 ++ source/funkin/play/PlayState.hx | 18 +- source/funkin/play/ResultState.hx | 288 ++++++++++-------- .../play/components/ClearPercentCounter.hx | 96 ++++++ source/funkin/save/Save.hx | 8 +- .../funkin/save/migrator/SaveDataMigrator.hx | 15 +- source/funkin/ui/freeplay/FreeplayState.hx | 4 +- source/funkin/ui/mainmenu/MainMenuState.hx | 3 +- 11 files changed, 311 insertions(+), 161 deletions(-) create mode 100644 source/funkin/play/components/ClearPercentCounter.hx diff --git a/.vscode/launch.json b/.vscode/launch.json index 74f72b8261..6dc1dc0082 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -3,10 +3,17 @@ "configurations": [ { // Launch in native/CPP on Windows/OSX/Linux - "name": "Lime", + "name": "Lime Build+Debug", "type": "lime", "request": "launch" }, + { + // Launch in native/CPP on Windows/OSX/Linux + "name": "Lime Debug (No Build)", + "type": "lime", + "request": "launch", + "preLaunchTask": null + }, { // Launch in browser "name": "HTML5 Debug", diff --git a/.vscode/settings.json b/.vscode/settings.json index a8a67245b2..26fe0b0427 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -155,6 +155,11 @@ "target": "hl", "args": ["-debug", "-DDIALOGUE"] }, + { + "label": "Windows / Debug (Results Screen Test)", + "target": "windows", + "args": ["-debug", "-DRESULTS"] + }, { "label": "Windows / Debug (Straight to Chart Editor)", "target": "windows", diff --git a/assets b/assets index fd112e293e..ce7dabffbe 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit fd112e293ee0f823ee98d5b8bd8a85e934f772f6 +Subproject commit ce7dabffbebc154c9dda1f01e92dbef83e3405ab diff --git a/source/funkin/InitState.hx b/source/funkin/InitState.hx index 00d34fadba..6a52eaf5d8 100644 --- a/source/funkin/InitState.hx +++ b/source/funkin/InitState.hx @@ -214,6 +214,30 @@ class InitState extends FlxState #elseif STAGEBUILD // -DSTAGEBUILD FlxG.switchState(() -> new funkin.ui.debug.stage.StageBuilderState()); + #elseif RESULTS + // -DRESULTS + FlxG.switchState(() -> new funkin.play.ResultState( + { + storyMode: false, + title: "CUM SONG", + isNewHighscore: true, + scoreData: + { + score: 1_234_567, + tallies: + { + sick: 130, + good: 69, + bad: 69, + shit: 69, + missed: 69, + combo: 69, + maxCombo: 69, + totalNotesHit: 140, + totalNotes: 2000, + } + }, + })); #elseif ANIMDEBUG // -DANIMDEBUG FlxG.switchState(() -> new funkin.ui.debug.anim.DebugBoundingState()); diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 44ad819c41..3e1d4cac8d 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -2777,6 +2777,7 @@ class PlayState extends MusicBeatSubState deathCounter = 0; var isNewHighscore = false; + var prevScoreData:Null = Save.instance.getSongScore(currentSong.id, currentDifficulty); if (currentSong != null && currentSong.validScore) { @@ -2796,7 +2797,6 @@ class PlayState extends MusicBeatSubState totalNotesHit: Highscore.tallies.totalNotesHit, totalNotes: Highscore.tallies.totalNotes, }, - accuracy: Highscore.tallies.totalNotesHit / Highscore.tallies.totalNotes, }; // adds current song data into the tallies for the level (story levels) @@ -2833,7 +2833,7 @@ class PlayState extends MusicBeatSubState score: PlayStatePlaylist.campaignScore, tallies: { - // TODO: Sum up the values for the whole level! + // TODO: Sum up the values for the whole week! sick: 0, good: 0, bad: 0, @@ -2844,7 +2844,6 @@ class PlayState extends MusicBeatSubState totalNotesHit: 0, totalNotes: 0, }, - accuracy: Highscore.tallies.totalNotesHit / Highscore.tallies.totalNotes, }; if (Save.instance.isLevelHighScore(PlayStatePlaylist.campaignId, PlayStatePlaylist.campaignDifficulty, data)) @@ -2930,11 +2929,11 @@ class PlayState extends MusicBeatSubState { if (rightGoddamnNow) { - moveToResultsScreen(isNewHighscore); + moveToResultsScreen(isNewHighscore, prevScoreData); } else { - zoomIntoResultsScreen(isNewHighscore); + zoomIntoResultsScreen(isNewHighscore, prevScoreData); } } } @@ -3008,7 +3007,7 @@ class PlayState extends MusicBeatSubState /** * Play the camera zoom animation and then move to the results screen once it's done. */ - function zoomIntoResultsScreen(isNewHighscore:Bool):Void + function zoomIntoResultsScreen(isNewHighscore:Bool, ?prevScoreData:SaveScoreData):Void { trace('WENT TO RESULTS SCREEN!'); @@ -3048,7 +3047,7 @@ class PlayState extends MusicBeatSubState FlxTween.tween(camHUD, {alpha: 0}, 0.6, { onComplete: function(_) { - moveToResultsScreen(isNewHighscore); + moveToResultsScreen(isNewHighscore, prevScoreData); } }); @@ -3081,7 +3080,7 @@ class PlayState extends MusicBeatSubState /** * Move to the results screen right goddamn now. */ - function moveToResultsScreen(isNewHighscore:Bool):Void + function moveToResultsScreen(isNewHighscore:Bool, ?prevScoreData:SaveScoreData):Void { persistentUpdate = false; vocals.stop(); @@ -3093,6 +3092,8 @@ class PlayState extends MusicBeatSubState { storyMode: PlayStatePlaylist.isStoryMode, title: PlayStatePlaylist.isStoryMode ? ('${PlayStatePlaylist.campaignTitle}') : ('${currentChart.songName} by ${currentChart.songArtist}'), + prevScoreData: prevScoreData, + difficultyId: currentDifficulty, scoreData: { score: PlayStatePlaylist.isStoryMode ? PlayStatePlaylist.campaignScore : songScore, @@ -3108,7 +3109,6 @@ class PlayState extends MusicBeatSubState totalNotesHit: talliesToUse.totalNotesHit, totalNotes: talliesToUse.totalNotes, }, - accuracy: Highscore.tallies.totalNotesHit / Highscore.tallies.totalNotes, }, isNewHighscore: isNewHighscore }); diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx index df3134b9d5..d038b77854 100644 --- a/source/funkin/play/ResultState.hx +++ b/source/funkin/play/ResultState.hx @@ -24,6 +24,7 @@ import funkin.save.Save; import funkin.save.Save.SaveScoreData; import funkin.graphics.shaders.LeftMaskShader; import funkin.play.components.TallyCounter; +import funkin.play.components.ClearPercentCounter; /** * The state for the results screen after a song or week is finished. @@ -109,7 +110,7 @@ class ResultState extends MusicBeatSubState var soundSystem:FlxSprite = FunkinSprite.createSparrow(-15, -180, 'resultScreen/soundSystem'); soundSystem.animation.addByPrefix("idle", "sound system", 24, false); soundSystem.visible = false; - new FlxTimer().start(0.4, _ -> { + new FlxTimer().start(0.3, _ -> { soundSystem.animation.play("idle"); soundSystem.visible = true; }); @@ -118,7 +119,7 @@ class ResultState extends MusicBeatSubState switch (rank) { - case PERFECT | PERFECT_GOLD | PERFECT_PLATINUM: + case PERFECT | PERFECT_GOLD: bfPerfect = new FlxAtlasSprite(370, -180, Paths.animateAtlas("resultScreen/results-bf/resultsPERFECT", "shared")); bfPerfect.visible = false; bfPerfect.zIndex = 500; @@ -183,22 +184,7 @@ class ResultState extends MusicBeatSubState }); } - var diffSpr:String = switch (PlayState.instance.currentDifficulty) - { - case 'easy': - 'difEasy'; - case 'normal': - 'difNormal'; - case 'hard': - 'difHard'; - case 'erect': - 'difErect'; - case 'nightmare': - 'difNightmare'; - case _: - 'difNormal'; - } - + var diffSpr:String = 'dif${params?.difficultyId ?? 'Normal'}'; difficulty.loadGraphic(Paths.image("resultScreen/" + diffSpr)); add(difficulty); @@ -208,7 +194,7 @@ class ResultState extends MusicBeatSubState speedOfTween.x = -1.0 * Math.cos(angleRad); speedOfTween.y = -1.0 * Math.sin(angleRad); - timerThenSongName(); + timerThenSongName(1.0); songName.shader = maskShaderSongName; difficulty.shader = maskShaderDifficulty; @@ -218,24 +204,40 @@ class ResultState extends MusicBeatSubState var blackTopBar:FlxSprite = new FlxSprite().loadGraphic(Paths.image("resultScreen/topBarBlack")); blackTopBar.y = -blackTopBar.height; - FlxTween.tween(blackTopBar, {y: 0}, 0.4, {ease: FlxEase.quartOut, startDelay: 0.5}); + FlxTween.tween(blackTopBar, {y: 0}, 0.4, {ease: FlxEase.quartOut}); blackTopBar.zIndex = 1010; add(blackTopBar); resultsAnim.animation.addByPrefix("result", "results instance 1", 24, false); - resultsAnim.animation.play("result"); + resultsAnim.visible = false; resultsAnim.zIndex = 1200; add(resultsAnim); + new FlxTimer().start(0.3, _ -> { + resultsAnim.visible = true; + resultsAnim.animation.play("result"); + }); ratingsPopin.animation.addByPrefix("idle", "Categories", 24, false); ratingsPopin.visible = false; ratingsPopin.zIndex = 1200; add(ratingsPopin); + new FlxTimer().start(1.0, _ -> { + ratingsPopin.visible = true; + ratingsPopin.animation.play("idle"); + }); scorePopin.animation.addByPrefix("score", "tally score", 24, false); scorePopin.visible = false; scorePopin.zIndex = 1200; add(scorePopin); + new FlxTimer().start(1.0, _ -> { + scorePopin.visible = true; + scorePopin.animation.play("score"); + scorePopin.animation.finishCallback = anim -> { + score.visible = true; + score.animateNumbers(); + }; + }); highscoreNew.frames = Paths.getSparrowAtlas("resultScreen/highscoreNew"); highscoreNew.animation.addByPrefix("new", "NEW HIGHSCORE", 24); @@ -285,13 +287,26 @@ class ResultState extends MusicBeatSubState for (ind => rating in ratingGrp.members) { rating.visible = false; - new FlxTimer().start((0.3 * ind) + 0.55, _ -> { + new FlxTimer().start((0.3 * ind) + 1.20, _ -> { rating.visible = true; FlxTween.tween(rating, {curNumber: rating.neededNumber}, 0.5, {ease: FlxEase.quartOut}); }); } - startRankTallySequence(); + ratingsPopin.animation.finishCallback = anim -> { + startRankTallySequence(); + + if (params.isNewHighscore ?? false) + { + highscoreNew.visible = true; + highscoreNew.animation.play("new"); + FlxTween.tween(highscoreNew, {y: highscoreNew.y + 10}, 0.8, {ease: FlxEase.quartOut}); + } + else + { + highscoreNew.visible = false; + } + }; refresh(); @@ -304,48 +319,43 @@ class ResultState extends MusicBeatSubState function startRankTallySequence():Void { - clearPercentTarget = Math.floor((params.scoreData.tallies.totalNotesHit) / params.scoreData.tallies.totalNotes * 100); - // clearPercentTarget = 97; + clearPercentTarget = Math.floor((params.scoreData.tallies.sick + params.scoreData.tallies.good) / params.scoreData.tallies.totalNotes * 100); + clearPercentTarget = 100; - var clearPercentText = new FlxText(FlxG.width / 2, FlxG.height / 2, 0, 'CLEAR: ${clearPercentLerp}%'); - clearPercentText.setFormat(Paths.font('vcr.ttf'), 64, FlxColor.BLACK, FlxTextAlign.RIGHT); - clearPercentText.zIndex = 1000; - add(clearPercentText); + clearPercentLerp = Std.int(Math.max(0, clearPercentTarget - 36)); - rankTallyTimer = new FlxTimer().start(1 / 24, _ -> { - // Tick up. - if (clearPercentLerp < clearPercentTarget) + var clearPercentCounter:ClearPercentCounter = new ClearPercentCounter(FlxG.width / 2 + 300, FlxG.height / 2 - 100, clearPercentTarget); + clearPercentCounter.curNumber = clearPercentLerp; + FlxTween.tween(clearPercentCounter, {curNumber: clearPercentTarget}, 1.5, { - clearPercentLerp++; - - clearPercentText.text = 'CLEAR: ${clearPercentLerp}%'; - FunkinSound.playOnce(Paths.sound('scrollMenu')); - } - - // Don't overshoot. - if (clearPercentLerp > clearPercentTarget) - { - clearPercentLerp = clearPercentTarget; - } + ease: FlxEase.quartOut, + onUpdate: _ -> { + // Only play the tick sound if the number increased. + if (clearPercentLerp != clearPercentCounter.curNumber) + { + clearPercentLerp = clearPercentCounter.curNumber; + FunkinSound.playOnce(Paths.sound('scrollMenu')); + } + }, + onComplete: _ -> { + // Play confirm sound. + FunkinSound.playOnce(Paths.sound('confirmMenu')); - if (clearPercentLerp == clearPercentTarget) - { - if (rankTallyTimer != null) - { - rankTallyTimer.destroy(); - rankTallyTimer = null; - } + // Flash background. + bgFlash.visible = true; + FlxTween.tween(bgFlash, {alpha: 0}, 0.4); - // Play confirm sound. - FunkinSound.playOnce(Paths.sound('confirmMenu')); + displayRankText(); - new FlxTimer().start(1.0, _ -> { - remove(clearPercentText); + new FlxTimer().start(2.0, _ -> { + // remove(clearPercentCounter); - afterRankTallySequence(); - }); - } - }, 0); // 0 = Loop until stopped + afterRankTallySequence(); + }); + } + }); + clearPercentCounter.zIndex = 450; + add(clearPercentCounter); if (ratingsPopin == null) { @@ -353,18 +363,15 @@ class ResultState extends MusicBeatSubState } else { - ratingsPopin.animation.play("idle"); - ratingsPopin.visible = true; + // ratingsPopin.animation.play("idle"); + // ratingsPopin.visible = true; ratingsPopin.animation.finishCallback = anim -> { - scorePopin.animation.play("score"); - scorePopin.animation.finishCallback = anim -> { - score.visible = true; - score.animateNumbers(); - }; - scorePopin.visible = true; + // scorePopin.animation.play("score"); + + // scorePopin.visible = true; - if (params.isNewHighscore) + if (params.isNewHighscore ?? false) { highscoreNew.visible = true; highscoreNew.animation.play("new"); @@ -380,6 +387,23 @@ class ResultState extends MusicBeatSubState refresh(); } + function displayRankText():Void + { + var rankTextVert:FunkinSprite = FunkinSprite.create(FlxG.width - 64, 100, rank.getVerTextAsset()); + rankTextVert.zIndex = 2000; + add(rankTextVert); + + for (i in 0...10) + { + var rankTextBack:FunkinSprite = FunkinSprite.create(FlxG.width / 2 - 80, 50, rank.getHorTextAsset()); + rankTextBack.y += (rankTextBack.height * i / 2) + 10; + rankTextBack.zIndex = 100; + add(rankTextBack); + } + + refresh(); + } + function afterRankTallySequence():Void { FunkinSound.playMusic(rank.getMusicPath(), @@ -406,7 +430,7 @@ class ResultState extends MusicBeatSubState switch (rank) { - case PERFECT | PERFECT_GOLD | PERFECT_PLATINUM: + case PERFECT | PERFECT_GOLD: if (bfPerfect == null) { trace("Could not build PERFECT animation!"); @@ -415,17 +439,6 @@ class ResultState extends MusicBeatSubState { bfPerfect.visible = true; bfPerfect.playAnimation(''); - - new FlxTimer().start((1 / 24) * 12, _ -> { - bgFlash.visible = true; - FlxTween.tween(bgFlash, {alpha: 0}, 0.4); - new FlxTimer().start((1 / 24) * 2, _ -> - { - // bgFlash.alpha = 0.5; - - // bgFlash.visible = false; - }); - }); } case EXCELLENT: @@ -437,17 +450,6 @@ class ResultState extends MusicBeatSubState { bfExcellent.visible = true; bfExcellent.playAnimation('Intro'); - - new FlxTimer().start((1 / 24) * 12, _ -> { - bgFlash.visible = true; - FlxTween.tween(bgFlash, {alpha: 0}, 0.4); - new FlxTimer().start((1 / 24) * 2, _ -> - { - // bgFlash.alpha = 0.5; - - // bgFlash.visible = false; - }); - }); } case SHIT: @@ -459,17 +461,6 @@ class ResultState extends MusicBeatSubState { bfShit.visible = true; bfShit.playAnimation('Intro'); - - new FlxTimer().start((1 / 24) * 12, _ -> { - bgFlash.visible = true; - FlxTween.tween(bgFlash, {alpha: 0}, 0.4); - new FlxTimer().start((1 / 24) * 2, _ -> - { - // bgFlash.alpha = 0.5; - - // bgFlash.visible = false; - }); - }); } case GREAT | GOOD: @@ -482,17 +473,6 @@ class ResultState extends MusicBeatSubState bfGood.animation.play('fall'); bfGood.visible = true; - new FlxTimer().start((1 / 24) * 12, _ -> { - bgFlash.visible = true; - FlxTween.tween(bgFlash, {alpha: 0}, 0.4); - new FlxTimer().start((1 / 24) * 2, _ -> - { - // bgFlash.alpha = 0.5; - - // bgFlash.visible = false; - }); - }); - new FlxTimer().start((1 / 24) * 22, _ -> { // plays about 22 frames (at 24fps timing) after bf spawns in if (gfGood != null) @@ -510,7 +490,7 @@ class ResultState extends MusicBeatSubState } } - function timerThenSongName():Void + function timerThenSongName(timerLength:Float = 3.0):Void { movingSongStuff = false; @@ -526,7 +506,7 @@ class ResultState extends MusicBeatSubState FlxTween.tween(songName, {y: diffYTween - 35 - fuckedupnumber}, 0.5, {ease: FlxEase.expoOut, startDelay: 0.9}); songName.x = (difficulty.x + difficulty.width) + 20; - new FlxTimer().start(3, _ -> { + new FlxTimer().start(timerLength, _ -> { var tempSpeed = FlxPoint.get(speedOfTween.x, speedOfTween.y); speedOfTween.set(0, 0); @@ -600,33 +580,29 @@ class ResultState extends MusicBeatSubState public static function calculateRank(params:ResultsStateParams):ResultRank { // Perfect (Platinum) is a Sick Full Clear - var isPerfectPlat = (params.scoreData.tallies.sick + params.scoreData.tallies.good) == params.scoreData.tallies.totalNotes - && params.scoreData.tallies.sick / params.scoreData.tallies.totalNotes >= Constants.RANK_PERFECT_PLAT_THRESHOLD; - if (isPerfectPlat) return ResultRank.PERFECT_PLATINUM; - - // Perfect (Gold) is an 85% Sick Full Clear - var isPerfectGold = (params.scoreData.tallies.sick + params.scoreData.tallies.good) == params.scoreData.tallies.totalNotes - && params.scoreData.tallies.sick / params.scoreData.tallies.totalNotes >= Constants.RANK_PERFECT_GOLD_THRESHOLD; + var isPerfectGold = params.scoreData.tallies.sick == params.scoreData.tallies.totalNotes; if (isPerfectGold) return ResultRank.PERFECT_GOLD; // Else, use the standard grades + // Grade % (only good and sick), 1.00 is a full combo + var grade = (params.scoreData.tallies.sick + params.scoreData.tallies.good) / params.scoreData.tallies.totalNotes; // Clear % (including bad and shit). 1.00 is a full clear but not a full combo var clear = (params.scoreData.tallies.totalNotesHit) / params.scoreData.tallies.totalNotes; - if (clear == Constants.RANK_PERFECT_THRESHOLD) + if (grade == Constants.RANK_PERFECT_THRESHOLD) { return ResultRank.PERFECT; } - else if (clear >= Constants.RANK_EXCELLENT_THRESHOLD) + else if (grade >= Constants.RANK_EXCELLENT_THRESHOLD) { return ResultRank.EXCELLENT; } - else if (clear >= Constants.RANK_GREAT_THRESHOLD) + else if (grade >= Constants.RANK_GREAT_THRESHOLD) { return ResultRank.GREAT; } - else if (clear >= Constants.RANK_GOOD_THRESHOLD) + else if (grade >= Constants.RANK_GOOD_THRESHOLD) { return ResultRank.GOOD; } @@ -639,7 +615,6 @@ class ResultState extends MusicBeatSubState enum abstract ResultRank(String) { - var PERFECT_PLATINUM; var PERFECT_GOLD; var PERFECT; var EXCELLENT; @@ -651,8 +626,6 @@ enum abstract ResultRank(String) { switch (abstract) { - case PERFECT_PLATINUM: - return 'resultsPERFECT'; case PERFECT_GOLD: return 'resultsPERFECT'; case PERFECT: @@ -665,6 +638,8 @@ enum abstract ResultRank(String) return 'resultsNORMAL'; case SHIT: return 'resultsSHIT'; + default: + return 'resultsNORMAL'; } } @@ -672,8 +647,6 @@ enum abstract ResultRank(String) { switch (abstract) { - case PERFECT_PLATINUM: - return true; case PERFECT_GOLD: return true; case PERFECT: @@ -690,6 +663,48 @@ enum abstract ResultRank(String) return false; } } + + public function getHorTextAsset() + { + switch (abstract) + { + case PERFECT_GOLD: + return 'resultScreen/rankText/rankScrollPERFECT'; + case PERFECT: + return 'resultScreen/rankText/rankScrollPERFECT'; + case EXCELLENT: + return 'resultScreen/rankText/rankScrollEXCELLENT'; + case GREAT: + return 'resultScreen/rankText/rankScrollGREAT'; + case GOOD: + return 'resultScreen/rankText/rankScrollGOOD'; + case SHIT: + return 'resultScreen/rankText/rankScrollLOSS'; + default: + return 'resultScreen/rankText/rankScrollGOOD'; + } + } + + public function getVerTextAsset() + { + switch (abstract) + { + case PERFECT_GOLD: + return 'resultScreen/rankText/rankTextPERFECT'; + case PERFECT: + return 'resultScreen/rankText/rankTextPERFECT'; + case EXCELLENT: + return 'resultScreen/rankText/rankTextEXCELLENT'; + case GREAT: + return 'resultScreen/rankText/rankTextGREAT'; + case GOOD: + return 'resultScreen/rankText/rankTextGOOD'; + case SHIT: + return 'resultScreen/rankText/rankTextLOSS'; + default: + return 'resultScreen/rankText/rankTextGOOD'; + } + } } typedef ResultsStateParams = @@ -707,10 +722,21 @@ typedef ResultsStateParams = /** * Whether the displayed score is a new highscore */ - var isNewHighscore:Bool; + var ?isNewHighscore:Bool; + + /** + * The difficulty ID of the song/week we just played. + * @default Normal + */ + var ?difficultyId:String; /** * The score, accuracy, and judgements. */ var scoreData:SaveScoreData; + + /** + * The previous score data, used for rank comparision. + */ + var ?prevScoreData:SaveScoreData; }; diff --git a/source/funkin/play/components/ClearPercentCounter.hx b/source/funkin/play/components/ClearPercentCounter.hx new file mode 100644 index 0000000000..4c03ec3a90 --- /dev/null +++ b/source/funkin/play/components/ClearPercentCounter.hx @@ -0,0 +1,96 @@ +package funkin.play.components; + +import funkin.graphics.FunkinSprite; +import flixel.FlxSprite; +import flixel.group.FlxGroup.FlxTypedGroup; +import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; +import flixel.math.FlxMath; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; +import flixel.text.FlxText.FlxTextAlign; +import funkin.util.MathUtil; + +/** + * Numerical counters used to display the clear percent. + */ +class ClearPercentCounter extends FlxTypedSpriteGroup +{ + public var curNumber:Int = 0; + public var neededNumber:Int = 0; + + public function new(x:Float, y:Float, neededNumber:Int = 0) + { + super(x, y); + + this.neededNumber = neededNumber; + + var clearPercentText:FunkinSprite = FunkinSprite.create(0, 0, 'resultScreen/clearPercent/clearPercentText'); + add(clearPercentText); + + if (curNumber == neededNumber) drawNumbers(); + } + + var tmr:Float = 0; + + override function update(elapsed:Float) + { + super.update(elapsed); + + if (curNumber < neededNumber) drawNumbers(); + } + + function drawNumbers() + { + var seperatedScore:Array = []; + var tempCombo:Int = Math.round(curNumber); + + var fullNumberDigits:Int = Std.int(Math.max(1, Math.ceil(MathUtil.logBase(10, neededNumber)))); + + while (tempCombo != 0) + { + seperatedScore.push(tempCombo % 10); + tempCombo = Math.floor(tempCombo / 10); + } + + if (seperatedScore.length == 0) seperatedScore.push(0); + + seperatedScore.reverse(); + + for (ind => num in seperatedScore) + { + var digitIndex = ind + 1; + if (digitIndex >= members.length) + { + var xPos = (digitIndex - 1) * (72 * this.scale.x); + var yPos = 72; + // Three digits = LRL so two different numbers aren't adjacent to each other. + var variant:Bool = (fullNumberDigits % 2 != 0) ? (digitIndex % 2 == 0) : (digitIndex % 2 == 1); + var numb:ClearPercentNumber = new ClearPercentNumber(xPos, yPos, num); + numb.scale.set(this.scale.x, this.scale.y); + add(numb); + } + else + { + members[digitIndex].animation.play(Std.string(num)); + } + } + } +} + +class ClearPercentNumber extends FlxSprite +{ + public function new(x:Float, y:Float, digit:Int, variant:Bool = false) + { + super(x, y); + + frames = Paths.getSparrowAtlas('resultScreen/clearPercent/clearPercentNumber${variant ? 'Right' : 'Left'}'); + + for (i in 0...10) + { + animation.addByPrefix('$i', 'number $i 0', 24, false); + } + + animation.play('$digit'); + updateHitbox(); + } +} diff --git a/source/funkin/save/Save.hx b/source/funkin/save/Save.hx index acbe59edda..08614e307b 100644 --- a/source/funkin/save/Save.hx +++ b/source/funkin/save/Save.hx @@ -53,7 +53,8 @@ class Save public function new(?data:RawSaveData) { if (data == null) this.data = Save.getDefault(); - else this.data = data; + else + this.data = data; } public static function getDefault():RawSaveData @@ -809,11 +810,6 @@ typedef SaveScoreData = * The count of each judgement hit. */ var tallies:SaveScoreTallyData; - - /** - * The accuracy percentage. - */ - var accuracy:Float; } typedef SaveScoreTallyData = diff --git a/source/funkin/save/migrator/SaveDataMigrator.hx b/source/funkin/save/migrator/SaveDataMigrator.hx index 3ed59e7268..9e308cb10e 100644 --- a/source/funkin/save/migrator/SaveDataMigrator.hx +++ b/source/funkin/save/migrator/SaveDataMigrator.hx @@ -118,7 +118,7 @@ class SaveDataMigrator var scoreDataEasy:SaveScoreData = { score: inputSaveData.songScores.get('${levelId}-easy') ?? 0, - accuracy: inputSaveData.songCompletion.get('${levelId}-easy') ?? 0.0, + // accuracy: inputSaveData.songCompletion.get('${levelId}-easy') ?? 0.0, tallies: { sick: 0, @@ -137,7 +137,7 @@ class SaveDataMigrator var scoreDataNormal:SaveScoreData = { score: inputSaveData.songScores.get('${levelId}') ?? 0, - accuracy: inputSaveData.songCompletion.get('${levelId}') ?? 0.0, + // accuracy: inputSaveData.songCompletion.get('${levelId}') ?? 0.0, tallies: { sick: 0, @@ -156,7 +156,7 @@ class SaveDataMigrator var scoreDataHard:SaveScoreData = { score: inputSaveData.songScores.get('${levelId}-hard') ?? 0, - accuracy: inputSaveData.songCompletion.get('${levelId}-hard') ?? 0.0, + // accuracy: inputSaveData.songCompletion.get('${levelId}-hard') ?? 0.0, tallies: { sick: 0, @@ -178,7 +178,6 @@ class SaveDataMigrator var scoreDataEasy:SaveScoreData = { score: 0, - accuracy: 0, tallies: { sick: 0, @@ -196,14 +195,13 @@ class SaveDataMigrator for (songId in songIds) { scoreDataEasy.score = Std.int(Math.max(scoreDataEasy.score, inputSaveData.songScores.get('${songId}-easy') ?? 0)); - scoreDataEasy.accuracy = Math.max(scoreDataEasy.accuracy, inputSaveData.songCompletion.get('${songId}-easy') ?? 0.0); + // scoreDataEasy.accuracy = Math.max(scoreDataEasy.accuracy, inputSaveData.songCompletion.get('${songId}-easy') ?? 0.0); } result.setSongScore(songIds[0], 'easy', scoreDataEasy); var scoreDataNormal:SaveScoreData = { score: 0, - accuracy: 0, tallies: { sick: 0, @@ -221,14 +219,13 @@ class SaveDataMigrator for (songId in songIds) { scoreDataNormal.score = Std.int(Math.max(scoreDataNormal.score, inputSaveData.songScores.get('${songId}') ?? 0)); - scoreDataNormal.accuracy = Math.max(scoreDataNormal.accuracy, inputSaveData.songCompletion.get('${songId}') ?? 0.0); + // scoreDataNormal.accuracy = Math.max(scoreDataNormal.accuracy, inputSaveData.songCompletion.get('${songId}') ?? 0.0); } result.setSongScore(songIds[0], 'normal', scoreDataNormal); var scoreDataHard:SaveScoreData = { score: 0, - accuracy: 0, tallies: { sick: 0, @@ -246,7 +243,7 @@ class SaveDataMigrator for (songId in songIds) { scoreDataHard.score = Std.int(Math.max(scoreDataHard.score, inputSaveData.songScores.get('${songId}-hard') ?? 0)); - scoreDataHard.accuracy = Math.max(scoreDataHard.accuracy, inputSaveData.songCompletion.get('${songId}-hard') ?? 0.0); + // scoreDataHard.accuracy = Math.max(scoreDataHard.accuracy, inputSaveData.songCompletion.get('${songId}-hard') ?? 0.0); } result.setSongScore(songIds[0], 'hard', scoreDataHard); } diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 2390682889..dbf223dc83 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -998,7 +998,7 @@ class FreeplayState extends MusicBeatSubState { var songScore:SaveScoreData = Save.instance.getSongScore(grpCapsules.members[curSelected].songData.songId, currentDifficulty); intendedScore = songScore?.score ?? 0; - intendedCompletion = songScore?.accuracy ?? 0.0; + intendedCompletion = songScore == null ? 0.0 : ((songScore.tallies.sick + songScore.tallies.good) / songScore.tallies.totalNotes); rememberedDifficulty = currentDifficulty; } else @@ -1196,7 +1196,7 @@ class FreeplayState extends MusicBeatSubState { var songScore:SaveScoreData = Save.instance.getSongScore(daSongCapsule.songData.songId, currentDifficulty); intendedScore = songScore?.score ?? 0; - intendedCompletion = songScore?.accuracy ?? 0.0; + intendedCompletion = songScore == null ? 0.0 : ((songScore.tallies.sick + songScore.tallies.good) / songScore.tallies.totalNotes); diffIdsCurrent = daSongCapsule.songData.songDifficulties; rememberedSongId = daSongCapsule.songData.songId; changeDiff(); diff --git a/source/funkin/ui/mainmenu/MainMenuState.hx b/source/funkin/ui/mainmenu/MainMenuState.hx index 466dbbb904..fcff41dfdf 100644 --- a/source/funkin/ui/mainmenu/MainMenuState.hx +++ b/source/funkin/ui/mainmenu/MainMenuState.hx @@ -355,8 +355,7 @@ class MainMenuState extends MusicBeatState maxCombo: 0, totalNotesHit: 0, totalNotes: 0, - }, - accuracy: 0, + } }); } #end From a73d65757cafa8b6eed97dd45ab5c1b1e28b6684 Mon Sep 17 00:00:00 2001 From: gamerbross <55158797+gamerbross@users.noreply.github.com> Date: Sun, 19 May 2024 00:23:51 +0200 Subject: [PATCH 035/266] Fix Options Menu not enabled in transIn --- source/funkin/ui/options/OptionsState.hx | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/source/funkin/ui/options/OptionsState.hx b/source/funkin/ui/options/OptionsState.hx index 81331b266f..e7950f0bd1 100644 --- a/source/funkin/ui/options/OptionsState.hx +++ b/source/funkin/ui/options/OptionsState.hx @@ -25,6 +25,8 @@ class OptionsState extends MusicBeatState override function create():Void { + persistentUpdate = true; + var menuBG = new FlxSprite().loadGraphic(Paths.image('menuBG')); var hsv = new HSVShader(); hsv.hue = -0.6; @@ -55,8 +57,6 @@ class OptionsState extends MusicBeatState setPage(Controls); } - // disable for intro transition - currentPage.enabled = false; super.create(); } @@ -86,13 +86,6 @@ class OptionsState extends MusicBeatState } } - override function finishTransIn() - { - super.finishTransIn(); - - currentPage.enabled = true; - } - function switchPage(name:PageName) { // TODO: Animate this transition? From bc1c15e91cdac75f7402840dbaf06811b8d44153 Mon Sep 17 00:00:00 2001 From: gamerbross <55158797+gamerbross@users.noreply.github.com> Date: Sun, 19 May 2024 00:29:46 +0200 Subject: [PATCH 036/266] Add Remember Selection to MainMenuState --- source/funkin/ui/mainmenu/MainMenuState.hx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/funkin/ui/mainmenu/MainMenuState.hx b/source/funkin/ui/mainmenu/MainMenuState.hx index 7a21a6e8f5..558a348345 100644 --- a/source/funkin/ui/mainmenu/MainMenuState.hx +++ b/source/funkin/ui/mainmenu/MainMenuState.hx @@ -42,6 +42,8 @@ class MainMenuState extends MusicBeatState var magenta:FlxSprite; var camFollow:FlxObject; + static var rememberedSelectedIndex:Int = 0; + override function create():Void { #if discord_rpc @@ -137,6 +139,8 @@ class MainMenuState extends MusicBeatState menuItem.scrollFactor.y = 0.4; } + menuItems.selectItem(rememberedSelectedIndex); + resetCamStuff(); subStateOpened.add(sub -> { @@ -285,6 +289,8 @@ class MainMenuState extends MusicBeatState function startExitState(state:NextState):Void { menuItems.enabled = false; // disable for exit + rememberedSelectedIndex = menuItems.selectedIndex; + var duration = 0.4; menuItems.forEach(function(item) { if (menuItems.selectedIndex != item.ID) From e0867643d04dd5624d0684fe8eca0fd7fd2efab9 Mon Sep 17 00:00:00 2001 From: lemz Date: Sun, 19 May 2024 01:39:30 +0200 Subject: [PATCH 037/266] fix the setgraphicsize stuff --- source/funkin/ui/transition/LoadingState.hx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/source/funkin/ui/transition/LoadingState.hx b/source/funkin/ui/transition/LoadingState.hx index 95c378b24d..bc26ad97a1 100644 --- a/source/funkin/ui/transition/LoadingState.hx +++ b/source/funkin/ui/transition/LoadingState.hx @@ -57,8 +57,7 @@ class LoadingState extends MusicBeatSubState funkay.scrollFactor.set(); funkay.screenCenter(); - loadBar = new FunkinSprite(0, FlxG.height - 20).makeSolidColor(FlxG.width, 10, 0xFFff16d2); - loadBar.screenCenter(X); + loadBar = new FunkinSprite(0, FlxG.height - 20).makeSolidColor(0, 10, 0xFFff16d2); add(loadBar); initSongsManifest().onComplete(function(lib) { @@ -163,8 +162,15 @@ class LoadingState extends MusicBeatSubState targetShit = FlxMath.remapToRange(callbacks.numRemaining / callbacks.length, 1, 0, 0, 1); var lerpWidth:Int = Std.int(FlxMath.lerp(loadBar.width, FlxG.width * targetShit, 0.2)); - loadBar.setGraphicSize(lerpWidth, loadBar.height); - loadBar.updateHitbox(); + // this if-check prevents the setGraphicSize function + // from setting the width of the loadBar to the height of the loadBar + // this is a behaviour that is implemented in the setGraphicSize function + // if the width parameter is equal to 0 + if (lerpWidth > 0) + { + loadBar.setGraphicSize(lerpWidth, loadBar.height); + loadBar.updateHitbox(); + } FlxG.watch.addQuick('percentage?', callbacks.numRemaining / callbacks.length); } From faf7a0643cd83bbf99ac99e302c6aaf2bcdebd30 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Sun, 19 May 2024 01:47:36 -0400 Subject: [PATCH 038/266] Tinkered with ghost tapping some, leaving it off for now tho. --- source/funkin/play/PlayState.hx | 24 ++++++++++++++---------- source/funkin/play/notes/Strumline.hx | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 44ad819c41..5b95c467c4 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -2298,8 +2298,6 @@ class PlayState extends MusicBeatSubState var notesInRange:Array = playerStrumline.getNotesMayHit(); var holdNotesInRange:Array = playerStrumline.getHoldNotesHitOrMissed(); - // If there are notes in range, pressing a key will cause a ghost miss. - var notesByDirection:Array> = [[], [], [], []]; for (note in notesInRange) @@ -2321,17 +2319,27 @@ class PlayState extends MusicBeatSubState // Play the strumline animation. playerStrumline.playPress(input.noteDirection); + trace('PENALTY Score: ${songScore}'); } - else if (Constants.GHOST_TAPPING && (holdNotesInRange.length + notesInRange.length > 0) && notesInDirection.length == 0) + else if (Constants.GHOST_TAPPING && (!playerStrumline.mayGhostTap()) && notesInDirection.length == 0) { - // Pressed a wrong key with no notes nearby AND with notes in a different direction available. + // Pressed a wrong key with notes visible on-screen. // Perform a ghost miss (anti-spam). ghostNoteMiss(input.noteDirection, notesInRange.length > 0); // Play the strumline animation. playerStrumline.playPress(input.noteDirection); + trace('PENALTY Score: ${songScore}'); + } + else if (notesInDirection.length == 0) + { + // Press a key with no penalty. + + // Play the strumline animation. + playerStrumline.playPress(input.noteDirection); + trace('NO PENALTY Score: ${songScore}'); } - else if (notesInDirection.length > 0) + else { // Choose the first note, deprioritizing low priority notes. var targetNote:Null = notesInDirection.find((note) -> !note.lowPriority); @@ -2341,17 +2349,13 @@ class PlayState extends MusicBeatSubState // Judge and hit the note. trace('Hit note! ${targetNote.noteData}'); goodNoteHit(targetNote, input); + trace('Score: ${songScore}'); notesInDirection.remove(targetNote); // Play the strumline animation. playerStrumline.playConfirm(input.noteDirection); } - else - { - // Play the strumline animation. - playerStrumline.playPress(input.noteDirection); - } } while (inputReleaseQueue.length > 0) diff --git a/source/funkin/play/notes/Strumline.hx b/source/funkin/play/notes/Strumline.hx index 6a18f17d5b..220b6723c5 100644 --- a/source/funkin/play/notes/Strumline.hx +++ b/source/funkin/play/notes/Strumline.hx @@ -171,6 +171,20 @@ class Strumline extends FlxSpriteGroup updateNotes(); } + /** + * Returns `true` if no notes are in range of the strumline and the player can spam without penalty. + */ + public function mayGhostTap():Bool + { + // TODO: Refine this. Only querying "can be hit" is too tight but "is being rendered" is too loose. + // Also, if you just hit a note, there should be a (short) period where this is off so you can't spam. + + // If there are any notes on screen, we can't ghost tap. + return notes.members.filter(function(note:NoteSprite) { + return note != null && note.alive && !note.hasBeenHit; + }).length == 0; + } + /** * Return notes that are within `Constants.HIT_WINDOW` ms of the strumline. * @return An array of `NoteSprite` objects. From 228ac66cc2e9966c0eae1f4bc050477ff9cba93f Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Sun, 19 May 2024 01:48:51 -0400 Subject: [PATCH 039/266] Credit the song's charter in the pause menu. --- assets | 2 +- source/funkin/data/song/SongData.hx | 3 + source/funkin/data/song/SongRegistry.hx | 2 +- .../data/song/importer/FNFLegacyImporter.hx | 2 +- source/funkin/play/PauseSubState.hx | 89 +++++++++++++++++-- source/funkin/play/song/Song.hx | 15 ++++ .../ui/debug/charting/ChartEditorState.hx | 2 +- .../toolboxes/ChartEditorMetadataToolbox.hx | 16 ++++ source/funkin/util/Constants.hx | 5 ++ 9 files changed, 127 insertions(+), 9 deletions(-) diff --git a/assets b/assets index fd112e293e..778e16705b 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit fd112e293ee0f823ee98d5b8bd8a85e934f772f6 +Subproject commit 778e16705b30af85087f627594c22f4b5ba6141a diff --git a/source/funkin/data/song/SongData.hx b/source/funkin/data/song/SongData.hx index 26380947af..bd25139a79 100644 --- a/source/funkin/data/song/SongData.hx +++ b/source/funkin/data/song/SongData.hx @@ -30,6 +30,9 @@ class SongMetadata implements ICloneable @:default("Unknown") public var artist:String; + @:optional + public var charter:Null = null; + @:optional @:default(96) public var divisions:Null; // Optional field diff --git a/source/funkin/data/song/SongRegistry.hx b/source/funkin/data/song/SongRegistry.hx index 277dcd9e1f..a3305c4ecc 100644 --- a/source/funkin/data/song/SongRegistry.hx +++ b/source/funkin/data/song/SongRegistry.hx @@ -20,7 +20,7 @@ class SongRegistry extends BaseRegistry * Handle breaking changes by incrementing this value * and adding migration to the `migrateStageData()` function. */ - public static final SONG_METADATA_VERSION:thx.semver.Version = "2.2.2"; + public static final SONG_METADATA_VERSION:thx.semver.Version = "2.2.3"; public static final SONG_METADATA_VERSION_RULE:thx.semver.VersionRule = "2.2.x"; diff --git a/source/funkin/data/song/importer/FNFLegacyImporter.hx b/source/funkin/data/song/importer/FNFLegacyImporter.hx index ab2abda8e1..fdfac7f726 100644 --- a/source/funkin/data/song/importer/FNFLegacyImporter.hx +++ b/source/funkin/data/song/importer/FNFLegacyImporter.hx @@ -36,7 +36,7 @@ class FNFLegacyImporter { trace('Migrating song metadata from FNF Legacy.'); - var songMetadata:SongMetadata = new SongMetadata('Import', 'Kawai Sprite', 'default'); + var songMetadata:SongMetadata = new SongMetadata('Import', Constants.DEFAULT_ARTIST, 'default'); var hadError:Bool = false; diff --git a/source/funkin/play/PauseSubState.hx b/source/funkin/play/PauseSubState.hx index fb9d9b4e29..c345871a9a 100644 --- a/source/funkin/play/PauseSubState.hx +++ b/source/funkin/play/PauseSubState.hx @@ -101,6 +101,10 @@ class PauseSubState extends MusicBeatSubState */ static final MUSIC_FINAL_VOLUME:Float = 0.75; + static final CHARTER_FADE_DELAY:Float = 15.0; + + static final CHARTER_FADE_DURATION:Float = 0.75; + /** * Defines which pause music to use. */ @@ -163,6 +167,12 @@ class PauseSubState extends MusicBeatSubState */ var metadataDeaths:FlxText; + /** + * A text object which displays the current song's artist. + * Fades to the charter after a period before fading back. + */ + var metadataArtist:FlxText; + /** * The actual text objects for the menu entries. */ @@ -203,6 +213,8 @@ class PauseSubState extends MusicBeatSubState regenerateMenu(); transitionIn(); + + startCharterTimer(); } /** @@ -222,6 +234,8 @@ class PauseSubState extends MusicBeatSubState public override function destroy():Void { super.destroy(); + charterFadeTween.destroy(); + charterFadeTween = null; pauseMusic.stop(); } @@ -270,16 +284,25 @@ class PauseSubState extends MusicBeatSubState metadata.scrollFactor.set(0, 0); add(metadata); - var metadataSong:FlxText = new FlxText(20, 15, FlxG.width - 40, 'Song Name - Artist'); + var metadataSong:FlxText = new FlxText(20, 15, FlxG.width - 40, 'Song Name'); metadataSong.setFormat(Paths.font('vcr.ttf'), 32, FlxColor.WHITE, FlxTextAlign.RIGHT); if (PlayState.instance?.currentChart != null) { - metadataSong.text = '${PlayState.instance.currentChart.songName} - ${PlayState.instance.currentChart.songArtist}'; + metadataSong.text = '${PlayState.instance.currentChart.songName}'; } metadataSong.scrollFactor.set(0, 0); metadata.add(metadataSong); - var metadataDifficulty:FlxText = new FlxText(20, 15 + 32, FlxG.width - 40, 'Difficulty: '); + metadataArtist = new FlxText(20, metadataSong.y + 32, FlxG.width - 40, 'Artist: ${Constants.DEFAULT_ARTIST}'); + metadataArtist.setFormat(Paths.font('vcr.ttf'), 32, FlxColor.WHITE, FlxTextAlign.RIGHT); + if (PlayState.instance?.currentChart != null) + { + metadataArtist.text = 'Artist: ${PlayState.instance.currentChart.songArtist}'; + } + metadataArtist.scrollFactor.set(0, 0); + metadata.add(metadataArtist); + + var metadataDifficulty:FlxText = new FlxText(20, metadataArtist.y + 32, FlxG.width - 40, 'Difficulty: '); metadataDifficulty.setFormat(Paths.font('vcr.ttf'), 32, FlxColor.WHITE, FlxTextAlign.RIGHT); if (PlayState.instance?.currentDifficulty != null) { @@ -288,12 +311,12 @@ class PauseSubState extends MusicBeatSubState metadataDifficulty.scrollFactor.set(0, 0); metadata.add(metadataDifficulty); - metadataDeaths = new FlxText(20, 15 + 64, FlxG.width - 40, '${PlayState.instance?.deathCounter} Blue Balls'); + metadataDeaths = new FlxText(20, metadataDifficulty.y + 32, FlxG.width - 40, '${PlayState.instance?.deathCounter} Blue Balls'); metadataDeaths.setFormat(Paths.font('vcr.ttf'), 32, FlxColor.WHITE, FlxTextAlign.RIGHT); metadataDeaths.scrollFactor.set(0, 0); metadata.add(metadataDeaths); - metadataPractice = new FlxText(20, 15 + 96, FlxG.width - 40, 'PRACTICE MODE'); + metadataPractice = new FlxText(20, metadataDeaths.y + 32, FlxG.width - 40, 'PRACTICE MODE'); metadataPractice.setFormat(Paths.font('vcr.ttf'), 32, FlxColor.WHITE, FlxTextAlign.RIGHT); metadataPractice.visible = PlayState.instance?.isPracticeMode ?? false; metadataPractice.scrollFactor.set(0, 0); @@ -302,6 +325,62 @@ class PauseSubState extends MusicBeatSubState updateMetadataText(); } + var charterFadeTween:Null = null; + + function startCharterTimer():Void + { + charterFadeTween = FlxTween.tween(metadataArtist, {alpha: 0.0}, CHARTER_FADE_DURATION, + { + startDelay: CHARTER_FADE_DELAY, + ease: FlxEase.quartOut, + onComplete: (_) -> { + if (PlayState.instance?.currentChart != null) + { + metadataArtist.text = 'Charter: ${PlayState.instance.currentChart.charter ?? 'Unknown'}'; + } + else + { + metadataArtist.text = 'Charter: ${Constants.DEFAULT_CHARTER}'; + } + + FlxTween.tween(metadataArtist, {alpha: 1.0}, CHARTER_FADE_DURATION, + { + ease: FlxEase.quartOut, + onComplete: (_) -> { + startArtistTimer(); + } + }); + } + }); + } + + function startArtistTimer():Void + { + charterFadeTween = FlxTween.tween(metadataArtist, {alpha: 0.0}, CHARTER_FADE_DURATION, + { + startDelay: CHARTER_FADE_DELAY, + ease: FlxEase.quartOut, + onComplete: (_) -> { + if (PlayState.instance?.currentChart != null) + { + metadataArtist.text = 'Artist: ${PlayState.instance.currentChart.songArtist}'; + } + else + { + metadataArtist.text = 'Artist: ${Constants.DEFAULT_ARTIST}'; + } + + FlxTween.tween(metadataArtist, {alpha: 1.0}, CHARTER_FADE_DURATION, + { + ease: FlxEase.quartOut, + onComplete: (_) -> { + startCharterTimer(); + } + }); + } + }); + } + /** * Perform additional animations to transition the pause menu in when it is first displayed. */ diff --git a/source/funkin/play/song/Song.hx b/source/funkin/play/song/Song.hx index 23d8d21986..5da78e9dfc 100644 --- a/source/funkin/play/song/Song.hx +++ b/source/funkin/play/song/Song.hx @@ -120,6 +120,18 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry 0) return _metadata.get(Constants.DEFAULT_VARIATION)?.charter ?? 'Unknown'; + return Constants.DEFAULT_CHARTER; + } + /** * @param id The ID of the song to load. * @param ignoreErrors If false, an exception will be thrown if the song data could not be loaded. @@ -270,6 +282,7 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry = null; public var looped:Bool = false; diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index a313981f45..980f5db4f3 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -1270,7 +1270,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState var result:Null = songMetadata.get(selectedVariation); if (result == null) { - result = new SongMetadata('DadBattle', 'Kawai Sprite', selectedVariation); + result = new SongMetadata('Default Song Name', Constants.DEFAULT_ARTIST, selectedVariation); songMetadata.set(selectedVariation, result); } return result; diff --git a/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx b/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx index f85307c64f..80a421d806 100644 --- a/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx +++ b/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx @@ -29,6 +29,7 @@ class ChartEditorMetadataToolbox extends ChartEditorBaseToolbox { var inputSongName:TextField; var inputSongArtist:TextField; + var inputSongCharter:TextField; var inputStage:DropDown; var inputNoteStyle:DropDown; var buttonCharacterPlayer:Button; @@ -89,6 +90,20 @@ class ChartEditorMetadataToolbox extends ChartEditorBaseToolbox } }; + inputSongCharter.onChange = function(event:UIEvent) { + var valid:Bool = event.target.text != null && event.target.text != ''; + + if (valid) + { + inputSongCharter.removeClass('invalid-value'); + chartEditorState.currentSongMetadata.charter = event.target.text; + } + else + { + chartEditorState.currentSongMetadata.charter = null; + } + }; + inputStage.onChange = function(event:UIEvent) { var valid:Bool = event.data != null && event.data.id != null; @@ -176,6 +191,7 @@ class ChartEditorMetadataToolbox extends ChartEditorBaseToolbox inputSongName.value = chartEditorState.currentSongMetadata.songName; inputSongArtist.value = chartEditorState.currentSongMetadata.artist; + inputSongCharter.value = chartEditorState.currentSongMetadata.charter; inputStage.value = chartEditorState.currentSongMetadata.playData.stage; inputNoteStyle.value = chartEditorState.currentSongMetadata.playData.noteStyle; inputBPM.value = chartEditorState.currentSongMetadata.timeChanges[0].bpm; diff --git a/source/funkin/util/Constants.hx b/source/funkin/util/Constants.hx index 2f3b570b3b..4e706c612e 100644 --- a/source/funkin/util/Constants.hx +++ b/source/funkin/util/Constants.hx @@ -248,6 +248,11 @@ class Constants */ public static final DEFAULT_ARTIST:String = 'Unknown'; + /** + * The default charter for songs. + */ + public static final DEFAULT_CHARTER:String = 'Unknown'; + /** * The default note style for songs. */ From 13595fca700d99c0a472687b20b1ba6170eec58f Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Sun, 19 May 2024 01:49:06 -0400 Subject: [PATCH 040/266] Changelog entry for chart metadata --- source/funkin/data/song/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/funkin/data/song/CHANGELOG.md b/source/funkin/data/song/CHANGELOG.md index 3cd3af0700..4f1c66adec 100644 --- a/source/funkin/data/song/CHANGELOG.md +++ b/source/funkin/data/song/CHANGELOG.md @@ -5,6 +5,10 @@ All notable changes to this project 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). +## [2.2.3] +### Added +- Added `charter` field to denote authorship of a chart. + ## [2.2.2] ### Added - Added `playData.previewStart` and `playData.previewEnd` fields to specify when in the song should the song's audio should be played as a preview in Freeplay. From dcfc51cdcd53cd52b1b5ee34f0df6778afa1f2b9 Mon Sep 17 00:00:00 2001 From: gamerbross <55158797+gamerbross@users.noreply.github.com> Date: Mon, 20 May 2024 01:37:35 +0200 Subject: [PATCH 041/266] Fix Charting Sustain Trails Inverted --- .../ui/debug/charting/components/ChartEditorHoldNoteSprite.hx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/funkin/ui/debug/charting/components/ChartEditorHoldNoteSprite.hx b/source/funkin/ui/debug/charting/components/ChartEditorHoldNoteSprite.hx index aeb6dd0e4a..7c20358a4c 100644 --- a/source/funkin/ui/debug/charting/components/ChartEditorHoldNoteSprite.hx +++ b/source/funkin/ui/debug/charting/components/ChartEditorHoldNoteSprite.hx @@ -36,6 +36,8 @@ class ChartEditorHoldNoteSprite extends SustainTrail zoom *= 0.7; zoom *= ChartEditorState.GRID_SIZE / Strumline.STRUMLINE_SIZE; + flipY = false; + setup(); } From 9a18e3fde6ee779ca391dece4a0d94e79f584501 Mon Sep 17 00:00:00 2001 From: gamerbross <55158797+gamerbross@users.noreply.github.com> Date: Mon, 20 May 2024 01:38:52 +0200 Subject: [PATCH 042/266] Fix Charting Dragging Sustain Trails --- source/funkin/ui/debug/charting/ChartEditorState.hx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index b75cd8bf1f..d426abaafd 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -4566,8 +4566,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState } gridGhostHoldNote.visible = true; - gridGhostHoldNote.noteData = gridGhostNote.noteData; - gridGhostHoldNote.noteDirection = gridGhostNote.noteData.getDirection(); + gridGhostHoldNote.noteData = currentPlaceNoteData; + gridGhostHoldNote.noteDirection = currentPlaceNoteData.getDirection(); gridGhostHoldNote.setHeightDirectly(dragLengthPixels, true); gridGhostHoldNote.updateHoldNotePosition(renderedHoldNotes); From 9968c8eabcd6ee6b805abee3a3dbd9c82695fc89 Mon Sep 17 00:00:00 2001 From: etvx86 <64978924+EnterTheVoid-x86@users.noreply.github.com> Date: Mon, 20 May 2024 10:42:17 -0400 Subject: [PATCH 043/266] Fix some trace typos --- source/funkin/play/PlayState.hx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index a9ca09ce84..88fea72ac8 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -772,19 +772,19 @@ class PlayState extends MusicBeatSubState var message:String = 'There was a critical error. Click OK to return to the main menu.'; if (currentSong == null) { - message = 'The was a critical error loading this song\'s chart. Click OK to return to the main menu.'; + message = 'There was a critical error loading this song\'s chart. Click OK to return to the main menu.'; } else if (currentDifficulty == null) { - message = 'The was a critical error selecting a difficulty for this song. Click OK to return to the main menu.'; + message = 'There was a critical error selecting a difficulty for this song. Click OK to return to the main menu.'; } else if (currentChart == null) { - message = 'The was a critical error retrieving data for this song on "$currentDifficulty" difficulty with variation "$currentVariation". Click OK to return to the main menu.'; + message = 'There was a critical error retrieving data for this song on "$currentDifficulty" difficulty with variation "$currentVariation". Click OK to return to the main menu.'; } else if (currentChart.notes == null) { - message = 'The was a critical error retrieving note data for this song on "$currentDifficulty" difficulty with variation "$currentVariation". Click OK to return to the main menu.'; + message = 'There was a critical error retrieving note data for this song on "$currentDifficulty" difficulty with variation "$currentVariation". Click OK to return to the main menu.'; } // Display a popup. This blocks the application until the user clicks OK. From 1050176b274014a17b7714ef75a26c8a8684cb46 Mon Sep 17 00:00:00 2001 From: richTrash21 Date: Mon, 20 May 2024 23:52:48 +0400 Subject: [PATCH 044/266] main menu camera fix --- source/funkin/ui/debug/DebugMenuSubState.hx | 1 - source/funkin/ui/mainmenu/MainMenuState.hx | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/source/funkin/ui/debug/DebugMenuSubState.hx b/source/funkin/ui/debug/DebugMenuSubState.hx index 6d6e73e809..f8b1be9d2d 100644 --- a/source/funkin/ui/debug/DebugMenuSubState.hx +++ b/source/funkin/ui/debug/DebugMenuSubState.hx @@ -62,7 +62,6 @@ class DebugMenuSubState extends MusicBeatSubState #if sys createItem("OPEN CRASH LOG FOLDER", openLogFolder); #end - FlxG.camera.focusOn(new FlxPoint(camFocusPoint.x, camFocusPoint.y)); FlxG.camera.focusOn(new FlxPoint(camFocusPoint.x, camFocusPoint.y + 500)); } diff --git a/source/funkin/ui/mainmenu/MainMenuState.hx b/source/funkin/ui/mainmenu/MainMenuState.hx index 7a21a6e8f5..9af4e299fd 100644 --- a/source/funkin/ui/mainmenu/MainMenuState.hx +++ b/source/funkin/ui/mainmenu/MainMenuState.hx @@ -49,6 +49,8 @@ class MainMenuState extends MusicBeatState DiscordClient.changePresence("In the Menus", null); #end + FlxG.cameras.reset(new FunkinCamera('mainMenu')); + transIn = FlxTransitionableState.defaultTransIn; transOut = FlxTransitionableState.defaultTransOut; @@ -170,7 +172,6 @@ class MainMenuState extends MusicBeatState function resetCamStuff():Void { - FlxG.cameras.reset(new FunkinCamera('mainMenu')); FlxG.camera.follow(camFollow, null, 0.06); FlxG.camera.snapToTarget(); } @@ -329,6 +330,8 @@ class MainMenuState extends MusicBeatState persistentUpdate = false; FlxG.state.openSubState(new DebugMenuSubState()); + // reset camera when debug menu is closed + subStateClosed.addOnce(_ -> resetCamStuff()); } #end From f3868c2ee8d9dcf9488c349d8509545f0113f010 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 21 May 2024 02:23:21 -0400 Subject: [PATCH 045/266] An attempt at an HTML5 save data fix --- hmm.json | 2 +- source/funkin/save/Save.hx | 6 ++-- .../funkin/save/migrator/SaveDataMigrator.hx | 7 ++-- source/funkin/util/StructureUtil.hx | 32 ++++++++++++++++--- source/funkin/util/VersionUtil.hx | 19 +++++++++++ 5 files changed, 55 insertions(+), 11 deletions(-) diff --git a/hmm.json b/hmm.json index c359d7a512..1fe5a923d6 100644 --- a/hmm.json +++ b/hmm.json @@ -153,7 +153,7 @@ "name": "polymod", "type": "git", "dir": null, - "ref": "8553b800965f225bb14c7ab8f04bfa9cdec362ac", + "ref": "bfbe30d81601b3543d80dce580108ad6b7e182c7", "url": "https://github.com/larsiusprime/polymod" }, { diff --git a/source/funkin/save/Save.hx b/source/funkin/save/Save.hx index acbe59edda..dbba4a4c46 100644 --- a/source/funkin/save/Save.hx +++ b/source/funkin/save/Save.hx @@ -53,7 +53,8 @@ class Save public function new(?data:RawSaveData) { if (data == null) this.data = Save.getDefault(); - else this.data = data; + else + this.data = data; } public static function getDefault():RawSaveData @@ -714,6 +715,7 @@ class Save /** * An anonymous structure containingg all the user's save data. + * Isn't stored with JSON, stored with some sort of Haxe built-in serialization? */ typedef RawSaveData = { @@ -724,8 +726,6 @@ typedef RawSaveData = /** * A semantic versioning string for the save data format. */ - @:jcustomparse(funkin.data.DataParse.semverVersion) - @:jcustomwrite(funkin.data.DataWrite.semverVersion) var version:Version; var api:SaveApiData; diff --git a/source/funkin/save/migrator/SaveDataMigrator.hx b/source/funkin/save/migrator/SaveDataMigrator.hx index 3ed59e7268..7f597b4ec9 100644 --- a/source/funkin/save/migrator/SaveDataMigrator.hx +++ b/source/funkin/save/migrator/SaveDataMigrator.hx @@ -24,6 +24,8 @@ class SaveDataMigrator } else { + // Sometimes the Haxe serializer has issues with the version so we fix it here. + version = VersionUtil.repairVersion(version); if (VersionUtil.validateVersion(version, Save.SAVE_DATA_VERSION_RULE)) { // Simply import the structured data. @@ -32,8 +34,9 @@ class SaveDataMigrator } else { - trace('[SAVE] Invalid save data version! Returning blank data.'); - trace(inputData); + var message:String = 'Error migrating save data, expected ${Save.SAVE_DATA_VERSION}.'; + lime.app.Application.current.window.alert(message, "Save Data Failure"); + trace('[SAVE] ' + message); return new Save(Save.getDefault()); } } diff --git a/source/funkin/util/StructureUtil.hx b/source/funkin/util/StructureUtil.hx index 2f0c3818a2..2a6b345d36 100644 --- a/source/funkin/util/StructureUtil.hx +++ b/source/funkin/util/StructureUtil.hx @@ -44,8 +44,15 @@ class StructureUtil return Std.isOfType(a, haxe.Constraints.IMap); } - public static function isObject(a:Dynamic):Bool + /** + * Returns `true` if `a` is an anonymous structure. + * I believe this returns `false` even for class instances and arrays. + */ + public static function isStructure(a:Dynamic):Bool { + // TODO: Is there a difference? + // return Reflect.isObject(foo); + switch (Type.typeof(a)) { case TObject: @@ -55,6 +62,22 @@ class StructureUtil } } + /** + * Returns true if `a` is an array. + * + * NOTE: isObject and isInstance also return true, + * since they're objects of the Array<> class, so check this first! + */ + public static function isArray(a:Dynamic):Bool + { + return Std.is(a, Array); + } + + public static function isInstance(a:Dynamic):Bool + { + return Type.getClass(a) != null; + } + public static function isPrimitive(a:Dynamic):Bool { switch (Type.typeof(a)) @@ -89,6 +112,7 @@ class StructureUtil { if (a == null) return b; if (b == null) return null; + if (isArray(a) && isArray(b)) return b; if (isPrimitive(a) && isPrimitive(b)) return b; if (isMap(b)) { @@ -101,7 +125,6 @@ class StructureUtil return StructureUtil.toMap(a).merge(b); } } - if (!Reflect.isObject(a) || !Reflect.isObject(b)) return b; if (Std.isOfType(b, haxe.ds.StringMap)) { if (Std.isOfType(a, haxe.ds.StringMap)) @@ -113,15 +136,14 @@ class StructureUtil return StructureUtil.toMap(a).merge(b); } } + if (!isStructure(a) || !isStructure(b)) return b; var result:DynamicAccess = Reflect.copy(a); for (field in Reflect.fields(b)) { - if (Reflect.isObject(b)) + if (isStructure(b)) { - // Note that isObject also returns true for class instances, - // but we just assume that's not a problem here. result.set(field, deepMerge(Reflect.field(result, field), Reflect.field(b, field))); } else diff --git a/source/funkin/util/VersionUtil.hx b/source/funkin/util/VersionUtil.hx index 247ba19db4..8f55506627 100644 --- a/source/funkin/util/VersionUtil.hx +++ b/source/funkin/util/VersionUtil.hx @@ -32,6 +32,25 @@ class VersionUtil } } + public static function repairVersion(version:thx.semver.Version):thx.semver.Version + { + var versionData:thx.semver.Version.SemVer = version; + + if (StructureUtil.isStructure(versionData.version)) + { + // This is bad! versionData.version should be an array! + versionData.version = [versionData.version[0], versionData.version[1], versionData.version[2]]; + + var fixedVersion:thx.semver.Version = versionData; + return fixedVersion; + } + else + { + // No need for repair. + return version; + } + } + /** * Checks that a given verison number satisisfies a given version rule. * Version rule can be complex, e.g. "1.0.x" or ">=1.0.0,<1.1.0", or anything NPM supports. From 6cb58163787b6951fa6fffed01a48e444cd5b5f5 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 21 May 2024 02:49:07 -0400 Subject: [PATCH 046/266] Add freeplay favorites to the save data so they persist between sessions. --- source/funkin/input/Controls.hx | 2 +- source/funkin/save/Save.hx | 44 ++++++++++++++++++++-- source/funkin/save/changelog.md | 3 ++ source/funkin/ui/freeplay/FreeplayState.hx | 25 +++++++++++- 4 files changed, 68 insertions(+), 6 deletions(-) diff --git a/source/funkin/input/Controls.hx b/source/funkin/input/Controls.hx index 1983d413ba..cede0b6887 100644 --- a/source/funkin/input/Controls.hx +++ b/source/funkin/input/Controls.hx @@ -707,7 +707,7 @@ class Controls extends FlxActionSet case Control.VOLUME_UP: return [PLUS, NUMPADPLUS]; case Control.VOLUME_DOWN: return [MINUS, NUMPADMINUS]; case Control.VOLUME_MUTE: return [ZERO, NUMPADZERO]; - case Control.FULLSCREEN: return [FlxKey.F]; + case Control.FULLSCREEN: return [FlxKey.F11]; // We use F for other things LOL. } case Duo(true): diff --git a/source/funkin/save/Save.hx b/source/funkin/save/Save.hx index acbe59edda..7b2d3f5114 100644 --- a/source/funkin/save/Save.hx +++ b/source/funkin/save/Save.hx @@ -14,8 +14,7 @@ import funkin.util.SerializerUtil; @:nullSafety class Save { - // Version 2.0.2 adds attributes to `optionsChartEditor`, that should return default values if they are null. - public static final SAVE_DATA_VERSION:thx.semver.Version = "2.0.3"; + public static final SAVE_DATA_VERSION:thx.semver.Version = "2.0.4"; public static final SAVE_DATA_VERSION_RULE:thx.semver.VersionRule = "2.0.x"; // We load this version's saves from a new save path, to maintain SOME level of backwards compatibility. @@ -53,7 +52,8 @@ class Save public function new(?data:RawSaveData) { if (data == null) this.data = Save.getDefault(); - else this.data = data; + else + this.data = data; } public static function getDefault():RawSaveData @@ -77,6 +77,9 @@ class Save levels: [], songs: [], }, + + favoriteSongs: [], + options: { // Reasonable defaults. @@ -554,6 +557,35 @@ class Save return false; } + public function isSongFavorited(id:String):Bool + { + if (data.favoriteSongs == null) + { + data.favoriteSongs = []; + flush(); + }; + + return data.favoriteSongs.contains(id); + } + + public function favoriteSong(id:String):Void + { + if (!isSongFavorited(id)) + { + data.favoriteSongs.push(id); + flush(); + } + } + + public function unfavoriteSong(id:String):Void + { + if (isSongFavorited(id)) + { + data.favoriteSongs.remove(id); + flush(); + } + } + public function getControls(playerId:Int, inputType:Device):Null { switch (inputType) @@ -740,6 +772,12 @@ typedef RawSaveData = */ var options:SaveDataOptions; + /** + * The user's favorited songs in the Freeplay menu, + * as a list of song IDs. + */ + var favoriteSongs:Array; + var mods:SaveDataMods; /** diff --git a/source/funkin/save/changelog.md b/source/funkin/save/changelog.md index 3fa9839d1c..7c9094f2dd 100644 --- a/source/funkin/save/changelog.md +++ b/source/funkin/save/changelog.md @@ -5,6 +5,9 @@ All notable changes to this project 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). +## [2.0.4] - 2024-05-21 +### Added +- `favoriteSongs:Array` to `Save` ## [2.0.3] - 2024-01-09 ### Added diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 2390682889..911d07a568 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -699,8 +699,8 @@ class FreeplayState extends MusicBeatSubState if (targetSong != null) { var realShit:Int = curSelected; - targetSong.isFav = !targetSong.isFav; - if (targetSong.isFav) + var isFav = targetSong.toggleFavorite(); + if (isFav) { FlxTween.tween(grpCapsules.members[realShit], {angle: 360}, 0.4, { @@ -1398,11 +1398,32 @@ class FreeplaySongData this.levelId = levelId; this.songId = songId; this.song = song; + + this.isFav = Save.instance.isSongFavorited(songId); + if (displayedVariations != null) this.displayedVariations = displayedVariations; updateValues(displayedVariations); } + /** + * Toggle whether or not the song is favorited, then flush to save data. + * @return Whether or not the song is now favorited. + */ + public function toggleFavorite():Bool + { + isFav = !isFav; + if (isFav) + { + Save.instance.favoriteSong(this.songId); + } + else + { + Save.instance.unfavoriteSong(this.songId); + } + return isFav; + } + function updateValues(variations:Array):Void { this.songDifficulties = song.listDifficulties(variations, false, false); From fed6d1146c67b048f2c9b82d3b50a7dd9cd1748f Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 21 May 2024 04:02:32 -0400 Subject: [PATCH 047/266] Do some cleanup (replace several utility functions with a utility library we already depend on!) --- Project.xml | 1 + source/funkin/import.hx | 1 + source/funkin/play/song/Song.hx | 16 +- .../funkin/save/migrator/SaveDataMigrator.hx | 5 +- source/funkin/ui/story/LevelProp.hx | 5 +- source/funkin/util/StructureUtil.hx | 158 ------------------ source/funkin/util/tools/ArrayTools.hx | 66 -------- 7 files changed, 17 insertions(+), 235 deletions(-) delete mode 100644 source/funkin/util/StructureUtil.hx diff --git a/Project.xml b/Project.xml index fcfcfb9f35..b5630a46ab 100644 --- a/Project.xml +++ b/Project.xml @@ -128,6 +128,7 @@ + diff --git a/source/funkin/import.hx b/source/funkin/import.hx index 250de99cb2..c8431be33b 100644 --- a/source/funkin/import.hx +++ b/source/funkin/import.hx @@ -11,6 +11,7 @@ import flixel.system.debug.watch.Tracker; // These are great. using Lambda; using StringTools; +using thx.Arrays; using funkin.util.tools.ArraySortTools; using funkin.util.tools.ArrayTools; using funkin.util.tools.FloatTools; diff --git a/source/funkin/play/song/Song.hx b/source/funkin/play/song/Song.hx index 23d8d21986..53408fb34d 100644 --- a/source/funkin/play/song/Song.hx +++ b/source/funkin/play/song/Song.hx @@ -439,12 +439,16 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry = difficulties.keys().array().map(function(diffId:String):Null { - var difficulty:Null = difficulties.get(diffId); - if (difficulty == null) return null; - if (variationIds.length > 0 && !variationIds.contains(difficulty.variation)) return null; - return difficulty.difficulty; - }).nonNull().unique(); + var diffFiltered:Array = difficulties.keys() + .array() + .map(function(diffId:String):Null { + var difficulty:Null = difficulties.get(diffId); + if (difficulty == null) return null; + if (variationIds.length > 0 && !variationIds.contains(difficulty.variation)) return null; + return difficulty.difficulty; + }) + .filterNull() + .distinct(); diffFiltered = diffFiltered.filter(function(diffId:String):Bool { if (showHidden) return true; diff --git a/source/funkin/save/migrator/SaveDataMigrator.hx b/source/funkin/save/migrator/SaveDataMigrator.hx index 7f597b4ec9..5398b21198 100644 --- a/source/funkin/save/migrator/SaveDataMigrator.hx +++ b/source/funkin/save/migrator/SaveDataMigrator.hx @@ -28,8 +28,9 @@ class SaveDataMigrator version = VersionUtil.repairVersion(version); if (VersionUtil.validateVersion(version, Save.SAVE_DATA_VERSION_RULE)) { - // Simply import the structured data. - var save:Save = new Save(StructureUtil.deepMerge(Save.getDefault(), inputData)); + // Import the structured data. + var saveDataWithDefaults:RawSaveData = thx.Objects.deepCombine(Save.getDefault(), inputData); + var save:Save = new Save(saveDataWithDefaults); return save; } else diff --git a/source/funkin/ui/story/LevelProp.hx b/source/funkin/ui/story/LevelProp.hx index ffc756e1cb..5a3efc36ae 100644 --- a/source/funkin/ui/story/LevelProp.hx +++ b/source/funkin/ui/story/LevelProp.hx @@ -13,11 +13,10 @@ class LevelProp extends Bopper // Only reset the prop if the asset path has changed. if (propData == null || value?.assetPath != propData?.assetPath) { - this.visible = (value != null); - this.propData = value; - danceEvery = this.propData?.danceEvery ?? 0; applyData(); } + this.visible = (value != null); + danceEvery = this.propData?.danceEvery ?? 0; return this.propData; } diff --git a/source/funkin/util/StructureUtil.hx b/source/funkin/util/StructureUtil.hx deleted file mode 100644 index 2a6b345d36..0000000000 --- a/source/funkin/util/StructureUtil.hx +++ /dev/null @@ -1,158 +0,0 @@ -package funkin.util; - -import funkin.util.tools.MapTools; -import haxe.DynamicAccess; - -/** - * Utilities for working with anonymous structures. - */ -class StructureUtil -{ - /** - * Merge two structures, with the second overwriting the first. - * Performs a SHALLOW clone, where child structures are not merged. - * @param a The base structure. - * @param b The new structure. - * @return The merged structure. - */ - public static function merge(a:Dynamic, b:Dynamic):Dynamic - { - var result:DynamicAccess = Reflect.copy(a); - - for (field in Reflect.fields(b)) - { - result.set(field, Reflect.field(b, field)); - } - - return result; - } - - public static function toMap(a:Dynamic):haxe.ds.Map - { - var result:haxe.ds.Map = []; - - for (field in Reflect.fields(a)) - { - result.set(field, Reflect.field(a, field)); - } - - return result; - } - - public static function isMap(a:Dynamic):Bool - { - return Std.isOfType(a, haxe.Constraints.IMap); - } - - /** - * Returns `true` if `a` is an anonymous structure. - * I believe this returns `false` even for class instances and arrays. - */ - public static function isStructure(a:Dynamic):Bool - { - // TODO: Is there a difference? - // return Reflect.isObject(foo); - - switch (Type.typeof(a)) - { - case TObject: - return true; - default: - return false; - } - } - - /** - * Returns true if `a` is an array. - * - * NOTE: isObject and isInstance also return true, - * since they're objects of the Array<> class, so check this first! - */ - public static function isArray(a:Dynamic):Bool - { - return Std.is(a, Array); - } - - public static function isInstance(a:Dynamic):Bool - { - return Type.getClass(a) != null; - } - - public static function isPrimitive(a:Dynamic):Bool - { - switch (Type.typeof(a)) - { - case TInt | TFloat | TBool: - return true; - case TClass(c): - return false; - case TEnum(e): - return false; - case TObject: - return false; - case TFunction: - return false; - case TNull: - return true; - case TUnknown: - return false; - default: - return false; - } - } - - /** - * Merge two structures, with the second overwriting the first. - * Performs a DEEP clone, where child structures are also merged recursively. - * @param a The base structure. - * @param b The new structure. - * @return The merged structure. - */ - public static function deepMerge(a:Dynamic, b:Dynamic):Dynamic - { - if (a == null) return b; - if (b == null) return null; - if (isArray(a) && isArray(b)) return b; - if (isPrimitive(a) && isPrimitive(b)) return b; - if (isMap(b)) - { - if (isMap(a)) - { - return MapTools.merge(a, b); - } - else - { - return StructureUtil.toMap(a).merge(b); - } - } - if (Std.isOfType(b, haxe.ds.StringMap)) - { - if (Std.isOfType(a, haxe.ds.StringMap)) - { - return MapTools.merge(a, b); - } - else - { - return StructureUtil.toMap(a).merge(b); - } - } - if (!isStructure(a) || !isStructure(b)) return b; - - var result:DynamicAccess = Reflect.copy(a); - - for (field in Reflect.fields(b)) - { - if (isStructure(b)) - { - result.set(field, deepMerge(Reflect.field(result, field), Reflect.field(b, field))); - } - else - { - // If we're here, b[field] is a primitive. - result.set(field, Reflect.field(b, field)); - } - } - - return result; - } -} diff --git a/source/funkin/util/tools/ArrayTools.hx b/source/funkin/util/tools/ArrayTools.hx index caf8e8aab5..0fe245e3a4 100644 --- a/source/funkin/util/tools/ArrayTools.hx +++ b/source/funkin/util/tools/ArrayTools.hx @@ -5,72 +5,6 @@ package funkin.util.tools; */ class ArrayTools { - /** - * Returns a copy of the array with all duplicate elements removed. - * @param array The array to remove duplicates from. - * @return A copy of the array with all duplicate elements removed. - */ - public static function unique(array:Array):Array - { - var result:Array = []; - for (element in array) - { - if (!result.contains(element)) - { - result.push(element); - } - } - return result; - } - - /** - * Returns a copy of the array with all `null` elements removed. - * @param array The array to remove `null` elements from. - * @return A copy of the array with all `null` elements removed. - */ - public static function nonNull(array:Array>):Array - { - var result:Array = []; - for (element in array) - { - if (element != null) - { - result.push(element); - } - } - return result; - } - - /** - * Return the first element of the array that satisfies the predicate, or null if none do. - * @param input The array to search - * @param predicate The predicate to call - * @return The result - */ - public static function find(input:Array, predicate:T->Bool):Null - { - for (element in input) - { - if (predicate(element)) return element; - } - return null; - } - - /** - * Return the index of the first element of the array that satisfies the predicate, or `-1` if none do. - * @param input The array to search - * @param predicate The predicate to call - * @return The index of the result - */ - public static function findIndex(input:Array, predicate:T->Bool):Int - { - for (index in 0...input.length) - { - if (predicate(input[index])) return index; - } - return -1; - } - /* * Push an element to the array if it is not already present. * @param input The array to push to From 6d3b58cecdb3b3881e261a3137518926835fd7a5 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 21 May 2024 04:02:53 -0400 Subject: [PATCH 048/266] Fix some additional compiling issues. --- source/funkin/save/migrator/SaveDataMigrator.hx | 3 +-- source/funkin/util/VersionUtil.hx | 2 +- source/funkin/util/macro/InlineMacro.hx | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/source/funkin/save/migrator/SaveDataMigrator.hx b/source/funkin/save/migrator/SaveDataMigrator.hx index 5398b21198..650666c5c4 100644 --- a/source/funkin/save/migrator/SaveDataMigrator.hx +++ b/source/funkin/save/migrator/SaveDataMigrator.hx @@ -3,7 +3,6 @@ package funkin.save.migrator; import funkin.save.Save; import funkin.save.migrator.RawSaveData_v1_0_0; import thx.semver.Version; -import funkin.util.StructureUtil; import funkin.util.VersionUtil; @:nullSafety @@ -29,7 +28,7 @@ class SaveDataMigrator if (VersionUtil.validateVersion(version, Save.SAVE_DATA_VERSION_RULE)) { // Import the structured data. - var saveDataWithDefaults:RawSaveData = thx.Objects.deepCombine(Save.getDefault(), inputData); + var saveDataWithDefaults:RawSaveData = cast thx.Objects.deepCombine(Save.getDefault(), inputData); var save:Save = new Save(saveDataWithDefaults); return save; } diff --git a/source/funkin/util/VersionUtil.hx b/source/funkin/util/VersionUtil.hx index 8f55506627..18d7eafa66 100644 --- a/source/funkin/util/VersionUtil.hx +++ b/source/funkin/util/VersionUtil.hx @@ -36,7 +36,7 @@ class VersionUtil { var versionData:thx.semver.Version.SemVer = version; - if (StructureUtil.isStructure(versionData.version)) + if (thx.Types.isAnonymousObject(versionData.version)) { // This is bad! versionData.version should be an array! versionData.version = [versionData.version[0], versionData.version[1], versionData.version[2]]; diff --git a/source/funkin/util/macro/InlineMacro.hx b/source/funkin/util/macro/InlineMacro.hx index b0e7ed1847..c402574098 100644 --- a/source/funkin/util/macro/InlineMacro.hx +++ b/source/funkin/util/macro/InlineMacro.hx @@ -23,7 +23,7 @@ class InlineMacro var fields:Array = haxe.macro.Context.getBuildFields(); // Find the field with the given name. - var targetField:Null = fields.find(function(f) return f.name == field + var targetField:Null = thx.Arrays.find(fields, function(f) return f.name == field && (MacroUtil.isFieldStatic(f) == isStatic)); // If the field was not found, throw an error. From 4e47bfe68b056656c24355c2ff90042db3a62744 Mon Sep 17 00:00:00 2001 From: Keoiki <55053690+Keoiki@users.noreply.github.com> Date: Tue, 21 May 2024 23:52:40 +0300 Subject: [PATCH 049/266] Fix Note Styles in PlayState & Chart Editor --- source/funkin/play/PlayState.hx | 7 +------ .../debug/charting/toolboxes/ChartEditorMetadataToolbox.hx | 2 ++ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 43dd485cf9..dc07e19103 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -1730,12 +1730,7 @@ class PlayState extends MusicBeatSubState */ function initStrumlines():Void { - var noteStyleId:String = switch (currentStageId) - { - case 'school': 'pixel'; - case 'schoolEvil': 'pixel'; - default: Constants.DEFAULT_NOTE_STYLE; - } + var noteStyleId:String = currentChart.noteStyle; var noteStyle:NoteStyle = NoteStyleRegistry.instance.fetchEntry(noteStyleId); if (noteStyle == null) noteStyle = NoteStyleRegistry.instance.fetchDefault(); diff --git a/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx b/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx index f85307c64f..98e263aaf9 100644 --- a/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx +++ b/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx @@ -104,6 +104,8 @@ class ChartEditorMetadataToolbox extends ChartEditorBaseToolbox if (event.data?.id == null) return; chartEditorState.currentSongNoteStyle = event.data.id; }; + var startingValueNoteStyle = ChartEditorDropdowns.populateDropdownWithNoteStyles(inputNoteStyle, chartEditorState.currentSongMetadata.playData.noteStyle); + inputNoteStyle.value = startingValueNoteStyle; inputBPM.onChange = function(event:UIEvent) { if (event.value == null || event.value <= 0) return; From f17f6393041a54e4b15418059f6a9ff9dc2a39cb Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 22 May 2024 01:07:20 -0400 Subject: [PATCH 050/266] Finish implementing smaller numbers. --- assets | 2 +- source/funkin/InitState.hx | 4 +- source/funkin/play/ResultState.hx | 75 ++++++++++++++++--- .../play/components/ClearPercentCounter.hx | 73 ++++++++++++++---- 4 files changed, 124 insertions(+), 30 deletions(-) diff --git a/assets b/assets index ce7dabffbe..b6d930109e 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit ce7dabffbebc154c9dda1f01e92dbef83e3405ab +Subproject commit b6d930109eb69cfd368145e893d81ac1e97ed004 diff --git a/source/funkin/InitState.hx b/source/funkin/InitState.hx index 6a52eaf5d8..d17554d11e 100644 --- a/source/funkin/InitState.hx +++ b/source/funkin/InitState.hx @@ -227,14 +227,14 @@ class InitState extends FlxState tallies: { sick: 130, - good: 69, + good: 70, bad: 69, shit: 69, missed: 69, combo: 69, maxCombo: 69, totalNotesHit: 140, - totalNotes: 2000, + totalNotes: 200 // 0, } }, })); diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx index d038b77854..fdcd0cc397 100644 --- a/source/funkin/play/ResultState.hx +++ b/source/funkin/play/ResultState.hx @@ -37,6 +37,7 @@ class ResultState extends MusicBeatSubState final rank:ResultRank; final songName:FlxBitmapText; final difficulty:FlxSprite; + final clearPercentSmall:ClearPercentCounter; final maskShaderSongName:LeftMaskShader = new LeftMaskShader(); final maskShaderDifficulty:LeftMaskShader = new LeftMaskShader(); @@ -78,6 +79,10 @@ class ResultState extends MusicBeatSubState difficulty = new FlxSprite(555); difficulty.zIndex = 1000; + clearPercentSmall = new ClearPercentCounter(FlxG.width / 2 + 300, FlxG.height / 2 - 100, 100, true); + clearPercentSmall.zIndex = 1000; + clearPercentSmall.visible = false; + bgFlash = FlxGradient.createGradientFlxSprite(FlxG.width, FlxG.height, [0xFFFFEB69, 0xFFFFE66A], 90); resultsAnim = FunkinSprite.createSparrow(-200, -10, "resultScreen/results"); @@ -194,7 +199,7 @@ class ResultState extends MusicBeatSubState speedOfTween.x = -1.0 * Math.cos(angleRad); speedOfTween.y = -1.0 * Math.sin(angleRad); - timerThenSongName(1.0); + timerThenSongName(1.0, false); songName.shader = maskShaderSongName; difficulty.shader = maskShaderDifficulty; @@ -319,13 +324,15 @@ class ResultState extends MusicBeatSubState function startRankTallySequence():Void { - clearPercentTarget = Math.floor((params.scoreData.tallies.sick + params.scoreData.tallies.good) / params.scoreData.tallies.totalNotes * 100); - clearPercentTarget = 100; + var clearPercentFloat = (params.scoreData.tallies.sick + params.scoreData.tallies.good) / params.scoreData.tallies.totalNotes * 100; + clearPercentTarget = Math.floor(clearPercentFloat); + // Prevent off-by-one errors. clearPercentLerp = Std.int(Math.max(0, clearPercentTarget - 36)); - var clearPercentCounter:ClearPercentCounter = new ClearPercentCounter(FlxG.width / 2 + 300, FlxG.height / 2 - 100, clearPercentTarget); - clearPercentCounter.curNumber = clearPercentLerp; + trace('Clear percent target: ' + clearPercentFloat + ', round: ' + clearPercentTarget); + + var clearPercentCounter:ClearPercentCounter = new ClearPercentCounter(FlxG.width / 2 + 300, FlxG.height / 2 - 100, clearPercentLerp); FlxTween.tween(clearPercentCounter, {curNumber: clearPercentTarget}, 1.5, { ease: FlxEase.quartOut, @@ -345,10 +352,25 @@ class ResultState extends MusicBeatSubState bgFlash.visible = true; FlxTween.tween(bgFlash, {alpha: 0}, 0.4); + // Just to be sure that the lerp didn't mess things up. + clearPercentCounter.curNumber = clearPercentTarget; + + clearPercentCounter.flash(true); + new FlxTimer().start(0.4, _ -> { + clearPercentCounter.flash(false); + }); + displayRankText(); new FlxTimer().start(2.0, _ -> { - // remove(clearPercentCounter); + FlxTween.tween(clearPercentCounter, {alpha: 0}, 0.5, + { + startDelay: 0.5, + ease: FlxEase.quartOut, + onComplete: _ -> { + remove(clearPercentCounter); + } + }); afterRankTallySequence(); }); @@ -406,6 +428,8 @@ class ResultState extends MusicBeatSubState function afterRankTallySequence():Void { + showSmallClearPercent(); + FunkinSound.playMusic(rank.getMusicPath(), { startingVolume: 1.0, @@ -490,7 +514,7 @@ class ResultState extends MusicBeatSubState } } - function timerThenSongName(timerLength:Float = 3.0):Void + function timerThenSongName(timerLength:Float = 3.0, autoScroll:Bool = true):Void { movingSongStuff = false; @@ -501,10 +525,17 @@ class ResultState extends MusicBeatSubState difficulty.y = -difficulty.height; FlxTween.tween(difficulty, {y: diffYTween}, 0.5, {ease: FlxEase.expoOut, startDelay: 0.8}); + if (clearPercentSmall != null) + { + clearPercentSmall.x = (difficulty.x + difficulty.width) + 60; + clearPercentSmall.y = -clearPercentSmall.height; + FlxTween.tween(clearPercentSmall, {y: 122 - 5}, 0.5, {ease: FlxEase.expoOut, startDelay: 0.8}); + } + songName.y = -songName.height; var fuckedupnumber = (10) * (songName.text.length / 15); - FlxTween.tween(songName, {y: diffYTween - 35 - fuckedupnumber}, 0.5, {ease: FlxEase.expoOut, startDelay: 0.9}); - songName.x = (difficulty.x + difficulty.width) + 20; + FlxTween.tween(songName, {y: diffYTween - 25 - fuckedupnumber}, 0.5, {ease: FlxEase.expoOut, startDelay: 0.9}); + songName.x = clearPercentSmall.x + clearPercentSmall.width - 30; new FlxTimer().start(timerLength, _ -> { var tempSpeed = FlxPoint.get(speedOfTween.x, speedOfTween.y); @@ -512,10 +543,29 @@ class ResultState extends MusicBeatSubState speedOfTween.set(0, 0); FlxTween.tween(speedOfTween, {x: tempSpeed.x, y: tempSpeed.y}, 0.7, {ease: FlxEase.quadIn}); - movingSongStuff = true; + movingSongStuff = (autoScroll); }); } + function showSmallClearPercent():Void + { + if (clearPercentSmall != null) + { + add(clearPercentSmall); + clearPercentSmall.visible = true; + clearPercentSmall.flash(true); + new FlxTimer().start(0.4, _ -> { + clearPercentSmall.flash(false); + }); + + clearPercentSmall.curNumber = clearPercentTarget; + clearPercentSmall.zIndex = 1000; + refresh(); + } + + movingSongStuff = true; + } + var movingSongStuff:Bool = false; var speedOfTween:FlxPoint = FlxPoint.get(-1, 1); @@ -523,7 +573,8 @@ class ResultState extends MusicBeatSubState { super.draw(); - songName.clipRect = FlxRect.get(Math.max(0, 540 - songName.x), 0, FlxG.width, songName.height); + songName.clipRect = FlxRect.get(Math.max(0, 520 - songName.x), 0, FlxG.width, songName.height); + // PROBABLY SHOULD FIX MEMORY FREE OR WHATEVER THE PUT() FUNCTION DOES !!!! FEELS LIKE IT STUTTERS!!! // if (songName != null && songName.frame != null) @@ -539,8 +590,10 @@ class ResultState extends MusicBeatSubState { songName.x += speedOfTween.x; difficulty.x += speedOfTween.x; + clearPercentSmall.x += speedOfTween.x; songName.y += speedOfTween.y; difficulty.y += speedOfTween.y; + clearPercentSmall.y += speedOfTween.y; if (songName.x + songName.width < 100) { diff --git a/source/funkin/play/components/ClearPercentCounter.hx b/source/funkin/play/components/ClearPercentCounter.hx index 4c03ec3a90..d296b0b0b1 100644 --- a/source/funkin/play/components/ClearPercentCounter.hx +++ b/source/funkin/play/components/ClearPercentCounter.hx @@ -1,6 +1,7 @@ package funkin.play.components; import funkin.graphics.FunkinSprite; +import funkin.graphics.shaders.PureColor; import flixel.FlxSprite; import flixel.group.FlxGroup.FlxTypedGroup; import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; @@ -9,25 +10,54 @@ import flixel.tweens.FlxEase; import flixel.tweens.FlxTween; import flixel.text.FlxText.FlxTextAlign; import funkin.util.MathUtil; +import flixel.util.FlxColor; /** * Numerical counters used to display the clear percent. */ class ClearPercentCounter extends FlxTypedSpriteGroup { - public var curNumber:Int = 0; - public var neededNumber:Int = 0; + public var curNumber(default, set):Int = 0; - public function new(x:Float, y:Float, neededNumber:Int = 0) + var numberChanged:Bool = false; + + function set_curNumber(val:Int):Int + { + numberChanged = true; + return curNumber = val; + } + + var small:Bool = false; + var flashShader:PureColor; + + public function new(x:Float, y:Float, startingNumber:Int = 0, small:Bool = false) { super(x, y); - this.neededNumber = neededNumber; + flashShader = new PureColor(FlxColor.WHITE); + flashShader.colorSet = true; + + curNumber = startingNumber; - var clearPercentText:FunkinSprite = FunkinSprite.create(0, 0, 'resultScreen/clearPercent/clearPercentText'); + this.small = small; + + var clearPercentText:FunkinSprite = FunkinSprite.create(0, 0, 'resultScreen/clearPercent/clearPercentText${small ? 'Small' : ''}'); + clearPercentText.x = small ? 40 : 0; add(clearPercentText); - if (curNumber == neededNumber) drawNumbers(); + drawNumbers(); + } + + /** + * Make the counter flash turn white or stop being all white. + * @param enabled Whether the counter should be white. + */ + public function flash(enabled:Bool):Void + { + for (member in members) + { + member.shader = enabled ? flashShader : null; + } } var tmr:Float = 0; @@ -36,7 +66,7 @@ class ClearPercentCounter extends FlxTypedSpriteGroup { super.update(elapsed); - if (curNumber < neededNumber) drawNumbers(); + if (numberChanged) drawNumbers(); } function drawNumbers() @@ -44,8 +74,6 @@ class ClearPercentCounter extends FlxTypedSpriteGroup var seperatedScore:Array = []; var tempCombo:Int = Math.round(curNumber); - var fullNumberDigits:Int = Std.int(Math.max(1, Math.ceil(MathUtil.logBase(10, neededNumber)))); - while (tempCombo != 0) { seperatedScore.push(tempCombo % 10); @@ -59,19 +87,32 @@ class ClearPercentCounter extends FlxTypedSpriteGroup for (ind => num in seperatedScore) { var digitIndex = ind + 1; + // If there's only one digit, move it to the right + // If there's three digits, move them all to the left + var digitOffset = (seperatedScore.length == 1) ? 1 : (seperatedScore.length == 3) ? -1 : 0; + var digitSize = small ? 32 : 72; + var digitHeightOffset = small ? -4 : 0; + + var xPos = (digitIndex - 1 + digitOffset) * (digitSize * this.scale.x); + xPos += small ? -24 : 0; + var yPos = (digitIndex - 1 + digitOffset) * (digitHeightOffset * this.scale.y); + yPos += small ? 0 : 72; + if (digitIndex >= members.length) { - var xPos = (digitIndex - 1) * (72 * this.scale.x); - var yPos = 72; - // Three digits = LRL so two different numbers aren't adjacent to each other. - var variant:Bool = (fullNumberDigits % 2 != 0) ? (digitIndex % 2 == 0) : (digitIndex % 2 == 1); - var numb:ClearPercentNumber = new ClearPercentNumber(xPos, yPos, num); + // Three digits = LLR because the 1 and 0 won't be the same anyway. + var variant:Bool = (seperatedScore.length == 3) ? (digitIndex >= 2) : (digitIndex >= 1); + // var variant:Bool = (seperatedScore.length % 2 != 0) ? (digitIndex % 2 == 0) : (digitIndex % 2 == 1); + var numb:ClearPercentNumber = new ClearPercentNumber(xPos, yPos, num, variant, this.small); numb.scale.set(this.scale.x, this.scale.y); add(numb); } else { members[digitIndex].animation.play(Std.string(num)); + // Reset the position of the number + members[digitIndex].x = xPos + this.x; + members[digitIndex].y = yPos + this.y; } } } @@ -79,11 +120,11 @@ class ClearPercentCounter extends FlxTypedSpriteGroup class ClearPercentNumber extends FlxSprite { - public function new(x:Float, y:Float, digit:Int, variant:Bool = false) + public function new(x:Float, y:Float, digit:Int, variant:Bool, small:Bool) { super(x, y); - frames = Paths.getSparrowAtlas('resultScreen/clearPercent/clearPercentNumber${variant ? 'Right' : 'Left'}'); + frames = Paths.getSparrowAtlas('resultScreen/clearPercent/clearPercentNumber${small ? 'Small' : variant ? 'Right' : 'Left'}'); for (i in 0...10) { From d84e832c6c9152abab106290dab72e5792fc6808 Mon Sep 17 00:00:00 2001 From: sector-a <82838084+sector-a@users.noreply.github.com> Date: Wed, 22 May 2024 12:57:57 +0300 Subject: [PATCH 051/266] Make texts update on difficulty change in Story Menu --- source/funkin/ui/story/StoryMenuState.hx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/funkin/ui/story/StoryMenuState.hx b/source/funkin/ui/story/StoryMenuState.hx index 0c22145294..820ac2ad14 100644 --- a/source/funkin/ui/story/StoryMenuState.hx +++ b/source/funkin/ui/story/StoryMenuState.hx @@ -466,6 +466,9 @@ class StoryMenuState extends MusicBeatState // Disable the funny music thing for now. // funnyMusicThing(); } + + updateText(); + refresh(); } final FADE_OUT_TIME:Float = 1.5; From 9afc314a0d20f29d69beba70d91d23cc37922660 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 22 May 2024 15:20:53 -0400 Subject: [PATCH 052/266] Fix an issue with git modules --- .gitmodules | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index be5e0aaa81..2d5c11067d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,5 @@ [submodule "assets"] path = assets - url = https://github.com/FunkinCrew/funkin.assets -[submodule "art"] + url = https://github.com/FunkinCrew/Funkin-Assets-secret path = art - url = https://github.com/FunkinCrew/funkin.art + url = https://github.com/FunkinCrew/Funkin-Art-secret From 5e130eeffcecf2746b222930f2d801faed5a4c64 Mon Sep 17 00:00:00 2001 From: gamerbross <55158797+gamerbross@users.noreply.github.com> Date: Thu, 23 May 2024 18:18:37 +0200 Subject: [PATCH 053/266] Add Winning support to Legacy Health Icons --- source/funkin/play/components/HealthIcon.hx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/funkin/play/components/HealthIcon.hx b/source/funkin/play/components/HealthIcon.hx index 957daa43c9..ded00f3783 100644 --- a/source/funkin/play/components/HealthIcon.hx +++ b/source/funkin/play/components/HealthIcon.hx @@ -373,6 +373,10 @@ class HealthIcon extends FunkinSprite // Don't flip BF's icon here! That's done later. this.animation.add(Idle, [0], 0, false, false); this.animation.add(Losing, [1], 0, false, false); + if (animation.numFrames >= 3) + { + this.animation.add(Winning, [2], 0, false, false); + } } function correctCharacterId(charId:Null):String From 1c352e4e114ed997f842d638ad0483b5a5554cae Mon Sep 17 00:00:00 2001 From: richTrash21 Date: Thu, 23 May 2024 21:50:11 +0400 Subject: [PATCH 054/266] simplify freeplay camera --- source/funkin/ui/freeplay/FreeplayState.hx | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 2f8231bb0f..2dea923529 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -156,6 +156,12 @@ class FreeplayState extends MusicBeatSubState FlxTransitionableState.skipNextTransIn = true; + // dedicated camera for the state so we don't need to fuk around with camera scrolls from the mainmenu / elsewhere + funnyCam = new FunkinCamera('freeplayFunny', 0, 0, FlxG.width, FlxG.height); + funnyCam.bgColor = FlxColor.TRANSPARENT; + FlxG.cameras.add(funnyCam, false); + this.cameras = [funnyCam]; + if (stickerSubState != null) { this.persistentUpdate = true; @@ -534,15 +540,6 @@ class FreeplayState extends MusicBeatSubState }); generateSongList(null, false); - - // dedicated camera for the state so we don't need to fuk around with camera scrolls from the mainmenu / elsewhere - funnyCam = new FunkinCamera('freeplayFunny', 0, 0, FlxG.width, FlxG.height); - funnyCam.bgColor = FlxColor.TRANSPARENT; - FlxG.cameras.add(funnyCam, false); - - forEach(function(bs) { - bs.cameras = [funnyCam]; - }); } var currentFilter:SongFilter = null; From 4ca30a571d46607c7fa3454bd00c7e16977eb10f Mon Sep 17 00:00:00 2001 From: richTrash21 Date: Thu, 23 May 2024 21:52:28 +0400 Subject: [PATCH 055/266] safety --- source/funkin/ui/freeplay/FreeplayState.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 2dea923529..4d1ad70194 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -536,7 +536,7 @@ class FreeplayState extends MusicBeatSubState grpTxtScrolls.visible = true; // render optimisation - _parentState.persistentDraw = false; + if (_parentState != null) _parentState.persistentDraw = false; }); generateSongList(null, false); From a2ee359e466746646c278d0adbef0c1fd08d21c1 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Thu, 23 May 2024 16:31:18 -0400 Subject: [PATCH 056/266] fix for songs overlapping each other on desktop --- source/funkin/audio/FunkinSound.hx | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/source/funkin/audio/FunkinSound.hx b/source/funkin/audio/FunkinSound.hx index 5a49e29eea..aaddda9dcb 100644 --- a/source/funkin/audio/FunkinSound.hx +++ b/source/funkin/audio/FunkinSound.hx @@ -364,10 +364,20 @@ class FunkinSound extends FlxSound implements ICloneable if (music != null) { + for (future in partialQueue) + { + future = cast Future.withError("Music was overridden by another partial load"); + } + partialQueue = []; + partialQueue.push(music); + + @:nullSafety(Off) music.onComplete(function(partialMusic:Null) { - @:nullSafety(Off) - FlxG.sound.music = partialMusic; - FlxG.sound.list.remove(FlxG.sound.music); + if (partialQueue.pop() == music) + { + FlxG.sound.music = partialMusic; + FlxG.sound.list.remove(FlxG.sound.music); + } }); return true; @@ -396,6 +406,8 @@ class FunkinSound extends FlxSound implements ICloneable } } + static var partialQueue:Array>> = []; + /** * Creates a new `FunkinSound` object synchronously. * @@ -461,6 +473,8 @@ class FunkinSound extends FlxSound implements ICloneable * @param looped Whether the sound file should loop * @param autoDestroy Whether the sound file should be destroyed after it finishes playing * @param autoPlay Whether the sound file should play immediately + * @param onComplete Callback when the sound finishes playing + * @param onLoad Callback when the sound finishes loading * @return A FunkinSound object */ public static function loadPartial(path:String, start:Float = 0, end:Float = 1, volume:Float = 1.0, looped:Bool = false, autoDestroy:Bool = false, From 44880fa5697ddf16a62211cd4089d63371acaf46 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 24 May 2024 00:06:26 -0400 Subject: [PATCH 057/266] Implement placeholder GREAT animation --- source/funkin/InitState.hx | 2 +- source/funkin/play/ResultState.hx | 29 +++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/source/funkin/InitState.hx b/source/funkin/InitState.hx index d17554d11e..a945c10c54 100644 --- a/source/funkin/InitState.hx +++ b/source/funkin/InitState.hx @@ -227,7 +227,7 @@ class InitState extends FlxState tallies: { sick: 130, - good: 70, + good: 25, bad: 69, shit: 69, missed: 69, diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx index fdcd0cc397..ee7c8eade5 100644 --- a/source/funkin/play/ResultState.hx +++ b/source/funkin/play/ResultState.hx @@ -53,6 +53,7 @@ class ResultState extends MusicBeatSubState var bfPerfect:Null = null; var bfExcellent:Null = null; + var bfGreat:Null = null; var bfGood:Null = null; var gfGood:Null = null; var bfShit:Null = null; @@ -151,7 +152,20 @@ class ResultState extends MusicBeatSubState } }); - case GOOD | GREAT: + case GREAT: + bfGreat = new FlxAtlasSprite(640, 200, Paths.animateAtlas("resultScreen/results-bf/resultsGREAT", "shared")); + bfGreat.visible = false; + bfGreat.zIndex = 500; + add(bfGreat); + + bfGreat.onAnimationFinish.add((animName) -> { + if (bfGreat != null) + { + bfGreat.playAnimation('Loop Start'); + } + }); + + case GOOD: gfGood = FunkinSprite.createSparrow(625, 325, 'resultScreen/results-bf/resultsGOOD/resultGirlfriendGOOD'); gfGood.animation.addByPrefix("clap", "Girlfriend Good Anim", 24, false); gfGood.visible = false; @@ -476,6 +490,17 @@ class ResultState extends MusicBeatSubState bfExcellent.playAnimation('Intro'); } + case GREAT: + if (bfGreat == null) + { + trace("Could not build GREAT animation!"); + } + else + { + bfGreat.visible = true; + bfGreat.playAnimation('Intro'); + } + case SHIT: if (bfShit == null) { @@ -487,7 +512,7 @@ class ResultState extends MusicBeatSubState bfShit.playAnimation('Intro'); } - case GREAT | GOOD: + case GOOD: if (bfGood == null) { trace("Could not build GOOD animation!"); From 2db99b3cb41bef826bd3a286ac0d942476dc5eee Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 24 May 2024 00:06:52 -0400 Subject: [PATCH 058/266] Update submodule --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index b6d930109e..2a57e34061 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit b6d930109eb69cfd368145e893d81ac1e97ed004 +Subproject commit 2a57e34061f6034236663851332319c5dedab259 From 0e920237940d894ffb9be77f67f4d73a8463d1f3 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 24 May 2024 00:21:45 -0400 Subject: [PATCH 059/266] Add credits for all charts + tweak charts for Guns, Lit Up, Winter Horrorland --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 778e16705b..826be3bf1e 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 778e16705b30af85087f627594c22f4b5ba6141a +Subproject commit 826be3bf1e635e6b61c8c11bd3ece51f8a2b3061 From 62e04b3372fe1b9f7256585a23ed38a5b51db98f Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 24 May 2024 13:24:11 -0400 Subject: [PATCH 060/266] Update Changelog --- CHANGELOG.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7f8300476..10bbfe5f7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,46 @@ 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.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. +- 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. +### Changed +- Tweaked the charts for several songs: + - Winter Horrorland + - Stress + - Lit Up +- 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!) +- 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 pressing the volume keys would stop the Toy commercial (thanks gamerbross!) +- Fixed a bug where the Chart Editor would crash when losing (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!) + +## [0.3.3] - 2024-05-14 +### Changed +- Cleaned up some code in `PlayAnimationSongEvent.hx` (thanks BurgerBalls!) +### Fixed +- Fix Web Loading Bar (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!) +- Fixed the chart editor character selector's hitbox width (thanks MadBear422!) +- 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 an issue where the Freeplay menu never displays 100% clear +- 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 + ## [0.3.2] - 2024-05-03 ### Added - Added `,` and `.` keybinds to the Chart Editor. These place Focus Camera events at the playhead, for the opponent and player respectively. From c8930b598025f6f9faff795aeb3280ae3480c6b6 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 24 May 2024 13:45:37 -0400 Subject: [PATCH 061/266] Attempt to repair local submodules --- .gitmodules | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitmodules b/.gitmodules index 2d5c11067d..452c0089b7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,5 +1,6 @@ [submodule "assets"] path = assets url = https://github.com/FunkinCrew/Funkin-Assets-secret +[submodule "art"] path = art url = https://github.com/FunkinCrew/Funkin-Art-secret From 98505e58eca59a084bdd5fc98765ee53aca7c926 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 24 May 2024 14:04:55 -0400 Subject: [PATCH 062/266] Take two at fixing submodules --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 66572f85d8..52e007f5b6 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 66572f85d826ce2ec1d45468c12733b161237ffa +Subproject commit 52e007f5b682ee7b9d252edba78a88780510d32b From 85bfd00bade0d7413b578d7152afa6cc8f93f1d6 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 24 May 2024 16:38:35 -0400 Subject: [PATCH 063/266] desktop vis testing --- Project.xml | 1 + hmm.json | 9 ++++++++- source/funkin/audio/visualize/ABotVis.hx | 8 +++----- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Project.xml b/Project.xml index 24cdac2700..03e87e2d87 100644 --- a/Project.xml +++ b/Project.xml @@ -125,6 +125,7 @@ + diff --git a/hmm.json b/hmm.json index 288aa80b8b..a1998f515d 100644 --- a/hmm.json +++ b/hmm.json @@ -49,9 +49,16 @@ "name": "funkin.vis", "type": "git", "dir": null, - "ref": "2aa654b974507ab51ab1724d2d97e75726fd7d78", + "ref": "c6a1e24d48646849ea63563ca45561512c953779", "url": "https://github.com/FunkinCrew/funkVis" }, + { + "name": "grig.audio", + "type": "git", + "dir": "src", + "ref": "cbf91e2180fd2e374924fe74844086aab7891666", + "url": "https://gitlab.com/haxe-grig/grig.audio.git" + }, { "name": "hamcrest", "type": "haxelib", diff --git a/source/funkin/audio/visualize/ABotVis.hx b/source/funkin/audio/visualize/ABotVis.hx index ca77dd58aa..15596318c3 100644 --- a/source/funkin/audio/visualize/ABotVis.hx +++ b/source/funkin/audio/visualize/ABotVis.hx @@ -58,8 +58,8 @@ class ABotVis extends FlxTypedSpriteGroup public function initAnalyzer() { @:privateAccess - analyzer = new SpectralAnalyzer(7, new LimeAudioClip(cast snd._channel.__source), 0.01, 30); - analyzer.maxDb = -35; + analyzer = new SpectralAnalyzer(snd._channel.__source, 7, 0.01, 30); + // analyzer.maxDb = -35; // analyzer.fftN = 2048; } @@ -83,9 +83,7 @@ class ABotVis extends FlxTypedSpriteGroup override function draw() { - #if web if (analyzer != null) drawFFT(); - #end super.draw(); } @@ -94,7 +92,7 @@ class ABotVis extends FlxTypedSpriteGroup */ function drawFFT():Void { - var levels = analyzer.getLevels(false); + var levels = analyzer.getLevels(); for (i in 0...min(group.members.length, levels.length)) { From dd3e241f0c08ae5239ba081c1022acc96e993abe Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 24 May 2024 16:44:12 -0400 Subject: [PATCH 064/266] Fix some merge conflicts --- source/funkin/input/Controls.hx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/funkin/input/Controls.hx b/source/funkin/input/Controls.hx index 31551dec94..345791eefe 100644 --- a/source/funkin/input/Controls.hx +++ b/source/funkin/input/Controls.hx @@ -997,7 +997,7 @@ class Controls extends FlxActionSet for (control in Control.createAll()) { var inputs:Array = Reflect.field(data, control.getName()); - inputs = inputs.unique(); + inputs = inputs.distinct(); if (inputs != null) { if (inputs.length == 0) { @@ -1050,7 +1050,7 @@ class Controls extends FlxActionSet if (inputs.length == 0) { inputs = [FlxKey.NONE]; } else { - inputs = inputs.unique(); + inputs = inputs.distinct(); } Reflect.setField(data, control.getName(), inputs); From 07959d3e88898048cc1037a43310c20223cf18b1 Mon Sep 17 00:00:00 2001 From: gamerbross <55158797+gamerbross@users.noreply.github.com> Date: Sat, 25 May 2024 01:08:17 +0200 Subject: [PATCH 065/266] Fix Unscripted Stage Log Trace --- source/funkin/data/BaseRegistry.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/data/BaseRegistry.hx b/source/funkin/data/BaseRegistry.hx index 118516bec3..2df3a87dae 100644 --- a/source/funkin/data/BaseRegistry.hx +++ b/source/funkin/data/BaseRegistry.hx @@ -117,7 +117,7 @@ abstract class BaseRegistry & Constructible Date: Sat, 25 May 2024 01:21:37 +0200 Subject: [PATCH 066/266] Fix Legacy Chart Importer wrong instrumental --- source/funkin/data/song/importer/FNFLegacyImporter.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/data/song/importer/FNFLegacyImporter.hx b/source/funkin/data/song/importer/FNFLegacyImporter.hx index ab2abda8e1..87f3f81367 100644 --- a/source/funkin/data/song/importer/FNFLegacyImporter.hx +++ b/source/funkin/data/song/importer/FNFLegacyImporter.hx @@ -65,7 +65,7 @@ class FNFLegacyImporter songMetadata.timeChanges = rebuildTimeChanges(songData); - songMetadata.playData.characters = new SongCharacterData(songData?.song?.player1 ?? 'bf', 'gf', songData?.song?.player2 ?? 'dad', 'mom'); + songMetadata.playData.characters = new SongCharacterData(songData?.song?.player1 ?? 'bf', 'gf', songData?.song?.player2 ?? 'dad'); return songMetadata; } From cb2f4b0f06f66a343edb6efe33f44d21d66dbc8c Mon Sep 17 00:00:00 2001 From: PurSnake <56314743+PurSnake@users.noreply.github.com> Date: Sat, 25 May 2024 21:00:10 +0300 Subject: [PATCH 067/266] [BUGFIX] Correct characters scaling bruh --- source/funkin/play/stage/Stage.hx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/funkin/play/stage/Stage.hx b/source/funkin/play/stage/Stage.hx index eb9eb18108..e9c99558dd 100644 --- a/source/funkin/play/stage/Stage.hx +++ b/source/funkin/play/stage/Stage.hx @@ -124,7 +124,7 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass implements getGirlfriend().resetCharacter(true); // Reapply the camera offsets. var stageCharData:StageDataCharacter = _data.characters.gf; - var finalScale:Float = getBoyfriend().getBaseScale() * stageCharData.scale; + var finalScale:Float = getGirlfriend().getBaseScale() * stageCharData.scale; getGirlfriend().setScale(finalScale); getGirlfriend().cameraFocusPoint.x += stageCharData.cameraOffsets[0]; getGirlfriend().cameraFocusPoint.y += stageCharData.cameraOffsets[1]; @@ -134,7 +134,7 @@ class Stage extends FlxSpriteGroup implements IPlayStateScriptedClass implements getDad().resetCharacter(true); // Reapply the camera offsets. var stageCharData:StageDataCharacter = _data.characters.dad; - var finalScale:Float = getBoyfriend().getBaseScale() * stageCharData.scale; + var finalScale:Float = getDad().getBaseScale() * stageCharData.scale; getDad().setScale(finalScale); getDad().cameraFocusPoint.x += stageCharData.cameraOffsets[0]; getDad().cameraFocusPoint.y += stageCharData.cameraOffsets[1]; From 6c0d998edd02f39863b840e5557fdb8375d367b5 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 28 May 2024 01:18:18 -0400 Subject: [PATCH 068/266] update funkVis in hmm --- hmm.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hmm.json b/hmm.json index a1998f515d..e364e405fe 100644 --- a/hmm.json +++ b/hmm.json @@ -49,7 +49,7 @@ "name": "funkin.vis", "type": "git", "dir": null, - "ref": "c6a1e24d48646849ea63563ca45561512c953779", + "ref": "38261833590773cb1de34ac5d11e0825696fc340", "url": "https://github.com/FunkinCrew/funkVis" }, { From 004ed32fad81f096a925b3e3068e55e27fd33a3d Mon Sep 17 00:00:00 2001 From: Axuko Date: Mon, 27 May 2024 22:34:28 -0700 Subject: [PATCH 069/266] Remove alot of unused imoprts --- source/funkin/api/newgrounds/NGUnsafe.hx | 4 ---- source/funkin/api/newgrounds/NGio.hx | 8 -------- source/funkin/audio/FunkinSound.hx | 3 +-- source/funkin/audio/VoicesGroup.hx | 2 -- source/funkin/audio/visualize/ABotVis.hx | 4 ---- source/funkin/audio/visualize/PolygonVisGroup.hx | 1 - source/funkin/audio/visualize/SpectogramSprite.hx | 12 ------------ source/funkin/audio/visualize/VisShit.hx | 5 ----- source/funkin/audio/visualize/dsp/FFT.hx | 2 -- source/funkin/audio/waveform/WaveformData.hx | 2 -- source/funkin/audio/waveform/WaveformSprite.hx | 2 -- .../data/dialogue/conversation/ConversationData.hx | 2 -- .../dialogue/conversation/ConversationRegistry.hx | 1 - 13 files changed, 1 insertion(+), 47 deletions(-) diff --git a/source/funkin/api/newgrounds/NGUnsafe.hx b/source/funkin/api/newgrounds/NGUnsafe.hx index 9616dfe187..77e44bd1d4 100644 --- a/source/funkin/api/newgrounds/NGUnsafe.hx +++ b/source/funkin/api/newgrounds/NGUnsafe.hx @@ -1,9 +1,5 @@ package funkin.api.newgrounds; -import flixel.util.FlxSignal; -import flixel.util.FlxTimer; -import lime.app.Application; -import openfl.display.Stage; #if newgrounds import io.newgrounds.NG; import io.newgrounds.NGLite; diff --git a/source/funkin/api/newgrounds/NGio.hx b/source/funkin/api/newgrounds/NGio.hx index c1f8ad3ba4..3f5fc078ac 100644 --- a/source/funkin/api/newgrounds/NGio.hx +++ b/source/funkin/api/newgrounds/NGio.hx @@ -2,19 +2,11 @@ package funkin.api.newgrounds; #if newgrounds import flixel.util.FlxSignal; -import flixel.util.FlxTimer; import io.newgrounds.NG; import io.newgrounds.NGLite; -import io.newgrounds.components.ScoreBoardComponent.Period; import io.newgrounds.objects.Error; -import io.newgrounds.objects.Medal; import io.newgrounds.objects.Score; -import io.newgrounds.objects.ScoreBoard; -import io.newgrounds.objects.events.Response; -import io.newgrounds.objects.events.Result.GetCurrentVersionResult; -import io.newgrounds.objects.events.Result.GetVersionResult; import lime.app.Application; -import openfl.display.Stage; #end /** diff --git a/source/funkin/audio/FunkinSound.hx b/source/funkin/audio/FunkinSound.hx index df05cc3ef6..939b17f28c 100644 --- a/source/funkin/audio/FunkinSound.hx +++ b/source/funkin/audio/FunkinSound.hx @@ -11,10 +11,9 @@ import funkin.audio.waveform.WaveformDataParser; import funkin.data.song.SongData.SongMusicData; import funkin.data.song.SongRegistry; import funkin.util.tools.ICloneable; -import openfl.Assets; import openfl.media.SoundMixer; + #if (openfl >= "8.0.0") -import openfl.utils.AssetType; #end /** diff --git a/source/funkin/audio/VoicesGroup.hx b/source/funkin/audio/VoicesGroup.hx index 5037ee1d0c..9a1e0e0c17 100644 --- a/source/funkin/audio/VoicesGroup.hx +++ b/source/funkin/audio/VoicesGroup.hx @@ -1,9 +1,7 @@ package funkin.audio; -import funkin.audio.FunkinSound; import flixel.group.FlxGroup.FlxTypedGroup; import funkin.audio.waveform.WaveformData; -import funkin.audio.waveform.WaveformDataParser; class VoicesGroup extends SoundGroup { diff --git a/source/funkin/audio/visualize/ABotVis.hx b/source/funkin/audio/visualize/ABotVis.hx index ca77dd58aa..b94f20b38a 100644 --- a/source/funkin/audio/visualize/ABotVis.hx +++ b/source/funkin/audio/visualize/ABotVis.hx @@ -1,13 +1,9 @@ package funkin.audio.visualize; -import funkin.audio.visualize.dsp.FFT; import flixel.FlxSprite; -import flixel.addons.plugin.taskManager.FlxTask; import flixel.graphics.frames.FlxAtlasFrames; import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; -import flixel.math.FlxMath; import flixel.sound.FlxSound; -import funkin.util.MathUtil; import funkin.vis.dsp.SpectralAnalyzer; import funkin.vis.audioclip.frontends.LimeAudioClip; diff --git a/source/funkin/audio/visualize/PolygonVisGroup.hx b/source/funkin/audio/visualize/PolygonVisGroup.hx index cc68f4ae08..bff8457965 100644 --- a/source/funkin/audio/visualize/PolygonVisGroup.hx +++ b/source/funkin/audio/visualize/PolygonVisGroup.hx @@ -1,6 +1,5 @@ package funkin.audio.visualize; -import funkin.audio.visualize.PolygonSpectogram; import flixel.group.FlxGroup.FlxTypedGroup; import flixel.sound.FlxSound; diff --git a/source/funkin/audio/visualize/SpectogramSprite.hx b/source/funkin/audio/visualize/SpectogramSprite.hx index 636c0726a6..615e80d956 100644 --- a/source/funkin/audio/visualize/SpectogramSprite.hx +++ b/source/funkin/audio/visualize/SpectogramSprite.hx @@ -8,8 +8,6 @@ import flixel.sound.FlxSound; import flixel.util.FlxColor; import funkin.audio.visualize.PolygonSpectogram.VISTYPE; import funkin.audio.visualize.VisShit.CurAudioInfo; -import funkin.audio.visualize.dsp.FFT; -import lime.system.ThreadPool; import lime.utils.Int16Array; using Lambda; @@ -38,8 +36,6 @@ class SpectogramSprite extends FlxTypedSpriteGroup lengthOfShit = amnt; regenLineShit(); - - // makeGraphic(200, 200, FlxColor.BLACK); } public function regenLineShit():Void @@ -89,8 +85,6 @@ class SpectogramSprite extends FlxTypedSpriteGroup { checkAndSetBuffer(); - // vis.checkAndSetBuffer(); - if (setBuffer) { var samplesToGen:Int = Std.int(sampleRate * seconds); @@ -191,7 +185,6 @@ class SpectogramSprite extends FlxTypedSpriteGroup // a value between 10hz and 100Khz var hzPicker:Float = Math.pow(10, powedShit); - // var sampleApprox:Int = Std.int(FlxMath.remapToRange(i, 0, group.members.length, startingSample, startingSample + samplesToGen)); var remappedFreq:Int = Std.int(FlxMath.remapToRange(hzPicker, 0, 10000, 0, freqShit[0].length - 1)); group.members[i].x = prevLine.x; @@ -211,8 +204,6 @@ class SpectogramSprite extends FlxTypedSpriteGroup var line = FlxPoint.get(prevLine.x - group.members[i].x, prevLine.y - group.members[i].y); // dont draw a line until i figure out a nicer way to view da spikes and shit idk lol! - // group.members[i].setGraphicSize(Std.int(Math.max(line.length, 1)), Std.int(1)); - // group.members[i].angle = line.degrees; } } } @@ -261,9 +252,6 @@ class SpectogramSprite extends FlxTypedSpriteGroup group.members[Std.int(remappedSample)].x = prevLine.x; group.members[Std.int(remappedSample)].y = prevLine.y; - // group.members[0].y = prevLine.y; - - // FlxSpriteUtil.drawLine(this, prevLine.x, prevLine.y, width * remappedSample, left * height / 2 + height / 2); prevLine.x = (curAud.balanced * swagheight / 2 + swagheight / 2) + x; prevLine.y = (Std.int(remappedSample) / lengthOfShit * daHeight) + y; diff --git a/source/funkin/audio/visualize/VisShit.hx b/source/funkin/audio/visualize/VisShit.hx index 204ced1e1a..ba235fe890 100644 --- a/source/funkin/audio/visualize/VisShit.hx +++ b/source/funkin/audio/visualize/VisShit.hx @@ -3,7 +3,6 @@ package funkin.audio.visualize; import flixel.math.FlxMath; import flixel.sound.FlxSound; import funkin.audio.visualize.dsp.FFT; -import lime.system.ThreadPool; import lime.utils.Int16Array; import funkin.util.MathUtil; @@ -73,9 +72,6 @@ class VisShit freqOutput.push([]); - // if (FlxG.keys.justPressed.M) - // trace(FFT.rfft(chunk).map(z -> z.scale(1 / fs).magnitude)); - // find spectral peaks and their instantaneous frequencies for (k => s in freqs) { @@ -91,7 +87,6 @@ class VisShit if (freq < maxFreq) freqOutput[indexOfArray].push(power); // } - // haxe.Log.trace("", null); indexOfArray++; // move to next (overlapping) chunk diff --git a/source/funkin/audio/visualize/dsp/FFT.hx b/source/funkin/audio/visualize/dsp/FFT.hx index dc75acb814..40ee9cb8c3 100644 --- a/source/funkin/audio/visualize/dsp/FFT.hx +++ b/source/funkin/audio/visualize/dsp/FFT.hx @@ -1,7 +1,5 @@ package funkin.audio.visualize.dsp; -import funkin.audio.visualize.dsp.Complex; - using funkin.audio.visualize.dsp.OffsetArray; using funkin.audio.visualize.dsp.Signal; diff --git a/source/funkin/audio/waveform/WaveformData.hx b/source/funkin/audio/waveform/WaveformData.hx index 1f649b4728..a939f91bf9 100644 --- a/source/funkin/audio/waveform/WaveformData.hx +++ b/source/funkin/audio/waveform/WaveformData.hx @@ -1,7 +1,5 @@ package funkin.audio.waveform; -import funkin.util.MathUtil; - @:nullSafety class WaveformData { diff --git a/source/funkin/audio/waveform/WaveformSprite.hx b/source/funkin/audio/waveform/WaveformSprite.hx index 32ced2fbd3..8eaba8117d 100644 --- a/source/funkin/audio/waveform/WaveformSprite.hx +++ b/source/funkin/audio/waveform/WaveformSprite.hx @@ -1,7 +1,5 @@ package funkin.audio.waveform; -import funkin.audio.waveform.WaveformData; -import funkin.audio.waveform.WaveformDataParser; import funkin.graphics.rendering.MeshRender; import flixel.util.FlxColor; diff --git a/source/funkin/data/dialogue/conversation/ConversationData.hx b/source/funkin/data/dialogue/conversation/ConversationData.hx index 30e3f451be..6505198367 100644 --- a/source/funkin/data/dialogue/conversation/ConversationData.hx +++ b/source/funkin/data/dialogue/conversation/ConversationData.hx @@ -1,7 +1,5 @@ package funkin.data.dialogue.conversation; -import funkin.data.animation.AnimationData; - /** * A type definition for the data for a specific conversation. * It includes things like what dialogue boxes to use, what text to display, and what animations to play. diff --git a/source/funkin/data/dialogue/conversation/ConversationRegistry.hx b/source/funkin/data/dialogue/conversation/ConversationRegistry.hx index ca072897fd..fad1e43adc 100644 --- a/source/funkin/data/dialogue/conversation/ConversationRegistry.hx +++ b/source/funkin/data/dialogue/conversation/ConversationRegistry.hx @@ -1,7 +1,6 @@ package funkin.data.dialogue.conversation; import funkin.play.cutscene.dialogue.Conversation; -import funkin.data.dialogue.conversation.ConversationData; import funkin.play.cutscene.dialogue.ScriptedConversation; class ConversationRegistry extends BaseRegistry From 9a47666fc7f5e51dc3b58df2023ec63d6a61202f Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 28 May 2024 01:37:30 -0400 Subject: [PATCH 070/266] Fix a merge issue. --- source/funkin/input/Controls.hx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/funkin/input/Controls.hx b/source/funkin/input/Controls.hx index 31551dec94..345791eefe 100644 --- a/source/funkin/input/Controls.hx +++ b/source/funkin/input/Controls.hx @@ -997,7 +997,7 @@ class Controls extends FlxActionSet for (control in Control.createAll()) { var inputs:Array = Reflect.field(data, control.getName()); - inputs = inputs.unique(); + inputs = inputs.distinct(); if (inputs != null) { if (inputs.length == 0) { @@ -1050,7 +1050,7 @@ class Controls extends FlxActionSet if (inputs.length == 0) { inputs = [FlxKey.NONE]; } else { - inputs = inputs.unique(); + inputs = inputs.distinct(); } Reflect.setField(data, control.getName(), inputs); From d4b2e9496382ef967d425d7fe92ca4a816dafe04 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 28 May 2024 02:17:55 -0400 Subject: [PATCH 071/266] assets submod --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 8a8239cb50..371cce1fdc 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 8a8239cb50b5277fb0cfce041b3d8a9dfc780c35 +Subproject commit 371cce1fdc44914ddc3a5327e996cece4e676715 From cf61b9ef90810451c1a186c0388325f4d012bb9a Mon Sep 17 00:00:00 2001 From: gamerbross <55158797+gamerbross@users.noreply.github.com> Date: Tue, 28 May 2024 14:51:16 +0200 Subject: [PATCH 072/266] Add toString to Stage + Revert "Fix Unscripted Stage Log Trace" --- source/funkin/data/BaseRegistry.hx | 2 +- source/funkin/play/stage/Stage.hx | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/source/funkin/data/BaseRegistry.hx b/source/funkin/data/BaseRegistry.hx index 2df3a87dae..118516bec3 100644 --- a/source/funkin/data/BaseRegistry.hx +++ b/source/funkin/data/BaseRegistry.hx @@ -117,7 +117,7 @@ abstract class BaseRegistry & Constructible { return StageRegistry.instance.parseEntryDataWithMigration(id, StageRegistry.instance.fetchEntryVersion(id)); From 1ae30283a3a0d2a3bafb6d4da84d906764e80ed6 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 28 May 2024 15:34:09 -0400 Subject: [PATCH 073/266] re add the xmlns schema stuff --- Project.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Project.xml b/Project.xml index 24cdac2700..dce45546fb 100644 --- a/Project.xml +++ b/Project.xml @@ -1,5 +1,6 @@ - + @@ -14,6 +15,7 @@ + < @@ -28,7 +30,7 @@ - + From 01b6a11ddbbacc034f73b61451b78587b3536b7d Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 28 May 2024 22:57:01 -0400 Subject: [PATCH 074/266] flxpartialsound lock to current version --- hmm.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hmm.json b/hmm.json index 6b119c52fb..5260d5229f 100644 --- a/hmm.json +++ b/hmm.json @@ -4,7 +4,7 @@ "name": "FlxPartialSound", "type": "git", "dir": null, - "ref": "main", + "ref": "8bb8ed50f520d9cd64a65414b119b8718924b93a", "url": "https://github.com/FunkinCrew/FlxPartialSound.git" }, { @@ -178,4 +178,4 @@ "url": "https://github.com/FunkinCrew/thx.semver" } ] -} \ No newline at end of file +} From 2d300039ae42988c570af0f36225c1732a4fb09c Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 28 May 2024 23:53:50 -0400 Subject: [PATCH 075/266] promises + error out partial sounds that attempt to load multiple times --- source/funkin/audio/FunkinSound.hx | 32 +++++++++++++++++------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/source/funkin/audio/FunkinSound.hx b/source/funkin/audio/FunkinSound.hx index aaddda9dcb..39a26aac1b 100644 --- a/source/funkin/audio/FunkinSound.hx +++ b/source/funkin/audio/FunkinSound.hx @@ -360,24 +360,24 @@ class FunkinSound extends FlxSound implements ICloneable if (shouldLoadPartial) { var music = FunkinSound.loadPartial(pathToUse, params.partialParams?.start ?? 0, params.partialParams?.end ?? 1, params?.startingVolume ?? 1.0, - params.loop ?? true, false, true, params.onComplete, params.onLoad); + params.loop ?? true, false, false, params.onComplete); if (music != null) { - for (future in partialQueue) + while (partialQueue.length > 0) { - future = cast Future.withError("Music was overridden by another partial load"); + @:nullSafety(Off) + partialQueue.pop().error("Cancel loading partial sound"); } - partialQueue = []; + partialQueue.push(music); @:nullSafety(Off) - music.onComplete(function(partialMusic:Null) { - if (partialQueue.pop() == music) - { - FlxG.sound.music = partialMusic; - FlxG.sound.list.remove(FlxG.sound.music); - } + music.future.onComplete(function(partialMusic:Null) { + FlxG.sound.music = partialMusic; + FlxG.sound.list.remove(FlxG.sound.music); + + if (params.onLoad != null) params.onLoad(); }); return true; @@ -406,7 +406,7 @@ class FunkinSound extends FlxSound implements ICloneable } } - static var partialQueue:Array>> = []; + static var partialQueue:Array>> = []; /** * Creates a new `FunkinSound` object synchronously. @@ -478,7 +478,7 @@ class FunkinSound extends FlxSound implements ICloneable * @return A FunkinSound object */ public static function loadPartial(path:String, start:Float = 0, end:Float = 1, volume:Float = 1.0, looped:Bool = false, autoDestroy:Bool = false, - autoPlay:Bool = true, ?onComplete:Void->Void, ?onLoad:Void->Void):Future> + autoPlay:Bool = true, ?onComplete:Void->Void, ?onLoad:Void->Void):Promise> { var promise:lime.app.Promise> = new lime.app.Promise>(); @@ -488,12 +488,16 @@ class FunkinSound extends FlxSound implements ICloneable var soundRequest = FlxPartialSound.partialLoadFromFile(path, start, end); - soundRequest.onComplete(function(partialSound) { + promise.future.onError(function(e) { + soundRequest.error("Sound loading was errored or cancelled"); + }); + + soundRequest.future.onComplete(function(partialSound) { var snd = FunkinSound.load(partialSound, volume, looped, autoDestroy, autoPlay, onComplete, onLoad); promise.complete(snd); }); - return promise.future; + return promise; } @:nullSafety(Off) From 1f64c7fcc9757004925fdb641f5b9f19be248e5f Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 28 May 2024 23:54:23 -0400 Subject: [PATCH 076/266] update hmm flxpartialsound --- hmm.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hmm.json b/hmm.json index 5260d5229f..91d2f08bb3 100644 --- a/hmm.json +++ b/hmm.json @@ -4,7 +4,7 @@ "name": "FlxPartialSound", "type": "git", "dir": null, - "ref": "8bb8ed50f520d9cd64a65414b119b8718924b93a", + "ref": "44aa7eb", "url": "https://github.com/FunkinCrew/FlxPartialSound.git" }, { From d97d77566e1e30800bb3c5f8ba973af38a8ded0b Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 29 May 2024 00:53:32 -0400 Subject: [PATCH 077/266] Make song score lerp faster --- source/funkin/ui/story/StoryMenuState.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/ui/story/StoryMenuState.hx b/source/funkin/ui/story/StoryMenuState.hx index 820ac2ad14..c1a001e5de 100644 --- a/source/funkin/ui/story/StoryMenuState.hx +++ b/source/funkin/ui/story/StoryMenuState.hx @@ -306,7 +306,7 @@ class StoryMenuState extends MusicBeatState { Conductor.instance.update(); - highScoreLerp = Std.int(MathUtil.smoothLerp(highScoreLerp, highScore, elapsed, 0.5)); + highScoreLerp = Std.int(MathUtil.smoothLerp(highScoreLerp, highScore, elapsed, 0.25)); scoreText.text = 'LEVEL SCORE: ${Math.round(highScoreLerp)}'; From ee4be810622f896fb1ff12e9f9ad03889e85f455 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 29 May 2024 15:16:31 -0300 Subject: [PATCH 078/266] Now Preloader resets CWD --- source/funkin/ui/transition/preload/FunkinPreloader.hx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/funkin/ui/transition/preload/FunkinPreloader.hx b/source/funkin/ui/transition/preload/FunkinPreloader.hx index b71af2b3b3..9d25695884 100644 --- a/source/funkin/ui/transition/preload/FunkinPreloader.hx +++ b/source/funkin/ui/transition/preload/FunkinPreloader.hx @@ -136,6 +136,8 @@ class FunkinPreloader extends FlxBasePreloader // We can't even call trace() yet, until Flixel loads. trace('Initializing custom preloader...'); + funkin.util.CLIUtil.resetWorkingDir(); + this.siteLockTitleText = Constants.SITE_LOCK_TITLE; this.siteLockBodyText = Constants.SITE_LOCK_DESC; } From fb752ddd7860248c208fc612a4630f4be2bcee1c Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 29 May 2024 17:05:20 -0400 Subject: [PATCH 079/266] remove random < in project.xml lol --- Project.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/Project.xml b/Project.xml index 16e4b9854b..fcd29a25e4 100644 --- a/Project.xml +++ b/Project.xml @@ -15,7 +15,6 @@ xsi:schemaLocation="http://lime.openfl.org/project/1.0.4 http://lime.openfl.org/ - < From 8d7591a796f9c0c392eb66c8e494d5f9a7a5e36a Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 29 May 2024 21:43:54 -0400 Subject: [PATCH 080/266] Fix an issue where Story Menu props wouldn't render. --- source/funkin/ui/story/LevelProp.hx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/funkin/ui/story/LevelProp.hx b/source/funkin/ui/story/LevelProp.hx index 5a3efc36ae..0547404a1a 100644 --- a/source/funkin/ui/story/LevelProp.hx +++ b/source/funkin/ui/story/LevelProp.hx @@ -11,12 +11,15 @@ class LevelProp extends Bopper function set_propData(value:LevelPropData):LevelPropData { // Only reset the prop if the asset path has changed. - if (propData == null || value?.assetPath != propData?.assetPath) + if (propData == null || !(thx.Dynamics.equals(value, propData))) { + this.propData = value; + + this.visible = this.propData != null; + danceEvery = this.propData?.danceEvery ?? 0; + applyData(); } - this.visible = (value != null); - danceEvery = this.propData?.danceEvery ?? 0; return this.propData; } From 174c595837a63fef473ad191576e51862c240cc0 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 29 May 2024 22:49:57 -0400 Subject: [PATCH 081/266] Fix crash caused by improperly canceling a tween --- source/funkin/play/PauseSubState.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/play/PauseSubState.hx b/source/funkin/play/PauseSubState.hx index c345871a9a..8c45fac650 100644 --- a/source/funkin/play/PauseSubState.hx +++ b/source/funkin/play/PauseSubState.hx @@ -234,7 +234,7 @@ class PauseSubState extends MusicBeatSubState public override function destroy():Void { super.destroy(); - charterFadeTween.destroy(); + charterFadeTween.cancel(); charterFadeTween = null; pauseMusic.stop(); } From 6572d13a7f3212a047b2cb2266edf6938ddd7e2f Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 29 May 2024 23:21:32 -0400 Subject: [PATCH 082/266] Improve documentation a bit. --- source/funkin/play/event/ScrollSpeedEvent.hx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/funkin/play/event/ScrollSpeedEvent.hx b/source/funkin/play/event/ScrollSpeedEvent.hx index 9abd4be90a..c752d2f6d1 100644 --- a/source/funkin/play/event/ScrollSpeedEvent.hx +++ b/source/funkin/play/event/ScrollSpeedEvent.hx @@ -21,7 +21,9 @@ import funkin.data.event.SongEventSchema.SongEventFieldType; * "v": { * "scroll": "1.3", * "duration": "4", - * "ease": "linear" + * "ease": "linear", + * "strumline": "both", + * "absolute": false * } * } * ``` @@ -98,6 +100,8 @@ class ScrollSpeedEvent extends SongEvent * 'scroll': FLOAT, // Target scroll level. * 'duration': FLOAT, // Duration in steps. * 'ease': ENUM, // Easing function. + * 'strumline': ENUM, // Which strumline to change + * 'absolute': BOOL, // True to set the scroll speed to the target level, false to set the scroll speed to (target level x base scroll speed) * } * @return SongEventSchema */ From 68e9937b43994f7fb1b21347bad3cd02ef195815 Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Thu, 30 May 2024 04:33:26 +0100 Subject: [PATCH 083/266] interval shake class --- source/funkin/effects/IntervalShake.hx | 240 +++++++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 source/funkin/effects/IntervalShake.hx diff --git a/source/funkin/effects/IntervalShake.hx b/source/funkin/effects/IntervalShake.hx new file mode 100644 index 0000000000..545739cc33 --- /dev/null +++ b/source/funkin/effects/IntervalShake.hx @@ -0,0 +1,240 @@ +package funkin.effects; + +import flixel.FlxObject; +import flixel.util.FlxDestroyUtil.IFlxDestroyable; +import flixel.util.FlxPool; +import flixel.util.FlxTimer; +import flixel.math.FlxPoint; +import flixel.util.FlxAxes; +import flixel.tweens.FlxEase.EaseFunction; +import flixel.math.FlxMath; + +/** + * pretty much a copy of FlxFlicker geared towards making sprites + * shake around at a set interval and slow down over time. + */ +class IntervalShake implements IFlxDestroyable +{ + static var _pool:FlxPool = new FlxPool(IntervalShake.new); + + /** + * Internal map for looking up which objects are currently shaking and getting their shake data. + */ + static var _boundObjects:Map = new Map(); + + /** + * An effect that shakes the sprite on a set interval and a starting intensity that goes down over time. + * + * @param Object The object to shake. + * @param Duration How long to shake for (in seconds). `0` means "forever". + * @param Interval In what interval to update the shake position. Set to `FlxG.elapsed` if `<= 0`! + * @param StartIntensity The starting intensity of the shake. + * @param EndIntensity The ending intensity of the shake. + * @param Ease Control the easing of the intensity over the shake. + * @param CompletionCallback Callback on shake completion + * @param ProgressCallback Callback on each shake interval + * @return The `IntervalShake` object. `IntervalShake`s are pooled internally, so beware of storing references. + */ + public static function shake(Object:FlxObject, Duration:Float = 1, Interval:Float = 0.04, StartIntensity:Float = 0, EndIntensity:Float = 0, + Ease:EaseFunction, ?CompletionCallback:IntervalShake->Void, ?ProgressCallback:IntervalShake->Void):IntervalShake + { + if (isShaking(Object)) + { + // if (ForceRestart) + // { + // stopShaking(Object); + // } + // else + // { + // Ignore this call if object is already flickering. + return _boundObjects[Object]; + // } + } + + if (Interval <= 0) + { + Interval = FlxG.elapsed; + } + + var shake:IntervalShake = _pool.get(); + shake.start(Object, Duration, Interval, StartIntensity, EndIntensity, Ease, CompletionCallback, ProgressCallback); + return _boundObjects[Object] = shake; + } + + /** + * Returns whether the object is shaking or not. + * + * @param Object The object to test. + */ + public static function isShaking(Object:FlxObject):Bool + { + return _boundObjects.exists(Object); + } + + /** + * Stops shaking the object. + * + * @param Object The object to stop shaking. + */ + public static function stopShaking(Object:FlxObject):Void + { + var boundShake:IntervalShake = _boundObjects[Object]; + if (boundShake != null) + { + boundShake.stop(); + } + } + + /** + * The shaking object. + */ + public var object(default, null):FlxObject; + + /** + * The shaking timer. You can check how many seconds has passed since shaking started etc. + */ + public var timer(default, null):FlxTimer; + + /** + * The starting intensity of the shake. + */ + public var startIntensity(default, null):Float; + + /** + * The ending intensity of the shake. + */ + public var endIntensity(default, null):Float; + + /** + * How long to shake for (in seconds). `0` means "forever". + */ + public var duration(default, null):Float; + + /** + * The interval of the shake. + */ + public var interval(default, null):Float; + + /** + * Defines on what axes to `shake()`. Default value is `XY` / both. + */ + public var axes(default, null):FlxAxes; + + /** + * Defines the initial position of the object at the beginning of the shake effect. + */ + public var initialOffset(default, null):FlxPoint; + + /** + * The callback that will be triggered after the shake has completed. + */ + public var completionCallback(default, null):IntervalShake->Void; + + /** + * The callback that will be triggered every time the object shakes. + */ + public var progressCallback(default, null):IntervalShake->Void; + + /** + * The easing of the intensity over the shake. + */ + public var ease(default, null):EaseFunction; + + /** + * Nullifies the references to prepare object for reuse and avoid memory leaks. + */ + public function destroy():Void + { + object = null; + timer = null; + ease = null; + completionCallback = null; + progressCallback = null; + } + + /** + * Starts shaking behavior. + */ + function start(Object:FlxObject, Duration:Float = 1, Interval:Float = 0.04, StartIntensity:Float = 0, EndIntensity:Float = 0, Ease:EaseFunction, + ?CompletionCallback:IntervalShake->Void, ?ProgressCallback:IntervalShake->Void):Void + { + object = Object; + duration = Duration; + interval = Interval; + completionCallback = CompletionCallback; + startIntensity = StartIntensity; + endIntensity = EndIntensity; + initialOffset = new FlxPoint(Object.x, Object.y); + ease = Ease; + axes = FlxAxes.XY; + _secondsSinceStart = 0; + timer = new FlxTimer().start(interval, shakeProgress, Std.int(duration / interval)); + } + + /** + * Prematurely ends shaking. + */ + public function stop():Void + { + timer.cancel(); + // object.visible = true; + object.x = initialOffset.x; + object.y = initialOffset.y; + release(); + } + + /** + * Unbinds the object from shaking and releases it into pool for reuse. + */ + function release():Void + { + _boundObjects.remove(object); + _pool.put(this); + } + + public var _secondsSinceStart(default, null):Float = 0; + + public var scale(default, null):Float = 0; + + /** + * Just a helper function for shake() to update object's position. + */ + function shakeProgress(timer:FlxTimer):Void + { + _secondsSinceStart += interval; + scale = _secondsSinceStart / duration; + if (ease != null) + { + scale = 1 - ease(scale); + // trace(scale); + } + + var curIntensity:Float = 0; + curIntensity = FlxMath.lerp(endIntensity, startIntensity, scale); + + if (axes.x) object.x = initialOffset.x + FlxG.random.float((-curIntensity) * object.width, (curIntensity) * object.width); + if (axes.y) object.y = initialOffset.y + FlxG.random.float((-curIntensity) * object.width, (curIntensity) * object.width); + + // object.visible = !object.visible; + + if (progressCallback != null) progressCallback(this); + + if (timer.loops > 0 && timer.loopsLeft == 0) + { + object.x = initialOffset.x; + object.y = initialOffset.y; + if (completionCallback != null) + { + completionCallback(this); + } + + if (this.timer == timer) release(); + } + } + + /** + * Internal constructor. Use static methods. + */ + @:keep + function new() {} +} From e7079452fb4e54cc26d8c1cd132d70d0103a5d37 Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Thu, 30 May 2024 04:34:00 +0100 Subject: [PATCH 084/266] freeplay visual changes + base rank visuals --- source/funkin/ui/freeplay/CapsuleText.hx | 135 +++++++ source/funkin/ui/freeplay/DJBoyfriend.hx | 35 ++ source/funkin/ui/freeplay/FreeplayState.hx | 396 +++++++++++++++++- source/funkin/ui/freeplay/SongMenuItem.hx | 450 ++++++++++++++++++++- 4 files changed, 992 insertions(+), 24 deletions(-) diff --git a/source/funkin/ui/freeplay/CapsuleText.hx b/source/funkin/ui/freeplay/CapsuleText.hx index 3a520e0152..c3fd51d1fd 100644 --- a/source/funkin/ui/freeplay/CapsuleText.hx +++ b/source/funkin/ui/freeplay/CapsuleText.hx @@ -4,6 +4,12 @@ import openfl.filters.BitmapFilterQuality; import flixel.text.FlxText; import flixel.group.FlxSpriteGroup; import funkin.graphics.shaders.GaussianBlurShader; +import funkin.graphics.shaders.LeftMaskShader; +import flixel.math.FlxRect; +import flixel.tweens.FlxEase; +import flixel.util.FlxTimer; +import flixel.tweens.FlxTween; +import openfl.display.BlendMode; class CapsuleText extends FlxSpriteGroup { @@ -13,6 +19,15 @@ class CapsuleText extends FlxSpriteGroup public var text(default, set):String; + var maskShaderSongName:LeftMaskShader = new LeftMaskShader(); + + public var clipWidth(default, set):Int = 255; + + public var tooLong:Bool = false; + + // 255, 27 normal + // 220, 27 favourited + public function new(x:Float, y:Float, songTitle:String, size:Float) { super(x, y); @@ -36,6 +51,30 @@ class CapsuleText extends FlxSpriteGroup return text; } + // ???? none + // 255, 27 normal + // 220, 27 favourited + + function set_clipWidth(value:Int):Int + { + resetText(); + if (whiteText.width > value) + { + tooLong = true; + + blurredText.clipRect = new FlxRect(0, 0, value, blurredText.height); + whiteText.clipRect = new FlxRect(0, 0, value, whiteText.height); + } + else + { + tooLong = false; + + blurredText.clipRect = null; + whiteText.clipRect = null; + } + return clipWidth = value; + } + function set_text(value:String):String { if (value == null) return value; @@ -51,6 +90,102 @@ class CapsuleText extends FlxSpriteGroup new openfl.filters.GlowFilter(0x00ccff, 1, 5, 5, 210, BitmapFilterQuality.MEDIUM), // new openfl.filters.BlurFilter(5, 5, BitmapFilterQuality.LOW) ]; + return text = value; } + + var moveTimer:FlxTimer = new FlxTimer(); + var moveTween:FlxTween; + + public function initMove():Void + { + moveTimer.start(0.6, (timer) -> { + moveTextRight(); + }); + } + + function moveTextRight():Void + { + var distToMove:Float = whiteText.width - clipWidth; + moveTween = FlxTween.tween(whiteText.offset, {x: distToMove}, 2, + { + onUpdate: function(_) { + whiteText.clipRect = new FlxRect(whiteText.offset.x, 0, clipWidth, whiteText.height); + blurredText.offset = whiteText.offset; + blurredText.clipRect = new FlxRect(whiteText.offset.x, 0, clipWidth, blurredText.height); + }, + onComplete: function(_) { + moveTimer.start(0.3, (timer) -> { + moveTextLeft(); + }); + }, + ease: FlxEase.sineInOut + }); + } + + function moveTextLeft():Void + { + moveTween = FlxTween.tween(whiteText.offset, {x: 0}, 2, + { + onUpdate: function(_) { + whiteText.clipRect = new FlxRect(whiteText.offset.x, 0, clipWidth, whiteText.height); + blurredText.offset = whiteText.offset; + blurredText.clipRect = new FlxRect(whiteText.offset.x, 0, clipWidth, blurredText.height); + }, + onComplete: function(_) { + moveTimer.start(0.3, (timer) -> { + moveTextRight(); + }); + }, + ease: FlxEase.sineInOut + }); + } + + public function resetText():Void + { + if (moveTween != null) moveTween.cancel(); + if (moveTimer != null) moveTimer.cancel(); + whiteText.offset.x = 0; + whiteText.clipRect = new FlxRect(whiteText.offset.x, 0, clipWidth, whiteText.height); + blurredText.clipRect = new FlxRect(whiteText.offset.x, 0, clipWidth, whiteText.height); + } + + var flickerState:Bool = false; + var flickerTimer:FlxTimer; + + public function flickerText():Void + { + resetText(); + flickerTimer = new FlxTimer().start(1 / 24, flickerProgress, 19); + } + + function flickerProgress(timer:FlxTimer):Void + { + if (flickerState == true) + { + whiteText.blend = BlendMode.ADD; + blurredText.blend = BlendMode.ADD; + blurredText.color = 0xFFFFFFFF; + whiteText.color = 0xFFFFFFFF; + whiteText.textField.filters = [ + new openfl.filters.GlowFilter(0xFFFFFF, 1, 5, 5, 210, BitmapFilterQuality.MEDIUM), + // new openfl.filters.BlurFilter(5, 5, BitmapFilterQuality.LOW) + ]; + } + else + { + blurredText.color = 0xFF00aadd; + whiteText.color = 0xFFDDDDDD; + whiteText.textField.filters = [ + new openfl.filters.GlowFilter(0xDDDDDD, 1, 5, 5, 210, BitmapFilterQuality.MEDIUM), + // new openfl.filters.BlurFilter(5, 5, BitmapFilterQuality.LOW) + ]; + } + flickerState = !flickerState; + } + + override function update(elapsed:Float):Void + { + super.update(elapsed); + } } diff --git a/source/funkin/ui/freeplay/DJBoyfriend.hx b/source/funkin/ui/freeplay/DJBoyfriend.hx index 5f1144fabe..248526aaf6 100644 --- a/source/funkin/ui/freeplay/DJBoyfriend.hx +++ b/source/funkin/ui/freeplay/DJBoyfriend.hx @@ -82,6 +82,8 @@ class DJBoyfriend extends FlxAtlasSprite return anims; } + var lowPumpLoopPoint:Int = 4; + public override function update(elapsed:Float):Void { super.update(elapsed); @@ -114,6 +116,14 @@ class DJBoyfriend extends FlxAtlasSprite case Confirm: if (getCurrentAnimation() != 'Boyfriend DJ confirm') playFlashAnimation('Boyfriend DJ confirm', false); timeSinceSpook = 0; + case PumpIntro: + if (getCurrentAnimation() != 'Boyfriend DJ fist pump') playFlashAnimation('Boyfriend DJ fist pump', false); + if (getCurrentAnimation() == 'Boyfriend DJ fist pump' && anim.curFrame >= 4) + { + anim.play("Boyfriend DJ fist pump", true, false, 0); + } + case FistPump: + case Spook: if (getCurrentAnimation() != 'bf dj afk') { @@ -174,6 +184,12 @@ class DJBoyfriend extends FlxAtlasSprite currentState = Idle; case "Boyfriend DJ confirm": + case "Boyfriend DJ fist pump": + currentState = Idle; + + case "Boyfriend DJ loss reaction 1": + currentState = Idle; + case "Boyfriend DJ watchin tv OG": var frame:Int = FlxG.random.bool(33) ? 112 : 166; @@ -275,6 +291,23 @@ class DJBoyfriend extends FlxAtlasSprite currentState = Confirm; } + public function fistPump():Void + { + currentState = PumpIntro; + } + + public function pumpFist():Void + { + currentState = FistPump; + anim.play("Boyfriend DJ fist pump", true, false, 4); + } + + public function pumpFistBad():Void + { + currentState = FistPump; + anim.play("Boyfriend DJ loss reaction 1", true, false, 4); + } + public inline function addOffset(name:String, x:Float = 0, y:Float = 0) { animOffsets[name] = [x, y]; @@ -331,6 +364,8 @@ enum DJBoyfriendState Intro; Idle; Confirm; + PumpIntro; + FistPump; Spook; TV; } diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 7b7543845a..a665f07565 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -1,5 +1,6 @@ package funkin.ui.freeplay; +import funkin.graphics.adobeanimate.FlxAtlasSprite; import flixel.addons.transition.FlxTransitionableState; import flixel.addons.ui.FlxInputText; import flixel.FlxCamera; @@ -10,6 +11,7 @@ import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; import flixel.input.touch.FlxTouch; import flixel.math.FlxAngle; import flixel.math.FlxPoint; +import openfl.display.BlendMode; import flixel.system.debug.watch.Tracker.TrackerProfile; import flixel.text.FlxText; import flixel.tweens.FlxEase; @@ -38,6 +40,8 @@ import funkin.ui.transition.LoadingState; import funkin.ui.transition.StickerSubState; import funkin.util.MathUtil; import lime.utils.Assets; +import flixel.tweens.misc.ShakeTween; +import funkin.effects.IntervalShake; /** * Parameters used to initialize the FreeplayState. @@ -135,6 +139,29 @@ class FreeplayState extends MusicBeatSubState public static var rememberedDifficulty:Null = Constants.DEFAULT_DIFFICULTY; public static var rememberedSongId:Null = 'tutorial'; + var funnyCam:FunkinCamera; + var rankCamera:FunkinCamera; + var rankBg:FunkinSprite; + var rankVignette:FlxSprite; + + var backingTextYeah:FlxAtlasSprite; + var orangeBackShit:FunkinSprite; + var alsoOrangeLOL:FunkinSprite; + var pinkBack:FunkinSprite; + var confirmGlow:FlxSprite; + var confirmGlow2:FlxSprite; + var confirmTextGlow:FlxSprite; + + var moreWays:BGScrollingText; + var funnyScroll:BGScrollingText; + var txtNuts:BGScrollingText; + var funnyScroll2:BGScrollingText; + var moreWays2:BGScrollingText; + var funnyScroll3:BGScrollingText; + + var bgDad:FlxSprite; + var cardGlow:FlxSprite; + public function new(?params:FreeplayStateParams, ?stickers:StickerSubState) { currentCharacter = params?.character ?? Constants.DEFAULT_CHARACTER; @@ -216,17 +243,17 @@ class FreeplayState extends MusicBeatSubState trace(FlxG.camera.initialZoom); trace(FlxCamera.defaultZoom); - var pinkBack:FunkinSprite = FunkinSprite.create('freeplay/pinkBack'); + pinkBack = FunkinSprite.create('freeplay/pinkBack'); pinkBack.color = 0xFFFFD4E9; // sets it to pink! pinkBack.x -= pinkBack.width; FlxTween.tween(pinkBack, {x: 0}, 0.6, {ease: FlxEase.quartOut}); add(pinkBack); - var orangeBackShit:FunkinSprite = new FunkinSprite(84, 440).makeSolidColor(Std.int(pinkBack.width), 75, 0xFFFEDA00); + orangeBackShit = new FunkinSprite(84, 440).makeSolidColor(Std.int(pinkBack.width), 75, 0xFFFEDA00); add(orangeBackShit); - var alsoOrangeLOL:FunkinSprite = new FunkinSprite(0, orangeBackShit.y).makeSolidColor(100, Std.int(orangeBackShit.height), 0xFFFFD400); + alsoOrangeLOL = new FunkinSprite(0, orangeBackShit.y).makeSolidColor(100, Std.int(orangeBackShit.height), 0xFFFFD400); add(alsoOrangeLOL); exitMovers.set([pinkBack, orangeBackShit, alsoOrangeLOL], @@ -241,13 +268,30 @@ class FreeplayState extends MusicBeatSubState orangeBackShit.visible = false; alsoOrangeLOL.visible = false; + confirmTextGlow = new FlxSprite(-8, 115).loadGraphic(Paths.image('freeplay/glowingText')); + confirmTextGlow.blend = BlendMode.ADD; + confirmTextGlow.visible = false; + + confirmGlow = new FlxSprite(-30, 240).loadGraphic(Paths.image('freeplay/confirmGlow')); + confirmGlow.blend = BlendMode.ADD; + + confirmGlow2 = new FlxSprite(confirmGlow.x, confirmGlow.y).loadGraphic(Paths.image('freeplay/confirmGlow2')); + + confirmGlow.visible = false; + confirmGlow2.visible = false; + + add(confirmGlow2); + add(confirmGlow); + + add(confirmTextGlow); + var grpTxtScrolls:FlxGroup = new FlxGroup(); add(grpTxtScrolls); grpTxtScrolls.visible = false; FlxG.debugger.addTrackerProfile(new TrackerProfile(BGScrollingText, ['x', 'y', 'speed', 'size'])); - var moreWays:BGScrollingText = new BGScrollingText(0, 160, 'HOT BLOODED IN MORE WAYS THAN ONE', FlxG.width, true, 43); + moreWays = new BGScrollingText(0, 160, 'HOT BLOODED IN MORE WAYS THAN ONE', FlxG.width, true, 43); moreWays.funnyColor = 0xFFFFF383; moreWays.speed = 6.8; grpTxtScrolls.add(moreWays); @@ -258,7 +302,7 @@ class FreeplayState extends MusicBeatSubState speed: 0.4, }); - var funnyScroll:BGScrollingText = new BGScrollingText(0, 220, 'BOYFRIEND', FlxG.width / 2, false, 60); + funnyScroll = new BGScrollingText(0, 220, 'BOYFRIEND', FlxG.width / 2, false, 60); funnyScroll.funnyColor = 0xFFFF9963; funnyScroll.speed = -3.8; grpTxtScrolls.add(funnyScroll); @@ -271,7 +315,7 @@ class FreeplayState extends MusicBeatSubState wait: 0 }); - var txtNuts:BGScrollingText = new BGScrollingText(0, 285, 'PROTECT YO NUTS', FlxG.width / 2, true, 43); + txtNuts = new BGScrollingText(0, 285, 'PROTECT YO NUTS', FlxG.width / 2, true, 43); txtNuts.speed = 3.5; grpTxtScrolls.add(txtNuts); exitMovers.set([txtNuts], @@ -280,7 +324,7 @@ class FreeplayState extends MusicBeatSubState speed: 0.4, }); - var funnyScroll2:BGScrollingText = new BGScrollingText(0, 335, 'BOYFRIEND', FlxG.width / 2, false, 60); + funnyScroll2 = new BGScrollingText(0, 335, 'BOYFRIEND', FlxG.width / 2, false, 60); funnyScroll2.funnyColor = 0xFFFF9963; funnyScroll2.speed = -3.8; grpTxtScrolls.add(funnyScroll2); @@ -291,7 +335,7 @@ class FreeplayState extends MusicBeatSubState speed: 0.5, }); - var moreWays2:BGScrollingText = new BGScrollingText(0, 397, 'HOT BLOODED IN MORE WAYS THAN ONE', FlxG.width, true, 43); + moreWays2 = new BGScrollingText(0, 397, 'HOT BLOODED IN MORE WAYS THAN ONE', FlxG.width, true, 43); moreWays2.funnyColor = 0xFFFFF383; moreWays2.speed = 6.8; grpTxtScrolls.add(moreWays2); @@ -302,7 +346,7 @@ class FreeplayState extends MusicBeatSubState speed: 0.4 }); - var funnyScroll3:BGScrollingText = new BGScrollingText(0, orangeBackShit.y + 10, 'BOYFRIEND', FlxG.width / 2, 60); + funnyScroll3 = new BGScrollingText(0, orangeBackShit.y + 10, 'BOYFRIEND', FlxG.width / 2, 60); funnyScroll3.funnyColor = 0xFFFEA400; funnyScroll3.speed = -3.8; grpTxtScrolls.add(funnyScroll3); @@ -313,6 +357,24 @@ class FreeplayState extends MusicBeatSubState speed: 0.3 }); + backingTextYeah = new FlxAtlasSprite(640, 370, Paths.animateAtlas("freeplay/backing-text-yeah"), + { + FrameRate: 24.0, + Reversed: false, + // ?OnComplete:Void -> Void, + ShowPivot: false, + Antialiasing: true, + ScrollFactor: new FlxPoint(1, 1), + }); + + add(backingTextYeah); + + cardGlow = new FlxSprite(-30, -30).loadGraphic(Paths.image('freeplay/cardGlow')); + cardGlow.blend = BlendMode.ADD; + cardGlow.visible = false; + + add(cardGlow); + dj = new DJBoyfriend(640, 366); exitMovers.set([dj], { @@ -325,7 +387,7 @@ class FreeplayState extends MusicBeatSubState add(dj); - var bgDad:FlxSprite = new FlxSprite(pinkBack.width * 0.75, 0).loadGraphic(Paths.image('freeplay/freeplayBGdad')); + bgDad = new FlxSprite(pinkBack.width * 0.75, 0).loadGraphic(Paths.image('freeplay/freeplayBGdad')); bgDad.setGraphicSize(0, FlxG.height); bgDad.updateHitbox(); bgDad.shader = new AngleMask(); @@ -342,10 +404,14 @@ class FreeplayState extends MusicBeatSubState }); add(bgDad); - FlxTween.tween(blackOverlayBullshitLOLXD, {x: pinkBack.width * 0.75}, 0.7, {ease: FlxEase.quintOut}); + FlxTween.tween(blackOverlayBullshitLOLXD, {x: pinkBack.width * 0.76}, 0.7, {ease: FlxEase.quintOut}); blackOverlayBullshitLOLXD.shader = bgDad.shader; + rankBg = new FunkinSprite(0, 0); + rankBg.makeSolidColor(FlxG.width, FlxG.height, 0xD3000000); + add(rankBg); + grpSongs = new FlxTypedGroup(); add(grpSongs); @@ -527,18 +593,35 @@ class FreeplayState extends MusicBeatSubState orangeBackShit.visible = true; alsoOrangeLOL.visible = true; grpTxtScrolls.visible = true; + + cardGlow.visible = true; + FlxTween.tween(cardGlow, {alpha: 0, "scale.x": 1.2, "scale.y": 1.2}, 0.45, {ease: FlxEase.sineOut}); }); generateSongList(null, false); // dedicated camera for the state so we don't need to fuk around with camera scrolls from the mainmenu / elsewhere - var funnyCam:FunkinCamera = new FunkinCamera('freeplayFunny', 0, 0, FlxG.width, FlxG.height); + funnyCam = new FunkinCamera('freeplayFunny', 0, 0, FlxG.width, FlxG.height); funnyCam.bgColor = FlxColor.TRANSPARENT; FlxG.cameras.add(funnyCam, false); + rankVignette = new FlxSprite(0, 0).loadGraphic(Paths.image('freeplay/rankVignette')); + rankVignette.scale.set(2, 2); + rankVignette.updateHitbox(); + rankVignette.blend = BlendMode.ADD; + // rankVignette.cameras = [rankCamera]; + add(rankVignette); + rankVignette.alpha = 0; + forEach(function(bs) { bs.cameras = [funnyCam]; }); + + rankCamera = new FunkinCamera('rankCamera', 0, 0, FlxG.width, FlxG.height); + rankCamera.bgColor = FlxColor.TRANSPARENT; + FlxG.cameras.add(rankCamera, false); + rankBg.cameras = [rankCamera]; + rankBg.alpha = 0; } var currentFilter:SongFilter = null; @@ -585,6 +668,7 @@ class FreeplayState extends MusicBeatSubState for (cap in grpCapsules.members) { + cap.songText.resetText(); cap.kill(); } @@ -602,9 +686,11 @@ class FreeplayState extends MusicBeatSubState }; randomCapsule.y = randomCapsule.intendedY(0) + 10; randomCapsule.targetPos.x = randomCapsule.x; - randomCapsule.alpha = 0.5; + randomCapsule.alpha = 0; randomCapsule.songText.visible = false; randomCapsule.favIcon.visible = false; + randomCapsule.ranking.visible = false; + randomCapsule.blurredRanking.visible = false; randomCapsule.initJumpIn(0, force); randomCapsule.hsvShader = hsvShader; grpCapsules.add(randomCapsule); @@ -627,8 +713,12 @@ class FreeplayState extends MusicBeatSubState funnyMenu.favIcon.visible = tempSongs[i].isFav; funnyMenu.hsvShader = hsvShader; + funnyMenu.newText.animation.curAnim.curFrame = 45 - ((i * 4) % 45); + funnyMenu.forcePosition(); + funnyMenu.checkClip(); + grpCapsules.add(funnyMenu); } @@ -682,6 +772,210 @@ class FreeplayState extends MusicBeatSubState return songsToFilter; } + function rankAnimStart() + { + dj.fistPump(); + // rankCamera.fade(FlxColor.BLACK, 0.5, true); + rankCamera.fade(0xFF000000, 0.5, true, null, true); + FlxG.sound.music.volume = 0; + rankBg.alpha = 1; + + originalPos.x = grpCapsules.members[curSelected].x; + originalPos.y = grpCapsules.members[curSelected].y; + + grpCapsules.members[curSelected].ranking.alpha = 0; + grpCapsules.members[curSelected].blurredRanking.alpha = 0; + + rankCamera.zoom = 1.85; + FlxTween.tween(rankCamera, {"zoom": 1.8}, 0.6, {ease: FlxEase.sineIn}); + + funnyCam.zoom = 1.15; + FlxTween.tween(funnyCam, {"zoom": 1.1}, 0.6, {ease: FlxEase.sineIn}); + + grpCapsules.members[curSelected].cameras = [rankCamera]; + grpCapsules.members[curSelected].targetPos.set((FlxG.width / 2) - (grpCapsules.members[curSelected].width / 2), + (FlxG.height / 2) - (grpCapsules.members[curSelected].height / 2)); + + new FlxTimer().start(0.5, _ -> { + grpCapsules.members[curSelected].doLerp = false; + rankDisplayNew(); + }); + } + + function rankDisplayNew() + { + grpCapsules.members[curSelected].ranking.alpha = 1; + grpCapsules.members[curSelected].blurredRanking.alpha = 1; + + grpCapsules.members[curSelected].ranking.scale.set(20, 20); + grpCapsules.members[curSelected].blurredRanking.scale.set(20, 20); + // var tempr:Int = FlxG.random.int(0, 4); + + // grpCapsules.members[curSelected].ranking.rank = tempr; + grpCapsules.members[curSelected].ranking.animation.play(grpCapsules.members[curSelected].ranking.animation.curAnim.name, true); + 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); + FlxTween.tween(grpCapsules.members[curSelected].blurredRanking, {"scale.x": 1, "scale.y": 1}, 0.1); + + new FlxTimer().start(0.1, _ -> { + trace(grpCapsules.members[curSelected].ranking.rank); + switch (grpCapsules.members[curSelected].tempr) + { + case 0: + FunkinSound.playOnce(Paths.sound('ranks/rankinbad')); + case 4: + FunkinSound.playOnce(Paths.sound('ranks/rankinperfect')); + case 5: + FunkinSound.playOnce(Paths.sound('ranks/rankinperfect')); + default: + FunkinSound.playOnce(Paths.sound('ranks/rankinnormal')); + } + rankCamera.zoom = 1.3; + // FlxTween.tween(rankCamera, {"zoom": 1.4}, 0.3, {ease: FlxEase.elasticOut}); + + FlxTween.tween(rankCamera, {"zoom": 1.5}, 0.3, {ease: FlxEase.backInOut}); + + grpCapsules.members[curSelected].x -= 10; + grpCapsules.members[curSelected].y -= 20; + + FlxTween.tween(funnyCam, {"zoom": 1.05}, 0.3, {ease: FlxEase.elasticOut}); + + grpCapsules.members[curSelected].capsule.angle = -3; + FlxTween.tween(grpCapsules.members[curSelected].capsule, {angle: 0}, 0.5, {ease: FlxEase.backOut}); + + IntervalShake.shake(grpCapsules.members[curSelected].capsule, 0.3, 1 / 30, 0.1, 0, FlxEase.quadOut); + }); + + new FlxTimer().start(0.4, _ -> { + FlxTween.tween(funnyCam, {"zoom": 1}, 0.8, {ease: FlxEase.sineIn}); + FlxTween.tween(rankCamera, {"zoom": 1.2}, 0.8, {ease: FlxEase.backIn}); + // IntervalShake.shake(grpCapsules.members[curSelected], 0.8 + 0.5, 1 / 24, 0, 2, FlxEase.quadIn); + FlxTween.tween(grpCapsules.members[curSelected], {x: originalPos.x - 7, y: originalPos.y - 80}, 0.8 + 0.5, {ease: FlxEase.quartIn}); + }); + + new FlxTimer().start(0.6, _ -> { + rankAnimSlam(); + // IntervalShake.shake(grpCapsules.members[curSelected].capsule, 0.3, 1 / 30, 0, 0.3, FlxEase.quartIn); + }); + } + + function rankAnimSlam() + { + // FlxTween.tween(rankCamera, {"zoom": 1.9}, 0.5, {ease: FlxEase.backOut}); + FlxTween.tween(rankBg, {alpha: 0}, 0.5, {ease: FlxEase.expoIn}); + + // FlxTween.tween(grpCapsules.members[curSelected], {angle: 5}, 0.5, {ease: FlxEase.backIn}); + + switch (grpCapsules.members[curSelected].tempr) + { + case 0: + FunkinSound.playOnce(Paths.sound('ranks/loss')); + case 1: + FunkinSound.playOnce(Paths.sound('ranks/good')); + case 2: + FunkinSound.playOnce(Paths.sound('ranks/great')); + case 3: + FunkinSound.playOnce(Paths.sound('ranks/excellent')); + case 4: + FunkinSound.playOnce(Paths.sound('ranks/perfect')); + case 5: + FunkinSound.playOnce(Paths.sound('ranks/perfect')); + default: + FunkinSound.playOnce(Paths.sound('ranks/loss')); + } + + FlxTween.tween(grpCapsules.members[curSelected], {"targetPos.x": originalPos.x, "targetPos.y": originalPos.y}, 0.5, {ease: FlxEase.expoOut}); + new FlxTimer().start(0.5, _ -> { + funnyCam.shake(0.0045, 0.35); + + if (grpCapsules.members[curSelected].tempr == 0) + { + dj.pumpFistBad(); + } + else + { + dj.pumpFist(); + } + + rankCamera.zoom = 0.8; + funnyCam.zoom = 0.8; + FlxTween.tween(rankCamera, {"zoom": 1}, 1, {ease: FlxEase.elasticOut}); + FlxTween.tween(funnyCam, {"zoom": 1}, 0.8, {ease: FlxEase.elasticOut}); + + for (index => capsule in grpCapsules.members) + { + var distFromSelected:Float = Math.abs(index - curSelected) - 1; + + if (distFromSelected < 5) + { + if (index == curSelected) + { + FlxTween.cancelTweensOf(capsule); + // capsule.targetPos.x += 50; + capsule.fadeAnim(); + + rankVignette.color = capsule.getTrailColor(); + rankVignette.alpha = 1; + FlxTween.tween(rankVignette, {alpha: 0}, 0.6, {ease: FlxEase.expoOut}); + + capsule.doLerp = false; + capsule.setPosition(originalPos.x, originalPos.y); + IntervalShake.shake(capsule, 0.6, 1 / 24, 0.12, 0, FlxEase.quadOut, function(_) { + capsule.doLerp = true; + capsule.cameras = [funnyCam]; + }, null); + + // FlxTween.tween(capsule, {"targetPos.x": capsule.targetPos.x - 50}, 0.6, + // { + // ease: FlxEase.backInOut, + // onComplete: function(_) { + // capsule.cameras = [funnyCam]; + // } + // }); + FlxTween.tween(capsule, {angle: 0}, 0.5, {ease: FlxEase.backOut}); + } + if (index > curSelected) + { + // capsule.color = FlxColor.RED; + new FlxTimer().start(distFromSelected / 20, _ -> { + capsule.doLerp = false; + + capsule.capsule.angle = FlxG.random.float(-10 + (distFromSelected * 2), 10 - (distFromSelected * 2)); + FlxTween.tween(capsule.capsule, {angle: 0}, 0.5, {ease: FlxEase.backOut}); + + IntervalShake.shake(capsule, 0.6, 1 / 24, 0.12 / (distFromSelected + 1), 0, FlxEase.quadOut, function(_) { + capsule.doLerp = true; + }); + }); + } + + if (index < curSelected) + { + // capsule.color = FlxColor.BLUE; + new FlxTimer().start(distFromSelected / 20, _ -> { + capsule.doLerp = false; + + capsule.capsule.angle = FlxG.random.float(-10 + (distFromSelected * 2), 10 - (distFromSelected * 2)); + FlxTween.tween(capsule.capsule, {angle: 0}, 0.5, {ease: FlxEase.backOut}); + + IntervalShake.shake(capsule, 0.6, 1 / 24, 0.12 / (distFromSelected + 1), 0, FlxEase.quadOut, function(_) { + capsule.doLerp = true; + }); + }); + } + } + + index += 1; + } + }); + + new FlxTimer().start(2, _ -> { + // dj.fistPump(); + FlxG.sound.music.fadeIn(4.0, 0.0, 1.0); + }); + } + var touchY:Float = 0; var touchX:Float = 0; var dxTouch:Float = 0; @@ -698,10 +992,48 @@ class FreeplayState extends MusicBeatSubState var busy:Bool = false; // Set to true once the user has pressed enter to select a song. + var originalPos:FlxPoint = new FlxPoint(); + override function update(elapsed:Float):Void { super.update(elapsed); + if (FlxG.keys.justPressed.T) + { + rankAnimStart(); + } + + if (FlxG.keys.justPressed.H) + { + rankDisplayNew(); + } + + if (FlxG.keys.justPressed.G) + { + rankAnimSlam(); + } + + if (FlxG.keys.justPressed.I) + { + confirmTextGlow.y -= 1; + trace(confirmTextGlow.x, confirmTextGlow.y); + } + if (FlxG.keys.justPressed.J) + { + confirmTextGlow.x -= 1; + trace(confirmTextGlow.x, confirmTextGlow.y); + } + if (FlxG.keys.justPressed.L) + { + confirmTextGlow.x += 1; + trace(confirmTextGlow.x, confirmTextGlow.y); + } + if (FlxG.keys.justPressed.K) + { + confirmTextGlow.y += 1; + trace(confirmTextGlow.x, confirmTextGlow.y); + } + if (FlxG.keys.justPressed.F) { var targetSong = grpCapsules.members[curSelected]?.songData; @@ -1145,6 +1477,42 @@ class FreeplayState extends MusicBeatSubState FunkinSound.playOnce(Paths.sound('confirmMenu')); dj.confirm(); + grpCapsules.members[curSelected].songText.flickerText(); + + // FlxTween.color(bgDad, 0.33, 0xFFFFFFFF, 0xFF555555, {ease: FlxEase.quadOut}); + FlxTween.color(pinkBack, 0.33, 0xFFFFD0D5, 0xFF171831, {ease: FlxEase.quadOut}); + orangeBackShit.visible = false; + alsoOrangeLOL.visible = false; + + confirmGlow.visible = true; + confirmGlow2.visible = true; + + backingTextYeah.anim.play("BF back card confirm raw", false, false, 0); + confirmGlow2.alpha = 0; + confirmGlow.alpha = 0; + + FlxTween.tween(confirmGlow2, {alpha: 0.5}, 0.33, + { + ease: FlxEase.quadOut, + onComplete: function(_) { + confirmGlow2.alpha = 0.6; + confirmGlow.alpha = 1; + confirmTextGlow.visible = true; + confirmTextGlow.alpha = 1; + FlxTween.tween(confirmTextGlow, {alpha: 0.4}, 0.5); + FlxTween.tween(confirmGlow, {alpha: 0}, 0.5); + } + }); + + // confirmGlow + + moreWays.visible = false; + funnyScroll.visible = false; + txtNuts.visible = false; + funnyScroll2.visible = false; + moreWays2.visible = false; + funnyScroll3.visible = false; + new FlxTimer().start(1, function(tmr:FlxTimer) { Paths.setCurrentLevel(cap.songData.levelId); LoadingState.loadPlayState( @@ -1383,6 +1751,7 @@ class FreeplaySongData public var songName(default, null):String = ''; public var songCharacter(default, null):String = ''; + public var songStartingBpm(default, null):Float = 0; public var songRating(default, null):Int = 0; public var albumId(default, null):Null = null; @@ -1415,6 +1784,7 @@ class FreeplaySongData var songDifficulty:SongDifficulty = song.getDifficulty(currentDifficulty, variations); if (songDifficulty == null) return; + this.songStartingBpm = songDifficulty.getStartingBPM(); this.songName = songDifficulty.songName; this.songCharacter = songDifficulty.characters.opponent; this.songRating = songDifficulty.difficultyRating; diff --git a/source/funkin/ui/freeplay/SongMenuItem.hx b/source/funkin/ui/freeplay/SongMenuItem.hx index f6d85e56e2..0f72199ba0 100644 --- a/source/funkin/ui/freeplay/SongMenuItem.hx +++ b/source/funkin/ui/freeplay/SongMenuItem.hx @@ -14,6 +14,13 @@ import flixel.text.FlxText; import flixel.util.FlxTimer; import funkin.util.MathUtil; import funkin.graphics.shaders.Grayscale; +import funkin.graphics.shaders.GaussianBlurShader; +import openfl.display.BlendMode; +import funkin.graphics.FunkinSprite; +import flixel.tweens.FlxEase; +import flixel.tweens.FlxTween; +import flixel.addons.effects.FlxTrail; +import flixel.util.FlxColor; class SongMenuItem extends FlxSpriteGroup { @@ -31,9 +38,10 @@ class SongMenuItem extends FlxSpriteGroup public var songText:CapsuleText; public var favIcon:FlxSprite; - public var ranking:FlxSprite; + public var ranking:FreeplayRank; + public var blurredRanking:FreeplayRank; - var ranks:Array = ["fail", "average", "great", "excellent", "perfect"]; + var ranks:Array = ["fail", "average", "great", "excellent", "perfect", "perfectsick"]; public var targetPos:FlxPoint = new FlxPoint(); public var doLerp:Bool = false; @@ -47,6 +55,22 @@ class SongMenuItem extends FlxSpriteGroup public var hsvShader(default, set):HSVShader; // var diffRatingSprite:FlxSprite; + public var bpmText:FlxSprite; + public var difficultyText:FlxSprite; + public var weekType:FlxSprite; + + public var newText:FlxSprite; + + // public var weekType:FlxSprite; + public var bigNumbers:Array = []; + + public var smallNumbers:Array = []; + + public var weekNumbers:Array = []; + + var impactThing:FunkinSprite; + + public var tempr:Int; public function new(x:Float, y:Float) { @@ -59,12 +83,64 @@ class SongMenuItem extends FlxSpriteGroup // capsule.animation add(capsule); + bpmText = new FlxSprite(144, 87).loadGraphic(Paths.image('freeplay/freeplayCapsule/bpmtext')); + bpmText.setGraphicSize(Std.int(bpmText.width * 0.9)); + add(bpmText); + + difficultyText = new FlxSprite(414, 87).loadGraphic(Paths.image('freeplay/freeplayCapsule/difficultytext')); + difficultyText.setGraphicSize(Std.int(difficultyText.width * 0.9)); + add(difficultyText); + + weekType = new FlxSprite(291, 87); + weekType.frames = Paths.getSparrowAtlas('freeplay/freeplayCapsule/weektypes'); + + weekType.animation.addByPrefix('WEEK', 'WEEK text instance 1', 24, false); + weekType.animation.addByPrefix('WEEKEND', 'WEEKEND text instance 1', 24, false); + + weekType.setGraphicSize(Std.int(weekType.width * 0.9)); + add(weekType); + + newText = new FlxSprite(454, 9); + newText.frames = Paths.getSparrowAtlas('freeplay/freeplayCapsule/new'); + newText.animation.addByPrefix('newAnim', 'NEW notif', 24, true); + newText.animation.play('newAnim', true); + newText.setGraphicSize(Std.int(newText.width * 0.9)); + + newText.visible = false; + + add(newText); + + // var debugNumber2:CapsuleNumber = new CapsuleNumber(0, 0, true, 2); + // add(debugNumber2); + + for (i in 0...2) + { + var bigNumber:CapsuleNumber = new CapsuleNumber(466 + (i * 30), 32, true, 0); + add(bigNumber); + + bigNumbers.push(bigNumber); + } + + for (i in 0...3) + { + var smallNumber:CapsuleNumber = new CapsuleNumber(185 + (i * 11), 88.5, false, 0); + add(smallNumber); + + smallNumbers.push(smallNumber); + } + // doesn't get added, simply is here to help with visibility of things for the pop in! grpHide = new FlxGroup(); var rank:String = FlxG.random.getObject(ranks); - ranking = new FlxSprite(capsule.width * 0.84, 30); + tempr = FlxG.random.int(0, 5); + ranking = new FreeplayRank(420, 41, tempr); + add(ranking); + + blurredRanking = new FreeplayRank(ranking.x, ranking.y, tempr); + blurredRanking.shader = new GaussianBlurShader(1); + add(blurredRanking); // ranking.loadGraphic(Paths.image('freeplay/ranks/' + rank)); // ranking.scale.x = ranking.scale.y = realScaled; // ranking.alpha = 0.75; @@ -73,11 +149,11 @@ class SongMenuItem extends FlxSpriteGroup // add(ranking); // grpHide.add(ranking); - switch (rank) - { - case 'perfect': - ranking.x -= 10; - } + // switch (rank) + // { + // case 'perfect': + // ranking.x -= 10; + // } grayscaleShader = new Grayscale(1); @@ -93,7 +169,7 @@ class SongMenuItem extends FlxSpriteGroup grpHide.add(songText); // TODO: Use value from metadata instead of random. - updateDifficultyRating(FlxG.random.int(0, 15)); + updateDifficultyRating(FlxG.random.int(0, 20)); pixelIcon = new FlxSprite(160, 35); @@ -103,21 +179,216 @@ class SongMenuItem extends FlxSpriteGroup add(pixelIcon); grpHide.add(pixelIcon); - favIcon = new FlxSprite(400, 40); + favIcon = new FlxSprite(380, 40); favIcon.frames = Paths.getSparrowAtlas('freeplay/favHeart'); favIcon.animation.addByPrefix('fav', 'favorite heart', 24, false); favIcon.animation.play('fav'); favIcon.setGraphicSize(50, 50); favIcon.visible = false; + favIcon.blend = BlendMode.ADD; add(favIcon); - // grpHide.add(favIcon); + + var weekNumber:CapsuleNumber = new CapsuleNumber(355, 88.5, false, 0); + add(weekNumber); + + weekNumbers.push(weekNumber); setVisibleGrp(false); } + // no way to grab weeks rn, so this needs to be done :/ + // negative values mean weekends + function checkWeek(name:String):Void + { + // trace(name); + var weekNum:Int = 0; + switch (name) + { + case 'bopeebo' | 'fresh' | 'dadbattle': + weekNum = 1; + case 'spookeez' | 'south' | 'monster': + weekNum = 2; + case 'pico' | 'philly-nice' | 'blammed': + weekNum = 3; + case "satin-panties" | 'high' | 'milf': + weekNum = 4; + case "cocoa" | 'eggnog' | 'winter-horrorland': + weekNum = 5; + case 'senpai' | 'roses' | 'thorns': + weekNum = 6; + case 'ugh' | 'guns' | 'stress': + weekNum = 7; + case 'darnell' | 'lit-up' | '2hot' | 'blazin': + weekNum = -1; + default: + weekNum = 0; + } + + weekNumbers[0].digit = Std.int(Math.abs(weekNum)); + + if (weekNum == 0) + { + weekType.visible = false; + weekNumbers[0].visible = false; + } + else + { + weekType.visible = true; + weekNumbers[0].visible = true; + } + if (weekNum > 0) + { + weekType.animation.play('WEEK', true); + } + else + { + weekType.animation.play('WEEKEND', true); + weekNumbers[0].offset.x -= 35; + } + } + + // 255, 27 normal + // 220, 27 favourited + public function checkClip():Void + { + var clipSize:Int = 290; + var clipType:Int = 0; + + if (ranking.visible == true) clipType += 1; + if (favIcon.visible == true) clipType += 1; + switch (clipType) + { + case 2: + clipSize = 220; + case 1: + clipSize = 255; + } + songText.clipWidth = clipSize; + } + + function updateBPM(newBPM:Int):Void + { + trace(newBPM); + + var shiftX:Float = 191; + var tempShift:Float = 0; + + if (Math.floor(newBPM / 100) == 1) + { + shiftX = 186; + } + + for (i in 0...smallNumbers.length) + { + smallNumbers[i].x = this.x + (shiftX + (i * 11)); + switch (i) + { + case 0: + if (newBPM < 100) + { + smallNumbers[i].digit = 0; + } + else + { + smallNumbers[i].digit = Math.floor(newBPM / 100) % 10; + } + + case 1: + if (newBPM < 10) + { + smallNumbers[i].digit = 0; + } + else + { + smallNumbers[i].digit = Math.floor(newBPM / 10) % 10; + + if (Math.floor(newBPM / 10) % 10 == 1) tempShift = -4; + } + case 2: + smallNumbers[i].digit = newBPM % 10; + default: + trace('why the fuck is this being called'); + } + smallNumbers[i].x += tempShift; + } + // diffRatingSprite.loadGraphic(Paths.image('freeplay/diffRatings/diff${ratingPadded}')); + // diffRatingSprite.visible = false; + } + + var evilTrail:FlxTrail; + + public function fadeAnim() + { + impactThing = new FunkinSprite(0, 0); + impactThing.frames = capsule.frames; + impactThing.frame = capsule.frame; + impactThing.updateHitbox(); + // impactThing.x = capsule.x; + // impactThing.y = capsule.y; + // picoFade.stamp(this, 0, 0); + impactThing.alpha = 0; + impactThing.zIndex = capsule.zIndex - 3; + add(impactThing); + FlxTween.tween(impactThing.scale, {x: 2.5, y: 2.5}, 0.5); + // FlxTween.tween(impactThing, {alpha: 0}, 0.5); + + evilTrail = new FlxTrail(impactThing, null, 15, 2, 0.01, 0.069); + evilTrail.blend = BlendMode.ADD; + evilTrail.zIndex = capsule.zIndex - 5; + FlxTween.tween(evilTrail, {alpha: 0}, 0.6, + { + ease: FlxEase.quadOut, + onComplete: function(_) { + remove(evilTrail); + } + }); + add(evilTrail); + + switch (tempr) + { + case 0: + evilTrail.color = 0xFF6044FF; + case 1: + evilTrail.color = 0xFFEF8764; + case 2: + evilTrail.color = 0xFFEAF6FF; + case 3: + evilTrail.color = 0xFFFDCB42; + case 4: + evilTrail.color = 0xFFFF58B4; + case 5: + evilTrail.color = 0xFFFFB619; + } + } + + public function getTrailColor():FlxColor + { + return evilTrail.color; + } + function updateDifficultyRating(newRating:Int):Void { var ratingPadded:String = newRating < 10 ? '0$newRating' : '$newRating'; + + for (i in 0...bigNumbers.length) + { + switch (i) + { + case 0: + if (newRating > 10) + { + bigNumbers[i].digit = 0; + } + else + { + bigNumbers[i].digit = Math.floor(newRating / 10); + } + case 1: + bigNumbers[i].digit = newRating % 10; + default: + trace('why the fuck is this being called'); + } + } // diffRatingSprite.loadGraphic(Paths.image('freeplay/diffRatings/diff${ratingPadded}')); // diffRatingSprite.visible = false; } @@ -169,8 +440,11 @@ class SongMenuItem extends FlxSpriteGroup // Update capsule character. if (songData?.songCharacter != null) setCharacter(songData.songCharacter); updateDifficultyRating(songData?.songRating ?? 0); + updateBPM(Std.int(songData?.songStartingBpm) ?? 0); // Update opacity, offsets, etc. updateSelected(); + + checkWeek(songData?.songId); } /** @@ -289,6 +563,28 @@ class SongMenuItem extends FlxSpriteGroup override function update(elapsed:Float):Void { + if (impactThing != null) impactThing.angle = capsule.angle; + + // if (FlxG.keys.justPressed.I) + // { + // newText.y -= 1; + // trace(this.x - newText.x, this.y - newText.y); + // } + // if (FlxG.keys.justPressed.J) + // { + // newText.x -= 1; + // trace(this.x - newText.x, this.y - newText.y); + // } + // if (FlxG.keys.justPressed.L) + // { + // newText.x += 1; + // trace(this.x - newText.x, this.y - newText.y); + // } + // if (FlxG.keys.justPressed.K) + // { + // newText.y += 1; + // trace(this.x - newText.x, this.y - newText.y); + // } if (doJumpIn) { frameInTicker += elapsed; @@ -358,5 +654,137 @@ class SongMenuItem extends FlxSpriteGroup capsule.animation.play(this.selected ? "selected" : "unselected"); ranking.alpha = this.selected ? 1 : 0.7; ranking.color = this.selected ? 0xFFFFFFFF : 0xFFAAAAAA; + + if (selected) + { + if (songText.tooLong == true) songText.initMove(); + } + else + { + if (songText.tooLong == true) songText.resetText(); + } + } +} + +class FreeplayRank extends FlxSprite +{ + public var rank(default, set):Int = 0; + + var numToRank:Array = ["LOSS", "GOOD", "GREAT", "EXCELLENT", "PERFECT", "PERFECTSICK"]; + + function set_rank(val):Int + { + animation.play(numToRank[val], true, false); + + centerOffsets(false); + + switch (val) + { + case 0: + // offset.x -= 1; + case 1: + // offset.x -= 1; + offset.y -= 8; + case 2: + // offset.x -= 1; + offset.y -= 8; + case 3: + // offset.y += 5; + case 4: + // offset.y += 5; + default: + centerOffsets(false); + } + updateHitbox(); + return val; + } + + public var baseY:Float = 0; + public var baseX:Float = 0; + + public function new(x:Float, y:Float, ?initRank:Int = 0) + { + super(x, y); + + frames = Paths.getSparrowAtlas('freeplay/rankbadges'); + + animation.addByPrefix('PERFECT', 'PERFECT rank0', 24, false); + animation.addByPrefix('EXCELLENT', 'EXCELLENT rank0', 24, false); + animation.addByPrefix('GOOD', 'GOOD rank0', 24, false); + animation.addByPrefix('PERFECTSICK', 'PERFECT rank GOLD', 24, false); + animation.addByPrefix('GREAT', 'GREAT rank0', 24, false); + animation.addByPrefix('LOSS', 'LOSS rank0', 24, false); + + blend = BlendMode.ADD; + + this.rank = initRank; + + animation.play(numToRank[initRank], true); + + // setGraphicSize(Std.int(width * 0.9)); + scale.set(0.9, 0.9); + updateHitbox(); + } +} + +class CapsuleNumber extends FlxSprite +{ + public var digit(default, set):Int = 0; + + function set_digit(val):Int + { + animation.play(numToString[val], true, false, 0); + + centerOffsets(false); + + switch (val) + { + case 1: + offset.x -= 4; + case 3: + offset.x -= 1; + + case 6: + + case 4: + // offset.y += 5; + case 9: + // offset.y += 5; + default: + centerOffsets(false); + } + return val; + } + + public var baseY:Float = 0; + public var baseX:Float = 0; + + var numToString:Array = ["ZERO", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE"]; + + public function new(x:Float, y:Float, big:Bool = false, ?initDigit:Int = 0) + { + super(x, y); + + if (big) + { + frames = Paths.getSparrowAtlas('freeplay/freeplayCapsule/bignumbers'); + } + else + { + frames = Paths.getSparrowAtlas('freeplay/freeplayCapsule/smallnumbers'); + } + + for (i in 0...10) + { + var stringNum:String = numToString[i]; + animation.addByPrefix(stringNum, '$stringNum', 24, false); + } + + this.digit = initDigit; + + animation.play(numToString[initDigit], true); + + setGraphicSize(Std.int(width * 0.9)); + updateHitbox(); } } From 5f9019a2a3f9283fa96684b91ce17cd8e1ff5b23 Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Thu, 30 May 2024 04:35:05 +0100 Subject: [PATCH 085/266] update assets submod --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index fe52d20de7..dabdf9b1d3 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit fe52d20de7025d90cadb429dbdedf6d986727088 +Subproject commit dabdf9b1d361afa0f65c87b9c0f12cf90b0eebdf From b7a828e7d89756a20c7415876446ddda2c1cbd84 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Thu, 30 May 2024 05:25:51 -0400 Subject: [PATCH 086/266] Make Freeplay use correct ranks, play the slam animation after Results, new Results music --- assets | 2 +- source/funkin/InitState.hx | 4 +- source/funkin/play/PlayState.hx | 3 +- source/funkin/play/ResultState.hx | 226 ++++++--------------- source/funkin/play/scoring/Scoring.hx | 176 ++++++++++++++++ source/funkin/save/Save.hx | 13 +- source/funkin/ui/freeplay/FreeplayState.hx | 107 +++++++--- source/funkin/ui/freeplay/SongMenuItem.hx | 97 +++++---- 8 files changed, 388 insertions(+), 240 deletions(-) diff --git a/assets b/assets index 8fea0bf1fe..2719d3fc1d 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 8fea0bf1fe07b6dd0efb8ecf46dc8091b0177007 +Subproject commit 2719d3fc1d8f5d0cbafae8d27141d6c471148482 diff --git a/source/funkin/InitState.hx b/source/funkin/InitState.hx index a945c10c54..d0009f95b7 100644 --- a/source/funkin/InitState.hx +++ b/source/funkin/InitState.hx @@ -220,6 +220,8 @@ class InitState extends FlxState { storyMode: false, title: "CUM SONG", + songId: "cum", + difficultyId: "hard", isNewHighscore: true, scoreData: { @@ -227,7 +229,7 @@ class InitState extends FlxState tallies: { sick: 130, - good: 25, + good: 70, bad: 69, shit: 69, missed: 69, diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index a95166e219..e69a50b00d 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -3123,9 +3123,10 @@ class PlayState extends MusicBeatSubState var res:ResultState = new ResultState( { storyMode: PlayStatePlaylist.isStoryMode, + songId: currentChart.song.id, + difficultyId: currentDifficulty, title: PlayStatePlaylist.isStoryMode ? ('${PlayStatePlaylist.campaignTitle}') : ('${currentChart.songName} by ${currentChart.songArtist}'), prevScoreData: prevScoreData, - difficultyId: currentDifficulty, scoreData: { score: PlayStatePlaylist.isStoryMode ? PlayStatePlaylist.campaignScore : songScore, diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx index ee7c8eade5..79880038df 100644 --- a/source/funkin/play/ResultState.hx +++ b/source/funkin/play/ResultState.hx @@ -21,6 +21,7 @@ import funkin.audio.FunkinSound; import flixel.util.FlxGradient; import flixel.util.FlxTimer; import funkin.save.Save; +import funkin.play.scoring.Scoring; import funkin.save.Save.SaveScoreData; import funkin.graphics.shaders.LeftMaskShader; import funkin.play.components.TallyCounter; @@ -34,7 +35,7 @@ class ResultState extends MusicBeatSubState { final params:ResultsStateParams; - final rank:ResultRank; + final rank:ScoringRank; final songName:FlxBitmapText; final difficulty:FlxSprite; final clearPercentSmall:ClearPercentCounter; @@ -64,8 +65,7 @@ class ResultState extends MusicBeatSubState this.params = params; - rank = calculateRank(params); - // rank = SHIT; + rank = Scoring.calculateRank(params.scoreData) ?? SHIT; // We build a lot of this stuff in the constructor, then place it in create(). // This prevents having to do `null` checks everywhere. @@ -99,6 +99,8 @@ class ResultState extends MusicBeatSubState override function create():Void { + if (FlxG.sound.music != null) FlxG.sound.music.stop(); + // Reset the camera zoom on the results screen. FlxG.camera.zoom = 1.0; @@ -327,6 +329,33 @@ class ResultState extends MusicBeatSubState } }; + new FlxTimer().start(rank.getMusicDelay(), _ -> { + if (rank.hasMusicIntro()) + { + // Play the intro music. + var introMusic:String = Paths.music(rank.getMusicPath() + '/' + rank.getMusicPath() + '-intro'); + FunkinSound.load(introMusic, 1.0, false, true, true, () -> { + FunkinSound.playMusic(rank.getMusicPath(), + { + startingVolume: 1.0, + overrideExisting: true, + restartTrack: true, + loop: rank.shouldMusicLoop() + }); + }); + } + else + { + FunkinSound.playMusic(rank.getMusicPath(), + { + startingVolume: 1.0, + overrideExisting: true, + restartTrack: true, + loop: rank.shouldMusicLoop() + }); + } + }); + refresh(); super.create(); @@ -376,7 +405,8 @@ class ResultState extends MusicBeatSubState displayRankText(); - new FlxTimer().start(2.0, _ -> { + // previously 2.0 seconds + new FlxTimer().start(0.25, _ -> { FlxTween.tween(clearPercentCounter, {alpha: 0}, 0.5, { startDelay: 0.5, @@ -444,28 +474,6 @@ class ResultState extends MusicBeatSubState { showSmallClearPercent(); - FunkinSound.playMusic(rank.getMusicPath(), - { - startingVolume: 1.0, - overrideExisting: true, - restartTrack: true, - loop: rank.shouldMusicLoop() - }); - - FlxG.sound.music.onComplete = () -> { - if (rank == SHIT) - { - FunkinSound.playMusic('bluu', - { - startingVolume: 0.0, - overrideExisting: true, - restartTrack: true, - loop: true - }); - FlxG.sound.music.fadeIn(10.0, 0.0, 1.0); - } - } - switch (rank) { case PERFECT | PERFECT_GOLD: @@ -478,7 +486,6 @@ class ResultState extends MusicBeatSubState bfPerfect.visible = true; bfPerfect.playAnimation(''); } - case EXCELLENT: if (bfExcellent == null) { @@ -489,7 +496,6 @@ class ResultState extends MusicBeatSubState bfExcellent.visible = true; bfExcellent.playAnimation('Intro'); } - case GREAT: if (bfGreat == null) { @@ -500,7 +506,6 @@ class ResultState extends MusicBeatSubState bfGreat.visible = true; bfGreat.playAnimation('Intro'); } - case SHIT: if (bfShit == null) { @@ -511,7 +516,6 @@ class ResultState extends MusicBeatSubState bfShit.visible = true; bfShit.playAnimation('Intro'); } - case GOOD: if (bfGood == null) { @@ -521,7 +525,6 @@ class ResultState extends MusicBeatSubState { bfGood.animation.play('fall'); bfGood.visible = true; - new FlxTimer().start((1 / 24) * 22, _ -> { // plays about 22 frames (at 24fps timing) after bf spawns in if (gfGood != null) @@ -635,154 +638,39 @@ class ResultState extends MusicBeatSubState if (controls.PAUSE) { - FlxTween.tween(FlxG.sound.music, {volume: 0}, 0.8); - FlxTween.tween(FlxG.sound.music, {pitch: 3}, 0.1, - { - onComplete: _ -> { - FlxTween.tween(FlxG.sound.music, {pitch: 0.5}, 0.4); - } - }); + if (FlxG.sound.music != null) + { + FlxTween.tween(FlxG.sound.music, {volume: 0}, 0.8); + FlxTween.tween(FlxG.sound.music, {pitch: 3}, 0.1, + { + onComplete: _ -> { + FlxTween.tween(FlxG.sound.music, {pitch: 0.5}, 0.4); + } + }); + } if (params.storyMode) { openSubState(new funkin.ui.transition.StickerSubState(null, (sticker) -> new StoryMenuState(sticker))); } else { - openSubState(new funkin.ui.transition.StickerSubState(null, (sticker) -> FreeplayState.build(null, sticker))); + openSubState(new funkin.ui.transition.StickerSubState(null, (sticker) -> FreeplayState.build( + { + { + fromResults: + { + oldRank: Scoring.calculateRank(params?.prevScoreData), + newRank: rank, + songId: params.songId, + difficultyId: params.difficultyId + } + } + }, sticker))); } } super.update(elapsed); } - - public static function calculateRank(params:ResultsStateParams):ResultRank - { - // Perfect (Platinum) is a Sick Full Clear - var isPerfectGold = params.scoreData.tallies.sick == params.scoreData.tallies.totalNotes; - if (isPerfectGold) return ResultRank.PERFECT_GOLD; - - // Else, use the standard grades - - // Grade % (only good and sick), 1.00 is a full combo - var grade = (params.scoreData.tallies.sick + params.scoreData.tallies.good) / params.scoreData.tallies.totalNotes; - // Clear % (including bad and shit). 1.00 is a full clear but not a full combo - var clear = (params.scoreData.tallies.totalNotesHit) / params.scoreData.tallies.totalNotes; - - if (grade == Constants.RANK_PERFECT_THRESHOLD) - { - return ResultRank.PERFECT; - } - else if (grade >= Constants.RANK_EXCELLENT_THRESHOLD) - { - return ResultRank.EXCELLENT; - } - else if (grade >= Constants.RANK_GREAT_THRESHOLD) - { - return ResultRank.GREAT; - } - else if (grade >= Constants.RANK_GOOD_THRESHOLD) - { - return ResultRank.GOOD; - } - else - { - return ResultRank.SHIT; - } - } -} - -enum abstract ResultRank(String) -{ - var PERFECT_GOLD; - var PERFECT; - var EXCELLENT; - var GREAT; - var GOOD; - var SHIT; - - public function getMusicPath():String - { - switch (abstract) - { - case PERFECT_GOLD: - return 'resultsPERFECT'; - case PERFECT: - return 'resultsPERFECT'; - case EXCELLENT: - return 'resultsNORMAL'; - case GREAT: - return 'resultsNORMAL'; - case GOOD: - return 'resultsNORMAL'; - case SHIT: - return 'resultsSHIT'; - default: - return 'resultsNORMAL'; - } - } - - public function shouldMusicLoop():Bool - { - switch (abstract) - { - case PERFECT_GOLD: - return true; - case PERFECT: - return true; - case EXCELLENT: - return true; - case GREAT: - return true; - case GOOD: - return true; - case SHIT: - return false; - default: - return false; - } - } - - public function getHorTextAsset() - { - switch (abstract) - { - case PERFECT_GOLD: - return 'resultScreen/rankText/rankScrollPERFECT'; - case PERFECT: - return 'resultScreen/rankText/rankScrollPERFECT'; - case EXCELLENT: - return 'resultScreen/rankText/rankScrollEXCELLENT'; - case GREAT: - return 'resultScreen/rankText/rankScrollGREAT'; - case GOOD: - return 'resultScreen/rankText/rankScrollGOOD'; - case SHIT: - return 'resultScreen/rankText/rankScrollLOSS'; - default: - return 'resultScreen/rankText/rankScrollGOOD'; - } - } - - public function getVerTextAsset() - { - switch (abstract) - { - case PERFECT_GOLD: - return 'resultScreen/rankText/rankTextPERFECT'; - case PERFECT: - return 'resultScreen/rankText/rankTextPERFECT'; - case EXCELLENT: - return 'resultScreen/rankText/rankTextEXCELLENT'; - case GREAT: - return 'resultScreen/rankText/rankTextGREAT'; - case GOOD: - return 'resultScreen/rankText/rankTextGOOD'; - case SHIT: - return 'resultScreen/rankText/rankTextLOSS'; - default: - return 'resultScreen/rankText/rankTextGOOD'; - } - } } typedef ResultsStateParams = @@ -797,6 +685,8 @@ typedef ResultsStateParams = */ var title:String; + var songId:String; + /** * Whether the displayed score is a new highscore */ diff --git a/source/funkin/play/scoring/Scoring.hx b/source/funkin/play/scoring/Scoring.hx index 744091b443..6155ec8798 100644 --- a/source/funkin/play/scoring/Scoring.hx +++ b/source/funkin/play/scoring/Scoring.hx @@ -1,5 +1,7 @@ package funkin.play.scoring; +import funkin.save.Save.SaveScoreData; + /** * Which system to use when scoring and judging notes. */ @@ -344,4 +346,178 @@ class Scoring return 'miss'; } } + + public static function calculateRank(scoreData:Null):Null + { + if (scoreData == null) return null; + + // Perfect (Platinum) is a Sick Full Clear + var isPerfectGold = scoreData.tallies.sick == scoreData.tallies.totalNotes; + if (isPerfectGold) return ScoringRank.PERFECT_GOLD; + + // Else, use the standard grades + + // Grade % (only good and sick), 1.00 is a full combo + var grade = (scoreData.tallies.sick + scoreData.tallies.good) / scoreData.tallies.totalNotes; + // Clear % (including bad and shit). 1.00 is a full clear but not a full combo + var clear = (scoreData.tallies.totalNotesHit) / scoreData.tallies.totalNotes; + + if (grade == Constants.RANK_PERFECT_THRESHOLD) + { + return ScoringRank.PERFECT; + } + else if (grade >= Constants.RANK_EXCELLENT_THRESHOLD) + { + return ScoringRank.EXCELLENT; + } + else if (grade >= Constants.RANK_GREAT_THRESHOLD) + { + return ScoringRank.GREAT; + } + else if (grade >= Constants.RANK_GOOD_THRESHOLD) + { + return ScoringRank.GOOD; + } + else + { + return ScoringRank.SHIT; + } + } +} + +enum abstract ScoringRank(String) +{ + var PERFECT_GOLD; + var PERFECT; + var EXCELLENT; + var GREAT; + var GOOD; + var SHIT; + + /** + * Delay in seconds + */ + public function getMusicDelay():Float + { + switch (abstract) + { + case PERFECT_GOLD | PERFECT: + // return 2.5; + return 5.0; + case EXCELLENT: + return 1.75; + default: + return 3.5; + } + } + + public function getMusicPath():String + { + switch (abstract) + { + case PERFECT_GOLD: + return 'resultsPERFECT'; + case PERFECT: + return 'resultsPERFECT'; + case EXCELLENT: + return 'resultsEXCELLENT'; + case GREAT: + return 'resultsNORMAL'; + case GOOD: + return 'resultsNORMAL'; + case SHIT: + return 'resultsSHIT'; + default: + return 'resultsNORMAL'; + } + } + + public function hasMusicIntro():Bool + { + switch (abstract) + { + case EXCELLENT: + return true; + case SHIT: + return true; + default: + return false; + } + } + + public function getFreeplayRankIconAsset():Null + { + switch (abstract) + { + case PERFECT_GOLD: + return 'PERFECTSICK'; + case PERFECT: + return 'PERFECT'; + case EXCELLENT: + return 'EXCELLENT'; + case GREAT: + return 'GREAT'; + case GOOD: + return 'GOOD'; + case SHIT: + return 'LOSS'; + default: + return null; + } + } + + public function shouldMusicLoop():Bool + { + switch (abstract) + { + case PERFECT_GOLD | PERFECT | EXCELLENT | GREAT | GOOD: + return true; + case SHIT: + return false; + default: + return false; + } + } + + public function getHorTextAsset() + { + switch (abstract) + { + case PERFECT_GOLD: + return 'resultScreen/rankText/rankScrollPERFECT'; + case PERFECT: + return 'resultScreen/rankText/rankScrollPERFECT'; + case EXCELLENT: + return 'resultScreen/rankText/rankScrollEXCELLENT'; + case GREAT: + return 'resultScreen/rankText/rankScrollGREAT'; + case GOOD: + return 'resultScreen/rankText/rankScrollGOOD'; + case SHIT: + return 'resultScreen/rankText/rankScrollLOSS'; + default: + return 'resultScreen/rankText/rankScrollGOOD'; + } + } + + public function getVerTextAsset() + { + switch (abstract) + { + case PERFECT_GOLD: + return 'resultScreen/rankText/rankTextPERFECT'; + case PERFECT: + return 'resultScreen/rankText/rankTextPERFECT'; + case EXCELLENT: + return 'resultScreen/rankText/rankTextEXCELLENT'; + case GREAT: + return 'resultScreen/rankText/rankTextGREAT'; + case GOOD: + return 'resultScreen/rankText/rankTextGOOD'; + case SHIT: + return 'resultScreen/rankText/rankTextLOSS'; + default: + return 'resultScreen/rankText/rankTextGOOD'; + } + } } diff --git a/source/funkin/save/Save.hx b/source/funkin/save/Save.hx index 934d6a4aa1..7f25a8e014 100644 --- a/source/funkin/save/Save.hx +++ b/source/funkin/save/Save.hx @@ -1,15 +1,17 @@ package funkin.save; import flixel.util.FlxSave; -import funkin.save.migrator.SaveDataMigrator; -import thx.semver.Version; import funkin.input.Controls.Device; +import funkin.play.scoring.Scoring; +import funkin.play.scoring.Scoring.ScoringRank; import funkin.save.migrator.RawSaveData_v1_0_0; import funkin.save.migrator.SaveDataMigrator; +import funkin.save.migrator.SaveDataMigrator; import funkin.ui.debug.charting.ChartEditorState.ChartEditorLiveInputStyle; import funkin.ui.debug.charting.ChartEditorState.ChartEditorTheme; -import thx.semver.Version; import funkin.util.SerializerUtil; +import thx.semver.Version; +import thx.semver.Version; @:nullSafety class Save @@ -492,6 +494,11 @@ class Save return song.get(difficultyId); } + public function getSongRank(songId:String, difficultyId:String = 'normal'):Null + { + return Scoring.calculateRank(getSongScore(songId, difficultyId)); + } + /** * Apply the score the user achieved for a given song on a given difficulty. */ diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 530f28c339..904a2ca4aa 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -34,6 +34,8 @@ import funkin.play.song.Song; import funkin.save.Save; import funkin.save.Save.SaveScoreData; import funkin.ui.AtlasText; +import funkin.play.scoring.Scoring; +import funkin.play.scoring.Scoring.ScoringRank; import funkin.ui.mainmenu.MainMenuState; import funkin.ui.MusicBeatSubState; import funkin.ui.transition.LoadingState; @@ -49,6 +51,34 @@ import funkin.effects.IntervalShake; typedef FreeplayStateParams = { ?character:String, + + ?fromResults:FromResultsParams, +}; + +/** + * A set of parameters for transitioning to the FreeplayState from the ResultsState. + */ +typedef FromResultsParams = +{ + /** + * The previous rank the song hand, if any. Null if it had no score before. + */ + var ?oldRank:ScoringRank; + + /** + * The new rank the song has. + */ + var newRank:ScoringRank; + + /** + * The song ID to play the animation on. + */ + var songId:String; + + /** + * The difficulty ID to play the animation on. + */ + var difficultyId:String; }; /** @@ -160,10 +190,14 @@ class FreeplayState extends MusicBeatSubState var bgDad:FlxSprite; var cardGlow:FlxSprite; + var fromResultsParams:Null = null; + public function new(?params:FreeplayStateParams, ?stickers:StickerSubState) { currentCharacter = params?.character ?? Constants.DEFAULT_CHARACTER; + fromResultsParams = params?.fromResults; + if (stickers != null) { stickerSubState = stickers; @@ -587,6 +621,11 @@ class FreeplayState extends MusicBeatSubState cardGlow.visible = true; FlxTween.tween(cardGlow, {alpha: 0, "scale.x": 1.2, "scale.y": 1.2}, 0.45, {ease: FlxEase.sineOut}); + + if (fromResultsParams != null) + { + rankAnimStart(fromResultsParams); + } }); generateSongList(null, false); @@ -657,6 +696,12 @@ class FreeplayState extends MusicBeatSubState // If curSelected is 0, the result will be null and fall back to the rememberedSongId. rememberedSongId = grpCapsules.members[curSelected]?.songData?.songId ?? rememberedSongId; + if (fromResultsParams != null) + { + rememberedSongId = fromResultsParams.songId; + rememberedDifficulty = fromResultsParams.difficultyId; + } + for (cap in grpCapsules.members) { cap.songText.resetText(); @@ -763,8 +808,10 @@ class FreeplayState extends MusicBeatSubState return songsToFilter; } - function rankAnimStart() + function rankAnimStart(fromResults:Null):Void { + busy = true; + dj.fistPump(); // rankCamera.fade(FlxColor.BLACK, 0.5, true); rankCamera.fade(0xFF000000, 0.5, true, null, true); @@ -789,21 +836,21 @@ class FreeplayState extends MusicBeatSubState new FlxTimer().start(0.5, _ -> { grpCapsules.members[curSelected].doLerp = false; - rankDisplayNew(); + rankDisplayNew(fromResults); }); } - function rankDisplayNew() + function rankDisplayNew(fromResults:Null):Void { grpCapsules.members[curSelected].ranking.alpha = 1; grpCapsules.members[curSelected].blurredRanking.alpha = 1; grpCapsules.members[curSelected].ranking.scale.set(20, 20); grpCapsules.members[curSelected].blurredRanking.scale.set(20, 20); - // var tempr:Int = FlxG.random.int(0, 4); - // grpCapsules.members[curSelected].ranking.rank = tempr; - grpCapsules.members[curSelected].ranking.animation.play(grpCapsules.members[curSelected].ranking.animation.curAnim.name, true); + grpCapsules.members[curSelected].ranking.animation.play(fromResults.newRank.getFreeplayRankIconAsset(), true); + // grpCapsules.members[curSelected].ranking.animation.curAnim.name, true); + 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); @@ -811,13 +858,13 @@ class FreeplayState extends MusicBeatSubState new FlxTimer().start(0.1, _ -> { trace(grpCapsules.members[curSelected].ranking.rank); - switch (grpCapsules.members[curSelected].tempr) + switch (fromResultsParams?.newRank) { - case 0: + case SHIT: FunkinSound.playOnce(Paths.sound('ranks/rankinbad')); - case 4: + case PERFECT: FunkinSound.playOnce(Paths.sound('ranks/rankinperfect')); - case 5: + case PERFECT_GOLD: FunkinSound.playOnce(Paths.sound('ranks/rankinperfect')); default: FunkinSound.playOnce(Paths.sound('ranks/rankinnormal')); @@ -846,31 +893,31 @@ class FreeplayState extends MusicBeatSubState }); new FlxTimer().start(0.6, _ -> { - rankAnimSlam(); + rankAnimSlam(fromResults); // IntervalShake.shake(grpCapsules.members[curSelected].capsule, 0.3, 1 / 30, 0, 0.3, FlxEase.quartIn); }); } - function rankAnimSlam() + function rankAnimSlam(fromResultsParams:Null) { // FlxTween.tween(rankCamera, {"zoom": 1.9}, 0.5, {ease: FlxEase.backOut}); FlxTween.tween(rankBg, {alpha: 0}, 0.5, {ease: FlxEase.expoIn}); // FlxTween.tween(grpCapsules.members[curSelected], {angle: 5}, 0.5, {ease: FlxEase.backIn}); - switch (grpCapsules.members[curSelected].tempr) + switch (fromResultsParams?.newRank) { - case 0: + case SHIT: FunkinSound.playOnce(Paths.sound('ranks/loss')); - case 1: + case GOOD: FunkinSound.playOnce(Paths.sound('ranks/good')); - case 2: + case GREAT: FunkinSound.playOnce(Paths.sound('ranks/great')); - case 3: + case EXCELLENT: FunkinSound.playOnce(Paths.sound('ranks/excellent')); - case 4: + case PERFECT: FunkinSound.playOnce(Paths.sound('ranks/perfect')); - case 5: + case PERFECT_GOLD: FunkinSound.playOnce(Paths.sound('ranks/perfect')); default: FunkinSound.playOnce(Paths.sound('ranks/loss')); @@ -880,7 +927,7 @@ class FreeplayState extends MusicBeatSubState new FlxTimer().start(0.5, _ -> { funnyCam.shake(0.0045, 0.35); - if (grpCapsules.members[curSelected].tempr == 0) + if (fromResultsParams?.newRank == SHIT) { dj.pumpFistBad(); } @@ -915,6 +962,9 @@ class FreeplayState extends MusicBeatSubState IntervalShake.shake(capsule, 0.6, 1 / 24, 0.12, 0, FlxEase.quadOut, function(_) { capsule.doLerp = true; capsule.cameras = [funnyCam]; + + // NOW we can interact with the menu + busy = false; }, null); // FlxTween.tween(capsule, {"targetPos.x": capsule.targetPos.x - 50}, 0.6, @@ -981,7 +1031,10 @@ class FreeplayState extends MusicBeatSubState var spamTimer:Float = 0; var spamming:Bool = false; - var busy:Bool = false; // Set to true once the user has pressed enter to select a song. + /** + * If true, disable interaction with the interface. + */ + var busy:Bool = false; var originalPos:FlxPoint = new FlxPoint(); @@ -989,19 +1042,20 @@ class FreeplayState extends MusicBeatSubState { super.update(elapsed); + #if debug if (FlxG.keys.justPressed.T) { - rankAnimStart(); + rankAnimStart(fromResultsParams); } if (FlxG.keys.justPressed.H) { - rankDisplayNew(); + rankDisplayNew(fromResultsParams); } if (FlxG.keys.justPressed.G) { - rankAnimSlam(); + rankAnimSlam(fromResultsParams); } if (FlxG.keys.justPressed.I) @@ -1024,6 +1078,7 @@ class FreeplayState extends MusicBeatSubState confirmTextGlow.y += 1; trace(confirmTextGlow.x, confirmTextGlow.y); } + #end if (FlxG.keys.justPressed.F) { @@ -1765,6 +1820,8 @@ class FreeplaySongData public var currentDifficulty(default, set):String = Constants.DEFAULT_DIFFICULTY; + public var scoringRank:Null = null; + var displayedVariations:Array = [Constants.DEFAULT_VARIATION]; function set_currentDifficulty(value:String):String @@ -1827,6 +1884,8 @@ class FreeplaySongData { this.albumId = songDifficulty.album; } + + this.scoringRank = Save.instance.getSongRank(songId, currentDifficulty); } } diff --git a/source/funkin/ui/freeplay/SongMenuItem.hx b/source/funkin/ui/freeplay/SongMenuItem.hx index 536a9cfe67..ad6ea386e7 100644 --- a/source/funkin/ui/freeplay/SongMenuItem.hx +++ b/source/funkin/ui/freeplay/SongMenuItem.hx @@ -20,6 +20,7 @@ import funkin.graphics.FunkinSprite; import flixel.tweens.FlxEase; import flixel.tweens.FlxTween; import flixel.addons.effects.FlxTrail; +import funkin.play.scoring.Scoring.ScoringRank; import flixel.util.FlxColor; class SongMenuItem extends FlxSpriteGroup @@ -70,8 +71,6 @@ class SongMenuItem extends FlxSpriteGroup var impactThing:FunkinSprite; - public var tempr:Int; - public function new(x:Float, y:Float) { super(x, y); @@ -132,13 +131,10 @@ class SongMenuItem extends FlxSpriteGroup // doesn't get added, simply is here to help with visibility of things for the pop in! grpHide = new FlxGroup(); - var rank:String = FlxG.random.getObject(ranks); - - tempr = FlxG.random.int(0, 5); - ranking = new FreeplayRank(420, 41, tempr); + ranking = new FreeplayRank(420, 41); add(ranking); - blurredRanking = new FreeplayRank(ranking.x, ranking.y, tempr); + blurredRanking = new FreeplayRank(ranking.x, ranking.y); blurredRanking.shader = new GaussianBlurShader(1); add(blurredRanking); // ranking.loadGraphic(Paths.image('freeplay/ranks/' + rank)); @@ -344,19 +340,19 @@ class SongMenuItem extends FlxSpriteGroup }); add(evilTrail); - switch (tempr) + switch (ranking.rank) { - case 0: + case SHIT: evilTrail.color = 0xFF6044FF; - case 1: + case GOOD: evilTrail.color = 0xFFEF8764; - case 2: + case GREAT: evilTrail.color = 0xFFEAF6FF; - case 3: + case EXCELLENT: evilTrail.color = 0xFFFDCB42; - case 4: + case PERFECT: evilTrail.color = 0xFFFF58B4; - case 5: + case PERFECT_GOLD: evilTrail.color = 0xFFFFB619; } } @@ -393,6 +389,12 @@ class SongMenuItem extends FlxSpriteGroup // diffRatingSprite.visible = false; } + function updateScoringRank(newRank:Null):Void + { + this.ranking.rank = newRank; + this.blurredRanking.rank = newRank; + } + function set_hsvShader(value:HSVShader):HSVShader { this.hsvShader = value; @@ -441,6 +443,7 @@ class SongMenuItem extends FlxSpriteGroup if (songData?.songCharacter != null) setCharacter(songData.songCharacter); updateBPM(Std.int(songData?.songStartingBpm) ?? 0); updateDifficultyRating(songData?.difficultyRating ?? 0); + updateScoringRank(songData?.scoringRank); // Update opacity, offsets, etc. updateSelected(); @@ -668,41 +671,53 @@ class SongMenuItem extends FlxSpriteGroup class FreeplayRank extends FlxSprite { - public var rank(default, set):Int = 0; - - var numToRank:Array = ["LOSS", "GOOD", "GREAT", "EXCELLENT", "PERFECT", "PERFECTSICK"]; + public var rank(default, set):Null = null; - function set_rank(val):Int + function set_rank(val:Null):Null { - animation.play(numToRank[val], true, false); + rank = val; - centerOffsets(false); - - switch (val) + if (rank == null) { - case 0: - // offset.x -= 1; - case 1: - // offset.x -= 1; - offset.y -= 8; - case 2: + this.visible = false; + } + else + { + this.visible = true; + + animation.play(val.getFreeplayRankIconAsset(), true, false); + + centerOffsets(false); + + switch (val) + { + case SHIT: // offset.x -= 1; - offset.y -= 8; - case 3: - // offset.y += 5; - case 4: - // offset.y += 5; - default: - centerOffsets(false); + case GOOD: + // offset.x -= 1; + offset.y -= 8; + case GREAT: + // offset.x -= 1; + offset.y -= 8; + case EXCELLENT: + // offset.y += 5; + case PERFECT: + // offset.y += 5; + case PERFECT_GOLD: + // offset.y += 5; + default: + centerOffsets(false); + } + updateHitbox(); } - updateHitbox(); - return val; + + return rank = val; } - public var baseY:Float = 0; public var baseX:Float = 0; + public var baseY:Float = 0; - public function new(x:Float, y:Float, ?initRank:Int = 0) + public function new(x:Float, y:Float) { super(x, y); @@ -717,9 +732,7 @@ class FreeplayRank extends FlxSprite blend = BlendMode.ADD; - this.rank = initRank; - - animation.play(numToRank[initRank], true); + this.rank = null; // setGraphicSize(Std.int(width * 0.9)); scale.set(0.9, 0.9); From 7a2f3c81a1d5cbb02c376256361eadb953cc9e6d Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Thu, 30 May 2024 21:11:17 -0400 Subject: [PATCH 087/266] fix the one random slice of pixels where the bg doesnt show... lol --- source/funkin/ui/title/TitleState.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/ui/title/TitleState.hx b/source/funkin/ui/title/TitleState.hx index c9b3619e93..c6dbcd5058 100644 --- a/source/funkin/ui/title/TitleState.hx +++ b/source/funkin/ui/title/TitleState.hx @@ -124,7 +124,7 @@ class TitleState extends MusicBeatState persistentUpdate = true; - var bg:FunkinSprite = new FunkinSprite().makeSolidColor(FlxG.width, FlxG.height, FlxColor.BLACK); + var bg:FunkinSprite = new FunkinSprite(-1).makeSolidColor(FlxG.width + 2, FlxG.height, FlxColor.BLACK); bg.screenCenter(); add(bg); From dc33da904cc51d2ce1cf08aa3af1030863ae86f3 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Thu, 30 May 2024 23:03:27 -0400 Subject: [PATCH 088/266] assets submod --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 2719d3fc1d..4bc0b35f6c 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 2719d3fc1d8f5d0cbafae8d27141d6c471148482 +Subproject commit 4bc0b35f6c7aa22086b85b6a635c6f0511d277fe From 7347b66ce47570b6098085945cd561d6fe0f2154 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Thu, 30 May 2024 23:07:41 -0400 Subject: [PATCH 089/266] removes trace() that lags freeplay --- source/funkin/ui/freeplay/SongMenuItem.hx | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/funkin/ui/freeplay/SongMenuItem.hx b/source/funkin/ui/freeplay/SongMenuItem.hx index ad6ea386e7..75a4c07a32 100644 --- a/source/funkin/ui/freeplay/SongMenuItem.hx +++ b/source/funkin/ui/freeplay/SongMenuItem.hx @@ -264,8 +264,6 @@ class SongMenuItem extends FlxSpriteGroup function updateBPM(newBPM:Int):Void { - trace(newBPM); - var shiftX:Float = 191; var tempShift:Float = 0; From 40d1fd96a36bf566437d2dafdb716ffafee9e212 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Thu, 30 May 2024 23:27:00 -0400 Subject: [PATCH 090/266] art submod --- art | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/art b/art index 66572f85d8..faeba700c5 160000 --- a/art +++ b/art @@ -1 +1 @@ -Subproject commit 66572f85d826ce2ec1d45468c12733b161237ffa +Subproject commit faeba700c5526bd4fd57ccc927d875c82b9d3553 From 007ec95e8548892e70189e782081201624211827 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Thu, 30 May 2024 23:42:48 -0400 Subject: [PATCH 091/266] update difficulties --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 4bc0b35f6c..11bcd1b791 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 4bc0b35f6c7aa22086b85b6a635c6f0511d277fe +Subproject commit 11bcd1b79169df4f0aa46d72c867e960a287d28a From 0d4f3cdc334c8593fe7b1042d1c2295adf69992e Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 31 May 2024 01:42:41 -0400 Subject: [PATCH 092/266] Scrolling results text --- assets | 2 +- source/funkin/InitState.hx | 4 +-- source/funkin/play/ResultState.hx | 44 ++++++++++++++++++++++++++++--- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/assets b/assets index 11bcd1b791..7a0d92d300 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 11bcd1b79169df4f0aa46d72c867e960a287d28a +Subproject commit 7a0d92d3007de42c452b2ea97a917d8c8d114ee7 diff --git a/source/funkin/InitState.hx b/source/funkin/InitState.hx index d0009f95b7..c7a08d714d 100644 --- a/source/funkin/InitState.hx +++ b/source/funkin/InitState.hx @@ -219,9 +219,9 @@ class InitState extends FlxState FlxG.switchState(() -> new funkin.play.ResultState( { storyMode: false, - title: "CUM SONG", + title: "Cum Song Erect by Kawai Sprite", songId: "cum", - difficultyId: "hard", + difficultyId: "nightmare", isNewHighscore: true, scoreData: { diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx index 79880038df..8b8c0aea33 100644 --- a/source/funkin/play/ResultState.hx +++ b/source/funkin/play/ResultState.hx @@ -15,8 +15,10 @@ import funkin.ui.freeplay.FreeplayScore; import flixel.text.FlxText; import flixel.util.FlxColor; import flixel.tweens.FlxEase; +import funkin.graphics.FunkinCamera; import funkin.ui.freeplay.FreeplayState; import flixel.tweens.FlxTween; +import flixel.addons.display.FlxBackdrop; import funkin.audio.FunkinSound; import flixel.util.FlxGradient; import flixel.util.FlxTimer; @@ -59,6 +61,10 @@ class ResultState extends MusicBeatSubState var gfGood:Null = null; var bfShit:Null = null; + final cameraBG:FunkinCamera; + final cameraScroll:FunkinCamera; + final cameraEverything:FunkinCamera; + public function new(params:ResultsStateParams) { super(); @@ -67,6 +73,10 @@ class ResultState extends MusicBeatSubState rank = Scoring.calculateRank(params.scoreData) ?? SHIT; + cameraBG = new FunkinCamera('resultsBG', 0, 0, FlxG.width, FlxG.height); + cameraScroll = new FunkinCamera('resultsScroll', 0, 0, FlxG.width, FlxG.height); + cameraEverything = new FunkinCamera('resultsEverything', 0, 0, FlxG.width, FlxG.height); + // We build a lot of this stuff in the constructor, then place it in create(). // This prevents having to do `null` checks everywhere. @@ -101,17 +111,32 @@ class ResultState extends MusicBeatSubState { if (FlxG.sound.music != null) FlxG.sound.music.stop(); + // We need multiple cameras so we can put one at an angle. + cameraScroll.angle = -3.8; + + cameraBG.bgColor = FlxColor.MAGENTA; + cameraScroll.bgColor = FlxColor.TRANSPARENT; + cameraEverything.bgColor = FlxColor.TRANSPARENT; + + FlxG.cameras.add(cameraBG, false); + FlxG.cameras.add(cameraScroll, false); + FlxG.cameras.add(cameraEverything, false); + + FlxG.cameras.setDefaultDrawTarget(cameraEverything, true); + // Reset the camera zoom on the results screen. FlxG.camera.zoom = 1.0; var bg:FlxSprite = FlxGradient.createGradientFlxSprite(FlxG.width, FlxG.height, [0xFFFECC5C, 0xFFFDC05C], 90); bg.scrollFactor.set(); bg.zIndex = 10; + bg.cameras = [cameraBG]; add(bg); bgFlash.scrollFactor.set(); bgFlash.visible = false; bgFlash.zIndex = 20; + bgFlash.cameras = [cameraBG]; add(bgFlash); // The sound system which falls into place behind the score text. Plays every time! @@ -455,16 +480,27 @@ class ResultState extends MusicBeatSubState function displayRankText():Void { - var rankTextVert:FunkinSprite = FunkinSprite.create(FlxG.width - 64, 100, rank.getVerTextAsset()); - rankTextVert.zIndex = 2000; + var rankTextVert:FlxBackdrop = new FlxBackdrop(Paths.image(rank.getVerTextAsset()), Y, 0, 30); + rankTextVert.x = FlxG.width - 64; + rankTextVert.y = 100; + rankTextVert.zIndex = 990; add(rankTextVert); + // Scrolling. + rankTextVert.velocity.y = -50; + for (i in 0...10) { - var rankTextBack:FunkinSprite = FunkinSprite.create(FlxG.width / 2 - 80, 50, rank.getHorTextAsset()); - rankTextBack.y += (rankTextBack.height * i / 2) + 10; + var rankTextBack:FlxBackdrop = new FlxBackdrop(Paths.image(rank.getHorTextAsset()), X, 10, 0); + rankTextBack.x = FlxG.width / 2 - 320; + rankTextBack.y = 50 + (150 * i / 2) + 10; + // rankTextBack.angle = -3.8; rankTextBack.zIndex = 100; + rankTextBack.cameras = [cameraScroll]; add(rankTextBack); + + // Scrolling. + rankTextBack.velocity.x = (i % 2 == 0) ? -10.0 : 10.0; } refresh(); From 9e0a99374691f8a3018dc547a49c7c400b9245a7 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 31 May 2024 02:03:40 -0400 Subject: [PATCH 093/266] Disable song previews for mod songs rather than crashing the game --- source/funkin/audio/FunkinSound.hx | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/source/funkin/audio/FunkinSound.hx b/source/funkin/audio/FunkinSound.hx index b94c6008c7..7663c1305c 100644 --- a/source/funkin/audio/FunkinSound.hx +++ b/source/funkin/audio/FunkinSound.hx @@ -377,7 +377,7 @@ class FunkinSound extends FlxSound implements ICloneable FlxG.sound.music = partialMusic; FlxG.sound.list.remove(FlxG.sound.music); - if (params.onLoad != null) params.onLoad(); + if (FlxG.sound.music != null && params.onLoad != null) params.onLoad(); }); return true; @@ -488,14 +488,21 @@ class FunkinSound extends FlxSound implements ICloneable var soundRequest = FlxPartialSound.partialLoadFromFile(path, start, end); - promise.future.onError(function(e) { - soundRequest.error("Sound loading was errored or cancelled"); - }); - - soundRequest.future.onComplete(function(partialSound) { - var snd = FunkinSound.load(partialSound, volume, looped, autoDestroy, autoPlay, onComplete, onLoad); - promise.complete(snd); - }); + if (soundRequest == null) + { + promise.complete(null); + } + else + { + promise.future.onError(function(e) { + soundRequest.error("Sound loading was errored or cancelled"); + }); + + soundRequest.future.onComplete(function(partialSound) { + var snd = FunkinSound.load(partialSound, volume, looped, autoDestroy, autoPlay, onComplete, onLoad); + promise.complete(snd); + }); + } return promise; } From 2a8cdfaffae9dca58c0957f825f491ec89bd8070 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 31 May 2024 02:30:42 -0400 Subject: [PATCH 094/266] Fix an extra crash. --- source/funkin/ui/freeplay/FreeplayState.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 192c6e3ce1..f0695e51e6 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -830,7 +830,7 @@ class FreeplayState extends MusicBeatSubState dj.fistPump(); // rankCamera.fade(FlxColor.BLACK, 0.5, true); rankCamera.fade(0xFF000000, 0.5, true, null, true); - FlxG.sound.music.volume = 0; + if (FlxG.sound.music != null) FlxG.sound.music.volume = 0; rankBg.alpha = 1; originalPos.x = grpCapsules.members[curSelected].x; From 1e65cacb0efaa92991fd2290fe6f30b58e38ba7d Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Fri, 31 May 2024 10:39:06 +0100 Subject: [PATCH 095/266] fix funkinsound compile error --- source/funkin/audio/FunkinSound.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/audio/FunkinSound.hx b/source/funkin/audio/FunkinSound.hx index b94c6008c7..cf4a71189b 100644 --- a/source/funkin/audio/FunkinSound.hx +++ b/source/funkin/audio/FunkinSound.hx @@ -359,7 +359,7 @@ class FunkinSound extends FlxSound implements ICloneable if (shouldLoadPartial) { - var music = FunkinSound.loadPartial(pathToUse, params.partialParams?.start ?? 0, params.partialParams?.end ?? 1, params?.startingVolume ?? 1.0, + var music = FunkinSound.loadPartial(pathToUse, params.partialParams?.start ?? 0.0, params.partialParams?.end ?? 1.0, params?.startingVolume ?? 1.0, params.loop ?? true, false, false, params.onComplete); if (music != null) From 28444fd47814a4c3833310743d7d5ce1944ec9e9 Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Fri, 31 May 2024 10:39:53 +0100 Subject: [PATCH 096/266] rank tweaks, favourite changes + rank anim fixes --- source/funkin/play/ResultState.hx | 61 +++++++++-- source/funkin/play/scoring/Scoring.hx | 58 ++++++++++- source/funkin/ui/credits/CreditsState.hx | 3 +- source/funkin/ui/freeplay/AlbumRoll.hx | 2 +- source/funkin/ui/freeplay/FreeplayState.hx | 112 +++++++++++++++++---- source/funkin/ui/freeplay/SongMenuItem.hx | 7 +- source/funkin/ui/mainmenu/MainMenuState.hx | 13 ++- 7 files changed, 220 insertions(+), 36 deletions(-) diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx index 79880038df..1ad19b41e1 100644 --- a/source/funkin/play/ResultState.hx +++ b/source/funkin/play/ResultState.hx @@ -59,6 +59,8 @@ class ResultState extends MusicBeatSubState var gfGood:Null = null; var bfShit:Null = null; + var rankBg:FunkinSprite; + public function new(params:ResultsStateParams) { super(); @@ -95,6 +97,8 @@ class ResultState extends MusicBeatSubState highscoreNew = new FlxSprite(310, 570); score = new ResultScore(35, 305, 10, params.scoreData.score); + + rankBg = new FunkinSprite(0, 0); } override function create():Void @@ -356,6 +360,12 @@ class ResultState extends MusicBeatSubState } }); + rankBg.makeSolidColor(FlxG.width, FlxG.height, 0xFF000000); + rankBg.zIndex = 99999; + add(rankBg); + + rankBg.alpha = 0; + refresh(); super.create(); @@ -654,18 +664,47 @@ class ResultState extends MusicBeatSubState } else { - openSubState(new funkin.ui.transition.StickerSubState(null, (sticker) -> FreeplayState.build( - { + var rigged:Bool = true; + if (rank > Scoring.calculateRank(params?.prevScoreData)) + //if (rigged) + { + trace('THE RANK IS Higher.....'); + + FlxTween.tween(rankBg, {alpha: 1}, 0.5, { - fromResults: - { - oldRank: Scoring.calculateRank(params?.prevScoreData), - newRank: rank, - songId: params.songId, - difficultyId: params.difficultyId - } - } - }, sticker))); + ease: FlxEase.expoOut, + onComplete: function(_) { + FlxG.switchState(FreeplayState.build( + { + { + fromResults: + { + oldRank: Scoring.calculateRank(params?.prevScoreData), + newRank: rank, + songId: params.songId, + difficultyId: params.difficultyId + } + } + })); + } + }); + } + else + { + trace('rank is lower...... and/or equal'); + openSubState(new funkin.ui.transition.StickerSubState(null, (sticker) -> FreeplayState.build( + { + { + fromResults: + { + oldRank: null, + newRank: rank, + songId: params.songId, + difficultyId: params.difficultyId + } + } + }, sticker))); + } } } diff --git a/source/funkin/play/scoring/Scoring.hx b/source/funkin/play/scoring/Scoring.hx index 6155ec8798..f941f3f010 100644 --- a/source/funkin/play/scoring/Scoring.hx +++ b/source/funkin/play/scoring/Scoring.hx @@ -349,7 +349,7 @@ class Scoring public static function calculateRank(scoreData:Null):Null { - if (scoreData == null) return null; + if (scoreData?.tallies.totalNotes == 0 || scoreData == null) return null; // Perfect (Platinum) is a Sick Full Clear var isPerfectGold = scoreData.tallies.sick == scoreData.tallies.totalNotes; @@ -394,6 +394,62 @@ enum abstract ScoringRank(String) var GOOD; var SHIT; + @:op(A > B) static function compare(a:Null, b:Null):Bool + { + if (a != null && b == null) return true; + if (a == null || b == null) return false; + + var temp1:Int = 0; + var temp2:Int = 0; + + // temp 1 + switch (a) + { + case PERFECT_GOLD: + temp1 = 5; + case PERFECT: + temp1 = 4; + case EXCELLENT: + temp1 = 3; + case GREAT: + temp1 = 2; + case GOOD: + temp1 = 1; + case SHIT: + temp1 = 0; + default: + temp1 = -1; + } + + // temp 2 + switch (b) + { + case PERFECT_GOLD: + temp2 = 5; + case PERFECT: + temp2 = 4; + case EXCELLENT: + temp2 = 3; + case GREAT: + temp2 = 2; + case GOOD: + temp2 = 1; + case SHIT: + temp2 = 0; + default: + temp2 = -1; + } + + if (temp1 > temp2) + { + return true; + } + else + { + return false; + } + } + /** * Delay in seconds */ diff --git a/source/funkin/ui/credits/CreditsState.hx b/source/funkin/ui/credits/CreditsState.hx index 6be1fecf71..44769e9b33 100644 --- a/source/funkin/ui/credits/CreditsState.hx +++ b/source/funkin/ui/credits/CreditsState.hx @@ -4,6 +4,7 @@ import flixel.text.FlxText; import flixel.util.FlxColor; import funkin.audio.FunkinSound; import flixel.FlxSprite; +import funkin.ui.mainmenu.MainMenuState; import flixel.group.FlxSpriteGroup; /** @@ -199,7 +200,7 @@ class CreditsState extends MusicBeatState function exit():Void { - FlxG.switchState(funkin.ui.mainmenu.MainMenuState.new); + FlxG.switchState(() -> new MainMenuState()); } public override function destroy():Void diff --git a/source/funkin/ui/freeplay/AlbumRoll.hx b/source/funkin/ui/freeplay/AlbumRoll.hx index 50f4a432c8..20cd913794 100644 --- a/source/funkin/ui/freeplay/AlbumRoll.hx +++ b/source/funkin/ui/freeplay/AlbumRoll.hx @@ -131,7 +131,7 @@ class AlbumRoll extends FlxSpriteGroup if (exitMovers == null) return; - exitMovers.set([newAlbumArt], + exitMovers.set([newAlbumArt, difficultyStars], { x: FlxG.width, speed: 0.4, diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 192c6e3ce1..186c84c338 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -193,12 +193,18 @@ class FreeplayState extends MusicBeatSubState var fromResultsParams:Null = null; + var prepForNewRank:Bool = false; + public function new(?params:FreeplayStateParams, ?stickers:StickerSubState) { currentCharacter = params?.character ?? Constants.DEFAULT_CHARACTER; fromResultsParams = params?.fromResults; + if(fromResultsParams?.oldRank != null){ + prepForNewRank = true; + } + if (stickers != null) { stickerSubState = stickers; @@ -235,11 +241,14 @@ class FreeplayState extends MusicBeatSubState isDebug = true; #end - FunkinSound.playMusic('freakyMenu', + if (prepForNewRank == false) + { + FunkinSound.playMusic('freakyMenu', { overrideExisting: true, restartTrack: false }); + } // Add a null entry that represents the RANDOM option songs.push(null); @@ -637,7 +646,7 @@ class FreeplayState extends MusicBeatSubState cardGlow.visible = true; FlxTween.tween(cardGlow, {alpha: 0, "scale.x": 1.2, "scale.y": 1.2}, 0.45, {ease: FlxEase.sineOut}); - if (fromResultsParams != null) + if (prepForNewRank == true) { rankAnimStart(fromResultsParams); } @@ -667,6 +676,11 @@ class FreeplayState extends MusicBeatSubState FlxG.cameras.add(rankCamera, false); rankBg.cameras = [rankCamera]; rankBg.alpha = 0; + + if (prepForNewRank == true) + { + rankCamera.fade(0xFF000000, 0, false, null, true); + } } var currentFilter:SongFilter = null; @@ -826,6 +840,7 @@ class FreeplayState extends MusicBeatSubState function rankAnimStart(fromResults:Null):Void { busy = true; + // grpCapsules.members[curSelected].forcePosition(); dj.fistPump(); // rankCamera.fade(FlxColor.BLACK, 0.5, true); @@ -833,8 +848,14 @@ class FreeplayState extends MusicBeatSubState FlxG.sound.music.volume = 0; rankBg.alpha = 1; - originalPos.x = grpCapsules.members[curSelected].x; - originalPos.y = grpCapsules.members[curSelected].y; + grpCapsules.members[curSelected].doLerp = false; + + // originalPos.x = grpCapsules.members[curSelected].x; + // originalPos.y = grpCapsules.members[curSelected].y; + + originalPos.x = 320.488; + originalPos.y = 235.6; + trace(originalPos); grpCapsules.members[curSelected].ranking.alpha = 0; grpCapsules.members[curSelected].blurredRanking.alpha = 0; @@ -846,11 +867,13 @@ class FreeplayState extends MusicBeatSubState FlxTween.tween(funnyCam, {"zoom": 1.1}, 0.6, {ease: FlxEase.sineIn}); grpCapsules.members[curSelected].cameras = [rankCamera]; - grpCapsules.members[curSelected].targetPos.set((FlxG.width / 2) - (grpCapsules.members[curSelected].width / 2), + // grpCapsules.members[curSelected].targetPos.set((FlxG.width / 2) - (grpCapsules.members[curSelected].width / 2), + // (FlxG.height / 2) - (grpCapsules.members[curSelected].height / 2)); + + grpCapsules.members[curSelected].setPosition((FlxG.width / 2) - (grpCapsules.members[curSelected].width / 2), (FlxG.height / 2) - (grpCapsules.members[curSelected].height / 2)); new FlxTimer().start(0.5, _ -> { - grpCapsules.members[curSelected].doLerp = false; rankDisplayNew(fromResults); }); } @@ -1028,6 +1051,12 @@ class FreeplayState extends MusicBeatSubState new FlxTimer().start(2, _ -> { // dj.fistPump(); + prepForNewRank = false; + FunkinSound.playMusic('freakyMenu', + { + overrideExisting: true, + restartTrack: false + }); FlxG.sound.music.fadeIn(4.0, 0.0, 1.0); }); } @@ -1095,7 +1124,7 @@ class FreeplayState extends MusicBeatSubState } #end - if (FlxG.keys.justPressed.F) + if (FlxG.keys.justPressed.F && !busy) { var targetSong = grpCapsules.members[curSelected]?.songData; if (targetSong != null) @@ -1104,24 +1133,45 @@ class FreeplayState extends MusicBeatSubState var isFav = targetSong.toggleFavorite(); if (isFav) { - FlxTween.tween(grpCapsules.members[realShit], {angle: 360}, 0.4, + grpCapsules.members[realShit].favIcon.visible = true; + grpCapsules.members[realShit].favIcon.animation.play('fav'); + FunkinSound.playOnce(Paths.sound('fav'), 1); + busy = true; + + grpCapsules.members[realShit].doLerp = false; + FlxTween.tween(grpCapsules.members[realShit], {y: grpCapsules.members[realShit].y - 5}, 0.1, {ease: FlxEase.expoOut}); + + FlxTween.tween(grpCapsules.members[realShit], {y: grpCapsules.members[realShit].y + 5}, 0.1, { - ease: FlxEase.elasticOut, - onComplete: _ -> { - grpCapsules.members[realShit].favIcon.visible = true; - grpCapsules.members[realShit].favIcon.animation.play('fav'); + ease: FlxEase.expoIn, + startDelay: 0.1, + onComplete: function(_) { + grpCapsules.members[realShit].doLerp = true; + busy = false; } }); } else { - grpCapsules.members[realShit].favIcon.animation.play('fav', false, true); - new FlxTimer().start((1 / 24) * 14, _ -> { + grpCapsules.members[realShit].favIcon.animation.play('fav', true, true, 9); + FunkinSound.playOnce(Paths.sound('unfav'), 1); + new FlxTimer().start(0.2, _ -> { grpCapsules.members[realShit].favIcon.visible = false; }); - new FlxTimer().start((1 / 24) * 24, _ -> { - FlxTween.tween(grpCapsules.members[realShit], {angle: 0}, 0.4, {ease: FlxEase.elasticOut}); - }); + + busy = true; + grpCapsules.members[realShit].doLerp = false; + FlxTween.tween(grpCapsules.members[realShit], {y: grpCapsules.members[realShit].y + 5}, 0.1, {ease: FlxEase.expoOut}); + + FlxTween.tween(grpCapsules.members[realShit], {y: grpCapsules.members[realShit].y - 5}, 0.1, + { + ease: FlxEase.expoIn, + startDelay: 0.1, + onComplete: function(_) { + grpCapsules.members[realShit].doLerp = true; + busy = false; + } + }); } } } @@ -1325,6 +1375,24 @@ class FreeplayState extends MusicBeatSubState var longestTimer:Float = 0; + // FlxTween.color(bgDad, 0.33, 0xFFFFFFFF, 0xFF555555, {ease: FlxEase.quadOut}); + FlxTween.color(pinkBack, 0.25, 0xFFFFD863, 0xFFFFD0D5, {ease: FlxEase.quadOut}); + + cardGlow.visible = true; + cardGlow.alpha = 1; + cardGlow.scale.set(1, 1); + FlxTween.tween(cardGlow, {alpha: 0, "scale.x": 1.2, "scale.y": 1.2}, 0.25, {ease: FlxEase.sineOut}); + + orangeBackShit.visible = false; + alsoOrangeLOL.visible = false; + + moreWays.visible = false; + funnyScroll.visible = false; + txtNuts.visible = false; + funnyScroll2.visible = false; + moreWays2.visible = false; + funnyScroll3.visible = false; + for (grpSpr in exitMovers.keys()) { var moveData:MoveData = exitMovers.get(grpSpr); @@ -1555,6 +1623,7 @@ class FreeplayState extends MusicBeatSubState FunkinSound.playOnce(Paths.sound('confirmMenu')); dj.confirm(); + grpCapsules.members[curSelected].forcePosition(); grpCapsules.members[curSelected].songText.flickerText(); // FlxTween.color(bgDad, 0.33, 0xFFFFFFFF, 0xFF555555, {ease: FlxEase.quadOut}); @@ -1689,6 +1758,7 @@ class FreeplayState extends MusicBeatSubState } else { + if(prepForNewRank == false){ var potentiallyErect:String = (currentDifficulty == "erect") || (currentDifficulty == "nightmare") ? "-erect" : ""; // TODO: Stream the instrumental of the selected song? FunkinSound.playMusic(daSongCapsule.songData.songId, @@ -1708,6 +1778,7 @@ class FreeplayState extends MusicBeatSubState FlxG.sound.music.fadeIn(2, 0, 0.4); } }); + } } grpCapsules.members[curSelected].selected = true; } @@ -1719,7 +1790,12 @@ class FreeplayState extends MusicBeatSubState */ public static function build(?params:FreeplayStateParams, ?stickers:StickerSubState):MusicBeatState { - var result = new MainMenuState(); + var result:MainMenuState; + if(params?.fromResults.oldRank != null){ + result = new MainMenuState(true); + }else{ + result = new MainMenuState(false); + } result.openSubState(new FreeplayState(params, stickers)); result.persistentUpdate = false; diff --git a/source/funkin/ui/freeplay/SongMenuItem.hx b/source/funkin/ui/freeplay/SongMenuItem.hx index ad6ea386e7..b52032bc3f 100644 --- a/source/funkin/ui/freeplay/SongMenuItem.hx +++ b/source/funkin/ui/freeplay/SongMenuItem.hx @@ -371,7 +371,7 @@ class SongMenuItem extends FlxSpriteGroup switch (i) { case 0: - if (newRating > 10) + if (newRating < 10) { bigNumbers[i].digit = 0; } @@ -677,7 +677,7 @@ class FreeplayRank extends FlxSprite { rank = val; - if (rank == null) + if (rank == null || val == null) { this.visible = false; } @@ -687,6 +687,8 @@ class FreeplayRank extends FlxSprite animation.play(val.getFreeplayRankIconAsset(), true, false); + trace(val.getFreeplayRankIconAsset()); + centerOffsets(false); switch (val) @@ -707,6 +709,7 @@ class FreeplayRank extends FlxSprite // offset.y += 5; default: centerOffsets(false); + this.visible = false; } updateHitbox(); } diff --git a/source/funkin/ui/mainmenu/MainMenuState.hx b/source/funkin/ui/mainmenu/MainMenuState.hx index 22262006ab..c504b3c3e1 100644 --- a/source/funkin/ui/mainmenu/MainMenuState.hx +++ b/source/funkin/ui/mainmenu/MainMenuState.hx @@ -42,6 +42,15 @@ class MainMenuState extends MusicBeatState var magenta:FlxSprite; var camFollow:FlxObject; + var overrideMusic:Bool = false; + + public function new(?_overrideMusic:Bool = false) + { + super(); + overrideMusic = _overrideMusic; + + } + override function create():Void { #if discord_rpc @@ -54,7 +63,7 @@ class MainMenuState extends MusicBeatState transIn = FlxTransitionableState.defaultTransIn; transOut = FlxTransitionableState.defaultTransOut; - playMenuMusic(); + if(overrideMusic == false) playMenuMusic(); // We want the state to always be able to begin with being able to accept inputs and show the anims of the menu items. persistentUpdate = true; @@ -163,7 +172,7 @@ class MainMenuState extends MusicBeatState function playMenuMusic():Void { - FunkinSound.playMusic('freakyMenu', + FunkinSound.playMusic('freakyMenu', { overrideExisting: true, restartTrack: false From 5d0db60810b37e3a076e3581ed2b33416ed1050c Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Fri, 31 May 2024 10:40:51 +0100 Subject: [PATCH 097/266] assets submod --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 4bc0b35f6c..d64939d866 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 4bc0b35f6c7aa22086b85b6a635c6f0511d277fe +Subproject commit d64939d866c70a831b76ed78930782b66871dcc2 From d89a898e6c3d33430002896bd601ec72c6a0faba Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 31 May 2024 17:16:26 -0400 Subject: [PATCH 098/266] make songs last longer on freeplay --- source/funkin/ui/freeplay/FreeplayState.hx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 192c6e3ce1..71052a923f 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -104,6 +104,7 @@ class FreeplayState extends MusicBeatSubState /** * For the audio preview, the duration of the fade-out effect. + * */ public static final FADE_OUT_DURATION:Float = 0.25; @@ -1690,7 +1691,6 @@ class FreeplayState extends MusicBeatSubState else { var potentiallyErect:String = (currentDifficulty == "erect") || (currentDifficulty == "nightmare") ? "-erect" : ""; - // TODO: Stream the instrumental of the selected song? FunkinSound.playMusic(daSongCapsule.songData.songId, { startingVolume: 0.0, @@ -1701,8 +1701,8 @@ class FreeplayState extends MusicBeatSubState partialParams: { loadPartial: true, - start: 0, - end: 0.1 + start: 0.05, + end: 0.25 }, onLoad: function() { FlxG.sound.music.fadeIn(2, 0, 0.4); From 98eda8ef551ad533b29a5a1625ec613b78165c5e Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 31 May 2024 18:09:07 -0400 Subject: [PATCH 099/266] Give timeFormat a default value (fixes the Stress issues!) --- source/funkin/data/song/SongData.hx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/funkin/data/song/SongData.hx b/source/funkin/data/song/SongData.hx index bd25139a79..ca805e1395 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; @@ -117,7 +119,7 @@ class SongMetadata implements ICloneable { 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); From 8bf26322e9a405e3eb70508711b66a606cd444a6 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 31 May 2024 18:09:30 -0400 Subject: [PATCH 100/266] Update `generatedBy` to the latest value when saving a chart. --- .../ChartEditorImportExportHandler.hx | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/source/funkin/ui/debug/charting/handlers/ChartEditorImportExportHandler.hx b/source/funkin/ui/debug/charting/handlers/ChartEditorImportExportHandler.hx index 0308cd8716..a78eeae4cd 100644 --- a/source/funkin/ui/debug/charting/handlers/ChartEditorImportExportHandler.hx +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorImportExportHandler.hx @@ -384,17 +384,32 @@ 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.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.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) + { + variationMetadata.generatedBy = funkin.data.song.SongRegistry.DEFAULT_GENERATEDBY; + 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.generatedBy = funkin.data.song.SongRegistry.DEFAULT_GENERATEDBY; + zipEntries.push(FileUtil.makeZIPEntry('${state.currentSongId}-chart-$variationId.json', variationChart.serialize())); + } } } From 06daa9d402a81bb45b5bf214595b4d0ac794fd4c Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 31 May 2024 19:20:39 -0400 Subject: [PATCH 101/266] Increase Great threshold to 80% --- source/funkin/util/Constants.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/util/Constants.hx b/source/funkin/util/Constants.hx index 4e706c612e..1e0978839a 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; From 9088570b926eae749c5cc6822dbb01cd1d541f69 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 31 May 2024 19:21:21 -0400 Subject: [PATCH 102/266] Make sure JSON data uses latest version/generatedBy when writing. --- source/funkin/data/song/SongData.hx | 24 +++++++++++++++++++ .../data/song/importer/ChartManifestData.hx | 8 +++++++ source/funkin/data/stage/StageData.hx | 8 +++++++ .../funkin/ui/credits/CreditsDataHandler.hx | 2 +- .../ChartEditorImportExportHandler.hx | 4 +++- 5 files changed, 44 insertions(+), 2 deletions(-) diff --git a/source/funkin/data/song/SongData.hx b/source/funkin/data/song/SongData.hx index ca805e1395..769af8f08a 100644 --- a/source/funkin/data/song/SongData.hx +++ b/source/funkin/data/song/SongData.hx @@ -117,6 +117,9 @@ 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 ignored by the writer? @@ -125,6 +128,12 @@ class SongMetadata implements ICloneable 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. */ @@ -373,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); @@ -605,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 dd0d284798..04b5a1b69b 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 22b883c759..bebd86d02b 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 2240ec50eb..844d0f4db7 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 a78eeae4cd..e84f7ec438 100644 --- a/source/funkin/ui/debug/charting/handlers/ChartEditorImportExportHandler.hx +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorImportExportHandler.hx @@ -386,12 +386,14 @@ class ChartEditorImportExportHandler var variationMetadata:Null = state.songMetadata.get(variation); 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) { + 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())); } @@ -401,12 +403,12 @@ class ChartEditorImportExportHandler var variationMetadata:Null = state.songMetadata.get(variation); if (variationMetadata != null) { - variationMetadata.generatedBy = funkin.data.song.SongRegistry.DEFAULT_GENERATEDBY; zipEntries.push(FileUtil.makeZIPEntry('${state.currentSongId}-metadata-$variationId.json', variationMetadata.serialize())); } var variationChart:Null = state.songChartData.get(variation); 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())); } From 074b1afc7659cf0923a03533994a812c9f39ef8d Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 31 May 2024 20:16:23 -0400 Subject: [PATCH 103/266] Readd a reverted freeplay bugfix --- source/funkin/audio/FunkinSound.hx | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/source/funkin/audio/FunkinSound.hx b/source/funkin/audio/FunkinSound.hx index b94c6008c7..7663c1305c 100644 --- a/source/funkin/audio/FunkinSound.hx +++ b/source/funkin/audio/FunkinSound.hx @@ -377,7 +377,7 @@ class FunkinSound extends FlxSound implements ICloneable FlxG.sound.music = partialMusic; FlxG.sound.list.remove(FlxG.sound.music); - if (params.onLoad != null) params.onLoad(); + if (FlxG.sound.music != null && params.onLoad != null) params.onLoad(); }); return true; @@ -488,14 +488,21 @@ class FunkinSound extends FlxSound implements ICloneable var soundRequest = FlxPartialSound.partialLoadFromFile(path, start, end); - promise.future.onError(function(e) { - soundRequest.error("Sound loading was errored or cancelled"); - }); - - soundRequest.future.onComplete(function(partialSound) { - var snd = FunkinSound.load(partialSound, volume, looped, autoDestroy, autoPlay, onComplete, onLoad); - promise.complete(snd); - }); + if (soundRequest == null) + { + promise.complete(null); + } + else + { + promise.future.onError(function(e) { + soundRequest.error("Sound loading was errored or cancelled"); + }); + + soundRequest.future.onComplete(function(partialSound) { + var snd = FunkinSound.load(partialSound, volume, looped, autoDestroy, autoPlay, onComplete, onLoad); + promise.complete(snd); + }); + } return promise; } From e36fbfa72c79bf2ac793e1a78a80b0559c9cba64 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 31 May 2024 20:16:37 -0400 Subject: [PATCH 104/266] Update the changelog --- CHANGELOG.md | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10bbfe5f7b..f5aefb8855 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 From e08cdac35bfa3c57540d90d21118797d2e244fde Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Sat, 1 Jun 2024 01:16:52 +0100 Subject: [PATCH 105/266] score number shuffling --- source/funkin/play/ResultScore.hx | 80 +++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 4 deletions(-) diff --git a/source/funkin/play/ResultScore.hx b/source/funkin/play/ResultScore.hx index d5d5a65670..23e6c8d326 100644 --- a/source/funkin/play/ResultScore.hx +++ b/source/funkin/play/ResultScore.hx @@ -2,11 +2,16 @@ package funkin.play; import flixel.FlxSprite; import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; +import flixel.tweens.FlxTween; +import flixel.util.FlxTimer; +import flixel.tweens.FlxEase; class ResultScore extends FlxTypedSpriteGroup { public var scoreShit(default, set):Int = 0; + public var scoreStart:Int = 0; + function set_scoreShit(val):Int { if (group == null || group.members == null) return val; @@ -16,7 +21,8 @@ class ResultScore extends FlxTypedSpriteGroup while (dumbNumb > 0) { - group.members[loopNum].digit = dumbNumb % 10; + scoreStart += 1; + group.members[loopNum].finalDigit = dumbNumb % 10; // var funnyNum = group.members[loopNum]; // prevNum = group.members[loopNum + 1]; @@ -44,9 +50,15 @@ class ResultScore extends FlxTypedSpriteGroup public function animateNumbers():Void { - for (i in group.members) + for (i in group.members.length-scoreStart...group.members.length) { - i.playAnim(); + // if(i.finalDigit == 10) continue; + + new FlxTimer().start((i-1)/24, _ -> { + group.members[i].finalDelay = scoreStart - (i-1); + group.members[i].playAnim(); + group.members[i].shuffle(); + }); } } @@ -71,12 +83,26 @@ class ResultScore extends FlxTypedSpriteGroup class ScoreNum extends FlxSprite { public var digit(default, set):Int = 10; + public var finalDigit(default, set):Int = 10; + public var glow:Bool = true; + + function set_finalDigit(val):Int + { + animation.play('GONE', true, false, 0); + + return finalDigit = val; + } function set_digit(val):Int { if (val >= 0 && animation.curAnim != null && animation.curAnim.name != numToString[val]) { - animation.play(numToString[val], true, false, 0); + if(glow){ + animation.play(numToString[val], true, false, 0); + glow = false; + }else{ + animation.play(numToString[val], true, false, 4); + } updateHitbox(); switch (val) @@ -107,6 +133,10 @@ class ScoreNum extends FlxSprite animation.play(numToString[digit], true, false, 0); } + public var shuffleTimer:FlxTimer; + public var finalTween:FlxTween; + public var finalDelay:Float = 0; + public var baseY:Float = 0; public var baseX:Float = 0; @@ -114,6 +144,47 @@ class ScoreNum extends FlxSprite "ZERO", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE", "DISABLED" ]; + function finishShuffleTween():Void{ + + var tweenFunction = function(x) { + var digitRounded = Math.floor(x); + //if(digitRounded == finalDigit) glow = true; + digit = digitRounded; + }; + + finalTween = FlxTween.num(0.0, finalDigit, 23/24, { + ease: FlxEase.quadOut, + onComplete: function (input) { + new FlxTimer().start((finalDelay)/24, _ -> { + animation.play(animation.curAnim.name, true, false, 0); + }); + // fuck + } + }, tweenFunction); + } + + + function shuffleProgress(shuffleTimer:FlxTimer):Void + { + var tempDigit:Int = digit; + tempDigit += 1; + if(tempDigit > 9) tempDigit = 0; + if(tempDigit < 0) tempDigit = 0; + digit = tempDigit; + + if (shuffleTimer.loops > 0 && shuffleTimer.loopsLeft == 0) + { + //digit = finalDigit; + finishShuffleTween(); + } + } + + public function shuffle():Void{ + var duration:Float = 41/24; + var interval:Float = 1/24; + shuffleTimer = new FlxTimer().start(interval, shuffleProgress, Std.int(duration / interval)); + } + public function new(x:Float, y:Float) { super(x, y); @@ -130,6 +201,7 @@ class ScoreNum extends FlxSprite } animation.addByPrefix('DISABLED', 'DISABLED', 24, false); + animation.addByPrefix('GONE', 'GONE', 24, false); this.digit = 10; From 1cffc36ba8aa51b90523ff7fbe4464eca957cc29 Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Sat, 1 Jun 2024 01:17:11 +0100 Subject: [PATCH 106/266] results timing redo + fixed anims for all ranks --- source/funkin/play/ResultState.hx | 278 +++++++++++++++++++++----- source/funkin/play/scoring/Scoring.hx | 70 ++++++- 2 files changed, 292 insertions(+), 56 deletions(-) diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx index 8b8c0aea33..8a7332a836 100644 --- a/source/funkin/play/ResultState.hx +++ b/source/funkin/play/ResultState.hx @@ -5,6 +5,7 @@ import funkin.ui.story.StoryMenuState; import funkin.graphics.adobeanimate.FlxAtlasSprite; import flixel.FlxSprite; import funkin.graphics.FunkinSprite; +import flixel.effects.FlxFlicker; import flixel.graphics.frames.FlxBitmapFont; import flixel.group.FlxGroup.FlxTypedGroup; import flixel.math.FlxPoint; @@ -55,8 +56,10 @@ class ResultState extends MusicBeatSubState final score:ResultScore; var bfPerfect:Null = null; + var heartsPerfect:Null = null; var bfExcellent:Null = null; var bfGreat:Null = null; + var gfGreat:Null = null; var bfGood:Null = null; var gfGood:Null = null; var bfShit:Null = null; @@ -94,15 +97,15 @@ class ResultState extends MusicBeatSubState clearPercentSmall.zIndex = 1000; clearPercentSmall.visible = false; - bgFlash = FlxGradient.createGradientFlxSprite(FlxG.width, FlxG.height, [0xFFFFEB69, 0xFFFFE66A], 90); + bgFlash = FlxGradient.createGradientFlxSprite(FlxG.width, FlxG.height, [0xFFFFF1A6, 0xFFFFF1BE], 90); resultsAnim = FunkinSprite.createSparrow(-200, -10, "resultScreen/results"); - ratingsPopin = FunkinSprite.createSparrow(-150, 120, "resultScreen/ratingsPopin"); + ratingsPopin = FunkinSprite.createSparrow(-135, 135, "resultScreen/ratingsPopin"); - scorePopin = FunkinSprite.createSparrow(-180, 520, "resultScreen/scorePopin"); + scorePopin = FunkinSprite.createSparrow(-180, 515, "resultScreen/scorePopin"); - highscoreNew = new FlxSprite(310, 570); + highscoreNew = new FlxSprite(44, 557); score = new ResultScore(35, 305, 10, params.scoreData.score); } @@ -136,14 +139,14 @@ class ResultState extends MusicBeatSubState bgFlash.scrollFactor.set(); bgFlash.visible = false; bgFlash.zIndex = 20; - bgFlash.cameras = [cameraBG]; + //bgFlash.cameras = [cameraBG]; add(bgFlash); // The sound system which falls into place behind the score text. Plays every time! var soundSystem:FlxSprite = FunkinSprite.createSparrow(-15, -180, 'resultScreen/soundSystem'); soundSystem.animation.addByPrefix("idle", "sound system", 24, false); soundSystem.visible = false; - new FlxTimer().start(0.3, _ -> { + new FlxTimer().start(8/24, _ -> { soundSystem.animation.play("idle"); soundSystem.visible = true; }); @@ -153,7 +156,22 @@ class ResultState extends MusicBeatSubState switch (rank) { case PERFECT | PERFECT_GOLD: - bfPerfect = new FlxAtlasSprite(370, -180, Paths.animateAtlas("resultScreen/results-bf/resultsPERFECT", "shared")); + heartsPerfect = new FlxAtlasSprite(1342, 370, Paths.animateAtlas("resultScreen/results-bf/resultsPERFECT/hearts", "shared")); + heartsPerfect.visible = false; + heartsPerfect.zIndex = 501; + add(heartsPerfect); + + heartsPerfect.anim.onComplete = () -> { + if (heartsPerfect != null) + { + //bfPerfect.anim.curFrame = 137; + heartsPerfect.anim.curFrame = 43; + heartsPerfect.anim.play(); // unpauses this anim, since it's on PlayOnce! + } + }; + + + bfPerfect = new FlxAtlasSprite(1342, 370, Paths.animateAtlas("resultScreen/results-bf/resultsPERFECT", "shared")); bfPerfect.visible = false; bfPerfect.zIndex = 500; add(bfPerfect); @@ -161,36 +179,57 @@ class ResultState extends MusicBeatSubState bfPerfect.anim.onComplete = () -> { if (bfPerfect != null) { + //bfPerfect.anim.curFrame = 137; bfPerfect.anim.curFrame = 137; bfPerfect.anim.play(); // unpauses this anim, since it's on PlayOnce! } }; case EXCELLENT: - bfExcellent = new FlxAtlasSprite(380, -170, Paths.animateAtlas("resultScreen/results-bf/resultsEXCELLENT", "shared")); + bfExcellent = new FlxAtlasSprite(1329, 429, Paths.animateAtlas("resultScreen/results-bf/resultsEXCELLENT", "shared")); bfExcellent.visible = false; bfExcellent.zIndex = 500; add(bfExcellent); - bfExcellent.onAnimationFinish.add((animName) -> { + bfExcellent.anim.onComplete = () -> { if (bfExcellent != null) { - bfExcellent.playAnimation('Loop Start'); + bfExcellent.anim.curFrame = 28; + bfExcellent.anim.play(); // unpauses this anim, since it's on PlayOnce! } - }); + }; + case GREAT: - bfGreat = new FlxAtlasSprite(640, 200, Paths.animateAtlas("resultScreen/results-bf/resultsGREAT", "shared")); + gfGreat = new FlxAtlasSprite(802, 331, Paths.animateAtlas("resultScreen/results-bf/resultsGREAT/gf", "shared")); + gfGreat.visible = false; + gfGreat.zIndex = 499; + add(gfGreat); + + gfGreat.scale.set(0.93, 0.93); + + gfGreat.anim.onComplete = () -> { + if (gfGreat != null) + { + gfGreat.anim.curFrame = 9; + gfGreat.anim.play(); // unpauses this anim, since it's on PlayOnce! + } + }; + + bfGreat = new FlxAtlasSprite(929, 363, Paths.animateAtlas("resultScreen/results-bf/resultsGREAT/bf", "shared")); bfGreat.visible = false; bfGreat.zIndex = 500; add(bfGreat); - bfGreat.onAnimationFinish.add((animName) -> { + bfGreat.scale.set(0.93, 0.93); + + bfGreat.anim.onComplete = () -> { if (bfGreat != null) { - bfGreat.playAnimation('Loop Start'); + bfGreat.anim.curFrame = 15; + bfGreat.anim.play(); // unpauses this anim, since it's on PlayOnce! } - }); + }; case GOOD: gfGood = FunkinSprite.createSparrow(625, 325, 'resultScreen/results-bf/resultsGOOD/resultGirlfriendGOOD'); @@ -250,7 +289,7 @@ class ResultState extends MusicBeatSubState var blackTopBar:FlxSprite = new FlxSprite().loadGraphic(Paths.image("resultScreen/topBarBlack")); blackTopBar.y = -blackTopBar.height; - FlxTween.tween(blackTopBar, {y: 0}, 0.4, {ease: FlxEase.quartOut}); + FlxTween.tween(blackTopBar, {y: 0}, 7/24, {ease: FlxEase.quartOut, startDelay: 3/24}); blackTopBar.zIndex = 1010; add(blackTopBar); @@ -258,7 +297,7 @@ class ResultState extends MusicBeatSubState resultsAnim.visible = false; resultsAnim.zIndex = 1200; add(resultsAnim); - new FlxTimer().start(0.3, _ -> { + new FlxTimer().start(6/24, _ -> { resultsAnim.visible = true; resultsAnim.animation.play("result"); }); @@ -267,7 +306,7 @@ class ResultState extends MusicBeatSubState ratingsPopin.visible = false; ratingsPopin.zIndex = 1200; add(ratingsPopin); - new FlxTimer().start(1.0, _ -> { + new FlxTimer().start(21/24, _ -> { ratingsPopin.visible = true; ratingsPopin.animation.play("idle"); }); @@ -276,23 +315,49 @@ class ResultState extends MusicBeatSubState scorePopin.visible = false; scorePopin.zIndex = 1200; add(scorePopin); - new FlxTimer().start(1.0, _ -> { + new FlxTimer().start(36/24, _ -> { scorePopin.visible = true; scorePopin.animation.play("score"); scorePopin.animation.finishCallback = anim -> { - score.visible = true; - score.animateNumbers(); + }; }); + new FlxTimer().start(37/24, _ -> { + score.visible = true; + score.animateNumbers(); + startRankTallySequence(); + }); + + new FlxTimer().start(rank.getBFDelay(), _ -> { + afterRankTallySequence(); + }); + + new FlxTimer().start(rank.getFlashDelay(), _ -> { + displayRankText(); + }); + highscoreNew.frames = Paths.getSparrowAtlas("resultScreen/highscoreNew"); - highscoreNew.animation.addByPrefix("new", "NEW HIGHSCORE", 24); + highscoreNew.animation.addByPrefix("new", "highscoreAnim0", 24, false); highscoreNew.visible = false; - highscoreNew.setGraphicSize(Std.int(highscoreNew.width * 0.8)); + //highscoreNew.setGraphicSize(Std.int(highscoreNew.width * 0.8)); highscoreNew.updateHitbox(); highscoreNew.zIndex = 1200; add(highscoreNew); + new FlxTimer().start(rank.getHighscoreDelay(), _ -> { + if (params.isNewHighscore ?? false) + { + highscoreNew.visible = true; + highscoreNew.animation.play("new"); + highscoreNew.animation.finishCallback = _ -> highscoreNew.animation.play("new", true, false, 16); + } + else + { + highscoreNew.visible = false; + } + }); + var hStuf:Int = 50; var ratingGrp:FlxTypedGroup = new FlxTypedGroup(); @@ -310,7 +375,10 @@ class ResultState extends MusicBeatSubState ratingGrp.add(maxCombo); hStuf += 2; - var extraYOffset:Float = 5; + var extraYOffset:Float = 7; + + hStuf += 2; + var tallySick:TallyCounter = new TallyCounter(230, (hStuf * 5) + extraYOffset, params.scoreData.tallies.sick, 0xFF89E59E); ratingGrp.add(tallySick); @@ -339,20 +407,17 @@ class ResultState extends MusicBeatSubState }); } - ratingsPopin.animation.finishCallback = anim -> { - startRankTallySequence(); - if (params.isNewHighscore ?? false) - { - highscoreNew.visible = true; - highscoreNew.animation.play("new"); - FlxTween.tween(highscoreNew, {y: highscoreNew.y + 10}, 0.8, {ease: FlxEase.quartOut}); - } - else - { - highscoreNew.visible = false; - } - }; + // if (params.isNewHighscore ?? false) + // { + // highscoreNew.visible = true; + // highscoreNew.animation.play("new"); + // //FlxTween.tween(highscoreNew, {y: highscoreNew.y + 10}, 0.8, {ease: FlxEase.quartOut}); + // } + // else + // { + // highscoreNew.visible = false; + // } new FlxTimer().start(rank.getMusicDelay(), _ -> { if (rank.hasMusicIntro()) @@ -392,6 +457,8 @@ class ResultState extends MusicBeatSubState function startRankTallySequence():Void { + bgFlash.visible = true; + FlxTween.tween(bgFlash, {alpha: 0}, 5/24); var clearPercentFloat = (params.scoreData.tallies.sick + params.scoreData.tallies.good) / params.scoreData.tallies.totalNotes * 100; clearPercentTarget = Math.floor(clearPercentFloat); // Prevent off-by-one errors. @@ -400,8 +467,8 @@ class ResultState extends MusicBeatSubState trace('Clear percent target: ' + clearPercentFloat + ', round: ' + clearPercentTarget); - var clearPercentCounter:ClearPercentCounter = new ClearPercentCounter(FlxG.width / 2 + 300, FlxG.height / 2 - 100, clearPercentLerp); - FlxTween.tween(clearPercentCounter, {curNumber: clearPercentTarget}, 1.5, + var clearPercentCounter:ClearPercentCounter = new ClearPercentCounter(FlxG.width / 2 + 190, FlxG.height / 2 - 70, clearPercentLerp); + FlxTween.tween(clearPercentCounter, {curNumber: clearPercentTarget}, 58/24, { ease: FlxEase.quartOut, onUpdate: _ -> { @@ -416,10 +483,6 @@ class ResultState extends MusicBeatSubState // Play confirm sound. FunkinSound.playOnce(Paths.sound('confirmMenu')); - // Flash background. - bgFlash.visible = true; - FlxTween.tween(bgFlash, {alpha: 0}, 0.4); - // Just to be sure that the lerp didn't mess things up. clearPercentCounter.curNumber = clearPercentTarget; @@ -428,7 +491,7 @@ class ResultState extends MusicBeatSubState clearPercentCounter.flash(false); }); - displayRankText(); + //displayRankText(); // previously 2.0 seconds new FlxTimer().start(0.25, _ -> { @@ -441,7 +504,7 @@ class ResultState extends MusicBeatSubState } }); - afterRankTallySequence(); + //afterRankTallySequence(); }); } }); @@ -466,7 +529,6 @@ class ResultState extends MusicBeatSubState { highscoreNew.visible = true; highscoreNew.animation.play("new"); - FlxTween.tween(highscoreNew, {y: highscoreNew.y + 10}, 0.8, {ease: FlxEase.quartOut}); } else { @@ -480,27 +542,36 @@ class ResultState extends MusicBeatSubState function displayRankText():Void { + bgFlash.visible = true; + bgFlash.alpha = 1; + FlxTween.tween(bgFlash, {alpha: 0}, 14/24); + var rankTextVert:FlxBackdrop = new FlxBackdrop(Paths.image(rank.getVerTextAsset()), Y, 0, 30); - rankTextVert.x = FlxG.width - 64; + rankTextVert.x = FlxG.width - 44; rankTextVert.y = 100; rankTextVert.zIndex = 990; add(rankTextVert); + FlxFlicker.flicker(rankTextVert, 2/24 * 3, 2/24, true); + // Scrolling. - rankTextVert.velocity.y = -50; + new FlxTimer().start(30/24, _ -> { + rankTextVert.velocity.y = -80; + }); + - for (i in 0...10) + for (i in 0...12) { var rankTextBack:FlxBackdrop = new FlxBackdrop(Paths.image(rank.getHorTextAsset()), X, 10, 0); rankTextBack.x = FlxG.width / 2 - 320; - rankTextBack.y = 50 + (150 * i / 2) + 10; + rankTextBack.y = 50 + (135 * i / 2) + 10; // rankTextBack.angle = -3.8; rankTextBack.zIndex = 100; rankTextBack.cameras = [cameraScroll]; add(rankTextBack); // Scrolling. - rankTextBack.velocity.x = (i % 2 == 0) ? -10.0 : 10.0; + rankTextBack.velocity.x = (i % 2 == 0) ? -7.0 : 7.0; } refresh(); @@ -508,6 +579,7 @@ class ResultState extends MusicBeatSubState function afterRankTallySequence():Void { + showSmallClearPercent(); switch (rank) @@ -522,6 +594,17 @@ class ResultState extends MusicBeatSubState bfPerfect.visible = true; bfPerfect.playAnimation(''); } + new FlxTimer().start(106 / 24, _ -> { + if (heartsPerfect == null) + { + trace("Could not build heartsPerfect animation!"); + } + else + { + heartsPerfect.visible = true; + heartsPerfect.playAnimation(''); + } + }); case EXCELLENT: if (bfExcellent == null) { @@ -530,7 +613,7 @@ class ResultState extends MusicBeatSubState else { bfExcellent.visible = true; - bfExcellent.playAnimation('Intro'); + bfExcellent.playAnimation(''); } case GREAT: if (bfGreat == null) @@ -540,8 +623,20 @@ class ResultState extends MusicBeatSubState else { bfGreat.visible = true; - bfGreat.playAnimation('Intro'); + bfGreat.playAnimation(''); + } + + new FlxTimer().start(6 / 24, _ -> { + if (gfGreat == null) + { + trace("Could not build GREAT animation for gf!"); + } + else + { + gfGreat.visible = true; + gfGreat.playAnimation(''); } + }); case SHIT: if (bfShit == null) { @@ -627,7 +722,9 @@ class ResultState extends MusicBeatSubState refresh(); } - movingSongStuff = true; + new FlxTimer().start(2.5, _ -> { + movingSongStuff = true; + }); } var movingSongStuff:Bool = false; @@ -647,6 +744,79 @@ class ResultState extends MusicBeatSubState override function update(elapsed:Float):Void { + // if(FlxG.keys.justPressed.R){ + // FlxG.switchState(() -> new funkin.play.ResultState( + // { + // storyMode: false, + // title: "Cum Song Erect by Kawai Sprite", + // songId: "cum", + // difficultyId: "nightmare", + // isNewHighscore: true, + // scoreData: + // { + // score: 1_234_567, + // tallies: + // { + // sick: 200, + // good: 0, + // bad: 0, + // shit: 0, + // missed: 0, + // combo: 0, + // maxCombo: 69, + // totalNotesHit: 200, + // totalNotes: 200 // 0, + // } + // }, + // })); + // } + + // if(heartsPerfect != null){ + // if (FlxG.keys.justPressed.I) + // { + // heartsPerfect.y -= 1; + // trace(heartsPerfect.x, heartsPerfect.y); + // } + // if (FlxG.keys.justPressed.J) + // { + // heartsPerfect.x -= 1; + // trace(heartsPerfect.x, heartsPerfect.y); + // } + // if (FlxG.keys.justPressed.L) + // { + // heartsPerfect.x += 1; + // trace(heartsPerfect.x, heartsPerfect.y); + // } + // if (FlxG.keys.justPressed.K) + // { + // heartsPerfect.y += 1; + // trace(heartsPerfect.x, heartsPerfect.y); + // } + // } + + // if(bfGreat != null){ + // if (FlxG.keys.justPressed.W) + // { + // bfGreat.y -= 1; + // trace(bfGreat.x, bfGreat.y); + // } + // if (FlxG.keys.justPressed.A) + // { + // bfGreat.x -= 1; + // trace(bfGreat.x, bfGreat.y); + // } + // if (FlxG.keys.justPressed.D) + // { + // bfGreat.x += 1; + // trace(bfGreat.x, bfGreat.y); + // } + // if (FlxG.keys.justPressed.S) + // { + // bfGreat.y += 1; + // trace(bfGreat.x, bfGreat.y); + // } + // } + // maskShaderSongName.swagSprX = songName.x; maskShaderDifficulty.swagSprX = difficulty.x; diff --git a/source/funkin/play/scoring/Scoring.hx b/source/funkin/play/scoring/Scoring.hx index 6155ec8798..04bd81cf84 100644 --- a/source/funkin/play/scoring/Scoring.hx +++ b/source/funkin/play/scoring/Scoring.hx @@ -403,9 +403,75 @@ enum abstract ScoringRank(String) { case PERFECT_GOLD | PERFECT: // return 2.5; - return 5.0; + return 95/24; case EXCELLENT: - return 1.75; + return 0; + case GREAT: + return 5/24; + case GOOD: + return 3/24; + case SHIT: + return 2/24; + default: + return 3.5; + } + } + + public function getBFDelay():Float + { + switch (abstract) + { + case PERFECT_GOLD | PERFECT: + // return 2.5; + return 95/24; + case EXCELLENT: + return 97/24; + case GREAT: + return 95/24; + case GOOD: + return 95/24; + case SHIT: + return 95/24; + default: + return 3.5; + } + } + + public function getFlashDelay():Float + { + switch (abstract) + { + case PERFECT_GOLD | PERFECT: + // return 2.5; + return 129/24; + case EXCELLENT: + return 122/24; + case GREAT: + return 109/24; + case GOOD: + return 107/24; + case SHIT: + return 186/24; + default: + return 3.5; + } + } + + public function getHighscoreDelay():Float + { + switch (abstract) + { + case PERFECT_GOLD | PERFECT: + // return 2.5; + return 140/24; + case EXCELLENT: + return 140/24; + case GREAT: + return 129/24; + case GOOD: + return 127/24; + case SHIT: + return 207/24; default: return 3.5; } From b8920effdcae5b2155a5a9a25e365dd500f9c705 Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Sat, 1 Jun 2024 01:17:58 +0100 Subject: [PATCH 107/266] assets submod.. --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 7a0d92d300..de73a8ec8b 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 7a0d92d3007de42c452b2ea97a917d8c8d114ee7 +Subproject commit de73a8ec8b7462beedca5c2eb539aea38d4c7712 From fd28c91e75b949976bc074d0cd1d0cde5c97b6f4 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 31 May 2024 21:21:46 -0400 Subject: [PATCH 108/266] Update assets submodule --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 7a0d92d300..59d376218d 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 7a0d92d3007de42c452b2ea97a917d8c8d114ee7 +Subproject commit 59d376218d288ef3001de6ef78b8d6d7c5f52842 From 12acdcd9d9cb4cf1a65e5598f421ecca962f33a3 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 31 May 2024 21:55:27 -0400 Subject: [PATCH 109/266] Fix a Results->Freeplay crash --- source/funkin/ui/freeplay/FreeplayState.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 192c6e3ce1..1bde92667e 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, _ -> { From 6851edc64b89ce960d34975af1cf2ce6699e5996 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 31 May 2024 21:55:33 -0400 Subject: [PATCH 110/266] Add new charts --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 59d376218d..0e5a66cb15 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 59d376218d288ef3001de6ef78b8d6d7c5f52842 +Subproject commit 0e5a66cb15229fde2c65503ba1267dfc7b4640b5 From e4eb9a7dc90f40ef667d78c027daecf58832819a Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sat, 1 Jun 2024 16:23:22 -0400 Subject: [PATCH 111/266] assets submod --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 0e5a66cb15..3bfa4e3da8 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 0e5a66cb15229fde2c65503ba1267dfc7b4640b5 +Subproject commit 3bfa4e3da87713ea651f60d4f898c283e5d86093 From bd7875e86a9a3aabe11d9e6679579540ac011189 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sat, 1 Jun 2024 17:13:07 -0400 Subject: [PATCH 112/266] fix rank icons appearing when they shouldn't be --- source/funkin/play/scoring/Scoring.hx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/funkin/play/scoring/Scoring.hx b/source/funkin/play/scoring/Scoring.hx index 6155ec8798..a6d92454bd 100644 --- a/source/funkin/play/scoring/Scoring.hx +++ b/source/funkin/play/scoring/Scoring.hx @@ -351,6 +351,9 @@ class Scoring { if (scoreData == null) return null; + // we can return null here, meaning that the player hasn't actually played and finished the song (thus has no data) + if (scoreData.tallies.totalNotes == 0) return null; + // Perfect (Platinum) is a Sick Full Clear var isPerfectGold = scoreData.tallies.sick == scoreData.tallies.totalNotes; if (isPerfectGold) return ScoringRank.PERFECT_GOLD; From 63bd6f2ace9c093133f1c7e1c02de60ad969aa4a Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Sun, 2 Jun 2024 00:25:52 +0100 Subject: [PATCH 113/266] sparks nd more fixes.. i think --- source/funkin/play/ResultState.hx | 9 +- source/funkin/ui/freeplay/FreeplayState.hx | 194 +++++++++++++++------ source/funkin/ui/freeplay/SongMenuItem.hx | 15 ++ 3 files changed, 164 insertions(+), 54 deletions(-) diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx index 1ad19b41e1..d38731e148 100644 --- a/source/funkin/play/ResultState.hx +++ b/source/funkin/play/ResultState.hx @@ -364,7 +364,7 @@ class ResultState extends MusicBeatSubState rankBg.zIndex = 99999; add(rankBg); - rankBg.alpha = 0; + rankBg.alpha = 0; refresh(); @@ -665,8 +665,7 @@ class ResultState extends MusicBeatSubState else { var rigged:Bool = true; - if (rank > Scoring.calculateRank(params?.prevScoreData)) - //if (rigged) + if (rank > Scoring.calculateRank(params?.prevScoreData)) // if (rigged) { trace('THE RANK IS Higher.....'); @@ -682,7 +681,8 @@ class ResultState extends MusicBeatSubState oldRank: Scoring.calculateRank(params?.prevScoreData), newRank: rank, songId: params.songId, - difficultyId: params.difficultyId + difficultyId: params.difficultyId, + playRankAnim: true } } })); @@ -698,6 +698,7 @@ class ResultState extends MusicBeatSubState fromResults: { oldRank: null, + playRankAnim: false, newRank: rank, songId: params.songId, difficultyId: params.difficultyId diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 186c84c338..e1d8eb81ce 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -6,6 +6,7 @@ import flixel.addons.ui.FlxInputText; import flixel.FlxCamera; import flixel.FlxSprite; import flixel.group.FlxGroup; +import funkin.graphics.shaders.GaussianBlurShader; import flixel.group.FlxGroup.FlxTypedGroup; import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup; import flixel.input.touch.FlxTouch; @@ -45,6 +46,7 @@ import funkin.util.MathUtil; import lime.utils.Assets; import flixel.tweens.misc.ShakeTween; import funkin.effects.IntervalShake; +import funkin.ui.freeplay.SongMenuItem.FreeplayRank; /** * Parameters used to initialize the FreeplayState. @@ -66,6 +68,11 @@ typedef FromResultsParams = */ var ?oldRank:ScoringRank; + /** + * Whether or not to play the rank animation on returning to freeplay. + */ + var playRankAnim:Bool; + /** * The new rank the song has. */ @@ -201,7 +208,8 @@ class FreeplayState extends MusicBeatSubState fromResultsParams = params?.fromResults; - if(fromResultsParams?.oldRank != null){ + if (fromResultsParams?.playRankAnim == true) + { prepForNewRank = true; } @@ -244,10 +252,10 @@ class FreeplayState extends MusicBeatSubState if (prepForNewRank == false) { FunkinSound.playMusic('freakyMenu', - { - overrideExisting: true, - restartTrack: false - }); + { + overrideExisting: true, + restartTrack: false + }); } // Add a null entry that represents the RANDOM option @@ -837,6 +845,9 @@ class FreeplayState extends MusicBeatSubState return songsToFilter; } + var sparks:FlxSprite; + var sparksADD:FlxSprite; + function rankAnimStart(fromResults:Null):Void { busy = true; @@ -848,6 +859,49 @@ class FreeplayState extends MusicBeatSubState FlxG.sound.music.volume = 0; rankBg.alpha = 1; + if (fromResults?.oldRank != null) + { + grpCapsules.members[curSelected].fakeRanking.rank = fromResults.oldRank; + grpCapsules.members[curSelected].fakeBlurredRanking.rank = fromResults.oldRank; + + sparks = new FlxSprite(0, 0); + sparks.frames = Paths.getSparrowAtlas('freeplay/sparks'); + sparks.animation.addByPrefix('sparks', 'sparks', 24, false); + sparks.visible = false; + sparks.blend = BlendMode.ADD; + sparks.setPosition(517, 134); + sparks.scale.set(0.5, 0.5); + add(sparks); + sparks.cameras = [rankCamera]; + + sparksADD = new FlxSprite(0, 0); + sparksADD.visible = false; + sparksADD.frames = Paths.getSparrowAtlas('freeplay/sparksadd'); + sparksADD.animation.addByPrefix('sparks add', 'sparks add', 24, false); + sparksADD.setPosition(498, 116); + sparksADD.blend = BlendMode.ADD; + sparksADD.scale.set(0.5, 0.5); + add(sparksADD); + sparksADD.cameras = [rankCamera]; + + switch (fromResults.oldRank) + { + case SHIT: + sparksADD.color = 0xFF6044FF; + case GOOD: + sparksADD.color = 0xFFEF8764; + case GREAT: + sparksADD.color = 0xFFEAF6FF; + case EXCELLENT: + sparksADD.color = 0xFFFDCB42; + case PERFECT: + sparksADD.color = 0xFFFF58B4; + case PERFECT_GOLD: + sparksADD.color = 0xFFFFB619; + } + // sparksADD.color = sparks.color; + } + grpCapsules.members[curSelected].doLerp = false; // originalPos.x = grpCapsules.members[curSelected].x; @@ -857,8 +911,8 @@ class FreeplayState extends MusicBeatSubState originalPos.y = 235.6; trace(originalPos); - grpCapsules.members[curSelected].ranking.alpha = 0; - grpCapsules.members[curSelected].blurredRanking.alpha = 0; + grpCapsules.members[curSelected].ranking.visible = false; + grpCapsules.members[curSelected].blurredRanking.visible = false; rankCamera.zoom = 1.85; FlxTween.tween(rankCamera, {"zoom": 1.8}, 0.6, {ease: FlxEase.sineIn}); @@ -880,9 +934,8 @@ class FreeplayState extends MusicBeatSubState function rankDisplayNew(fromResults:Null):Void { - grpCapsules.members[curSelected].ranking.alpha = 1; - grpCapsules.members[curSelected].blurredRanking.alpha = 1; - + grpCapsules.members[curSelected].ranking.visible = true; + grpCapsules.members[curSelected].blurredRanking.visible = true; grpCapsules.members[curSelected].ranking.scale.set(20, 20); grpCapsules.members[curSelected].blurredRanking.scale.set(20, 20); @@ -895,7 +948,23 @@ class FreeplayState extends MusicBeatSubState FlxTween.tween(grpCapsules.members[curSelected].blurredRanking, {"scale.x": 1, "scale.y": 1}, 0.1); new FlxTimer().start(0.1, _ -> { - trace(grpCapsules.members[curSelected].ranking.rank); + // trace(grpCapsules.members[curSelected].ranking.rank); + if (fromResults?.oldRank != null) + { + grpCapsules.members[curSelected].fakeRanking.visible = false; + grpCapsules.members[curSelected].fakeBlurredRanking.visible = false; + + sparks.visible = true; + sparksADD.visible = true; + sparks.animation.play('sparks', true); + sparksADD.animation.play('sparks add', true); + + sparks.animation.finishCallback = anim -> { + sparks.visible = false; + sparksADD.visible = false; + }; + } + switch (fromResultsParams?.newRank) { case SHIT: @@ -1053,10 +1122,10 @@ class FreeplayState extends MusicBeatSubState // dj.fistPump(); prepForNewRank = false; FunkinSound.playMusic('freakyMenu', - { - overrideExisting: true, - restartTrack: false - }); + { + overrideExisting: true, + restartTrack: false + }); FlxG.sound.music.fadeIn(4.0, 0.0, 1.0); }); } @@ -1092,35 +1161,56 @@ class FreeplayState extends MusicBeatSubState rankAnimStart(fromResultsParams); } - if (FlxG.keys.justPressed.H) - { - rankDisplayNew(fromResultsParams); - } + // if (FlxG.keys.justPressed.H) + // { + // rankDisplayNew(fromResultsParams); + // } + + // if (FlxG.keys.justPressed.G) + // { + // rankAnimSlam(fromResultsParams); + // } if (FlxG.keys.justPressed.G) { - rankAnimSlam(fromResultsParams); + sparks.y -= 2; + trace(sparks.x, sparks.y); + } + if (FlxG.keys.justPressed.V) + { + sparks.x -= 2; + trace(sparks.x, sparks.y); + } + if (FlxG.keys.justPressed.N) + { + sparks.x += 2; + trace(sparks.x, sparks.y); + } + if (FlxG.keys.justPressed.B) + { + sparks.y += 2; + trace(sparks.x, sparks.y); } if (FlxG.keys.justPressed.I) { - confirmTextGlow.y -= 1; - trace(confirmTextGlow.x, confirmTextGlow.y); + sparksADD.y -= 2; + trace(sparksADD.x, sparksADD.y); } if (FlxG.keys.justPressed.J) { - confirmTextGlow.x -= 1; - trace(confirmTextGlow.x, confirmTextGlow.y); + sparksADD.x -= 2; + trace(sparksADD.x, sparksADD.y); } if (FlxG.keys.justPressed.L) { - confirmTextGlow.x += 1; - trace(confirmTextGlow.x, confirmTextGlow.y); + sparksADD.x += 2; + trace(sparksADD.x, sparksADD.y); } if (FlxG.keys.justPressed.K) { - confirmTextGlow.y += 1; - trace(confirmTextGlow.x, confirmTextGlow.y); + sparksADD.y += 2; + trace(sparksADD.x, sparksADD.y); } #end @@ -1758,26 +1848,27 @@ class FreeplayState extends MusicBeatSubState } else { - if(prepForNewRank == false){ - var potentiallyErect:String = (currentDifficulty == "erect") || (currentDifficulty == "nightmare") ? "-erect" : ""; - // TODO: Stream the instrumental of the selected song? - FunkinSound.playMusic(daSongCapsule.songData.songId, - { - startingVolume: 0.0, - overrideExisting: true, - restartTrack: false, - pathsFunction: INST, - suffix: potentiallyErect, - partialParams: - { - loadPartial: true, - start: 0, - end: 0.1 - }, - onLoad: function() { - FlxG.sound.music.fadeIn(2, 0, 0.4); - } - }); + if (prepForNewRank == false) + { + var potentiallyErect:String = (currentDifficulty == "erect") || (currentDifficulty == "nightmare") ? "-erect" : ""; + // TODO: Stream the instrumental of the selected song? + FunkinSound.playMusic(daSongCapsule.songData.songId, + { + startingVolume: 0.0, + overrideExisting: true, + restartTrack: false, + pathsFunction: INST, + suffix: potentiallyErect, + partialParams: + { + loadPartial: true, + start: 0, + end: 0.1 + }, + onLoad: function() { + FlxG.sound.music.fadeIn(2, 0, 0.4); + } + }); } } grpCapsules.members[curSelected].selected = true; @@ -1791,9 +1882,12 @@ class FreeplayState extends MusicBeatSubState public static function build(?params:FreeplayStateParams, ?stickers:StickerSubState):MusicBeatState { var result:MainMenuState; - if(params?.fromResults.oldRank != null){ + if (params?.fromResults.playRankAnim == true) + { result = new MainMenuState(true); - }else{ + } + else + { result = new MainMenuState(false); } diff --git a/source/funkin/ui/freeplay/SongMenuItem.hx b/source/funkin/ui/freeplay/SongMenuItem.hx index b52032bc3f..3af75c1056 100644 --- a/source/funkin/ui/freeplay/SongMenuItem.hx +++ b/source/funkin/ui/freeplay/SongMenuItem.hx @@ -39,9 +39,13 @@ class SongMenuItem extends FlxSpriteGroup public var songText:CapsuleText; public var favIcon:FlxSprite; + public var ranking:FreeplayRank; public var blurredRanking:FreeplayRank; + public var fakeRanking:FreeplayRank; + public var fakeBlurredRanking:FreeplayRank; + var ranks:Array = ["fail", "average", "great", "excellent", "perfect", "perfectsick"]; public var targetPos:FlxPoint = new FlxPoint(); @@ -131,12 +135,23 @@ class SongMenuItem extends FlxSpriteGroup // doesn't get added, simply is here to help with visibility of things for the pop in! grpHide = new FlxGroup(); + fakeRanking = new FreeplayRank(420, 41); + add(fakeRanking); + + fakeBlurredRanking = new FreeplayRank(fakeRanking.x, fakeRanking.y); + fakeBlurredRanking.shader = new GaussianBlurShader(1); + add(fakeBlurredRanking); + + fakeRanking.visible = false; + fakeBlurredRanking.visible = false; + ranking = new FreeplayRank(420, 41); add(ranking); blurredRanking = new FreeplayRank(ranking.x, ranking.y); blurredRanking.shader = new GaussianBlurShader(1); add(blurredRanking); + // ranking.loadGraphic(Paths.image('freeplay/ranks/' + rank)); // ranking.scale.x = ranking.scale.y = realScaled; // ranking.alpha = 0.75; From b96fa51045f4cae5fa889eade75ac1f1c676034a Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Sun, 2 Jun 2024 00:26:13 +0100 Subject: [PATCH 114/266] assets submod!! --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index d64939d866..ad8a0a28ad 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit d64939d866c70a831b76ed78930782b66871dcc2 +Subproject commit ad8a0a28addb3153c01bca2f8a2fdea05c5ac9ea From 8248cffbafb1621b5c2811f01a02ee62bd3b48ee Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sat, 1 Jun 2024 20:36:14 -0400 Subject: [PATCH 115/266] small bool cleanings, and maybe fixes --- source/funkin/ui/freeplay/FreeplayState.hx | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index e1d8eb81ce..e97ab391b8 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -1121,12 +1121,6 @@ class FreeplayState extends MusicBeatSubState new FlxTimer().start(2, _ -> { // dj.fistPump(); prepForNewRank = false; - FunkinSound.playMusic('freakyMenu', - { - overrideExisting: true, - restartTrack: false - }); - FlxG.sound.music.fadeIn(4.0, 0.0, 1.0); }); } @@ -1527,6 +1521,7 @@ class FreeplayState extends MusicBeatSubState overrideExisting: true, restartTrack: false }); + FlxG.sound.music.fadeIn(4.0, 0.0, 1.0); close(); } else @@ -1842,13 +1837,13 @@ class FreeplayState extends MusicBeatSubState { startingVolume: 0.0, overrideExisting: true, - restartTrack: true + restartTrack: false }); FlxG.sound.music.fadeIn(2, 0, 0.8); } else { - if (prepForNewRank == false) + if (!prepForNewRank) { var potentiallyErect:String = (currentDifficulty == "erect") || (currentDifficulty == "nightmare") ? "-erect" : ""; // TODO: Stream the instrumental of the selected song? @@ -1882,14 +1877,9 @@ class FreeplayState extends MusicBeatSubState public static function build(?params:FreeplayStateParams, ?stickers:StickerSubState):MusicBeatState { var result:MainMenuState; - if (params?.fromResults.playRankAnim == true) - { - result = new MainMenuState(true); - } + if (params?.fromResults.playRankAnim) result = new MainMenuState(true); else - { result = new MainMenuState(false); - } result.openSubState(new FreeplayState(params, stickers)); result.persistentUpdate = false; From 7aee1f900af2d19df18252a72eb382326b878c2f Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 31 May 2024 21:55:27 -0400 Subject: [PATCH 116/266] Fix a Results->Freeplay crash --- source/funkin/ui/freeplay/FreeplayState.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index e97ab391b8..0dd520ee31 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -944,7 +944,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, _ -> { From 7c6c51ea71d8c8790a3ba742e0b7b5724ad33197 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sat, 1 Jun 2024 22:36:47 -0400 Subject: [PATCH 117/266] results dupe fix --- source/funkin/ui/freeplay/FreeplayState.hx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 6441c9cd58..218ecc2ab3 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -712,12 +712,6 @@ class FreeplayState extends MusicBeatSubState // If curSelected is 0, the result will be null and fall back to the rememberedSongId. rememberedSongId = grpCapsules.members[curSelected]?.songData?.songId ?? rememberedSongId; - if (fromResultsParams != null) - { - rememberedSongId = fromResultsParams.songId; - rememberedDifficulty = fromResultsParams.difficultyId; - } - for (cap in grpCapsules.members) { cap.songText.resetText(); @@ -828,6 +822,14 @@ class FreeplayState extends MusicBeatSubState { busy = true; + if (fromResults != null) + { + rememberedSongId = fromResults.songId; + rememberedDifficulty = fromResults.difficultyId; + changeSelection(); + changeDiff(); + } + dj.fistPump(); // rankCamera.fade(FlxColor.BLACK, 0.5, true); rankCamera.fade(0xFF000000, 0.5, true, null, true); From 51a44d481056b5846ed23c97af5f6547ff99ae76 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sat, 1 Jun 2024 23:36:57 -0400 Subject: [PATCH 118/266] persistent draw false for results screen (fixes FUNK-256) --- source/funkin/play/PlayState.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 478a132690..af3281c4bb 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -3144,7 +3144,7 @@ class PlayState extends MusicBeatSubState }, isNewHighscore: isNewHighscore }); - res.camera = camHUD; + this.persistentDraw = false; openSubState(res); } From 08f3b1d95b99ce84907fcf74bc12a68c699dc8a8 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sun, 2 Jun 2024 00:15:10 -0400 Subject: [PATCH 119/266] anim fixes on results --- source/funkin/play/ResultState.hx | 1 + 1 file changed, 1 insertion(+) diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx index 8b8c0aea33..35976c3590 100644 --- a/source/funkin/play/ResultState.hx +++ b/source/funkin/play/ResultState.hx @@ -123,6 +123,7 @@ class ResultState extends MusicBeatSubState FlxG.cameras.add(cameraEverything, false); FlxG.cameras.setDefaultDrawTarget(cameraEverything, true); + this.camera = cameraEverything; // Reset the camera zoom on the results screen. FlxG.camera.zoom = 1.0; From f961ac8e4e55e4d9b9f4250b6c123869a6d1a96a Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Sun, 2 Jun 2024 02:11:06 -0400 Subject: [PATCH 120/266] Actually fix a crash bug on Freeplay menu when selecting a mod --- hmm.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/hmm.json b/hmm.json index fe4e56dd90..f94b662ac9 100644 --- a/hmm.json +++ b/hmm.json @@ -1,12 +1,5 @@ { "dependencies": [ - { - "name": "FlxPartialSound", - "type": "git", - "dir": null, - "ref": "44aa7eb", - "url": "https://github.com/FunkinCrew/FlxPartialSound.git" - }, { "name": "discord_rpc", "type": "git", @@ -47,6 +40,13 @@ "ref": "17e0d59fdbc2b6283a5c0e4df41f1c7f27b71c49", "url": "https://github.com/FunkinCrew/flxanimate" }, + { + "name": "FlxPartialSound", + "type": "git", + "dir": null, + "ref": "f986332ba5ab02abd386ce662578baf04904604a", + "url": "https://github.com/FunkinCrew/FlxPartialSound.git" + }, { "name": "format", "type": "haxelib", From 75621435ea870d80532a66cbf13f60bd361811e3 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sun, 2 Jun 2024 02:53:07 -0400 Subject: [PATCH 121/266] lil more polish to fav icon + clipping --- source/funkin/ui/freeplay/FreeplayState.hx | 11 ++++++----- source/funkin/ui/freeplay/SongMenuItem.hx | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index d3471eeb1c..494bc20f01 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -655,7 +655,7 @@ class FreeplayState extends MusicBeatSubState cardGlow.visible = true; FlxTween.tween(cardGlow, {alpha: 0, "scale.x": 1.2, "scale.y": 1.2}, 0.45, {ease: FlxEase.sineOut}); - if (prepForNewRank == true) + if (prepForNewRank) { rankAnimStart(fromResultsParams); } @@ -686,7 +686,7 @@ class FreeplayState extends MusicBeatSubState rankBg.cameras = [rankCamera]; rankBg.alpha = 0; - if (prepForNewRank == true) + if (prepForNewRank) { rankCamera.fade(0xFF000000, 0, false, null, true); } @@ -782,10 +782,8 @@ class FreeplayState extends MusicBeatSubState funnyMenu.hsvShader = hsvShader; funnyMenu.newText.animation.curAnim.curFrame = 45 - ((i * 4) % 45); - - funnyMenu.forcePosition(); - funnyMenu.checkClip(); + funnyMenu.forcePosition(); grpCapsules.add(funnyMenu); } @@ -1223,6 +1221,8 @@ class FreeplayState extends MusicBeatSubState grpCapsules.members[realShit].favIcon.visible = true; grpCapsules.members[realShit].favIcon.animation.play('fav'); FunkinSound.playOnce(Paths.sound('fav'), 1); + grpCapsules.members[realShit].checkClip(); + grpCapsules.members[realShit].selected = grpCapsules.members[realShit].selected; // set selected again, so it can run it's getter function to initialize movement busy = true; grpCapsules.members[realShit].doLerp = false; @@ -1244,6 +1244,7 @@ class FreeplayState extends MusicBeatSubState FunkinSound.playOnce(Paths.sound('unfav'), 1); new FlxTimer().start(0.2, _ -> { grpCapsules.members[realShit].favIcon.visible = false; + grpCapsules.members[realShit].checkClip(); }); busy = true; diff --git a/source/funkin/ui/freeplay/SongMenuItem.hx b/source/funkin/ui/freeplay/SongMenuItem.hx index 41010f0b5b..b9fef5a79f 100644 --- a/source/funkin/ui/freeplay/SongMenuItem.hx +++ b/source/funkin/ui/freeplay/SongMenuItem.hx @@ -266,7 +266,7 @@ class SongMenuItem extends FlxSpriteGroup var clipType:Int = 0; if (ranking.visible == true) clipType += 1; - if (favIcon.visible == true) clipType += 1; + if (favIcon.visible == true) clipType = 2; switch (clipType) { case 2: From 6596c47f473d935ca135b1e66c384d52007755b8 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 3 Jun 2024 14:03:30 -0400 Subject: [PATCH 122/266] fabs --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index d9ea5ebe5e..f7c418c52f 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit d9ea5ebe5e4db8584a8b1e1e16820b4d1527794c +Subproject commit f7c418c52f38769daf56521ee801df699ae5435b From e12a48b6fc2721086fa54b6deb3d7cd08130ae2b Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 3 Jun 2024 18:18:33 -0400 Subject: [PATCH 123/266] fabs code stuff and difficulty fixin --- assets | 2 +- source/funkin/play/ResultState.hx | 123 ++++++++++++++---------------- 2 files changed, 59 insertions(+), 66 deletions(-) diff --git a/assets b/assets index f7c418c52f..3766c3b670 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit f7c418c52f38769daf56521ee801df699ae5435b +Subproject commit 3766c3b6709f043e63d8eae66887159975891073 diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx index 1740c0371a..6f540687f3 100644 --- a/source/funkin/play/ResultState.hx +++ b/source/funkin/play/ResultState.hx @@ -143,14 +143,14 @@ class ResultState extends MusicBeatSubState bgFlash.scrollFactor.set(); bgFlash.visible = false; bgFlash.zIndex = 20; - //bgFlash.cameras = [cameraBG]; + // bgFlash.cameras = [cameraBG]; add(bgFlash); // The sound system which falls into place behind the score text. Plays every time! var soundSystem:FlxSprite = FunkinSprite.createSparrow(-15, -180, 'resultScreen/soundSystem'); soundSystem.animation.addByPrefix("idle", "sound system", 24, false); soundSystem.visible = false; - new FlxTimer().start(8/24, _ -> { + new FlxTimer().start(8 / 24, _ -> { soundSystem.animation.play("idle"); soundSystem.visible = true; }); @@ -168,13 +168,12 @@ class ResultState extends MusicBeatSubState heartsPerfect.anim.onComplete = () -> { if (heartsPerfect != null) { - //bfPerfect.anim.curFrame = 137; + // bfPerfect.anim.curFrame = 137; heartsPerfect.anim.curFrame = 43; heartsPerfect.anim.play(); // unpauses this anim, since it's on PlayOnce! } }; - bfPerfect = new FlxAtlasSprite(1342, 370, Paths.animateAtlas("resultScreen/results-bf/resultsPERFECT", "shared")); bfPerfect.visible = false; bfPerfect.zIndex = 500; @@ -183,7 +182,7 @@ class ResultState extends MusicBeatSubState bfPerfect.anim.onComplete = () -> { if (bfPerfect != null) { - //bfPerfect.anim.curFrame = 137; + // bfPerfect.anim.curFrame = 137; bfPerfect.anim.curFrame = 137; bfPerfect.anim.play(); // unpauses this anim, since it's on PlayOnce! } @@ -203,7 +202,6 @@ class ResultState extends MusicBeatSubState } }; - case GREAT: gfGreat = new FlxAtlasSprite(802, 331, Paths.animateAtlas("resultScreen/results-bf/resultsGREAT/gf", "shared")); gfGreat.visible = false; @@ -273,7 +271,7 @@ class ResultState extends MusicBeatSubState }); } - var diffSpr:String = 'dif${params?.difficultyId ?? 'Normal'}'; + var diffSpr:String = 'diff_${params?.difficultyId ?? 'Normal'}'; difficulty.loadGraphic(Paths.image("resultScreen/" + diffSpr)); add(difficulty); @@ -293,7 +291,7 @@ class ResultState extends MusicBeatSubState var blackTopBar:FlxSprite = new FlxSprite().loadGraphic(Paths.image("resultScreen/topBarBlack")); blackTopBar.y = -blackTopBar.height; - FlxTween.tween(blackTopBar, {y: 0}, 7/24, {ease: FlxEase.quartOut, startDelay: 3/24}); + FlxTween.tween(blackTopBar, {y: 0}, 7 / 24, {ease: FlxEase.quartOut, startDelay: 3 / 24}); blackTopBar.zIndex = 1010; add(blackTopBar); @@ -301,7 +299,7 @@ class ResultState extends MusicBeatSubState resultsAnim.visible = false; resultsAnim.zIndex = 1200; add(resultsAnim); - new FlxTimer().start(6/24, _ -> { + new FlxTimer().start(6 / 24, _ -> { resultsAnim.visible = true; resultsAnim.animation.play("result"); }); @@ -310,7 +308,7 @@ class ResultState extends MusicBeatSubState ratingsPopin.visible = false; ratingsPopin.zIndex = 1200; add(ratingsPopin); - new FlxTimer().start(21/24, _ -> { + new FlxTimer().start(21 / 24, _ -> { ratingsPopin.visible = true; ratingsPopin.animation.play("idle"); }); @@ -319,15 +317,13 @@ class ResultState extends MusicBeatSubState scorePopin.visible = false; scorePopin.zIndex = 1200; add(scorePopin); - new FlxTimer().start(36/24, _ -> { + new FlxTimer().start(36 / 24, _ -> { scorePopin.visible = true; scorePopin.animation.play("score"); - scorePopin.animation.finishCallback = anim -> { - - }; + scorePopin.animation.finishCallback = anim -> {}; }); - new FlxTimer().start(37/24, _ -> { + new FlxTimer().start(37 / 24, _ -> { score.visible = true; score.animateNumbers(); startRankTallySequence(); @@ -344,22 +340,22 @@ class ResultState extends MusicBeatSubState highscoreNew.frames = Paths.getSparrowAtlas("resultScreen/highscoreNew"); highscoreNew.animation.addByPrefix("new", "highscoreAnim0", 24, false); highscoreNew.visible = false; - //highscoreNew.setGraphicSize(Std.int(highscoreNew.width * 0.8)); + // highscoreNew.setGraphicSize(Std.int(highscoreNew.width * 0.8)); highscoreNew.updateHitbox(); highscoreNew.zIndex = 1200; add(highscoreNew); new FlxTimer().start(rank.getHighscoreDelay(), _ -> { - if (params.isNewHighscore ?? false) - { - highscoreNew.visible = true; - highscoreNew.animation.play("new"); - highscoreNew.animation.finishCallback = _ -> highscoreNew.animation.play("new", true, false, 16); - } - else - { - highscoreNew.visible = false; - } + if (params.isNewHighscore ?? false) + { + highscoreNew.visible = true; + highscoreNew.animation.play("new"); + highscoreNew.animation.finishCallback = _ -> highscoreNew.animation.play("new", true, false, 16); + } + else + { + highscoreNew.visible = false; + } }); var hStuf:Int = 50; @@ -411,17 +407,16 @@ class ResultState extends MusicBeatSubState }); } - - // if (params.isNewHighscore ?? false) - // { - // highscoreNew.visible = true; - // highscoreNew.animation.play("new"); - // //FlxTween.tween(highscoreNew, {y: highscoreNew.y + 10}, 0.8, {ease: FlxEase.quartOut}); - // } - // else - // { - // highscoreNew.visible = false; - // } + // if (params.isNewHighscore ?? false) + // { + // highscoreNew.visible = true; + // highscoreNew.animation.play("new"); + // //FlxTween.tween(highscoreNew, {y: highscoreNew.y + 10}, 0.8, {ease: FlxEase.quartOut}); + // } + // else + // { + // highscoreNew.visible = false; + // } new FlxTimer().start(rank.getMusicDelay(), _ -> { if (rank.hasMusicIntro()) @@ -468,7 +463,7 @@ class ResultState extends MusicBeatSubState function startRankTallySequence():Void { bgFlash.visible = true; - FlxTween.tween(bgFlash, {alpha: 0}, 5/24); + FlxTween.tween(bgFlash, {alpha: 0}, 5 / 24); var clearPercentFloat = (params.scoreData.tallies.sick + params.scoreData.tallies.good) / params.scoreData.tallies.totalNotes * 100; clearPercentTarget = Math.floor(clearPercentFloat); // Prevent off-by-one errors. @@ -478,7 +473,7 @@ class ResultState extends MusicBeatSubState trace('Clear percent target: ' + clearPercentFloat + ', round: ' + clearPercentTarget); var clearPercentCounter:ClearPercentCounter = new ClearPercentCounter(FlxG.width / 2 + 190, FlxG.height / 2 - 70, clearPercentLerp); - FlxTween.tween(clearPercentCounter, {curNumber: clearPercentTarget}, 58/24, + FlxTween.tween(clearPercentCounter, {curNumber: clearPercentTarget}, 58 / 24, { ease: FlxEase.quartOut, onUpdate: _ -> { @@ -501,7 +496,7 @@ class ResultState extends MusicBeatSubState clearPercentCounter.flash(false); }); - //displayRankText(); + // displayRankText(); // previously 2.0 seconds new FlxTimer().start(0.25, _ -> { @@ -514,7 +509,7 @@ class ResultState extends MusicBeatSubState } }); - //afterRankTallySequence(); + // afterRankTallySequence(); }); } }); @@ -554,7 +549,7 @@ class ResultState extends MusicBeatSubState { bgFlash.visible = true; bgFlash.alpha = 1; - FlxTween.tween(bgFlash, {alpha: 0}, 14/24); + FlxTween.tween(bgFlash, {alpha: 0}, 14 / 24); var rankTextVert:FlxBackdrop = new FlxBackdrop(Paths.image(rank.getVerTextAsset()), Y, 0, 30); rankTextVert.x = FlxG.width - 44; @@ -562,14 +557,13 @@ class ResultState extends MusicBeatSubState rankTextVert.zIndex = 990; add(rankTextVert); - FlxFlicker.flicker(rankTextVert, 2/24 * 3, 2/24, true); + FlxFlicker.flicker(rankTextVert, 2 / 24 * 3, 2 / 24, true); // Scrolling. - new FlxTimer().start(30/24, _ -> { - rankTextVert.velocity.y = -80; + new FlxTimer().start(30 / 24, _ -> { + rankTextVert.velocity.y = -80; }); - for (i in 0...12) { var rankTextBack:FlxBackdrop = new FlxBackdrop(Paths.image(rank.getHorTextAsset()), X, 10, 0); @@ -589,7 +583,6 @@ class ResultState extends MusicBeatSubState function afterRankTallySequence():Void { - showSmallClearPercent(); switch (rank) @@ -605,15 +598,15 @@ class ResultState extends MusicBeatSubState bfPerfect.playAnimation(''); } new FlxTimer().start(106 / 24, _ -> { - if (heartsPerfect == null) - { - trace("Could not build heartsPerfect animation!"); - } - else - { - heartsPerfect.visible = true; - heartsPerfect.playAnimation(''); - } + if (heartsPerfect == null) + { + trace("Could not build heartsPerfect animation!"); + } + else + { + heartsPerfect.visible = true; + heartsPerfect.playAnimation(''); + } }); case EXCELLENT: if (bfExcellent == null) @@ -637,15 +630,15 @@ class ResultState extends MusicBeatSubState } new FlxTimer().start(6 / 24, _ -> { - if (gfGreat == null) - { - trace("Could not build GREAT animation for gf!"); - } - else - { - gfGreat.visible = true; - gfGreat.playAnimation(''); - } + if (gfGreat == null) + { + trace("Could not build GREAT animation for gf!"); + } + else + { + gfGreat.visible = true; + gfGreat.playAnimation(''); + } }); case SHIT: if (bfShit == null) From cd85bcf22264b9527848a2d2963206b898ee8bd2 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 3 Jun 2024 18:32:46 -0400 Subject: [PATCH 124/266] assets submod --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 3766c3b670..1f3e2932eb 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 3766c3b6709f043e63d8eae66887159975891073 +Subproject commit 1f3e2932ebc3395eb484e364605c233166052868 From bc21f0c6063453e10e102411c7c69018d978c29e Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Mon, 3 Jun 2024 19:39:37 -0400 Subject: [PATCH 125/266] Update assets submodule --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 1f3e2932eb..4039bd018d 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 1f3e2932ebc3395eb484e364605c233166052868 +Subproject commit 4039bd018d474994b44317b74cdd724b5f73b749 From c056c7276285b847e4ea969ccb3b38dd23fd60b6 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 4 Jun 2024 14:26:24 -0400 Subject: [PATCH 126/266] Implement advanced save data repair. --- source/funkin/save/Save.hx | 81 +++++++++++++++++++ .../funkin/save/migrator/SaveDataMigrator.hx | 1 + source/funkin/util/VersionUtil.hx | 5 +- 3 files changed, 86 insertions(+), 1 deletion(-) diff --git a/source/funkin/save/Save.hx b/source/funkin/save/Save.hx index 7f25a8e014..7634c1f51b 100644 --- a/source/funkin/save/Save.hx +++ b/source/funkin/save/Save.hx @@ -732,6 +732,87 @@ class Save } } + public static function archiveBadSaveData(data:Dynamic):Void + { + // We want to save this somewhere so we can try to recover it for the user in the future! + + final RECOVERY_SLOT_START = 1000; + + writeToAvailableSlot(RECOVERY_SLOT_START, data); + } + + public static function debug_queryBadSaveData():Void + { + final RECOVERY_SLOT_START = 1000; + final RECOVERY_SLOT_END = 1100; + var firstBadSaveData = querySlotRange(RECOVERY_SLOT_START, RECOVERY_SLOT_END); + if (firstBadSaveData > 0) + { + trace('[SAVE] Found bad save data in slot ${firstBadSaveData}!'); + trace('We should look into recovery...'); + + trace(haxe.Json.stringify(fetchFromSlotRaw(firstBadSaveData))); + } + } + + static function fetchFromSlotRaw(slot:Int):Null + { + var targetSaveData = new FlxSave(); + targetSaveData.bind('$SAVE_NAME${slot}', SAVE_PATH); + if (targetSaveData.isEmpty()) return null; + return targetSaveData.data; + } + + static function writeToAvailableSlot(slot:Int, data:Dynamic):Void + { + trace('[SAVE] Finding slot to write data to (starting with ${slot})...'); + + var targetSaveData = new FlxSave(); + targetSaveData.bind('$SAVE_NAME${slot}', SAVE_PATH); + while (!targetSaveData.isEmpty()) + { + // Keep trying to bind to slots until we find an empty slot. + trace('[SAVE] Slot ${slot} is taken, continuing...'); + slot++; + targetSaveData.bind('$SAVE_NAME${slot}', SAVE_PATH); + } + + trace('[SAVE] Writing data to slot ${slot}...'); + targetSaveData.mergeData(data, true); + + trace('[SAVE] Data written to slot ${slot}!'); + } + + /** + * Return true if the given save slot is not empty. + * @param slot The slot number to check. + * @return Whether the slot is not empty. + */ + static function querySlot(slot:Int):Bool + { + var targetSaveData = new FlxSave(); + targetSaveData.bind('$SAVE_NAME${slot}', SAVE_PATH); + return !targetSaveData.isEmpty(); + } + + /** + * Return true if any of the slots in the given range is not empty. + * @param start The starting slot number to check. + * @param end The ending slot number to check. + * @return The first slot in the range that is not empty, or `-1` if none are. + */ + static function querySlotRange(start:Int, end:Int):Int + { + for (i in start...end) + { + if (querySlot(i)) + { + return i; + } + } + return -1; + } + static function fetchLegacySaveData():Null { trace("[SAVE] Checking for legacy save data..."); diff --git a/source/funkin/save/migrator/SaveDataMigrator.hx b/source/funkin/save/migrator/SaveDataMigrator.hx index 4fa9dd6b31..b7d278cc6e 100644 --- a/source/funkin/save/migrator/SaveDataMigrator.hx +++ b/source/funkin/save/migrator/SaveDataMigrator.hx @@ -36,6 +36,7 @@ class SaveDataMigrator { var message:String = 'Error migrating save data, expected ${Save.SAVE_DATA_VERSION}.'; lime.app.Application.current.window.alert(message, "Save Data Failure"); + Save.archiveBadSaveData(inputData); trace('[SAVE] ' + message); return new Save(Save.getDefault()); } diff --git a/source/funkin/util/VersionUtil.hx b/source/funkin/util/VersionUtil.hx index 18d7eafa66..b84b663414 100644 --- a/source/funkin/util/VersionUtil.hx +++ b/source/funkin/util/VersionUtil.hx @@ -39,13 +39,16 @@ class VersionUtil if (thx.Types.isAnonymousObject(versionData.version)) { // This is bad! versionData.version should be an array! - versionData.version = [versionData.version[0], versionData.version[1], versionData.version[2]]; + trace('[SAVE] Version data repair required! (got ${versionData.version})'); + var fixedVersionData = [versionData.version[0], versionData.version[1], versionData.version[2]]; + versionData.version = fixedVersionData; var fixedVersion:thx.semver.Version = versionData; return fixedVersion; } else { + trace('[SAVE] Version data repair not required (got ${version})'); // No need for repair. return version; } From d4712a8ef7ebc60318e47b6c70faca646a9d0830 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 4 Jun 2024 16:24:24 -0400 Subject: [PATCH 127/266] alphabetical filtering for freeplay non-all sort --- source/funkin/ui/freeplay/FreeplayState.hx | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 494bc20f01..fe64a1e6f4 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -804,6 +804,13 @@ class FreeplayState extends MusicBeatSubState */ public function sortSongs(songsToFilter:Array, songFilter:SongFilter):Array { + var filterAlphabetically = function(a:FreeplaySongData, b:FreeplaySongData):Int { + if (a?.songName.toLowerCase() < b?.songName.toLowerCase()) return -1; + else if (a?.songName.toLowerCase() > b?.songName.toLowerCase()) return 1; + else + return 0; + }; + switch (songFilter.filterType) { case REGEXP: @@ -818,6 +825,8 @@ class FreeplayState extends MusicBeatSubState return filterRegexp.match(str.songName); }); + songsToFilter.sort(filterAlphabetically); + case STARTSWITH: // extra note: this is essentially a "search" @@ -832,9 +841,13 @@ class FreeplayState extends MusicBeatSubState if (str == null) return true; // Random return str.isFav; }); + + songsToFilter.sort(filterAlphabetically); + default: // return all on default } + return songsToFilter; } From 29a33c8815a1ca3e33a731f9d8d405a57041f102 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 4 Jun 2024 16:38:21 -0400 Subject: [PATCH 128/266] modifies behaviour of how the difficulty stars appear --- source/funkin/ui/freeplay/AlbumRoll.hx | 7 ++++--- source/funkin/ui/freeplay/DifficultyStars.hx | 11 ++++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/source/funkin/ui/freeplay/AlbumRoll.hx b/source/funkin/ui/freeplay/AlbumRoll.hx index 20cd913794..49c5887225 100644 --- a/source/funkin/ui/freeplay/AlbumRoll.hx +++ b/source/funkin/ui/freeplay/AlbumRoll.hx @@ -66,7 +66,7 @@ class AlbumRoll extends FlxSpriteGroup add(newAlbumArt); difficultyStars = new DifficultyStars(140, 39); - difficultyStars.stars.visible = false; + difficultyStars.visible = false; add(difficultyStars); } @@ -149,7 +149,7 @@ class AlbumRoll extends FlxSpriteGroup newAlbumArt.visible = true; newAlbumArt.playAnimation(animNames.get('$albumId-active'), false, false, false); - difficultyStars.stars.visible = false; + difficultyStars.visible = false; new FlxTimer().start(0.75, function(_) { // showTitle(); showStars(); @@ -172,6 +172,7 @@ class AlbumRoll extends FlxSpriteGroup */ public function showStars():Void { - difficultyStars.stars.visible = true; // true; + difficultyStars.visible = true; // true; + difficultyStars.flameCheck(); } } diff --git a/source/funkin/ui/freeplay/DifficultyStars.hx b/source/funkin/ui/freeplay/DifficultyStars.hx index 51526bcbec..e7a2b8888d 100644 --- a/source/funkin/ui/freeplay/DifficultyStars.hx +++ b/source/funkin/ui/freeplay/DifficultyStars.hx @@ -19,7 +19,7 @@ class DifficultyStars extends FlxSpriteGroup public var stars:FlxAtlasSprite; - var flames:FreeplayFlames; + public var flames:FreeplayFlames; var hsvShader:HSVShader; @@ -80,11 +80,16 @@ class DifficultyStars extends FlxSpriteGroup curDifficulty = difficulty - 1; } + flameCheck(); + + return difficulty; + } + + public function flameCheck():Void + { if (difficulty > 10) flames.flameCount = difficulty - 10; else flames.flameCount = 0; - - return difficulty; } function set_curDifficulty(value:Int):Int From 84d4d044d647fa3460ca484526cb3282a0c51930 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 4 Jun 2024 16:47:58 -0400 Subject: [PATCH 129/266] check clip width when text changes --- source/funkin/ui/freeplay/CapsuleText.hx | 20 ++++++++++++++++---- source/funkin/ui/freeplay/SongMenuItem.hx | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/source/funkin/ui/freeplay/CapsuleText.hx b/source/funkin/ui/freeplay/CapsuleText.hx index c3fd51d1fd..c3bcdb09bb 100644 --- a/source/funkin/ui/freeplay/CapsuleText.hx +++ b/source/funkin/ui/freeplay/CapsuleText.hx @@ -58,12 +58,24 @@ class CapsuleText extends FlxSpriteGroup function set_clipWidth(value:Int):Int { resetText(); - if (whiteText.width > value) + checkClipWidth(value); + return clipWidth = value; + } + + /** + * Checks if the text if it's too long, and clips if it is + * @param wid + */ + function checkClipWidth(?wid:Int):Void + { + if (wid == null) wid = clipWidth; + + if (whiteText.width > wid) { tooLong = true; - blurredText.clipRect = new FlxRect(0, 0, value, blurredText.height); - whiteText.clipRect = new FlxRect(0, 0, value, whiteText.height); + blurredText.clipRect = new FlxRect(0, 0, wid, blurredText.height); + whiteText.clipRect = new FlxRect(0, 0, wid, whiteText.height); } else { @@ -72,7 +84,6 @@ class CapsuleText extends FlxSpriteGroup blurredText.clipRect = null; whiteText.clipRect = null; } - return clipWidth = value; } function set_text(value:String):String @@ -86,6 +97,7 @@ class CapsuleText extends FlxSpriteGroup blurredText.text = value; whiteText.text = value; + checkClipWidth(); whiteText.textField.filters = [ new openfl.filters.GlowFilter(0x00ccff, 1, 5, 5, 210, BitmapFilterQuality.MEDIUM), // new openfl.filters.BlurFilter(5, 5, BitmapFilterQuality.LOW) diff --git a/source/funkin/ui/freeplay/SongMenuItem.hx b/source/funkin/ui/freeplay/SongMenuItem.hx index b9fef5a79f..d40809fada 100644 --- a/source/funkin/ui/freeplay/SongMenuItem.hx +++ b/source/funkin/ui/freeplay/SongMenuItem.hx @@ -326,7 +326,7 @@ class SongMenuItem extends FlxSpriteGroup var evilTrail:FlxTrail; - public function fadeAnim() + public function fadeAnim():Void { impactThing = new FunkinSprite(0, 0); impactThing.frames = capsule.frames; From 6a62f38c33a33c90c224bfc7ecbef0481e29c908 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 4 Jun 2024 16:51:27 -0400 Subject: [PATCH 130/266] quicki fix for incorrect clip tweens --- source/funkin/ui/freeplay/SongMenuItem.hx | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/source/funkin/ui/freeplay/SongMenuItem.hx b/source/funkin/ui/freeplay/SongMenuItem.hx index d40809fada..b861bca15b 100644 --- a/source/funkin/ui/freeplay/SongMenuItem.hx +++ b/source/funkin/ui/freeplay/SongMenuItem.hx @@ -671,14 +671,9 @@ class SongMenuItem extends FlxSpriteGroup ranking.alpha = this.selected ? 1 : 0.7; ranking.color = this.selected ? 0xFFFFFFFF : 0xFFAAAAAA; - if (selected) - { - if (songText.tooLong == true) songText.initMove(); - } - else - { - if (songText.tooLong == true) songText.resetText(); - } + if (songText.tooLong) songText.resetText(); + + if (selected && songText.tooLong) songText.initMove(); } } From ae950c738214e20446cc8ded5b163544a5ee0280 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 4 Jun 2024 19:44:00 -0400 Subject: [PATCH 131/266] Finish save data repair (you should be able to transfer your save now) --- CHANGELOG.md | 1 + source/funkin/save/Save.hx | 16 +++++++++------- source/funkin/save/changelog.md | 4 ++++ .../funkin/save/migrator/SaveDataMigrator.hx | 6 +++--- source/funkin/util/VersionUtil.hx | 18 ++++++++++++++++-- 5 files changed, 33 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5aefb8855..898978ca38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Senpai (increased the note speed) - Thorns (increased the note speed slightly) - Favorite songs marked in Freeplay are now stored between sessions. +- In the event that the game cannot load your save data, it will now perform a backup before clearing it, so that we can try to repair it in the future. - 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!) diff --git a/source/funkin/save/Save.hx b/source/funkin/save/Save.hx index 7634c1f51b..2ff6b96cc1 100644 --- a/source/funkin/save/Save.hx +++ b/source/funkin/save/Save.hx @@ -16,7 +16,7 @@ import thx.semver.Version; @:nullSafety class Save { - public static final SAVE_DATA_VERSION:thx.semver.Version = "2.0.4"; + public static final SAVE_DATA_VERSION:thx.semver.Version = "2.0.5"; public static final SAVE_DATA_VERSION_RULE:thx.semver.VersionRule = "2.0.x"; // We load this version's saves from a new save path, to maintain SOME level of backwards compatibility. @@ -56,6 +56,9 @@ class Save if (data == null) this.data = Save.getDefault(); else this.data = data; + + // Make sure the verison number is up to date before we flush. + this.data.version = Save.SAVE_DATA_VERSION; } public static function getDefault():RawSaveData @@ -713,7 +716,6 @@ class Save { trace('[SAVE] Found legacy save data, converting...'); var gameSave = SaveDataMigrator.migrateFromLegacy(legacySaveData); - @:privateAccess FlxG.save.mergeData(gameSave.data, true); } else @@ -725,20 +727,19 @@ class Save } else { - trace('[SAVE] Loaded save data.'); - @:privateAccess + trace('[SAVE] Found existing save data.'); var gameSave = SaveDataMigrator.migrate(FlxG.save.data); FlxG.save.mergeData(gameSave.data, true); } } - public static function archiveBadSaveData(data:Dynamic):Void + public static function archiveBadSaveData(data:Dynamic):Int { // We want to save this somewhere so we can try to recover it for the user in the future! final RECOVERY_SLOT_START = 1000; - writeToAvailableSlot(RECOVERY_SLOT_START, data); + return writeToAvailableSlot(RECOVERY_SLOT_START, data); } public static function debug_queryBadSaveData():Void @@ -763,7 +764,7 @@ class Save return targetSaveData.data; } - static function writeToAvailableSlot(slot:Int, data:Dynamic):Void + static function writeToAvailableSlot(slot:Int, data:Dynamic):Int { trace('[SAVE] Finding slot to write data to (starting with ${slot})...'); @@ -781,6 +782,7 @@ class Save targetSaveData.mergeData(data, true); trace('[SAVE] Data written to slot ${slot}!'); + return slot; } /** diff --git a/source/funkin/save/changelog.md b/source/funkin/save/changelog.md index 7c9094f2dd..e3038373d2 100644 --- a/source/funkin/save/changelog.md +++ b/source/funkin/save/changelog.md @@ -5,6 +5,10 @@ All notable changes to this project 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). +## [2.0.5] - 2024-05-21 +### Fixed +- Resolved an issue where HTML5 wouldn't store the semantic version properly, causing the game to fail to load the save. + ## [2.0.4] - 2024-05-21 ### Added - `favoriteSongs:Array` to `Save` diff --git a/source/funkin/save/migrator/SaveDataMigrator.hx b/source/funkin/save/migrator/SaveDataMigrator.hx index b7d278cc6e..7a929322a0 100644 --- a/source/funkin/save/migrator/SaveDataMigrator.hx +++ b/source/funkin/save/migrator/SaveDataMigrator.hx @@ -35,9 +35,9 @@ class SaveDataMigrator else { var message:String = 'Error migrating save data, expected ${Save.SAVE_DATA_VERSION}.'; - lime.app.Application.current.window.alert(message, "Save Data Failure"); - Save.archiveBadSaveData(inputData); - trace('[SAVE] ' + message); + var slot:Int = Save.archiveBadSaveData(inputData); + var fullMessage:String = 'An error occurred migrating your save data.\n${message}\nInvalid data has been moved to save slot ${slot}.'; + lime.app.Application.current.window.alert(fullMessage, "Save Data Failure"); return new Save(Save.getDefault()); } } diff --git a/source/funkin/util/VersionUtil.hx b/source/funkin/util/VersionUtil.hx index b84b663414..832ce008ab 100644 --- a/source/funkin/util/VersionUtil.hx +++ b/source/funkin/util/VersionUtil.hx @@ -23,6 +23,8 @@ class VersionUtil { try { + var versionRaw:thx.semver.Version.SemVer = version; + trace('${versionRaw} satisfies (${versionRule})? ${version.satisfies(versionRule)}'); return version.satisfies(versionRule); } catch (e) @@ -40,10 +42,22 @@ class VersionUtil { // This is bad! versionData.version should be an array! trace('[SAVE] Version data repair required! (got ${versionData.version})'); - var fixedVersionData = [versionData.version[0], versionData.version[1], versionData.version[2]]; - versionData.version = fixedVersionData; + // Turn the objects back into arrays. + // I'd use DynamicsT.values but IDK if it maintains order + versionData.version = [versionData.version[0], versionData.version[1], versionData.version[2]]; + + // This is so jank but it should work. + var buildData:Dynamic = cast versionData.build; + var buildDataFixed:Array = thx.Dynamics.DynamicsT.values(buildData) + .map(function(d:Dynamic) return StringId(d.toString())); + versionData.build = buildDataFixed; + + var preData:Dynamic = cast versionData.pre; + var preDataFixed:Array = thx.Dynamics.DynamicsT.values(preData).map(function(d:Dynamic) return StringId(d.toString())); + versionData.pre = preDataFixed; var fixedVersion:thx.semver.Version = versionData; + trace('[SAVE] Fixed version: ${fixedVersion}'); return fixedVersion; } else From 97400ed5d8dc8867f7eb4dde01ed7b0832309054 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 4 Jun 2024 22:26:35 -0400 Subject: [PATCH 132/266] santa sounds --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 4039bd018d..b7d3772e76 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 4039bd018d474994b44317b74cdd724b5f73b749 +Subproject commit b7d3772e76ca1d05626201594acb7f4b996d4a80 From f2dd626ed9ab616d6b66d72fb2b399683fd11999 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 4 Jun 2024 22:37:51 -0400 Subject: [PATCH 133/266] rollback viz hmm --- hmm.json | 2 +- source/funkin/audio/visualize/ABotVis.hx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hmm.json b/hmm.json index e364e405fe..a1998f515d 100644 --- a/hmm.json +++ b/hmm.json @@ -49,7 +49,7 @@ "name": "funkin.vis", "type": "git", "dir": null, - "ref": "38261833590773cb1de34ac5d11e0825696fc340", + "ref": "c6a1e24d48646849ea63563ca45561512c953779", "url": "https://github.com/FunkinCrew/funkVis" }, { diff --git a/source/funkin/audio/visualize/ABotVis.hx b/source/funkin/audio/visualize/ABotVis.hx index 15596318c3..8ddc416911 100644 --- a/source/funkin/audio/visualize/ABotVis.hx +++ b/source/funkin/audio/visualize/ABotVis.hx @@ -58,7 +58,7 @@ class ABotVis extends FlxTypedSpriteGroup public function initAnalyzer() { @:privateAccess - analyzer = new SpectralAnalyzer(snd._channel.__source, 7, 0.01, 30); + analyzer = new SpectralAnalyzer(snd._channel.__source, 7, 0.1, 30); // analyzer.maxDb = -35; // analyzer.fftN = 2048; } From 8bdaf8f513c9a003f1622123dce1aeeb1d8ebab5 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 4 Jun 2024 22:55:21 -0400 Subject: [PATCH 134/266] web rank sounds --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index b7d3772e76..f2202ff9d9 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit b7d3772e76ca1d05626201594acb7f4b996d4a80 +Subproject commit f2202ff9d920743830cf2b47442040ad80f5ca05 From 66d86a6969b924cba3c17ae5505aea7dbddcec6f Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 4 Jun 2024 23:07:08 -0400 Subject: [PATCH 135/266] 2hot death fix --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index f2202ff9d9..613365d989 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit f2202ff9d920743830cf2b47442040ad80f5ca05 +Subproject commit 613365d98921346f0502a62d0a5f68fce6d27373 From 50990b15e100a18f2f3d2cd8074e09a8c70e3749 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 4 Jun 2024 23:36:32 -0400 Subject: [PATCH 136/266] heart glow --- source/funkin/ui/freeplay/FreeplayState.hx | 6 ++++++ source/funkin/ui/freeplay/SongMenuItem.hx | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index fe64a1e6f4..4fc94c2d79 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -757,6 +757,7 @@ class FreeplayState extends MusicBeatSubState randomCapsule.alpha = 0; randomCapsule.songText.visible = false; randomCapsule.favIcon.visible = false; + randomCapsule.favIconBlurred.visible = false; randomCapsule.ranking.visible = false; randomCapsule.blurredRanking.visible = false; randomCapsule.initJumpIn(0, force); @@ -779,6 +780,7 @@ class FreeplayState extends MusicBeatSubState funnyMenu.capsule.alpha = 0.5; funnyMenu.songText.visible = false; funnyMenu.favIcon.visible = tempSongs[i].isFav; + funnyMenu.favIconBlurred.visible = tempSongs[i].isFav; funnyMenu.hsvShader = hsvShader; funnyMenu.newText.animation.curAnim.curFrame = 45 - ((i * 4) % 45); @@ -1232,7 +1234,9 @@ class FreeplayState extends MusicBeatSubState if (isFav) { grpCapsules.members[realShit].favIcon.visible = true; + grpCapsules.members[realShit].favIconBlurred.visible = true; grpCapsules.members[realShit].favIcon.animation.play('fav'); + grpCapsules.members[realShit].favIconBlurred.animation.play('fav'); FunkinSound.playOnce(Paths.sound('fav'), 1); grpCapsules.members[realShit].checkClip(); grpCapsules.members[realShit].selected = grpCapsules.members[realShit].selected; // set selected again, so it can run it's getter function to initialize movement @@ -1254,9 +1258,11 @@ class FreeplayState extends MusicBeatSubState else { grpCapsules.members[realShit].favIcon.animation.play('fav', true, true, 9); + grpCapsules.members[realShit].favIconBlurred.animation.play('fav', true, true, 9); FunkinSound.playOnce(Paths.sound('unfav'), 1); new FlxTimer().start(0.2, _ -> { grpCapsules.members[realShit].favIcon.visible = false; + grpCapsules.members[realShit].favIconBlurred.visible = false; grpCapsules.members[realShit].checkClip(); }); diff --git a/source/funkin/ui/freeplay/SongMenuItem.hx b/source/funkin/ui/freeplay/SongMenuItem.hx index b861bca15b..fb91fbd1c5 100644 --- a/source/funkin/ui/freeplay/SongMenuItem.hx +++ b/source/funkin/ui/freeplay/SongMenuItem.hx @@ -38,6 +38,7 @@ class SongMenuItem extends FlxSpriteGroup public var selected(default, set):Bool; public var songText:CapsuleText; + public var favIconBlurred:FlxSprite; public var favIcon:FlxSprite; public var ranking:FreeplayRank; @@ -190,6 +191,16 @@ class SongMenuItem extends FlxSpriteGroup add(pixelIcon); grpHide.add(pixelIcon); + favIconBlurred = new FlxSprite(380, 40); + favIconBlurred.frames = Paths.getSparrowAtlas('freeplay/favHeart'); + favIconBlurred.animation.addByPrefix('fav', 'favorite heart', 24, false); + favIconBlurred.animation.play('fav'); + favIconBlurred.setGraphicSize(50, 50); + favIconBlurred.blend = BlendMode.ADD; + favIconBlurred.shader = new GaussianBlurShader(1.2); + favIconBlurred.visible = false; + add(favIconBlurred); + favIcon = new FlxSprite(380, 40); favIcon.frames = Paths.getSparrowAtlas('freeplay/favHeart'); favIcon.animation.addByPrefix('fav', 'favorite heart', 24, false); @@ -669,6 +680,8 @@ class SongMenuItem extends FlxSpriteGroup capsule.offset.x = this.selected ? 0 : -5; capsule.animation.play(this.selected ? "selected" : "unselected"); ranking.alpha = this.selected ? 1 : 0.7; + favIcon.alpha = this.selected ? 1 : 0.6; + favIconBlurred.alpha = this.selected ? 1 : 0; ranking.color = this.selected ? 0xFFFFFFFF : 0xFFAAAAAA; if (songText.tooLong) songText.resetText(); From 03bccee0542c363548b9cad25e1cbfd84e6fb0a3 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 4 Jun 2024 23:39:49 -0400 Subject: [PATCH 137/266] assets submod --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 613365d989..efb7a833a7 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 613365d98921346f0502a62d0a5f68fce6d27373 +Subproject commit efb7a833a78ab9c3bd9fe36bb10a8adc6a87e30b From 5dda95c69baffddfae35f7e5fdf1fdb84661a80f Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 5 Jun 2024 00:40:14 -0400 Subject: [PATCH 138/266] Fix some display issues with the clear percent in the results screen. --- source/funkin/InitState.hx | 2 +- .../play/components/ClearPercentCounter.hx | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/source/funkin/InitState.hx b/source/funkin/InitState.hx index c7a08d714d..49b15ddf60 100644 --- a/source/funkin/InitState.hx +++ b/source/funkin/InitState.hx @@ -229,7 +229,7 @@ class InitState extends FlxState tallies: { sick: 130, - good: 70, + good: 60, bad: 69, shit: 69, missed: 69, diff --git a/source/funkin/play/components/ClearPercentCounter.hx b/source/funkin/play/components/ClearPercentCounter.hx index d296b0b0b1..6af40019b1 100644 --- a/source/funkin/play/components/ClearPercentCounter.hx +++ b/source/funkin/play/components/ClearPercentCounter.hx @@ -35,7 +35,7 @@ class ClearPercentCounter extends FlxTypedSpriteGroup super(x, y); flashShader = new PureColor(FlxColor.WHITE); - flashShader.colorSet = true; + flashShader.colorSet = false; curNumber = startingNumber; @@ -54,10 +54,7 @@ class ClearPercentCounter extends FlxTypedSpriteGroup */ public function flash(enabled:Bool):Void { - for (member in members) - { - member.shader = enabled ? flashShader : null; - } + flashShader.colorSet = enabled; } var tmr:Float = 0; @@ -98,6 +95,7 @@ class ClearPercentCounter extends FlxTypedSpriteGroup var yPos = (digitIndex - 1 + digitOffset) * (digitHeightOffset * this.scale.y); yPos += small ? 0 : 72; + trace('[COUNTER] Drawing digit ${num}'); if (digitIndex >= members.length) { // Three digits = LLR because the 1 and 0 won't be the same anyway. @@ -105,6 +103,8 @@ class ClearPercentCounter extends FlxTypedSpriteGroup // var variant:Bool = (seperatedScore.length % 2 != 0) ? (digitIndex % 2 == 0) : (digitIndex % 2 == 1); var numb:ClearPercentNumber = new ClearPercentNumber(xPos, yPos, num, variant, this.small); numb.scale.set(this.scale.x, this.scale.y); + numb.shader = flashShader; + numb.visible = true; add(numb); } else @@ -113,8 +113,15 @@ class ClearPercentCounter extends FlxTypedSpriteGroup // Reset the position of the number members[digitIndex].x = xPos + this.x; members[digitIndex].y = yPos + this.y; + members[digitIndex].visible = true; } } + trace('[COUNTER] Members: ${members.length}, expected members: ${seperatedScore.length + 1}'); + for (ind in (seperatedScore.length + 1)...(members.length)) + { + trace('Hiding digit ${ind}'); + members[ind].visible = false; + } } } From 640c1cf236f2578795c1385ac2ffad72a4095228 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 5 Jun 2024 00:49:59 -0400 Subject: [PATCH 139/266] Dave say 1 minute to make Dad sneak up and 2 minutes to play the cartoons --- source/funkin/ui/freeplay/DJBoyfriend.hx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/funkin/ui/freeplay/DJBoyfriend.hx b/source/funkin/ui/freeplay/DJBoyfriend.hx index 248526aaf6..bd2f73e422 100644 --- a/source/funkin/ui/freeplay/DJBoyfriend.hx +++ b/source/funkin/ui/freeplay/DJBoyfriend.hx @@ -27,8 +27,8 @@ class DJBoyfriend extends FlxAtlasSprite var gotSpooked:Bool = false; - static final SPOOK_PERIOD:Float = 120.0; - static final TV_PERIOD:Float = 180.0; + static final SPOOK_PERIOD:Float = 60.0; + static final TV_PERIOD:Float = 120.0; // Time since dad last SPOOKED you. var timeSinceSpook:Float = 0; From 9f3d80d1dbbefba5adc91aab84a0a25c91cb0394 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 5 Jun 2024 01:16:30 -0400 Subject: [PATCH 140/266] Cory made some chart tweaks. Plus some authorship changes. --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index efb7a833a7..6af0940504 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit efb7a833a78ab9c3bd9fe36bb10a8adc6a87e30b +Subproject commit 6af0940504514701e3625b65d8332c27198e9198 From 3534ba6224d8dd950c9f599cedd15e597cc469ab Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 5 Jun 2024 13:50:57 -0400 Subject: [PATCH 141/266] roses fix --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 6af0940504..faef517a06 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 6af0940504514701e3625b65d8332c27198e9198 +Subproject commit faef517a068bb6821d828462504d7baebc91306f From fa1fafba68be5b8abf0e7ad266b333a3d47c1875 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 5 Jun 2024 14:13:06 -0400 Subject: [PATCH 142/266] less effin traces --- source/funkin/play/components/ClearPercentCounter.hx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/source/funkin/play/components/ClearPercentCounter.hx b/source/funkin/play/components/ClearPercentCounter.hx index 6af40019b1..e3d3795d97 100644 --- a/source/funkin/play/components/ClearPercentCounter.hx +++ b/source/funkin/play/components/ClearPercentCounter.hx @@ -59,14 +59,14 @@ class ClearPercentCounter extends FlxTypedSpriteGroup var tmr:Float = 0; - override function update(elapsed:Float) + override function update(elapsed:Float):Void { super.update(elapsed); if (numberChanged) drawNumbers(); } - function drawNumbers() + function drawNumbers():Void { var seperatedScore:Array = []; var tempCombo:Int = Math.round(curNumber); @@ -83,7 +83,7 @@ class ClearPercentCounter extends FlxTypedSpriteGroup for (ind => num in seperatedScore) { - var digitIndex = ind + 1; + var digitIndex:Int = ind + 1; // If there's only one digit, move it to the right // If there's three digits, move them all to the left var digitOffset = (seperatedScore.length == 1) ? 1 : (seperatedScore.length == 3) ? -1 : 0; @@ -95,7 +95,6 @@ class ClearPercentCounter extends FlxTypedSpriteGroup var yPos = (digitIndex - 1 + digitOffset) * (digitHeightOffset * this.scale.y); yPos += small ? 0 : 72; - trace('[COUNTER] Drawing digit ${num}'); if (digitIndex >= members.length) { // Three digits = LLR because the 1 and 0 won't be the same anyway. @@ -116,10 +115,8 @@ class ClearPercentCounter extends FlxTypedSpriteGroup members[digitIndex].visible = true; } } - trace('[COUNTER] Members: ${members.length}, expected members: ${seperatedScore.length + 1}'); for (ind in (seperatedScore.length + 1)...(members.length)) { - trace('Hiding digit ${ind}'); members[ind].visible = false; } } From 6e761ba156de336af2b567e14dfbfdc36c796129 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 5 Jun 2024 14:47:29 -0400 Subject: [PATCH 143/266] hardcode the songname position --- source/funkin/play/ResultState.hx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/funkin/play/ResultState.hx b/source/funkin/play/ResultState.hx index 6f540687f3..48fb3b04e9 100644 --- a/source/funkin/play/ResultState.hx +++ b/source/funkin/play/ResultState.hx @@ -691,13 +691,13 @@ class ResultState extends MusicBeatSubState { clearPercentSmall.x = (difficulty.x + difficulty.width) + 60; clearPercentSmall.y = -clearPercentSmall.height; - FlxTween.tween(clearPercentSmall, {y: 122 - 5}, 0.5, {ease: FlxEase.expoOut, startDelay: 0.8}); + FlxTween.tween(clearPercentSmall, {y: 122 - 5}, 0.5, {ease: FlxEase.expoOut, startDelay: 0.85}); } songName.y = -songName.height; var fuckedupnumber = (10) * (songName.text.length / 15); FlxTween.tween(songName, {y: diffYTween - 25 - fuckedupnumber}, 0.5, {ease: FlxEase.expoOut, startDelay: 0.9}); - songName.x = clearPercentSmall.x + clearPercentSmall.width - 30; + songName.x = clearPercentSmall.x + 94; new FlxTimer().start(timerLength, _ -> { var tempSpeed = FlxPoint.get(speedOfTween.x, speedOfTween.y); From 5bcc0f9b25c8dc4d8942fa87fb085430efc99575 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 5 Jun 2024 15:02:29 -0400 Subject: [PATCH 144/266] partial sound loading should be more resiliant --- source/funkin/audio/FunkinSound.hx | 20 ++++++++++++++------ source/funkin/ui/freeplay/FreeplayState.hx | 2 ++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/source/funkin/audio/FunkinSound.hx b/source/funkin/audio/FunkinSound.hx index 4cd0e7557d..4f61e70c27 100644 --- a/source/funkin/audio/FunkinSound.hx +++ b/source/funkin/audio/FunkinSound.hx @@ -357,6 +357,11 @@ class FunkinSound extends FlxSound implements ICloneable var shouldLoadPartial = params.partialParams?.loadPartial ?? false; + // even if we arent' trying to partial load a song, we want to error out any songs in progress, + // so we don't get overlapping music if someone were to load a new song while a partial one is loading! + + emptyPartialQueue(); + if (shouldLoadPartial) { var music = FunkinSound.loadPartial(pathToUse, params.partialParams?.start ?? 0.0, params.partialParams?.end ?? 1.0, params?.startingVolume ?? 1.0, @@ -364,12 +369,6 @@ class FunkinSound extends FlxSound implements ICloneable if (music != null) { - while (partialQueue.length > 0) - { - @:nullSafety(Off) - partialQueue.pop().error("Cancel loading partial sound"); - } - partialQueue.push(music); @:nullSafety(Off) @@ -406,6 +405,15 @@ class FunkinSound extends FlxSound implements ICloneable } } + public static function emptyPartialQueue():Void + { + while (partialQueue.length > 0) + { + @:nullSafety(Off) + partialQueue.pop().error("Cancel loading partial sound"); + } + } + static var partialQueue:Array>> = []; /** diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 4fc94c2d79..2ecbb5739c 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -1769,6 +1769,8 @@ class FreeplayState extends MusicBeatSubState funnyScroll3.visible = false; new FlxTimer().start(1, function(tmr:FlxTimer) { + FunkinSound.emptyPartialQueue(); + Paths.setCurrentLevel(cap.songData.levelId); LoadingState.loadPlayState( { From c1bfc67f52d527bdeffa2a57c06a6dccbf105b0c Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 5 Jun 2024 15:43:25 -0400 Subject: [PATCH 145/266] remove effin trace --- source/funkin/ui/freeplay/SongMenuItem.hx | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/funkin/ui/freeplay/SongMenuItem.hx b/source/funkin/ui/freeplay/SongMenuItem.hx index fb91fbd1c5..a0fa0ae42c 100644 --- a/source/funkin/ui/freeplay/SongMenuItem.hx +++ b/source/funkin/ui/freeplay/SongMenuItem.hx @@ -708,8 +708,6 @@ class FreeplayRank extends FlxSprite animation.play(val.getFreeplayRankIconAsset(), true, false); - trace(val.getFreeplayRankIconAsset()); - centerOffsets(false); switch (val) From eaa63196b3fda9243784c3706610361da861e45e Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 5 Jun 2024 17:10:53 -0400 Subject: [PATCH 146/266] fix for dadbattle appearing on freeplay --- source/funkin/play/song/Song.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/play/song/Song.hx b/source/funkin/play/song/Song.hx index fd006c0f3a..d85703721b 100644 --- a/source/funkin/play/song/Song.hx +++ b/source/funkin/play/song/Song.hx @@ -378,7 +378,7 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry):Null { - if (diffId == null) diffId = listDifficulties(variation)[0]; + if (diffId == null) diffId = listDifficulties(variation, variations)[0]; if (variation == null) variation = Constants.DEFAULT_VARIATION; if (variations == null) variations = [variation]; From 8616722e6023729f354da0949d93a204ddd36dba Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 5 Jun 2024 17:14:04 -0400 Subject: [PATCH 147/266] asset submod --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index faef517a06..56fe3a3662 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit faef517a068bb6821d828462504d7baebc91306f +Subproject commit 56fe3a3662bf5588b4f6cfec492efe5d4cfd600c From 4311dd20744fac60909f8ecf923ef3533654505b Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 5 Jun 2024 17:58:22 -0400 Subject: [PATCH 148/266] hopefully dadbattle fix lol --- source/funkin/ui/freeplay/FreeplayState.hx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 2ecbb5739c..035ad26125 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -2024,7 +2024,7 @@ class FreeplaySongData function set_currentDifficulty(value:String):String { - if (currentDifficulty == value) return value; + // if (currentDifficulty == value) return value; currentDifficulty = value; updateValues(displayedVariations); @@ -2064,7 +2064,7 @@ class FreeplaySongData function updateValues(variations:Array):Void { - this.songDifficulties = song.listDifficulties(variations, false, false); + this.songDifficulties = song.listDifficulties(null, variations, false, false); if (!this.songDifficulties.contains(currentDifficulty)) currentDifficulty = Constants.DEFAULT_DIFFICULTY; var songDifficulty:SongDifficulty = song.getDifficulty(currentDifficulty, variations); From bc783a278a0ebd7e69ba9f81698346198bfb98d8 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 5 Jun 2024 18:21:57 -0400 Subject: [PATCH 149/266] rank clipping fix --- source/funkin/ui/freeplay/FreeplayState.hx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 035ad26125..a9721bd7cf 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -1640,6 +1640,7 @@ class FreeplayState extends MusicBeatSubState { songCapsule.songData.currentDifficulty = currentDifficulty; songCapsule.init(null, null, songCapsule.songData); + songCapsule.checkClip(); } else { @@ -2024,8 +2025,6 @@ class FreeplaySongData function set_currentDifficulty(value:String):String { - // if (currentDifficulty == value) return value; - currentDifficulty = value; updateValues(displayedVariations); return value; From 6d133f007d9aa09bd46ee7212298bcd702028537 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 5 Jun 2024 19:25:53 -0400 Subject: [PATCH 150/266] Fix a bug where the event data toolbox wouldn't rebuild, and it would crash. --- source/funkin/audio/FunkinSound.hx | 6 +- .../ui/debug/charting/ChartEditorState.hx | 2 +- .../toolboxes/ChartEditorEventDataToolbox.hx | 58 +++++++++++++------ .../charting/util/ChartEditorDropdowns.hx | 38 ++++++++++++ 4 files changed, 83 insertions(+), 21 deletions(-) diff --git a/source/funkin/audio/FunkinSound.hx b/source/funkin/audio/FunkinSound.hx index 4cd0e7557d..58b9100512 100644 --- a/source/funkin/audio/FunkinSound.hx +++ b/source/funkin/audio/FunkinSound.hx @@ -227,12 +227,12 @@ class FunkinSound extends FlxSound implements ICloneable // already paused before we lost focus. if (_lostFocus && !_alreadyPaused) { - trace('Resuming audio (${this._label}) on focus!'); + // trace('Resuming audio (${this._label}) on focus!'); resume(); } else { - trace('Not resuming audio (${this._label}) on focus!'); + // trace('Not resuming audio (${this._label}) on focus!'); } _lostFocus = false; } @@ -242,7 +242,7 @@ class FunkinSound extends FlxSound implements ICloneable */ override function onFocusLost():Void { - trace('Focus lost, pausing audio!'); + // trace('Focus lost, pausing audio!'); _lostFocus = true; _alreadyPaused = _paused; pause(); diff --git a/source/funkin/ui/debug/charting/ChartEditorState.hx b/source/funkin/ui/debug/charting/ChartEditorState.hx index 260393fac4..08edb45aba 100644 --- a/source/funkin/ui/debug/charting/ChartEditorState.hx +++ b/source/funkin/ui/debug/charting/ChartEditorState.hx @@ -904,7 +904,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState function set_notePreviewDirty(value:Bool):Bool { - trace('Note preview dirtied!'); + // trace('Note preview dirtied!'); return notePreviewDirty = value; } diff --git a/source/funkin/ui/debug/charting/toolboxes/ChartEditorEventDataToolbox.hx b/source/funkin/ui/debug/charting/toolboxes/ChartEditorEventDataToolbox.hx index f0949846d1..cee25963e0 100644 --- a/source/funkin/ui/debug/charting/toolboxes/ChartEditorEventDataToolbox.hx +++ b/source/funkin/ui/debug/charting/toolboxes/ChartEditorEventDataToolbox.hx @@ -58,17 +58,8 @@ class ChartEditorEventDataToolbox extends ChartEditorBaseToolbox function initialize():Void { - toolboxEventsEventKind.dataSource = new ArrayDataSource(); - - var songEvents:Array = SongEventRegistry.listEvents(); - - for (event in songEvents) - { - toolboxEventsEventKind.dataSource.add({text: event.getTitle(), value: event.id}); - } - toolboxEventsEventKind.onChange = function(event:UIEvent) { - var eventType:String = event.data.value; + var eventType:String = event.data.id; trace('ChartEditorToolboxHandler.buildToolboxEventDataLayout() - Event type changed: $eventType'); @@ -83,7 +74,7 @@ class ChartEditorEventDataToolbox extends ChartEditorBaseToolbox return; } - buildEventDataFormFromSchema(toolboxEventsDataGrid, schema); + buildEventDataFormFromSchema(toolboxEventsDataGrid, schema, chartEditorState.eventKindToPlace); if (!_initializing && chartEditorState.currentEventSelection.length > 0) { @@ -98,14 +89,38 @@ class ChartEditorEventDataToolbox extends ChartEditorBaseToolbox chartEditorState.notePreviewDirty = true; } } - toolboxEventsEventKind.value = chartEditorState.eventKindToPlace; + var startingEventValue = ChartEditorDropdowns.populateDropdownWithSongEvents(toolboxEventsEventKind, chartEditorState.eventKindToPlace); + toolboxEventsEventKind.value = startingEventValue; } public override function refresh():Void { super.refresh(); - toolboxEventsEventKind.value = chartEditorState.eventKindToPlace; + var newDropdownElement = ChartEditorDropdowns.findDropdownElement(chartEditorState.eventKindToPlace, toolboxEventsEventKind); + + if (newDropdownElement == null) + { + throw 'ChartEditorToolboxHandler.buildToolboxEventDataLayout() - Event kind not in dropdown: ${chartEditorState.eventKindToPlace}'; + } + else if (toolboxEventsEventKind.value != newDropdownElement) + { + toolboxEventsEventKind.value = newDropdownElement; + + var schema:SongEventSchema = SongEventRegistry.getEventSchema(chartEditorState.eventKindToPlace); + if (schema == null) + { + trace('ChartEditorToolboxHandler.buildToolboxEventDataLayout() - Unknown event kind: ${chartEditorState.eventKindToPlace}'); + } + else + { + buildEventDataFormFromSchema(toolboxEventsDataGrid, schema, chartEditorState.eventKindToPlace); + } + } + else + { + trace('ChartEditorToolboxHandler.buildToolboxEventDataLayout() - Event kind not changed: ${toolboxEventsEventKind.value} == ${newDropdownElement}'); + } for (pair in chartEditorState.eventDataToPlace.keyValueIterator()) { @@ -116,7 +131,7 @@ class ChartEditorEventDataToolbox extends ChartEditorBaseToolbox if (field == null) { - throw 'ChartEditorToolboxHandler.refresh() - Field "${fieldId}" does not exist in the event data form.'; + throw 'ChartEditorToolboxHandler.refresh() - Field "${fieldId}" does not exist in the event data form for kind ${lastEventKind}.'; } else { @@ -141,9 +156,15 @@ class ChartEditorEventDataToolbox extends ChartEditorBaseToolbox } } - function buildEventDataFormFromSchema(target:Box, schema:SongEventSchema):Void + var lastEventKind:String = 'unknown'; + + function buildEventDataFormFromSchema(target:Box, schema:SongEventSchema, eventKind:String):Void { - trace(schema); + trace('Building event data form from schema for event kind: ${eventKind}'); + // trace(schema); + + lastEventKind = eventKind ?? 'unknown'; + // Clear the frame. target.removeAllComponents(); @@ -197,12 +218,15 @@ class ChartEditorEventDataToolbox extends ChartEditorBaseToolbox for (optionName in field.keys.keys()) { var optionValue:Null = field.keys.get(optionName); - trace('$optionName : $optionValue'); + // trace('$optionName : $optionValue'); dropDown.dataSource.add({value: optionValue, text: optionName}); } dropDown.value = field.defaultValue; + // TODO: Add an option to customize sort. + dropDown.dataSource.sort('text', ASCENDING); + input = dropDown; case STRING: input = new TextField(); diff --git a/source/funkin/ui/debug/charting/util/ChartEditorDropdowns.hx b/source/funkin/ui/debug/charting/util/ChartEditorDropdowns.hx index d2a0a053e5..55aab0ab00 100644 --- a/source/funkin/ui/debug/charting/util/ChartEditorDropdowns.hx +++ b/source/funkin/ui/debug/charting/util/ChartEditorDropdowns.hx @@ -3,11 +3,13 @@ package funkin.ui.debug.charting.util; import funkin.data.notestyle.NoteStyleRegistry; import funkin.play.notes.notestyle.NoteStyle; import funkin.data.stage.StageData; +import funkin.play.event.SongEvent; import funkin.data.stage.StageRegistry; import funkin.play.character.CharacterData; import haxe.ui.components.DropDown; import funkin.play.stage.Stage; import funkin.play.character.BaseCharacter.CharacterType; +import funkin.data.event.SongEventRegistry; import funkin.play.character.CharacterData.CharacterDataParser; /** @@ -81,6 +83,42 @@ class ChartEditorDropdowns return returnValue; } + public static function populateDropdownWithSongEvents(dropDown:DropDown, startingEventId:String):DropDownEntry + { + dropDown.dataSource.clear(); + + var returnValue:DropDownEntry = {id: "FocusCamera", text: "Focus Camera"}; + + var songEvents:Array = SongEventRegistry.listEvents(); + + for (event in songEvents) + { + var value = {id: event.id, text: event.getTitle()}; + if (startingEventId == event.id) returnValue = value; + dropDown.dataSource.add(value); + } + + dropDown.dataSource.sort('text', ASCENDING); + + return returnValue; + } + + /** + * Given the ID of a dropdown element, find the corresponding entry in the dropdown's dataSource. + */ + public static function findDropdownElement(id:String, dropDown:DropDown):Null + { + // Attempt to find the entry. + for (entryIndex in 0...dropDown.dataSource.size) + { + var entry = dropDown.dataSource.get(entryIndex); + if (entry.id == id) return entry; + } + + // Not found. + return null; + } + /** * Populate a dropdown with a list of note styles. */ From 6fb19dc4d363f3eef7c534216e1435f38bbfbd01 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 5 Jun 2024 20:09:26 -0400 Subject: [PATCH 151/266] Update chart editor dropdowns to be searchable --- CHANGELOG.md | 2 ++ assets | 2 +- .../ui/debug/charting/toolboxes/ChartEditorEventDataToolbox.hx | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 898978ca38..6bf59061d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,9 +28,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 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. +- Improved the Event Toolbox in the Chart Editor; dropdowns are now bigger, include search field, and display elements in alphabetical order rather than a random order. ### 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 +- Fixed a bug where the Chart Editor would crash when attempting to select an event with the Event toolbox open - 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!) diff --git a/assets b/assets index faef517a06..ecedb373ce 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit faef517a068bb6821d828462504d7baebc91306f +Subproject commit ecedb373ce7a4a6bac0026253813da7363743ca0 diff --git a/source/funkin/ui/debug/charting/toolboxes/ChartEditorEventDataToolbox.hx b/source/funkin/ui/debug/charting/toolboxes/ChartEditorEventDataToolbox.hx index cee25963e0..4e4d5a0776 100644 --- a/source/funkin/ui/debug/charting/toolboxes/ChartEditorEventDataToolbox.hx +++ b/source/funkin/ui/debug/charting/toolboxes/ChartEditorEventDataToolbox.hx @@ -209,6 +209,9 @@ class ChartEditorEventDataToolbox extends ChartEditorBaseToolbox var dropDown:DropDown = new DropDown(); dropDown.id = field.name; dropDown.width = 200.0; + dropDown.dropdownSize = 10; + dropDown.dropdownWidth = 300; + dropDown.searchable = true; dropDown.dataSource = new ArrayDataSource(); if (field.keys == null) throw 'Field "${field.name}" is of Enum type but has no keys.'; From e27e96a1cb3ce63a3fc75054b67757e6ba6c20c1 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 5 Jun 2024 20:19:00 -0400 Subject: [PATCH 152/266] Update assets submodule --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 56fe3a3662..68f223f965 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 56fe3a3662bf5588b4f6cfec492efe5d4cfd600c +Subproject commit 68f223f965c60a3874d7842ee2d448eee5afc87b From 642f272bce4a4399936fe1114e0db6795c0c19dd Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Thu, 6 Jun 2024 01:49:33 +0100 Subject: [PATCH 153/266] freeplay polish + new text --- source/funkin/play/song/Song.hx | 6 ++ source/funkin/ui/freeplay/FreeplayState.hx | 78 +++++++++++++--------- source/funkin/ui/freeplay/SongMenuItem.hx | 37 +++++++++- 3 files changed, 87 insertions(+), 34 deletions(-) diff --git a/source/funkin/play/song/Song.hx b/source/funkin/play/song/Song.hx index d85703721b..df3e343e2b 100644 --- a/source/funkin/play/song/Song.hx +++ b/source/funkin/play/song/Song.hx @@ -91,6 +91,12 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry):Void { busy = true; + grpCapsules.members[curSelected].sparkle.alpha = 0; // grpCapsules.members[curSelected].forcePosition(); if (fromResults != null) @@ -1088,6 +1089,8 @@ class FreeplayState extends MusicBeatSubState // NOW we can interact with the menu busy = false; + grpCapsules.members[curSelected].sparkle.alpha = 0.7; + playCurSongPreview(capsule); }, null); // FlxTween.tween(capsule, {"targetPos.x": capsule.targetPos.x - 50}, 0.6, @@ -1814,7 +1817,7 @@ class FreeplayState extends MusicBeatSubState function changeSelection(change:Int = 0):Void { - FunkinSound.playOnce(Paths.sound('scrollMenu'), 0.4); + if (!prepForNewRank) FunkinSound.playOnce(Paths.sound('scrollMenu'), 0.4); var prevSelected:Int = curSelected; @@ -1855,43 +1858,48 @@ class FreeplayState extends MusicBeatSubState if (index < curSelected) capsule.targetPos.y -= 100; // another 100 for good measure } - if (grpCapsules.countLiving() > 0) + if (grpCapsules.countLiving() > 0 && !prepForNewRank) { - if (curSelected == 0) - { - FunkinSound.playMusic('freeplayRandom', - { - startingVolume: 0.0, - overrideExisting: true, - restartTrack: false - }); - FlxG.sound.music.fadeIn(2, 0, 0.8); - } - else - { - var potentiallyErect:String = (currentDifficulty == "erect") || (currentDifficulty == "nightmare") ? "-erect" : ""; - FunkinSound.playMusic(daSongCapsule.songData.songId, - { - startingVolume: 0.0, - overrideExisting: true, - restartTrack: false, - pathsFunction: INST, - suffix: potentiallyErect, - partialParams: - { - loadPartial: true, - start: 0.05, - end: 0.25 - }, - onLoad: function() { - FlxG.sound.music.fadeIn(2, 0, 0.4); - } - }); - } + playCurSongPreview(daSongCapsule); grpCapsules.members[curSelected].selected = true; } } + public function playCurSongPreview(daSongCapsule:SongMenuItem):Void + { + if (curSelected == 0) + { + FunkinSound.playMusic('freeplayRandom', + { + startingVolume: 0.0, + overrideExisting: true, + restartTrack: false + }); + FlxG.sound.music.fadeIn(2, 0, 0.8); + } + else + { + var potentiallyErect:String = (currentDifficulty == "erect") || (currentDifficulty == "nightmare") ? "-erect" : ""; + FunkinSound.playMusic(daSongCapsule.songData.songId, + { + startingVolume: 0.0, + overrideExisting: true, + restartTrack: false, + pathsFunction: INST, + suffix: potentiallyErect, + partialParams: + { + loadPartial: true, + start: 0.05, + end: 0.25 + }, + onLoad: function() { + FlxG.sound.music.fadeIn(2, 0, 0.4); + } + }); + } + } + /** * Build an instance of `FreeplayState` that is above the `MainMenuState`. * @return The MainMenuState with the FreeplayState as a substate. @@ -2004,6 +2012,8 @@ class FreeplaySongData */ public var isFav:Bool = false; + public var isNew:Bool = false; + var song:Song; public var levelId(default, null):String = ''; @@ -2083,6 +2093,8 @@ class FreeplaySongData } this.scoringRank = Save.instance.getSongRank(songId, currentDifficulty); + + this.isNew = song.isSongNew(currentDifficulty); } } diff --git a/source/funkin/ui/freeplay/SongMenuItem.hx b/source/funkin/ui/freeplay/SongMenuItem.hx index a0fa0ae42c..dc30b4345f 100644 --- a/source/funkin/ui/freeplay/SongMenuItem.hx +++ b/source/funkin/ui/freeplay/SongMenuItem.hx @@ -21,6 +21,8 @@ import flixel.tweens.FlxEase; import flixel.tweens.FlxTween; import flixel.addons.effects.FlxTrail; import funkin.play.scoring.Scoring.ScoringRank; +import funkin.save.Save; +import funkin.save.Save.SaveScoreData; import flixel.util.FlxColor; class SongMenuItem extends FlxSpriteGroup @@ -76,6 +78,10 @@ class SongMenuItem extends FlxSpriteGroup var impactThing:FunkinSprite; + public var sparkle:FlxSprite; + + var sparkleTimer:FlxTimer; + public function new(x:Float, y:Float) { super(x, y); @@ -110,7 +116,7 @@ class SongMenuItem extends FlxSpriteGroup newText.animation.play('newAnim', true); newText.setGraphicSize(Std.int(newText.width * 0.9)); - newText.visible = false; + // newText.visible = false; add(newText); @@ -153,6 +159,18 @@ class SongMenuItem extends FlxSpriteGroup blurredRanking.shader = new GaussianBlurShader(1); add(blurredRanking); + sparkle = new FlxSprite(ranking.x, ranking.y); + sparkle.frames = Paths.getSparrowAtlas('freeplay/sparkle'); + sparkle.animation.addByPrefix('sparkle', 'sparkle', 24, false); + sparkle.animation.play('sparkle', true); + sparkle.scale.set(0.8, 0.8); + sparkle.blend = BlendMode.ADD; + + sparkle.visible = false; + sparkle.alpha = 0.7; + + add(sparkle); + // ranking.loadGraphic(Paths.image('freeplay/ranks/' + rank)); // ranking.scale.x = ranking.scale.y = realScaled; // ranking.alpha = 0.75; @@ -218,6 +236,13 @@ class SongMenuItem extends FlxSpriteGroup setVisibleGrp(false); } + function sparkleEffect(timer:FlxTimer):Void + { + sparkle.setPosition(FlxG.random.float(ranking.x - 20, ranking.x + 3), FlxG.random.float(ranking.y - 29, ranking.y + 4)); + sparkle.animation.play('sparkle', true); + sparkleTimer = new FlxTimer().start(FlxG.random.float(1.2, 4.5), sparkleEffect); + } + // no way to grab weeks rn, so this needs to be done :/ // negative values mean weekends function checkWeek(name:String):Void @@ -415,8 +440,17 @@ class SongMenuItem extends FlxSpriteGroup function updateScoringRank(newRank:Null):Void { + if (sparkleTimer != null) sparkleTimer.cancel(); + sparkle.visible = false; + this.ranking.rank = newRank; this.blurredRanking.rank = newRank; + + if (newRank == PERFECT_GOLD) + { + sparkleTimer = new FlxTimer().start(1, sparkleEffect); + sparkle.visible = true; + } } function set_hsvShader(value:HSVShader):HSVShader @@ -468,6 +502,7 @@ class SongMenuItem extends FlxSpriteGroup updateBPM(Std.int(songData?.songStartingBpm) ?? 0); updateDifficultyRating(songData?.difficultyRating ?? 0); updateScoringRank(songData?.scoringRank); + newText.visible = songData?.isNew; // Update opacity, offsets, etc. updateSelected(); From b7eed4c4d3a1c1b4331e254f7eea75ff334fc3f4 Mon Sep 17 00:00:00 2001 From: FabsTheFabs Date: Thu, 6 Jun 2024 01:50:19 +0100 Subject: [PATCH 154/266] assets submoddd!!!!! --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 56fe3a3662..36e3954675 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 56fe3a3662bf5588b4f6cfec492efe5d4cfd600c +Subproject commit 36e3954675428214ae6d3ce5123ad3bc9882ea8b From 2596e6369ecbe27de8db7b86f6b3dbd05319e5fc Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Thu, 6 Jun 2024 14:00:22 -0400 Subject: [PATCH 155/266] More chart changes by SpazKid + changelog update --- CHANGELOG.md | 10 +++++++--- assets | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 898978ca38..42f1fee00d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,13 +15,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added a new Scroll Speed chart event to change the note speed mid-song (thanks ) ### Changed - Tweaked the charts for several songs: + - Tutorial (increased the note speed slightly) + - Spookeez - Monster - Winter Horrorland - - Stress - - Lit Up - - Tutorial (increased the note speed slightly) + - M.I.L.F. - Senpai (increased the note speed) + - Roses - Thorns (increased the note speed slightly) + - Ugh + - Stress + - Lit Up - Favorite songs marked in Freeplay are now stored between sessions. - In the event that the game cannot load your save data, it will now perform a backup before clearing it, so that we can try to repair it in the future. - 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!) diff --git a/assets b/assets index 56fe3a3662..6e124504f7 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 56fe3a3662bf5588b4f6cfec492efe5d4cfd600c +Subproject commit 6e124504f777048d357c4b94737dda1b569b4d03 From a81b6b2d6e979b3ab5c680f33b846277f3557ab7 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Thu, 6 Jun 2024 16:44:20 -0400 Subject: [PATCH 156/266] Fix issue with rendering the grid in 3/4 time signature --- source/funkin/play/GameOverSubState.hx | 2 +- source/funkin/play/components/HealthIcon.hx | 3 ++- .../ui/debug/charting/handlers/ChartEditorThemeHandler.hx | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/source/funkin/play/GameOverSubState.hx b/source/funkin/play/GameOverSubState.hx index 4d50d75cc4..ac45dc194b 100644 --- a/source/funkin/play/GameOverSubState.hx +++ b/source/funkin/play/GameOverSubState.hx @@ -237,7 +237,7 @@ class GameOverSubState extends MusicBeatSubState } // KEYBOARD ONLY: Restart the level when pressing the assigned key. - if (controls.ACCEPT && blueballed) + if (controls.ACCEPT && blueballed && !mustNotExit) { blueballed = false; confirmDeath(); diff --git a/source/funkin/play/components/HealthIcon.hx b/source/funkin/play/components/HealthIcon.hx index a3204329a7..2442b0dc57 100644 --- a/source/funkin/play/components/HealthIcon.hx +++ b/source/funkin/play/components/HealthIcon.hx @@ -53,8 +53,9 @@ class HealthIcon extends FunkinSprite /** * Apply the "bop" animation once every X steps. + * Defaults to once per beat. */ - public var bopEvery:Int = 4; + public var bopEvery:Int = Constants.STEPS_PER_BEAT; /** * The amount, in degrees, to rotate the icon by when boping. diff --git a/source/funkin/ui/debug/charting/handlers/ChartEditorThemeHandler.hx b/source/funkin/ui/debug/charting/handlers/ChartEditorThemeHandler.hx index b1af0ce4cb..e42102a529 100644 --- a/source/funkin/ui/debug/charting/handlers/ChartEditorThemeHandler.hx +++ b/source/funkin/ui/debug/charting/handlers/ChartEditorThemeHandler.hx @@ -201,7 +201,8 @@ class ChartEditorThemeHandler // Selection borders horizontally in the middle. for (i in 1...(Conductor.instance.stepsPerMeasure)) { - if ((i % Conductor.instance.beatsPerMeasure) == 0) + // There may be a different number of beats per measure, but there's always 4 steps per beat. + if ((i % Constants.STEPS_PER_BEAT) == 0) { state.gridBitmap.fillRect(new Rectangle(0, (ChartEditorState.GRID_SIZE * i) - (GRID_BEAT_DIVIDER_WIDTH / 2), state.gridBitmap.width, GRID_BEAT_DIVIDER_WIDTH), From 70f027cc3fb7310403f388b8927cd2ea41f50177 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Thu, 6 Jun 2024 16:44:47 -0400 Subject: [PATCH 157/266] Fix another crash with the chart editor event toolbox --- .../debug/charting/commands/SetItemSelectionCommand.hx | 10 +++++++++- .../charting/toolboxes/ChartEditorEventDataToolbox.hx | 6 ++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/source/funkin/ui/debug/charting/commands/SetItemSelectionCommand.hx b/source/funkin/ui/debug/charting/commands/SetItemSelectionCommand.hx index 73cf80fa0e..661c44d85a 100644 --- a/source/funkin/ui/debug/charting/commands/SetItemSelectionCommand.hx +++ b/source/funkin/ui/debug/charting/commands/SetItemSelectionCommand.hx @@ -35,7 +35,15 @@ class SetItemSelectionCommand implements ChartEditorCommand { var eventSelected = this.events[0]; - state.eventKindToPlace = eventSelected.eventKind; + if (state.eventKindToPlace == eventSelected.eventKind) + { + trace('Target event kind matches selection: ${eventSelected.eventKind}'); + } + else + { + trace('Switching target event kind to match selection: ${state.eventKindToPlace} != ${eventSelected.eventKind}'); + state.eventKindToPlace = eventSelected.eventKind; + } // This code is here to parse event data that's not built as a struct for some reason. // TODO: Clean this up or get rid of it. diff --git a/source/funkin/ui/debug/charting/toolboxes/ChartEditorEventDataToolbox.hx b/source/funkin/ui/debug/charting/toolboxes/ChartEditorEventDataToolbox.hx index 4e4d5a0776..8f021840ac 100644 --- a/source/funkin/ui/debug/charting/toolboxes/ChartEditorEventDataToolbox.hx +++ b/source/funkin/ui/debug/charting/toolboxes/ChartEditorEventDataToolbox.hx @@ -90,6 +90,7 @@ class ChartEditorEventDataToolbox extends ChartEditorBaseToolbox } } var startingEventValue = ChartEditorDropdowns.populateDropdownWithSongEvents(toolboxEventsEventKind, chartEditorState.eventKindToPlace); + trace('ChartEditorToolboxHandler.buildToolboxEventDataLayout() - Starting event kind: ${startingEventValue}'); toolboxEventsEventKind.value = startingEventValue; } @@ -103,7 +104,7 @@ class ChartEditorEventDataToolbox extends ChartEditorBaseToolbox { throw 'ChartEditorToolboxHandler.buildToolboxEventDataLayout() - Event kind not in dropdown: ${chartEditorState.eventKindToPlace}'; } - else if (toolboxEventsEventKind.value != newDropdownElement) + else if (toolboxEventsEventKind.value != newDropdownElement || lastEventKind != toolboxEventsEventKind.value.id) { toolboxEventsEventKind.value = newDropdownElement; @@ -114,12 +115,13 @@ class ChartEditorEventDataToolbox extends ChartEditorBaseToolbox } else { + trace('ChartEditorToolboxHandler.buildToolboxEventDataLayout() - Event kind changed: ${toolboxEventsEventKind.value.id} != ${newDropdownElement.id} != ${lastEventKind}, rebuilding form'); buildEventDataFormFromSchema(toolboxEventsDataGrid, schema, chartEditorState.eventKindToPlace); } } else { - trace('ChartEditorToolboxHandler.buildToolboxEventDataLayout() - Event kind not changed: ${toolboxEventsEventKind.value} == ${newDropdownElement}'); + trace('ChartEditorToolboxHandler.buildToolboxEventDataLayout() - Event kind not changed: ${toolboxEventsEventKind.value} == ${newDropdownElement} == ${lastEventKind}'); } for (pair in chartEditorState.eventDataToPlace.keyValueIterator()) From fe5f1eb6ea5b88e9186d448f814204df81845a31 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Thu, 6 Jun 2024 17:11:30 -0400 Subject: [PATCH 158/266] Fix merge conflict --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index ecedb373ce..898e94729a 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit ecedb373ce7a4a6bac0026253813da7363743ca0 +Subproject commit 898e94729aa2f0ad4179d6f66dd075070c3172dc From 700b6e11b8f06a9ad12c152e5974d5b4f016730c Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Thu, 6 Jun 2024 19:05:05 -0400 Subject: [PATCH 159/266] Update assets submodule --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 6e124504f7..862b513556 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 6e124504f777048d357c4b94737dda1b569b4d03 +Subproject commit 862b51355622c29b5b11ff8ce979afeb53df4636 From e4647e9e2d754a8128a25dcc3d75e463fa8aed4c Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Thu, 6 Jun 2024 19:46:44 -0400 Subject: [PATCH 160/266] assets submod --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 36e3954675..0062c05d55 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 36e3954675428214ae6d3ce5123ad3bc9882ea8b +Subproject commit 0062c05d559ae281ce39f8df3da6efb1f92ca808 From 0bb22b60d9b4703ddcfc2def84bf1a574f2631a4 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Thu, 6 Jun 2024 19:55:50 -0400 Subject: [PATCH 161/266] update game version --- Project.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.xml b/Project.xml index fcd29a25e4..d93cf3e425 100644 --- a/Project.xml +++ b/Project.xml @@ -2,7 +2,7 @@ - + From 266049df658061b705ee772d013080ab47940240 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Thu, 6 Jun 2024 20:10:28 -0400 Subject: [PATCH 162/266] Update assets submodule --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 898e94729a..6ea0324f79 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 898e94729aa2f0ad4179d6f66dd075070c3172dc +Subproject commit 6ea0324f79a6fdabe802c39598ba2b823ed1e593 From 4f0e77c974c7a62fb1deb6cc351668a4b01a4f92 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Thu, 6 Jun 2024 20:20:54 -0400 Subject: [PATCH 163/266] update hmm --- hmm.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hmm.json b/hmm.json index ab55e30ba6..4f3d9ac4d2 100644 --- a/hmm.json +++ b/hmm.json @@ -56,7 +56,7 @@ "name": "funkin.vis", "type": "git", "dir": null, - "ref": "c6a1e24d48646849ea63563ca45561512c953779", + "ref": "38261833590773cb1de34ac5d11e0825696fc340", "url": "https://github.com/FunkinCrew/funkVis" }, { From e01e4d1e769ac111352ff3ecdbe620e7a2908363 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Thu, 6 Jun 2024 20:21:37 -0400 Subject: [PATCH 164/266] assets submod --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 862b513556..e8fc4616c1 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 862b51355622c29b5b11ff8ce979afeb53df4636 +Subproject commit e8fc4616c167de66c4eddcfe1cbe51bae83536da From 7c638e02740a4937f2fb54b282f79ef25e2634e8 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Thu, 6 Jun 2024 20:26:25 -0400 Subject: [PATCH 165/266] Add satin panties erect difficulty chart --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 0062c05d55..e8bfc7461a 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 0062c05d559ae281ce39f8df3da6efb1f92ca808 +Subproject commit e8bfc7461a403e108a7f7b5fa4eebba38bb6a5fe From 715e834753fe18c4fa62e0aca627f80559ef8f82 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Thu, 6 Jun 2024 20:30:15 -0400 Subject: [PATCH 166/266] Update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 898978ca38..acb85df6cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,12 +25,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Favorite songs marked in Freeplay are now stored between sessions. - In the event that the game cannot load your save data, it will now perform a backup before clearing it, so that we can try to repair it in the future. - 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 +- Improved offsets for Pico and Tankman opponents so they don't slide around as much. - 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!) From c54c10f562e1931f39f0eb41d1f41c16c8505447 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Thu, 6 Jun 2024 20:46:12 -0400 Subject: [PATCH 167/266] lower fft res on desktop --- source/funkin/audio/visualize/ABotVis.hx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/funkin/audio/visualize/ABotVis.hx b/source/funkin/audio/visualize/ABotVis.hx index ed22092b6c..1b04631445 100644 --- a/source/funkin/audio/visualize/ABotVis.hx +++ b/source/funkin/audio/visualize/ABotVis.hx @@ -55,6 +55,13 @@ class ABotVis extends FlxTypedSpriteGroup { @:privateAccess analyzer = new SpectralAnalyzer(snd._channel.__source, 7, 0.1, 30); + + #if desktop + // On desktop it uses FFT stuff that isn't as optimized as the direct browser stuff we use on HTML5 + // So we want to manually change it! + analyzer.fftN = 512; + #end + // analyzer.maxDb = -35; // analyzer.fftN = 2048; } From 7214e159e0174a04b21fd4f01bceaa405e062e4f Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Thu, 6 Jun 2024 20:50:53 -0400 Subject: [PATCH 168/266] update grig --- hmm.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hmm.json b/hmm.json index 4f3d9ac4d2..68e0c5cb03 100644 --- a/hmm.json +++ b/hmm.json @@ -63,7 +63,7 @@ "name": "grig.audio", "type": "git", "dir": "src", - "ref": "cbf91e2180fd2e374924fe74844086aab7891666", + "ref": "57f5d47f2533fd0c3dcd025a86cb86c0dfa0b6d2", "url": "https://gitlab.com/haxe-grig/grig.audio.git" }, { From e2fbeeb13e37070f59627751216218f943f84a3d Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Thu, 6 Jun 2024 21:18:53 -0400 Subject: [PATCH 169/266] assets submod --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index e8bfc7461a..4427687c48 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit e8bfc7461a403e108a7f7b5fa4eebba38bb6a5fe +Subproject commit 4427687c487d643c6051f8c4610470326c87ea4d From ca345e6c4fad9cc7fd3e6d0de41e68a6cb0298b9 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Thu, 6 Jun 2024 21:38:00 -0400 Subject: [PATCH 170/266] Play song IDs based on the chart file's "instrumental" field, not the variation ID. --- source/funkin/play/PlayState.hx | 9 ++++++++- source/funkin/play/song/Song.hx | 4 ++-- source/funkin/ui/freeplay/FreeplayState.hx | 18 ++++++++++++++---- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index b02cc69f74..6bc4b2d890 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -175,6 +175,12 @@ class PlayState extends MusicBeatSubState */ public var currentVariation:String = Constants.DEFAULT_VARIATION; + /** + * The currently selected instrumental ID. + * @default `''` + */ + public var currentInstrumental:String = ''; + /** * The currently active Stage. This is the object containing all the props. */ @@ -603,6 +609,7 @@ class PlayState extends MusicBeatSubState currentSong = params.targetSong; if (params.targetDifficulty != null) currentDifficulty = params.targetDifficulty; if (params.targetVariation != null) currentVariation = params.targetVariation; + if (params.targetInstrumental != null) currentInstrumental = params.targetInstrumental; isPracticeMode = params.practiceMode ?? false; isBotPlayMode = params.botPlayMode ?? false; isMinimalMode = params.minimalMode ?? false; @@ -1968,7 +1975,7 @@ class PlayState extends MusicBeatSubState if (!overrideMusic && !isGamePaused && currentChart != null) { - currentChart.playInst(1.0, false); + currentChart.playInst(1.0, currentInstrumental, false); } if (FlxG.sound.music == null) diff --git a/source/funkin/play/song/Song.hx b/source/funkin/play/song/Song.hx index df3e343e2b..dde5ee7b8d 100644 --- a/source/funkin/play/song/Song.hx +++ b/source/funkin/play/song/Song.hx @@ -682,9 +682,9 @@ class SongDifficulty FlxG.sound.cache(getInstPath(instrumental)); } - public function playInst(volume:Float = 1.0, looped:Bool = false):Void + public function playInst(volume:Float = 1.0, instId:String = '', looped:Bool = false):Void { - var suffix:String = (variation != null && variation != '' && variation != 'default') ? '-$variation' : ''; + var suffix:String = (instId != '') ? '-$instId' : ''; FlxG.sound.music = FunkinSound.load(Paths.inst(this.song.id, suffix), volume, looped, false, true); diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 607b7a353e..c47933fd73 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -1726,11 +1726,20 @@ class FreeplayState extends MusicBeatSubState FlxG.log.warn('WARN: could not find song with id (${cap.songData.songId})'); return; } - var targetDifficulty:String = currentDifficulty; - var targetVariation:String = targetSong.getFirstValidVariation(targetDifficulty); - + var targetDifficultyId:String = currentDifficulty; + var targetVariation:String = targetSong.getFirstValidVariation(targetDifficultyId); PlayStatePlaylist.campaignId = cap.songData.levelId; + var targetDifficulty:SongDifficulty = targetSong.getDifficulty(targetDifficultyId, targetVariation); + if (targetDifficulty == null) + { + FlxG.log.warn('WARN: could not find difficulty with id (${targetDifficultyId})'); + return; + } + + // TODO: Change this with alternate instrumentals + var targetInstId:String = targetDifficulty.characters.instrumental; + // Visual and audio effects. FunkinSound.playOnce(Paths.sound('confirmMenu')); dj.confirm(); @@ -1779,8 +1788,9 @@ class FreeplayState extends MusicBeatSubState LoadingState.loadPlayState( { targetSong: targetSong, - targetDifficulty: targetDifficulty, + targetDifficulty: targetDifficultyId, targetVariation: targetVariation, + targetInstrumental: targetInstId, practiceMode: false, minimalMode: false, From 6665924dd968ff96d074843988d34c64035aa479 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Thu, 6 Jun 2024 23:28:41 -0400 Subject: [PATCH 171/266] We forgot to credit burgerballs! --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e44005ffa8..1c4969cdee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ 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.4.0] - 2024-05-?? +## [0.4.0] - 2024-06-06 ### Added - 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. @@ -12,7 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 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 ) +- Added a new Scroll Speed chart event to change the note speed mid-song (thanks burgerballs!) ### Changed - Tweaked the charts for several songs: - Tutorial (increased the note speed slightly) From 8700db198890ba5e83b0b0df22dc4b878a97dce0 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Thu, 6 Jun 2024 23:51:22 -0400 Subject: [PATCH 172/266] Make sure to credit all the community contributions properly. --- CHANGELOG.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c4969cdee..90d2a50017 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,23 +32,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 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 an issue where Nene's visualizer would not play on Desktop builds - 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 - Improved offsets for Pico and Tankman opponents so they don't slide around as much. -- 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 crash on Linux caused by an old version of hxCodec (thanks Noobz4Life!) +- Optimized animation handling for characters (thanks richTrash21!) +- Made improvements to compiling documentation (thanks gedehari!) - Fixed a bug where pressing the volume keys would stop the Toy commercial (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!) +- Fixed a bug where hold notes would be positioned wrong on downscroll (thanks MaybeMaru!) +- Additional fixes to the Loading bar on HTML5 (thanks lemz1!) +- Fixed a crash in Freeplay caused by a level referencing an invalid song (thanks gamerbross!) - 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!) +- Fixed a bug where changing difficulties in Story mode wouldn't update the score (thanks sectorA!) +- Fixed an issue where the Chart Editor would use an incorrect instrumental on imported Legacy songs (thanks gamerbross!) +- Fixed a camera bug in the Main Menu (thanks richTrash21!) +- Fixed several bugs with the TitleState, including missing music when returning from the Main Menu (thanks gamerbross!) +- Fixed a bug where opening the game from the command line would crash the preloader (thanks NotHyper474!) +- 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 characters would sometimes use the wrong scale value (thanks PurSnake!) - Additional bug fixes and optimizations. ## [0.3.3] - 2024-05-14 From 3567e4e8e441613c0ed72d2cf13567568964cb7e Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 7 Jun 2024 00:43:31 -0400 Subject: [PATCH 173/266] Writing down more changes as I remember them --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90d2a50017..35618dca9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Stress - Lit Up - Favorite songs marked in Freeplay are now stored between sessions. +- The Freeplay easter eggs are now easier to see. - In the event that the game cannot load your save data, it will now perform a backup before clearing it, so that we can try to repair it in the future. - 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!) - Health icons now support a Winning frame without requiring a spritesheet, simply include a third frame in the icon file. (thanks gamerbross!) From 03cf3dcf99807e411288845b006a47cc902a2176 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Fri, 7 Jun 2024 03:29:58 -0400 Subject: [PATCH 174/266] README grammar fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4c6fd9e843..81f8b03e3b 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Friday Night Funkin' is a rhythm game. Built using HaxeFlixel for Ludum Dare 47. -This game was made with love to Newgrounds and it's community. Extra love to Tom Fulp. +This game was made with love to Newgrounds and its community. Extra love to Tom Fulp. - [Playable web demo on Newgrounds!](https://www.newgrounds.com/portal/view/770371) - [Demo download builds for Windows, Mac, and Linux from Itch.io!](https://ninja-muffin24.itch.io/funkin) From d4a524bbcbee7e4ba10da77fbfb4a9d6964a9bbe Mon Sep 17 00:00:00 2001 From: An-enderman <126195358+An-enderman@users.noreply.github.com> Date: Fri, 7 Jun 2024 16:40:37 +0200 Subject: [PATCH 175/266] Update COMPILING, adding one step I added the step that says to download Git, because the command "hmm install" requires Git to work. --- docs/COMPILING.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/COMPILING.md b/docs/COMPILING.md index 7278e027c2..6fbcfe6276 100644 --- a/docs/COMPILING.md +++ b/docs/COMPILING.md @@ -6,9 +6,10 @@ - `git clone --recurse-submodules https://github.com/FunkinCrew/funkin.git` - If you accidentally cloned without the `assets` submodule (aka didn't follow the step above), you can run `git submodule update --init --recursive` to get the assets in a foolproof way. 2. Install `hmm` (run `haxelib --global install hmm` and then `haxelib --global run hmm setup`) -3. Install all haxelibs of the current branch by running `hmm install` -4. Setup lime: `haxelib run lime setup` -5. Platform setup +3. Download Git from [git-scm.com](https://www.git-scm.com) +4. Install all haxelibs of the current branch by running `hmm install` +5. Setup lime: `haxelib run lime setup` +6. 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 @@ -16,5 +17,5 @@ - 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/) - HTML5: Compiles without any extra setup -6. If you are targeting for native, you may need to run `lime rebuild PLATFORM` and `lime rebuild PLATFORM -debug` -7. `lime test PLATFORM` ! Add `-debug` to enable several debug features such as time travel (`PgUp`/`PgDn` in Play State). +7. If you are targeting for native, you may need to run `lime rebuild PLATFORM` and `lime rebuild PLATFORM -debug` +8. `lime test PLATFORM` ! Add `-debug` to enable several debug features such as time travel (`PgUp`/`PgDn` in Play State). From a7e33e73ab13ad26db6feede8d6eb775edb9aa0a Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 7 Jun 2024 11:24:31 -0400 Subject: [PATCH 176/266] assets submod updated and gitmodules fix for public --- .gitmodules | 4 ++-- assets | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 452c0089b7..be5e0aaa81 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 diff --git a/assets b/assets index 4427687c48..3b8235e953 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 4427687c487d643c6051f8c4610470326c87ea4d +Subproject commit 3b8235e953505a6fe7f4ff253f5a99b9a7b9857a From 73984ea9d6830493b004800d85960b6ca69a85f8 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 7 Jun 2024 11:28:35 -0400 Subject: [PATCH 177/266] fix art submod --- art | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/art b/art index faeba700c5..66572f85d8 160000 --- a/art +++ b/art @@ -1 +1 @@ -Subproject commit faeba700c5526bd4fd57ccc927d875c82b9d3553 +Subproject commit 66572f85d826ce2ec1d45468c12733b161237ffa From a0adbc72b36dea5cafeccf10b71c46e90be2b138 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 7 Jun 2024 13:04:45 -0400 Subject: [PATCH 178/266] regexp for numbers --- source/funkin/ui/freeplay/FreeplayState.hx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 607b7a353e..66df2a88d5 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -583,6 +583,8 @@ class FreeplayState extends MusicBeatSubState generateSongList({filterType: FAVORITE}, true); case 'ALL': generateSongList(null, true); + case '#': + generateSongList({filterType: REGEXP, filterData: '0-9'}, true); default: generateSongList({filterType: REGEXP, filterData: str}, true); } From 34c91dae76c87e5821d661e409bcfdbf283c8f5a Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 7 Jun 2024 14:24:57 -0400 Subject: [PATCH 179/266] dadbattle hard/erect fix --- assets | 2 +- source/funkin/ui/freeplay/FreeplayState.hx | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/assets b/assets index 4427687c48..d5ab93cb02 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 4427687c487d643c6051f8c4610470326c87ea4d +Subproject commit d5ab93cb024364404dbeb79d0d0228bb06602f13 diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 607b7a353e..a6cba9b13e 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -285,7 +285,10 @@ class FreeplayState extends MusicBeatSubState // Only display songs which actually have available difficulties for the current character. var displayedVariations = song.getVariationsByCharId(currentCharacter); + trace(songId); + trace(displayedVariations); var availableDifficultiesForSong:Array = song.listDifficulties(displayedVariations, false); + trace(availableDifficultiesForSong); if (availableDifficultiesForSong.length == 0) continue; songs.push(new FreeplaySongData(levelId, songId, song, displayedVariations)); @@ -2076,7 +2079,7 @@ class FreeplaySongData this.songDifficulties = song.listDifficulties(null, variations, false, false); if (!this.songDifficulties.contains(currentDifficulty)) currentDifficulty = Constants.DEFAULT_DIFFICULTY; - var songDifficulty:SongDifficulty = song.getDifficulty(currentDifficulty, variations); + var songDifficulty:SongDifficulty = song.getDifficulty(currentDifficulty, null, variations); if (songDifficulty == null) return; this.songStartingBpm = songDifficulty.getStartingBPM(); this.songName = songDifficulty.songName; From 7b90a3cee3fca0f9c435169c03d3ca9eea65b517 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 7 Jun 2024 14:36:14 -0400 Subject: [PATCH 180/266] lil changelog in progres --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35618dca9b..8397af6660 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ 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.4.1] +### Fixed +- Bug where Dadbattle shows up as Dadbattle Erect when returning to freeplay +- Fixed 2Hot not appearing under the "#" category in Freeplay menu + ## [0.4.0] - 2024-06-06 ### Added - 2 new Erect remixes, Eggnog and Satin Panties. Check them out from the Freeplay menu! From 393355b512556dc3bd7ab33576b2e1c63903299b Mon Sep 17 00:00:00 2001 From: Hundrec Date: Fri, 7 Jun 2024 19:59:02 -0400 Subject: [PATCH 181/266] Fix botplay sustain release bug Copied opponent's holdTimer code to the player's side --- source/funkin/play/PlayState.hx | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index b02cc69f74..d3e287da96 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -2269,11 +2269,20 @@ class PlayState extends MusicBeatSubState if (holdNote == null || !holdNote.alive) continue; // While the hold note is being hit, and there is length on the hold note... - if (!isBotPlayMode && holdNote.hitNote && !holdNote.missedNote && holdNote.sustainLength > 0) + if (holdNote.hitNote && !holdNote.missedNote && holdNote.sustainLength > 0) { // Grant the player health. - health += Constants.HEALTH_HOLD_BONUS_PER_SECOND * elapsed; - songScore += Std.int(Constants.SCORE_HOLD_BONUS_PER_SECOND * elapsed); + if (!isBotPlayMode) + { + health += Constants.HEALTH_HOLD_BONUS_PER_SECOND * elapsed; + songScore += Std.int(Constants.SCORE_HOLD_BONUS_PER_SECOND * elapsed); + } + + // Make sure the player keeps singing while the note is held by the bot. + if (isBotPlayMode && currentStage != null && currentStage.getBoyfriend() != null && currentStage.getBoyfriend().isSinging()) + { + currentStage.getBoyfriend().holdTimer = 0; + } } if (holdNote.missedNote && !holdNote.handledMiss) From ee6c4478a9ed35aee362b796b5c5fb62ba702e72 Mon Sep 17 00:00:00 2001 From: gamerbross <55158797+gamerbross@users.noreply.github.com> Date: Sat, 8 Jun 2024 02:02:54 +0200 Subject: [PATCH 182/266] Use FlxG.camera instead of camGame --- source/funkin/play/PlayState.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index 369d789825..bb45f45e0d 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -3070,7 +3070,7 @@ class PlayState extends MusicBeatSubState FlxG.camera.targetOffset.x += 20; // Replace zoom animation with a fade out for now. - camGame.fade(FlxColor.BLACK, 0.6); + FlxG.camera.fade(FlxColor.BLACK, 0.6); FlxTween.tween(camHUD, {alpha: 0}, 0.6, { From cd485213dbc277b15a70f77679b747527c9a2a96 Mon Sep 17 00:00:00 2001 From: gamerbross <55158797+gamerbross@users.noreply.github.com> Date: Sat, 8 Jun 2024 02:26:17 +0200 Subject: [PATCH 183/266] Pause Camera Follow when pausing --- source/funkin/play/PlayState.hx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index bb45f45e0d..42dc6086c1 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -1211,6 +1211,9 @@ class PlayState extends MusicBeatSubState cameraTweensPausedBySubState.add(cameraZoomTween); } + // Pause camera follow + FlxG.camera.followLerp = 0; + for (tween in scrollSpeedTweens) { if (tween != null && tween.active) @@ -1255,6 +1258,9 @@ class PlayState extends MusicBeatSubState } cameraTweensPausedBySubState.clear(); + // Resume camera follow + FlxG.camera.followLerp = Constants.DEFAULT_CAMERA_FOLLOW_RATE; + if (currentConversation != null) { currentConversation.resumeMusic(); @@ -3165,7 +3171,7 @@ class PlayState extends MusicBeatSubState cancelAllCameraTweens(); } - FlxG.camera.follow(cameraFollowPoint, LOCKON, 0.04); + FlxG.camera.follow(cameraFollowPoint, LOCKON, Constants.DEFAULT_CAMERA_FOLLOW_RATE); FlxG.camera.targetOffset.set(); if (resetZoom) From 2e4b94d528ca5bd5d369c264424be89bc4f3226d Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Fri, 7 Jun 2024 21:20:04 -0400 Subject: [PATCH 184/266] Fix additional merge conflicts --- source/funkin/ui/freeplay/FreeplayState.hx | 1 - 1 file changed, 1 deletion(-) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 576d44c948..5e07fb3967 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -172,7 +172,6 @@ class FreeplayState extends MusicBeatSubState var exitMovers:ExitMoverData = new Map(); var stickerSubState:StickerSubState; - var funnyCam:FunkinCamera; public static var rememberedDifficulty:Null = Constants.DEFAULT_DIFFICULTY; public static var rememberedSongId:Null = 'tutorial'; From 1172949a0425c0a80ded4205a60a253e0a473ed8 Mon Sep 17 00:00:00 2001 From: gamerbross <55158797+gamerbross@users.noreply.github.com> Date: Sun, 19 May 2024 00:23:51 +0200 Subject: [PATCH 185/266] Fix Options Menu not enabled in transIn --- source/funkin/ui/options/OptionsState.hx | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/source/funkin/ui/options/OptionsState.hx b/source/funkin/ui/options/OptionsState.hx index 81331b266f..e7950f0bd1 100644 --- a/source/funkin/ui/options/OptionsState.hx +++ b/source/funkin/ui/options/OptionsState.hx @@ -25,6 +25,8 @@ class OptionsState extends MusicBeatState override function create():Void { + persistentUpdate = true; + var menuBG = new FlxSprite().loadGraphic(Paths.image('menuBG')); var hsv = new HSVShader(); hsv.hue = -0.6; @@ -55,8 +57,6 @@ class OptionsState extends MusicBeatState setPage(Controls); } - // disable for intro transition - currentPage.enabled = false; super.create(); } @@ -86,13 +86,6 @@ class OptionsState extends MusicBeatState } } - override function finishTransIn() - { - super.finishTransIn(); - - currentPage.enabled = true; - } - function switchPage(name:PageName) { // TODO: Animate this transition? From 45b43108d12be31bd79d26dbce1b6dadd8182191 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Fri, 7 Jun 2024 22:36:25 -0400 Subject: [PATCH 186/266] lower fft amount on desktop --- source/funkin/audio/visualize/ABotVis.hx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/funkin/audio/visualize/ABotVis.hx b/source/funkin/audio/visualize/ABotVis.hx index 1b04631445..a455cb8a2b 100644 --- a/source/funkin/audio/visualize/ABotVis.hx +++ b/source/funkin/audio/visualize/ABotVis.hx @@ -54,12 +54,12 @@ class ABotVis extends FlxTypedSpriteGroup public function initAnalyzer() { @:privateAccess - analyzer = new SpectralAnalyzer(snd._channel.__source, 7, 0.1, 30); + analyzer = new SpectralAnalyzer(snd._channel.__source, 7, 0.1, 40); #if desktop // On desktop it uses FFT stuff that isn't as optimized as the direct browser stuff we use on HTML5 // So we want to manually change it! - analyzer.fftN = 512; + analyzer.fftN = 256; #end // analyzer.maxDb = -35; From bc80e39a8543df6c44b102d3ddf4b4c1f2a93ff0 Mon Sep 17 00:00:00 2001 From: zacksgamerz <81515012+zacksgamerz@users.noreply.github.com> Date: Sat, 8 Jun 2024 19:07:22 +0700 Subject: [PATCH 187/266] you're to your --- .github/ISSUE_TEMPLATE/bug.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index efa81b56de..733656a118 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -41,4 +41,4 @@ labels: bug -## If you're game is FROZEN and you're playing a web version, press F12 to open up browser dev window, and go to console, and copy-paste whatever red error you're getting +## If your game is FROZEN and you're playing a web version, press F12 to open up browser dev window, and go to console, and copy-paste whatever red error you're getting From 3334cc35637cd0ddb58f8675dd92e6495bfa1949 Mon Sep 17 00:00:00 2001 From: tposejank <81495861+tposejank@users.noreply.github.com> Date: Sat, 8 Jun 2024 22:40:09 -0400 Subject: [PATCH 188/266] Update and rename bug.md to bug.yml --- .github/ISSUE_TEMPLATE/bug.md | 44 ------------------------ .github/ISSUE_TEMPLATE/bug.yml | 61 ++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 44 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug.md create mode 100644 .github/ISSUE_TEMPLATE/bug.yml diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md deleted file mode 100644 index efa81b56de..0000000000 --- a/.github/ISSUE_TEMPLATE/bug.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -name: Bug Report -about: Report a bug or critical performance issue -title: 'Bug Report: [DESCRIBE YOUR BUG IN DETAIL HERE]' -labels: bug ---- - -[weed]: <> (FILL THIS ISSUE THING OUT AS MUCH AS POSSIBLE) -[weed]: <> (OR ELSE YOUR ISSUE WILL BE LESS LIKELY TO BE SOLVED!) -[weed]: <> (DO NOT POST ABOUT ISSUES FROM OTHER FNF MOD ENGINES! I CANNOT AND PROBABLY WON'T SOLVE THOSE!) -[weed]: <> (GO TO THEIR RESPECTIVE GITHUB ISSUES AND REPORT THEM THERE LOL!) - -[weed]: <> (ALSO MAKE SURE THAT YOU USE PROPER LABELS, IF YOU'RE RUNNING INTO COMPILER ISSUES, USE THE compiler issue LABEL!!!) - -#### Please check for duplicates or similar issues, as well performing simple troubleshooting steps (such as clearing cookies, clearing AppData, trying another browser) before submitting an issue. -### If you are playing the game in a browser, what site are you playing it from? - -[weed]: <> (Put an X in the [ ] thingies to fill out checkbox!) -[weed]: <> (something like [x] pretty much, don't screw up or you will look stupid) - -- [ ] [Newgrounds](https://www.newgrounds.com/portal/view/770371) -- [ ] [Itch.io](https://ninja-muffin24.itch.io/funkin)? Specify below -- - [ ] Windows -- - [ ] Mac -- - [ ] Linux - -### If you are playing the game in a browser, what browser are you using? - -[weed]: <> (Again, put an x in the [ ] box!) - -- [ ] Google Chrome (or chomium based like Brave, vivaldi, MS Edge) -- [ ] Firefox -- [ ] Safari - -## What version of the game are you using? Look in the bottom left corner of the main menu. (ex: 0.2.7, 0.2.1, shit like that) - - -## Have you identified any steps to reproduce the bug? If so, please describe them below in as much detail as possible. Use images if possible. - -## Please describe your issue. Provide extensive detail and images if possible. - - - -## If you're game is FROZEN and you're playing a web version, press F12 to open up browser dev window, and go to console, and copy-paste whatever red error you're getting diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml new file mode 100644 index 0000000000..c0334394f0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -0,0 +1,61 @@ +name: Bug Report +description: Report a bug or an issue in the game +labels: ["bug"] +title: "Bug Report: " +body: + - type: checkboxes + attributes: + label: Issue Checklist + options: + - label: I have properly named the issue + - label: I looked in issues/discussions, if it has been previously reported + + - type: dropdown + attributes: + label: What platform are you using? + options: + - Itch.io - Windows + - Itch.io - MacOS + - Itch.io - Linux + - Newgrounds (Web) + validations: + required: true + + - type: dropdown + attributes: + label: If you were playing on a browser, which one were you using? + options: + - Google Chrome + - Microsoft Edge + - Firefox + - Opera + - Safari + - Other (Specify below) + + - type: input + attributes: + label: Version + description: What version were you using? + placeholder: ex. 0.4.0 + validations: + required: true + + - type: markdown + attributes: + value: "## Describe your bug." + + - type: markdown + attributes: + value: "### Please do not report issues from other engines. These must be reported in their repositories." + + - type: markdown + attributes: + value: "#### Provide as many details as you can." + + - type: textarea + attributes: + label: Context (Provide images, videos, etc.) + + - type: textarea + attributes: + label: Steps to reproduce (or crash logs, errors, etc.) From 6b74befb5f622d75aeedc9ef6f9457b125904152 Mon Sep 17 00:00:00 2001 From: tposejank <81495861+tposejank@users.noreply.github.com> Date: Sat, 8 Jun 2024 22:42:50 -0400 Subject: [PATCH 189/266] Run it through prettier --- .github/ISSUE_TEMPLATE/bug.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index c0334394f0..457bf11e17 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -20,7 +20,7 @@ body: - Newgrounds (Web) validations: required: true - + - type: dropdown attributes: label: If you were playing on a browser, which one were you using? @@ -41,16 +41,16 @@ body: required: true - type: markdown - attributes: - value: "## Describe your bug." + attributes: + value: "## Describe your bug." - type: markdown - attributes: - value: "### Please do not report issues from other engines. These must be reported in their repositories." + attributes: + value: "### Please do not report issues from other engines. These must be reported in their repositories." - type: markdown - attributes: - value: "#### Provide as many details as you can." + attributes: + value: "#### Provide as many details as you can." - type: textarea attributes: From c1da4d336c4d96e6eab73499a7dd8b23fcbb4f47 Mon Sep 17 00:00:00 2001 From: tposejank <81495861+tposejank@users.noreply.github.com> Date: Sat, 8 Jun 2024 22:48:05 -0400 Subject: [PATCH 190/266] Update and rename compiling.md to compiling.yml --- .github/ISSUE_TEMPLATE/compiling.md | 25 ----------------- .github/ISSUE_TEMPLATE/compiling.yml | 42 ++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 25 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/compiling.md create mode 100644 .github/ISSUE_TEMPLATE/compiling.yml diff --git a/.github/ISSUE_TEMPLATE/compiling.md b/.github/ISSUE_TEMPLATE/compiling.md deleted file mode 100644 index 14aea44a7c..0000000000 --- a/.github/ISSUE_TEMPLATE/compiling.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -name: Compiling help -about: If you need help compiling the game, and you're running into issues. (Look through the 'compiling help' label in case it's been solved!) -title: 'Compiling help: [BRIEF DESCRIPTION / ERROR MESSAGE OUTPUT]' -labels: compiling help ---- - -[weed]: <> (FILL THIS ISSUE THING OUT AS MUCH AS POSSIBLE) -[weed]: <> (OR ELSE YOUR ISSUE WILL BE LESS LIKELY TO BE SOLVED!) -[weed]: <> (DO NOT POST ABOUT ISSUES FROM OTHER FNF MOD ENGINES! I CANNOT AND PROBABLY WON'T SOLVE THOSE!) -[weed]: <> (GO TO THEIR RESPECTIVE GITHUB ISSUES AND REPORT THEM THERE LOL!) - -#### Please check for duplicates or similar compiler issues by filtering for 'compiler help' - -[weed]: <> (Put an X in the [ ] thingies to fill out checkbox!) -[weed]: <> (something like [x] pretty much, don't screw up or you will look stupid) - - -- [ ] Windows -- [ ] Mac -- [ ] Linux -- [ ] HTML5 - -## Please describe your issue. Provide extensive detail and images if possible. - diff --git a/.github/ISSUE_TEMPLATE/compiling.yml b/.github/ISSUE_TEMPLATE/compiling.yml new file mode 100644 index 0000000000..d446b64b4e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/compiling.yml @@ -0,0 +1,42 @@ +name: Compiling help +description: If you need help compiling the game, and you're running into issues. +labels: ["compiling help"] +title: "Compiling help: " +body: + - type: checkboxes + attributes: + label: Issue Checklist + options: + - label: I have properly named the issue + - label: I looked in issues/discussions, if it has been previously reported + + - type: dropdown + attributes: + label: What platform are you compiling to? + options: + - Windows + - MacOS + - Linux + - HTML5 + validations: + required: true + + - type: markdown + attributes: + value: "## Describe the issue." + + - type: markdown + attributes: + value: "### Please do not report issues from other engines. These must be reported in their repositories." + + - type: markdown + attributes: + value: "#### Provide as many details as you can." + + - type: textarea + attributes: + label: Context (Provide images, videos, etc.) + + - type: textarea + attributes: + label: Steps to reproduce (or crash logs, errors, etc.) From 3f77d1d7cab89e080de5df26dff94bd8e1ff12bf Mon Sep 17 00:00:00 2001 From: tposejank <81495861+tposejank@users.noreply.github.com> Date: Sat, 8 Jun 2024 22:50:44 -0400 Subject: [PATCH 191/266] Update and rename enhancement.md to enhancement.yml --- .github/ISSUE_TEMPLATE/enhancement.md | 8 -------- .github/ISSUE_TEMPLATE/enhancement.yml | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 8 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/enhancement.md create mode 100644 .github/ISSUE_TEMPLATE/enhancement.yml diff --git a/.github/ISSUE_TEMPLATE/enhancement.md b/.github/ISSUE_TEMPLATE/enhancement.md deleted file mode 100644 index e1cc3ae0df..0000000000 --- a/.github/ISSUE_TEMPLATE/enhancement.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: Enhancement -about: Suggest a new feature -title: 'Enhancement: ' -labels: enhancement ---- -#### Please check for duplicates or similar issues before creating this issue. -## What is your suggestion, and why should it be implemented? diff --git a/.github/ISSUE_TEMPLATE/enhancement.yml b/.github/ISSUE_TEMPLATE/enhancement.yml new file mode 100644 index 0000000000..29c7e56694 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/enhancement.yml @@ -0,0 +1,15 @@ +name: Enhancement +description: Suggest a new feature +labels: ["enhancement"] +title: "Enhancement: " +body: + - type: checkboxes + attributes: + label: Issue Checklist + options: + - label: I have properly named the issue + - label: I looked in issues/discussions, if it has been previously reported + + - type: textarea + attributes: + label: What is your suggestion, and why should it be implemented? From 0808469a6207b33d58c6de9789d4319ace01f5c3 Mon Sep 17 00:00:00 2001 From: tposejank <81495861+tposejank@users.noreply.github.com> Date: Sat, 8 Jun 2024 22:52:37 -0400 Subject: [PATCH 192/266] Update and rename question.md to question.yml --- .github/ISSUE_TEMPLATE/question.md | 12 ------------ .github/ISSUE_TEMPLATE/question.yml | 8 ++++++++ 2 files changed, 8 insertions(+), 12 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/question.md create mode 100644 .github/ISSUE_TEMPLATE/question.yml diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md deleted file mode 100644 index a257c217a7..0000000000 --- a/.github/ISSUE_TEMPLATE/question.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -name: Question -about: Ask a general question -title: 'Question: ' -labels: question ---- - -[weed]: <> (This isn't a place for AMA type questions, if you want to ask any of the devs something, reach out to them on twitter prob ) -[weed]: <> (any biz bullshit can go to cameron.taylor.ninja@gmail.com) - -#### Please check for duplicates or similar issues before asking your question. -## What is your question? diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml new file mode 100644 index 0000000000..c6e6e1b116 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.yml @@ -0,0 +1,8 @@ +name: Question +description: Ask a general question +labels: ["question"] +title: "Question: " +body: + - type: textarea + attributes: + label: What is your question? From 347f487358c4873960e58ec1500d2976e5293463 Mon Sep 17 00:00:00 2001 From: tposejank <81495861+tposejank@users.noreply.github.com> Date: Sat, 8 Jun 2024 22:54:44 -0400 Subject: [PATCH 193/266] Create config.yml --- .github/ISSUE_TEMPLATE/config.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000..3ba13e0cec --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false From 19ef15dbc8381b37807d6aae28bcb3b64bb94ca2 Mon Sep 17 00:00:00 2001 From: tposejank <81495861+tposejank@users.noreply.github.com> Date: Sat, 8 Jun 2024 22:59:17 -0400 Subject: [PATCH 194/266] Update and rename bug.md to bug.yml --- .github/PULL_REQUEST_TEMPLATE/bug.md | 10 ---------- .github/PULL_REQUEST_TEMPLATE/bug.yml | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 10 deletions(-) delete mode 100644 .github/PULL_REQUEST_TEMPLATE/bug.md create mode 100644 .github/PULL_REQUEST_TEMPLATE/bug.yml diff --git a/.github/PULL_REQUEST_TEMPLATE/bug.md b/.github/PULL_REQUEST_TEMPLATE/bug.md deleted file mode 100644 index 41914c5ede..0000000000 --- a/.github/PULL_REQUEST_TEMPLATE/bug.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: Bug Fix -about: Fix a bug or critical performance issue -title: 'Bug Fix: ' -labels: bug ---- -#### Please check for duplicates or similar PRs before creating this issue. -## Does this PR close any issue(s)? If so, link them below. - -## Briefly describe the issue(s) fixed. diff --git a/.github/PULL_REQUEST_TEMPLATE/bug.yml b/.github/PULL_REQUEST_TEMPLATE/bug.yml new file mode 100644 index 0000000000..c8aa2fcb3f --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/bug.yml @@ -0,0 +1,18 @@ +name: Bug Fix +description: Fix a bug or critical performance issue +labels: ["bug"] +title: "Bug Fix: " +body: + - type: checkboxes + attributes: + label: Issue Checklist + options: + - label: I have checked if this PR isn't a duplicate + + - type: textarea + attributes: + label: Does this PR fix any issues? Please link them below if so. + + - type: textarea + attributes: + label: Briefly describe the issue(s) fixed. From 075989ce9c403c6a64f5eb3f04136acf68991cf0 Mon Sep 17 00:00:00 2001 From: tposejank <81495861+tposejank@users.noreply.github.com> Date: Sat, 8 Jun 2024 23:00:24 -0400 Subject: [PATCH 195/266] Update and rename enhancement.md to enhancement.yml --- .github/PULL_REQUEST_TEMPLATE/enhancement.md | 10 ---------- .github/PULL_REQUEST_TEMPLATE/enhancement.yml | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 10 deletions(-) delete mode 100644 .github/PULL_REQUEST_TEMPLATE/enhancement.md create mode 100644 .github/PULL_REQUEST_TEMPLATE/enhancement.yml diff --git a/.github/PULL_REQUEST_TEMPLATE/enhancement.md b/.github/PULL_REQUEST_TEMPLATE/enhancement.md deleted file mode 100644 index e208deefea..0000000000 --- a/.github/PULL_REQUEST_TEMPLATE/enhancement.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: Enhancement -about: Add a new feature -title: 'Enhancement: ' -labels: enhancement ---- -#### Please check for duplicates or similar PRs before creating this issue. -## Does this PR close any issue(s)? If so, link them below. - -## What do your change(s) add, and why should they be implemented? diff --git a/.github/PULL_REQUEST_TEMPLATE/enhancement.yml b/.github/PULL_REQUEST_TEMPLATE/enhancement.yml new file mode 100644 index 0000000000..57186b9807 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/enhancement.yml @@ -0,0 +1,18 @@ +name: Enhancement +description: Add a new feature +labels: ["enhancement"] +title: "Enhancement: " +body: + - type: checkboxes + attributes: + label: Issue Checklist + options: + - label: I have checked if this PR isn't a duplicate + + - type: textarea + attributes: + label: Does this PR fix any issues? Please link them below if so. + + - type: textarea + attributes: + label: What do your change(s) add, and why should they be implemented? From 09aa8fbf52941d8f35cd36418263147673f341b1 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Sun, 9 Jun 2024 02:22:03 -0400 Subject: [PATCH 196/266] Rebindable controls for the Freeplay menu --- source/funkin/input/Controls.hx | 160 ++++++++++++------ source/funkin/ui/freeplay/FreeplayState.hx | 57 +------ source/funkin/ui/freeplay/LetterSort.hx | 10 +- source/funkin/ui/options/ControlsMenu.hx | 18 +- source/funkin/util/WindowUtil.hx | 2 +- .../funkin/util/plugins/ScreenshotPlugin.hx | 2 +- 6 files changed, 141 insertions(+), 108 deletions(-) diff --git a/source/funkin/input/Controls.hx b/source/funkin/input/Controls.hx index 345791eefe..e2cae56130 100644 --- a/source/funkin/input/Controls.hx +++ b/source/funkin/input/Controls.hx @@ -58,7 +58,11 @@ class Controls extends FlxActionSet var _back = new FunkinAction(Action.BACK); var _pause = new FunkinAction(Action.PAUSE); var _reset = new FunkinAction(Action.RESET); - var _screenshot = new FunkinAction(Action.SCREENSHOT); + var _window_screenshot = new FunkinAction(Action.WINDOW_SCREENSHOT); + var _window_fullscreen = new FunkinAction(Action.WINDOW_FULLSCREEN); + var _freeplay_favorite = new FunkinAction(Action.FREEPLAY_FAVORITE); + var _freeplay_left = new FunkinAction(Action.FREEPLAY_LEFT); + var _freeplay_right = new FunkinAction(Action.FREEPLAY_RIGHT); var _cutscene_advance = new FunkinAction(Action.CUTSCENE_ADVANCE); var _debug_menu = new FunkinAction(Action.DEBUG_MENU); var _debug_chart = new FunkinAction(Action.DEBUG_CHART); @@ -66,7 +70,6 @@ class Controls extends FlxActionSet var _volume_up = new FunkinAction(Action.VOLUME_UP); var _volume_down = new FunkinAction(Action.VOLUME_DOWN); var _volume_mute = new FunkinAction(Action.VOLUME_MUTE); - var _fullscreen = new FunkinAction(Action.FULLSCREEN); var byName:Map = new Map(); @@ -233,10 +236,30 @@ class Controls extends FlxActionSet inline function get_RESET() return _reset.check(); - public var SCREENSHOT(get, never):Bool; + public var WINDOW_FULLSCREEN(get, never):Bool; - inline function get_SCREENSHOT() - return _screenshot.check(); + inline function get_WINDOW_FULLSCREEN() + return _window_fullscreen.check(); + + public var WINDOW_SCREENSHOT(get, never):Bool; + + inline function get_WINDOW_SCREENSHOT() + return _window_screenshot.check(); + + public var FREEPLAY_FAVORITE(get, never):Bool; + + inline function get_FREEPLAY_FAVORITE() + return _freeplay_favorite.check(); + + public var FREEPLAY_LEFT(get, never):Bool; + + inline function get_FREEPLAY_LEFT() + return _freeplay_left.check(); + + public var FREEPLAY_RIGHT(get, never):Bool; + + inline function get_FREEPLAY_RIGHT() + return _freeplay_right.check(); public var CUTSCENE_ADVANCE(get, never):Bool; @@ -273,11 +296,6 @@ class Controls extends FlxActionSet inline function get_VOLUME_MUTE() return _volume_mute.check(); - public var FULLSCREEN(get, never):Bool; - - inline function get_FULLSCREEN() - return _fullscreen.check(); - public function new(name, scheme:KeyboardScheme = null) { super(name); @@ -294,7 +312,11 @@ class Controls extends FlxActionSet add(_back); add(_pause); add(_reset); - add(_screenshot); + add(_window_screenshot); + add(_window_fullscreen); + add(_freeplay_favorite); + add(_freeplay_left); + add(_freeplay_right); add(_cutscene_advance); add(_debug_menu); add(_debug_chart); @@ -302,7 +324,6 @@ class Controls extends FlxActionSet add(_volume_up); add(_volume_down); add(_volume_mute); - add(_fullscreen); for (action in digitalActions) { if (Std.isOfType(action, FunkinAction)) { @@ -398,7 +419,11 @@ class Controls extends FlxActionSet case BACK: _back; case PAUSE: _pause; case RESET: _reset; - case SCREENSHOT: _screenshot; + case WINDOW_SCREENSHOT: _window_screenshot; + case WINDOW_FULLSCREEN: _window_fullscreen; + case FREEPLAY_FAVORITE: _freeplay_favorite; + case FREEPLAY_LEFT: _freeplay_left; + case FREEPLAY_RIGHT: _freeplay_right; case CUTSCENE_ADVANCE: _cutscene_advance; case DEBUG_MENU: _debug_menu; case DEBUG_CHART: _debug_chart; @@ -406,7 +431,6 @@ class Controls extends FlxActionSet case VOLUME_UP: _volume_up; case VOLUME_DOWN: _volume_down; case VOLUME_MUTE: _volume_mute; - case FULLSCREEN: _fullscreen; } } @@ -466,8 +490,16 @@ class Controls extends FlxActionSet func(_pause, JUST_PRESSED); case RESET: func(_reset, JUST_PRESSED); - case SCREENSHOT: - func(_screenshot, JUST_PRESSED); + case WINDOW_SCREENSHOT: + func(_window_screenshot, JUST_PRESSED); + case WINDOW_FULLSCREEN: + func(_window_fullscreen, JUST_PRESSED); + case FREEPLAY_FAVORITE: + func(_freeplay_favorite, JUST_PRESSED); + case FREEPLAY_LEFT: + func(_freeplay_left, JUST_PRESSED); + case FREEPLAY_RIGHT: + func(_freeplay_right, JUST_PRESSED); case CUTSCENE_ADVANCE: func(_cutscene_advance, JUST_PRESSED); case DEBUG_MENU: @@ -482,8 +514,6 @@ class Controls extends FlxActionSet func(_volume_down, JUST_PRESSED); case VOLUME_MUTE: func(_volume_mute, JUST_PRESSED); - case FULLSCREEN: - func(_fullscreen, JUST_PRESSED); } } @@ -678,7 +708,11 @@ class Controls extends FlxActionSet bindKeys(Control.BACK, getDefaultKeybinds(scheme, Control.BACK)); bindKeys(Control.PAUSE, getDefaultKeybinds(scheme, Control.PAUSE)); bindKeys(Control.RESET, getDefaultKeybinds(scheme, Control.RESET)); - bindKeys(Control.SCREENSHOT, getDefaultKeybinds(scheme, Control.SCREENSHOT)); + bindKeys(Control.WINDOW_SCREENSHOT, getDefaultKeybinds(scheme, Control.WINDOW_SCREENSHOT)); + bindKeys(Control.WINDOW_FULLSCREEN, getDefaultKeybinds(scheme, Control.WINDOW_FULLSCREEN)); + bindKeys(Control.FREEPLAY_FAVORITE, getDefaultKeybinds(scheme, Control.FREEPLAY_FAVORITE)); + bindKeys(Control.FREEPLAY_LEFT, getDefaultKeybinds(scheme, Control.FREEPLAY_LEFT)); + bindKeys(Control.FREEPLAY_RIGHT, getDefaultKeybinds(scheme, Control.FREEPLAY_RIGHT)); bindKeys(Control.CUTSCENE_ADVANCE, getDefaultKeybinds(scheme, Control.CUTSCENE_ADVANCE)); bindKeys(Control.DEBUG_MENU, getDefaultKeybinds(scheme, Control.DEBUG_MENU)); bindKeys(Control.DEBUG_CHART, getDefaultKeybinds(scheme, Control.DEBUG_CHART)); @@ -686,7 +720,6 @@ class Controls extends FlxActionSet bindKeys(Control.VOLUME_UP, getDefaultKeybinds(scheme, Control.VOLUME_UP)); bindKeys(Control.VOLUME_DOWN, getDefaultKeybinds(scheme, Control.VOLUME_DOWN)); bindKeys(Control.VOLUME_MUTE, getDefaultKeybinds(scheme, Control.VOLUME_MUTE)); - bindKeys(Control.FULLSCREEN, getDefaultKeybinds(scheme, Control.FULLSCREEN)); bindMobileLol(); } @@ -707,7 +740,11 @@ class Controls extends FlxActionSet case Control.BACK: return [X, BACKSPACE, ESCAPE]; case Control.PAUSE: return [P, ENTER, ESCAPE]; case Control.RESET: return [R]; - case Control.SCREENSHOT: return [F3]; // TODO: Change this back to PrintScreen + case Control.WINDOW_FULLSCREEN: return [F11]; // We use F for other things LOL. + case Control.WINDOW_SCREENSHOT: return [F3]; + case Control.FREEPLAY_FAVORITE: return [F]; // Favorite a song on the menu + case Control.FREEPLAY_LEFT: return [Q]; // Switch tabs on the menu + case Control.FREEPLAY_RIGHT: return [E]; // Switch tabs on the menu case Control.CUTSCENE_ADVANCE: return [Z, ENTER]; case Control.DEBUG_MENU: return [GRAVEACCENT]; case Control.DEBUG_CHART: return []; @@ -715,8 +752,6 @@ class Controls extends FlxActionSet case Control.VOLUME_UP: return [PLUS, NUMPADPLUS]; case Control.VOLUME_DOWN: return [MINUS, NUMPADMINUS]; case Control.VOLUME_MUTE: return [ZERO, NUMPADZERO]; - case Control.FULLSCREEN: return [FlxKey.F11]; // We use F for other things LOL. - } case Duo(true): switch (control) { @@ -732,7 +767,11 @@ class Controls extends FlxActionSet case Control.BACK: return [H, X]; case Control.PAUSE: return [ONE]; case Control.RESET: return [R]; - case Control.SCREENSHOT: return [PRINTSCREEN]; + case Control.WINDOW_SCREENSHOT: return [F3]; + case Control.WINDOW_FULLSCREEN: return [F11]; + case Control.FREEPLAY_FAVORITE: return [F]; // Favorite a song on the menu + case Control.FREEPLAY_LEFT: return [Q]; // Switch tabs on the menu + case Control.FREEPLAY_RIGHT: return [E]; // Switch tabs on the menu case Control.CUTSCENE_ADVANCE: return [G, Z]; case Control.DEBUG_MENU: return [GRAVEACCENT]; case Control.DEBUG_CHART: return []; @@ -740,7 +779,6 @@ class Controls extends FlxActionSet case Control.VOLUME_UP: return [PLUS]; case Control.VOLUME_DOWN: return [MINUS]; case Control.VOLUME_MUTE: return [ZERO]; - case Control.FULLSCREEN: return [FlxKey.F]; } case Duo(false): @@ -757,15 +795,18 @@ class Controls extends FlxActionSet case Control.BACK: return [ESCAPE]; case Control.PAUSE: return [ONE]; case Control.RESET: return [R]; - case Control.SCREENSHOT: return [PRINTSCREEN]; + case Control.WINDOW_SCREENSHOT: return []; + case Control.WINDOW_FULLSCREEN: return []; + case Control.FREEPLAY_FAVORITE: return []; + case Control.FREEPLAY_LEFT: return []; + case Control.FREEPLAY_RIGHT: return []; case Control.CUTSCENE_ADVANCE: return [ENTER]; - case Control.DEBUG_MENU: return [GRAVEACCENT]; + case Control.DEBUG_MENU: return []; case Control.DEBUG_CHART: return []; case Control.DEBUG_STAGE: return []; case Control.VOLUME_UP: return [NUMPADPLUS]; case Control.VOLUME_DOWN: return [NUMPADMINUS]; case Control.VOLUME_MUTE: return [NUMPADZERO]; - case Control.FULLSCREEN: return []; } default: @@ -856,34 +897,37 @@ class Controls extends FlxActionSet public function addDefaultGamepad(id):Void { addGamepadLiteral(id, [ - Control.ACCEPT => getDefaultGamepadBinds(Control.ACCEPT), Control.BACK => getDefaultGamepadBinds(Control.BACK), Control.UI_UP => getDefaultGamepadBinds(Control.UI_UP), Control.UI_DOWN => getDefaultGamepadBinds(Control.UI_DOWN), Control.UI_LEFT => getDefaultGamepadBinds(Control.UI_LEFT), Control.UI_RIGHT => getDefaultGamepadBinds(Control.UI_RIGHT), - // don't swap A/B or X/Y for switch on these. A is always the bottom face button Control.NOTE_UP => getDefaultGamepadBinds(Control.NOTE_UP), Control.NOTE_DOWN => getDefaultGamepadBinds(Control.NOTE_DOWN), Control.NOTE_LEFT => getDefaultGamepadBinds(Control.NOTE_LEFT), Control.NOTE_RIGHT => getDefaultGamepadBinds(Control.NOTE_RIGHT), Control.PAUSE => getDefaultGamepadBinds(Control.PAUSE), Control.RESET => getDefaultGamepadBinds(Control.RESET), - // Control.SCREENSHOT => [], - // Control.VOLUME_UP => [RIGHT_SHOULDER], - // Control.VOLUME_DOWN => [LEFT_SHOULDER], - // Control.VOLUME_MUTE => [RIGHT_TRIGGER], + Control.WINDOW_FULLSCREEN => getDefaultGamepadBinds(Control.WINDOW_FULLSCREEN), + Control.WINDOW_SCREENSHOT => getDefaultGamepadBinds(Control.WINDOW_SCREENSHOT), Control.CUTSCENE_ADVANCE => getDefaultGamepadBinds(Control.CUTSCENE_ADVANCE), - // Control.DEBUG_MENU - // Control.DEBUG_CHART + Control.FREEPLAY_FAVORITE => getDefaultGamepadBinds(Control.FREEPLAY_FAVORITE), + Control.FREEPLAY_LEFT => getDefaultGamepadBinds(Control.FREEPLAY_LEFT), + Control.FREEPLAY_RIGHT => getDefaultGamepadBinds(Control.FREEPLAY_RIGHT), + Control.VOLUME_UP => getDefaultGamepadBinds(Control.VOLUME_UP), + Control.VOLUME_DOWN => getDefaultGamepadBinds(Control.VOLUME_DOWN), + Control.VOLUME_MUTE => getDefaultGamepadBinds(Control.VOLUME_MUTE), + Control.DEBUG_MENU => getDefaultGamepadBinds(Control.DEBUG_MENU), + Control.DEBUG_CHART => getDefaultGamepadBinds(Control.DEBUG_CHART), + Control.DEBUG_STAGE => getDefaultGamepadBinds(Control.DEBUG_STAGE), ]); } function getDefaultGamepadBinds(control:Control):Array { switch(control) { case Control.ACCEPT: return [#if switch B #else A #end]; - case Control.BACK: return [#if switch A #else B #end, FlxGamepadInputID.BACK]; + case Control.BACK: return [#if switch A #else B #end]; case Control.UI_UP: return [DPAD_UP, LEFT_STICK_DIGITAL_UP]; case Control.UI_DOWN: return [DPAD_DOWN, LEFT_STICK_DIGITAL_DOWN]; case Control.UI_LEFT: return [DPAD_LEFT, LEFT_STICK_DIGITAL_LEFT]; @@ -893,15 +937,19 @@ class Controls extends FlxActionSet case Control.NOTE_LEFT: return [DPAD_LEFT, X, LEFT_STICK_DIGITAL_LEFT, RIGHT_STICK_DIGITAL_LEFT]; case Control.NOTE_RIGHT: return [DPAD_RIGHT, B, LEFT_STICK_DIGITAL_RIGHT, RIGHT_STICK_DIGITAL_RIGHT]; case Control.PAUSE: return [START]; - case Control.RESET: return [RIGHT_SHOULDER]; - case Control.SCREENSHOT: return []; - case Control.VOLUME_UP: return []; - case Control.VOLUME_DOWN: return []; - case Control.VOLUME_MUTE: return []; + case Control.RESET: return [FlxGamepadInputID.BACK]; // Back (i.e. Select) + case Control.WINDOW_FULLSCREEN: []; + case Control.WINDOW_SCREENSHOT: []; case Control.CUTSCENE_ADVANCE: return [A]; - case Control.DEBUG_MENU: return []; - case Control.DEBUG_CHART: return []; - case Control.FULLSCREEN: return []; + case Control.FREEPLAY_FAVORITE: [FlxGamepadInputID.BACK]; // Back (i.e. Select) + case Control.FREEPLAY_LEFT: [LEFT_SHOULDER]; + case Control.FREEPLAY_RIGHT: [RIGHT_SHOULDER]; + case Control.VOLUME_UP: []; + case Control.VOLUME_DOWN: []; + case Control.VOLUME_MUTE: []; + case Control.DEBUG_MENU: []; + case Control.DEBUG_CHART: []; + case Control.DEBUG_STAGE: []; default: // Fallthrough. } @@ -1392,7 +1440,7 @@ class FlxActionInputDigitalAndroid extends FlxActionInputDigital override public function check(Action:FlxAction):Bool { - returnswitch(trigger) + return switch(trigger) { #if android case PRESSED: FlxG.android.checkStatus(inputID, PRESSED) || FlxG.android.checkStatus(inputID, PRESSED); @@ -1425,14 +1473,18 @@ enum Control UI_RIGHT; UI_DOWN; RESET; - SCREENSHOT; ACCEPT; BACK; PAUSE; - FULLSCREEN; // CUTSCENE CUTSCENE_ADVANCE; - // SCREENSHOT + // FREEPLAY + FREEPLAY_FAVORITE; + FREEPLAY_LEFT; + FREEPLAY_RIGHT; + // WINDOW + WINDOW_SCREENSHOT; + WINDOW_FULLSCREEN; // VOLUME VOLUME_UP; VOLUME_DOWN; @@ -1475,11 +1527,15 @@ enum abstract Action(String) to String from String var BACK = "back"; var PAUSE = "pause"; var RESET = "reset"; - var FULLSCREEN = "fullscreen"; - // SCREENSHOT - var SCREENSHOT = "screenshot"; + // WINDOW + var WINDOW_FULLSCREEN = "window_fullscreen"; + var WINDOW_SCREENSHOT = "window_screenshot"; // CUTSCENE var CUTSCENE_ADVANCE = "cutscene_advance"; + // FREEPLAY + var FREEPLAY_FAVORITE = "freeplay_favorite"; + var FREEPLAY_LEFT = "freeplay_left"; + var FREEPLAY_RIGHT = "freeplay_right"; // VOLUME var VOLUME_UP = "volume_up"; var VOLUME_DOWN = "volume_down"; diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 5e07fb3967..1a4d034118 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -965,16 +965,18 @@ class FreeplayState extends MusicBeatSubState grpCapsules.members[curSelected].ranking.scale.set(20, 20); grpCapsules.members[curSelected].blurredRanking.scale.set(20, 20); - grpCapsules.members[curSelected].ranking.animation.play(fromResults.newRank.getFreeplayRankIconAsset(), true); - // grpCapsules.members[curSelected].ranking.animation.curAnim.name, true); + if (fromResults?.newRank != null) { + grpCapsules.members[curSelected].ranking.animation.play(fromResults.newRank.getFreeplayRankIconAsset(), true); + } FlxTween.tween(grpCapsules.members[curSelected].ranking, {"scale.x": 1, "scale.y": 1}, 0.1); - grpCapsules.members[curSelected].blurredRanking.animation.play(fromResults.newRank.getFreeplayRankIconAsset(), true); + if (fromResults?.newRank != null) { + 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, _ -> { - // trace(grpCapsules.members[curSelected].ranking.rank); if (fromResults?.oldRank != null) { grpCapsules.members[curSelected].fakeRanking.visible = false; @@ -1003,7 +1005,6 @@ class FreeplayState extends MusicBeatSubState FunkinSound.playOnce(Paths.sound('ranks/rankinnormal')); } rankCamera.zoom = 1.3; - // FlxTween.tween(rankCamera, {"zoom": 1.4}, 0.3, {ease: FlxEase.elasticOut}); FlxTween.tween(rankCamera, {"zoom": 1.5}, 0.3, {ease: FlxEase.backInOut}); @@ -1021,13 +1022,11 @@ class FreeplayState extends MusicBeatSubState new FlxTimer().start(0.4, _ -> { FlxTween.tween(funnyCam, {"zoom": 1}, 0.8, {ease: FlxEase.sineIn}); FlxTween.tween(rankCamera, {"zoom": 1.2}, 0.8, {ease: FlxEase.backIn}); - // IntervalShake.shake(grpCapsules.members[curSelected], 0.8 + 0.5, 1 / 24, 0, 2, FlxEase.quadIn); FlxTween.tween(grpCapsules.members[curSelected], {x: originalPos.x - 7, y: originalPos.y - 80}, 0.8 + 0.5, {ease: FlxEase.quartIn}); }); new FlxTimer().start(0.6, _ -> { rankAnimSlam(fromResults); - // IntervalShake.shake(grpCapsules.members[curSelected].capsule, 0.3, 1 / 30, 0, 0.3, FlxEase.quartIn); }); } @@ -1192,51 +1191,9 @@ class FreeplayState extends MusicBeatSubState // { // rankAnimSlam(fromResultsParams); // } - - if (FlxG.keys.justPressed.G) - { - sparks.y -= 2; - trace(sparks.x, sparks.y); - } - if (FlxG.keys.justPressed.V) - { - sparks.x -= 2; - trace(sparks.x, sparks.y); - } - if (FlxG.keys.justPressed.N) - { - sparks.x += 2; - trace(sparks.x, sparks.y); - } - if (FlxG.keys.justPressed.B) - { - sparks.y += 2; - trace(sparks.x, sparks.y); - } - - if (FlxG.keys.justPressed.I) - { - sparksADD.y -= 2; - trace(sparksADD.x, sparksADD.y); - } - if (FlxG.keys.justPressed.J) - { - sparksADD.x -= 2; - trace(sparksADD.x, sparksADD.y); - } - if (FlxG.keys.justPressed.L) - { - sparksADD.x += 2; - trace(sparksADD.x, sparksADD.y); - } - if (FlxG.keys.justPressed.K) - { - sparksADD.y += 2; - trace(sparksADD.x, sparksADD.y); - } #end - if (FlxG.keys.justPressed.F && !busy) + if (controls.FREEPLAY_FAVORITE && !busy) { var targetSong = grpCapsules.members[curSelected]?.songData; if (targetSong != null) diff --git a/source/funkin/ui/freeplay/LetterSort.hx b/source/funkin/ui/freeplay/LetterSort.hx index e813c9198b..049e9194aa 100644 --- a/source/funkin/ui/freeplay/LetterSort.hx +++ b/source/funkin/ui/freeplay/LetterSort.hx @@ -8,6 +8,7 @@ import flixel.tweens.FlxTween; import flixel.tweens.FlxEase; import flixel.util.FlxColor; import flixel.util.FlxTimer; +import funkin.input.Controls; import funkin.graphics.adobeanimate.FlxAtlasSprite; class LetterSort extends FlxTypedSpriteGroup @@ -69,14 +70,19 @@ class LetterSort extends FlxTypedSpriteGroup changeSelection(0); } + var controls(get, never):Controls; + + inline function get_controls():Controls + return PlayerSettings.player1.controls; + override function update(elapsed:Float):Void { super.update(elapsed); if (inputEnabled) { - if (FlxG.keys.justPressed.E) changeSelection(1); - if (FlxG.keys.justPressed.Q) changeSelection(-1); + if (controls.FREEPLAY_LEFT) changeSelection(-1); + if (controls.FREEPLAY_RIGHT) changeSelection(1); } } diff --git a/source/funkin/ui/options/ControlsMenu.hx b/source/funkin/ui/options/ControlsMenu.hx index dd7d5ff38d..1f40a84556 100644 --- a/source/funkin/ui/options/ControlsMenu.hx +++ b/source/funkin/ui/options/ControlsMenu.hx @@ -28,6 +28,8 @@ class ControlsMenu extends funkin.ui.options.OptionsState.Page [NOTE_UP, NOTE_DOWN, NOTE_LEFT, NOTE_RIGHT], [UI_UP, UI_DOWN, UI_LEFT, UI_RIGHT, ACCEPT, BACK], [CUTSCENE_ADVANCE], + [FREEPLAY_FAVORITE, FREEPLAY_LEFT, FREEPLAY_RIGHT], + [WINDOW_FULLSCREEN, WINDOW_SCREENSHOT], [VOLUME_UP, VOLUME_DOWN, VOLUME_MUTE], [DEBUG_MENU, DEBUG_CHART] ]; @@ -108,6 +110,18 @@ class ControlsMenu extends funkin.ui.options.OptionsState.Page headers.add(new AtlasText(0, y, "CUTSCENE", AtlasFont.BOLD)).screenCenter(X); y += spacer; } + else if (currentHeader != "FREEPLAY_" && name.indexOf("FREEPLAY_") == 0) + { + currentHeader = "FREEPLAY_"; + headers.add(new AtlasText(0, y, "FREEPLAY", AtlasFont.BOLD)).screenCenter(X); + y += spacer; + } + else if (currentHeader != "WINDOW_" && name.indexOf("WINDOW_") == 0) + { + currentHeader = "WINDOW_"; + headers.add(new AtlasText(0, y, "WINDOW", AtlasFont.BOLD)).screenCenter(X); + y += spacer; + } else if (currentHeader != "VOLUME_" && name.indexOf("VOLUME_") == 0) { currentHeader = "VOLUME_"; @@ -123,10 +137,10 @@ class ControlsMenu extends funkin.ui.options.OptionsState.Page if (currentHeader != null && name.indexOf(currentHeader) == 0) name = name.substr(currentHeader.length); - var label = labels.add(new AtlasText(150, y, name, AtlasFont.BOLD)); + var label = labels.add(new AtlasText(100, y, name, AtlasFont.BOLD)); label.alpha = 0.6; for (i in 0...COLUMNS) - createItem(label.x + 400 + i * 300, y, control, i); + createItem(label.x + 550 + i * 400, y, control, i); y += spacer; } diff --git a/source/funkin/util/WindowUtil.hx b/source/funkin/util/WindowUtil.hx index 07f6bc13ad..0fe63fe324 100644 --- a/source/funkin/util/WindowUtil.hx +++ b/source/funkin/util/WindowUtil.hx @@ -92,7 +92,7 @@ class WindowUtil }); openfl.Lib.current.stage.addEventListener(openfl.events.KeyboardEvent.KEY_DOWN, (e:openfl.events.KeyboardEvent) -> { - for (key in PlayerSettings.player1.controls.getKeysForAction(FULLSCREEN)) + for (key in PlayerSettings.player1.controls.getKeysForAction(WINDOW_FULLSCREEN)) { if (e.keyCode == key) { diff --git a/source/funkin/util/plugins/ScreenshotPlugin.hx b/source/funkin/util/plugins/ScreenshotPlugin.hx index 9ac21d4b86..c859710dec 100644 --- a/source/funkin/util/plugins/ScreenshotPlugin.hx +++ b/source/funkin/util/plugins/ScreenshotPlugin.hx @@ -103,7 +103,7 @@ class ScreenshotPlugin extends FlxBasic public function hasPressedScreenshot():Bool { - return PlayerSettings.player1.controls.SCREENSHOT; + return PlayerSettings.player1.controls.WINDOW_SCREENSHOT; } public function updatePreferences():Void From 839d6a0841e0d1ee04f49a14e73c0166f3a9f491 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Sun, 9 Jun 2024 02:27:36 -0400 Subject: [PATCH 197/266] A couple chart fixes --- CHANGELOG.md | 6 ++++++ assets | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35618dca9b..623039e209 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ 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.4.0] - 2024-06-?? +### Changed +- Tweaked the chart for Lit Up some more to fix some offset notes. +### Fixed +- Fixed an issue where M.I.L.F. displayed the wrong difficulty rating in the Freeplay menu. + ## [0.4.0] - 2024-06-06 ### Added - 2 new Erect remixes, Eggnog and Satin Panties. Check them out from the Freeplay menu! diff --git a/assets b/assets index 3b8235e953..84aeb428e0 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 3b8235e953505a6fe7f4ff253f5a99b9a7b9857a +Subproject commit 84aeb428e0bfb967323d250b68e359174be4c38a From 9455b6eadc121b5497fa94c9b1b2ceb31b23d6eb Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sun, 9 Jun 2024 12:41:00 -0400 Subject: [PATCH 198/266] simplified the bug template to have less clutter --- .github/ISSUE_TEMPLATE/bug.md | 56 +++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index efa81b56de..82c121b5a1 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -5,40 +5,46 @@ title: 'Bug Report: [DESCRIBE YOUR BUG IN DETAIL HERE]' labels: bug --- -[weed]: <> (FILL THIS ISSUE THING OUT AS MUCH AS POSSIBLE) -[weed]: <> (OR ELSE YOUR ISSUE WILL BE LESS LIKELY TO BE SOLVED!) -[weed]: <> (DO NOT POST ABOUT ISSUES FROM OTHER FNF MOD ENGINES! I CANNOT AND PROBABLY WON'T SOLVE THOSE!) -[weed]: <> (GO TO THEIR RESPECTIVE GITHUB ISSUES AND REPORT THEM THERE LOL!) + -- [ ] Google Chrome (or chomium based like Brave, vivaldi, MS Edge) -- [ ] Firefox -- [ ] Safari +## Describe the bug + -## What version of the game are you using? Look in the bottom left corner of the main menu. (ex: 0.2.7, 0.2.1, shit like that) +## To Reproduce + +## Expected behavior + +## Screenshots/Video + -## Have you identified any steps to reproduce the bug? If so, please describe them below in as much detail as possible. Use images if possible. +## Desktop + - OS: + + - Browser + + - Version: + -## Please describe your issue. Provide extensive detail and images if possible. +## Additional context + - - -## If you're game is FROZEN and you're playing a web version, press F12 to open up browser dev window, and go to console, and copy-paste whatever red error you're getting + From 9f960f5c284e019e2787a0fe913368db18b68ad7 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sun, 9 Jun 2024 12:43:43 -0400 Subject: [PATCH 199/266] removed compiling help and question templates --- .github/ISSUE_TEMPLATE/compiling.md | 25 ------------------------- .github/ISSUE_TEMPLATE/question.md | 12 ------------ 2 files changed, 37 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/compiling.md delete mode 100644 .github/ISSUE_TEMPLATE/question.md diff --git a/.github/ISSUE_TEMPLATE/compiling.md b/.github/ISSUE_TEMPLATE/compiling.md deleted file mode 100644 index 14aea44a7c..0000000000 --- a/.github/ISSUE_TEMPLATE/compiling.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -name: Compiling help -about: If you need help compiling the game, and you're running into issues. (Look through the 'compiling help' label in case it's been solved!) -title: 'Compiling help: [BRIEF DESCRIPTION / ERROR MESSAGE OUTPUT]' -labels: compiling help ---- - -[weed]: <> (FILL THIS ISSUE THING OUT AS MUCH AS POSSIBLE) -[weed]: <> (OR ELSE YOUR ISSUE WILL BE LESS LIKELY TO BE SOLVED!) -[weed]: <> (DO NOT POST ABOUT ISSUES FROM OTHER FNF MOD ENGINES! I CANNOT AND PROBABLY WON'T SOLVE THOSE!) -[weed]: <> (GO TO THEIR RESPECTIVE GITHUB ISSUES AND REPORT THEM THERE LOL!) - -#### Please check for duplicates or similar compiler issues by filtering for 'compiler help' - -[weed]: <> (Put an X in the [ ] thingies to fill out checkbox!) -[weed]: <> (something like [x] pretty much, don't screw up or you will look stupid) - - -- [ ] Windows -- [ ] Mac -- [ ] Linux -- [ ] HTML5 - -## Please describe your issue. Provide extensive detail and images if possible. - diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md deleted file mode 100644 index a257c217a7..0000000000 --- a/.github/ISSUE_TEMPLATE/question.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -name: Question -about: Ask a general question -title: 'Question: ' -labels: question ---- - -[weed]: <> (This isn't a place for AMA type questions, if you want to ask any of the devs something, reach out to them on twitter prob ) -[weed]: <> (any biz bullshit can go to cameron.taylor.ninja@gmail.com) - -#### Please check for duplicates or similar issues before asking your question. -## What is your question? From bdaadfbfdd7067be46c73bc87a174f72469688f2 Mon Sep 17 00:00:00 2001 From: Ikko Eltociear Ashimine Date: Mon, 10 Jun 2024 02:26:55 +0900 Subject: [PATCH 200/266] chore: update MenuList.hx lenth -> length --- source/funkin/ui/MenuList.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/ui/MenuList.hx b/source/funkin/ui/MenuList.hx index 63a6887781..c815e0adcc 100644 --- a/source/funkin/ui/MenuList.hx +++ b/source/funkin/ui/MenuList.hx @@ -142,7 +142,7 @@ class MenuTypedList extends FlxTypedGroup */ function navGrid(latSize:Int, latPrev:Bool, latNext:Bool, latAllowWrap:Bool, prev:Bool, next:Bool, allowWrap:Bool):Int { - // The grid lenth along the variable-length axis + // The grid length along the variable-length axis var size = Math.ceil(length / latSize); // The selected position along the variable-length axis var index = Math.floor(selectedIndex / latSize); From f2d5a80bd158ffd49c93d272e04083caa9bf0b44 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sun, 9 Jun 2024 15:06:45 -0400 Subject: [PATCH 201/266] completes funk-305 --- source/funkin/ui/freeplay/SongMenuItem.hx | 27 +++++++++++++++++------ 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/source/funkin/ui/freeplay/SongMenuItem.hx b/source/funkin/ui/freeplay/SongMenuItem.hx index dc30b4345f..7708b3bcf9 100644 --- a/source/funkin/ui/freeplay/SongMenuItem.hx +++ b/source/funkin/ui/freeplay/SongMenuItem.hx @@ -219,7 +219,7 @@ class SongMenuItem extends FlxSpriteGroup favIconBlurred.visible = false; add(favIconBlurred); - favIcon = new FlxSprite(380, 40); + favIcon = new FlxSprite(favIconBlurred.x, favIconBlurred.y); favIcon.frames = Paths.getSparrowAtlas('freeplay/favHeart'); favIcon.animation.addByPrefix('fav', 'favorite heart', 24, false); favIcon.animation.play('fav'); @@ -294,21 +294,34 @@ class SongMenuItem extends FlxSpriteGroup } } - // 255, 27 normal - // 220, 27 favourited + /** + * Checks whether the song is favorited, and/or has a rank, and adjusts the clipping + * for the scenario when the text could be too long + */ public function checkClip():Void { var clipSize:Int = 290; var clipType:Int = 0; - if (ranking.visible == true) clipType += 1; - if (favIcon.visible == true) clipType = 2; + if (ranking.visible) + { + favIconBlurred.x = this.x + 370; + favIcon.x = favIconBlurred.x; + clipType += 1; + } + else + { + favIconBlurred.x = favIcon.x = this.x + 405; + } + + if (favIcon.visible) clipType += 1; + switch (clipType) { case 2: - clipSize = 220; + clipSize = 210; case 1: - clipSize = 255; + clipSize = 245; } songText.clipWidth = clipSize; } From 55edb9ea14cc003de542e60e11cc5f3453b0d5da Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sun, 9 Jun 2024 15:38:22 -0400 Subject: [PATCH 202/266] pressing escape on title screen exits game --- source/funkin/ui/title/TitleState.hx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/funkin/ui/title/TitleState.hx b/source/funkin/ui/title/TitleState.hx index c6dbcd5058..8087916cbd 100644 --- a/source/funkin/ui/title/TitleState.hx +++ b/source/funkin/ui/title/TitleState.hx @@ -265,6 +265,13 @@ class TitleState extends MusicBeatState if (FlxG.keys.pressed.DOWN) FlxG.sound.music.pitch -= 0.5 * elapsed; #end + #if desktop + if (FlxG.keys.justPressed.ESCAPE) + { + Sys.exit(0); + } + #end + Conductor.instance.update(); /* if (FlxG.onMobile) From b811aeec803b6689def1ded61df766961e0a5080 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sun, 9 Jun 2024 16:15:33 -0400 Subject: [PATCH 203/266] fix for pico explo --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index d5ab93cb02..6421057faa 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit d5ab93cb024364404dbeb79d0d0228bb06602f13 +Subproject commit 6421057faae19782fcda81349bbdeb40f014323e From 8f44d9606d4cdf5c9935175894a706dcd50319a4 Mon Sep 17 00:00:00 2001 From: gamerbross <55158797+gamerbross@users.noreply.github.com> Date: Mon, 10 Jun 2024 18:04:18 +0200 Subject: [PATCH 204/266] Remove unnecessary scrollMenu sounds + adjust volume --- source/funkin/play/PauseSubState.hx | 5 +++-- source/funkin/ui/MenuList.hx | 2 +- source/funkin/ui/freeplay/FreeplayState.hx | 4 ++-- source/funkin/ui/story/StoryMenuState.hx | 3 ++- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/source/funkin/play/PauseSubState.hx b/source/funkin/play/PauseSubState.hx index 8c45fac650..d0c759b16a 100644 --- a/source/funkin/play/PauseSubState.hx +++ b/source/funkin/play/PauseSubState.hx @@ -449,13 +449,14 @@ class PauseSubState extends MusicBeatSubState */ function changeSelection(change:Int = 0):Void { - FunkinSound.playOnce(Paths.sound('scrollMenu'), 0.4); - + var prevEntry:Int = currentEntry; currentEntry += change; if (currentEntry < 0) currentEntry = currentMenuEntries.length - 1; if (currentEntry >= currentMenuEntries.length) currentEntry = 0; + if (currentEntry != prevEntry) FunkinSound.playOnce(Paths.sound('scrollMenu'), 0.4); + for (entryIndex in 0...currentMenuEntries.length) { var isCurrent:Bool = entryIndex == currentEntry; diff --git a/source/funkin/ui/MenuList.hx b/source/funkin/ui/MenuList.hx index 63a6887781..6fd6063782 100644 --- a/source/funkin/ui/MenuList.hx +++ b/source/funkin/ui/MenuList.hx @@ -94,7 +94,7 @@ class MenuTypedList extends FlxTypedGroup if (newIndex != selectedIndex) { - FunkinSound.playOnce(Paths.sound('scrollMenu')); + FunkinSound.playOnce(Paths.sound('scrollMenu'), 0.4); selectItem(newIndex); } diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 09f79fcfd4..e801099009 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -1833,12 +1833,12 @@ class FreeplayState extends MusicBeatSubState function changeSelection(change:Int = 0):Void { - if (!prepForNewRank) FunkinSound.playOnce(Paths.sound('scrollMenu'), 0.4); - var prevSelected:Int = curSelected; curSelected += change; + if (!prepForNewRank && curSelected != prevSelected) FunkinSound.playOnce(Paths.sound('scrollMenu'), 0.4); + if (curSelected < 0) curSelected = grpCapsules.countLiving() - 1; if (curSelected >= grpCapsules.countLiving()) curSelected = 0; diff --git a/source/funkin/ui/story/StoryMenuState.hx b/source/funkin/ui/story/StoryMenuState.hx index c1a001e5de..06a83ab4db 100644 --- a/source/funkin/ui/story/StoryMenuState.hx +++ b/source/funkin/ui/story/StoryMenuState.hx @@ -387,6 +387,7 @@ class StoryMenuState extends MusicBeatState function changeLevel(change:Int = 0):Void { var currentIndex:Int = levelList.indexOf(currentLevelId); + var prevIndex:Int = currentIndex; currentIndex += change; @@ -417,7 +418,7 @@ class StoryMenuState extends MusicBeatState } } - FunkinSound.playOnce(Paths.sound('scrollMenu'), 0.4); + if (currentIndex != prevIndex) FunkinSound.playOnce(Paths.sound('scrollMenu'), 0.4); updateText(); updateBackground(previousLevelId); From f31ea8fb73ade3a5ff073b4c96b59625be17e8de Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Mon, 10 Jun 2024 16:13:32 -0400 Subject: [PATCH 205/266] add sound for changing sorting --- source/funkin/ui/freeplay/FreeplayState.hx | 1 + 1 file changed, 1 insertion(+) diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index e801099009..c54091d26c 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -602,6 +602,7 @@ class FreeplayState extends MusicBeatSubState // that is, only if there's more than one song in the group! if (grpCapsules.members.length > 0) { + FunkinSound.playOnce(Paths.sound('scrollMenu'), 0.4); curSelected = 1; changeSelection(); } From da61b72c48200faf5276d3f87f347970c4d3221a Mon Sep 17 00:00:00 2001 From: DM-kun <86197998+DMMaster636@users.noreply.github.com> Date: Sat, 8 Jun 2024 19:58:34 +0200 Subject: [PATCH 206/266] crash fix --- source/funkin/play/GameOverSubState.hx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/funkin/play/GameOverSubState.hx b/source/funkin/play/GameOverSubState.hx index ac45dc194b..c84d5b154a 100644 --- a/source/funkin/play/GameOverSubState.hx +++ b/source/funkin/play/GameOverSubState.hx @@ -71,7 +71,7 @@ class GameOverSubState extends MusicBeatSubState var gameOverMusic:Null = null; /** - * Whether the player has confirmed and prepared to restart the level. + * Whether the player has confirmed and prepared to restart the level or to go back to the freeplay menu. * This means the animation and transition have already started. */ var isEnding:Bool = false; @@ -244,8 +244,9 @@ class GameOverSubState extends MusicBeatSubState } // KEYBOARD ONLY: Return to the menu when pressing the assigned key. - if (controls.BACK && !mustNotExit) + if (controls.BACK && !mustNotExit && !isEnding) { + isEnding = true; blueballed = false; PlayState.instance.deathCounter = 0; // PlayState.seenCutscene = false; // old thing... From f91f4b2ddba32357ee7a4f4c3bae5cb99c5f2974 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sun, 9 Jun 2024 12:41:00 -0400 Subject: [PATCH 207/266] simplified the bug template to have less clutter --- .github/ISSUE_TEMPLATE/bug.md | 56 +++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index 733656a118..82c121b5a1 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -5,40 +5,46 @@ title: 'Bug Report: [DESCRIBE YOUR BUG IN DETAIL HERE]' labels: bug --- -[weed]: <> (FILL THIS ISSUE THING OUT AS MUCH AS POSSIBLE) -[weed]: <> (OR ELSE YOUR ISSUE WILL BE LESS LIKELY TO BE SOLVED!) -[weed]: <> (DO NOT POST ABOUT ISSUES FROM OTHER FNF MOD ENGINES! I CANNOT AND PROBABLY WON'T SOLVE THOSE!) -[weed]: <> (GO TO THEIR RESPECTIVE GITHUB ISSUES AND REPORT THEM THERE LOL!) + -- [ ] Google Chrome (or chomium based like Brave, vivaldi, MS Edge) -- [ ] Firefox -- [ ] Safari +## Describe the bug + -## What version of the game are you using? Look in the bottom left corner of the main menu. (ex: 0.2.7, 0.2.1, shit like that) +## To Reproduce + +## Expected behavior + +## Screenshots/Video + -## Have you identified any steps to reproduce the bug? If so, please describe them below in as much detail as possible. Use images if possible. +## Desktop + - OS: + + - Browser + + - Version: + -## Please describe your issue. Provide extensive detail and images if possible. +## Additional context + - - -## If your game is FROZEN and you're playing a web version, press F12 to open up browser dev window, and go to console, and copy-paste whatever red error you're getting + From 13d49017ac4bd55fcd59003f38cedc58da7167af Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sun, 9 Jun 2024 12:43:43 -0400 Subject: [PATCH 208/266] removed compiling help and question templates --- .github/ISSUE_TEMPLATE/compiling.md | 25 ------------------------- .github/ISSUE_TEMPLATE/question.md | 12 ------------ 2 files changed, 37 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/compiling.md delete mode 100644 .github/ISSUE_TEMPLATE/question.md diff --git a/.github/ISSUE_TEMPLATE/compiling.md b/.github/ISSUE_TEMPLATE/compiling.md deleted file mode 100644 index 14aea44a7c..0000000000 --- a/.github/ISSUE_TEMPLATE/compiling.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -name: Compiling help -about: If you need help compiling the game, and you're running into issues. (Look through the 'compiling help' label in case it's been solved!) -title: 'Compiling help: [BRIEF DESCRIPTION / ERROR MESSAGE OUTPUT]' -labels: compiling help ---- - -[weed]: <> (FILL THIS ISSUE THING OUT AS MUCH AS POSSIBLE) -[weed]: <> (OR ELSE YOUR ISSUE WILL BE LESS LIKELY TO BE SOLVED!) -[weed]: <> (DO NOT POST ABOUT ISSUES FROM OTHER FNF MOD ENGINES! I CANNOT AND PROBABLY WON'T SOLVE THOSE!) -[weed]: <> (GO TO THEIR RESPECTIVE GITHUB ISSUES AND REPORT THEM THERE LOL!) - -#### Please check for duplicates or similar compiler issues by filtering for 'compiler help' - -[weed]: <> (Put an X in the [ ] thingies to fill out checkbox!) -[weed]: <> (something like [x] pretty much, don't screw up or you will look stupid) - - -- [ ] Windows -- [ ] Mac -- [ ] Linux -- [ ] HTML5 - -## Please describe your issue. Provide extensive detail and images if possible. - diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md deleted file mode 100644 index a257c217a7..0000000000 --- a/.github/ISSUE_TEMPLATE/question.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -name: Question -about: Ask a general question -title: 'Question: ' -labels: question ---- - -[weed]: <> (This isn't a place for AMA type questions, if you want to ask any of the devs something, reach out to them on twitter prob ) -[weed]: <> (any biz bullshit can go to cameron.taylor.ninja@gmail.com) - -#### Please check for duplicates or similar issues before asking your question. -## What is your question? From e8f8a0c1819297c8ce9ac92517dd61978b6be6c8 Mon Sep 17 00:00:00 2001 From: Ikko Eltociear Ashimine Date: Mon, 10 Jun 2024 02:26:55 +0900 Subject: [PATCH 209/266] chore: update MenuList.hx lenth -> length --- source/funkin/ui/MenuList.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/ui/MenuList.hx b/source/funkin/ui/MenuList.hx index 6fd6063782..d7319abd6c 100644 --- a/source/funkin/ui/MenuList.hx +++ b/source/funkin/ui/MenuList.hx @@ -142,7 +142,7 @@ class MenuTypedList extends FlxTypedGroup */ function navGrid(latSize:Int, latPrev:Bool, latNext:Bool, latAllowWrap:Bool, prev:Bool, next:Bool, allowWrap:Bool):Int { - // The grid lenth along the variable-length axis + // The grid length along the variable-length axis var size = Math.ceil(length / latSize); // The selected position along the variable-length axis var index = Math.floor(selectedIndex / latSize); From 00021523bc1f1d7f99fc436a6d16e32a26dbcdb9 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sun, 9 Jun 2024 15:17:41 -0400 Subject: [PATCH 210/266] lower volume on freeplay easter egg --- source/funkin/ui/freeplay/DJBoyfriend.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/ui/freeplay/DJBoyfriend.hx b/source/funkin/ui/freeplay/DJBoyfriend.hx index bd2f73e422..bbf043dd48 100644 --- a/source/funkin/ui/freeplay/DJBoyfriend.hx +++ b/source/funkin/ui/freeplay/DJBoyfriend.hx @@ -266,7 +266,7 @@ class DJBoyfriend extends FlxAtlasSprite // Fade out music to 40% volume over 1 second. // This helps make the TV a bit more audible. - FlxG.sound.music.fadeOut(1.0, 0.4); + FlxG.sound.music.fadeOut(1.0, 0.1); // Play the cartoon at a random time between the start and 5 seconds from the end. cartoonSnd.time = FlxG.random.float(0, Math.max(cartoonSnd.length - (5 * Constants.MS_PER_SEC), 0.0)); From c0a7e4f728d38a9717000164d893fde61f49aafe Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Mon, 10 Jun 2024 19:32:53 -0400 Subject: [PATCH 211/266] Readd camera events to Roses --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 84aeb428e0..54eb4feaf7 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 84aeb428e0bfb967323d250b68e359174be4c38a +Subproject commit 54eb4feaf7b740dbe1988cb35debc97bdff372b8 From b30faad7d9b5c659c14db2694ac7b5938606a3e1 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 11 Jun 2024 00:40:43 -0400 Subject: [PATCH 212/266] Save high scores and high ranks separately. --- source/funkin/play/PlayState.hx | 29 +++-- source/funkin/play/scoring/Scoring.hx | 144 ++++++++++++--------- source/funkin/save/Save.hx | 102 ++++++++++++++- source/funkin/ui/freeplay/FreeplayState.hx | 14 +- source/funkin/ui/mainmenu/MainMenuState.hx | 27 ++++ source/funkin/util/FileUtil.hx | 1 + 6 files changed, 244 insertions(+), 73 deletions(-) diff --git a/source/funkin/play/PlayState.hx b/source/funkin/play/PlayState.hx index b3d0a9f8a0..ad7a398d4d 100644 --- a/source/funkin/play/PlayState.hx +++ b/source/funkin/play/PlayState.hx @@ -2284,7 +2284,7 @@ class PlayState extends MusicBeatSubState health += Constants.HEALTH_HOLD_BONUS_PER_SECOND * elapsed; songScore += Std.int(Constants.SCORE_HOLD_BONUS_PER_SECOND * elapsed); } - + // Make sure the player keeps singing while the note is held by the bot. if (isBotPlayMode && currentStage != null && currentStage.getBoyfriend() != null && currentStage.getBoyfriend().isSinging()) { @@ -2818,8 +2818,13 @@ class PlayState extends MusicBeatSubState deathCounter = 0; + // TODO: This line of code makes me sad, but you can't really fix it without a breaking migration. + // `easy`, `erect`, `normal-pico`, etc. + var suffixedDifficulty = (currentVariation != Constants.DEFAULT_VARIATION + && currentVariation != 'erect') ? '$currentDifficulty-${currentVariation}' : currentDifficulty; + var isNewHighscore = false; - var prevScoreData:Null = Save.instance.getSongScore(currentSong.id, currentDifficulty); + var prevScoreData:Null = Save.instance.getSongScore(currentSong.id, suffixedDifficulty); if (currentSong != null && currentSong.validScore) { @@ -2844,13 +2849,21 @@ class PlayState extends MusicBeatSubState // adds current song data into the tallies for the level (story levels) Highscore.talliesLevel = Highscore.combineTallies(Highscore.tallies, Highscore.talliesLevel); - if (!isPracticeMode && !isBotPlayMode && Save.instance.isSongHighScore(currentSong.id, currentDifficulty, data)) + if (!isPracticeMode && !isBotPlayMode) { - Save.instance.setSongScore(currentSong.id, currentDifficulty, data); - #if newgrounds - NGio.postScore(score, currentSong.id); - #end - isNewHighscore = true; + isNewHighscore = Save.instance.isSongHighScore(currentSong.id, suffixedDifficulty, data); + + // If no high score is present, save both score and rank. + // If score or rank are better, save the highest one. + // If neither are higher, nothing will change. + Save.instance.applySongRank(currentSong.id, suffixedDifficulty, data); + + if (isNewHighscore) + { + #if newgrounds + NGio.postScore(score, currentSong.id); + #end + } } } diff --git a/source/funkin/play/scoring/Scoring.hx b/source/funkin/play/scoring/Scoring.hx index d6f71fc7e0..dc2c406475 100644 --- a/source/funkin/play/scoring/Scoring.hx +++ b/source/funkin/play/scoring/Scoring.hx @@ -356,7 +356,10 @@ class Scoring // Perfect (Platinum) is a Sick Full Clear var isPerfectGold = scoreData.tallies.sick == scoreData.tallies.totalNotes; - if (isPerfectGold) return ScoringRank.PERFECT_GOLD; + if (isPerfectGold) + { + return ScoringRank.PERFECT_GOLD; + } // Else, use the standard grades @@ -397,62 +400,79 @@ enum abstract ScoringRank(String) var GOOD; var SHIT; - @:op(A > B) static function compare(a:Null, b:Null):Bool + /** + * Converts ScoringRank to an integer value for comparison. + * Better ranks should be tied to a higher value. + */ + static function getValue(rank:Null):Int { - if (a != null && b == null) return true; - if (a == null || b == null) return false; - - var temp1:Int = 0; - var temp2:Int = 0; - - // temp 1 - switch (a) + if (rank == null) return -1; + switch (rank) { case PERFECT_GOLD: - temp1 = 5; + return 5; case PERFECT: - temp1 = 4; + return 4; case EXCELLENT: - temp1 = 3; + return 3; case GREAT: - temp1 = 2; + return 2; case GOOD: - temp1 = 1; + return 1; case SHIT: - temp1 = 0; + return 0; default: - temp1 = -1; + return -1; } + } - // temp 2 - switch (b) - { - case PERFECT_GOLD: - temp2 = 5; - case PERFECT: - temp2 = 4; - case EXCELLENT: - temp2 = 3; - case GREAT: - temp2 = 2; - case GOOD: - temp2 = 1; - case SHIT: - temp2 = 0; - default: - temp2 = -1; - } + // Yes, we really need a different function for each comparison operator. + @:op(A > B) static function compareGT(a:Null, b:Null):Bool + { + if (a != null && b == null) return true; + if (a == null || b == null) return false; - if (temp1 > temp2) - { - return true; - } - else - { - return false; - } + var temp1:Int = getValue(a); + var temp2:Int = getValue(b); + + return temp1 > temp2; } + @:op(A >= B) static function compareGTEQ(a:Null, b:Null):Bool + { + if (a != null && b == null) return true; + if (a == null || b == null) return false; + + var temp1:Int = getValue(a); + var temp2:Int = getValue(b); + + return temp1 >= temp2; + } + + @:op(A < B) static function compareLT(a:Null, b:Null):Bool + { + if (a != null && b == null) return true; + if (a == null || b == null) return false; + + var temp1:Int = getValue(a); + var temp2:Int = getValue(b); + + return temp1 < temp2; + } + + @:op(A <= B) static function compareLTEQ(a:Null, b:Null):Bool + { + if (a != null && b == null) return true; + if (a == null || b == null) return false; + + var temp1:Int = getValue(a); + var temp2:Int = getValue(b); + + return temp1 <= temp2; + } + + // @:op(A == B) isn't necessary! + /** * Delay in seconds */ @@ -462,15 +482,15 @@ enum abstract ScoringRank(String) { case PERFECT_GOLD | PERFECT: // return 2.5; - return 95/24; + return 95 / 24; case EXCELLENT: return 0; case GREAT: - return 5/24; + return 5 / 24; case GOOD: - return 3/24; + return 3 / 24; case SHIT: - return 2/24; + return 2 / 24; default: return 3.5; } @@ -482,15 +502,15 @@ enum abstract ScoringRank(String) { case PERFECT_GOLD | PERFECT: // return 2.5; - return 95/24; + return 95 / 24; case EXCELLENT: - return 97/24; + return 97 / 24; case GREAT: - return 95/24; + return 95 / 24; case GOOD: - return 95/24; + return 95 / 24; case SHIT: - return 95/24; + return 95 / 24; default: return 3.5; } @@ -502,15 +522,15 @@ enum abstract ScoringRank(String) { case PERFECT_GOLD | PERFECT: // return 2.5; - return 129/24; + return 129 / 24; case EXCELLENT: - return 122/24; + return 122 / 24; case GREAT: - return 109/24; + return 109 / 24; case GOOD: - return 107/24; + return 107 / 24; case SHIT: - return 186/24; + return 186 / 24; default: return 3.5; } @@ -522,15 +542,15 @@ enum abstract ScoringRank(String) { case PERFECT_GOLD | PERFECT: // return 2.5; - return 140/24; + return 140 / 24; case EXCELLENT: - return 140/24; + return 140 / 24; case GREAT: - return 129/24; + return 129 / 24; case GOOD: - return 127/24; + return 127 / 24; case SHIT: - return 207/24; + return 207 / 24; default: return 3.5; } diff --git a/source/funkin/save/Save.hx b/source/funkin/save/Save.hx index 2ff6b96cc1..2900ce2be6 100644 --- a/source/funkin/save/Save.hx +++ b/source/funkin/save/Save.hx @@ -1,6 +1,7 @@ package funkin.save; import flixel.util.FlxSave; +import funkin.util.FileUtil; import funkin.input.Controls.Device; import funkin.play.scoring.Scoring; import funkin.play.scoring.Scoring.ScoringRank; @@ -58,7 +59,7 @@ class Save this.data = data; // Make sure the verison number is up to date before we flush. - this.data.version = Save.SAVE_DATA_VERSION; + updateVersionToLatest(); } public static function getDefault():RawSaveData @@ -503,7 +504,7 @@ class Save } /** - * Apply the score the user achieved for a given song on a given difficulty. + * Directly set the score the user achieved for a given song on a given difficulty. */ public function setSongScore(songId:String, difficultyId:String, score:SaveScoreData):Void { @@ -518,6 +519,44 @@ class Save flush(); } + /** + * Only replace the ranking data for the song, because the old score is still better. + */ + public function applySongRank(songId:String, difficultyId:String, newScoreData:SaveScoreData):Void + { + var newRank = Scoring.calculateRank(newScoreData); + if (newScoreData == null || newRank == null) return; + + var song = data.scores.songs.get(songId); + if (song == null) + { + song = []; + data.scores.songs.set(songId, song); + } + + var previousScoreData = song.get(difficultyId); + + var previousRank = Scoring.calculateRank(previousScoreData); + + if (previousScoreData == null || previousRank == null) + { + // Directly set the highscore. + setSongScore(songId, difficultyId, newScoreData); + return; + } + + // Set the high score and the high rank separately. + var newScore:SaveScoreData = + { + score: (previousScoreData.score > newScoreData.score) ? previousScoreData.score : newScoreData.score, + tallies: (previousRank > newRank) ? previousScoreData.tallies : newScoreData.tallies + }; + + song.set(difficultyId, newScore); + + flush(); + } + /** * Is the provided score data better than the current high score for the given song? * @param songId The song ID to check. @@ -543,6 +582,39 @@ class Save return score.score > currentScore.score; } + /** + * Is the provided score data better than the current rank for the given song? + * @param songId The song ID to check. + * @param difficultyId The difficulty to check. + * @param score The score to check the rank for. + * @return Whether the score's rank is better than the current rank. + */ + public function isSongHighRank(songId:String, difficultyId:String = 'normal', score:SaveScoreData):Bool + { + var newScoreRank = Scoring.calculateRank(score); + if (newScoreRank == null) + { + // The provided score is invalid. + return false; + } + + var song = data.scores.songs.get(songId); + if (song == null) + { + song = []; + data.scores.songs.set(songId, song); + } + var currentScore = song.get(difficultyId); + var currentScoreRank = Scoring.calculateRank(currentScore); + if (currentScoreRank == null) + { + // There is no primary highscore for this song. + return true; + } + + return newScoreRank > currentScoreRank; + } + /** * Has the provided song been beaten on one of the listed difficulties? * @param songId The song ID to check. @@ -832,6 +904,29 @@ class Save return cast legacySave.data; } } + + /** + * Serialize this Save into a JSON string. + * @param pretty Whether the JSON should be big ol string (false), + * or formatted with tabs (true) + * @return The JSON string. + */ + public function serialize(pretty:Bool = true):String + { + var ignoreNullOptionals = true; + var writer = new json2object.JsonWriter(ignoreNullOptionals); + return writer.write(data, pretty ? ' ' : null); + } + + public function updateVersionToLatest():Void + { + this.data.version = Save.SAVE_DATA_VERSION; + } + + public function debug_dumpSave():Void + { + FileUtil.saveFile(haxe.io.Bytes.ofString(this.serialize()), [FileUtil.FILE_FILTER_JSON], null, null, './save.json', 'Write save data as JSON...'); + } } /** @@ -904,6 +999,9 @@ typedef SaveHighScoresData = typedef SaveDataMods = { var enabledMods:Array; + + // TODO: Make this not trip up the serializer when debugging. + @:jignored var modOptions:Map; } diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index c54091d26c..f0ca9a9425 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -1608,7 +1608,19 @@ class FreeplayState extends MusicBeatSubState var daSong:Null = grpCapsules.members[curSelected].songData; if (daSong != null) { - var songScore:SaveScoreData = Save.instance.getSongScore(grpCapsules.members[curSelected].songData.songId, currentDifficulty); + // TODO: Make this actually be the variation you're focused on. We don't need to fetch the song metadata just to calculate it. + var targetSong:Song = SongRegistry.instance.fetchEntry(grpCapsules.members[curSelected].songData.songId); + if (targetSong == null) + { + FlxG.log.warn('WARN: could not find song with id (${grpCapsules.members[curSelected].songData.songId})'); + return; + } + var targetVariation:String = targetSong.getFirstValidVariation(currentDifficulty); + + // TODO: This line of code makes me sad, but you can't really fix it without a breaking migration. + var suffixedDifficulty = (targetVariation != Constants.DEFAULT_VARIATION + && targetVariation != 'erect') ? '$currentDifficulty-${targetVariation}' : currentDifficulty; + var songScore:SaveScoreData = Save.instance.getSongScore(grpCapsules.members[curSelected].songData.songId, suffixedDifficulty); intendedScore = songScore?.score ?? 0; intendedCompletion = songScore == null ? 0.0 : ((songScore.tallies.sick + songScore.tallies.good) / songScore.tallies.totalNotes); rememberedDifficulty = currentDifficulty; diff --git a/source/funkin/ui/mainmenu/MainMenuState.hx b/source/funkin/ui/mainmenu/MainMenuState.hx index b6ec25e618..d09536eea2 100644 --- a/source/funkin/ui/mainmenu/MainMenuState.hx +++ b/source/funkin/ui/mainmenu/MainMenuState.hx @@ -371,6 +371,33 @@ class MainMenuState extends MusicBeatState } }); } + + if (FlxG.keys.pressed.CONTROL && FlxG.keys.pressed.ALT && FlxG.keys.pressed.SHIFT && FlxG.keys.justPressed.R) + { + // Give the user a hypothetical overridden score, + // and see if we can maintain that golden P rank. + funkin.save.Save.instance.setSongScore('tutorial', 'easy', + { + score: 1234567, + tallies: + { + sick: 0, + good: 0, + bad: 0, + shit: 1, + missed: 0, + combo: 0, + maxCombo: 0, + totalNotesHit: 1, + totalNotes: 10, + } + }); + } + + if (FlxG.keys.pressed.CONTROL && FlxG.keys.pressed.ALT && FlxG.keys.pressed.SHIFT && FlxG.keys.justPressed.E) + { + funkin.save.Save.instance.debug_dumpSave(); + } #end if (FlxG.sound.music != null && FlxG.sound.music.volume < 0.8) diff --git a/source/funkin/util/FileUtil.hx b/source/funkin/util/FileUtil.hx index 7a7b1422cf..00a0a14b76 100644 --- a/source/funkin/util/FileUtil.hx +++ b/source/funkin/util/FileUtil.hx @@ -19,6 +19,7 @@ import haxe.ui.containers.dialogs.Dialogs.FileDialogExtensionInfo; class FileUtil { public static final FILE_FILTER_FNFC:FileFilter = new FileFilter("Friday Night Funkin' Chart (.fnfc)", "*.fnfc"); + public static final FILE_FILTER_JSON:FileFilter = new FileFilter("JSON Data File (.json)", "*.json"); public static final FILE_FILTER_ZIP:FileFilter = new FileFilter("ZIP Archive (.zip)", "*.zip"); public static final FILE_FILTER_PNG:FileFilter = new FileFilter("PNG Image (.png)", "*.png"); From f48a65e9cebc754a721de00dbb2ad26c4f9869f0 Mon Sep 17 00:00:00 2001 From: tposejank <81495861+tposejank@users.noreply.github.com> Date: Tue, 11 Jun 2024 02:09:56 -0400 Subject: [PATCH 213/266] Remove question & compiling help --- .github/ISSUE_TEMPLATE/compiling.yml | 42 ---------------------------- .github/ISSUE_TEMPLATE/question.yml | 8 ------ 2 files changed, 50 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/compiling.yml delete mode 100644 .github/ISSUE_TEMPLATE/question.yml diff --git a/.github/ISSUE_TEMPLATE/compiling.yml b/.github/ISSUE_TEMPLATE/compiling.yml deleted file mode 100644 index d446b64b4e..0000000000 --- a/.github/ISSUE_TEMPLATE/compiling.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Compiling help -description: If you need help compiling the game, and you're running into issues. -labels: ["compiling help"] -title: "Compiling help: " -body: - - type: checkboxes - attributes: - label: Issue Checklist - options: - - label: I have properly named the issue - - label: I looked in issues/discussions, if it has been previously reported - - - type: dropdown - attributes: - label: What platform are you compiling to? - options: - - Windows - - MacOS - - Linux - - HTML5 - validations: - required: true - - - type: markdown - attributes: - value: "## Describe the issue." - - - type: markdown - attributes: - value: "### Please do not report issues from other engines. These must be reported in their repositories." - - - type: markdown - attributes: - value: "#### Provide as many details as you can." - - - type: textarea - attributes: - label: Context (Provide images, videos, etc.) - - - type: textarea - attributes: - label: Steps to reproduce (or crash logs, errors, etc.) diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml deleted file mode 100644 index c6e6e1b116..0000000000 --- a/.github/ISSUE_TEMPLATE/question.yml +++ /dev/null @@ -1,8 +0,0 @@ -name: Question -description: Ask a general question -labels: ["question"] -title: "Question: " -body: - - type: textarea - attributes: - label: What is your question? From 93c0bd0b634a44466239ea79886be21a46bce1f2 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 11 Jun 2024 11:25:43 -0400 Subject: [PATCH 214/266] assets submod --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 54eb4feaf7..c22ed15e83 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 54eb4feaf7b740dbe1988cb35debc97bdff372b8 +Subproject commit c22ed15e83182f628d7830773021e3e48c596174 From 37a15e0a0fd9e1825680fb4fb9eb2a42922157ac Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 11 Jun 2024 12:13:10 -0400 Subject: [PATCH 215/266] reactive speaker to gamevolume on desktop --- source/funkin/audio/visualize/ABotVis.hx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/funkin/audio/visualize/ABotVis.hx b/source/funkin/audio/visualize/ABotVis.hx index a455cb8a2b..cf43a8add8 100644 --- a/source/funkin/audio/visualize/ABotVis.hx +++ b/source/funkin/audio/visualize/ABotVis.hx @@ -101,6 +101,10 @@ class ABotVis extends FlxTypedSpriteGroup { var animFrame:Int = Math.round(levels[i].value * 5); + #if desktop + animFrame = Math.round(animFrame * FlxG.sound.volume); + #end + animFrame = Math.floor(Math.min(5, animFrame)); animFrame = Math.floor(Math.max(0, animFrame)); From 1e3ef61fc9e34675c48189a106d6aae37cb885ad Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Tue, 11 Jun 2024 15:57:45 -0400 Subject: [PATCH 216/266] freeplay bg nicer AA and proper sizing --- source/funkin/graphics/shaders/AngleMask.hx | 76 +++++++++++++++------ source/funkin/ui/freeplay/FreeplayState.hx | 19 ++++-- 2 files changed, 70 insertions(+), 25 deletions(-) diff --git a/source/funkin/graphics/shaders/AngleMask.hx b/source/funkin/graphics/shaders/AngleMask.hx index 30e508a580..c5ef87b720 100644 --- a/source/funkin/graphics/shaders/AngleMask.hx +++ b/source/funkin/graphics/shaders/AngleMask.hx @@ -5,35 +5,73 @@ import flixel.system.FlxAssets.FlxShader; class AngleMask extends FlxShader { @:glFragmentSource(' - #pragma header - uniform vec2 endPosition; - void main() - { - vec4 base = texture2D(bitmap, openfl_TextureCoordv); + #pragma header - vec2 uv = openfl_TextureCoordv.xy; + uniform vec2 endPosition; + vec2 hash22(vec2 p) { + vec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973)); + p3 += dot(p3, p3.yzx + 33.33); + return fract((p3.xx + p3.yz) * p3.zy); + } - vec2 start = vec2(0.0, 0.0); - vec2 end = vec2(endPosition.x / openfl_TextureSize.x, 1.0); + // ====== GAMMA CORRECTION ====== // + // Helps with color mixing -- good to have by default in almost any shader + // See https://www.shadertoy.com/view/lscSzl + vec3 gamma(in vec3 color) { + return pow(color, vec3(1.0 / 2.2)); + } - float dx = end.x - start.x; - float dy = end.y - start.y; + vec4 mainPass(vec2 fragCoord) { + vec4 base = texture2D(bitmap, fragCoord); - float angle = atan(dy, dx); + vec2 uv = fragCoord.xy; - uv.x -= start.x; - uv.y -= start.y; + vec2 start = vec2(0.0, 0.0); + vec2 end = vec2(endPosition.x / openfl_TextureSize.x, 1.0); - float uvA = atan(uv.y, uv.x); + float dx = end.x - start.x; + float dy = end.y - start.y; - if (uvA < angle) - gl_FragColor = base; - else - gl_FragColor = vec4(0.0); + float angle = atan(dy, dx); - }') + uv.x -= start.x; + uv.y -= start.y; + + float uvA = atan(uv.y, uv.x); + + if (uvA < angle) + return base; + else + return vec4(0.0); + } + + vec4 antialias(vec2 fragCoord) { + + const float AA_STAGES = 2.0; + + const float AA_TOTAL_PASSES = AA_STAGES * AA_STAGES + 1.0; + const float AA_JITTER = 0.5; + + // Run the shader multiple times with a random subpixel offset each time and average the results + vec4 color = mainPass(fragCoord); + for (float x = 0.0; x < AA_STAGES; x++) + { + for (float y = 0.0; y < AA_STAGES; y++) + { + vec2 offset = AA_JITTER * (2.0 * hash22(vec2(x, y)) - 1.0) / openfl_TextureSize.xy; + color += mainPass(fragCoord + offset); + } + } + return color / AA_TOTAL_PASSES; + } + + void main() { + vec4 col = antialias(openfl_TextureCoordv); + // col.xyz = gamma(col.xyz); + gl_FragColor = col; + }') public function new() { super(); diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 06684ae7c2..1149aec0ca 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -458,15 +458,20 @@ class FreeplayState extends MusicBeatSubState add(dj); - bgDad = new FlxSprite(pinkBack.width * 0.75, 0).loadGraphic(Paths.image('freeplay/freeplayBGdad')); - bgDad.setGraphicSize(0, FlxG.height); - bgDad.updateHitbox(); + bgDad = new FlxSprite(pinkBack.width * 0.74, 0).loadGraphic(Paths.image('freeplay/freeplayBGdad')); bgDad.shader = new AngleMask(); bgDad.visible = false; var blackOverlayBullshitLOLXD:FlxSprite = new FlxSprite(FlxG.width).makeGraphic(Std.int(bgDad.width), Std.int(bgDad.height), FlxColor.BLACK); add(blackOverlayBullshitLOLXD); // used to mask the text lol! + // this makes the texture sizes consistent, for the angle shader + bgDad.setGraphicSize(0, FlxG.height); + blackOverlayBullshitLOLXD.setGraphicSize(0, FlxG.height); + + bgDad.updateHitbox(); + blackOverlayBullshitLOLXD.updateHitbox(); + exitMovers.set([blackOverlayBullshitLOLXD, bgDad], { x: FlxG.width * 1.5, @@ -475,7 +480,7 @@ class FreeplayState extends MusicBeatSubState }); add(bgDad); - FlxTween.tween(blackOverlayBullshitLOLXD, {x: pinkBack.width * 0.76}, 0.7, {ease: FlxEase.quintOut}); + FlxTween.tween(blackOverlayBullshitLOLXD, {x: pinkBack.width * 0.74}, 0.7, {ease: FlxEase.quintOut}); blackOverlayBullshitLOLXD.shader = bgDad.shader; @@ -971,13 +976,15 @@ class FreeplayState extends MusicBeatSubState grpCapsules.members[curSelected].ranking.scale.set(20, 20); grpCapsules.members[curSelected].blurredRanking.scale.set(20, 20); - if (fromResults?.newRank != null) { + if (fromResults?.newRank != null) + { grpCapsules.members[curSelected].ranking.animation.play(fromResults.newRank.getFreeplayRankIconAsset(), true); } FlxTween.tween(grpCapsules.members[curSelected].ranking, {"scale.x": 1, "scale.y": 1}, 0.1); - if (fromResults?.newRank != null) { + if (fromResults?.newRank != null) + { grpCapsules.members[curSelected].blurredRanking.animation.play(fromResults.newRank.getFreeplayRankIconAsset(), true); } FlxTween.tween(grpCapsules.members[curSelected].blurredRanking, {"scale.x": 1, "scale.y": 1}, 0.1); From 47f885ae97f37eaf0f165c377dc76f41df260ba0 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Wed, 12 Jun 2024 13:33:19 -0400 Subject: [PATCH 217/266] Charter credits for Eggnog Erect --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index c22ed15e83..2e1594ee4c 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit c22ed15e83182f628d7830773021e3e48c596174 +Subproject commit 2e1594ee4c04c7148628bae471bdd061c9deb6b7 From 1ebcae79fe186e0f5aa4c1d917a017c810981c4b Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 12 Jun 2024 13:14:24 -0400 Subject: [PATCH 218/266] changelog for 0.4.1 --- CHANGELOG.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78391c2750..1e331cf27a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,21 @@ 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.4.1] +## [0.4.1] - 2024-06-12 +### Added +- Pressing ESCAPE on the title screen on desktop now exits the game, allowing you to exit the game while in fullscreen on desktop ### Changed - Tweaked the chart for Lit Up some more to fix some offset notes. +- A-Bot speaker now reacts to the user's volume preference on desktop (thanks to [M7theguy for the issue report/suggestion](https://github.com/FunkinCrew/Funkin/issues/2744)!) +- On Freeplay, heart icons are shifted to the right when you favorite a song that has no rank on it. +- Only play `scrollMenu` sound effect when there's a real change on the freeplay menu ([thanks gamerbross for the PR!](https://github.com/FunkinCrew/Funkin/pull/2741)) ### Fixed -- Bug where Dadbattle shows up as Dadbattle Erect when returning to freeplay +- Fixed crash when attempting to exit the gameover screen when also attempting to retry the song ([thanks DMMaster636 for the PR!](https://github.com/FunkinCrew/Funkin/pull/2709)) +- Fix botplay sustain release bug ([thanks Hundrec!](Fix botplay sustain release bug #2683)) +- Fix for the camera not pausing during a gameplay pause ([thanks gamerbross!](https://github.com/FunkinCrew/Funkin/pull/2684)) +- Fixed issue where Pico's gameplay sprite would unintentionally appear on the gameover screen when dying on 2Hot from an explosion +- Freeplay previews properly fade volume during the BF idle animation +- Fixed bug where Dadbattle incorrectly appeared as Dadbattle Erect when returning to freeplay on Hard - Fixed 2Hot not appearing under the "#" category in Freeplay menu - Fixed a bug where the Chart Editor would crash when attempting to select an event with the Event toolbox open - Improved offsets for Pico and Tankman opponents so they don't slide around as much. From f8ecddc5b313d555d4fefa33dd570ad57be598a8 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 12 Jun 2024 13:19:31 -0400 Subject: [PATCH 219/266] added eric code to changelog --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e331cf27a..9997ca4bc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,12 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.4.1] - 2024-06-12 ### Added - Pressing ESCAPE on the title screen on desktop now exits the game, allowing you to exit the game while in fullscreen on desktop +- Freeplay menu controls are now rebindable ### Changed +- Highscores and ranks are now saved separately, which fixes the issue where people would overwrite their saves with higher scores, +which would remove their rank if they had a lower one. - Tweaked the chart for Lit Up some more to fix some offset notes. - A-Bot speaker now reacts to the user's volume preference on desktop (thanks to [M7theguy for the issue report/suggestion](https://github.com/FunkinCrew/Funkin/issues/2744)!) - On Freeplay, heart icons are shifted to the right when you favorite a song that has no rank on it. - Only play `scrollMenu` sound effect when there's a real change on the freeplay menu ([thanks gamerbross for the PR!](https://github.com/FunkinCrew/Funkin/pull/2741)) +- Gave antialiasing to the edge of the dad graphic on Freeplay +- Rearranged some controls in the controls menu ### Fixed +- Fixed an issue in the controls menu where some control binds would overlap their names - Fixed crash when attempting to exit the gameover screen when also attempting to retry the song ([thanks DMMaster636 for the PR!](https://github.com/FunkinCrew/Funkin/pull/2709)) - Fix botplay sustain release bug ([thanks Hundrec!](Fix botplay sustain release bug #2683)) - Fix for the camera not pausing during a gameplay pause ([thanks gamerbross!](https://github.com/FunkinCrew/Funkin/pull/2684)) @@ -23,6 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed a bug where the Chart Editor would crash when attempting to select an event with the Event toolbox open - Improved offsets for Pico and Tankman opponents so they don't slide around as much. - Fixed an issue where M.I.L.F. displayed the wrong difficulty rating in the Freeplay menu. +- Fixed the black "temp" graphic on freeplay from being incorrectly sized / masked, now it's identical to the dad freeplay graphic From 7ce0544b18e2d227739052f9d7bf0798f8a905b4 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 12 Jun 2024 13:25:00 -0400 Subject: [PATCH 220/266] Update CHANGELOG.md --- CHANGELOG.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9997ca4bc4..054f01f49a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.4.1] - 2024-06-12 ### Added - Pressing ESCAPE on the title screen on desktop now exits the game, allowing you to exit the game while in fullscreen on desktop -- Freeplay menu controls are now rebindable +- Freeplay menu controls (favoriting and switching categories) are now rebindable from the Options menu, and now have default binds on controllers. ### Changed - Highscores and ranks are now saved separately, which fixes the issue where people would overwrite their saves with higher scores, which would remove their rank if they had a lower one. @@ -17,6 +17,10 @@ which would remove their rank if they had a lower one. - Only play `scrollMenu` sound effect when there's a real change on the freeplay menu ([thanks gamerbross for the PR!](https://github.com/FunkinCrew/Funkin/pull/2741)) - Gave antialiasing to the edge of the dad graphic on Freeplay - Rearranged some controls in the controls menu +- Made several chart revisions + - Re-enabled custom camera events in Roses (Erect/Nightmare) + - Tweaked the chart for Lit Up (Hard) + - Corrected the difficulty ratings for M.I.L.F. (Easy/Normal/Hard) ### Fixed - Fixed an issue in the controls menu where some control binds would overlap their names - Fixed crash when attempting to exit the gameover screen when also attempting to retry the song ([thanks DMMaster636 for the PR!](https://github.com/FunkinCrew/Funkin/pull/2709)) @@ -28,11 +32,8 @@ which would remove their rank if they had a lower one. - Fixed 2Hot not appearing under the "#" category in Freeplay menu - Fixed a bug where the Chart Editor would crash when attempting to select an event with the Event toolbox open - Improved offsets for Pico and Tankman opponents so they don't slide around as much. -- Fixed an issue where M.I.L.F. displayed the wrong difficulty rating in the Freeplay menu. - Fixed the black "temp" graphic on freeplay from being incorrectly sized / masked, now it's identical to the dad freeplay graphic - - ## [0.4.0] - 2024-06-06 ### Added - 2 new Erect remixes, Eggnog and Satin Panties. Check them out from the Freeplay menu! From 48653ababd38c56a82a22e8e01855c7222ea25ce Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 12 Jun 2024 14:56:15 -0400 Subject: [PATCH 221/266] Update CHANGELOG.md --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 054f01f49a..755b3b3bcf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Highscores and ranks are now saved separately, which fixes the issue where people would overwrite their saves with higher scores, which would remove their rank if they had a lower one. -- Tweaked the chart for Lit Up some more to fix some offset notes. - A-Bot speaker now reacts to the user's volume preference on desktop (thanks to [M7theguy for the issue report/suggestion](https://github.com/FunkinCrew/Funkin/issues/2744)!) - On Freeplay, heart icons are shifted to the right when you favorite a song that has no rank on it. - Only play `scrollMenu` sound effect when there's a real change on the freeplay menu ([thanks gamerbross for the PR!](https://github.com/FunkinCrew/Funkin/pull/2741)) From cce2ab7fff202bb74e358966e42028f27ee11268 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 12 Jun 2024 15:05:32 -0400 Subject: [PATCH 222/266] update project.xml for 0.4.1 lol --- Project.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.xml b/Project.xml index e0e25883dd..fae9c768bd 100644 --- a/Project.xml +++ b/Project.xml @@ -2,7 +2,7 @@ - + From 9908f973cf1ec322a11ada5e8928992d6cf8bc2b Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 12 Jun 2024 15:27:56 -0400 Subject: [PATCH 223/266] someone pls tell me how to use two different git submodules --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 452c0089b7..be5e0aaa81 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 From 7a2b023f307c673d212ddec1817e97ef8933167e Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 12 Jun 2024 15:29:44 -0400 Subject: [PATCH 224/266] gitmodules for dev repo --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index be5e0aaa81..452c0089b7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "assets"] path = assets - url = https://github.com/FunkinCrew/funkin.assets + url = https://github.com/FunkinCrew/Funkin-Assets-secret [submodule "art"] path = art - url = https://github.com/FunkinCrew/funkin.art + url = https://github.com/FunkinCrew/Funkin-Art-secret From 80981eee3733c3507250a37e2bff9807a481aa0c Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 12 Jun 2024 15:41:42 -0400 Subject: [PATCH 225/266] inputs null fix --- source/funkin/input/Controls.hx | 370 +++++++++++++++++++------------- 1 file changed, 218 insertions(+), 152 deletions(-) diff --git a/source/funkin/input/Controls.hx b/source/funkin/input/Controls.hx index e2cae56130..f6c881f6df 100644 --- a/source/funkin/input/Controls.hx +++ b/source/funkin/input/Controls.hx @@ -31,6 +31,7 @@ class Controls extends FlxActionSet * Uses FlxActions to funnel various inputs to a single action. */ var _ui_up = new FunkinAction(Action.UI_UP); + var _ui_left = new FunkinAction(Action.UI_LEFT); var _ui_right = new FunkinAction(Action.UI_RIGHT); var _ui_down = new FunkinAction(Action.UI_DOWN); @@ -325,19 +326,18 @@ class Controls extends FlxActionSet add(_volume_down); add(_volume_mute); - for (action in digitalActions) { - if (Std.isOfType(action, FunkinAction)) { + for (action in digitalActions) + { + if (Std.isOfType(action, FunkinAction)) + { var funkinAction:FunkinAction = cast action; byName[funkinAction.name] = funkinAction; - if (funkinAction.namePressed != null) - byName[funkinAction.namePressed] = funkinAction; - if (funkinAction.nameReleased != null) - byName[funkinAction.nameReleased] = funkinAction; + if (funkinAction.namePressed != null) byName[funkinAction.namePressed] = funkinAction; + if (funkinAction.nameReleased != null) byName[funkinAction.nameReleased] = funkinAction; } } - if (scheme == null) - scheme = None; + if (scheme == null) scheme = None; setKeyboardScheme(scheme, false); } @@ -350,38 +350,38 @@ class Controls extends FlxActionSet public function check(name:Action, trigger:FlxInputState = JUST_PRESSED, gamepadOnly:Bool = false):Bool { #if debug - if (!byName.exists(name)) - throw 'Invalid name: $name'; + if (!byName.exists(name)) throw 'Invalid name: $name'; #end var action = byName[name]; - if (gamepadOnly) - return action.checkFiltered(trigger, GAMEPAD); + if (gamepadOnly) return action.checkFiltered(trigger, GAMEPAD); else return action.checkFiltered(trigger); } - public function getKeysForAction(name:Action):Array { + public function getKeysForAction(name:Action):Array + { #if debug - if (!byName.exists(name)) - throw 'Invalid name: $name'; + if (!byName.exists(name)) throw 'Invalid name: $name'; #end // TODO: Revert to `.map().filter()` once HashLink doesn't complain anymore. var result:Array = []; - for (input in byName[name].inputs) { + for (input in byName[name].inputs) + { if (input.device == KEYBOARD) result.push(input.inputID); } return result; } - public function getButtonsForAction(name:Action):Array { + public function getButtonsForAction(name:Action):Array + { #if debug - if (!byName.exists(name)) - throw 'Invalid name: $name'; + if (!byName.exists(name)) throw 'Invalid name: $name'; #end var result:Array = []; - for (input in byName[name].inputs) { + for (input in byName[name].inputs) + { if (input.device == GAMEPAD) result.push(input.inputID); } return result; @@ -405,7 +405,7 @@ class Controls extends FlxActionSet function getActionFromControl(control:Control):FlxActionDigital { - return switch(control) + return switch (control) { case UI_UP: _ui_up; case UI_DOWN: _ui_down; @@ -448,7 +448,7 @@ class Controls extends FlxActionSet */ function forEachBound(control:Control, func:FlxActionDigital->FlxInputState->Void) { - switch(control) + switch (control) { case UI_UP: func(_ui_up, PRESSED); @@ -519,10 +519,9 @@ class Controls extends FlxActionSet public function replaceBinding(control:Control, device:Device, toAdd:Int, toRemove:Int) { - if (toAdd == toRemove) - return; + if (toAdd == toRemove) return; - switch(device) + switch (device) { case Keys: forEachBound(control, function(action, state) replaceKey(action, toAdd, toRemove, state)); @@ -534,7 +533,8 @@ class Controls extends FlxActionSet function replaceKey(action:FlxActionDigital, toAdd:FlxKey, toRemove:FlxKey, state:FlxInputState) { - if (action.inputs.length == 0) { + if (action.inputs.length == 0) + { // Add the keybind, don't replace. addKeys(action, [toAdd], state); return; @@ -548,34 +548,44 @@ class Controls extends FlxActionSet if (input.device == KEYBOARD && input.inputID == toRemove) { - if (toAdd == FlxKey.NONE) { + if (toAdd == FlxKey.NONE) + { // Remove the keybind, don't replace. action.inputs.remove(input); - } else { + } + else + { // Replace the keybind. @:privateAccess action.inputs[i].inputID = toAdd; } hasReplaced = true; - } else if (input.device == KEYBOARD && input.inputID == toAdd) { + } + else if (input.device == KEYBOARD && input.inputID == toAdd) + { // This key is already bound! - if (hasReplaced) { + if (hasReplaced) + { // Remove the duplicate keybind, don't replace. action.inputs.remove(input); - } else { + } + else + { hasReplaced = true; } } } - if (!hasReplaced) { + if (!hasReplaced) + { addKeys(action, [toAdd], state); } } function replaceButton(action:FlxActionDigital, deviceID:Int, toAdd:FlxGamepadInputID, toRemove:FlxGamepadInputID, state:FlxInputState) { - if (action.inputs.length == 0) { + if (action.inputs.length == 0) + { addButtons(action, [toAdd], state, deviceID); return; } @@ -594,7 +604,8 @@ class Controls extends FlxActionSet } } - if (!hasReplaced) { + if (!hasReplaced) + { addButtons(action, [toAdd], state, deviceID); } } @@ -606,18 +617,16 @@ class Controls extends FlxActionSet var action = controls.byName[name]; for (input in action.inputs) { - if (device == null || isDevice(input, device)) - byName[name].add(cast input); + if (device == null || isDevice(input, device)) byName[name].add(cast input); } } - switch(device) + switch (device) { case null: // add all for (gamepad in controls.gamepadsAdded) - if (gamepadsAdded.indexOf(gamepad) == -1) - gamepadsAdded.push(gamepad); + if (gamepadsAdded.indexOf(gamepad) == -1) gamepadsAdded.push(gamepad); mergeKeyboardScheme(controls.keyboardScheme); @@ -637,7 +646,7 @@ class Controls extends FlxActionSet { if (scheme != None) { - switch(keyboardScheme) + switch (keyboardScheme) { case None: keyboardScheme = scheme; @@ -672,7 +681,8 @@ class Controls extends FlxActionSet static function addKeys(action:FlxActionDigital, keys:Array, state:FlxInputState) { - for (key in keys) { + for (key in keys) + { if (key == FlxKey.NONE) continue; // Ignore unbound keys. action.addKey(key, state); } @@ -684,15 +694,13 @@ class Controls extends FlxActionSet while (i-- > 0) { var input = action.inputs[i]; - if (input.device == KEYBOARD && keys.indexOf(cast input.inputID) != -1) - action.remove(input); + if (input.device == KEYBOARD && keys.indexOf(cast input.inputID) != -1) action.remove(input); } } public function setKeyboardScheme(scheme:KeyboardScheme, reset = true) { - if (reset) - removeKeyboard(); + if (reset) removeKeyboard(); keyboardScheme = scheme; @@ -724,10 +732,13 @@ class Controls extends FlxActionSet bindMobileLol(); } - function getDefaultKeybinds(scheme:KeyboardScheme, control:Control):Array { - switch (scheme) { + function getDefaultKeybinds(scheme:KeyboardScheme, control:Control):Array + { + switch (scheme) + { case Solo: - switch (control) { + switch (control) + { case Control.UI_UP: return [W, FlxKey.UP]; case Control.UI_DOWN: return [S, FlxKey.DOWN]; case Control.UI_LEFT: return [A, FlxKey.LEFT]; @@ -754,7 +765,8 @@ class Controls extends FlxActionSet case Control.VOLUME_MUTE: return [ZERO, NUMPADZERO]; } case Duo(true): - switch (control) { + switch (control) + { case Control.UI_UP: return [W]; case Control.UI_DOWN: return [S]; case Control.UI_LEFT: return [A]; @@ -779,10 +791,10 @@ class Controls extends FlxActionSet case Control.VOLUME_UP: return [PLUS]; case Control.VOLUME_DOWN: return [MINUS]; case Control.VOLUME_MUTE: return [ZERO]; - } case Duo(false): - switch (control) { + switch (control) + { case Control.UI_UP: return [FlxKey.UP]; case Control.UI_DOWN: return [FlxKey.DOWN]; case Control.UI_LEFT: return [FlxKey.LEFT]; @@ -807,7 +819,6 @@ class Controls extends FlxActionSet case Control.VOLUME_UP: return [NUMPADPLUS]; case Control.VOLUME_DOWN: return [NUMPADMINUS]; case Control.VOLUME_MUTE: return [NUMPADZERO]; - } default: // Fallthrough. @@ -834,8 +845,7 @@ class Controls extends FlxActionSet #end #if android - forEachBound(Control.BACK, function(action, pres) - { + forEachBound(Control.BACK, function(action, pres) { action.add(new FlxActionInputDigitalAndroid(FlxAndroidKey.BACK, JUST_PRESSED)); }); #end @@ -849,8 +859,7 @@ class Controls extends FlxActionSet while (i-- > 0) { var input = action.inputs[i]; - if (input.device == KEYBOARD) - action.remove(input); + if (input.device == KEYBOARD) action.remove(input); } } } @@ -862,11 +871,13 @@ class Controls extends FlxActionSet fromSaveData(padData, Gamepad(id)); } - public function getGamepadIds():Array { + public function getGamepadIds():Array + { return gamepadsAdded; } - public function getGamepads():Array { + public function getGamepads():Array + { return [for (id in gamepadsAdded) FlxG.gamepads.getByID(id)]; } @@ -886,8 +897,7 @@ class Controls extends FlxActionSet while (i-- > 0) { var input = action.inputs[i]; - if (isGamepad(input, deviceID)) - action.remove(input); + if (isGamepad(input, deviceID)) action.remove(input); } } @@ -924,32 +934,58 @@ class Controls extends FlxActionSet ]); } - function getDefaultGamepadBinds(control:Control):Array { - switch(control) { - case Control.ACCEPT: return [#if switch B #else A #end]; - case Control.BACK: return [#if switch A #else B #end]; - case Control.UI_UP: return [DPAD_UP, LEFT_STICK_DIGITAL_UP]; - case Control.UI_DOWN: return [DPAD_DOWN, LEFT_STICK_DIGITAL_DOWN]; - case Control.UI_LEFT: return [DPAD_LEFT, LEFT_STICK_DIGITAL_LEFT]; - case Control.UI_RIGHT: return [DPAD_RIGHT, LEFT_STICK_DIGITAL_RIGHT]; - case Control.NOTE_UP: return [DPAD_UP, Y, LEFT_STICK_DIGITAL_UP, RIGHT_STICK_DIGITAL_UP]; - case Control.NOTE_DOWN: return [DPAD_DOWN, A, LEFT_STICK_DIGITAL_DOWN, RIGHT_STICK_DIGITAL_DOWN]; - case Control.NOTE_LEFT: return [DPAD_LEFT, X, LEFT_STICK_DIGITAL_LEFT, RIGHT_STICK_DIGITAL_LEFT]; - case Control.NOTE_RIGHT: return [DPAD_RIGHT, B, LEFT_STICK_DIGITAL_RIGHT, RIGHT_STICK_DIGITAL_RIGHT]; - case Control.PAUSE: return [START]; - case Control.RESET: return [FlxGamepadInputID.BACK]; // Back (i.e. Select) - case Control.WINDOW_FULLSCREEN: []; - case Control.WINDOW_SCREENSHOT: []; - case Control.CUTSCENE_ADVANCE: return [A]; - case Control.FREEPLAY_FAVORITE: [FlxGamepadInputID.BACK]; // Back (i.e. Select) - case Control.FREEPLAY_LEFT: [LEFT_SHOULDER]; - case Control.FREEPLAY_RIGHT: [RIGHT_SHOULDER]; - case Control.VOLUME_UP: []; - case Control.VOLUME_DOWN: []; - case Control.VOLUME_MUTE: []; - case Control.DEBUG_MENU: []; - case Control.DEBUG_CHART: []; - case Control.DEBUG_STAGE: []; + function getDefaultGamepadBinds(control:Control):Array + { + switch (control) + { + case Control.ACCEPT: + return [#if switch B #else A #end]; + case Control.BACK: + return [#if switch A #else B #end]; + case Control.UI_UP: + return [DPAD_UP, LEFT_STICK_DIGITAL_UP]; + case Control.UI_DOWN: + return [DPAD_DOWN, LEFT_STICK_DIGITAL_DOWN]; + case Control.UI_LEFT: + return [DPAD_LEFT, LEFT_STICK_DIGITAL_LEFT]; + case Control.UI_RIGHT: + return [DPAD_RIGHT, LEFT_STICK_DIGITAL_RIGHT]; + case Control.NOTE_UP: + return [DPAD_UP, Y, LEFT_STICK_DIGITAL_UP, RIGHT_STICK_DIGITAL_UP]; + case Control.NOTE_DOWN: + return [DPAD_DOWN, A, LEFT_STICK_DIGITAL_DOWN, RIGHT_STICK_DIGITAL_DOWN]; + case Control.NOTE_LEFT: + return [DPAD_LEFT, X, LEFT_STICK_DIGITAL_LEFT, RIGHT_STICK_DIGITAL_LEFT]; + case Control.NOTE_RIGHT: + return [DPAD_RIGHT, B, LEFT_STICK_DIGITAL_RIGHT, RIGHT_STICK_DIGITAL_RIGHT]; + case Control.PAUSE: + return [START]; + case Control.RESET: + return [FlxGamepadInputID.BACK]; // Back (i.e. Select) + case Control.WINDOW_FULLSCREEN: + []; + case Control.WINDOW_SCREENSHOT: + []; + case Control.CUTSCENE_ADVANCE: + return [A]; + case Control.FREEPLAY_FAVORITE: + [FlxGamepadInputID.BACK]; // Back (i.e. Select) + case Control.FREEPLAY_LEFT: + [LEFT_SHOULDER]; + case Control.FREEPLAY_RIGHT: + [RIGHT_SHOULDER]; + case Control.VOLUME_UP: + []; + case Control.VOLUME_DOWN: + []; + case Control.VOLUME_MUTE: + []; + case Control.DEBUG_MENU: + []; + case Control.DEBUG_CHART: + []; + case Control.DEBUG_STAGE: + []; default: // Fallthrough. } @@ -967,8 +1003,7 @@ class Controls extends FlxActionSet public function touchShit(control:Control, id) { - forEachBound(control, function(action, state) - { + forEachBound(control, function(action, state) { // action }); } @@ -984,7 +1019,8 @@ class Controls extends FlxActionSet inline static function addButtons(action:FlxActionDigital, buttons:Array, state, id) { - for (button in buttons) { + for (button in buttons) + { if (button == FlxGamepadInputID.NONE) continue; // Ignore unbound keys. action.addGamepad(button, state, id); } @@ -996,29 +1032,25 @@ class Controls extends FlxActionSet while (i-- > 0) { var input = action.inputs[i]; - if (isGamepad(input, gamepadID) && buttons.indexOf(cast input.inputID) != -1) - action.remove(input); + if (isGamepad(input, gamepadID) && buttons.indexOf(cast input.inputID) != -1) action.remove(input); } } public function getInputsFor(control:Control, device:Device, ?list:Array):Array { - if (list == null) - list = []; + if (list == null) list = []; - switch(device) + switch (device) { case Keys: for (input in getActionFromControl(control).inputs) { - if (input.device == KEYBOARD) - list.push(input.inputID); + if (input.device == KEYBOARD) list.push(input.inputID); } case Gamepad(id): for (input in getActionFromControl(control).inputs) { - if (isGamepad(input, id)) - list.push(input.inputID); + if (isGamepad(input, id)) list.push(input.inputID); } } return list; @@ -1026,7 +1058,7 @@ class Controls extends FlxActionSet public function removeDevice(device:Device) { - switch(device) + switch (device) { case Keys: setKeyboardScheme(None); @@ -1040,27 +1072,32 @@ class Controls extends FlxActionSet * An EMPTY array means the control is uninitialized and needs to be reset to default. * An array with a single FlxKey.NONE means the control was intentionally unbound by the user. */ - public function fromSaveData(data:Dynamic, device:Device) + public function fromSaveData(data:Dynamic, device:Device):Void { for (control in Control.createAll()) { var inputs:Array = Reflect.field(data, control.getName()); - inputs = inputs.distinct(); + inputs = inputs?.distinct(); if (inputs != null) { - if (inputs.length == 0) { + if (inputs.length == 0) + { trace('Control ${control} is missing bindings, resetting to default.'); - switch(device) + switch (device) { case Keys: bindKeys(control, getDefaultKeybinds(Solo, control)); case Gamepad(id): bindButtons(control, id, getDefaultGamepadBinds(control)); } - } else if (inputs == [FlxKey.NONE]) { + } + else if (inputs == [FlxKey.NONE]) + { trace('Control ${control} is unbound, leaving it be.'); - } else { - switch(device) + } + else + { + switch (device) { case Keys: bindKeys(control, inputs.copy()); @@ -1068,9 +1105,11 @@ class Controls extends FlxActionSet bindButtons(control, id, inputs.copy()); } } - } else { + } + else + { trace('Control ${control} is missing bindings, resetting to default.'); - switch(device) + switch (device) { case Keys: bindKeys(control, getDefaultKeybinds(Solo, control)); @@ -1095,9 +1134,12 @@ class Controls extends FlxActionSet var inputs = getInputsFor(control, device); isEmpty = isEmpty && inputs.length == 0; - if (inputs.length == 0) { + if (inputs.length == 0) + { inputs = [FlxKey.NONE]; - } else { + } + else + { inputs = inputs.distinct(); } @@ -1109,7 +1151,7 @@ class Controls extends FlxActionSet static function isDevice(input:FlxActionInput, device:Device) { - return switch(device) + return switch (device) { case Keys: input.device == KEYBOARD; case Gamepad(id): isGamepad(input, id); @@ -1141,7 +1183,8 @@ typedef Swipes = * - Combining `pressed` and `released` inputs into one action. * - Filtering by input method (`KEYBOARD`, `MOUSE`, `GAMEPAD`, etc). */ -class FunkinAction extends FlxActionDigital { +class FunkinAction extends FlxActionDigital +{ public var namePressed(default, null):Null; public var nameReleased(default, null):Null; @@ -1158,83 +1201,102 @@ class FunkinAction extends FlxActionDigital { /** * Input checks default to whether the input was just pressed, on any input device. */ - public override function check():Bool { + public override function check():Bool + { return checkFiltered(JUST_PRESSED); } /** * Check whether the input is currently being held. */ - public function checkPressed():Bool { + public function checkPressed():Bool + { return checkFiltered(PRESSED); } /** * Check whether the input is currently being held, and was not held last frame. */ - public function checkJustPressed():Bool { + public function checkJustPressed():Bool + { return checkFiltered(JUST_PRESSED); } /** * Check whether the input is not currently being held. */ - public function checkReleased():Bool { + public function checkReleased():Bool + { return checkFiltered(RELEASED); } /** * Check whether the input is not currently being held, and was held last frame. */ - public function checkJustReleased():Bool { + public function checkJustReleased():Bool + { return checkFiltered(JUST_RELEASED); } /** * Check whether the input is currently being held by a gamepad device. */ - public function checkPressedGamepad():Bool { + public function checkPressedGamepad():Bool + { return checkFiltered(PRESSED, GAMEPAD); } /** * Check whether the input is currently being held by a gamepad device, and was not held last frame. */ - public function checkJustPressedGamepad():Bool { + public function checkJustPressedGamepad():Bool + { return checkFiltered(JUST_PRESSED, GAMEPAD); } /** * Check whether the input is not currently being held by a gamepad device. */ - public function checkReleasedGamepad():Bool { + public function checkReleasedGamepad():Bool + { return checkFiltered(RELEASED, GAMEPAD); } /** * Check whether the input is not currently being held by a gamepad device, and was held last frame. */ - public function checkJustReleasedGamepad():Bool { + public function checkJustReleasedGamepad():Bool + { return checkFiltered(JUST_RELEASED, GAMEPAD); } - public function checkMultiFiltered(?filterTriggers:Array, ?filterDevices:Array):Bool { - if (filterTriggers == null) { + public function checkMultiFiltered(?filterTriggers:Array, ?filterDevices:Array):Bool + { + if (filterTriggers == null) + { filterTriggers = [PRESSED, JUST_PRESSED]; } - if (filterDevices == null) { + if (filterDevices == null) + { filterDevices = []; } // Perform checkFiltered for each combination. - for (i in filterTriggers) { - if (filterDevices.length == 0) { - if (checkFiltered(i)) { + for (i in filterTriggers) + { + if (filterDevices.length == 0) + { + if (checkFiltered(i)) + { return true; } - } else { - for (j in filterDevices) { - if (checkFiltered(i, j)) { + } + else + { + for (j in filterDevices) + { + if (checkFiltered(i, j)) + { return true; } } @@ -1249,52 +1311,56 @@ class FunkinAction extends FlxActionDigital { * @param filterTrigger Optionally filter by trigger condition (`JUST_PRESSED`, `PRESSED`, `JUST_RELEASED`, `RELEASED`). * @param filterDevice Optionally filter by device (`KEYBOARD`, `MOUSE`, `GAMEPAD`, `OTHER`). */ - public function checkFiltered(?filterTrigger:FlxInputState, ?filterDevice:FlxInputDevice):Bool { + public function checkFiltered(?filterTrigger:FlxInputState, ?filterDevice:FlxInputDevice):Bool + { // The normal // Make sure we only update the inputs once per frame. var key = '${filterTrigger}:${filterDevice}'; var cacheEntry = cache.get(key); - if (cacheEntry != null && cacheEntry.timestamp == FlxG.game.ticks) { + if (cacheEntry != null && cacheEntry.timestamp == FlxG.game.ticks) + { return cacheEntry.value; } // Use a for loop instead so we can remove inputs while iterating. // We don't return early because we need to call check() on ALL inputs. var result = false; - var len = inputs != null ? inputs.length : 0; - for (i in 0...len) - { - var j = len - i - 1; - var input = inputs[j]; + var len = inputs != null ? inputs.length : 0; + for (i in 0...len) + { + var j = len - i - 1; + var input = inputs[j]; // Filter out dead inputs. - if (input.destroyed) - { - inputs.splice(j, 1); - continue; - } + if (input.destroyed) + { + inputs.splice(j, 1); + continue; + } // Update the input. input.update(); // Check whether the input is the right trigger. - if (filterTrigger != null && input.trigger != filterTrigger) { + if (filterTrigger != null && input.trigger != filterTrigger) + { continue; } // Check whether the input is the right device. - if (filterDevice != null && input.device != filterDevice) { + if (filterDevice != null && input.device != filterDevice) + { continue; } // Check whether the input has triggered. - if (input.check(this)) - { - result = true; - } - } + if (input.check(this)) + { + result = true; + } + } // We need to cache this result. cache.set(key, {timestamp: FlxG.game.ticks, value: result}); @@ -1391,12 +1457,12 @@ class FlxActionInputDigitalMobileSwipeGameplay extends FlxActionInputDigital { var degAngle = FlxAngle.asDegrees(swp.touchAngle); - switch(trigger) + switch (trigger) { case JUST_PRESSED: if (swp.touchLength >= activateLength) { - switch(inputID) + switch (inputID) { case FlxDirectionFlags.UP: if (degAngle >= 45 && degAngle <= 90 + 45) return properTouch(swp); @@ -1440,7 +1506,7 @@ class FlxActionInputDigitalAndroid extends FlxActionInputDigital override public function check(Action:FlxAction):Bool { - return switch(trigger) + return switch (trigger) { #if android case PRESSED: FlxG.android.checkStatus(inputID, PRESSED) || FlxG.android.checkStatus(inputID, PRESSED); From 1c45c9b03b86f2c4dc1049f0a41fd61b5e167af5 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 12 Jun 2024 15:50:59 -0400 Subject: [PATCH 226/266] git modules --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 452c0089b7..be5e0aaa81 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 From a63b60d458bedca9bb980e6d7c8e47b73357adfc Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Wed, 12 Jun 2024 20:31:27 -0400 Subject: [PATCH 227/266] fix for release, no bf printing directly to stdout! --- source/funkin/util/logging/AnsiTrace.hx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/funkin/util/logging/AnsiTrace.hx b/source/funkin/util/logging/AnsiTrace.hx index 9fdc19e1be..2c18d494d2 100644 --- a/source/funkin/util/logging/AnsiTrace.hx +++ b/source/funkin/util/logging/AnsiTrace.hx @@ -51,7 +51,7 @@ class AnsiTrace public static function traceBF() { - #if sys + #if (sys && debug) if (colorSupported) { for (line in ansiBF) From b8c971786486b04663b4cafaf8da88e02296a684 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Fri, 14 Jun 2024 21:52:52 -0700 Subject: [PATCH 228/266] Reorder download Git step in compiling guide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moved “download Git” from the middle of the guide to the setup step Should prevent errors with Git before installing Git --- docs/COMPILING.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/COMPILING.md b/docs/COMPILING.md index e7c19875a7..b8ddee4a70 100644 --- a/docs/COMPILING.md +++ b/docs/COMPILING.md @@ -2,14 +2,14 @@ 0. Setup - Download Haxe from [Haxe.org](https://haxe.org) + - Download Git from [git-scm.com](https://www.git-scm.com) 1. Cloning the Repository: Make sure when you clone, you clone the submodules to get the assets repo: - `git clone --recurse-submodules https://github.com/FunkinCrew/funkin.git` - If you accidentally cloned without the `assets` submodule (aka didn't follow the step above), you can run `git submodule update --init --recursive` to get the assets in a foolproof way. 2. Install `hmm` (run `haxelib --global install hmm` and then `haxelib --global run hmm setup`) -3. Download Git from [git-scm.com](https://www.git-scm.com) -4. Install all haxelibs of the current branch by running `hmm install` -5. Setup lime: `haxelib run lime setup` -6. Platform setup +3. Install all haxelibs of the current branch by running `hmm install` +4. Setup lime: `haxelib run lime setup` +5. 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 @@ -17,8 +17,8 @@ - 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/) - HTML5: Compiles without any extra setup -7. If you are targeting for native, you may need to run `lime rebuild PLATFORM` and `lime rebuild PLATFORM -debug` -8. `lime test PLATFORM` ! Add `-debug` to enable several debug features such as time travel (`PgUp`/`PgDn` in Play State). +6. If you are targeting for native, you may need to run `lime rebuild PLATFORM` and `lime rebuild PLATFORM -debug` +7. `lime test PLATFORM` ! Add `-debug` to enable several debug features such as time travel (`PgUp`/`PgDn` in Play State). # Troubleshooting From 32ad9d159ee46429e582f1bd7c891ccf4cae6138 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Sat, 15 Jun 2024 13:37:21 -0400 Subject: [PATCH 229/266] Add ZIP button warning and restructured sentences Each step should be easier to follow with this structure --- docs/COMPILING.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/COMPILING.md b/docs/COMPILING.md index b8ddee4a70..b2a106c867 100644 --- a/docs/COMPILING.md +++ b/docs/COMPILING.md @@ -3,12 +3,13 @@ 0. Setup - Download Haxe from [Haxe.org](https://haxe.org) - Download Git from [git-scm.com](https://www.git-scm.com) -1. Cloning the Repository: Make sure when you clone, you clone the submodules to get the assets repo: - - `git clone --recurse-submodules https://github.com/FunkinCrew/funkin.git` - - If you accidentally cloned without the `assets` submodule (aka didn't follow the step above), you can run `git submodule update --init --recursive` to get the assets in a foolproof way. -2. Install `hmm` (run `haxelib --global install hmm` and then `haxelib --global run hmm setup`) -3. Install all haxelibs of the current branch by running `hmm install` -4. Setup lime: `haxelib run lime setup` + - Do NOT download the repository using the Download ZIP button on GitHub or you may run into errors! + - Instead, open a command prompt and do the following steps... +1. Run `git clone --recurse-submodules https://github.com/FunkinCrew/funkin.git` to clone the repository with the necessary assets submodule + - _If you accidentally cloned without the `assets` submodule (aka didn't follow the step above), you can run `git submodule update --init --recursive` to get the assets in a foolproof way._ +2. Run `haxelib --global install hmm` and then `haxelib --global run hmm setup` to install hmm.json +3. Run `hmm install` to install all haxelibs of the current branch +4. Run `haxelib run lime setup` to set up lime 5. 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: From 9bd09e37915300ca595950a6dcc2b215f7dcf077 Mon Sep 17 00:00:00 2001 From: Eric Date: Sun, 16 Jun 2024 18:48:01 -0400 Subject: [PATCH 230/266] Make downloading the assets submodule a separate step. --- docs/COMPILING.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/COMPILING.md b/docs/COMPILING.md index b2a106c867..cc90bd348e 100644 --- a/docs/COMPILING.md +++ b/docs/COMPILING.md @@ -5,8 +5,9 @@ - Download Git from [git-scm.com](https://www.git-scm.com) - Do NOT download the repository using the Download ZIP button on GitHub or you may run into errors! - Instead, open a command prompt and do the following steps... -1. Run `git clone --recurse-submodules https://github.com/FunkinCrew/funkin.git` to clone the repository with the necessary assets submodule - - _If you accidentally cloned without the `assets` submodule (aka didn't follow the step above), you can run `git submodule update --init --recursive` to get the assets in a foolproof way._ +1. Run `git clone https://github.com/FunkinCrew/funkin.git` to clone the base repository. +2. Run `git submodule update --init --recursive` to download the game's assets. + - 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. 2. Run `haxelib --global install hmm` and then `haxelib --global run hmm setup` to install hmm.json 3. Run `hmm install` to install all haxelibs of the current branch 4. Run `haxelib run lime setup` to set up lime From 5cde06bc8687d6eae12bbbb18b1a3a673a0549fa Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sun, 9 Jun 2024 12:41:00 -0400 Subject: [PATCH 231/266] simplified the bug template to have less clutter From 4b354f6f32abb20f1d0cb1be3b787a3310eed190 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sun, 9 Jun 2024 12:41:00 -0400 Subject: [PATCH 232/266] simplified the bug template to have less clutter --- .github/ISSUE_TEMPLATE/bug.md | 50 +++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug.md diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md new file mode 100644 index 0000000000..82c121b5a1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -0,0 +1,50 @@ +--- +name: Bug Report +about: Report a bug or critical performance issue +title: 'Bug Report: [DESCRIBE YOUR BUG IN DETAIL HERE]' +labels: bug +--- + + + +## Describe the bug + + +## To Reproduce + +## Expected behavior + + +## Screenshots/Video + + +## Desktop + - OS: + + - Browser + + - Version: + + +## Additional context + + + From ac08f5518dd957a9e720063041069c6070a0f00d Mon Sep 17 00:00:00 2001 From: tposejank <81495861+tposejank@users.noreply.github.com> Date: Mon, 17 Jun 2024 00:45:00 -0400 Subject: [PATCH 233/266] Thanks, Git! --- .github/ISSUE_TEMPLATE/bug.md | 50 ----------------------------------- 1 file changed, 50 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug.md diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md deleted file mode 100644 index 82c121b5a1..0000000000 --- a/.github/ISSUE_TEMPLATE/bug.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -name: Bug Report -about: Report a bug or critical performance issue -title: 'Bug Report: [DESCRIBE YOUR BUG IN DETAIL HERE]' -labels: bug ---- - - - -## Describe the bug - - -## To Reproduce - -## Expected behavior - - -## Screenshots/Video - - -## Desktop - - OS: - - - Browser - - - Version: - - -## Additional context - - - From 60f6e5ec50b4a98923e1bdea0104d742aed7b507 Mon Sep 17 00:00:00 2001 From: Cameron Taylor Date: Sun, 9 Jun 2024 12:41:00 -0400 Subject: [PATCH 234/266] simplified the bug template to have less clutter --- .github/ISSUE_TEMPLATE/bug.md | 50 +++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug.md diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md new file mode 100644 index 0000000000..82c121b5a1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -0,0 +1,50 @@ +--- +name: Bug Report +about: Report a bug or critical performance issue +title: 'Bug Report: [DESCRIBE YOUR BUG IN DETAIL HERE]' +labels: bug +--- + + + +## Describe the bug + + +## To Reproduce + +## Expected behavior + + +## Screenshots/Video + + +## Desktop + - OS: + + - Browser + + - Version: + + +## Additional context + + + From 3c81f93ca2a191d7682e1472a42baf2674ea743c Mon Sep 17 00:00:00 2001 From: tposejank <81495861+tposejank@users.noreply.github.com> Date: Mon, 17 Jun 2024 00:47:46 -0400 Subject: [PATCH 235/266] will you --- .github/ISSUE_TEMPLATE/bug.md | 51 +---------------------------------- 1 file changed, 1 insertion(+), 50 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index 82c121b5a1..45b983be36 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -1,50 +1 @@ ---- -name: Bug Report -about: Report a bug or critical performance issue -title: 'Bug Report: [DESCRIBE YOUR BUG IN DETAIL HERE]' -labels: bug ---- - - - -## Describe the bug - - -## To Reproduce - -## Expected behavior - - -## Screenshots/Video - - -## Desktop - - OS: - - - Browser - - - Version: - - -## Additional context - - - +hi From b5c4a8589aa1d29aeaca4b892aef5f8d78838691 Mon Sep 17 00:00:00 2001 From: tposejank <81495861+tposejank@users.noreply.github.com> Date: Mon, 17 Jun 2024 00:49:09 -0400 Subject: [PATCH 236/266] Delete --- .github/ISSUE_TEMPLATE/bug.md | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug.md diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md deleted file mode 100644 index 32f95c0d12..0000000000 --- a/.github/ISSUE_TEMPLATE/bug.md +++ /dev/null @@ -1 +0,0 @@ -hi \ No newline at end of file From 37b8c881a8809ffd8b192afec9f336a798fa8eb2 Mon Sep 17 00:00:00 2001 From: tposejank <81495861+tposejank@users.noreply.github.com> Date: Mon, 17 Jun 2024 01:06:14 -0400 Subject: [PATCH 237/266] Fulfill requests & new crash template --- .github/ISSUE_TEMPLATE/bug.yml | 4 +- .github/ISSUE_TEMPLATE/crash.yml | 69 +++++++++++++++++++ .github/ISSUE_TEMPLATE/enhancement.yml | 2 +- .github/PULL_REQUEST_TEMPLATE/bug.yml | 4 +- .github/PULL_REQUEST_TEMPLATE/enhancement.yml | 4 +- 5 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/crash.yml diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 457bf11e17..ffbc02fbc6 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -1,6 +1,6 @@ name: Bug Report description: Report a bug or an issue in the game -labels: ["bug"] +labels: ["type: minor bug", "status: pending triage"] title: "Bug Report: " body: - type: checkboxes @@ -36,7 +36,7 @@ body: attributes: label: Version description: What version were you using? - placeholder: ex. 0.4.0 + placeholder: ex. 0.4.1 validations: required: true diff --git a/.github/ISSUE_TEMPLATE/crash.yml b/.github/ISSUE_TEMPLATE/crash.yml new file mode 100644 index 0000000000..7c160244db --- /dev/null +++ b/.github/ISSUE_TEMPLATE/crash.yml @@ -0,0 +1,69 @@ +name: Crash Report +description: Report a crash that occurred while playing. +labels: ["type: major bug", "status: pending triage"] +title: "Crash: " +body: + - type: checkboxes + attributes: + label: Issue Checklist + options: + - label: I have properly named the issue + - label: I looked in issues/discussions, if it has been previously reported + + - type: dropdown + attributes: + label: What platform are you using? + options: + - Itch.io - Windows + - Itch.io - MacOS + - Itch.io - Linux + - Newgrounds (Web) + validations: + required: true + + - type: dropdown + attributes: + label: If you were playing on a browser, which one were you using? + options: + - Google Chrome + - Microsoft Edge + - Firefox + - Opera + - Safari + - Other (Specify below) + + - type: input + attributes: + label: Version + description: What version were you using? + placeholder: ex. 0.4.1 + validations: + required: true + + - type: markdown + attributes: + value: "## Describe the issue." + + - type: markdown + attributes: + value: "### Please do not report issues from other engines. These must be reported in their repositories." + + - type: markdown + attributes: + value: "#### Provide as many details as you can." + + - type: textarea + attributes: + label: Context (Provide images, videos, etc. of the crash happening) + + - type: textarea + attributes: + label: Steps to reproduce + validations: + required: true + + - type: textarea + attributes: + label: Crash Logs (can be found in the crash folder) + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/enhancement.yml b/.github/ISSUE_TEMPLATE/enhancement.yml index 29c7e56694..327a91fec3 100644 --- a/.github/ISSUE_TEMPLATE/enhancement.yml +++ b/.github/ISSUE_TEMPLATE/enhancement.yml @@ -1,6 +1,6 @@ name: Enhancement description: Suggest a new feature -labels: ["enhancement"] +labels: ["type: enhancement", "status: pending triage"] title: "Enhancement: " body: - type: checkboxes diff --git a/.github/PULL_REQUEST_TEMPLATE/bug.yml b/.github/PULL_REQUEST_TEMPLATE/bug.yml index c8aa2fcb3f..ca17d0168f 100644 --- a/.github/PULL_REQUEST_TEMPLATE/bug.yml +++ b/.github/PULL_REQUEST_TEMPLATE/bug.yml @@ -1,6 +1,6 @@ name: Bug Fix description: Fix a bug or critical performance issue -labels: ["bug"] +labels: ["type: minor bug", "status: pending triage"] title: "Bug Fix: " body: - type: checkboxes @@ -8,7 +8,7 @@ body: label: Issue Checklist options: - label: I have checked if this PR isn't a duplicate - + - type: textarea attributes: label: Does this PR fix any issues? Please link them below if so. diff --git a/.github/PULL_REQUEST_TEMPLATE/enhancement.yml b/.github/PULL_REQUEST_TEMPLATE/enhancement.yml index 57186b9807..c39bd3e4a5 100644 --- a/.github/PULL_REQUEST_TEMPLATE/enhancement.yml +++ b/.github/PULL_REQUEST_TEMPLATE/enhancement.yml @@ -1,6 +1,6 @@ name: Enhancement description: Add a new feature -labels: ["enhancement"] +labels: ["type: enhancement", "status: pending triage"] title: "Enhancement: " body: - type: checkboxes @@ -8,7 +8,7 @@ body: label: Issue Checklist options: - label: I have checked if this PR isn't a duplicate - + - type: textarea attributes: label: Does this PR fix any issues? Please link them below if so. From 4a73d7e1cec158c7258eca8099954f029fdb5103 Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Tue, 25 Jun 2024 18:22:30 -0400 Subject: [PATCH 238/266] Add change counts labels to Actions labeler --- .github/changed-lines-count-labeler.yml | 12 ++++++++++++ .github/workflows/labeler.yml | 15 ++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 .github/changed-lines-count-labeler.yml diff --git a/.github/changed-lines-count-labeler.yml b/.github/changed-lines-count-labeler.yml new file mode 100644 index 0000000000..6f890f5342 --- /dev/null +++ b/.github/changed-lines-count-labeler.yml @@ -0,0 +1,12 @@ +# Add 'small' to any changes below 10 lines +small: + max: 9 + +# Add 'medium' to any changes between 10 and 100 lines +medium: + min: 10 + max: 99 + +# Add 'large' to any changes for more than 100 lines +large: + min: 100 diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 0bcc420d34..a861af5781 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -9,6 +9,19 @@ jobs: pull-requests: write runs-on: ubuntu-latest steps: - - uses: actions/labeler@v5 + - name: Set basic labels + uses: actions/labeler@v5 with: sync-labels: true + changed-lines-count-labeler: + permissions: + contents: read + pull-requests: write + runs-on: ubuntu-latest + name: An action for automatically labelling pull requests based on the changed lines count + steps: + - name: Set change count labels + uses: vkirilichev/changed-lines-count-labeler@v0.2 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + configuration-path: .github/changed-lines-count-labeler.yml From 05b57c88d3ff34ea36ce704678547a1f1ab3dd4a Mon Sep 17 00:00:00 2001 From: Punkinator7 Date: Wed, 3 Jul 2024 20:55:15 -0400 Subject: [PATCH 239/266] Add fixed Changelog There were several duplicate lines in the V4.0 Changelog, so I removed them --- changelog.md | 334 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 334 insertions(+) create mode 100644 changelog.md diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000000..653ee203f8 --- /dev/null +++ b/changelog.md @@ -0,0 +1,334 @@ +# Changelog +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.4.1] - 2024-06-12 +### Added +- Pressing ESCAPE on the title screen on desktop now exits the game, allowing you to exit the game while in fullscreen on desktop +- Freeplay menu controls (favoriting and switching categories) are now rebindable from the Options menu, and now have default binds on controllers. +### Changed +- Highscores and ranks are now saved separately, which fixes the issue where people would overwrite their saves with higher scores, +which would remove their rank if they had a lower one. +- A-Bot speaker now reacts to the user's volume preference on desktop (thanks to [M7theguy for the issue report/suggestion](https://github.com/FunkinCrew/Funkin/issues/2744)!) +- On Freeplay, heart icons are shifted to the right when you favorite a song that has no rank on it. +- Only play `scrollMenu` sound effect when there's a real change on the freeplay menu ([thanks gamerbross for the PR!](https://github.com/FunkinCrew/Funkin/pull/2741)) +- Gave antialiasing to the edge of the dad graphic on Freeplay +- Rearranged some controls in the controls menu +- Made several chart revisions + - Re-enabled custom camera events in Roses (Erect/Nightmare) + - Tweaked the chart for Lit Up (Hard) + - Corrected the difficulty ratings for M.I.L.F. (Easy/Normal/Hard) +### Fixed +- Fixed an issue in the controls menu where some control binds would overlap their names +- Fixed crash when attempting to exit the gameover screen when also attempting to retry the song ([thanks DMMaster636 for the PR!](https://github.com/FunkinCrew/Funkin/pull/2709)) +- Fix botplay sustain release bug ([thanks Hundrec!](Fix botplay sustain release bug #2683)) +- Fix for the camera not pausing during a gameplay pause ([thanks gamerbross!](https://github.com/FunkinCrew/Funkin/pull/2684)) +- Fixed issue where Pico's gameplay sprite would unintentionally appear on the gameover screen when dying on 2Hot from an explosion +- Freeplay previews properly fade volume during the BF idle animation +- Fixed bug where Dadbattle incorrectly appeared as Dadbattle Erect when returning to freeplay on Hard +- Fixed 2Hot not appearing under the "#" category in Freeplay menu +- Fixed a bug where the Chart Editor would crash when attempting to select an event with the Event toolbox open +- Improved offsets for Pico and Tankman opponents so they don't slide around as much. +- Fixed the black "temp" graphic on freeplay from being incorrectly sized / masked, now it's identical to the dad freeplay graphic + +## [0.4.0] - 2024-06-06 +### Added +- 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 burgerballs!) +### Changed +- Tweaked the charts for several songs: + - Tutorial (increased the note speed slightly) + - Spookeez + - Monster + - Winter Horrorland + - M.I.L.F. + - Senpai (increased the note speed) + - Roses + - Thorns (increased the note speed slightly) + - Ugh + - Stress + - Lit Up +- Favorite songs marked in Freeplay are now stored between sessions. +- The Freeplay easter eggs are now easier to see. +- In the event that the game cannot load your save data, it will now perform a backup before clearing it, so that we can try to repair it in the future. +- 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!) +- 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. +- Improved the Event Toolbox in the Chart Editor; dropdowns are now bigger, include search field, and display elements in alphabetical order rather than a random order. +### Fixed +- Fixed an issue where Nene's visualizer would not play on Desktop builds +- 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 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!) +- Made improvements to compiling documentation (thanks gedehari!) +- Fixed an issue where the Chart Editor would use an incorrect instrumental on imported Legacy songs (thanks gamerbross!) +- Fixed a camera bug in the Main Menu (thanks richTrash21!) +- Fixed a bug where opening the game from the command line would crash the preloader (thanks NotHyper474!) +- Fixed a bug where characters would sometimes use the wrong scale value (thanks PurSnake!) +- Additional bug fixes and optimizations. + +## [0.3.3] - 2024-05-14 +### Changed +- Cleaned up some code in `PlayAnimationSongEvent.hx` (thanks BurgerBalls!) +### Fixed +- 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!) +- Fixed the chart editor character selector's hitbox width (thanks MadBear422!) +- 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 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!) +- Fix a crash on Freeplay found on AMD graphics cards + +## [0.3.2] - 2024-05-03 +### Added +- Added `,` and `.` keybinds to the Chart Editor. These place Focus Camera events at the playhead, for the opponent and player respectively. +- Implemented a blacklist to prevent mods from calling system functions. + - Added a couple utility functions to call useful stuff that got blacklisted. +- Added an `onSongLoad` script event which allows for mutation of notes and events. +- Added the current loaded modlist to crash logs. +- Added the `visible` attribute to Level JSON data. +- Enabled ZIP file system support for Polymod (make sure the metadata is in the root of the ZIP). +### Changed +- Songs in the mod folders will display in Freeplay without any extra scripting. +- Story levels in the mod folders will display in Story without any extra scripting. +- All audio should sound better in HTML5, less muddy +### Fixed +- Fixed a typo in the credits folder (`Custcene` -> `Cutscene`) +- Fixed an issue where health icon transition animations would loop and never finish properly. +- Fixed an issue where video cutscenes flagged as mid-song would crash the game when they finish. +- Fixed an issue where some substate lifecycle events were not being dispatched. +- Fixed a crash when trying to load into the Animation Offsets menu with an invalid character. +- Fixed an issue where the preloader would spam the logs when it was complete and waiting for user input. +- Should definitely have the fix for freeplay where it stops taking control of the main menu below it +- Changed the code for the story menu difficulties so that "normal" doesn't overlap the arrows after leaving Weekend 1 +### Removed +- Removed some unused `.txt` files in the `assets/data` folder. + +## [0.3.1] - 2024-05-01 +### Changed +- Ensure the Git commit hash always displays in the log files. +- Added whether the local Git repo was modified to the log files. +- Removed "PROTOTYPE" text on release builds only (it still shows on debug builds). +- Added additional credits and special thanks. +- Updated peepo in creds to peepo173 +### Fixed +- Fix a crash when retrieving system specs while handing a crash. +- Fix a crash triggered when pausing before the song started. +- Fix a crash triggered when dying before the song started. +- Fix a crash triggered when unloading certain graphics. +- Pico game over confirm plays correctly +- When exiting from a song into freeplay, main menu no longer takes inputs unintentionally (aka issues with merch links opening up when selecting songs) +- Fix for arrow keys causing web browser page scroll + +## [0.3.0] - 2024-04-30 +### Added +- New Story Level: Weekend 1, starting Pico, Darnell, and Nene. + - Beat the level in Story Mode to unlock the songs for Freeplay! +- 12 new Erect remixes, featuring Kawai Sprite, Saruky, Kohta Takahashi, and Saster + - Unlocked instantly in Freeplay +- New visually enhanced Freeplay menu. + - Sorting, favorites, and more. +- New Results screen upon completing any song or story level. +- New refactored Chart Editor prototype (accessible via `~` in the main menu or `7` in the Play State, rebindable). (VERY EARLY PROTOTYPE. EXPECT BUGS AND CRASHES) +- Implemented a new scripting system using HScript (an interpreted language with Haxe-like syntax) for incredible flexibility. + - All character-specific, stage-specific, or song-specific behaviors have been moved to HScript. +- New song events system allows for simple customization of camera behavior. + - Mods can implement custom song events via HScript, and new built-in song events will come in the future. +- New credits menu to list all the dozens of people who contributed. +### Changed +- Completely refactored the game's input system for higher reliability and accuracy. +- Reworked note rendering to massively reduce lag on larger charts. +- Reworks to scoring and health gain. +- Dedicated gamepad support with the ability to rebind buttons. +- Improvements to video cutscenes and dialogue, allowing them to be easily skipped or restarted. +- Updated Polymod by several major versions, allowing for fully dynamic asset replacement and support for scripted classes. +- Completely refactored almost every part of the game's code for performance, stability, and extensibility. + - This is not the Ludem Dare game held together with sticks and glue you played three years ago. +- Characters, stages, songs, story levels, and dialogue are now built from JSON data registries rather than being hardcoded. + - All of these also support attaching scripts for custom behavior, more documentation on this soon. + - You can forcibly reload the game's JSON data and scripts by pressing F5. +- Fully refactored the game's chart file format for extensibility and readability. + - You can migrate old charts using the Import FNF Legacy option in the chart editor. +- Various visual tweaks and improvements. +### Fixed +- 17 quadrillion bugs across hundreds of PRs. + +## [0.2.8] - 2021-04-18 (note, this one is iffy cuz we slacked wit it lol!) +### Added +- TANKMAN! 3 NEW SONGS BY KAWAISPRITE (UGH, GUNS, STRESS)! Charting help by MtH! +- Monster added into week 2, FINALLY (Charting help by MtH and ChaoticGamer!) +- Can now change song difficulty mid-game. +- Shows some song info on pause screen. +- Cute little icons onto freeplay menu +- Offset files for easier modification of characters +### Changed +- ASSET LOADING OVERHAUL, WAY FASTER LOAD TIMES ON WEB!!! (THANKS TO GEOKURELI WOKE KING) +- Made difficulty selector on freeplay menu more apparent +### Fixed +- That one random note on Bopeebo + +## [0.2.7.1] - 2021-02-14 +### Added +- Easter eggs +- readme's in desktop versions of the game +### Changed +- New icons, old one was placeholder since October woops! +- Made the transitions between the story mode levels more seamless. +- Offset of the Newgrounds logo on boot screen. +- Made the changelog txt so it can be opened easier by normal people who don't have a markdown reader (most normal people); +### Fixed +- Fixed crashes on Week 6 story mode dialogue if spam too fast ([Thanks to Lotusotho for the Pull Request!](https://github.com/ninjamuffin99/Funkin/pull/357)) +- Should show intro credits on desktop versions of the game more consistently +- Layering on Week 4 songs with GF and the LIMO LOL HOW TF I MISS THIS +- Chart's and chart editor now support changeBPM, GOD BLESS MTH FOR THIS ONE I BEEN STRUGGLIN WIT THAT SINCE OCTOBER LMAO ([GOD BLESS MTH](https://github.com/ninjamuffin99/Funkin/pull/382)) +- Fixed sustain note trails ALSO THANKS TO MTH U A REAL ONE ([MTH VERY POWERFUL](https://github.com/ninjamuffin99/Funkin/pull/415)) +- Antialiasing on the skyscraper lights + +## [0.2.7] - 2021-02-02 +### Added +- PIXEL DAY UPDATE LOL 1 WEEK LATER +- 3 New songs by Kawaisprite! +- COOL CUTSCENES +- WEEK 6 YOYOYOYOY +- Swaggy pixel art by Moawling! +### Changed +- Made it so you lose sliiiightly more health when you miss a note. +- Removed the default HaxeFlixel pause screen when the game window loses focus, can get screenshots of the game easier hehehe +### Fixed +- Idle animation bug with BF christmas and BF hair blow sprites ([Thanks to Injourn for the Pull Request!](https://github.com/ninjamuffin99/Funkin/pull/237)) + +## [0.2.6] - 2021-01-20 +### Added +- 3 NEW CHRISTMAS SONGS. 2 BY KAWAISPRITE, 1 BY BASSETFILMS!!!!! BF WITH DRIP! SANTA HANGIN OUT! +- Enemy icons change when they you are winning a lot ([Thanks to pahaze for the Pull Request!](https://github.com/ninjamuffin99/Funkin/pull/138)) +- Holding CTRL in charting editor places notes on both sides +- Q and E changes sustain lengths in note editor +- Other charting editor workflow improvements +- More hair physics +- Heads appear at top of chart editor to help show which side ur charting for +### Changed +- Tweaked code relating to inputs, hopefully making notes that are close together more fair to hit +### Removed +- Removed APE +### Fixed +- Maybe fixed double notes / jump notes. Need to tweak it for balance, but should open things up for cooler charts in the future. +- Old Verison popup screen weirdness ([Thanks to gedehari for the Pull Request!](https://github.com/ninjamuffin99/Funkin/pull/155)) +- Song no longer loops when finishing the song. ([Thanks Injourn for the Pull Request!](https://github.com/ninjamuffin99/Funkin/pull/132)) +- Screen wipe being cut off in the limo/mom stage. Should fill the whole screen now. +- Boyfriend animations on hold notes, and pressing on repeating notes should behave differently + +## [0.2.5] - 2020-12-27 +### Added +- MOMMY GF, 3 NEW ASS SONGS BY KAWAISPRITE, NEW ART BY PHANTOMARCADE,WOOOOOOAH!!!! +- Different icons depending on which character you are against, art by EVILSK8R!! +- Autosave to chart editor +- Clear section button to note editor +- Swap button in note editor +- a new boot text or two +- automatic check for when you're on an old version of the game! +### Changed +- Made Spookeez on Normal easier. +- Mouse is now visible in note editor +### Fixed +- Crash when playing Week 3 and then playing a non-week 3 song +- When pausing music at the start, it doesn't continue the song anyways. ([shoutouts gedehari for the Pull Request!](https://github.com/ninjamuffin99/Funkin/pull/48)) +- IDK i think backing out of song menu should play main menu songs again hehe ([shoutouts gedehari for the Pull Request!](https://github.com/ninjamuffin99/Funkin/pull/48)) + +## [0.2.4] - 2020-12-11 +### Added +- 3 NEW SONGS BY KAWAISPRITE. Pico, Philly, and Blammed. +- NEW CHARACTER, PICO. Based off the classic Flash game "Pico's School" by Tom Fulp +- NEW LEVEL WOW! PHILLY BABEEEE +### Changed +- Made it less punishing to ATTEMPT to hit a note and miss, rather than let it pass you +### Fixed +- Song desync of you paused and unpaused frequently ([shoutouts SonicBlam](https://github.com/ninjamuffin99/Funkin/issues/37)) +- Animation offsets when GF is scared + +## [0.2.3] - 2020-12-04 +### Added +- More intro texts +### Fixed +- Exploit where you could potentially give yourself a high score via the debug menu +- Issue/bug where you could spam the confirm button on the story menu ([shoutouts lotusotho for the CODE contribution/pull request!](https://github.com/ninjamuffin99/Funkin/pull/19)) +- Glitch where if you never would lose health if you missed a note on a fast song (shoutouts [MrDulfin](https://github.com/ninjamuffin99/Funkin/issues/10), [HotSauceBurritos](https://github.com/ninjamuffin99/Funkin/issues/13) and [LobsterMango](https://lobstermango.newgrounds.com)) +- Fixed tiny note bleed over thingies (shoutouts [lotusotho](https://github.com/ninjamuffin99/Funkin/pull/24)) + +## [0.2.2] - 2020-11-20 +### Added +- Music playing on the freeplay menu. +- UI sounds on freeplay menu +- Score now shows mid-song. +- Menu on pause screen! Can resume, and restart song, or go back to main menu. +- New music made for pause menu! + +### Changed +- Moved all the intro texts to its own txt file instead of being hardcoded, this allows for much easier customization. File is in the data folder, called "introText.txt", follow the format in there and you're probably good to go! +### Fixed +- Fixed soft lock when pausing on song finish ([shoutouts gedehari](https://github.com/ninjamuffin99/Funkin/issues/15)) +- Think I fixed issue that led to in-game scores being off by 2 ([shoutouts Mike](https://github.com/ninjamuffin99/Funkin/issues/4)) +- Should have fixed the 1 frame note appearance thing. ([shoutouts Mike](https://github.com/ninjamuffin99/Funkin/issues/6)) +- Cleaned up some charting on South on hard mode +- Fixed some animation timings, should feel both better to play, and watch. (shoutouts Dave/Ivan lol) +- Animation issue where GF would freak out on the title screen if you returned to it([shoutouts MultiXIII](https://github.com/ninjamuffin99/Funkin/issues/12)). + +## [0.2.1.2] - 2020-11-06 +### Fixed +- Story mode scores not properly resetting, leading to VERY inflated highscores on the leaderboards. This also requires me to clear the scores that are on the leaderboard right now, sorry! +- Difficulty on storymode and in freeplay scores +- Hard mode difficulty on campaign levels have been fixed + +## [0.2.1.1] - 2020-11-06 +### Fixed +- Week 2 not unlocking properly + +## [0.2.1] - 2020-11-06 +### Added +- Scores to the freeplay menu +- A few new intro boot messages. +- Lightning effect in Spooky stages +- Campaign scores, can now compete on scoreboards for campaign! +- Can now change difficulties in Freeplay mode + +### Changed +- Balanced out Normal mode for the harder songs(Dadbattle and Spookeez, not South yet). Should be much easier all around. +- Put tutorial in it's own 'week', so that if you want to play week 1, you don't have to play the tutorial. + +### Fixed +- One of the charting bits on South and Spookeez during the intro. + +## [0.2.0] - 2020-11-01 +### Added +- Uhh Newgrounds release lolol I always lose track of shit. + +## [0.1.0] - 2020-10-05 +### Added +- Uh, everything. This the game's initial gamejam release. We put it out From cd9400e898fc2b0edd07280c59fc73c3a8b03e64 Mon Sep 17 00:00:00 2001 From: Punkinator7 Date: Wed, 3 Jul 2024 20:56:19 -0400 Subject: [PATCH 240/266] Delete CHANGELOG.md --- CHANGELOG.md | 344 --------------------------------------------------- 1 file changed, 344 deletions(-) delete mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 755b3b3bcf..0000000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,344 +0,0 @@ -# Changelog -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.4.1] - 2024-06-12 -### Added -- Pressing ESCAPE on the title screen on desktop now exits the game, allowing you to exit the game while in fullscreen on desktop -- Freeplay menu controls (favoriting and switching categories) are now rebindable from the Options menu, and now have default binds on controllers. -### Changed -- Highscores and ranks are now saved separately, which fixes the issue where people would overwrite their saves with higher scores, -which would remove their rank if they had a lower one. -- A-Bot speaker now reacts to the user's volume preference on desktop (thanks to [M7theguy for the issue report/suggestion](https://github.com/FunkinCrew/Funkin/issues/2744)!) -- On Freeplay, heart icons are shifted to the right when you favorite a song that has no rank on it. -- Only play `scrollMenu` sound effect when there's a real change on the freeplay menu ([thanks gamerbross for the PR!](https://github.com/FunkinCrew/Funkin/pull/2741)) -- Gave antialiasing to the edge of the dad graphic on Freeplay -- Rearranged some controls in the controls menu -- Made several chart revisions - - Re-enabled custom camera events in Roses (Erect/Nightmare) - - Tweaked the chart for Lit Up (Hard) - - Corrected the difficulty ratings for M.I.L.F. (Easy/Normal/Hard) -### Fixed -- Fixed an issue in the controls menu where some control binds would overlap their names -- Fixed crash when attempting to exit the gameover screen when also attempting to retry the song ([thanks DMMaster636 for the PR!](https://github.com/FunkinCrew/Funkin/pull/2709)) -- Fix botplay sustain release bug ([thanks Hundrec!](Fix botplay sustain release bug #2683)) -- Fix for the camera not pausing during a gameplay pause ([thanks gamerbross!](https://github.com/FunkinCrew/Funkin/pull/2684)) -- Fixed issue where Pico's gameplay sprite would unintentionally appear on the gameover screen when dying on 2Hot from an explosion -- Freeplay previews properly fade volume during the BF idle animation -- Fixed bug where Dadbattle incorrectly appeared as Dadbattle Erect when returning to freeplay on Hard -- Fixed 2Hot not appearing under the "#" category in Freeplay menu -- Fixed a bug where the Chart Editor would crash when attempting to select an event with the Event toolbox open -- Improved offsets for Pico and Tankman opponents so they don't slide around as much. -- Fixed the black "temp" graphic on freeplay from being incorrectly sized / masked, now it's identical to the dad freeplay graphic - -## [0.4.0] - 2024-06-06 -### Added -- 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 burgerballs!) -### Changed -- Tweaked the charts for several songs: - - Tutorial (increased the note speed slightly) - - Spookeez - - Monster - - Winter Horrorland - - M.I.L.F. - - Senpai (increased the note speed) - - Roses - - Thorns (increased the note speed slightly) - - Ugh - - Stress - - Lit Up -- Favorite songs marked in Freeplay are now stored between sessions. -- The Freeplay easter eggs are now easier to see. -- In the event that the game cannot load your save data, it will now perform a backup before clearing it, so that we can try to repair it in the future. -- 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!) -- 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. -- Improved the Event Toolbox in the Chart Editor; dropdowns are now bigger, include search field, and display elements in alphabetical order rather than a random order. -### Fixed -- Fixed an issue where Nene's visualizer would not play on Desktop builds -- 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 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!) -- Made improvements to compiling documentation (thanks gedehari!) -- Fixed a bug where pressing the volume keys would stop the Toy commercial (thanks gamerbross!) -- Fixed a bug where the Chart Editor Playtest would crash when losing (thanks gamerbross!) -- Removed a large number of unused imports to optimize builds (thanks Ethan-makes-music!) -- Fixed a bug where hold notes would be positioned wrong on downscroll (thanks MaybeMaru!) -- Additional fixes to the Loading bar on HTML5 (thanks lemz1!) -- Fixed a crash in Freeplay caused by a level referencing an invalid song (thanks gamerbross!) -- Improved debug logging for unscripted stages (thanks gamerbross!) -- Fixed a bug where changing difficulties in Story mode wouldn't update the score (thanks sectorA!) -- Fixed an issue where the Chart Editor would use an incorrect instrumental on imported Legacy songs (thanks gamerbross!) -- Fixed a camera bug in the Main Menu (thanks richTrash21!) -- Fixed several bugs with the TitleState, including missing music when returning from the Main Menu (thanks gamerbross!) -- Fixed a bug where opening the game from the command line would crash the preloader (thanks NotHyper474!) -- 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 characters would sometimes use the wrong scale value (thanks PurSnake!) -- Additional bug fixes and optimizations. - -## [0.3.3] - 2024-05-14 -### Changed -- Cleaned up some code in `PlayAnimationSongEvent.hx` (thanks BurgerBalls!) -### Fixed -- 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!) -- Fixed the chart editor character selector's hitbox width (thanks MadBear422!) -- 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 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!) -- Fix a crash on Freeplay found on AMD graphics cards - -## [0.3.2] - 2024-05-03 -### Added -- Added `,` and `.` keybinds to the Chart Editor. These place Focus Camera events at the playhead, for the opponent and player respectively. -- Implemented a blacklist to prevent mods from calling system functions. - - Added a couple utility functions to call useful stuff that got blacklisted. -- Added an `onSongLoad` script event which allows for mutation of notes and events. -- Added the current loaded modlist to crash logs. -- Added the `visible` attribute to Level JSON data. -- Enabled ZIP file system support for Polymod (make sure the metadata is in the root of the ZIP). -### Changed -- Songs in the mod folders will display in Freeplay without any extra scripting. -- Story levels in the mod folders will display in Story without any extra scripting. -- All audio should sound better in HTML5, less muddy -### Fixed -- Fixed a typo in the credits folder (`Custcene` -> `Cutscene`) -- Fixed an issue where health icon transition animations would loop and never finish properly. -- Fixed an issue where video cutscenes flagged as mid-song would crash the game when they finish. -- Fixed an issue where some substate lifecycle events were not being dispatched. -- Fixed a crash when trying to load into the Animation Offsets menu with an invalid character. -- Fixed an issue where the preloader would spam the logs when it was complete and waiting for user input. -- Should definitely have the fix for freeplay where it stops taking control of the main menu below it -- Changed the code for the story menu difficulties so that "normal" doesn't overlap the arrows after leaving Weekend 1 -### Removed -- Removed some unused `.txt` files in the `assets/data` folder. - -## [0.3.1] - 2024-05-01 -### Changed -- Ensure the Git commit hash always displays in the log files. -- Added whether the local Git repo was modified to the log files. -- Removed "PROTOTYPE" text on release builds only (it still shows on debug builds). -- Added additional credits and special thanks. -- Updated peepo in creds to peepo173 -### Fixed -- Fix a crash when retrieving system specs while handing a crash. -- Fix a crash triggered when pausing before the song started. -- Fix a crash triggered when dying before the song started. -- Fix a crash triggered when unloading certain graphics. -- Pico game over confirm plays correctly -- When exiting from a song into freeplay, main menu no longer takes inputs unintentionally (aka issues with merch links opening up when selecting songs) -- Fix for arrow keys causing web browser page scroll - -## [0.3.0] - 2024-04-30 -### Added -- New Story Level: Weekend 1, starting Pico, Darnell, and Nene. - - Beat the level in Story Mode to unlock the songs for Freeplay! -- 12 new Erect remixes, featuring Kawai Sprite, Saruky, Kohta Takahashi, and Saster - - Unlocked instantly in Freeplay -- New visually enhanced Freeplay menu. - - Sorting, favorites, and more. -- New Results screen upon completing any song or story level. -- New refactored Chart Editor prototype (accessible via `~` in the main menu or `7` in the Play State, rebindable). (VERY EARLY PROTOTYPE. EXPECT BUGS AND CRASHES) -- Implemented a new scripting system using HScript (an interpreted language with Haxe-like syntax) for incredible flexibility. - - All character-specific, stage-specific, or song-specific behaviors have been moved to HScript. -- New song events system allows for simple customization of camera behavior. - - Mods can implement custom song events via HScript, and new built-in song events will come in the future. -- New credits menu to list all the dozens of people who contributed. -### Changed -- Completely refactored the game's input system for higher reliability and accuracy. -- Reworked note rendering to massively reduce lag on larger charts. -- Reworks to scoring and health gain. -- Dedicated gamepad support with the ability to rebind buttons. -- Improvements to video cutscenes and dialogue, allowing them to be easily skipped or restarted. -- Updated Polymod by several major versions, allowing for fully dynamic asset replacement and support for scripted classes. -- Completely refactored almost every part of the game's code for performance, stability, and extensibility. - - This is not the Ludem Dare game held together with sticks and glue you played three years ago. -- Characters, stages, songs, story levels, and dialogue are now built from JSON data registries rather than being hardcoded. - - All of these also support attaching scripts for custom behavior, more documentation on this soon. - - You can forcibly reload the game's JSON data and scripts by pressing F5. -- Fully refactored the game's chart file format for extensibility and readability. - - You can migrate old charts using the Import FNF Legacy option in the chart editor. -- Various visual tweaks and improvements. -### Fixed -- 17 quadrillion bugs across hundreds of PRs. - -## [0.2.8] - 2021-04-18 (note, this one is iffy cuz we slacked wit it lol!) -### Added -- TANKMAN! 3 NEW SONGS BY KAWAISPRITE (UGH, GUNS, STRESS)! Charting help by MtH! -- Monster added into week 2, FINALLY (Charting help by MtH and ChaoticGamer!) -- Can now change song difficulty mid-game. -- Shows some song info on pause screen. -- Cute little icons onto freeplay menu -- Offset files for easier modification of characters -### Changed -- ASSET LOADING OVERHAUL, WAY FASTER LOAD TIMES ON WEB!!! (THANKS TO GEOKURELI WOKE KING) -- Made difficulty selector on freeplay menu more apparent -### Fixed -- That one random note on Bopeebo - -## [0.2.7.1] - 2021-02-14 -### Added -- Easter eggs -- readme's in desktop versions of the game -### Changed -- New icons, old one was placeholder since October woops! -- Made the transitions between the story mode levels more seamless. -- Offset of the Newgrounds logo on boot screen. -- Made the changelog txt so it can be opened easier by normal people who don't have a markdown reader (most normal people); -### Fixed -- Fixed crashes on Week 6 story mode dialogue if spam too fast ([Thanks to Lotusotho for the Pull Request!](https://github.com/ninjamuffin99/Funkin/pull/357)) -- Should show intro credits on desktop versions of the game more consistently -- Layering on Week 4 songs with GF and the LIMO LOL HOW TF I MISS THIS -- Chart's and chart editor now support changeBPM, GOD BLESS MTH FOR THIS ONE I BEEN STRUGGLIN WIT THAT SINCE OCTOBER LMAO ([GOD BLESS MTH](https://github.com/ninjamuffin99/Funkin/pull/382)) -- Fixed sustain note trails ALSO THANKS TO MTH U A REAL ONE ([MTH VERY POWERFUL](https://github.com/ninjamuffin99/Funkin/pull/415)) -- Antialiasing on the skyscraper lights - -## [0.2.7] - 2021-02-02 -### Added -- PIXEL DAY UPDATE LOL 1 WEEK LATER -- 3 New songs by Kawaisprite! -- COOL CUTSCENES -- WEEK 6 YOYOYOYOY -- Swaggy pixel art by Moawling! -### Changed -- Made it so you lose sliiiightly more health when you miss a note. -- Removed the default HaxeFlixel pause screen when the game window loses focus, can get screenshots of the game easier hehehe -### Fixed -- Idle animation bug with BF christmas and BF hair blow sprites ([Thanks to Injourn for the Pull Request!](https://github.com/ninjamuffin99/Funkin/pull/237)) - -## [0.2.6] - 2021-01-20 -### Added -- 3 NEW CHRISTMAS SONGS. 2 BY KAWAISPRITE, 1 BY BASSETFILMS!!!!! BF WITH DRIP! SANTA HANGIN OUT! -- Enemy icons change when they you are winning a lot ([Thanks to pahaze for the Pull Request!](https://github.com/ninjamuffin99/Funkin/pull/138)) -- Holding CTRL in charting editor places notes on both sides -- Q and E changes sustain lengths in note editor -- Other charting editor workflow improvements -- More hair physics -- Heads appear at top of chart editor to help show which side ur charting for -### Changed -- Tweaked code relating to inputs, hopefully making notes that are close together more fair to hit -### Removed -- Removed APE -### Fixed -- Maybe fixed double notes / jump notes. Need to tweak it for balance, but should open things up for cooler charts in the future. -- Old Verison popup screen weirdness ([Thanks to gedehari for the Pull Request!](https://github.com/ninjamuffin99/Funkin/pull/155)) -- Song no longer loops when finishing the song. ([Thanks Injourn for the Pull Request!](https://github.com/ninjamuffin99/Funkin/pull/132)) -- Screen wipe being cut off in the limo/mom stage. Should fill the whole screen now. -- Boyfriend animations on hold notes, and pressing on repeating notes should behave differently - -## [0.2.5] - 2020-12-27 -### Added -- MOMMY GF, 3 NEW ASS SONGS BY KAWAISPRITE, NEW ART BY PHANTOMARCADE,WOOOOOOAH!!!! -- Different icons depending on which character you are against, art by EVILSK8R!! -- Autosave to chart editor -- Clear section button to note editor -- Swap button in note editor -- a new boot text or two -- automatic check for when you're on an old version of the game! -### Changed -- Made Spookeez on Normal easier. -- Mouse is now visible in note editor -### Fixed -- Crash when playing Week 3 and then playing a non-week 3 song -- When pausing music at the start, it doesn't continue the song anyways. ([shoutouts gedehari for the Pull Request!](https://github.com/ninjamuffin99/Funkin/pull/48)) -- IDK i think backing out of song menu should play main menu songs again hehe ([shoutouts gedehari for the Pull Request!](https://github.com/ninjamuffin99/Funkin/pull/48)) - -## [0.2.4] - 2020-12-11 -### Added -- 3 NEW SONGS BY KAWAISPRITE. Pico, Philly, and Blammed. -- NEW CHARACTER, PICO. Based off the classic Flash game "Pico's School" by Tom Fulp -- NEW LEVEL WOW! PHILLY BABEEEE -### Changed -- Made it less punishing to ATTEMPT to hit a note and miss, rather than let it pass you -### Fixed -- Song desync of you paused and unpaused frequently ([shoutouts SonicBlam](https://github.com/ninjamuffin99/Funkin/issues/37)) -- Animation offsets when GF is scared - -## [0.2.3] - 2020-12-04 -### Added -- More intro texts -### Fixed -- Exploit where you could potentially give yourself a high score via the debug menu -- Issue/bug where you could spam the confirm button on the story menu ([shoutouts lotusotho for the CODE contribution/pull request!](https://github.com/ninjamuffin99/Funkin/pull/19)) -- Glitch where if you never would lose health if you missed a note on a fast song (shoutouts [MrDulfin](https://github.com/ninjamuffin99/Funkin/issues/10), [HotSauceBurritos](https://github.com/ninjamuffin99/Funkin/issues/13) and [LobsterMango](https://lobstermango.newgrounds.com)) -- Fixed tiny note bleed over thingies (shoutouts [lotusotho](https://github.com/ninjamuffin99/Funkin/pull/24)) - -## [0.2.2] - 2020-11-20 -### Added -- Music playing on the freeplay menu. -- UI sounds on freeplay menu -- Score now shows mid-song. -- Menu on pause screen! Can resume, and restart song, or go back to main menu. -- New music made for pause menu! - -### Changed -- Moved all the intro texts to its own txt file instead of being hardcoded, this allows for much easier customization. File is in the data folder, called "introText.txt", follow the format in there and you're probably good to go! -### Fixed -- Fixed soft lock when pausing on song finish ([shoutouts gedehari](https://github.com/ninjamuffin99/Funkin/issues/15)) -- Think I fixed issue that led to in-game scores being off by 2 ([shoutouts Mike](https://github.com/ninjamuffin99/Funkin/issues/4)) -- Should have fixed the 1 frame note appearance thing. ([shoutouts Mike](https://github.com/ninjamuffin99/Funkin/issues/6)) -- Cleaned up some charting on South on hard mode -- Fixed some animation timings, should feel both better to play, and watch. (shoutouts Dave/Ivan lol) -- Animation issue where GF would freak out on the title screen if you returned to it([shoutouts MultiXIII](https://github.com/ninjamuffin99/Funkin/issues/12)). - -## [0.2.1.2] - 2020-11-06 -### Fixed -- Story mode scores not properly resetting, leading to VERY inflated highscores on the leaderboards. This also requires me to clear the scores that are on the leaderboard right now, sorry! -- Difficulty on storymode and in freeplay scores -- Hard mode difficulty on campaign levels have been fixed - -## [0.2.1.1] - 2020-11-06 -### Fixed -- Week 2 not unlocking properly - -## [0.2.1] - 2020-11-06 -### Added -- Scores to the freeplay menu -- A few new intro boot messages. -- Lightning effect in Spooky stages -- Campaign scores, can now compete on scoreboards for campaign! -- Can now change difficulties in Freeplay mode - -### Changed -- Balanced out Normal mode for the harder songs(Dadbattle and Spookeez, not South yet). Should be much easier all around. -- Put tutorial in it's own 'week', so that if you want to play week 1, you don't have to play the tutorial. - -### Fixed -- One of the charting bits on South and Spookeez during the intro. - -## [0.2.0] - 2020-11-01 -### Added -- Uhh Newgrounds release lolol I always lose track of shit. - -## [0.1.0] - 2020-10-05 -### Added -- Uh, everything. This the game's initial gamejam release. We put it out From f31d2f7bfc1ed5918816eda617bd385d0a4b8c94 Mon Sep 17 00:00:00 2001 From: Punkinator7 Date: Wed, 3 Jul 2024 20:57:01 -0400 Subject: [PATCH 241/266] Rename changelog.md to CHANGELOG.md replace the old one with the fixed version --- changelog.md => CHANGELOG.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelog.md => CHANGELOG.md (100%) diff --git a/changelog.md b/CHANGELOG.md similarity index 100% rename from changelog.md rename to CHANGELOG.md From 39a774709e7a7ba9776e334837e58e2dde6ee0bd Mon Sep 17 00:00:00 2001 From: Hundrec Date: Tue, 9 Jul 2024 02:10:55 -0700 Subject: [PATCH 242/266] [DOCS] Add common troubleshooting steps to compiling guide Makes compiling easier for everyone --- docs/COMPILING.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/COMPILING.md b/docs/COMPILING.md index cc90bd348e..db32defe5e 100644 --- a/docs/COMPILING.md +++ b/docs/COMPILING.md @@ -8,10 +8,10 @@ 1. Run `git clone https://github.com/FunkinCrew/funkin.git` to clone the base repository. 2. Run `git submodule update --init --recursive` to download the game's assets. - 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. -2. Run `haxelib --global install hmm` and then `haxelib --global run hmm setup` to install hmm.json -3. Run `hmm install` to install all haxelibs of the current branch -4. Run `haxelib run lime setup` to set up lime -5. Platform setup +3. Run `haxelib --global install hmm` and then `haxelib --global run hmm setup` to install hmm.json +4. Run `hmm install` to install all haxelibs of the current branch +5. Run `haxelib run lime setup` to set up lime +6. 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 @@ -19,10 +19,12 @@ - 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/) - HTML5: Compiles without any extra setup -6. If you are targeting for native, you may need to run `lime rebuild PLATFORM` and `lime rebuild PLATFORM -debug` -7. `lime test PLATFORM` ! Add `-debug` to enable several debug features such as time travel (`PgUp`/`PgDn` in Play State). +7. If you are targeting for native, you may need to run `lime rebuild PLATFORM` and `lime rebuild PLATFORM -debug` +8. `lime test PLATFORM` ! Add `-debug` to enable several debug features such as time travel (`PgUp`/`PgDn` in Play State). -# Troubleshooting +# Troubleshooting +## GO THROUGH THESE STEPS BEFORE OPENING ISSUES ON GITHUB! - During the cloning process, you may experience an error along the lines of `error: RPC failed; curl 92 HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)` due to poor connectivity. A common fix is to run ` git config --global http.postBuffer 4096M`. - +- Check that your `assets` folder is not empty! If it is, go back to **Step 2** and follow the guide from there. +- The compilation process often fails due to having the wrong versions of the required libraries. Many errors can be resolved by deleting the `.haxelib` folder and rerunning the commands listed in **Step 3** and onwards. From 2d1d6eb19ec5afa157631be9802644b3baa8c145 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Tue, 9 Jul 2024 12:54:29 -0700 Subject: [PATCH 243/266] Add cd step for improved clarity --- docs/COMPILING.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/docs/COMPILING.md b/docs/COMPILING.md index db32defe5e..5784d9c7e5 100644 --- a/docs/COMPILING.md +++ b/docs/COMPILING.md @@ -5,13 +5,15 @@ - Download Git from [git-scm.com](https://www.git-scm.com) - Do NOT download the repository using the Download ZIP button on GitHub or you may run into errors! - Instead, open a command prompt and do the following steps... -1. Run `git clone https://github.com/FunkinCrew/funkin.git` to clone the base repository. -2. Run `git submodule update --init --recursive` to download the game's assets. +1. Run `cd the/directory/you/want/the/source/code/in` to specify which folder the command prompt is working in. + - For example, `cd C:\Users\YOURNAME\Documents` would instruct the command prompt to perform the next steps in your Documents folder. +2. Run `git clone https://github.com/FunkinCrew/funkin.git` to clone the base repository. +3. Run `git submodule update --init --recursive` to download the game's assets. - 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. -3. Run `haxelib --global install hmm` and then `haxelib --global run hmm setup` to install hmm.json -4. Run `hmm install` to install all haxelibs of the current branch -5. Run `haxelib run lime setup` to set up lime -6. Platform setup +4. Run `haxelib --global install hmm` and then `haxelib --global run hmm setup` to install hmm.json +5. Run `hmm install` to install all haxelibs of the current branch +6. Run `haxelib run lime setup` to set up lime +7. 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 @@ -19,12 +21,12 @@ - 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/) - HTML5: Compiles without any extra setup -7. If you are targeting for native, you may need to run `lime rebuild PLATFORM` and `lime rebuild PLATFORM -debug` -8. `lime test PLATFORM` ! Add `-debug` to enable several debug features such as time travel (`PgUp`/`PgDn` in Play State). +8. If you are targeting for native, you may need to run `lime rebuild PLATFORM` and `lime rebuild PLATFORM -debug` +9. `lime test PLATFORM` ! Add `-debug` to enable several debug features such as time travel (`PgUp`/`PgDn` in Play State). -# Troubleshooting -## GO THROUGH THESE STEPS BEFORE OPENING ISSUES ON GITHUB! +# Troubleshooting - GO THROUGH THESE STEPS BEFORE OPENING ISSUES ON GITHUB! - During the cloning process, you may experience an error along the lines of `error: RPC failed; curl 92 HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)` due to poor connectivity. A common fix is to run ` git config --global http.postBuffer 4096M`. -- Check that your `assets` folder is not empty! If it is, go back to **Step 2** and follow the guide from there. -- The compilation process often fails due to having the wrong versions of the required libraries. Many errors can be resolved by deleting the `.haxelib` folder and rerunning the commands listed in **Step 3** and onwards. +- Make sure your game directory has an `assets` folder! If it's missing, make sure you're in the right directory by running **Step 1**. +- Check that your `assets` folder is not empty! If it is, go back to **Step 3** and follow the guide from there. +- The compilation process often fails due to having the wrong versions of the required libraries. Many errors can be resolved by deleting the `.haxelib` folder and rerunning the commands listed in **Step 4** and onwards. From ff770d6948caad68086caf597f4cc84dea3c5a91 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Tue, 9 Jul 2024 12:55:04 -0700 Subject: [PATCH 244/266] Wrong slashes lol --- docs/COMPILING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/COMPILING.md b/docs/COMPILING.md index 5784d9c7e5..5a0c4dbd78 100644 --- a/docs/COMPILING.md +++ b/docs/COMPILING.md @@ -5,7 +5,7 @@ - Download Git from [git-scm.com](https://www.git-scm.com) - Do NOT download the repository using the Download ZIP button on GitHub or you may run into errors! - Instead, open a command prompt and do the following steps... -1. Run `cd the/directory/you/want/the/source/code/in` to specify which folder the command prompt is working in. +1. Run `cd the\directory\you\want\the\source\code\in` to specify which folder the command prompt is working in. - For example, `cd C:\Users\YOURNAME\Documents` would instruct the command prompt to perform the next steps in your Documents folder. 2. Run `git clone https://github.com/FunkinCrew/funkin.git` to clone the base repository. 3. Run `git submodule update --init --recursive` to download the game's assets. From 6c077cad5f7dce27832f0e38b096a55d987284c2 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Tue, 9 Jul 2024 16:22:43 -0700 Subject: [PATCH 245/266] Add second cd step after cloning --- docs/COMPILING.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/docs/COMPILING.md b/docs/COMPILING.md index 5a0c4dbd78..1fc0c51c65 100644 --- a/docs/COMPILING.md +++ b/docs/COMPILING.md @@ -8,12 +8,13 @@ 1. Run `cd the\directory\you\want\the\source\code\in` to specify which folder the command prompt is working in. - For example, `cd C:\Users\YOURNAME\Documents` would instruct the command prompt to perform the next steps in your Documents folder. 2. Run `git clone https://github.com/FunkinCrew/funkin.git` to clone the base repository. -3. Run `git submodule update --init --recursive` to download the game's assets. +3. Run `cd funkin` to enter the cloned repository's directory. +4. Run `git submodule update --init --recursive` to download the game's assets. - 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. -4. Run `haxelib --global install hmm` and then `haxelib --global run hmm setup` to install hmm.json -5. Run `hmm install` to install all haxelibs of the current branch -6. Run `haxelib run lime setup` to set up lime -7. Platform setup +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. 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 @@ -21,12 +22,12 @@ - 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/) - HTML5: Compiles without any extra setup -8. If you are targeting for native, you may need to run `lime rebuild PLATFORM` and `lime rebuild PLATFORM -debug` -9. `lime test PLATFORM` ! Add `-debug` to enable several debug features such as time travel (`PgUp`/`PgDn` in Play State). +9. If you are targeting for native, you may need to run `lime rebuild PLATFORM` and `lime rebuild PLATFORM -debug` +10. `lime test PLATFORM` ! Add `-debug` to enable several debug features such as time travel (`PgUp`/`PgDn` in Play State). # Troubleshooting - GO THROUGH THESE STEPS BEFORE OPENING ISSUES ON GITHUB! - During the cloning process, you may experience an error along the lines of `error: RPC failed; curl 92 HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)` due to poor connectivity. A common fix is to run ` git config --global http.postBuffer 4096M`. -- Make sure your game directory has an `assets` folder! If it's missing, make sure you're in the right directory by running **Step 1**. -- Check that your `assets` folder is not empty! If it is, go back to **Step 3** and follow the guide from there. -- The compilation process often fails due to having the wrong versions of the required libraries. Many errors can be resolved by deleting the `.haxelib` folder and rerunning the commands listed in **Step 4** and onwards. +- Make sure your game directory has an `assets` folder! If it's missing, copy the path to your `funkin` folder and run `cd the\path\you\copied`. Then follow the guide starting from **Step 4**. +- Check that your `assets` folder is not empty! If it is, go back to **Step 4** and follow the guide from there. +- The compilation process often fails due to having the wrong versions of the required libraries. Many errors can be resolved by deleting the `.haxelib` folder and following the guide starting from **Step 5**. From 2a5a24af708b738154718faab85f318ff1f41f96 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Wed, 10 Jul 2024 15:54:54 -0700 Subject: [PATCH 246/266] Polish and add triage label to bug template --- .github/ISSUE_TEMPLATE/bug.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index 82c121b5a1..d9b5bc34be 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -2,7 +2,7 @@ name: Bug Report about: Report a bug or critical performance issue title: 'Bug Report: [DESCRIBE YOUR BUG IN DETAIL HERE]' -labels: bug +labels: 'status: pending triage' --- -## Describe the bug +## Describe the Bug ## To Reproduce - -## Expected behavior + + +## Expected Behavior ## Screenshots/Video +Remember to mark the area in the application that's impacted. --> ## Desktop - OS: - - Browser - + - Browser: + - Version: ## Additional context - + From 6b2ab64e97e656fda98da0b81cf0859410c9e050 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Wed, 10 Jul 2024 15:58:42 -0700 Subject: [PATCH 247/266] Add triage label to enhancement template --- .github/ISSUE_TEMPLATE/enhancement.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/enhancement.md b/.github/ISSUE_TEMPLATE/enhancement.md index e1cc3ae0df..0bdaa953a3 100644 --- a/.github/ISSUE_TEMPLATE/enhancement.md +++ b/.github/ISSUE_TEMPLATE/enhancement.md @@ -2,7 +2,7 @@ name: Enhancement about: Suggest a new feature title: 'Enhancement: ' -labels: enhancement +labels: 'status: pending triage' --- -#### Please check for duplicates or similar issues before creating this issue. +#### Please check for duplicates or similar issues before submitting this suggestion. ## What is your suggestion, and why should it be implemented? From 2ba71e78bb3f73ca40a53d754ec8c1732c78c625 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Wed, 10 Jul 2024 16:00:28 -0700 Subject: [PATCH 248/266] Add triage label to PR bugfix template --- .github/PULL_REQUEST_TEMPLATE/bug.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE/bug.md b/.github/PULL_REQUEST_TEMPLATE/bug.md index 41914c5ede..db42b51ebd 100644 --- a/.github/PULL_REQUEST_TEMPLATE/bug.md +++ b/.github/PULL_REQUEST_TEMPLATE/bug.md @@ -2,9 +2,9 @@ name: Bug Fix about: Fix a bug or critical performance issue title: 'Bug Fix: ' -labels: bug +labels: 'status: pending triage' --- -#### Please check for duplicates or similar PRs before creating this issue. -## Does this PR close any issue(s)? If so, link them below. +#### Please check for duplicates or similar PRs before submitting this PR. +## Does this PR close any issues? If so, link them below. ## Briefly describe the issue(s) fixed. From fd7cdca333ccd9244231dd6d742188a486e51145 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Wed, 10 Jul 2024 16:01:52 -0700 Subject: [PATCH 249/266] Add triage label to PR enhancement template --- .github/PULL_REQUEST_TEMPLATE/enhancement.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE/enhancement.md b/.github/PULL_REQUEST_TEMPLATE/enhancement.md index e208deefea..192d31c486 100644 --- a/.github/PULL_REQUEST_TEMPLATE/enhancement.md +++ b/.github/PULL_REQUEST_TEMPLATE/enhancement.md @@ -2,9 +2,9 @@ name: Enhancement about: Add a new feature title: 'Enhancement: ' -labels: enhancement +labels: 'status: pending triage" --- -#### Please check for duplicates or similar PRs before creating this issue. -## Does this PR close any issue(s)? If so, link them below. +#### Please check for duplicates or similar PRs before submitting this PR. +## Does this PR close any issues? If so, link them below. -## What do your change(s) add, and why should they be implemented? +## What do your changes add, and why should they be implemented? From 5a534e210b06bc97b01ddca7cf7fb0b713496d22 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Wed, 10 Jul 2024 16:02:18 -0700 Subject: [PATCH 250/266] Wrong quote whoops --- .github/PULL_REQUEST_TEMPLATE/enhancement.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE/enhancement.md b/.github/PULL_REQUEST_TEMPLATE/enhancement.md index 192d31c486..4390685985 100644 --- a/.github/PULL_REQUEST_TEMPLATE/enhancement.md +++ b/.github/PULL_REQUEST_TEMPLATE/enhancement.md @@ -2,7 +2,7 @@ name: Enhancement about: Add a new feature title: 'Enhancement: ' -labels: 'status: pending triage" +labels: 'status: pending triage' --- #### Please check for duplicates or similar PRs before submitting this PR. ## Does this PR close any issues? If so, link them below. From 56948507e81939c77e7d7aad4d9bc11eca60bac2 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Wed, 10 Jul 2024 16:04:21 -0700 Subject: [PATCH 251/266] Capitalize C in "context" --- .github/ISSUE_TEMPLATE/bug.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index d9b5bc34be..fcbfacfaa2 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -45,7 +45,7 @@ Remember to mark the area in the application that's impacted. --> - Version: -## Additional context +## Additional Context From db0bb4d9c23d42e5121a87a4ddfcc759b89f8498 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Wed, 10 Jul 2024 16:14:29 -0700 Subject: [PATCH 252/266] Final bug template polish --- .github/ISSUE_TEMPLATE/bug.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index fcbfacfaa2..bae88b1321 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -10,7 +10,7 @@ OR ELSE YOUR ISSUE WILL BE LESS LIKELY TO BE SOLVED! Do not post about issues from other FNF mod engines! We cannot and probably won't solve those! -You can hopefully go to their respective GitHub issues and report them there, thank you :) +You can hopefully go to their respective GitHub issues pages and report them there, thank you :) Please check for duplicates or similar issues, as well as performing simple troubleshooting steps (such as clearing cookies, clearing AppData, trying another browser) before submitting an issue. @@ -48,4 +48,4 @@ Remember to mark the area in the application that's impacted. --> ## Additional Context - + From 738a21eeb63611e555b6e45cb8f9baf11c3274e3 Mon Sep 17 00:00:00 2001 From: tposejank <81495861+tposejank@users.noreply.github.com> Date: Wed, 10 Jul 2024 20:41:40 -0400 Subject: [PATCH 253/266] abcd --- .github/ISSUE_TEMPLATE/bug.md | 52 +------------------ .github/ISSUE_TEMPLATE/enhancement.md | 9 +--- .github/PULL_REQUEST_TEMPLATE.md | 10 ++++ .github/PULL_REQUEST_TEMPLATE/bug.md | 11 +--- .github/PULL_REQUEST_TEMPLATE/bug.yml | 19 +------ .github/PULL_REQUEST_TEMPLATE/enhancement.md | 11 +--- .github/PULL_REQUEST_TEMPLATE/enhancement.yml | 19 +------ 7 files changed, 16 insertions(+), 115 deletions(-) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md index bae88b1321..89fb11fade 100644 --- a/.github/ISSUE_TEMPLATE/bug.md +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -1,51 +1 @@ ---- -name: Bug Report -about: Report a bug or critical performance issue -title: 'Bug Report: [DESCRIBE YOUR BUG IN DETAIL HERE]' -labels: 'status: pending triage' ---- - - - -## Describe the Bug - - -## To Reproduce - - -## Expected Behavior - - -## Screenshots/Video - - -## Desktop - - OS: - - - Browser: - - - Version: - - -## Additional Context - - - +do not give me merge conflicts. diff --git a/.github/ISSUE_TEMPLATE/enhancement.md b/.github/ISSUE_TEMPLATE/enhancement.md index 0bdaa953a3..89fb11fade 100644 --- a/.github/ISSUE_TEMPLATE/enhancement.md +++ b/.github/ISSUE_TEMPLATE/enhancement.md @@ -1,8 +1 @@ ---- -name: Enhancement -about: Suggest a new feature -title: 'Enhancement: ' -labels: 'status: pending triage' ---- -#### Please check for duplicates or similar issues before submitting this suggestion. -## What is your suggestion, and why should it be implemented? +do not give me merge conflicts. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..db42b51ebd --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,10 @@ +--- +name: Bug Fix +about: Fix a bug or critical performance issue +title: 'Bug Fix: ' +labels: 'status: pending triage' +--- +#### Please check for duplicates or similar PRs before submitting this PR. +## Does this PR close any issues? If so, link them below. + +## Briefly describe the issue(s) fixed. diff --git a/.github/PULL_REQUEST_TEMPLATE/bug.md b/.github/PULL_REQUEST_TEMPLATE/bug.md index db42b51ebd..89fb11fade 100644 --- a/.github/PULL_REQUEST_TEMPLATE/bug.md +++ b/.github/PULL_REQUEST_TEMPLATE/bug.md @@ -1,10 +1 @@ ---- -name: Bug Fix -about: Fix a bug or critical performance issue -title: 'Bug Fix: ' -labels: 'status: pending triage' ---- -#### Please check for duplicates or similar PRs before submitting this PR. -## Does this PR close any issues? If so, link them below. - -## Briefly describe the issue(s) fixed. +do not give me merge conflicts. diff --git a/.github/PULL_REQUEST_TEMPLATE/bug.yml b/.github/PULL_REQUEST_TEMPLATE/bug.yml index ca17d0168f..89fb11fade 100644 --- a/.github/PULL_REQUEST_TEMPLATE/bug.yml +++ b/.github/PULL_REQUEST_TEMPLATE/bug.yml @@ -1,18 +1 @@ -name: Bug Fix -description: Fix a bug or critical performance issue -labels: ["type: minor bug", "status: pending triage"] -title: "Bug Fix: " -body: - - type: checkboxes - attributes: - label: Issue Checklist - options: - - label: I have checked if this PR isn't a duplicate - - - type: textarea - attributes: - label: Does this PR fix any issues? Please link them below if so. - - - type: textarea - attributes: - label: Briefly describe the issue(s) fixed. +do not give me merge conflicts. diff --git a/.github/PULL_REQUEST_TEMPLATE/enhancement.md b/.github/PULL_REQUEST_TEMPLATE/enhancement.md index 4390685985..89fb11fade 100644 --- a/.github/PULL_REQUEST_TEMPLATE/enhancement.md +++ b/.github/PULL_REQUEST_TEMPLATE/enhancement.md @@ -1,10 +1 @@ ---- -name: Enhancement -about: Add a new feature -title: 'Enhancement: ' -labels: 'status: pending triage' ---- -#### Please check for duplicates or similar PRs before submitting this PR. -## Does this PR close any issues? If so, link them below. - -## What do your changes add, and why should they be implemented? +do not give me merge conflicts. diff --git a/.github/PULL_REQUEST_TEMPLATE/enhancement.yml b/.github/PULL_REQUEST_TEMPLATE/enhancement.yml index c39bd3e4a5..89fb11fade 100644 --- a/.github/PULL_REQUEST_TEMPLATE/enhancement.yml +++ b/.github/PULL_REQUEST_TEMPLATE/enhancement.yml @@ -1,18 +1 @@ -name: Enhancement -description: Add a new feature -labels: ["type: enhancement", "status: pending triage"] -title: "Enhancement: " -body: - - type: checkboxes - attributes: - label: Issue Checklist - options: - - label: I have checked if this PR isn't a duplicate - - - type: textarea - attributes: - label: Does this PR fix any issues? Please link them below if so. - - - type: textarea - attributes: - label: What do your change(s) add, and why should they be implemented? +do not give me merge conflicts. From 2915fd7717669dd1152b13dac8c562cb0794ff08 Mon Sep 17 00:00:00 2001 From: tposejank <81495861+tposejank@users.noreply.github.com> Date: Wed, 10 Jul 2024 20:42:08 -0400 Subject: [PATCH 254/266] efgh --- .github/ISSUE_TEMPLATE/bug.md | 1 - .github/ISSUE_TEMPLATE/enhancement.md | 1 - .github/PULL_REQUEST_TEMPLATE/bug.md | 1 - .github/PULL_REQUEST_TEMPLATE/bug.yml | 1 - .github/PULL_REQUEST_TEMPLATE/enhancement.md | 1 - .github/PULL_REQUEST_TEMPLATE/enhancement.yml | 1 - 6 files changed, 6 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/bug.md delete mode 100644 .github/ISSUE_TEMPLATE/enhancement.md delete mode 100644 .github/PULL_REQUEST_TEMPLATE/bug.md delete mode 100644 .github/PULL_REQUEST_TEMPLATE/bug.yml delete mode 100644 .github/PULL_REQUEST_TEMPLATE/enhancement.md delete mode 100644 .github/PULL_REQUEST_TEMPLATE/enhancement.yml diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md deleted file mode 100644 index 89fb11fade..0000000000 --- a/.github/ISSUE_TEMPLATE/bug.md +++ /dev/null @@ -1 +0,0 @@ -do not give me merge conflicts. diff --git a/.github/ISSUE_TEMPLATE/enhancement.md b/.github/ISSUE_TEMPLATE/enhancement.md deleted file mode 100644 index 89fb11fade..0000000000 --- a/.github/ISSUE_TEMPLATE/enhancement.md +++ /dev/null @@ -1 +0,0 @@ -do not give me merge conflicts. diff --git a/.github/PULL_REQUEST_TEMPLATE/bug.md b/.github/PULL_REQUEST_TEMPLATE/bug.md deleted file mode 100644 index 89fb11fade..0000000000 --- a/.github/PULL_REQUEST_TEMPLATE/bug.md +++ /dev/null @@ -1 +0,0 @@ -do not give me merge conflicts. diff --git a/.github/PULL_REQUEST_TEMPLATE/bug.yml b/.github/PULL_REQUEST_TEMPLATE/bug.yml deleted file mode 100644 index 89fb11fade..0000000000 --- a/.github/PULL_REQUEST_TEMPLATE/bug.yml +++ /dev/null @@ -1 +0,0 @@ -do not give me merge conflicts. diff --git a/.github/PULL_REQUEST_TEMPLATE/enhancement.md b/.github/PULL_REQUEST_TEMPLATE/enhancement.md deleted file mode 100644 index 89fb11fade..0000000000 --- a/.github/PULL_REQUEST_TEMPLATE/enhancement.md +++ /dev/null @@ -1 +0,0 @@ -do not give me merge conflicts. diff --git a/.github/PULL_REQUEST_TEMPLATE/enhancement.yml b/.github/PULL_REQUEST_TEMPLATE/enhancement.yml deleted file mode 100644 index 89fb11fade..0000000000 --- a/.github/PULL_REQUEST_TEMPLATE/enhancement.yml +++ /dev/null @@ -1 +0,0 @@ -do not give me merge conflicts. From fd37e2121ce9ea14494fdb5393ad5a3bf7ce5464 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Wed, 10 Jul 2024 18:13:27 -0700 Subject: [PATCH 255/266] PR template rename --- .github/{PULL_REQUEST_TEMPLATE.md => pull_request_template.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{PULL_REQUEST_TEMPLATE.md => pull_request_template.md} (100%) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/pull_request_template.md similarity index 100% rename from .github/PULL_REQUEST_TEMPLATE.md rename to .github/pull_request_template.md From 7353747ca593901d9fbc5ec44e5aac5c638ad44b Mon Sep 17 00:00:00 2001 From: Hundrec Date: Wed, 10 Jul 2024 18:25:32 -0700 Subject: [PATCH 256/266] Simplify PR template --- .github/pull_request_template.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index db42b51ebd..b1bd09a8f1 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,10 +1,6 @@ ---- -name: Bug Fix -about: Fix a bug or critical performance issue -title: 'Bug Fix: ' -labels: 'status: pending triage' ---- -#### Please check for duplicates or similar PRs before submitting this PR. + ## Does this PR close any issues? If so, link them below. ## Briefly describe the issue(s) fixed. + +## Screenshots/Videos From 88b35ce8c2c9db037aca5df03535eead0b38f659 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Wed, 10 Jul 2024 18:37:19 -0700 Subject: [PATCH 257/266] Tweak Bug Report Template --- .github/ISSUE_TEMPLATE/bug.yml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index ffbc02fbc6..6be3f1245e 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -1,5 +1,5 @@ name: Bug Report -description: Report a bug or an issue in the game +description: Report a bug or an issue in the game. labels: ["type: minor bug", "status: pending triage"] title: "Bug Report: " body: @@ -8,22 +8,23 @@ body: label: Issue Checklist options: - label: I have properly named the issue - - label: I looked in issues/discussions, if it has been previously reported + - label: I have checked the issues/discussions pages to see if the issue has been previously reported - type: dropdown attributes: label: What platform are you using? options: - - Itch.io - Windows - - Itch.io - MacOS - - Itch.io - Linux - Newgrounds (Web) + - Itch.io (Web) + - Itch.io (Downloadable Build) - Windows + - Itch.io (Downloadable Build) - MacOS + - Itch.io (Downloadable Build) - Linux validations: required: true - type: dropdown attributes: - label: If you were playing on a browser, which one were you using? + label: If you are playing on a browser, which one are you using? options: - Google Chrome - Microsoft Edge @@ -35,7 +36,7 @@ body: - type: input attributes: label: Version - description: What version were you using? + description: What version are you using? placeholder: ex. 0.4.1 validations: required: true @@ -46,7 +47,7 @@ body: - type: markdown attributes: - value: "### Please do not report issues from other engines. These must be reported in their repositories." + value: "### Please do not report issues from other engines. These must be reported in their respective repositories." - type: markdown attributes: From ac11e5238d75deb789aee096904577772faaf022 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Wed, 10 Jul 2024 18:40:38 -0700 Subject: [PATCH 258/266] Tweak Crash Report Template --- .github/ISSUE_TEMPLATE/crash.yml | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/crash.yml b/.github/ISSUE_TEMPLATE/crash.yml index 7c160244db..74d2d628fd 100644 --- a/.github/ISSUE_TEMPLATE/crash.yml +++ b/.github/ISSUE_TEMPLATE/crash.yml @@ -1,5 +1,5 @@ name: Crash Report -description: Report a crash that occurred while playing. +description: Report a crash that occurred while playing the game. labels: ["type: major bug", "status: pending triage"] title: "Crash: " body: @@ -8,22 +8,23 @@ body: label: Issue Checklist options: - label: I have properly named the issue - - label: I looked in issues/discussions, if it has been previously reported + - label: I have checked the issues/discussions pages to see if the issue has been previously reported - type: dropdown attributes: label: What platform are you using? options: - - Itch.io - Windows - - Itch.io - MacOS - - Itch.io - Linux - Newgrounds (Web) + - Itch.io (Web) + - Itch.io (Downloadable Build) - Windows + - Itch.io (Downloadable Build) - MacOS + - Itch.io (Downloadable Build) - Linux validations: required: true - type: dropdown attributes: - label: If you were playing on a browser, which one were you using? + label: If you are playing on a browser, which one are you using? options: - Google Chrome - Microsoft Edge @@ -35,18 +36,18 @@ body: - type: input attributes: label: Version - description: What version were you using? + description: What version are you using? placeholder: ex. 0.4.1 validations: required: true - type: markdown attributes: - value: "## Describe the issue." + value: "## Describe your bug." - type: markdown attributes: - value: "### Please do not report issues from other engines. These must be reported in their repositories." + value: "### Please do not report issues from other engines. These must be reported in their respective repositories." - type: markdown attributes: From ce24a6f7a3d5bfcc3eee48193c1972c052922a94 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Wed, 10 Jul 2024 18:42:25 -0700 Subject: [PATCH 259/266] Tweak Enhancement Template --- .github/ISSUE_TEMPLATE/enhancement.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/enhancement.yml b/.github/ISSUE_TEMPLATE/enhancement.yml index 327a91fec3..c3ac345dbd 100644 --- a/.github/ISSUE_TEMPLATE/enhancement.yml +++ b/.github/ISSUE_TEMPLATE/enhancement.yml @@ -7,8 +7,8 @@ body: attributes: label: Issue Checklist options: - - label: I have properly named the issue - - label: I looked in issues/discussions, if it has been previously reported + - label: I have properly named the enhancement + - label: I have checked the issues/discussions pages to see if the enhancement has been previously suggested - type: textarea attributes: From 0f35618a1597e599c4ff1804baf716831d91c035 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Wed, 10 Jul 2024 18:43:15 -0700 Subject: [PATCH 260/266] PR template tweak --- .github/pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index b1bd09a8f1..8e8a45e195 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -3,4 +3,4 @@ ## Briefly describe the issue(s) fixed. -## Screenshots/Videos +## Include any relevant screenshots or videos. From ca5e08f967d3aa43a34895170b3c97aa04794cba Mon Sep 17 00:00:00 2001 From: Hundrec Date: Wed, 10 Jul 2024 18:47:34 -0700 Subject: [PATCH 261/266] Specify crash log location --- .github/ISSUE_TEMPLATE/crash.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/crash.yml b/.github/ISSUE_TEMPLATE/crash.yml index 74d2d628fd..7690e83081 100644 --- a/.github/ISSUE_TEMPLATE/crash.yml +++ b/.github/ISSUE_TEMPLATE/crash.yml @@ -65,6 +65,6 @@ body: - type: textarea attributes: - label: Crash Logs (can be found in the crash folder) + label: Crash logs (can be found in the logs folder where Funkin.exe is) validations: required: true From ffadce45e0901ec8ef9f19e5ac1b9047867fd790 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Wed, 10 Jul 2024 18:50:12 -0700 Subject: [PATCH 262/266] More crash report tweaks --- .github/ISSUE_TEMPLATE/crash.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/crash.yml b/.github/ISSUE_TEMPLATE/crash.yml index 7690e83081..c5240495d9 100644 --- a/.github/ISSUE_TEMPLATE/crash.yml +++ b/.github/ISSUE_TEMPLATE/crash.yml @@ -1,7 +1,7 @@ name: Crash Report description: Report a crash that occurred while playing the game. labels: ["type: major bug", "status: pending triage"] -title: "Crash: " +title: "Crash Report: " body: - type: checkboxes attributes: @@ -55,7 +55,7 @@ body: - type: textarea attributes: - label: Context (Provide images, videos, etc. of the crash happening) + label: Context (Provide screenshots or videos of the crash happening) - type: textarea attributes: From 6698ee6770aa2525c861d8966e259f4f62777dd1 Mon Sep 17 00:00:00 2001 From: Hundrec Date: Wed, 10 Jul 2024 20:31:06 -0700 Subject: [PATCH 263/266] . --- .github/ISSUE_TEMPLATE/enhancement.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/enhancement.yml b/.github/ISSUE_TEMPLATE/enhancement.yml index c3ac345dbd..816e4a12b1 100644 --- a/.github/ISSUE_TEMPLATE/enhancement.yml +++ b/.github/ISSUE_TEMPLATE/enhancement.yml @@ -1,5 +1,5 @@ name: Enhancement -description: Suggest a new feature +description: Suggest a new feature. labels: ["type: enhancement", "status: pending triage"] title: "Enhancement: " body: From 25a90d841980c29e4007ce12818c294db431557e Mon Sep 17 00:00:00 2001 From: Hundrec Date: Wed, 10 Jul 2024 20:33:12 -0700 Subject: [PATCH 264/266] Reword in crash report --- .github/ISSUE_TEMPLATE/crash.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/crash.yml b/.github/ISSUE_TEMPLATE/crash.yml index c5240495d9..6fb7c94374 100644 --- a/.github/ISSUE_TEMPLATE/crash.yml +++ b/.github/ISSUE_TEMPLATE/crash.yml @@ -43,7 +43,7 @@ body: - type: markdown attributes: - value: "## Describe your bug." + value: "## Describe your issue." - type: markdown attributes: From e7655664081289abe68dc3d36ec85808f54f224c Mon Sep 17 00:00:00 2001 From: MadBear422 Date: Mon, 22 Jul 2024 11:14:24 -0700 Subject: [PATCH 265/266] test --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index b69ba22ca5..a47b77c05e 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit b69ba22ca5069aed0e8545e1c2e79cadc39cac56 +Subproject commit a47b77c05eb7325a6d096009fca7e47d862c3f47 From 28e159577310a77654a03a4518389a364812e32a Mon Sep 17 00:00:00 2001 From: MadBear422 Date: Mon, 22 Jul 2024 11:22:53 -0700 Subject: [PATCH 266/266] assets merge --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index a47b77c05e..a2fb0637f5 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit a47b77c05eb7325a6d096009fca7e47d862c3f47 +Subproject commit a2fb0637f5c57ac140250c11d35f0c0911af08bb