From 51fcc2c88ffe886ad3c72827558e81683ca957bb Mon Sep 17 00:00:00 2001 From: XtraCube <72575280+XtraCube@users.noreply.github.com> Date: Wed, 29 Jan 2025 20:57:21 -0500 Subject: [PATCH] add ModdedEnumOption --- MiraAPI.Example/Options/ExampleOptions2.cs | 4 +- .../OptionTypes/ModdedEnumOption.cs | 95 +++++++++++++++++++ 2 files changed, 97 insertions(+), 2 deletions(-) diff --git a/MiraAPI.Example/Options/ExampleOptions2.cs b/MiraAPI.Example/Options/ExampleOptions2.cs index 50152dc..9abf375 100644 --- a/MiraAPI.Example/Options/ExampleOptions2.cs +++ b/MiraAPI.Example/Options/ExampleOptions2.cs @@ -17,13 +17,13 @@ public class ExampleOptions2 : AbstractOptionGroup Visible = () => OptionGroupSingleton.Instance.ToggleOpt1, // implicit cast from ModdedToggleOption to bool }; - public ModdedEnumOption EnumOpt { get; } = new("Enum Opt", 0, typeof(TestingData)) + public ModdedEnumOption EnumOpt { get; } = new("Enum Opt", 0) { ChangedEvent = x => Logger.Info($"changed Enum Opt to {x}"), }; } -public enum TestingData +public enum TestingData : ulong { Happy, Sad, diff --git a/MiraAPI/GameOptions/OptionTypes/ModdedEnumOption.cs b/MiraAPI/GameOptions/OptionTypes/ModdedEnumOption.cs index 0d236a0..e917cdc 100644 --- a/MiraAPI/GameOptions/OptionTypes/ModdedEnumOption.cs +++ b/MiraAPI/GameOptions/OptionTypes/ModdedEnumOption.cs @@ -1,5 +1,7 @@ using System; +using System.Globalization; using System.Linq; +using System.Text; using Il2CppInterop.Runtime.InteropTypes.Arrays; using MiraAPI.Networking; using Reactor.Localization.Utilities; @@ -98,3 +100,96 @@ public class ModdedEnumOption : ModdedOption } } } + + +/// +/// An option for selecting an enum value. +/// +/// The enum type. +public class ModdedEnumOption : ModdedOption where T : Enum +{ + /// + /// Gets the string values of the enum. + /// + public string[]? Values { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The title of the option. + /// The default value as an int. + /// The Enum type. + /// An option list of string values to use in place of the enum name. + /// An optional role type to specify for a specific role. + public ModdedEnumOption(string title, T defaultValue, string[]? values = null, Type? roleType = null) : base(title, defaultValue, roleType) + { + Values = values ?? Enum.GetNames(typeof(T)); + Data = ScriptableObject.CreateInstance(); + var data = (StringGameSetting)Data; + + data.Title = StringName; + data.Type = global::OptionTypes.String; + data.Values = values is null ? + Enum.GetNames(typeof(T)).Select(CustomStringName.CreateAndRegister).ToArray() + : values.Select(CustomStringName.CreateAndRegister).ToArray(); + + data.Index = Convert.ToInt32(Value); + } + + /// + public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, Transform container) + { + var stringOption = Object.Instantiate(stringOpt, container); + + stringOption.SetUpFromData(Data, 20); + stringOption.OnValueChanged = (Il2CppSystem.Action)ValueChanged; + + // SetUpFromData method doesnt work correctly so we must set the values manually + stringOption.Title = StringName; + stringOption.Values = (Data as StringGameSetting)?.Values ?? new Il2CppStructArray(0); + stringOption.Value = Convert.ToInt32(Value); + + OptionBehaviour = stringOption; + + return stringOption; + } + + /// + public override float GetFloatData() + { + return Convert.ToSingle(Value); + } + + /// + public override NetData GetNetData() + { + return new NetData(Id, Encoding.Unicode.GetBytes(Convert.ToString(Value))); + } + + /// + public override void HandleNetData(byte[] data) + { + SetValue((T)Enum.Parse(typeof(T), Encoding.Unicode.GetString(data))); + } + + /// + public override T GetValueFromOptionBehaviour(OptionBehaviour optionBehaviour) + { + return (T)Enum.Parse(typeof(T), optionBehaviour.GetInt().ToString()); + } + + /// + protected override void OnValueChanged(T newValue) + { + HudManager.Instance.Notifier.AddSettingsChangeMessage(StringName, Data?.GetValueString(Convert.ToInt32(newValue)), false); + if (!OptionBehaviour) + { + return; + } + + if (OptionBehaviour is StringOption opt) + { + opt.Value = Convert.ToInt32(newValue); + } + } +}