From 21fedb2953c0c1eafad7e7c604d00f7eecd9affd Mon Sep 17 00:00:00 2001 From: Ralty <78720179+Raltyro@users.noreply.github.com> Date: Thu, 31 Jul 2025 05:10:37 +0700 Subject: [PATCH] Add missing custom options --- source/funkin/options/OptionsMenu.hx | 37 +++- source/funkin/options/type/Checkbox.hx | 2 +- source/funkin/options/type/MeterOption.hx | 198 --------------------- source/funkin/options/type/NumOption.hx | 2 +- source/funkin/options/type/RadioButton.hx | 2 +- source/funkin/options/type/SliderOption.hx | 2 +- 6 files changed, 33 insertions(+), 210 deletions(-) delete mode 100644 source/funkin/options/type/MeterOption.hx diff --git a/source/funkin/options/OptionsMenu.hx b/source/funkin/options/OptionsMenu.hx index 6359a21f..c60adc3e 100644 --- a/source/funkin/options/OptionsMenu.hx +++ b/source/funkin/options/OptionsMenu.hx @@ -89,6 +89,7 @@ class OptionsMenu extends TreeMenu { })])); checkDebugOption(); + var first = tree.first(); for (i in funkin.backend.assets.ModsFolder.getLoadedMods()) { var xmlPath = Paths.xml('config/options/LIB_$i'); @@ -97,24 +98,24 @@ 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)) tree.first().add(o); + if (access != null) for (o in parseOptionsFromXML(first, access)) first.add(o); } } } function checkDebugOption() { - var screen = tree.first(); + var first = tree.first(); if (Options.devMode) { if (debugOption == null) { - screen.insert(CoolUtil.minInt(screen.length, mainOptions.length), + first.insert(CoolUtil.minInt(first.length, mainOptions.length), debugOption = new TextOption('optionsTree.debug-name', 'optionsTree.debug-desc', ' >', () -> addMenu(new DebugOptions())) ); } } else if (debugOption != null) { - screen.remove(debugOption, true); + first.remove(debugOption, true); debugOption = flixel.util.FlxDestroyUtil.destroy(debugOption); - if (screen.curSelected >= screen.length) screen.changeSelection(0, true); + if (first.curSelected >= first.length) first.changeSelection(0, true); } } @@ -144,7 +145,7 @@ class OptionsMenu extends TreeMenu { } // XML STUFF - public function parseOptionsFromXML(xml:Access):Array { + public function parseOptionsFromXML(screen:TreeMenuScreen, xml:Access):Array { var options:Array = []; for(node in xml.elements) { @@ -168,7 +169,7 @@ class OptionsMenu extends TreeMenu { Logs.warn("A number option requires an \"id\" for option saving."); continue; } - options.push(new NumOption(name, desc, Std.parseFloat(node.att.min), Std.parseFloat(node.att.max), Std.parseFloat(node.att.change), node.att.id, null, FlxG.save.data)); + options.push(new NumOption(name, desc, Std.parseFloat(node.att.min), Std.parseFloat(node.att.max), Std.parseFloat(node.att.step), node.att.id, null, FlxG.save.data)); case "choice": if (!node.has.id) { Logs.warn("A choice option requires an \"id\" for option saving."); @@ -185,9 +186,29 @@ class OptionsMenu extends TreeMenu { if(optionOptions.length > 0) options.push(new ArrayOption(name, desc, optionOptions, optionDisplayOptions, node.att.id, null, FlxG.save.data)); + case 'radio': + if (!node.has.id) { + Logs.warn("A radio option requires an \"id\" for option saving."); + continue; + } + var v:Dynamic = Std.parseFloat(node.att.value); + options.push(new RadioButton(screen, name, desc, node.att.id, v != null ? v : node.att.value, null, FlxG.save.data, node.att.forId)); + case 'slider': + if (!node.has.id) { + Logs.warn("A slider option requires an \"id\" for option saving."); + continue; + } + options.push(new SliderOption(name, desc, Std.parseFloat(node.att.min), Std.parseFloat(node.att.max), Std.parseFloat(node.att.step), Std.parseInt(node.att.segments), node.att.id, Std.parseInt(node.att.barWidth), null, FlxG.save.data)); + + case 'separator': + options.push(new Separator(Std.parseFloat(node.att.height))); case "menu": - options.push(new TextOption(name, desc, ' >', () -> addMenu(new TreeMenuScreen(name, desc, parseOptionsFromXML(node))))); + options.push(new TextOption(name, desc, ' >', () -> { + var screen = new TreeMenuScreen(name, desc); + for (o in parseOptionsFromXML(screen, node)) screen.add(o); + addMenu(screen); + })); } } diff --git a/source/funkin/options/type/Checkbox.hx b/source/funkin/options/type/Checkbox.hx index 2e333420..8ee3a5f6 100644 --- a/source/funkin/options/type/Checkbox.hx +++ b/source/funkin/options/type/Checkbox.hx @@ -25,7 +25,7 @@ class Checkbox extends TextOption { return v; } - public function new(text:String, desc:String, optionName:String, ?selectCallback:Void->Void, ?parent:Dynamic) { + public function new(text:String, desc:String, ?optionName:String, ?selectCallback:Void->Void, ?parent:Dynamic) { this.optionName = optionName; this.parent = parent = parent != null ? parent : Options; diff --git a/source/funkin/options/type/MeterOption.hx b/source/funkin/options/type/MeterOption.hx deleted file mode 100644 index 831a4adc..00000000 --- a/source/funkin/options/type/MeterOption.hx +++ /dev/null @@ -1,198 +0,0 @@ -package funkin.options.type; - -// TODO: RECODE ALL OF THISS!! ITS SO SHITTY - -import flixel.graphics.frames.FlxFrame; -import flixel.math.FlxMatrix; -import flixel.math.FlxRect; - -@:access(flixel.FlxSprite._frame) -class MeterOption extends OptionType { - public var selectCallback:Float->Void; - - public var min:Float; - public var max:Float; - - public var currentSelection:Float; - public var changeVal:Float; - - public var parent:Dynamic; - - public var barWidth(default, set):Int; - - override function set_text(v:String) return __text.text = text = v; - - private var __text:Alphabet; - var optionName:String; - - var barScale:Float = 0.75; - var realBarWidth:Float; - var cornerWidth:Float; - var slider:FlxSprite; - var cornerEmpty:FlxSprite; - var barEmpty:FlxSprite; - var cornerFill:FlxSprite; - var barFill:FlxSprite; - var valueWidth:Float; - var cornerClipRect:FlxRect; - - public function new(text:String, desc:String, min:Float, max:Float, changeVal:Float, optionName:String, barWidth:Int = 520, - ?selectCallback:Float->Void = null, ?parent:Dynamic) - { - super(text, desc); - - this.selectCallback = selectCallback; - this.min = min; - this.max = max; - if (parent == null) parent = Options; - - this.parent = parent; - - if (Reflect.field(parent, optionName) != null) this.currentSelection = Reflect.field(parent, optionName); - this.changeVal = changeVal; - this.optionName = optionName; - - add(__text = new Alphabet(20, 20, "", "bold")); - rawText = text; - - var frames = Paths.getFrames('menus/options/meter'); - add(slider = new FlxSprite(0, 24)); - slider.frames = frames; - slider.animation.addByPrefix('slider', 'meter slider', 24); - slider.animation.play('slider'); - slider.antialiasing = true; - slider.scale.set(barScale, barScale); - slider.updateHitbox(); - - (cornerEmpty = new FlxSprite()).frames = (barEmpty = new FlxSprite()).frames = frames; - (cornerFill = new FlxSprite()).frames = (barFill = new FlxSprite()).frames = frames; - cornerEmpty.animation.addByPrefix('corner', 'meter empty corner', 24); - cornerEmpty.animation.play('corner'); - barEmpty.animation.addByPrefix('bar', 'meter empty piece', 24); - barEmpty.animation.play('bar'); - cornerFill.animation.addByPrefix('corner', 'meter filled corner', 24); - cornerFill.animation.play('corner'); - barFill.animation.addByPrefix('bar', 'meter filled piece', 24); - barFill.animation.play('bar'); - - cornerClipRect = new FlxRect(); - cornerEmpty.rawClipRect = cornerClipRect; - cornerFill.rawClipRect = cornerClipRect; - - _matrix = new FlxMatrix(); - cornerWidth = Math.max(cornerFill.frameWidth, cornerEmpty.frameWidth); - this.barWidth = barWidth; - } - - function set_barWidth(value:Int):Int { - if (value == barWidth) return value; - realBarWidth = Math.max(cornerWidth + value / barScale, cornerWidth * 2); - updateBar(); - - __text.x = x + 20 + realBarWidth * barScale; - - return barWidth = value; - } - - function updateBar() { - var w = (currentSelection - min) / (max - min) * (realBarWidth - cornerWidth * 2) + cornerWidth; - slider.x = x + w * barScale - slider.width * 0.5; - valueWidth = w; - } - - inline function drawObject(sprite:FlxSprite, camera:FlxCamera, x:Float, y:Float) { - getScreenPosition(_point, camera).subtractPoint(offset); - _matrix.translate(_point.x + x, _point.y + y); - - /*if (isPixelPerfectRender(camera)) { - _matrix.tx = Math.floor(_matrix.tx); - _matrix.ty = Math.floor(_matrix.ty); - }*/ - - if (layer != null) layer.drawPixels(sprite, camera, sprite._frame, sprite.framePixels, _matrix, colorTransform, blend, true); - else camera.drawPixels(sprite._frame, sprite.framePixels, _matrix, colorTransform, blend, true); - } - - var lastX:Float; - var temp:Float; - function drawCorner(width:Float, flip:Bool, camera:FlxCamera) { - if ((temp = Math.max(Math.min(width, cornerFill.frameWidth), 0)) > 0) { - cornerClipRect.set(0, 0, temp, cornerFill.frameHeight); - cornerFill.frame = cornerFill.frames.frames[cornerFill.animation.frameIndex]; - cornerFill._frame.prepareMatrix(_matrix, FlxFrameAngle.ANGLE_0, flip != camera.flipX, flipY != camera.flipY); - _matrix.scale(barScale, barScale); - drawObject(cornerFill, camera, 0, 37); - } - - if (temp < cornerEmpty.frameWidth) { - cornerClipRect.set(temp, 0, cornerEmpty.frameWidth - temp, cornerEmpty.frameHeight); - cornerEmpty.frame = cornerEmpty.frames.frames[cornerEmpty.animation.frameIndex]; - cornerEmpty._frame.prepareMatrix(_matrix, FlxFrameAngle.ANGLE_0, flip != camera.flipX, flipY != camera.flipY); - _matrix.scale(barScale, barScale); - drawObject(cornerEmpty, camera, temp * barScale, 37); - } - - x += cornerWidth * barScale; - } - - function drawBar(width:Float, camera:FlxCamera) { - temp = realBarWidth - cornerWidth * 2; - if (width > 0) { - barFill._frame.prepareMatrix(_matrix, FlxFrameAngle.ANGLE_0, camera.flipX, flipY != camera.flipY); - _matrix.scale((Math.min(width, temp) + 2) / barFill.frameWidth * barScale, barScale); - drawObject(barFill, camera, -1, 37); - } - - if (width < temp) { - barEmpty._frame.prepareMatrix(_matrix, FlxFrameAngle.ANGLE_0, camera.flipX, flipY != camera.flipY); - _matrix.scale((Math.max(temp - width, 0) + 1) / barEmpty.frameWidth * barScale, barScale); - drawObject(barEmpty, camera, width * barScale, 37); - } - - /*if (width < (temp = realBarWidth - cornerWidth * 2)) { - barEmpty._frame.prepareMatrix(_matrix, FlxFrameAngle.ANGLE_0, camera.flipX, flipY != camera.flipY); - _matrix.scale((width - realBarWidth + cornerWidth + 1) / barFill.frameWidth, 1); - drawObject(barEmpty, camera, realBarWidth - width, 37); - }*/ - - x += temp * barScale; - } - - override function draw() { - lastX = x; - - for (camera in cameras) { - if (!camera.visible || !camera.exists) continue; - - drawCorner(currentSelection == min ? 0 : valueWidth, false, camera); - drawBar(valueWidth - cornerWidth, camera); - drawCorner(currentSelection == max ? cornerWidth : valueWidth - realBarWidth + cornerWidth, true, camera); - - x = lastX; - } - super.draw(); - } - - override function destroy() { - super.destroy(); - cornerEmpty.destroy(); - barEmpty.destroy(); - cornerFill.destroy(); - barFill.destroy(); - } - - override function reloadStrings() { - super.reloadStrings(); - this.rawText = rawText; - } - - override function changeSelection(change:Float) { - if (currentSelection <= min && change == -1 || currentSelection >= max && change == 1) return; - currentSelection = FlxMath.roundDecimal(currentSelection + (change * changeVal), FlxMath.getDecimals(changeVal)); - - updateBar(); - - Reflect.setField(parent, optionName, currentSelection); - if (selectCallback != null) selectCallback(currentSelection); - } -} \ No newline at end of file diff --git a/source/funkin/options/type/NumOption.hx b/source/funkin/options/type/NumOption.hx index 953294ff..f1d2a33e 100644 --- a/source/funkin/options/type/NumOption.hx +++ b/source/funkin/options/type/NumOption.hx @@ -23,7 +23,7 @@ class NumOption extends TextOption { return v; } - public function new(text:String, desc:String, min:Float, max:Float, step:Float, optionName:String, ?changedCallback:Float->Void = null, ?parent:Dynamic) { + public function new(text:String, desc:String, min:Float, max:Float, step:Float = 1, ?optionName:String, ?changedCallback:Float->Void = null, ?parent:Dynamic) { this.changedCallback = changedCallback; this.min = min; this.max = max; diff --git a/source/funkin/options/type/RadioButton.hx b/source/funkin/options/type/RadioButton.hx index b576c192..f2dba83e 100644 --- a/source/funkin/options/type/RadioButton.hx +++ b/source/funkin/options/type/RadioButton.hx @@ -21,7 +21,7 @@ class RadioButton extends TextOption { "checking" => FlxPoint.get(17, -40) ]; - public function new(?screen:TreeMenuScreen, text:String, desc:String, optionName:String, value:Dynamic, ?selectCallback:Void->Void, ?parent:Dynamic, ?forId:String) { + public function new(?screen:TreeMenuScreen, text:String, desc:String, ?optionName:String, value:Dynamic, ?selectCallback:Void->Void, ?parent:Dynamic, ?forId:String) { super(text, desc, selectCallback); this.screen = screen; this.optionName = optionName; diff --git a/source/funkin/options/type/SliderOption.hx b/source/funkin/options/type/SliderOption.hx index 955b61d9..f04efee3 100644 --- a/source/funkin/options/type/SliderOption.hx +++ b/source/funkin/options/type/SliderOption.hx @@ -32,7 +32,7 @@ class SliderOption extends TextOption implements ITreeFloatOption { return v; } - public function new(text:String, desc:String, min:Float, max:Float, step:Float, ?segments:Int, optionName:String, barWidth = -1, + public function new(text:String, desc:String, min:Float, max:Float, step:Float = 1, ?segments:Int, ?optionName:String, barWidth = -1, ?changedCallback:Float->Void = null, ?parent:Dynamic) { this.changedCallback = changedCallback;