diff --git a/assets b/assets index b2404b6b1..7efad31cf 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit b2404b6b1cba47da8eef4910f49985d54318186b +Subproject commit 7efad31cf80a42600375bf08b397786df5c1037c diff --git a/source/funkin/play/song/Song.hx b/source/funkin/play/song/Song.hx index 91e158299..20d2f75a4 100644 --- a/source/funkin/play/song/Song.hx +++ b/source/funkin/play/song/Song.hx @@ -98,7 +98,7 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry<SongMeta } // this returns false so that any new song can override this and return true when needed - public function isSongNew(currentDifficulty:String):Bool + public function isSongNew(currentDifficulty:String, currentVariation:String):Bool { return false; } @@ -434,17 +434,25 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry<SongMeta return null; } + /** + * Returns the first valid variation that matches both the difficulty id, and the current character / possible input variations + * @param diffId + * @param currentCharacter + * @param possibleVariations + * @return Null<String> + */ public function getFirstValidVariation(?diffId:String, ?currentCharacter:PlayableCharacter, ?possibleVariations:Array<String>):Null<String> { if (possibleVariations == null) { possibleVariations = getVariationsByCharacter(currentCharacter); } + if (diffId == null) diffId = listDifficulties(null, possibleVariations)[0]; for (variationId in possibleVariations) { - if (difficulties.exists('$variationId')) return variationId; + if (difficulties.get('$variationId')?.exists(diffId) ?? false) return variationId; } return null; diff --git a/source/funkin/save/Save.hx b/source/funkin/save/Save.hx index 73e7aa77e..47467cd45 100644 --- a/source/funkin/save/Save.hx +++ b/source/funkin/save/Save.hx @@ -543,22 +543,34 @@ class Save * * @param songId The ID of the song. * @param difficultyId The difficulty to check. + * @param variation The variation to check. Defaults to empty string. Appended to difficulty with `-`, e.g. `easy-pico`. * @return A data structure containing score, judgement counts, and accuracy. Returns `null` if no score is saved. */ - public function getSongScore(songId:String, difficultyId:String = 'normal'):Null<SaveScoreData> + public function getSongScore(songId:String, difficultyId:String = 'normal', ?variation:String):Null<SaveScoreData> { var song = data.scores.songs.get(songId); + trace('Getting song score for $songId $difficultyId $variation'); if (song == null) { + trace('Could not find song data for $songId $difficultyId $variation'); song = []; data.scores.songs.set(songId, song); } + + // 'default' variations are left with no suffix ('easy', 'normal', 'hard'), + // along with 'erect' variations ('erect', 'nightmare') + // otherwise, we want to add a suffix of our current variation to get the save data. + if (variation != null && variation != '' && variation != 'default' && variation != 'erect') + { + difficultyId = '${difficultyId}-${variation}'; + } + return song.get(difficultyId); } - public function getSongRank(songId:String, difficultyId:String = 'normal'):Null<ScoringRank> + public function getSongRank(songId:String, difficultyId:String = 'normal', ?variation:String):Null<ScoringRank> { - return Scoring.calculateRank(getSongScore(songId, difficultyId)); + return Scoring.calculateRank(getSongScore(songId, difficultyId, variation)); } /** diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 312c17713..b4e72ef4a 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -1717,8 +1717,6 @@ class FreeplayState extends MusicBeatSubState } } - trace('CURRENT VARIATION OF SONG: ${currentVariation}'); - var daSong:Null<FreeplaySongData> = grpCapsules.members[curSelected].freeplayData; if (daSong != null) { @@ -1729,7 +1727,7 @@ class FreeplayState extends MusicBeatSubState return; } - var songScore:Null<SaveScoreData> = Save.instance.getSongScore(daSong.data.id, currentDifficulty); + var songScore:Null<SaveScoreData> = Save.instance.getSongScore(daSong.data.id, currentDifficulty, currentVariation); intendedScore = songScore?.score ?? 0; intendedCompletion = songScore == null ? 0.0 : ((songScore.tallies.sick + songScore.tallies.good) / songScore.tallies.totalNotes); rememberedDifficulty = currentDifficulty; @@ -2025,7 +2023,7 @@ class FreeplayState extends MusicBeatSubState var daSongCapsule:SongMenuItem = grpCapsules.members[curSelected]; if (daSongCapsule.freeplayData != null) { - var songScore:Null<SaveScoreData> = Save.instance.getSongScore(daSongCapsule.freeplayData.data.id, currentDifficulty); + var songScore:Null<SaveScoreData> = Save.instance.getSongScore(daSongCapsule.freeplayData.data.id, currentDifficulty, currentVariation); intendedScore = songScore?.score ?? 0; intendedCompletion = songScore == null ? 0.0 : ((songScore.tallies.sick + songScore.tallies.good) / songScore.tallies.totalNotes); rememberedSongId = daSongCapsule.freeplayData.data.id; @@ -2260,7 +2258,7 @@ class FreeplaySongData /** * Whether the player has seen/played this song before within freeplay */ - public var isNew:Bool = false; + public var isNew(get, never):Bool; /** * The default opponent for the song. @@ -2312,6 +2310,18 @@ class FreeplaySongData // this.isNew = song.isSongNew(suffixedDifficulty); } + function get_isNew():Bool + { + // We use a slightly different manner to get the new status of a song than the other getters here + // `isSongNew()` only takes a single variation, and it's data that isn't accessible via the Song data/metadata + // it's stored in the song .hxc script in a function that overrides `isSongNew()` + // and is only accessible with the correct valid variation inputs + + var variations:Array<String> = data.getVariationsByCharacterId(FreeplayState.rememberedCharacterId); + var variation:String = data.getFirstValidVariation(FreeplayState.rememberedDifficulty, null, variations); + return data.isSongNew(FreeplayState.rememberedDifficulty, variation); + } + function get_songCharacter():String { var variations:Array<String> = data.getVariationsByCharacterId(FreeplayState.rememberedCharacterId); @@ -2340,8 +2350,10 @@ class FreeplaySongData function get_scoringRank():Null<ScoringRank> { - // TODO: Properly get/migrate the save data from the suffixed difficulty version to our new unsuffixed version - return Save.instance.getSongRank(data.songName, FreeplayState.rememberedDifficulty); + var variations:Array<String> = data.getVariationsByCharacterId(FreeplayState.rememberedCharacterId); + var variation:String = data.getFirstValidVariation(FreeplayState.rememberedDifficulty, null, variations); + + return Save.instance.getSongRank(data.id, FreeplayState.rememberedDifficulty, variation); } }