diff --git a/assets/languages/en/Editors.xml b/assets/languages/en/Editors.xml index e5517f75..be6f9cdb 100644 --- a/assets/languages/en/Editors.xml +++ b/assets/languages/en/Editors.xml @@ -45,12 +45,15 @@ Select a song to modify the charts from. Press ACCEPT to choose a difficulty to edit. + Press ACCEPT to choose a song variation to edit. Press ACCEPT to edit the chart for the selected difficulty. Select a difficulty to continue. New Difficulty Press ACCEPT to create a new chart difficulty. New Song Press ACCEPT to create a new song. + New Variation + Press ACCEPT to create a new song variation. @@ -104,6 +107,7 @@ Song Data Song Name + Song Variation BPM Time Signature Menus Data (Freeplay/Story) diff --git a/source/funkin/editors/charter/Charter.hx b/source/funkin/editors/charter/Charter.hx index 284cb8e6..c09bfebc 100644 --- a/source/funkin/editors/charter/Charter.hx +++ b/source/funkin/editors/charter/Charter.hx @@ -600,32 +600,34 @@ class Charter extends UIState { PlayState.loadSong(__song, __diff, __variant, false, false); __resetStatics(); } - Conductor.setupSong(PlayState.SONG); - noteTypes = PlayState.SONG.noteTypes; - FlxG.sound.setMusic(FlxG.sound.load(Paths.inst(__song, __diff, PlayState.SONG.meta.instSuffix))); - if (Assets.exists(Paths.voices(__song, __diff, PlayState.SONG.meta.vocalsSuffix))) - vocals = FlxG.sound.load(Paths.voices(__song, __diff, PlayState.SONG.meta.vocalsSuffix)); + var SONG = PlayState.SONG; + Conductor.setupSong(SONG); + noteTypes = SONG.noteTypes; + + FlxG.sound.setMusic(FlxG.sound.load(Paths.inst(SONG.meta.name, __diff, SONG.meta.instSuffix))); + if (Assets.exists(Paths.voices(SONG.meta.name, __diff, SONG.meta.vocalsSuffix))) + vocals = FlxG.sound.load(Paths.voices(SONG.meta.name, __diff, SONG.meta.vocalsSuffix)); else vocals = new FlxSound(); - vocals.muted = !PlayState.SONG.meta.needsVoices; + vocals.muted = !SONG.meta.needsVoices; vocals.group = FlxG.sound.defaultMusicGroup; - gridBackdrops.createGrids(PlayState.SONG.strumLines.length); + gridBackdrops.createGrids(SONG.strumLines.length); - for(strL in PlayState.SONG.strumLines) + for(strL in SONG.strumLines) createStrumline(strumLines.members.length, strL, false, false); // create notes notesGroup.autoSort = false; var noteCount:Int = 0; - for (strL in PlayState.SONG.strumLines) + for (strL in SONG.strumLines) noteCount += strL.notes.length; notesGroup.preallocate(noteCount); var notesCreated:Int = 0; - for (i => strL in PlayState.SONG.strumLines) + for (i => strL in SONG.strumLines) for (note in strL.notes) { var n = new CharterNote(); var t = Conductor.getStepForTime(note.time); @@ -639,7 +641,7 @@ class Charter extends UIState { rightEventsGroup.autoSort = leftEventsGroup.autoSort = false; var lastLeftEvents:CharterEvent = null, lastRightEvents:CharterEvent = null; var lastLeftTime = Math.NaN, lastRightTime = Math.NaN; - for (e in PlayState.SONG.events) if (e != null) { + for (e in SONG.events) if (e != null) { if (e.global) { if (lastRightEvents != null && lastRightTime == e.time) lastRightEvents.events.push(e); else rightEventsGroup.add(lastRightEvents = new CharterEvent(Conductor.getStepForTime(lastRightTime = e.time), [e], e.global)); @@ -685,10 +687,10 @@ class Charter extends UIState { var wavesToGenerate:Array<{name:String, sound:FlxSound}> = []; if (FlxG.sound.music.loaded) - wavesToGenerate.push({name: "Inst.ogg", sound: FlxG.sound.music}); + wavesToGenerate.push({name: 'Inst${PlayState.SONG.meta.instSuffix}.ogg', sound: FlxG.sound.music}); if (vocals.loaded) - wavesToGenerate.push({name: "Voices.ogg", sound: vocals}); + wavesToGenerate.push({name: 'Voices${PlayState.SONG.meta.vocalsSuffix}.ogg', sound: vocals}); for (strumLine in strumLines) if (strumLine.vocals != null && strumLine.strumLine.vocalsSuffix != null && strumLine.strumLine.vocalsSuffix != "" && strumLine.vocals.loaded) diff --git a/source/funkin/editors/charter/CharterMetaDataScreen.hx b/source/funkin/editors/charter/CharterMetaDataScreen.hx index a86ae09b..cf709ab1 100644 --- a/source/funkin/editors/charter/CharterMetaDataScreen.hx +++ b/source/funkin/editors/charter/CharterMetaDataScreen.hx @@ -150,20 +150,21 @@ class CharterMetaDataScreen extends UISubstateWindow { Reflect.setProperty(customVals, vals.propertyText.label.text, vals.valueText.label.text); } - PlayState.SONG.meta = { - name: songNameTextBox.label.text, - bpm: bpmStepper.value, - needsVoices: needsVoicesCheckbox.checked, - beatsPerMeasure: Std.int(beatsPerMeasureStepper.value), - stepsPerBeat: Std.int(16 / denominatorStepper.value), - displayName: displayNameTextBox.label.text, - icon: iconTextBox.label.text, - color: colorWheel.curColor, - opponentModeAllowed: opponentModeCheckbox.checked, - coopAllowed: coopAllowedCheckbox.checked, - difficulties: [for (diff in difficultiesTextBox.label.text.split(",")) diff.trim()], - customValues: customVals, - }; + var meta = PlayState.SONG.meta; + if (meta == null) meta = {name: songNameTextBox.label.text}; + else meta.name = songNameTextBox.label.text; + + meta.bpm = bpmStepper.value; + meta.needsVoices = needsVoicesCheckbox.checked; + meta.beatsPerMeasure = Std.int(beatsPerMeasureStepper.value); + meta.stepsPerBeat = Std.int(16 / denominatorStepper.value); + meta.displayName = displayNameTextBox.label.text; + meta.icon = iconTextBox.label.text; + meta.color = colorWheel.curColor; + meta.opponentModeAllowed = opponentModeCheckbox.checked; + meta.coopAllowed = coopAllowedCheckbox.checked; + meta.difficulties = [for (diff in difficultiesTextBox.label.text.split(",")) diff.trim()]; + meta.customValues = customVals; Charter.instance.updateBPMEvents(); Charter.instance.vocals.muted = !needsVoicesCheckbox.checked; diff --git a/source/funkin/editors/charter/CharterSelection.hx b/source/funkin/editors/charter/CharterSelection.hx index ce105f42..7e05867a 100644 --- a/source/funkin/editors/charter/CharterSelection.hx +++ b/source/funkin/editors/charter/CharterSelection.hx @@ -25,48 +25,65 @@ class CharterSelectionScreen extends EditorTreeMenuScreen { public var songList:Array = []; public var curSong:ChartMetaData; - inline public function makeChartOption(d:String, name:String):TextOption { - return new TextOption(d, getID('acceptDifficulty'), () -> FlxG.switchState(new Charter(name, d, null))); + inline public function makeChartOption(d:String, v:String, name:String):TextOption { + return new TextOption(d, getID('acceptDifficulty'), FlxG.switchState.bind(new Charter(name, d, v))); + } + + inline public function makeVariationOption(s:ChartMetaData):TextOption { + return new TextOption(s.variant, getID('acceptVariation'), " >", openSongOption.bind(s, false)); + } + + public function openSongOption(s:ChartMetaData, first = true) { + curSong = s; + + var isVariant = s.variant != null && s.variant != ''; + var screen = new EditorTreeMenuScreen((first || !isVariant) ? (s.name + (isVariant ? ' (${s.variant})' : '')) : s.variant, getID('selectDifficulty')); + + for (d in s.difficulties) if (d != '') screen.add(makeChartOption(d, isVariant ? s.variant : null, s.name)); + screen.add(new Separator()); + for (v in s.variants) if (s.metas.get(v) != null) screen.add(makeVariationOption(s.metas.get(v))); + + #if sys + screen.insert(0, new NewOption(getID('newDifficulty'), getID('newDifficultyDesc'), () -> { + parent.openSubState(new ChartCreationScreen(saveChart)); + })); + + if (!first) screen.curSelected = 1; + else { + cast(screen.members[0], NewOption).itemHeight = 120; + screen.insert(1, new NewOption(getID('newVariation'), getID('newVariationDesc'), () -> { + parent.openSubState(new VariationCreationScreen(s, saveSong)); + })); + screen.curSelected = 2; + } + #end + + parent.addMenu(screen); } public function makeSongOption(s:ChartMetaData):IconOption { songList.push(s.name.toLowerCase()); - var opt = new IconOption(s.name, getID('acceptSong'), s.icon, () -> { - curSong = s; - - var screen = new EditorTreeMenuScreen(s.name, getID('selectDifficulty'), [ - for (d in s.difficulties) if (d != '') makeChartOption(d, s.name) - ]); - - #if sys - screen.insert(0, new NewOption(getID('newDifficulty'), getID('newDifficultyDesc'), () -> { - parent.openSubState(new ChartCreationScreen(saveChart)); - })); - screen.curSelected = 1; - #end - - parent.addMenu(screen); - }); - opt.suffix = ' >'; + var opt = new IconOption(s.name, getID('acceptSong'), s.icon, openSongOption.bind(s, true)); + opt.suffix = " >"; opt.editorFlashColor = s.color.getDefault(FlxColor.WHITE); return opt; } public function new() { - super('editor.chart.name', 'charterSelection.desc', 'charterSelection.', 'newSong', 'newSongDesc', () -> { + super('editor.chart.name', 'charterSelection.desc', 'charterSelection.', 'newSong', 'newSongDesc', #if sys () -> { parent.openSubState(new SongCreationScreen(saveSong)); - }); + } #end); freeplayList = FreeplaySonglist.get(false); for (i => s in freeplayList.songs) add(makeSongOption(s)); } #if sys - public function saveSong(creation:SongCreationData, ?callback:String -> SongCreationData -> Void) { - var songAlreadyExists:Bool = songList.contains(creation.meta.name.toLowerCase()); - if (songAlreadyExists) { + public function saveSong(creation:SongCreationData, ?callback:String -> Void) { + var variant = creation.meta.variant != null && creation.meta.variant != "" ? creation.meta.variant : null; + if (songList.contains(creation.meta.name.toLowerCase()) || (variant != null && curSong != null && curSong.variants.contains(variant))) { parent.openSubState(new UIWarningSubstate(TU.translate("chartCreation.warnings.song-exists-title"), TU.translate("chartCreation.warnings.song-exists-body"), [ {label: TU.translate("editor.ok"), color: 0xFFFF0000, onClick: (t) -> {}}, ])); @@ -74,6 +91,7 @@ class CharterSelectionScreen extends EditorTreeMenuScreen { } var songFolder:String = '${Paths.getAssetsRoot()}/songs/${creation.meta.name}'; + creation.meta = Chart.filterMetaForSaving(creation.meta); #if sys // Make Directories @@ -82,24 +100,32 @@ class CharterSelectionScreen extends EditorTreeMenuScreen { sys.FileSystem.createDirectory('$songFolder/charts'); // Save Files - CoolUtil.safeSaveFile('$songFolder/meta.json', Chart.makeMetaSaveable(creation.meta)); - if (creation.instBytes != null) sys.io.File.saveBytes('$songFolder/song/Inst.${Flags.SOUND_EXT}', creation.instBytes); - if (creation.voicesBytes != null) sys.io.File.saveBytes('$songFolder/song/Voices.${Flags.SOUND_EXT}', creation.voicesBytes); + var instSuffix = creation.meta.instSuffix != null ? creation.meta.instSuffix : '', vocalsSuffix = creation.meta.vocalsSuffix != null ? creation.meta.vocalsSuffix : ''; + CoolUtil.safeSaveFile('$songFolder/meta${variant != null ? "-" + variant : ""}.json', Json.stringify(creation.meta, null, Flags.JSON_PRETTY_PRINT)); + if (creation.instBytes != null) sys.io.File.saveBytes('$songFolder/song/Inst$instSuffix.${Flags.SOUND_EXT}', creation.instBytes); + if (creation.voicesBytes != null) sys.io.File.saveBytes('$songFolder/song/Voices$vocalsSuffix.${Flags.SOUND_EXT}', creation.voicesBytes); - if (creation.playerVocals != null) sys.io.File.saveBytes('$songFolder/song/Voices-Player.${Flags.SOUND_EXT}', creation.playerVocals); - if (creation.oppVocals != null) sys.io.File.saveBytes('$songFolder/song/Voices-Opponent.${Flags.SOUND_EXT}', creation.oppVocals); + if (creation.playerVocals != null) sys.io.File.saveBytes('$songFolder/song/Voices-Player$vocalsSuffix.${Flags.SOUND_EXT}', creation.playerVocals); + if (creation.oppVocals != null) sys.io.File.saveBytes('$songFolder/song/Voices-Opponent$vocalsSuffix.${Flags.SOUND_EXT}', creation.oppVocals); #end - if (callback != null) callback(songFolder, creation); + if (callback != null) callback(songFolder); // Add to List - freeplayList.songs.insert(0, creation.meta); - insert(1, makeSongOption(creation.meta)); + if (variant != null && curSong != null) { + curSong.variants.push(variant); + curSong.metas.set(variant, creation.meta); + + parent.tree.last().add(makeVariationOption(creation.meta)); + } + else { + freeplayList.songs.insert(0, creation.meta); + insert(1, makeSongOption(creation.meta)); + } } public function saveChart(name:String, data:ChartData) { - var difficultyAlreadyExists:Bool = curSong.difficulties.contains(name); - if (difficultyAlreadyExists) { + if (curSong.difficulties.contains(name)) { parent.openSubState(new UIWarningSubstate(TU.translate("chartCreation.warnings.chart-exists-title"), TU.translate("chartCreation.warnings.chart-exists-body"), [ {label: TU.translate("editor.ok"), color: 0xFFFF0000, onClick: (t) -> {}}, ])); @@ -113,11 +139,16 @@ class CharterSelectionScreen extends EditorTreeMenuScreen { // Add to List curSong.difficulties.push(name); - parent.tree.last().insert(parent.tree.last().length - 1, makeChartOption(name, curSong.name)); + + var screen = parent.tree.last(); + var idx = 0; + while (!(screen.members[idx] is Separator)) idx++; + screen.insert(idx, makeChartOption(name, curSong.variant != null && curSong.variant != "" ? curSong.variant : null, curSong.name)); // Add to Meta var meta = Json.parse(sys.io.File.getContent('$songFolder/meta.json')); - if (meta.difficulties != null && !meta.difficulties.contains(name)) { + if (meta.difficulties == null) meta.difficulties = []; + if (!meta.difficulties.contains(name)) { meta.difficulties.push(name); CoolUtil.safeSaveFile('$songFolder/meta.json', Chart.makeMetaSaveable(meta)); } diff --git a/source/funkin/editors/charter/SongCreationScreen.hx b/source/funkin/editors/charter/SongCreationScreen.hx index 5528640d..869c7ba9 100644 --- a/source/funkin/editors/charter/SongCreationScreen.hx +++ b/source/funkin/editors/charter/SongCreationScreen.hx @@ -23,7 +23,7 @@ typedef SongCreationData = { } class SongCreationScreen extends UISubstateWindow { - private var onSave:Null -> Null SongCreationData -> Void> -> Void = null; + private var onSave:Null -> Null Void> -> Void = null; public var songNameTextBox:UITextBox; public var bpmStepper:UINumericStepper; @@ -42,7 +42,6 @@ class SongCreationScreen extends UISubstateWindow { public var difficultiesTextBox:UITextBox; public var engineDropdown:UIDropDown; - public var createSong:UIButton; public var importInstExplorer:UIFileExplorer; public var importVoicesExplorer:UIFileExplorer; @@ -72,7 +71,7 @@ class SongCreationScreen extends UISubstateWindow { public var curPage:Int = 0; - public function new(?onSave:SongCreationData -> Null SongCreationData -> Void> -> Void) { + public function new(?onSave:SongCreationData -> Null Void> -> Void) { super(); if (onSave != null) this.onSave = onSave; } @@ -190,14 +189,6 @@ class SongCreationScreen extends UISubstateWindow { selectFormatGroup.add(engineDropdown); addLabelOn(engineDropdown, translate("importChartFormat")); - createSong = new UIButton(windowSpr.x + 20, windowSpr.y + windowSpr.bHeight - 16 - 32, "< " + translate("back"), function() { - winTitle = translate("win-title"); - isImporting = false; - updatePagesTexts(); - refreshPages(); - }, 120); - selectFormatGroup.add(createSong); - var menuTitle:UIText; importAudioGroup.add(menuTitle = new UIText(windowSpr.x + 20, windowSpr.y + 30 + 16, 0, translate("importAudios"), 28)); @@ -341,7 +332,7 @@ class SongCreationScreen extends UISubstateWindow { backButton.x = (saveButton.x = windowSpr.x + windowSpr.bWidth - 20 - 125) - 20 - saveButton.bWidth; closeButton.x = (curPage > 0 ? backButton : saveButton).x - 20 - saveButton.bWidth; - for (button in [saveButton, backButton, closeButton, importFrom, createSong]) + for (button in [saveButton, backButton, closeButton, importFrom]) button.y = windowSpr.y + windowSpr.bHeight - 16 - 32; } @@ -356,6 +347,12 @@ class SongCreationScreen extends UISubstateWindow { iconSprite.scrollFactor.set(1, 1); } + // for variations + function formatMeta(meta:ChartMetaData):ChartMetaData return meta; + + function getChartSavePath(meta:ChartMetaData, diff:String):String + return 'charts/${meta.variant != null && meta.variant != "" ? meta.variant + "/" : ""}$diff.json'; + function saveSongInfo() { if (isImporting) { @@ -390,20 +387,21 @@ class SongCreationScreen extends UISubstateWindow { codenameChart: true }; PsychParser.parse(oldChart, base); + var meta = formatMeta({ + name: songId, + difficulties: ['normal'], + bpm: oldChart.bpm, + beatsPerMeasure: oldChart.beatsPerMeasure, + stepsPerBeat: oldChart.stepsPerBeat, + displayName: oldChart.song + }); if (onSave != null) onSave({ - meta: { - name: songId, - difficulties: [songId], - bpm: oldChart.bpm, - beatsPerMeasure: oldChart.beatsPerMeasure, - stepsPerBeat: oldChart.stepsPerBeat, - displayName: oldChart.song - }, + meta: meta, instBytes: importInstExplorer.file, voicesBytes: importVoicesExplorer.file, - }, (songFolder:String, creation:SongCreationData) -> { + }, (songFolder:String) -> { #if sys - CoolUtil.safeSaveFile('$songFolder/charts/${songId}.json', Json.stringify(base, Flags.JSON_PRETTY_PRINT)); + CoolUtil.safeSaveFile('$songFolder/${getChartSavePath(meta, "normal")}', Json.stringify(base, Flags.JSON_PRETTY_PRINT)); #end }); } catch (e:haxe.Exception) { @@ -415,7 +413,7 @@ class SongCreationScreen extends UISubstateWindow { for (stepper in [bpmStepper, beatsPerMeasureStepper, denominatorStepper]) @:privateAccess stepper.__onChange(stepper.label.text); - var meta:ChartMetaData = { + var meta:ChartMetaData = formatMeta({ name: songNameTextBox.label.text, bpm: bpmStepper.value, beatsPerMeasure: Std.int(beatsPerMeasureStepper.value), @@ -426,7 +424,7 @@ class SongCreationScreen extends UISubstateWindow { opponentModeAllowed: opponentModeCheckbox.checked, coopAllowed: coopAllowedCheckbox.checked, difficulties: [for (diff in difficultiesTextBox.label.text.split(",")) diff.trim()], - }; + }); if (onSave != null) onSave({ meta: meta, @@ -445,6 +443,7 @@ class SongCreationScreen extends UISubstateWindow { var meta:ChartMetaData = {name: songId}; var diffCharts:Array = []; VSliceParser.parse(vslicemeta, vslicechart, meta, diffCharts, songId); + formatMeta(meta); if (onSave != null) onSave({ meta: meta, @@ -452,9 +451,9 @@ class SongCreationScreen extends UISubstateWindow { voicesBytes: files.get('Voices.${Flags.SOUND_EXT}'), //it may exist playerVocals: files.get('Voices-${playData.characters.playerVocals != null ? playData.characters.playerVocals[0] : playData.characters.player}.${Flags.SOUND_EXT}'), oppVocals: files.get('Voices-${playData.characters.opponentVocals != null ? playData.characters.opponentVocals[0] : playData.characters.opponent}.${Flags.SOUND_EXT}'), - }, (songFolder:String, creation:SongCreationData) -> { + }, (songFolder:String) -> { #if sys - for (diff in diffCharts) CoolUtil.safeSaveFile('$songFolder/charts/${diff.diffName}.json', Json.stringify(diff.chart, Flags.JSON_PRETTY_PRINT)); + for (diff in diffCharts) CoolUtil.safeSaveFile('$songFolder/${getChartSavePath(meta, diff.diffName)}', Json.stringify(diff.chart, Flags.JSON_PRETTY_PRINT)); #end }); } diff --git a/source/funkin/editors/charter/VariationCreationScreen.hx b/source/funkin/editors/charter/VariationCreationScreen.hx new file mode 100644 index 00000000..132bda75 --- /dev/null +++ b/source/funkin/editors/charter/VariationCreationScreen.hx @@ -0,0 +1,44 @@ +package funkin.editors.charter; + +import flixel.text.FlxText.FlxTextFormat; +import flixel.text.FlxText.FlxTextFormatMarkerPair; +import funkin.backend.chart.ChartData; +import funkin.editors.charter.SongCreationScreen; + +class VariationCreationScreen extends SongCreationScreen { + public var parentMeta:ChartMetaData; + + public function new(parent:ChartMetaData, ?onSave:SongCreationData -> Null Void> -> Void) { + super(onSave); + this.parentMeta = parent; + } + + override function create() { + super.create(); + + songNameTextBox.label.text = translateMeta("variation"); + cast(songNameTextBox.members[songNameTextBox.members.length - 1], UIText).text = translateMeta("variation"); + + cast(importIdTextBox.members[importIdTextBox.members.length - 1], UIText).applyMarkup( + translate("variation"), + [new FlxTextFormatMarkerPair(new FlxTextFormat(0xFFAD1212), "$")] + ); + + bpmStepper.value = parentMeta.bpm; + beatsPerMeasureStepper.value = parentMeta.beatsPerMeasure; + denominatorStepper.value = Std.int(16 / parentMeta.stepsPerBeat); + displayNameTextBox.label.text = parentMeta.displayName; + iconTextBox.label.text = parentMeta.icon; + opponentModeCheckbox.checked = parentMeta.opponentModeAllowed; + coopAllowedCheckbox.checked = parentMeta.coopAllowed; + colorWheel.setColor(parentMeta.color); + difficultiesTextBox.label.text = parentMeta.difficulties.join(', '); + } + + override function formatMeta(meta:ChartMetaData):ChartMetaData { + meta.variant = meta.name; + meta.vocalsSuffix = meta.instSuffix = '-${meta.variant}'; + meta.name = parentMeta.name; + return meta; + } +} \ No newline at end of file diff --git a/source/funkin/editors/ui/UIColorwheel.hx b/source/funkin/editors/ui/UIColorwheel.hx index c1ac432f..cc348a0e 100644 --- a/source/funkin/editors/ui/UIColorwheel.hx +++ b/source/funkin/editors/ui/UIColorwheel.hx @@ -31,7 +31,6 @@ class UIColorwheel extends UISliceSprite { hue = curColor.hue; saturation = curColor.saturation; brightness = curColor.brightness; colorPickerShader = new CustomShader("engine/colorPicker"); - colorPickerShader.hset("hue", hue); colorPicker = new FlxSprite(x + 12.5, (y + 125/2) - (100/2)).makeGraphic(100, 100, FlxColor.TRANSPARENT); colorPicker.drawRoundRect(0, 0, 100, 100, 10, 10, FlxColor.WHITE); @@ -91,6 +90,11 @@ class UIColorwheel extends UISliceSprite { updateWheel(false); } + public function setColor(color:FlxColor) { + hue = curColor.hue; saturation = curColor.saturation; brightness = curColor.brightness; + updateWheel(false); + } + inline function updateColorPickerSelector() colorPickerSelector.selector.setPosition(colorPicker.x + (colorPicker.width *saturation) - 8, colorPicker.y + (colorPicker.height + (colorPicker.height * -brightness))- 8); diff --git a/source/funkin/options/TreeMenuScreen.hx b/source/funkin/options/TreeMenuScreen.hx index 33883fc0..c5b26678 100644 --- a/source/funkin/options/TreeMenuScreen.hx +++ b/source/funkin/options/TreeMenuScreen.hx @@ -128,11 +128,12 @@ class TreeMenuScreen extends FlxSpriteGroup { var i = curSelected, y = initY, object:FlxSprite = null, itemHeight:Float = 0; inline function updateItem() { - object.y = CoolUtil.fpsLerp(object.y, y - (itemHeight = object.height) * 0.5, r); + object.y = CoolUtil.fpsLerp(object.y, y - itemHeight * 0.5, r); object.x = x + 100 - Math.pow(Math.abs((object.y - (FlxG.height - itemHeight) * 0.5) / itemHeight / FlxG.height * FlxG.initialHeight), 1.6) * 15; } while (i < length) if ((object = members[i++]) != null) { + itemHeight = object.height; updateItem(); y += itemHeight; } @@ -140,7 +141,7 @@ class TreeMenuScreen extends FlxSpriteGroup { y = initY; i = curSelected; while (i-- > 0) if ((object = members[i]) != null) { - y -= itemHeight; + y -= (itemHeight = object.height); updateItem(); } } diff --git a/source/funkin/options/type/NewOption.hx b/source/funkin/options/type/NewOption.hx index 85181412..e9d6a00b 100644 --- a/source/funkin/options/type/NewOption.hx +++ b/source/funkin/options/type/NewOption.hx @@ -10,7 +10,7 @@ class NewOption extends TextOption { public function new(name:String, desc:String, callback:Void->Void) { super(name, desc, callback); - itemHeight = 160; + itemHeight = 150; __text.color = FlxColor.LIME; __text.x = 100; diff --git a/source/funkin/savedata/FunkinSave.hx b/source/funkin/savedata/FunkinSave.hx index 851b5c1f..5d43a40d 100644 --- a/source/funkin/savedata/FunkinSave.hx +++ b/source/funkin/savedata/FunkinSave.hx @@ -49,8 +49,9 @@ class FunkinSave { __load(); if (save.data.highscores != null) { var temp; - for (entryData in Reflect.fields(save.data.highscores)) if ((temp = __getHighscoreEntry(entryData)) != null) - highscores.set(temp, Reflect.field(save.data.highscores, entryData)); + for (entryData in Reflect.fields(save.data.highscores)) + if ((temp = __getHighscoreEntry(entryData)) != null && Reflect.field(save.data.highscores, entryData) != null) + highscores.set(temp, Reflect.field(save.data.highscores, entryData)); } }