diff --git a/assets/images/editors/bgs/default.png b/assets/images/editors/bgs/default.png
new file mode 100644
index 00000000..ba4754ed
Binary files /dev/null and b/assets/images/editors/bgs/default.png differ
diff --git a/assets/languages/en/Editors.xml b/assets/languages/en/Editors.xml
index 86ca86ac..e62add53 100644
--- a/assets/languages/en/Editors.xml
+++ b/assets/languages/en/Editors.xml
@@ -46,7 +46,9 @@
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.
@@ -435,6 +437,11 @@
Creating New Character
Character Name $* Required$
Character Image File $* Required$
+
+
+ Creating Character: Error!
+ The character you are trying to create already exists, if you would like to override it delete the character first!
+
@@ -442,6 +449,7 @@
Press ACCEPT to edit this typeface.
New Typeface
+ Press ACCEPT to create a new typeface.
Select a typeface to edit
@@ -554,6 +562,11 @@
Stage Info
Stage Name
Stage Path
+
+
+ Creating Stage: Error!
+ The stage you are trying to create alreadly exists, if you would like to override it delete the stage first!
+
diff --git a/source/funkin/editors/DebugOptions.hx b/source/funkin/editors/DebugOptions.hx
index 0f3dc9fd..e0293319 100644
--- a/source/funkin/editors/DebugOptions.hx
+++ b/source/funkin/editors/DebugOptions.hx
@@ -1,18 +1,57 @@
package funkin.editors;
import funkin.backend.utils.NativeAPI;
-import funkin.options.OptionsScreen;
import funkin.options.TreeMenu;
+import funkin.options.TreeMenuScreen;
import funkin.options.type.*;
class DebugOptions extends TreeMenu {
- public override function create() {
+ var bg:FlxSprite;
+
+ override function create() {
super.create();
+ UIState.setResolutionAware();
+
+ add(bg = new FlxSprite().loadAnimatedGraphic(Paths.image('menus/menuBGBlue')));
+ bg.antialiasing = true;
+ bg.scrollFactor.set();
+ updateBG();
+
+ addMenu(new TreeMenuScreen('DebugOptions.title', 'DebugOptions.desc'));
FlxG.camera.fade(0xFF000000, 0.5, true);
}
+
+ public function updateBG() {
+ var scaleX:Float = FlxG.width / bg.width;
+ var scaleY:Float = FlxG.height / bg.height;
+ bg.scale.x = bg.scale.y = Math.max(scaleX, scaleY) * 1.15;
+ bg.screenCenter();
+ }
+
+ override function onResize(width:Int, height:Int) {
+ super.onResize(width, height);
+ if (!UIState.resolutionAware) return;
+
+ updateBG();
+ }
}
-class DebugOptionsScreen extends OptionsScreen {
+class DebugOptionsScreen extends TreeMenuScreen {
+ public function new() {
+ super('DebugOptions.title', 'DebugOptions.desc', 'DebugOptions.');
+ #if windows
+ add(new TextOption(getNameID("showConsole"), getDescID("showConsole"), () -> NativeAPI.allocConsole()));
+ #end
+ add(new Checkbox(getNameID("editorsResizable"), getDescID("editorsResizable"), "editorsResizable"));
+ add(new Checkbox(getNameID("bypassEditorsResize"), getDescID("bypassEditorsResize"), "bypassEditorsResize"));
+ add(new Checkbox(getNameID("editorSFX"), getDescID("editorSFX"), "editorSFX"));
+ add(new Checkbox(getNameID("editorPrettyPrint"), getDescID("editorPrettyPrint"), "editorPrettyPrint"));
+ add(new Checkbox(getNameID("intensiveBlur"), getDescID("intensiveBlur"), "intensiveBlur"));
+ add(new Checkbox(getNameID("charterAutoSaves"), getDescID("charterAutoSaves"), "charterAutoSaves"));
+ add(new NumOption(getNameID("charterAutoSaveTime"), getDescID("charterAutoSaveTime"), 60, 60*10, 1, "charterAutoSaveTime"));
+ add(new NumOption(getNameID("charterAutoSaveWarningTime"), getDescID("charterAutoSaveWarningTime"), 0, 15, 1, "charterAutoSaveWarningTime"));
+ add(new Checkbox(getNameID("charterAutoSavesSeparateFolder"), getDescID("charterAutoSavesSeparateFolder"), "charterAutoSavesSeparateFolder"));
+ }
}
\ No newline at end of file
diff --git a/source/funkin/editors/EditorTreeMenu.hx b/source/funkin/editors/EditorTreeMenu.hx
index b4904866..afe6dd18 100644
--- a/source/funkin/editors/EditorTreeMenu.hx
+++ b/source/funkin/editors/EditorTreeMenu.hx
@@ -1,28 +1,25 @@
package funkin.editors;
import flixel.addons.display.FlxBackdrop;
-import funkin.menus.MainMenuState;
-import funkin.options.*;
+import funkin.options.type.OptionType;
-class EditorTreeMenu extends TreeMenu {
+class EditorTreeMenu extends funkin.options.TreeMenu {
public var bg:FlxBackdrop;
public var bgType:String = "default";
public var bgMovement:FlxPoint = new FlxPoint();
- public var main:OptionsScreen;
-
- public override function create() {
+ override function create() {
super.create();
-
UIState.setResolutionAware();
-
FlxG.camera.fade(0xFF000000, 0.5, true);
+ }
- bg = new FlxBackdrop();
+ override function createPost() {
+ super.createPost();
+ add(bg = new FlxBackdrop());
bg.loadGraphic(Paths.image('editors/bgs/${bgType}'));
bg.antialiasing = true;
setBackgroundRotation(-5);
- add(bg);
}
public inline function setBackgroundRotation(rotation:Float) {
@@ -30,11 +27,47 @@ class EditorTreeMenu extends TreeMenu {
bg.velocity.set(85, 0).degrees = bg.rotation;
}
- public override function exit() {
- FlxG.switchState(new MainMenuState());
+ override function exit() {
+ FlxG.switchState(new funkin.menus.MainMenuState());
}
- public function onMenuChange() {
-
+ override function update(elapsed:Float) {
+ super.update(elapsed);
+
+ bg.colorTransform.redOffset = lerp(bg.colorTransform.redOffset, 0, 0.0625);
+ bg.colorTransform.greenOffset = lerp(bg.colorTransform.greenOffset, 0, 0.0625);
+ bg.colorTransform.blueOffset = lerp(bg.colorTransform.blueOffset, 0, 0.0625);
+ bg.colorTransform.redMultiplier = lerp(bg.colorTransform.redMultiplier, 1, 0.0625);
+ bg.colorTransform.greenMultiplier = lerp(bg.colorTransform.greenMultiplier, 1, 0.0625);
+ bg.colorTransform.blueMultiplier = lerp(bg.colorTransform.blueMultiplier, 1, 0.0625);
+ }
+
+ override function menuChanged() @:privateAccess {
+ super.menuChanged();
+ if (previousMenus.length > 0) return; // selected a sub-menu
+
+ var prev = tree[tree.length - 2];
+ if (prev == null || prev.curOption == null || !(prev.curOption is OptionType)) return;
+
+ // small flashbang
+ var color = cast(prev.curOption, OptionType).editorFlashColor;
+ bg.colorTransform.redOffset = 0.25 * color.red;
+ bg.colorTransform.greenOffset = 0.25 * color.green;
+ bg.colorTransform.blueOffset = 0.25 * color.blue;
+ bg.colorTransform.redMultiplier = FlxMath.lerp(1, color.redFloat, 0.25);
+ bg.colorTransform.greenMultiplier = FlxMath.lerp(1, color.greenFloat, 0.25);
+ bg.colorTransform.blueMultiplier = FlxMath.lerp(1, color.blueFloat, 0.25);
+ }
+}
+
+class EditorTreeMenuScreen extends funkin.options.TreeMenuScreen {
+ public function new(name:String, desc:String, ?prefix:String, ?objects:Array,
+ ?newButton:String, ?newButtonDesc:String, ?newCallback:Void->Void)
+ {
+ super(name, desc, prefix, objects);
+ if (newCallback != null) {
+ insert(0, new funkin.options.type.NewOption(getID(newButton), getID(newButtonDesc), newCallback));
+ curSelected = 1;
+ }
}
}
\ No newline at end of file
diff --git a/source/funkin/editors/alphabet/AlphabetSelection.hx b/source/funkin/editors/alphabet/AlphabetSelection.hx
index 1b8155ee..9d937a83 100644
--- a/source/funkin/editors/alphabet/AlphabetSelection.hx
+++ b/source/funkin/editors/alphabet/AlphabetSelection.hx
@@ -1,51 +1,35 @@
package funkin.editors.alphabet;
+import haxe.io.Path;
import haxe.xml.Access;
import funkin.game.Character;
-import funkin.options.OptionsScreen;
-import funkin.options.type.IconOption;
+import funkin.editors.EditorTreeMenu;
import funkin.options.type.NewOption;
import funkin.options.type.TextOption;
import funkin.options.type.OptionType;
-import haxe.io.Path;
-class AlphabetSelection extends EditorTreeMenu
-{
- inline function translate(id:String, ?args:Array)
- return TU.translate("editor.alphabet.selection." + id, args);
-
- public override function create()
- {
- bgType = "charter";
+class AlphabetSelection extends EditorTreeMenu {
+ override function create() {
super.create();
+ DiscordUtil.call("onEditorTreeLoaded", ["Alphabet Editor"]);
+ addMenu(new AlphabetSelectionScreen());
+ }
+}
+
+class AlphabetSelectionScreen extends EditorTreeMenuScreen {
+ public function new() {
+ super('editor.alphabet.name', 'editor.alphabet.selection.desc', 'editor.alphabet.selection', 'newTypeface', 'newTypefaceDesc', () -> {
+ parent.openSubState(new UIWarningSubstate(translate('warnings.notImplemented-title'), translate('warnings.notImplemented-body'), [
+ {label: TU.translate("editor.ok"), color: 0xFFFF0000, onClick: (t) -> {}}
+ ]));
+ });
var modsList:Array = [];
- for(file in Paths.getFolderContent('data/alphabet/', true, BOTH)) // mods ? MODS : BOTH
+ for (file in Paths.getFolderContent('data/alphabet/', true, BOTH)) // mods ? MODS : BOTH
if (Path.extension(file) == "xml") modsList.push(CoolUtil.getFilename(file));
- var list:Array = [
- for (typeface in modsList)
- new AlphabetIconOption(typeface, translate("acceptTypeface"), typeface, function() {
- FlxG.switchState(new AlphabetEditor(typeface));
- })
- ];
-
- var newChar = translate("newTypeface");
- list.insert(0, new NewOption(newChar, newChar, function() {
- openSubState(new UIWarningSubstate(translate("warnings.notImplemented-title"), translate("warnings.notImplemented-body"), [
- {label: TU.translate("editor.ok"), color: 0xFFFF0000, onClick: function(t) {}}
- ]));
- }));
-
- main = new OptionsScreen(TU.translate("editor.alphabet.name"), translate("desc"), list);
-
- DiscordUtil.call("onEditorTreeLoaded", ["Alphabet Editor"]);
- }
-
- override function createPost() {
- super.createPost();
-
- main.changeSelection(1);
+ for (typeface in modsList)
+ add(new AlphabetIconOption(typeface, getID('acceptTypeface'), typeface, () -> FlxG.switchState(new AlphabetEditor(typeface))));
}
}
@@ -57,7 +41,7 @@ class AlphabetIconOption extends TextOption {
var xml = Xml.parse(Assets.getText(Paths.xml('alphabet/$typeface'))).firstElement();
var spritesheet = null;
- for(node in xml.elements()) {
+ for (node in xml.elements()) {
if (node.nodeName == "spritesheet") {
spritesheet = node.firstChild().nodeValue;
break;
@@ -73,14 +57,14 @@ class AlphabetIconOption extends TextOption {
iconSpr.frames = Paths.getFrames(spritesheet);
iconSpr.antialiasing = true;
var frameToUse = iconSpr.frames.frames[0];
- for(frame in iconSpr.frames.frames) {
+ for (frame in iconSpr.frames.frames) {
if (frame.name.toUpperCase().startsWith("A")) {
frameToUse = frame;
break;
}
}
iconSpr.frame = frameToUse;
- if(useColorOffsets) {
+ if (useColorOffsets) {
iconSpr.colorTransform.color = -1;
}
iconSpr.setPosition(90 - iconSpr.width - 20, (__text.height - iconSpr.height) / 2);
diff --git a/source/funkin/editors/character/CharacterSelection.hx b/source/funkin/editors/character/CharacterSelection.hx
index 9f009ccb..1b9d2d70 100644
--- a/source/funkin/editors/character/CharacterSelection.hx
+++ b/source/funkin/editors/character/CharacterSelection.hx
@@ -1,81 +1,69 @@
package funkin.editors.character;
import haxe.xml.Printer;
-import funkin.editors.ui.UIImageExplorer.ImageSaveData;
import funkin.game.Character;
-import funkin.options.OptionsScreen;
+import funkin.editors.ui.UIImageExplorer.ImageSaveData;
+import funkin.editors.EditorTreeMenu;
import funkin.options.type.IconOption;
import funkin.options.type.NewOption;
import funkin.options.type.TextOption;
import funkin.options.type.OptionType;
-import funkin.backend.assets.ModsFolder;
-class CharacterSelection extends EditorTreeMenu
-{
- inline function translate(id:String, ?args:Array)
- return TU.translate("characterSelection." + id, args);
+class CharacterSelection extends EditorTreeMenu {
+ override function create() {
+ super.create();
+ DiscordUtil.call("onEditorTreeLoaded", ["Character Editor"]);
+ addMenu(new CharacterSelectionScreen());
+ }
+}
+class CharacterSelectionScreen extends EditorTreeMenuScreen {
public var modsList:Array = [];
- public override function create()
- {
- bgType = "charter";
- super.create();
+ public function new() {
+ super('editor.character.name', 'characterSelection.desc', 'characterSelection.', 'newCharacter', 'newCharacterDesc', () -> {
+ parent.openSubState(new CharacterCreationScreen(createCharacter));
+ });
var isMods:Bool = true;
modsList = Character.getList(true, true);
- if(modsList.length == 0) {
+ if (modsList.length == 0) {
modsList = Character.getList(false, true);
isMods = false;
}
- function generateList(modsList:Array, isMods:Bool, folderPath:String = ""):Array {
- var list:Array = [];
+ function generateList(modsList:Array, isMods:Bool, folderPath:String = ""):Array {
+ var list:Array = [];
- for(char in modsList) {
- if(char.endsWith("/")) {
+ for (char in modsList) {
+ if (char.endsWith("/")) {
var folderName = CoolUtil.getFilename(char.substr(0, char.length-1));
- list.push(new TextOption(folderName + " >", translate("acceptFolder"), function() {
+ list.push(new TextOption(folderName, getID('acceptFolder'), ' >', () -> {
var newModsList = Character.getList(isMods, true, char);
- var newList:Array = generateList(newModsList, isMods, folderPath + folderName + "/");
- optionsTree.add(new OptionsScreen(folderPath + folderName, translate("desc-folder", [folderPath + folderName + "/"]), newList));
+ var newList:Array = generateList(newModsList, isMods, folderPath + folderName + "/");
+ parent.addMenu(new EditorTreeMenuScreen(folderPath + folderName, translate('desc-folder', [folderPath + folderName + "/"]), newList));
+ }));
+ }
+ else {
+ list.push(new IconOption(char, getID('acceptCharacter'), Character.getIconFromCharName(folderPath + char, char), () -> {
+ FlxG.switchState(new CharacterEditor(folderPath + char));
}));
- } else {
- list.push(new IconOption(char, translate("acceptCharacter"), Character.getIconFromCharName(folderPath + char, char),
- function() {
- FlxG.switchState(new CharacterEditor(folderPath + char));
- })
- );
}
}
- list.insert(0, new NewOption(translate("newCharacter"), translate("newCharacterDesc"), function() {
- openSubState(new CharacterCreationScreen(createCharacter));
- }));
-
return list;
}
- var list = generateList(modsList, isMods);
-
- main = new OptionsScreen(TU.translate("editor.character.name"), translate("desc"), list);
-
- DiscordUtil.call("onEditorTreeLoaded", ["Character Editor"]);
- }
-
- override function createPost() {
- super.createPost();
-
- main.changeSelection(1);
+ for (o in generateList(modsList, isMods)) add(o);
}
public function createCharacter(name:String, imageSaveData:ImageSaveData, xml:Xml) {
var characterAlreadyExists:Bool = modsList.contains(name);
if (characterAlreadyExists) {
- openSubState(new UIWarningSubstate("Creating Character: Error!", "The character you are trying to create already exists, if you would like to override it delete the character first!", [
- {label: "Ok", color: 0xFFFF0000, onClick: function(t) {}}
+ parent.openSubState(new UIWarningSubstate(TU.translate('characterCreationScreen.warning.char-exists-title'), TU.translate('characterCreationScreen.warning.char-exists-body'), [
+ {label: TU.translate('editor.ok'), color: 0xFFFF0000, onClick: (t) -> {}}
]));
return;
}
@@ -88,11 +76,10 @@ class CharacterSelection extends EditorTreeMenu
UIImageExplorer.saveFilesGlobal(imageSaveData, '${Paths.getAssetsRoot()}/images/characters');
// Add to Menu >:D
- var option:IconOption = new IconOption(name, "Press ACCEPT to edit this character.", Character.getIconFromCharName(name),
- function() {
- FlxG.switchState(new CharacterEditor(name));
- }
- );
- optionsTree.members[optionsTree.members.length-1].insert(1, option);
+ var option:IconOption = new IconOption(name, getID('acceptCharacter'), Character.getIconFromCharName(name), () -> {
+ FlxG.switchState(new CharacterEditor(name));
+ });
+
+ insert(1, option);
}
}
\ No newline at end of file
diff --git a/source/funkin/editors/charter/CharterSelection.hx b/source/funkin/editors/charter/CharterSelection.hx
index 467817d7..fda0f1c3 100644
--- a/source/funkin/editors/charter/CharterSelection.hx
+++ b/source/funkin/editors/charter/CharterSelection.hx
@@ -1,118 +1,83 @@
package funkin.editors.charter;
+import flixel.util.FlxColor;
import funkin.backend.chart.Chart;
-import funkin.backend.chart.ChartData.ChartMetaData;
import funkin.backend.chart.ChartData;
-import funkin.backend.system.framerate.Framerate;
-import funkin.editors.EditorTreeMenu;
import funkin.editors.charter.SongCreationScreen.SongCreationData;
+import funkin.editors.EditorTreeMenu;
import funkin.menus.FreeplayState.FreeplaySonglist;
-import funkin.options.*;
import funkin.options.type.*;
-import funkin.options.type.NewOption;
import haxe.Json;
using StringTools;
class CharterSelection extends EditorTreeMenu {
- public var freeplayList:FreeplaySonglist;
- public var curSong:ChartMetaData;
- public override function create() {
- bgType = "charter";
-
+ override function create() {
super.create();
+ DiscordUtil.call("onEditorTreeLoaded", ["Chart Editor"]);
+ addMenu(new CharterSelectionScreen());
+ bgType = 'charter';
+ }
+}
- Framerate.offset.y = 60;
+class CharterSelectionScreen extends EditorTreeMenuScreen {
+ public var freeplayList:FreeplaySonglist;
+ 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)));
+ }
+
+ 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 = ' >';
+ opt.color = s.color.getDefault(FlxColor.WHITE);
+
+ return opt;
+ }
+
+ public function new() {
+ super('editor.chart.name', 'charterSelection.desc', 'charterSelection.', 'newSong', 'newSongDesc', () -> {
+ parent.openSubState(new SongCreationScreen(saveSong));
+ });
freeplayList = FreeplaySonglist.get(false);
- var list:Array = [
- for(s in freeplayList.songs) new EditorIconOption(s.name, TU.translate("charterSelection.acceptSong"), s.icon, function() {
- curSong = s;
- var list:Array = [
- for(d in s.difficulties) if (d != "")
- new TextOption(d, TU.translate("charterSelection.acceptDifficulty"), function() {
- FlxG.switchState(new Charter(s.name, d));
- })
- ];
- #if sys
- var newDiff = TU.translate("charterSelection.newDifficulty");
- list.push(new NewOption(newDiff, newDiff, function() {
- FlxG.state.openSubState(new ChartCreationScreen(saveChart));
- }));
- #end
- optionsTree.add(new OptionsScreen(s.name, TU.translate("charterSelection.selectDifficulty"), list));
- }, s.color.getDefault(0xFFFFFFFF))
- ];
-
- #if sys
- var newSong = TU.translate("charterSelection.newSong");
- list.insert(0, new NewOption(newSong, newSong, function() {
- FlxG.state.openSubState(new SongCreationScreen(saveSong));
- }));
- #end
-
- main = new OptionsScreen(TU.translate("editor.chart.name"), TU.translate("charterSelection.desc"), list);
-
- DiscordUtil.call("onEditorTreeLoaded", ["Chart Editor"]);
- }
-
- override function createPost() {
- super.createPost();
-
- main.changeSelection(1);
- }
-
- public override function update(elapsed:Float) {
- super.update(elapsed);
-
- bg.colorTransform.redOffset = lerp(bg.colorTransform.redOffset, 0, 0.0625);
- bg.colorTransform.greenOffset = lerp(bg.colorTransform.greenOffset, 0, 0.0625);
- bg.colorTransform.blueOffset = lerp(bg.colorTransform.blueOffset, 0, 0.0625);
- bg.colorTransform.redMultiplier = lerp(bg.colorTransform.redMultiplier, 1, 0.0625);
- bg.colorTransform.greenMultiplier = lerp(bg.colorTransform.greenMultiplier, 1, 0.0625);
- bg.colorTransform.blueMultiplier = lerp(bg.colorTransform.blueMultiplier, 1, 0.0625);
- }
-
- public override function onMenuChange() {
- super.onMenuChange();
- if (optionsTree.members.length > 1) { // selected a song
- if(main != null) {
- var opt = main.members[main.curSelected];
- if(opt is EditorIconOption) {
- var opt:EditorIconOption = cast opt;
-
- // small flashbang
- var color = opt.flashColor;
- bg.colorTransform.redOffset = 0.25 * color.red;
- bg.colorTransform.greenOffset = 0.25 * color.green;
- bg.colorTransform.blueOffset = 0.25 * color.blue;
- bg.colorTransform.redMultiplier = FlxMath.lerp(1, color.redFloat, 0.25);
- bg.colorTransform.greenMultiplier = FlxMath.lerp(1, color.greenFloat, 0.25);
- bg.colorTransform.blueMultiplier = FlxMath.lerp(1, color.blueFloat, 0.25);
- }
- }
- }
+ for (i => s in freeplayList.songs) add(makeSongOption(s));
}
#if sys
public function saveSong(creation:SongCreationData, ?callback:String -> SongCreationData -> Void) {
- var songAlreadyExists:Bool = [for (s in freeplayList.songs) s.name.toLowerCase()].contains(creation.meta.name.toLowerCase());
-
+ var songAlreadyExists:Bool = songList.contains(creation.meta.name.toLowerCase());
if (songAlreadyExists) {
- 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: function(t) {}},
+ 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) -> {}},
]));
return;
}
- // Paths
- var songsDir:String = '${Paths.getAssetsRoot()}/songs/';
- var songFolder:String = '$songsDir${creation.meta.name}';
+ var songFolder:String = '${Paths.getAssetsRoot()}/songs/${creation.meta.name}';
#if sys
// Make Directories
- sys.FileSystem.createDirectory(songFolder);
+ CoolUtil.addMissingFolders(songFolder);
sys.FileSystem.createDirectory('$songFolder/song');
sys.FileSystem.createDirectory('$songFolder/charts');
@@ -125,52 +90,30 @@ class CharterSelection extends EditorTreeMenu {
if (creation.oppVocals != null) sys.io.File.saveBytes('$songFolder/song/Voices-Opponent.${Flags.SOUND_EXT}', creation.oppVocals);
#end
- if (callback != null)
- callback(songFolder, creation);
-
- var option = new EditorIconOption(creation.meta.name, TU.translate("charterSelection.acceptSong"), creation.meta.icon, function() {
- curSong = creation.meta;
- var list:Array = [
- for(d in creation.meta.difficulties)
- if (d != "") new TextOption(d, TU.translate("charterSelection.acceptDifficulty"), function() {
- FlxG.switchState(new Charter(creation.meta.name, d));
- })
- ];
- var newDiff = TU.translate("charterSelection.newDifficulty");
- list.push(new NewOption(newDiff, newDiff, function() {
- FlxG.state.openSubState(new ChartCreationScreen(saveChart));
- }));
- optionsTree.insert(1, new OptionsScreen(creation.meta.name, TU.translate("charterSelection.selectDifficulty"), list));
- }, creation.meta.color.getDefault(0xFFFFFFFF));
+ if (callback != null) callback(songFolder, creation);
// Add to List
freeplayList.songs.insert(0, creation.meta);
- main.insert(1, option);
+ insert(1, makeSongOption(creation.meta));
}
public function saveChart(name:String, data:ChartData) {
var difficultyAlreadyExists:Bool = curSong.difficulties.contains(name);
-
if (difficultyAlreadyExists) {
- 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: function(t) {}},
+ 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) -> {}},
]));
return;
}
- // Paths
var songFolder:String = '${Paths.getAssetsRoot()}/songs/${curSong.name}';
// Save Files
CoolUtil.safeSaveFile('$songFolder/charts/${name}.json', Json.stringify(data, Flags.JSON_PRETTY_PRINT));
// Add to List
- // duplicated code, todo: fix this
curSong.difficulties.push(name);
- var option = new TextOption(name, TU.translate("charterSelection.acceptDifficulty"), function() {
- FlxG.switchState(new Charter(curSong.name, name));
- });
- optionsTree.members[optionsTree.members.length-1].insert(optionsTree.members[optionsTree.members.length-1].length-1, option);
+ parent.tree.last().insert(parent.tree.last().length - 1, makeChartOption(name, curSong.name));
// Add to Meta
var meta = Json.parse(sys.io.File.getContent('$songFolder/meta.json'));
diff --git a/source/funkin/editors/stage/StageSelection.hx b/source/funkin/editors/stage/StageSelection.hx
index b78aebc3..418e0190 100644
--- a/source/funkin/editors/stage/StageSelection.hx
+++ b/source/funkin/editors/stage/StageSelection.hx
@@ -1,46 +1,47 @@
package funkin.editors.stage;
import funkin.editors.stage.StageCreationScreen.StageCreationData;
+import funkin.editors.EditorTreeMenu;
import funkin.game.Stage;
-import funkin.options.OptionsScreen;
import funkin.options.type.NewOption;
import funkin.options.type.OptionType;
import funkin.options.type.TextOption;
-class StageSelection extends EditorTreeMenu
-{
+using StringTools;
+
+class StageSelection extends EditorTreeMenu {
+ override function create() {
+ super.create();
+ DiscordUtil.call("onEditorTreeLoaded", ["Stage Editor"]);
+ addMenu(new StageSelectionScreen());
+ }
+}
+
+class StageSelectionScreen extends EditorTreeMenuScreen {
public var stages:Array = [];
- public override function create()
- {
- bgType = "charter";
- super.create();
+ public function makeStageOption(stage:String):TextOption {
+ return new TextOption(stage, getID('acceptStage'), () -> {
+ FlxG.switchState(new StageEditor(stage));
+ });
+ }
+
+ public function new() {
+ super('editor.stage.name', 'stageSelection.desc', 'stageSelection.', 'newStage', 'acceptNewStage', () -> {
+ parent.openSubState(new StageCreationScreen(saveStage));
+ });
var modsList:Array = Stage.getList(true, true);
-
- var list:Array = [
- for (stage in (modsList.length == 0 ? Stage.getList(false, true) : modsList)) {
- stages.push(stage);
- new TextOption(stage, TU.translate("stageSelection.acceptStage"),
- function() {
- FlxG.switchState(new StageEditor(stage));
- });
- }
- ];
-
- list.insert(0, new NewOption(TU.translate("stageSelection.newStage"), TU.translate("stageSelection.acceptNewStage"), function() {
- FlxG.state.openSubState(new StageCreationScreen(saveStage));
- }));
-
- main = new OptionsScreen(TU.translate("editor.stage.name"), TU.translate("stageSelection.desc"), list);
-
- DiscordUtil.call("onEditorTreeLoaded", ["Stage Editor"]);
+ for (stage in (modsList.length == 0 ? Stage.getList(false, true) : modsList)) {
+ stages.push(stage.toLowerCase());
+ add(makeStageOption(stage));
+ }
}
public function saveStage(creation:StageCreationData) {
- if ([for (s in stages) s.toLowerCase()].contains(creation.name.toLowerCase())) {
- openSubState(new UIWarningSubstate("Creating Stage: Error!", "The stage you are trying to create alreadly exists, if you would like to override it delete the stage first!", [
- {label: "Ok", color: 0xFFFF0000, onClick: function(t) {}}
+ if (stages.contains(creation.name.toLowerCase())) {
+ parent.openSubState(new UIWarningSubstate(TU.translate("stageCreationScreen.warnings.stage-exists-title"), TU.translate("stageCreationScreen.warnings.stage-exists-body"), [
+ {label: TU.translate("editor.ok"), color: 0xFFFF0000, onClick: (t) -> {}},
]));
return;
}
@@ -51,15 +52,7 @@ class StageSelection extends EditorTreeMenu
#end
// Add to List
- var option = new TextOption(creation.name, TU.translate("stageSelection.acceptStage"), function() {
- FlxG.switchState(new StageEditor(creation.name));
- });
- optionsTree.members[optionsTree.members.length-1].insert(1, option);
- }
-
- override function createPost() {
- super.createPost();
-
- main.changeSelection(1);
+ stages.push(creation.name.toLowerCase());
+ parent.tree.last().insert(parent.tree.last().length - 1, makeStageOption(creation.name));
}
}
\ No newline at end of file
diff --git a/source/funkin/menus/MainMenuState.hx b/source/funkin/menus/MainMenuState.hx
index 1a931781..1a68f4a2 100644
--- a/source/funkin/menus/MainMenuState.hx
+++ b/source/funkin/menus/MainMenuState.hx
@@ -6,7 +6,7 @@ import flixel.tweens.FlxTween;
import funkin.backend.FunkinText;
import funkin.backend.scripting.events.menu.MenuChangeEvent;
import funkin.backend.scripting.events.NameEvent;
-//import funkin.menus.credits.CreditsMain;
+import funkin.menus.credits.CreditsMain;
import funkin.options.OptionsMenu;
import lime.app.Application;
@@ -168,7 +168,7 @@ class MainMenuState extends MusicBeatState
{
case 'story mode': FlxG.switchState(new StoryMenuState());
case 'freeplay': FlxG.switchState(new FreeplayState());
- //case 'donate', 'credits': FlxG.switchState(new CreditsMain()); // kept donate for not breaking scripts, if you don't want donate to bring you to the credits menu, thats easy softcodable - Nex
+ case 'donate', 'credits': FlxG.switchState(new CreditsMain()); // kept donate for not breaking scripts, if you don't want donate to bring you to the credits menu, thats easy softcodable - Nex
case 'options': FlxG.switchState(new OptionsMenu());
}
});
diff --git a/source/funkin/menus/credits/CreditsCodename.hx b/source/funkin/menus/credits/CreditsCodename.hx
new file mode 100644
index 00000000..5448825c
--- /dev/null
+++ b/source/funkin/menus/credits/CreditsCodename.hx
@@ -0,0 +1,135 @@
+package funkin.menus.credits;
+
+import flixel.text.FlxText;
+import flixel.util.FlxColor;
+import funkin.backend.system.github.GitHub;
+import funkin.backend.system.github.GitHubContributor.CreditsGitHubContributor;
+import funkin.options.PlayerSettings;
+import funkin.options.type.GithubIconOption;
+
+using StringTools;
+
+class CreditsCodename extends funkin.options.TreeMenuScreen {
+ public var error:Bool = false;
+ public var totalContributions:Int = 0;
+ public var contribFormats:Array = [];
+
+ public function new() {
+ super("Codename Engine", "credits.allContributors");
+ tryUpdating(true);
+ }
+
+ // blame the secondary threads if the code has to look this bad - Nex
+ private var _canReset:Bool = true;
+ private var _downloadingSteps:Int = 0;
+ override function update(elapsed:Float) {
+ super.update(elapsed);
+
+ if (_downloadingSteps == 2) {
+ _downloadingSteps = 0;
+ _canReset = true;
+ displayList();
+ } else if (_downloadingSteps == 1) {
+ _downloadingSteps = 0;
+ _canReset = true;
+ updateMenuDesc();
+ }
+ else if (_canReset && PlayerSettings.solo.controls.RESET) tryUpdating();
+ }
+
+ public function tryUpdating(forceDisplaying:Bool = false) {
+ updateMenuDesc(TU.translate("credits.downloadingList"));
+ _canReset = false;
+ Main.execAsync(() -> {
+ if (checkUpdate() || forceDisplaying) _downloadingSteps = 2;
+ else _downloadingSteps = 1;
+ });
+ }
+
+ public override function updateMenuDesc(?txt:String) {
+ if (!_canReset) return;
+ super.updateMenuDesc(txt);
+ updateMarkup();
+ }
+
+ public function updateMarkup() {
+ if (parent == null) return;
+ var text:String = parent.descLabel.text;
+ parent.descLabel.text = "";
+ parent.descLabel.applyMarkup(text, contribFormats = [
+ new FlxTextFormatMarkerPair(new FlxTextFormat(Flags.MAIN_DEVS_COLOR), '*'),
+ new FlxTextFormatMarkerPair(new FlxTextFormat(FlxColor.interpolate(Flags.MIN_CONTRIBUTIONS_COLOR, Flags.MAIN_DEVS_COLOR, Options.contributors[curSelected].contributions / totalContributions)), '~')
+ ]);
+ }
+
+ override function destroy() {
+ super.destroy();
+ for (frmt in contribFormats) parent.descLabel.removeFormat(frmt.format);
+ }
+
+ public function checkUpdate():Bool {
+ var curTime:Float = Date.now().getTime();
+ if(Options.lastUpdated != null && curTime < Options.lastUpdated + 120000) return false; // Fuck you Github rate limits - Nex
+ Options.lastUpdated = curTime;
+
+ error = false;
+ var idk = GitHub.getContributors(Flags.REPO_OWNER, Flags.REPO_NAME, function(e) {
+ error = true;
+ var errMsg:String = 'Error while trying to download contributors list:\n${CoolUtil.removeIP(e.message)}';
+ Logs.error(errMsg.replace('\n', ' '));
+ funkin.backend.utils.NativeAPI.showMessageBox("Codename Engine Warning", errMsg, MSG_WARNING);
+ });
+ if(error) return false;
+ if((idk is Array)) {
+ var contributors:Array = [];
+ for(e in idk) contributors.push({
+ login: e.login,
+ avatar_url: e.avatar_url,
+ html_url: e.html_url,
+ id: e.id,
+ contributions: e.contributions
+ });
+ Options.contributors = contributors;
+ }
+ Logs.verbose('[CreditsCodename] Contributors list Updated!');
+
+ var errorOnMain:Bool = false;
+ var idk2 = GitHub.getOrganizationMembers(Flags.REPO_OWNER, function(e) {
+ errorOnMain = true;
+ var errMsg:String = 'Error while trying to download ${Flags.REPO_OWNER} members list:\n${CoolUtil.removeIP(e.message)}';
+ Logs.error(errMsg.replace('\n', ' '));
+ funkin.backend.utils.NativeAPI.showMessageBox("Codename Engine Warning", errMsg, MSG_WARNING);
+ });
+ if(!errorOnMain) {
+ Options.mainDevs = [for(m in idk2) m.id];
+ Logs.verbose('[CreditsCodename] Main Devs list Updated!');
+ }
+
+ return true;
+ }
+
+ public function displayList() {
+ //if (curSelected > Options.contributors.length - 1) changeSelection(-(curSelected - (Options.contributors.length - 1)));
+ if (curSelected > Options.contributors.length - 1) curSelected = Options.contributors.length - 1;
+ changeSelection(0, true);
+
+ while (members.length > 0) {
+ members[0].destroy();
+ remove(members[0], true);
+ }
+
+ totalContributions = 0;
+ for(c in Options.contributors) totalContributions += c.contributions;
+ for(c in Options.contributors) {
+ var text = TU.translate("credits.totalContributions", [c.contributions, totalContributions, FlxMath.roundDecimal(c.contributions / totalContributions * 100, 2)]);
+ var opt:GithubIconOption = new GithubIconOption(c, text);
+ if(Options.mainDevs.contains(c.id)) {
+ opt.desc += TU.translate("credits.mainDev");
+ @:privateAccess opt.__text.color = Flags.MAIN_DEVS_COLOR;
+ }
+ add(opt);
+ }
+
+ updateMenuDesc();
+ }
+}
\ No newline at end of file
diff --git a/source/funkin/menus/credits/CreditsMain.hx b/source/funkin/menus/credits/CreditsMain.hx
new file mode 100644
index 00000000..79182bcc
--- /dev/null
+++ b/source/funkin/menus/credits/CreditsMain.hx
@@ -0,0 +1,103 @@
+package funkin.menus.credits;
+
+import flixel.util.FlxColor;
+import funkin.backend.assets.AssetSource;
+import funkin.backend.system.github.GitHubContributor.CreditsGitHubContributor;
+import funkin.options.TreeMenu;
+import funkin.options.TreeMenuScreen;
+import funkin.options.type.*;
+import haxe.xml.Access;
+
+class CreditsMain extends TreeMenu {
+ var bg:FlxSprite;
+ var items:Array = [];
+
+ override function create() {
+ super.create();
+
+ DiscordUtil.call("onMenuLoaded", ["Credits Menu"]);
+
+ add(bg = new FlxSprite().loadAnimatedGraphic(Paths.image('menus/menuBGBlue')));
+ bg.antialiasing = true;
+ bg.scrollFactor.set();
+ updateBG();
+
+ var first = new TreeMenuScreen('credits.name', 'credits.madePossible');
+ addMenu(first);
+
+ for (i in funkin.backend.assets.ModsFolder.getLoadedMods()) {
+ var xmlPath = Paths.xml('config/credits/LIB_$i');
+
+ if (Paths.assetsTree.existsSpecific(xmlPath, "TEXT")) {
+ var access:Access = null;
+ try access = new Access(Xml.parse(Paths.assetsTree.getSpecificAsset(xmlPath, "TEXT")))
+ catch(e) Logs.trace('[CreditsMain] Error while parsing credits.xml: ${Std.string(e)}', ERROR);
+ if (access != null) for (c in parseCreditsFromXML(access)) first.add(c);
+ }
+ }
+
+ first.add(new TextOption('Codename Engine', 'credits.selectCodename', ' >', () -> addMenu(new CreditsCodename())));
+ first.add(new TextOption('Friday Night Funkin\'', 'credits.selectBase', ' >', () -> CoolUtil.openURL(Flags.URL_FNF_ITCH)));
+ }
+
+ public function updateBG() {
+ var scaleX:Float = FlxG.width / bg.width;
+ var scaleY:Float = FlxG.height / bg.height;
+ bg.scale.x = bg.scale.y = Math.max(scaleX, scaleY) * 1.15;
+ bg.screenCenter();
+ }
+
+ // XML STUFF
+ public function parseCreditsFromXML(xml:Access, source:AssetSource = BOTH):Array {
+ var credsMenus:Array = [];
+
+ for(node in xml.elements) {
+ var desc = node.getAtt("desc").getDefault("No Description");
+
+ if (node.name == "github") {
+ if (!node.has.user) {
+ Logs.warn("A github node requires a user attribute.", "CreditsMain");
+ continue;
+ }
+
+ var username = node.getAtt("user");
+ var user:CreditsGitHubContributor = { // Kind of forcing
+ login: username,
+ html_url: 'https://github.com/$username',
+ avatar_url: 'https://github.com/$username.png'
+ };
+ var opt:GithubIconOption = new GithubIconOption(user, desc, null,
+ node.has.customName ? node.att.customName : null,
+ node.has.size ? Std.parseInt(node.att.size) : 96,
+ node.has.portrait ? node.att.portrait.toLowerCase() == "false" ? false : true : true
+ );
+ if (node.has.color)
+ @:privateAccess opt.__text.color = FlxColor.fromString(node.att.color);
+ credsMenus.push(opt);
+ } else {
+ if (!node.has.name) {
+ Logs.warn("A credit node requires a name attribute.", "CreditsMain");
+ continue;
+ }
+ var name = node.getAtt("name");
+
+ switch(node.name) {
+ case "credit":
+ var opt:PortraitOption = new PortraitOption(name, desc, function() if(node.has.url) CoolUtil.openURL(node.att.url),
+ node.has.icon && Paths.assetsTree.existsSpecific(Paths.image('credits/${node.att.icon}'), "IMAGE", source) ?
+ FlxG.bitmap.add(Paths.image('credits/${node.att.icon}')) : null, node.has.size ? Std.parseInt(node.att.size) : 96,
+ node.has.portrait ? node.att.portrait.toLowerCase() == "false" ? false : true : true
+ );
+ if (node.has.color)
+ @:privateAccess opt.__text.color = FlxColor.fromString(node.att.color);
+ credsMenus.push(opt);
+
+ case "menu":
+ credsMenus.push(new TextOption(name, desc, ' >', () -> addMenu(new TreeMenuScreen(name, desc, parseCreditsFromXML(node, source)))));
+ }
+ }
+ }
+
+ return credsMenus;
+ }
+}
\ No newline at end of file
diff --git a/source/funkin/options/OptionsMenu.hx b/source/funkin/options/OptionsMenu.hx
index ae184e0c..7522b87c 100644
--- a/source/funkin/options/OptionsMenu.hx
+++ b/source/funkin/options/OptionsMenu.hx
@@ -94,7 +94,7 @@ class OptionsMenu extends TreeMenu {
var access:Access = null;
try access = new Access(Xml.parse(Paths.assetsTree.getSpecificAsset(xmlPath, "TEXT")))
catch(e) Logs.trace('Error while parsing options.xml: ${Std.string(e)}', ERROR);
- //if (access != null) for (o in parseOptionsFromXML(access)) main.add(o);
+ if (access != null) for (o in parseOptionsFromXML(access)) tree.first().add(o);
}
}
}
@@ -120,9 +120,8 @@ class OptionsMenu extends TreeMenu {
}
// XML STUFF
- /*
- public function parseOptionsFromXML(xml:Access):Array {
- var options:Array = [];
+ public function parseOptionsFromXML(xml:Access):Array {
+ var options:Array = [];
for(node in xml.elements) {
if (!node.has.name) {
@@ -164,13 +163,10 @@ class OptionsMenu extends TreeMenu {
options.push(new ArrayOption(name, desc, optionOptions, optionDisplayOptions, node.att.id, null, FlxG.save.data));
case "menu":
- options.push(new TextOption(name + " >", desc, function() {
- optionsTree.add(new TreeMenuScreen(name, desc, parseOptionsFromXML(node)));
- }));
+ options.push(new TextOption(name, desc, ' >', () -> addMenu(new TreeMenuScreen(name, desc, parseOptionsFromXML(node)))));
}
}
return options;
}
- */
}
\ No newline at end of file
diff --git a/source/funkin/options/OptionsScreen.hx b/source/funkin/options/OptionsScreen.hx
deleted file mode 100644
index 672feb40..00000000
--- a/source/funkin/options/OptionsScreen.hx
+++ /dev/null
@@ -1,141 +0,0 @@
-// REMOVE THIS WHEN COMPLETE
-
-package funkin.options;
-
-import funkin.options.type.OptionType;
-
-class OptionsScreen extends FlxTypedSpriteGroup {
- public static var optionHeight:Float = 120;
-
- public var parent:OptionsTree;
-
- public var curSelected:Int = 0;
- public var id:Int = 0;
-
- private var __firstFrame:Bool = true;
-
- public var name:String;
- public var desc:String;
- /**
- * The prefix to add to the translations ids.
- **/
- public var prefix:String = "";
-
- private var rawName(default, set):String;
- private var rawDesc(default, set):String;
-
- public inline function getNameID(name):String {
- return prefix + name + "-name";
- }
- public inline function getDescID(name):String {
- return prefix + name + "-desc";
- }
-
- public function getName(name:String, ?args:Array):String {
- return TU.translate(getNameID(name), args);
- }
- public function getDesc(name:String, ?args:Array):String {
- return TU.translate(getDescID(name), args);
- }
- public function translate(name:String, ?args:Array):String {
- return TU.translate(prefix + name, args);
- }
-
- public function new(name:String, desc:String, ?prefix:String, ?options:Array) {
- super();
- rawName = name;
- rawDesc = desc;
- this.prefix = prefix != null ? prefix : "";
- if (options != null) for(o in options) add(o);
- }
-
- function set_rawName(v:String) {
- rawName = v;
- this.name = TU.exists(rawName) ? TU.translate(rawName) : rawName;
- return v;
- }
-
- function set_rawDesc(v:String) {
- rawDesc = v;
- this.desc = TU.exists(rawDesc) ? TU.translate(rawDesc) : rawDesc;
- return v;
- }
-
- public function reloadStrings() {
- this.rawName = rawName;
- this.rawDesc = rawDesc;
-
- for(o in members) {
- o.reloadStrings();
- }
- }
-
- public override function update(elapsed:Float) {
- super.update(elapsed);
-
- var controls = PlayerSettings.solo.controls;
-
- changeSelection((controls.UP_P ? -1 : 0) + (controls.DOWN_P ? 1 : 0) - FlxG.mouse.wheel);
- x = id * FlxG.width;
- for(k=>option in members) {
- if(option == null) continue;
-
- var y:Float = ((FlxG.height - optionHeight) / 2) + ((k - curSelected) * optionHeight);
-
- option.selected = false;
- option.y = __firstFrame ? y : CoolUtil.fpsLerp(option.y, y, 0.25);
- option.x = x + (-50 + (Math.abs(Math.cos((option.y + (optionHeight / 2) - (FlxG.camera.scroll.y + (FlxG.camera.height / 2))) / (FlxG.camera.height * 1.25) * Math.PI)) * 150));
- }
- if (__firstFrame) {
- __firstFrame = false;
- return;
- }
-
- if (members.length > 0) {
- members[curSelected].selected = true;
- if (controls.ACCEPT || (FlxG.mouse.justReleased && Main.timeSinceFocus > 0.25)) {
- members[curSelected].select();
- onSelect(members[curSelected]);
- }
- if (controls.LEFT_P)
- members[curSelected].changeSelection(-1);
- if (controls.RIGHT_P)
- members[curSelected].changeSelection(1);
- }
- if (controls.BACK || FlxG.mouse.justReleasedRight)
- close();
- }
-
- public function close() {
- onClose(this);
- }
-
- public function changeSelection(sel:Int, force:Bool = false) {
- if (members.length <= 0 || (sel == 0 && !force)) return;
-
- CoolUtil.playMenuSFX(SCROLL);
- curSelected = FlxMath.wrap(curSelected + sel, 0, members.length-1);
- members[curSelected].selected = true;
- updateMenuDesc();
- }
-
- public function updateMenuDesc(?customTxt:String) {
- if (parent == null || parent.treeParent == null) return;
- parent.treeParent.updateDesc(customTxt != null ? customTxt : members[curSelected].desc);
- }
-
- public dynamic function onClose(o:OptionsScreen) {}
- public dynamic function onSelect(o:OptionType) {
- if(o is funkin.options.type.RadioButton) {
- var orb:funkin.options.type.RadioButton = cast o;
- for(e in members) {
- if(e is funkin.options.type.RadioButton) {
- var rb:funkin.options.type.RadioButton = cast e;
- if(rb.forId == orb.forId && rb != o) {
- rb.checked = false;
- }
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/source/funkin/options/OptionsTree.hx b/source/funkin/options/OptionsTree.hx
deleted file mode 100644
index 1f0bfcc7..00000000
--- a/source/funkin/options/OptionsTree.hx
+++ /dev/null
@@ -1,91 +0,0 @@
-// REMOVE THIS WHEN COMPLETE
-
-package funkin.options;
-
-class OptionsTree extends FlxTypedGroup {
- public var lastMenu:OptionsScreen;
- public var treeParent:TreeMenu;
- public var wasClosing:Bool = false;
- //public override function new() {
- // super();
- //}
-
- public override function update(elapsed:Float) {
- var last = members.last();
- if (last != null)
- last.update(elapsed);
- }
-
- public function updateAll(elapsed:Float) {
- for (member in members) {
- if(member == null) continue;
- if(member.active && member.exists) {
- member.update(elapsed);
- }
- }
- }
-
- public override function draw() {
- super.draw();
- if (lastMenu != null) { // manually draw lastMenu since it got removed from the members list
- lastMenu.draw();
- }
- }
-
- public function reloadStrings() {
- for(o in members) {
- o.reloadStrings();
- }
- }
-
- public override function add(m:OptionsScreen) {
- super.add(m);
- setup(m);
- clearLastMenu();
- wasClosing = false;
- onMenuChange();
- return m;
- }
- public override function insert(pos:Int, m:OptionsScreen) {
- var last = members.last();
- super.insert(pos, m);
- setup(m);
- if (last != members.last()) {
- wasClosing = false;
- onMenuChange();
- }
- return m;
- }
-
- public function setup(m:OptionsScreen) {
- m.onClose = __subMenuClose;
- m.id = members.indexOf(m);
- m.parent = this;
- m.update(0);
- }
-
- function __subMenuClose(m:OptionsScreen) {
- wasClosing = true;
- clearLastMenu();
- lastMenu = m;
- remove(m, true);
- onMenuChange();
- onMenuClose(m);
- }
-
- public function clearLastMenu() {
- lastMenu = FlxDestroyUtil.destroy(lastMenu);
- }
-
- public override function destroy() {
- super.destroy();
- lastMenu = FlxDestroyUtil.destroy(lastMenu);
- }
-
- public dynamic function onMenuChange() {
-
- }
-
- public dynamic function onMenuClose(m:OptionsScreen) {
- }
-}
\ No newline at end of file
diff --git a/source/funkin/options/TreeMenu.hx b/source/funkin/options/TreeMenu.hx
index 9a8b933a..f5c0e177 100644
--- a/source/funkin/options/TreeMenu.hx
+++ b/source/funkin/options/TreeMenu.hx
@@ -32,8 +32,6 @@ class TreeMenu extends UIState {
public var descLabel:FunkinText;
public var bgLabel:FlxSprite;
- public var optionsTree:OptionsTree;
-
var menuChangeTween:FlxTween;
var __drawer:TreeMenuDrawer;
var __treeCreated:Bool = false;
@@ -74,7 +72,9 @@ class TreeMenu extends UIState {
add(bgLabel);
add(titleLabel);
add(descLabel);
- updateLabels();
+
+ FlxG.camera.scroll.x = -FlxG.width;
+ menuChanged();
__treeCreated = true;
}
diff --git a/source/funkin/options/type/EditorIconOption.hx b/source/funkin/options/type/EditorIconOption.hx
deleted file mode 100644
index 5303fb01..00000000
--- a/source/funkin/options/type/EditorIconOption.hx
+++ /dev/null
@@ -1,13 +0,0 @@
-package funkin.options.type;
-
-import flixel.util.FlxColor;
-
-class EditorIconOption extends IconOption {
- public var flashColor:FlxColor;
-
- public function new(name:String, desc:String, icon:String, callback:Void->Void, flashColor:FlxColor = 0) {
- super(name, desc, icon, callback);
-
- this.flashColor = flashColor;
- }
-}
\ No newline at end of file
diff --git a/source/funkin/options/type/GithubIconOption.hx b/source/funkin/options/type/GithubIconOption.hx
index be3567a8..16916b55 100644
--- a/source/funkin/options/type/GithubIconOption.hx
+++ b/source/funkin/options/type/GithubIconOption.hx
@@ -26,6 +26,7 @@ class GithubIconOption extends TextOption
this.icon = new GithubUserIcon(user, size, waitUntilLoad);
this.usePortrait = usePortrait;
add(icon);
+ __text.x = 100;
}
}
diff --git a/source/funkin/options/type/NewOption.hx b/source/funkin/options/type/NewOption.hx
index 07f4fdf0..85181412 100644
--- a/source/funkin/options/type/NewOption.hx
+++ b/source/funkin/options/type/NewOption.hx
@@ -10,6 +10,7 @@ class NewOption extends TextOption {
public function new(name:String, desc:String, callback:Void->Void) {
super(name, desc, callback);
+ itemHeight = 160;
__text.color = FlxColor.LIME;
__text.x = 100;
diff --git a/source/funkin/options/type/OptionType.hx b/source/funkin/options/type/OptionType.hx
index 41f4302c..3d4d25f0 100644
--- a/source/funkin/options/type/OptionType.hx
+++ b/source/funkin/options/type/OptionType.hx
@@ -1,6 +1,7 @@
package funkin.options.type;
import flixel.group.FlxSpriteGroup;
+import flixel.util.FlxColor;
import funkin.backend.system.Controls;
import funkin.options.TreeMenu.ITreeOption;
@@ -19,6 +20,8 @@ class OptionType extends FlxSpriteGroup implements ITreeOption {
public var itemHeight:Float = 120;
+ public var editorFlashColor:FlxColor = FlxColor.WHITE;
+
public function new(text:String, desc:String) {
super();
rawText = text;
diff --git a/source/funkin/options/type/TextOption.hx b/source/funkin/options/type/TextOption.hx
index 74ccfc2b..e859b668 100644
--- a/source/funkin/options/type/TextOption.hx
+++ b/source/funkin/options/type/TextOption.hx
@@ -6,7 +6,7 @@ import flixel.effects.FlxFlicker;
* Option type that has text.
**/
class TextOption extends OptionType {
- public var suffix:String;
+ public var suffix(default, set):String;
public var selectCallback:Void->Void;
var __text:Alphabet;
@@ -15,6 +15,12 @@ class TextOption extends OptionType {
return text = v;
}
+ function set_suffix(v:String) {
+ if (suffix == (suffix = v)) return v;
+ __text.text = text + suffix;
+ return v;
+ }
+
public function new(text:String, desc:String, ?suffix:String = "", ?selectCallback:Void->Void = null) {
this.suffix = suffix;
this.selectCallback = selectCallback;