diff --git a/source/funkin/data/song/SongData.hx b/source/funkin/data/song/SongData.hx index 074ed0b440..bd65d82782 100644 --- a/source/funkin/data/song/SongData.hx +++ b/source/funkin/data/song/SongData.hx @@ -552,8 +552,12 @@ class SongCharacterData implements ICloneable @:optional public var playerVocals:Null> = null; + @:optional + @:default(true) + public var unlockedInstByDefault:Null = true; + public function new(player:String = '', girlfriend:String = '', opponent:String = '', instrumental:String = '', ?altInstrumentals:Array, - ?opponentVocals:Array, ?playerVocals:Array) + ?opponentVocals:Array, ?playerVocals:Array, ?unlockedInstByDefault:Bool) { this.player = player; this.girlfriend = girlfriend; @@ -563,6 +567,7 @@ class SongCharacterData implements ICloneable this.altInstrumentals = altInstrumentals; this.opponentVocals = opponentVocals; this.playerVocals = playerVocals; + this.unlockedInstByDefault = unlockedInstByDefault; if (opponentVocals == null) this.opponentVocals = [opponent]; if (playerVocals == null) this.playerVocals = [player]; @@ -572,6 +577,7 @@ class SongCharacterData implements ICloneable { var result:SongCharacterData = new SongCharacterData(this.player, this.girlfriend, this.opponent, this.instrumental); result.altInstrumentals = this.altInstrumentals.clone(); + result.unlockedInstByDefault = this.unlockedInstByDefault; return result; } @@ -581,7 +587,8 @@ class SongCharacterData implements ICloneable */ public function toString():String { - return 'SongCharacterData(${this.player}, ${this.girlfriend}, ${this.opponent}, ${this.instrumental}, [${this.altInstrumentals.join(', ')}])'; + return + 'SongCharacterData(${this.player}, ${this.girlfriend}, ${this.opponent}, ${this.instrumental}, [${this.altInstrumentals.join(', ')}], ${this.unlockedInstByDefault})'; } } diff --git a/source/funkin/play/song/Song.hx b/source/funkin/play/song/Song.hx index 17585973fb..529ff373ab 100644 --- a/source/funkin/play/song/Song.hx +++ b/source/funkin/play/song/Song.hx @@ -16,6 +16,7 @@ import funkin.modding.IScriptedClass.IPlayStateScriptedClass; import funkin.modding.events.ScriptEvent; import funkin.ui.freeplay.charselect.PlayableCharacter; import funkin.data.freeplay.player.PlayerRegistry; +import funkin.save.Save; import funkin.util.SortUtil; /** @@ -588,6 +589,25 @@ class Song implements IPlayStateScriptedClass implements IRegistryEntry = getDifficulty(difficultyId, variationId); + if (targetDifficulty == null) return true; + + var unlocked:Bool = (targetDifficulty?.characters?.unlockedInstByDefault) || Save.instance.hasBeatenSong(this.id, null, variationId); + + trace('Is ${this.id}-${variationId} alt inst unlocked: ' + + unlocked + + ((targetDifficulty?.characters?.unlockedInstByDefault ?? true) ? ' (by default)' : '')); + + return unlocked; + } + /** * Return the list of available alternate instrumentals. * Scripts can override this, fun. diff --git a/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx b/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx index f68776cabf..5a74100779 100644 --- a/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx +++ b/source/funkin/ui/debug/charting/toolboxes/ChartEditorMetadataToolbox.hx @@ -32,6 +32,7 @@ class ChartEditorMetadataToolbox extends ChartEditorBaseToolbox var inputSongCharter:TextField; var inputStage:DropDown; var inputNoteStyle:DropDown; + var inputIsunlockedInstByDefault:CheckBox; var buttonCharacterPlayer:Button; var buttonCharacterGirlfriend:Button; var buttonCharacterOpponent:Button; @@ -122,6 +123,10 @@ class ChartEditorMetadataToolbox extends ChartEditorBaseToolbox var startingValueNoteStyle = ChartEditorDropdowns.populateDropdownWithNoteStyles(inputNoteStyle, chartEditorState.currentSongMetadata.playData.noteStyle); inputNoteStyle.value = startingValueNoteStyle; + inputIsunlockedInstByDefault.onChange = function(event:UIEvent) { + chartEditorState.currentSongMetadata.playData.characters.unlockedInstByDefault = event.target.value; + }; + inputBPM.onChange = function(event:UIEvent) { if (event.value == null || event.value <= 0) return; @@ -196,6 +201,7 @@ class ChartEditorMetadataToolbox extends ChartEditorBaseToolbox inputSongCharter.value = chartEditorState.currentSongMetadata.charter; inputStage.value = chartEditorState.currentSongMetadata.playData.stage; inputNoteStyle.value = chartEditorState.currentSongMetadata.playData.noteStyle; + inputIsunlockedInstByDefault.selected = chartEditorState.currentSongMetadata.playData.characters.unlockedInstByDefault; inputBPM.value = chartEditorState.currentSongMetadata.timeChanges[0].bpm; inputDifficultyRating.value = chartEditorState.currentSongChartDifficultyRating; inputScrollSpeed.value = chartEditorState.currentSongChartScrollSpeed; diff --git a/source/funkin/ui/freeplay/FreeplayState.hx b/source/funkin/ui/freeplay/FreeplayState.hx index 351de6b977..9c45d990d7 100644 --- a/source/funkin/ui/freeplay/FreeplayState.hx +++ b/source/funkin/ui/freeplay/FreeplayState.hx @@ -1865,12 +1865,25 @@ class FreeplayState extends MusicBeatSubState trace('target variation: ${targetDifficulty?.variation ?? Constants.DEFAULT_VARIATION}'); var baseInstrumentalId:String = targetSong.getBaseInstrumentalId(targetDifficultyId, targetDifficulty?.variation ?? Constants.DEFAULT_VARIATION) ?? ''; + var hasBeenBeaten:Bool = Save.instance.hasBeatenSong(targetSongId, null, baseInstrumentalId); + trace('Has ${targetSongId}' + + ((baseInstrumentalId.length > 0) ? '-${baseInstrumentalId}' : '') + + " been beaten" + + hasBeenBeaten); var altInstrumentalIds:Array = targetSong.listAltInstrumentalIds(targetDifficultyId, targetDifficulty?.variation ?? Constants.DEFAULT_VARIATION) ?? []; + var instrumentalIds = [baseInstrumentalId].concat(altInstrumentalIds); + for (altInstrumentalId in instrumentalIds) + { + var altIsUnlocked = targetSong.isAltInstUnlocked(targetDifficultyId, altInstrumentalId) ?? true; + if (!altIsUnlocked) + { + instrumentalIds.remove(altInstrumentalId); + } + } - if (altInstrumentalIds.length > 0) + if (instrumentalIds.length > 1 && hasBeenBeaten) { - var instrumentalIds = [baseInstrumentalId].concat(altInstrumentalIds); openInstrumentalList(cap, instrumentalIds); } else