From 65242ff29ca6931cb34cf8e318c3a5794078bd0c Mon Sep 17 00:00:00 2001 From: Ralty <78720179+Raltyro@users.noreply.github.com> Date: Wed, 23 Jul 2025 01:35:09 +0700 Subject: [PATCH] Shitty MeterOption Impl for now --- assets/images/menus/options/meter.png | Bin 0 -> 4221 bytes assets/images/menus/options/meter.xml | 8 + assets/languages/en/Options.xml | 5 +- source/funkin/options/Options.hx | 1 + .../options/categories/GameplayOptions.hx | 7 + source/funkin/options/type/MeterOption.hx | 208 ++++++++++++++++++ source/funkin/options/type/NumOption.hx | 8 +- source/funkin/options/type/TextOption.hx | 2 +- 8 files changed, 233 insertions(+), 6 deletions(-) create mode 100644 assets/images/menus/options/meter.png create mode 100644 assets/images/menus/options/meter.xml create mode 100644 source/funkin/options/type/MeterOption.hx diff --git a/assets/images/menus/options/meter.png b/assets/images/menus/options/meter.png new file mode 100644 index 0000000000000000000000000000000000000000..4607e9b08c89fcb35365c65c41da70cbe2dc4ab5 GIT binary patch literal 4221 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 TeEljG00000NkvXXu0mjfIWF!n literal 0 HcmV?d00001 diff --git a/assets/images/menus/options/meter.xml b/assets/images/menus/options/meter.xml new file mode 100644 index 00000000..fddf0e4e --- /dev/null +++ b/assets/images/menus/options/meter.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/assets/languages/en/Options.xml b/assets/languages/en/Options.xml index 4e0b46fd..2557c8ec 100644 --- a/assets/languages/en/Options.xml +++ b/assets/languages/en/Options.xml @@ -105,7 +105,10 @@ If unchecked, will censor the Week 7 cutscenes. Camera Zoom on Beat - If unchecked, will stop the camera from zooming in every 4 beats + If unchecked, will stop the camera from zooming in every 4 beats. + + SFX Volume + Changes only the volume of the SFX instead of everything. diff --git a/source/funkin/options/Options.hx b/source/funkin/options/Options.hx index 767f239e..2e89b29f 100644 --- a/source/funkin/options/Options.hx +++ b/source/funkin/options/Options.hx @@ -29,6 +29,7 @@ class Options public static var autoPause:Bool = true; public static var antialiasing:Bool = true; public static var volume:Float = 1; + public static var volumeSFX:Float = 1; public static var week6PixelPerfect:Bool = true; public static var gameplayShaders:Bool = true; public static var colorHealthBar:Bool = true; diff --git a/source/funkin/options/categories/GameplayOptions.hx b/source/funkin/options/categories/GameplayOptions.hx index 4d6dc72c..0de4ceeb 100644 --- a/source/funkin/options/categories/GameplayOptions.hx +++ b/source/funkin/options/categories/GameplayOptions.hx @@ -34,6 +34,13 @@ class GameplayOptions extends OptionsScreen { getName("camZoomOnBeat"), getDesc("camZoomOnBeat"), "camZoomOnBeat")); + add(new MeterOption( + getName("volumeSFX"), + getDesc("volumeSFX"), + 0, // minimum + 1, // maximum + 0.1, // change + "volumeSFX")); } private function __changeOffset(offset) diff --git a/source/funkin/options/type/MeterOption.hx b/source/funkin/options/type/MeterOption.hx new file mode 100644 index 00000000..7902e09e --- /dev/null +++ b/source/funkin/options/type/MeterOption.hx @@ -0,0 +1,208 @@ +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; + + private var rawText(default, set):String; + + public var text(get, set):String; + private function get_text() {return __text.text;} + private function set_text(v:String) {return __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(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; + } + + function set_rawText(v:String) { + rawText = v; + __text.text = TU.exists(rawText) ? TU.translate(rawText) : rawText; + return v; + } + + 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 onChangeSelection(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 75aa2b5a..e570e197 100644 --- a/source/funkin/options/type/NumOption.hx +++ b/source/funkin/options/type/NumOption.hx @@ -42,9 +42,8 @@ class NumOption extends OptionType { this.changeVal = changeVal; this.optionName = optionName; - add(__text = new Alphabet(100, 20, text, "bold")); - add(__number = new Alphabet(__text.width + 120, 20, ': $currentSelection', "normal")); - + add(__text = new Alphabet(20, 20, "", "bold")); + add(__number = new Alphabet(0, 20, ': $currentSelection', "bold")); rawText = text; } @@ -56,10 +55,11 @@ class NumOption extends OptionType { function set_rawText(v:String) { rawText = v; __text.text = TU.exists(rawText) ? TU.translate(rawText) : rawText; + __number.x = __text.x + __text.width + 12; return v; } - public override function onChangeSelection(change:Float):Void + override function onChangeSelection(change:Float):Void { if(currentSelection <= min && change == -1 || currentSelection >= max && change == 1) return; currentSelection = FlxMath.roundDecimal(currentSelection + (change * changeVal), FlxMath.getDecimals(changeVal)); diff --git a/source/funkin/options/type/TextOption.hx b/source/funkin/options/type/TextOption.hx index 5026211f..2d2b5187 100644 --- a/source/funkin/options/type/TextOption.hx +++ b/source/funkin/options/type/TextOption.hx @@ -23,7 +23,7 @@ class TextOption extends OptionType { public function new(text:String, desc:String, ?suffix:String = "", ?selectCallback:Void->Void = null) { super(desc); this.selectCallback = selectCallback; - add(__text = new Alphabet(100, 20, text, "bold")); + add(__text = new Alphabet(100, 20, "", "bold")); this.suffix = suffix; rawText = text; }