mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2024-12-27 23:46:45 +00:00
Merge pull request #128 from FunkinCrew/feature/chart-editor-difficulty-stuff
Chart Editor: Difficulty tweaks and bug fixes
This commit is contained in:
commit
280ecc2003
|
@ -55,7 +55,7 @@ class MainMenuState extends MusicBeatState
|
|||
transIn = FlxTransitionableState.defaultTransIn;
|
||||
transOut = FlxTransitionableState.defaultTransOut;
|
||||
|
||||
if (!FlxG.sound.music.playing)
|
||||
if (!(FlxG?.sound?.music?.playing ?? false))
|
||||
{
|
||||
FlxG.sound.playMusic(Paths.music('freakyMenu/freakyMenu'));
|
||||
}
|
||||
|
|
|
@ -297,7 +297,7 @@ class SongDifficulty
|
|||
public var songName:String = SongValidator.DEFAULT_SONGNAME;
|
||||
public var songArtist:String = SongValidator.DEFAULT_ARTIST;
|
||||
public var timeFormat:SongTimeFormat = SongValidator.DEFAULT_TIMEFORMAT;
|
||||
public var divisions:Int = SongValidator.DEFAULT_DIVISIONS;
|
||||
public var divisions:Null<Int> = SongValidator.DEFAULT_DIVISIONS;
|
||||
public var looped:Bool = SongValidator.DEFAULT_LOOPED;
|
||||
public var generatedBy:String = SongValidator.DEFAULT_GENERATEDBY;
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import haxe.DynamicAccess;
|
|||
import haxe.Json;
|
||||
import openfl.utils.Assets;
|
||||
import thx.semver.Version;
|
||||
import funkin.util.SerializerUtil;
|
||||
|
||||
/**
|
||||
* Contains utilities for loading and parsing stage data.
|
||||
|
@ -138,13 +139,8 @@ class SongDataParser
|
|||
{
|
||||
var result:Array<SongMetadata> = [];
|
||||
|
||||
var rawJson:String = loadSongMetadataFile(songId);
|
||||
var jsonData:Dynamic = null;
|
||||
try
|
||||
{
|
||||
jsonData = Json.parse(rawJson);
|
||||
}
|
||||
catch (e) {}
|
||||
var jsonStr:String = loadSongMetadataFile(songId);
|
||||
var jsonData:Dynamic = SerializerUtil.fromJSON(jsonStr);
|
||||
|
||||
var songMetadata:SongMetadata = SongMigrator.migrateSongMetadata(jsonData, songId);
|
||||
songMetadata = SongValidator.validateSongMetadata(songMetadata, songId);
|
||||
|
@ -160,9 +156,10 @@ class SongDataParser
|
|||
|
||||
for (variation in variations)
|
||||
{
|
||||
var variationRawJson:String = loadSongMetadataFile(songId, variation);
|
||||
var variationSongMetadata:SongMetadata = SongMigrator.migrateSongMetadata(variationRawJson, '${songId}_${variation}');
|
||||
variationSongMetadata = SongValidator.validateSongMetadata(variationSongMetadata, '${songId}_${variation}');
|
||||
var variationJsonStr:String = loadSongMetadataFile(songId, variation);
|
||||
var variationJsonData:Dynamic = SerializerUtil.fromJSON(variationJsonStr);
|
||||
var variationSongMetadata:SongMetadata = SongMigrator.migrateSongMetadata(variationJsonData, '${songId}:${variation}');
|
||||
variationSongMetadata = SongValidator.validateSongMetadata(variationSongMetadata, '${songId}:${variation}');
|
||||
if (variationSongMetadata != null)
|
||||
{
|
||||
variationSongMetadata.variation = variation;
|
||||
|
@ -269,7 +266,7 @@ typedef RawSongMetadata =
|
|||
var songName:String;
|
||||
var artist:String;
|
||||
var timeFormat:SongTimeFormat;
|
||||
var divisions:Int;
|
||||
var divisions:Null<Int>; // Optional field
|
||||
var timeChanges:Array<SongTimeChange>;
|
||||
var looped:Bool;
|
||||
var playData:SongPlayData;
|
||||
|
@ -292,7 +289,7 @@ abstract SongMetadata(RawSongMetadata)
|
|||
songName: songName,
|
||||
artist: artist,
|
||||
timeFormat: 'ms',
|
||||
divisions: 96,
|
||||
divisions: null,
|
||||
timeChanges: [new SongTimeChange(-1, 0, 100, 4, 4, [4, 4, 4, 4])],
|
||||
looped: false,
|
||||
playData:
|
||||
|
|
|
@ -15,7 +15,7 @@ class SongValidator
|
|||
public static final DEFAULT_SONGNAME:String = "Unknown";
|
||||
public static final DEFAULT_ARTIST:String = "Unknown";
|
||||
public static final DEFAULT_TIMEFORMAT:SongTimeFormat = SongTimeFormat.MILLISECONDS;
|
||||
public static final DEFAULT_DIVISIONS:Int = -1;
|
||||
public static final DEFAULT_DIVISIONS:Null<Int> = null;
|
||||
public static final DEFAULT_LOOPED:Bool = false;
|
||||
public static final DEFAULT_STAGE:String = "mainStage";
|
||||
public static final DEFAULT_SCROLLSPEED:Float = 1.0;
|
||||
|
|
|
@ -115,7 +115,12 @@ class ChartEditorDialogHandler
|
|||
|
||||
if (songData == null) continue;
|
||||
|
||||
var songName:String = songData.getDifficulty().songName;
|
||||
var songName:Null<String> = songData.getDifficulty('normal') ?.songName;
|
||||
if (songName == null) songName = songData.getDifficulty() ?.songName;
|
||||
if (songName == null)
|
||||
{
|
||||
trace('[WARN] Could not fetch song name for ${targetSongId}');
|
||||
}
|
||||
|
||||
var linkTemplateSong:Link = new Link();
|
||||
linkTemplateSong.text = songName;
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
package funkin.ui.debug.charting;
|
||||
|
||||
import haxe.ui.components.TextField;
|
||||
import haxe.ui.components.DropDown;
|
||||
import haxe.ui.components.NumberStepper;
|
||||
import haxe.ui.containers.Frame;
|
||||
import flixel.addons.display.FlxSliceSprite;
|
||||
import flixel.addons.display.FlxTiledSprite;
|
||||
import flixel.FlxCamera;
|
||||
|
@ -722,11 +726,38 @@ class ChartEditorState extends HaxeUIState
|
|||
*/
|
||||
var songMetadata:Map<String, SongMetadata>;
|
||||
|
||||
/**
|
||||
* Retrieves the list of variations for the current song.
|
||||
*/
|
||||
var availableVariations(get, null):Array<String>;
|
||||
|
||||
function get_availableVariations():Array<String>
|
||||
{
|
||||
return [for (x in songMetadata.keys()) x];
|
||||
var variations:Array<String> = [for (x in songMetadata.keys()) x];
|
||||
variations.sort(SortUtil.defaultThenAlphabetically.bind('default'));
|
||||
return variations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of difficulties for the current variation of the current song.
|
||||
* ONLY CONTAINS DIFFICULTIES FOR THE CURRENT VARIATION so if on the default variation, erect/nightmare won't be included.
|
||||
*/
|
||||
var availableDifficulties(get, null):Array<String>;
|
||||
|
||||
function get_availableDifficulties():Array<String>
|
||||
{
|
||||
return songMetadata.get(selectedVariation).playData.difficulties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of difficulties for ALL variations of the current song.
|
||||
*/
|
||||
var allDifficulties(get, null):Array<String>;
|
||||
|
||||
function get_allDifficulties():Array<String>
|
||||
{
|
||||
var result:Array<Array<String>> = [for (x in availableVariations) songMetadata.get(x).playData.difficulties];
|
||||
return result.flatten();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -976,6 +1007,11 @@ class ChartEditorState extends HaxeUIState
|
|||
return playableCharData.opponent = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* SIGNALS
|
||||
*/
|
||||
// ==============================
|
||||
// public var onDifficultyChange(default, null):FlxTypedSignal<ChartEditorState->Void> = new FlxTypedSignal<ChartEditorState->Void>();
|
||||
/**
|
||||
* RENDER OBJECTS
|
||||
*/
|
||||
|
@ -1247,7 +1283,6 @@ class ChartEditorState extends HaxeUIState
|
|||
var height:Int = FlxG.height - MENU_BAR_HEIGHT - GRID_TOP_PAD - 200;
|
||||
notePreview = new ChartEditorNotePreview(height);
|
||||
notePreview.y = MENU_BAR_HEIGHT + GRID_TOP_PAD;
|
||||
// TODO: Re-enable.
|
||||
// add(notePreview);
|
||||
}
|
||||
|
||||
|
@ -1438,6 +1473,9 @@ class ChartEditorState extends HaxeUIState
|
|||
addUIChangeListener('menubarItemDownscroll', event -> isViewDownscroll = event.value);
|
||||
setUICheckboxSelected('menubarItemDownscroll', isViewDownscroll);
|
||||
|
||||
addUIClickListener('menubarItemDifficultyUp', _ -> incrementDifficulty(1));
|
||||
addUIClickListener('menubarItemDifficultyDown', _ -> incrementDifficulty(-1));
|
||||
|
||||
addUIChangeListener('menubarItemPlaytestStartTime', event -> playtestStartTime = event.value);
|
||||
setUICheckboxSelected('menubarItemPlaytestStartTime', playtestStartTime);
|
||||
|
||||
|
@ -1584,6 +1622,7 @@ class ChartEditorState extends HaxeUIState
|
|||
handleToolboxes();
|
||||
handlePlaybar();
|
||||
handlePlayhead();
|
||||
// handleNotePreview();
|
||||
|
||||
handleFileKeybinds();
|
||||
handleEditKeybinds();
|
||||
|
@ -2755,7 +2794,105 @@ class ChartEditorState extends HaxeUIState
|
|||
/**
|
||||
* Handle keybinds for View menu items.
|
||||
*/
|
||||
function handleViewKeybinds():Void {}
|
||||
function handleViewKeybinds():Void
|
||||
{
|
||||
if (FlxG.keys.pressed.CONTROL && FlxG.keys.justPressed.LEFT)
|
||||
{
|
||||
incrementDifficulty(-1);
|
||||
}
|
||||
if (FlxG.keys.pressed.CONTROL && FlxG.keys.justPressed.RIGHT)
|
||||
{
|
||||
incrementDifficulty(1);
|
||||
}
|
||||
}
|
||||
|
||||
function incrementDifficulty(change:Int):Void
|
||||
{
|
||||
var currentDifficultyIndex:Int = availableDifficulties.indexOf(selectedDifficulty);
|
||||
var currentAllDifficultyIndex:Int = allDifficulties.indexOf(selectedDifficulty);
|
||||
|
||||
if (currentDifficultyIndex == -1 || currentAllDifficultyIndex == -1)
|
||||
{
|
||||
trace('ERROR determining difficulty index!');
|
||||
}
|
||||
|
||||
var isFirstDiff:Bool = currentAllDifficultyIndex == 0;
|
||||
var isLastDiff:Bool = (currentAllDifficultyIndex == allDifficulties.length - 1);
|
||||
|
||||
var isFirstDiffInVariation:Bool = currentDifficultyIndex == 0;
|
||||
var isLastDiffInVariation:Bool = (currentDifficultyIndex == availableDifficulties.length - 1);
|
||||
|
||||
trace(allDifficulties);
|
||||
|
||||
if (change < 0 && isFirstDiff)
|
||||
{
|
||||
trace('At lowest difficulty! Do nothing.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (change > 0 && isLastDiff)
|
||||
{
|
||||
trace('At highest difficulty! Do nothing.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (change < 0)
|
||||
{
|
||||
trace('Decrement difficulty.');
|
||||
|
||||
// If we reached this point, we are not at the lowest difficulty.
|
||||
if (isFirstDiffInVariation)
|
||||
{
|
||||
// Go to the previous variation, then last difficulty in that variation.
|
||||
var currentVariationIndex:Int = availableVariations.indexOf(selectedVariation);
|
||||
var prevVariation = availableVariations[currentVariationIndex - 1];
|
||||
selectedVariation = prevVariation;
|
||||
|
||||
var prevDifficulty = availableDifficulties[availableDifficulties.length - 1];
|
||||
selectedDifficulty = prevDifficulty;
|
||||
|
||||
refreshDifficultyTreeSelection();
|
||||
refreshSongMetadataToolbox();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Go to previous difficulty in this variation.
|
||||
var prevDifficulty = availableDifficulties[currentDifficultyIndex - 1];
|
||||
selectedDifficulty = prevDifficulty;
|
||||
|
||||
refreshDifficultyTreeSelection();
|
||||
refreshSongMetadataToolbox();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
trace('Increment difficulty.');
|
||||
|
||||
// If we reached this point, we are not at the highest difficulty.
|
||||
if (isLastDiffInVariation)
|
||||
{
|
||||
// Go to next variation, then first difficulty in that variation.
|
||||
var currentVariationIndex:Int = availableVariations.indexOf(selectedVariation);
|
||||
var nextVariation = availableVariations[currentVariationIndex + 1];
|
||||
selectedVariation = nextVariation;
|
||||
|
||||
var nextDifficulty = availableDifficulties[0];
|
||||
selectedDifficulty = nextDifficulty;
|
||||
|
||||
refreshDifficultyTreeSelection();
|
||||
refreshSongMetadataToolbox();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Go to next difficulty in this variation.
|
||||
var nextDifficulty = availableDifficulties[currentDifficultyIndex + 1];
|
||||
selectedDifficulty = nextDifficulty;
|
||||
|
||||
refreshDifficultyTreeSelection();
|
||||
refreshSongMetadataToolbox();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle keybinds for the Test menu items.
|
||||
|
@ -2801,10 +2938,14 @@ class ChartEditorState extends HaxeUIState
|
|||
// Clear the tree view so we can rebuild it.
|
||||
treeView.clearNodes();
|
||||
|
||||
var treeSong:TreeViewNode = treeView.addNode({id: 'stv_song', text: 'S: $currentSongName', icon: 'haxeui-core/styles/default/haxeui_tiny.png'});
|
||||
// , icon: 'haxeui-core/styles/default/haxeui_tiny.png'
|
||||
var treeSong:TreeViewNode = treeView.addNode({id: 'stv_song', text: 'S: $currentSongName'});
|
||||
treeSong.expanded = true;
|
||||
|
||||
for (curVariation in availableVariations)
|
||||
var variations = Reflect.copy(availableVariations);
|
||||
variations.sort(SortUtil.alphabetically);
|
||||
|
||||
for (curVariation in variations)
|
||||
{
|
||||
var variationMetadata:SongMetadata = songMetadata.get(curVariation);
|
||||
|
||||
|
@ -2828,10 +2969,26 @@ class ChartEditorState extends HaxeUIState
|
|||
}
|
||||
|
||||
treeView.onChange = onChangeTreeDifficulty;
|
||||
treeView.selectedNode = getCurrentTreeDifficultyNode();
|
||||
refreshDifficultyTreeSelection(treeView);
|
||||
}
|
||||
}
|
||||
|
||||
function refreshDifficultyTreeSelection(?treeView:TreeView):Void
|
||||
{
|
||||
if (treeView == null)
|
||||
{
|
||||
// Manage the Select Difficulty tree view.
|
||||
var difficultyToolbox:CollapsibleDialog = ChartEditorToolboxHandler.getToolbox(this, CHART_EDITOR_TOOLBOX_DIFFICULTY_LAYOUT);
|
||||
if (difficultyToolbox == null) return;
|
||||
|
||||
treeView = difficultyToolbox.findComponent('difficultyToolboxTree');
|
||||
if (treeView == null) return;
|
||||
}
|
||||
|
||||
trace(treeView);
|
||||
treeView.selectedNode = getCurrentTreeDifficultyNode(treeView);
|
||||
}
|
||||
|
||||
function handlePlayerPreviewToolbox():Void
|
||||
{
|
||||
// Manage the Select Difficulty tree view.
|
||||
|
@ -2938,20 +3095,28 @@ class ChartEditorState extends HaxeUIState
|
|||
}
|
||||
}
|
||||
|
||||
function getCurrentTreeDifficultyNode():TreeViewNode
|
||||
function getCurrentTreeDifficultyNode(?treeView:TreeView = null):TreeViewNode
|
||||
{
|
||||
var treeView:TreeView = findComponent('difficultyToolboxTree');
|
||||
if (treeView == null)
|
||||
{
|
||||
var difficultyToolbox:CollapsibleDialog = ChartEditorToolboxHandler.getToolbox(this, CHART_EDITOR_TOOLBOX_DIFFICULTY_LAYOUT);
|
||||
if (difficultyToolbox == null) return null;
|
||||
|
||||
if (treeView == null) return null;
|
||||
treeView = difficultyToolbox.findComponent('difficultyToolboxTree');
|
||||
if (treeView == null) return null;
|
||||
}
|
||||
|
||||
var result:TreeViewNode = treeView.findNodeByPath('stv_song/stv_variation_$selectedVariation/stv_difficulty_${selectedVariation}_$selectedDifficulty',
|
||||
'id');
|
||||
|
||||
if (result == null) return null;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when selecting a tree element in the Difficulty toolbox.
|
||||
* @param event The click event.
|
||||
*/
|
||||
function onChangeTreeDifficulty(event:UIEvent):Void
|
||||
{
|
||||
// Get the newly selected node.
|
||||
|
@ -2962,7 +3127,7 @@ class ChartEditorState extends HaxeUIState
|
|||
{
|
||||
trace('No target node!');
|
||||
// Reset the user's selection.
|
||||
treeView.selectedNode = getCurrentTreeDifficultyNode();
|
||||
treeView.selectedNode = getCurrentTreeDifficultyNode(treeView);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2974,19 +3139,56 @@ class ChartEditorState extends HaxeUIState
|
|||
|
||||
if (variation != null && difficulty != null)
|
||||
{
|
||||
trace('Changing difficulty to $variation:$difficulty');
|
||||
trace('Changing difficulty to "$variation:$difficulty"');
|
||||
selectedVariation = variation;
|
||||
selectedDifficulty = difficulty;
|
||||
// refreshDifficultyTreeSelection(treeView);
|
||||
refreshSongMetadataToolbox();
|
||||
}
|
||||
// case 'song':
|
||||
// case 'variation':
|
||||
default:
|
||||
// Reset the user's selection.
|
||||
trace('Selected wrong node type, resetting selection.');
|
||||
treeView.selectedNode = getCurrentTreeDifficultyNode();
|
||||
treeView.selectedNode = getCurrentTreeDifficultyNode(treeView);
|
||||
refreshSongMetadataToolbox();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When the difficulty changes, update the song metadata toolbox to reflect the new data.
|
||||
*/
|
||||
function refreshSongMetadataToolbox():Void
|
||||
{
|
||||
var toolbox:CollapsibleDialog = ChartEditorToolboxHandler.getToolbox(this, CHART_EDITOR_TOOLBOX_METADATA_LAYOUT);
|
||||
|
||||
var inputSongName:TextField = toolbox.findComponent('inputSongName', TextField);
|
||||
inputSongName.value = currentSongMetadata.songName;
|
||||
|
||||
var inputSongArtist:TextField = toolbox.findComponent('inputSongArtist', TextField);
|
||||
inputSongArtist.value = currentSongMetadata.artist;
|
||||
|
||||
var inputStage:DropDown = toolbox.findComponent('inputStage', DropDown);
|
||||
inputStage.value = currentSongMetadata.playData.stage;
|
||||
|
||||
var inputNoteSkin:DropDown = toolbox.findComponent('inputNoteSkin', DropDown);
|
||||
inputNoteSkin.value = currentSongMetadata.playData.noteSkin;
|
||||
|
||||
var inputBPM:NumberStepper = toolbox.findComponent('inputBPM', NumberStepper);
|
||||
inputBPM.value = currentSongMetadata.timeChanges[0].bpm;
|
||||
|
||||
var labelScrollSpeed:Label = toolbox.findComponent('labelScrollSpeed', Label);
|
||||
labelScrollSpeed.text = 'Scroll Speed: ${currentSongChartScrollSpeed}x';
|
||||
|
||||
var inputScrollSpeed:Slider = toolbox.findComponent('inputScrollSpeed', Slider);
|
||||
inputScrollSpeed.value = currentSongChartScrollSpeed;
|
||||
|
||||
var frameVariation:Frame = toolbox.findComponent('frameVariation', Frame);
|
||||
frameVariation.text = 'Variation: ${selectedVariation.toTitleCase()}';
|
||||
var frameDifficulty:Frame = toolbox.findComponent('frameDifficulty', Frame);
|
||||
frameDifficulty.text = 'Difficulty: ${selectedDifficulty.toTitleCase()}';
|
||||
}
|
||||
|
||||
function addDifficulty(variation:String):Void {}
|
||||
|
||||
function addVariation(variationId:String):Void
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package funkin.ui.debug.charting;
|
||||
|
||||
import haxe.ui.containers.TreeView;
|
||||
import haxe.ui.containers.TreeViewNode;
|
||||
import funkin.play.character.BaseCharacter.CharacterType;
|
||||
import funkin.play.event.SongEvent;
|
||||
import funkin.play.event.SongEventData;
|
||||
|
@ -17,6 +19,7 @@ import haxe.ui.containers.Box;
|
|||
import haxe.ui.containers.Grid;
|
||||
import haxe.ui.containers.Group;
|
||||
import haxe.ui.containers.VBox;
|
||||
import haxe.ui.containers.Frame;
|
||||
import haxe.ui.containers.dialogs.CollapsibleDialog;
|
||||
import haxe.ui.containers.dialogs.Dialog.DialogButton;
|
||||
import haxe.ui.containers.dialogs.Dialog.DialogEvent;
|
||||
|
@ -36,6 +39,7 @@ enum ChartEditorToolMode
|
|||
/**
|
||||
* Static functions which handle building themed UI elements for a provided ChartEditorState.
|
||||
*/
|
||||
@:allow(funkin.ui.debug.charting.ChartEditorState)
|
||||
class ChartEditorToolboxHandler
|
||||
{
|
||||
public static function setToolboxState(state:ChartEditorState, id:String, shown:Bool):Void
|
||||
|
@ -59,6 +63,29 @@ class ChartEditorToolboxHandler
|
|||
if (toolbox != null)
|
||||
{
|
||||
toolbox.showDialog(false);
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case ChartEditorState.CHART_EDITOR_TOOLBOX_TOOLS_LAYOUT:
|
||||
onShowToolboxTools(state, toolbox);
|
||||
case ChartEditorState.CHART_EDITOR_TOOLBOX_NOTEDATA_LAYOUT:
|
||||
onShowToolboxNoteData(state, toolbox);
|
||||
case ChartEditorState.CHART_EDITOR_TOOLBOX_EVENTDATA_LAYOUT:
|
||||
onShowToolboxEventData(state, toolbox);
|
||||
case ChartEditorState.CHART_EDITOR_TOOLBOX_DIFFICULTY_LAYOUT:
|
||||
onShowToolboxDifficulty(state, toolbox);
|
||||
case ChartEditorState.CHART_EDITOR_TOOLBOX_METADATA_LAYOUT:
|
||||
onShowToolboxMetadata(state, toolbox);
|
||||
case ChartEditorState.CHART_EDITOR_TOOLBOX_CHARACTERS_LAYOUT:
|
||||
onShowToolboxCharacters(state, toolbox);
|
||||
case ChartEditorState.CHART_EDITOR_TOOLBOX_PLAYER_PREVIEW_LAYOUT:
|
||||
onShowToolboxPlayerPreview(state, toolbox);
|
||||
case ChartEditorState.CHART_EDITOR_TOOLBOX_OPPONENT_PREVIEW_LAYOUT:
|
||||
onShowToolboxOpponentPreview(state, toolbox);
|
||||
default:
|
||||
// This happens if you try to load an unknown layout.
|
||||
trace('ChartEditorToolboxHandler.showToolbox() - Unknown toolbox ID: $id');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -75,6 +102,29 @@ class ChartEditorToolboxHandler
|
|||
if (toolbox != null)
|
||||
{
|
||||
toolbox.hideDialog(DialogButton.CANCEL);
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case ChartEditorState.CHART_EDITOR_TOOLBOX_TOOLS_LAYOUT:
|
||||
onHideToolboxTools(state, toolbox);
|
||||
case ChartEditorState.CHART_EDITOR_TOOLBOX_NOTEDATA_LAYOUT:
|
||||
onHideToolboxNoteData(state, toolbox);
|
||||
case ChartEditorState.CHART_EDITOR_TOOLBOX_EVENTDATA_LAYOUT:
|
||||
onHideToolboxEventData(state, toolbox);
|
||||
case ChartEditorState.CHART_EDITOR_TOOLBOX_DIFFICULTY_LAYOUT:
|
||||
onHideToolboxDifficulty(state, toolbox);
|
||||
case ChartEditorState.CHART_EDITOR_TOOLBOX_METADATA_LAYOUT:
|
||||
onHideToolboxMetadata(state, toolbox);
|
||||
case ChartEditorState.CHART_EDITOR_TOOLBOX_CHARACTERS_LAYOUT:
|
||||
onHideToolboxCharacters(state, toolbox);
|
||||
case ChartEditorState.CHART_EDITOR_TOOLBOX_PLAYER_PREVIEW_LAYOUT:
|
||||
onHideToolboxPlayerPreview(state, toolbox);
|
||||
case ChartEditorState.CHART_EDITOR_TOOLBOX_OPPONENT_PREVIEW_LAYOUT:
|
||||
onHideToolboxOpponentPreview(state, toolbox);
|
||||
default:
|
||||
// This happens if you try to load an unknown layout.
|
||||
trace('ChartEditorToolboxHandler.hideToolbox() - Unknown toolbox ID: $id');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -186,6 +236,10 @@ class ChartEditorToolboxHandler
|
|||
return toolbox;
|
||||
}
|
||||
|
||||
static function onShowToolboxTools(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
||||
|
||||
static function onHideToolboxTools(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
||||
|
||||
static function buildToolboxNoteDataLayout(state:ChartEditorState):CollapsibleDialog
|
||||
{
|
||||
var toolbox:CollapsibleDialog = cast state.buildComponent(ChartEditorState.CHART_EDITOR_TOOLBOX_NOTEDATA_LAYOUT);
|
||||
|
@ -230,6 +284,10 @@ class ChartEditorToolboxHandler
|
|||
return toolbox;
|
||||
}
|
||||
|
||||
static function onShowToolboxNoteData(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
||||
|
||||
static function onHideToolboxNoteData(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
||||
|
||||
static function buildToolboxEventDataLayout(state:ChartEditorState):CollapsibleDialog
|
||||
{
|
||||
var toolbox:CollapsibleDialog = cast state.buildComponent(ChartEditorState.CHART_EDITOR_TOOLBOX_EVENTDATA_LAYOUT);
|
||||
|
@ -275,6 +333,10 @@ class ChartEditorToolboxHandler
|
|||
return toolbox;
|
||||
}
|
||||
|
||||
static function onShowToolboxEventData(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
||||
|
||||
static function onHideToolboxEventData(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
||||
|
||||
static function buildEventDataFormFromSchema(state:ChartEditorState, target:Box, schema:SongEventSchema):Void
|
||||
{
|
||||
trace(schema);
|
||||
|
@ -405,6 +467,18 @@ class ChartEditorToolboxHandler
|
|||
return toolbox;
|
||||
}
|
||||
|
||||
static function onShowToolboxDifficulty(state:ChartEditorState, toolbox:CollapsibleDialog):Void
|
||||
{
|
||||
// Update the selected difficulty when reopening the toolbox.
|
||||
var treeView:TreeView = toolbox.findComponent('difficultyToolboxTree');
|
||||
if (treeView == null) return;
|
||||
|
||||
treeView.selectedNode = state.getCurrentTreeDifficultyNode(treeView);
|
||||
trace('selected node: ${treeView.selectedNode}');
|
||||
}
|
||||
|
||||
static function onHideToolboxDifficulty(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
||||
|
||||
static function buildToolboxMetadataLayout(state:ChartEditorState):CollapsibleDialog
|
||||
{
|
||||
var toolbox:CollapsibleDialog = cast state.buildComponent(ChartEditorState.CHART_EDITOR_TOOLBOX_METADATA_LAYOUT);
|
||||
|
@ -464,7 +538,7 @@ class ChartEditorToolboxHandler
|
|||
|
||||
var inputNoteSkin:DropDown = toolbox.findComponent('inputNoteSkin', DropDown);
|
||||
inputNoteSkin.onChange = function(event:UIEvent) {
|
||||
if (event.data.id == null) return;
|
||||
if ((event?.data?.id ?? null) == null) return;
|
||||
state.currentSongMetadata.playData.noteSkin = event.data.id;
|
||||
};
|
||||
inputNoteSkin.value = state.currentSongMetadata.playData.noteSkin;
|
||||
|
@ -489,6 +563,8 @@ class ChartEditorToolboxHandler
|
|||
};
|
||||
inputBPM.value = state.currentSongMetadata.timeChanges[0].bpm;
|
||||
|
||||
var labelScrollSpeed:Label = toolbox.findComponent('labelScrollSpeed', Label);
|
||||
|
||||
var inputScrollSpeed:Slider = toolbox.findComponent('inputScrollSpeed', Slider);
|
||||
inputScrollSpeed.onChange = function(event:UIEvent) {
|
||||
var valid:Bool = event.target.value != null && event.target.value > 0;
|
||||
|
@ -502,12 +578,27 @@ class ChartEditorToolboxHandler
|
|||
{
|
||||
state.currentSongChartScrollSpeed = 1.0;
|
||||
}
|
||||
labelScrollSpeed.text = 'Scroll Speed: ${state.currentSongChartScrollSpeed}x';
|
||||
};
|
||||
inputScrollSpeed.value = state.currentSongChartData.scrollSpeed;
|
||||
inputScrollSpeed.value = state.currentSongChartScrollSpeed;
|
||||
labelScrollSpeed.text = 'Scroll Speed: ${state.currentSongChartScrollSpeed}x';
|
||||
|
||||
var frameVariation:Frame = toolbox.findComponent('frameVariation', Frame);
|
||||
frameVariation.text = 'Variation: ${state.selectedVariation.toTitleCase()}';
|
||||
|
||||
var frameDifficulty:Frame = toolbox.findComponent('frameDifficulty', Frame);
|
||||
frameDifficulty.text = 'Difficulty: ${state.selectedDifficulty.toTitleCase()}';
|
||||
|
||||
return toolbox;
|
||||
}
|
||||
|
||||
static function onShowToolboxMetadata(state:ChartEditorState, toolbox:CollapsibleDialog):Void
|
||||
{
|
||||
state.refreshSongMetadataToolbox();
|
||||
}
|
||||
|
||||
static function onHideToolboxMetadata(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
||||
|
||||
static function buildToolboxCharactersLayout(state:ChartEditorState):CollapsibleDialog
|
||||
{
|
||||
var toolbox:CollapsibleDialog = cast state.buildComponent(ChartEditorState.CHART_EDITOR_TOOLBOX_CHARACTERS_LAYOUT);
|
||||
|
@ -525,6 +616,10 @@ class ChartEditorToolboxHandler
|
|||
return toolbox;
|
||||
}
|
||||
|
||||
static function onShowToolboxCharacters(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
||||
|
||||
static function onHideToolboxCharacters(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
||||
|
||||
static function buildToolboxPlayerPreviewLayout(state:ChartEditorState):CollapsibleDialog
|
||||
{
|
||||
var toolbox:CollapsibleDialog = cast state.buildComponent(ChartEditorState.CHART_EDITOR_TOOLBOX_PLAYER_PREVIEW_LAYOUT);
|
||||
|
@ -549,6 +644,10 @@ class ChartEditorToolboxHandler
|
|||
return toolbox;
|
||||
}
|
||||
|
||||
static function onShowToolboxPlayerPreview(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
||||
|
||||
static function onHideToolboxPlayerPreview(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
||||
|
||||
static function buildToolboxOpponentPreviewLayout(state:ChartEditorState):CollapsibleDialog
|
||||
{
|
||||
var toolbox:CollapsibleDialog = cast state.buildComponent(ChartEditorState.CHART_EDITOR_TOOLBOX_OPPONENT_PREVIEW_LAYOUT);
|
||||
|
@ -572,4 +671,8 @@ class ChartEditorToolboxHandler
|
|||
|
||||
return toolbox;
|
||||
}
|
||||
|
||||
static function onShowToolboxOpponentPreview(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
||||
|
||||
static function onHideToolboxOpponentPreview(state:ChartEditorState, toolbox:CollapsibleDialog):Void {}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,16 @@ class SerializerUtil
|
|||
*/
|
||||
public static function fromJSON(input:String):Dynamic
|
||||
{
|
||||
return Json.parse(input);
|
||||
try
|
||||
{
|
||||
return Json.parse(input);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
trace('An error occurred while parsing JSON from string data');
|
||||
trace(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,6 +6,19 @@ import flixel.util.FlxSort;
|
|||
#end
|
||||
import funkin.play.notes.NoteSprite;
|
||||
|
||||
/**
|
||||
* A set of functions related to sorting.
|
||||
*
|
||||
* NOTE: `Array.sort()` takes a function `(x, y) -> Int`.
|
||||
* If the objects are in the correct order (x before y), return a negative value.
|
||||
* If the objects need to be swapped (y before x), return a negative value.
|
||||
* If the objects are equal, return 0.
|
||||
*
|
||||
* NOTE: `Array.sort()` does NOT guarantee that the order of equal elements. `haxe.ds.ArraySort.sort()` does guarantee this.
|
||||
* NOTE: `Array.sort()` may not be the most efficient sorting algorithm for all use cases (especially if the array is known to be mostly sorted).
|
||||
* You may consider using one of the functions in `funkin.util.tools.ArraySortTools` instead.
|
||||
* NOTE: Both sort functions modify the array in-place. You may consider using `Reflect.copy()` to make a copy of the array before sorting.
|
||||
*/
|
||||
class SortUtil
|
||||
{
|
||||
/**
|
||||
|
@ -30,8 +43,10 @@ class SortUtil
|
|||
|
||||
/**
|
||||
* Sort predicate for sorting strings alphabetically.
|
||||
* @param a The first string to compare.
|
||||
* @param b The second string to compare.
|
||||
*/
|
||||
public static function alphabetically(a:String, b:String)
|
||||
public static function alphabetically(a:String, b:String):Int
|
||||
{
|
||||
a = a.toUpperCase();
|
||||
b = b.toUpperCase();
|
||||
|
@ -39,4 +54,39 @@ class SortUtil
|
|||
// Sort alphabetically. Yes that's how this works.
|
||||
return a == b ? 0 : a > b ? 1 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort predicate which sorts two strings alphabetically, but prioritizes a specific string first.
|
||||
* Example usage: `array.sort(defaultThenAlphabetical.bind('test'))` will sort the array so that the string 'test' is first.
|
||||
* @param a The first string to compare.
|
||||
* @param b The second string to compare.
|
||||
* @param defaultValue The value to prioritize.
|
||||
*/
|
||||
public static function defaultThenAlphabetically(defaultValue:String, a:String, b:String):Int
|
||||
{
|
||||
if (a == b) return 0;
|
||||
if (a == defaultValue) return -1;
|
||||
if (b == defaultValue) return 1;
|
||||
return alphabetically(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort predicate which sorts two strings alphabetically, but prioritizes a specific string first.
|
||||
* Example usage: `array.sort(defaultsThenAlphabetical.bind(['test']))` will sort the array so that the string 'test' is first.
|
||||
* @param a The first string to compare.
|
||||
* @param b The second string to compare.
|
||||
* @param defaultValues The values to prioritize.
|
||||
*/
|
||||
public static function defaultsThenAlphabetically(defaultValues:Array<String>, a:String, b:String):Int
|
||||
{
|
||||
if (a == b) return 0;
|
||||
if (defaultValues.contains(a) && defaultValues.contains(b))
|
||||
{
|
||||
// Sort by index in defaultValues
|
||||
return defaultValues.indexOf(a) - defaultValues.indexOf(b);
|
||||
};
|
||||
if (defaultValues.contains(a)) return -1;
|
||||
if (defaultValues.contains(b)) return 1;
|
||||
return alphabetically(a, b);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue