diff --git a/MiraAPI/GameOptions/OptionTypes/ModdedEnumOption.cs b/MiraAPI/GameOptions/OptionTypes/ModdedEnumOption.cs index 69815b9..e88b2b4 100644 --- a/MiraAPI/GameOptions/OptionTypes/ModdedEnumOption.cs +++ b/MiraAPI/GameOptions/OptionTypes/ModdedEnumOption.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using Il2CppInterop.Runtime.InteropTypes.Arrays; using MiraAPI.Networking; +using MiraAPI.PluginLoading; using MiraAPI.Translation; using UnityEngine; using Object = UnityEngine.Object; @@ -36,7 +37,7 @@ public class ModdedEnumOption : ModdedOption var data = ScriptableObject.CreateInstance(); data.Title = StringName; data.Type = global::OptionTypes.String; - data.Values = Values.Select(MiraLocaleManager.GetOrCreateLocaleString).ToArray(); + data.Values = Values.Select(x => MiraLocaleManager.GetOrCreateLocaleString(ParentMod!.IdBuilder.CreateEnumOptionId(x, enumType))).ToArray(); data.Index = Value; Data = data; @@ -135,12 +136,18 @@ public class ModdedEnumOption : ModdedOption var data = ScriptableObject.CreateInstance(); data.Title = StringName; data.Type = global::OptionTypes.String; - data.Values = Values.Select(MiraLocaleManager.GetOrCreateLocaleString).ToArray(); data.Index = Convert.ToInt32(Value, NumberFormatInfo.InvariantInfo); Data = data; } + /// + protected override void OnParentModSet(IMiraPlugin plugin) + { + base.OnParentModSet(plugin); + ((StringGameSetting)Data).Values = Values.Select(x => MiraLocaleManager.GetOrCreateLocaleString(ParentMod!.IdBuilder.CreateEnumOptionId(x))).ToArray(); + } + /// public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, PlayerOption playerOpt, Transform container) { diff --git a/MiraAPI/GameOptions/OptionTypes/ModdedOption.cs b/MiraAPI/GameOptions/OptionTypes/ModdedOption.cs index 24747ad..78387e8 100644 --- a/MiraAPI/GameOptions/OptionTypes/ModdedOption.cs +++ b/MiraAPI/GameOptions/OptionTypes/ModdedOption.cs @@ -12,16 +12,19 @@ namespace MiraAPI.GameOptions.OptionTypes; /// Represents a modded option. /// /// The value type. -public abstract class ModdedOption : IModdedOption +/// The option title. +/// The default value. +/// Whether to include the option in the preset. +public abstract class ModdedOption(string title, T defaultValue, bool includeInPreset = true) : IModdedOption { /// - public uint Id { get; } + public uint Id { get; } = ModdedOptionsManager.NextId; /// - public string Title { get; set; } + public string Title { get; set; } = title; /// - public StringNames StringName { get; } + public StringNames StringName { get; private set; } /// public BaseGameSetting Data { get; protected set; } = null!; @@ -34,6 +37,7 @@ public abstract class ModdedOption : IModdedOption { if (field != null || value == null) return; field = value; + OnParentModSet(value); var entry = field.GetConfigFile().Bind(ConfigDefinition, DefaultValue); Value = entry.Value; @@ -43,12 +47,12 @@ public abstract class ModdedOption : IModdedOption /// /// Gets or sets the value of the option. /// - public T Value { get; protected set; } + public T Value { get; protected set; } = defaultValue; /// /// Gets the default value of the option. /// - public T DefaultValue { get; } + public T DefaultValue { get; } = defaultValue; /// /// Gets or sets the event that is invoked when the value of the option changes. @@ -56,10 +60,10 @@ public abstract class ModdedOption : IModdedOption public Action? ChangedEvent { get; set; } /// - public Func Visible { get; set; } + public Func Visible { get; set; } = () => true; /// - public bool IncludeInPreset { get; set; } + public bool IncludeInPreset { get; set; } = includeInPreset; /// public OptionBehaviour? OptionBehaviour { get; protected set; } @@ -67,22 +71,11 @@ public abstract class ModdedOption : IModdedOption /// public ConfigDefinition? ConfigDefinition { get; set; } - /// - /// Initializes a new instance of the class. - /// - /// The option title. - /// The default value. - /// Whether to include the option in the preset. - protected ModdedOption(string title, T defaultValue, bool includeInPreset = true) - { - Id = ModdedOptionsManager.NextId; - Title = title.Translate(); - DefaultValue = defaultValue; - Value = defaultValue; - StringName = MiraLocaleManager.GetOrCreateLocaleString(Title); - Visible = () => true; - IncludeInPreset = includeInPreset; - } + /// + public AbstractOptionGroup ParentGroup { get; set; } + + /// + public virtual OptionNotifConfiguration Configuration => new(ParentGroup); internal void ValueChanged(OptionBehaviour optionBehaviour) { @@ -149,6 +142,15 @@ public abstract class ModdedOption : IModdedOption } } + /// + /// An event that is invoked when the option's parent mod as been assigned to the option. + /// + /// The plugin that was assigned. + protected virtual void OnParentModSet(IMiraPlugin plugin) + { + StringName = MiraLocaleManager.GetOrCreateLocaleString(plugin.IdBuilder.CreateOptionTitleId(Title)); + } + /// public abstract float GetFloatData(); @@ -188,10 +190,4 @@ public abstract class ModdedOption : IModdedOption { return option.Value; } - - /// - public AbstractOptionGroup ParentGroup { get; set; } - - /// - public virtual OptionNotifConfiguration Configuration => new(ParentGroup); } diff --git a/MiraAPI/GameOptions/OptionTypes/ModdedStringOption.cs b/MiraAPI/GameOptions/OptionTypes/ModdedStringOption.cs index 8381177..fe281e9 100644 --- a/MiraAPI/GameOptions/OptionTypes/ModdedStringOption.cs +++ b/MiraAPI/GameOptions/OptionTypes/ModdedStringOption.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using Il2CppInterop.Runtime.InteropTypes.Arrays; using MiraAPI.Networking; +using MiraAPI.PluginLoading; using MiraAPI.Translation; using UnityEngine; using Object = UnityEngine.Object; @@ -57,43 +58,41 @@ public class ModdedStringOption : ModdedOption newVals.Insert(index, value); Values = [.. newVals]; var newStrVals = StringNameValues.ToList(); - newStrVals.Insert(index, MiraLocaleManager.GetOrCreateLocaleString(value)); + newStrVals.Insert(index, MiraLocaleManager.GetOrCreateLocaleString(ParentMod!.IdBuilder.CreateStringOptionId(value))); StringNameValues = [.. newStrVals]; } - if (Data != null) - { - var data = (StringGameSetting)Data; - data.Values = StringNameValues; - - data.Index = GetIndex(Value); - if (OptionBehaviour != null) - { - var strOpt = OptionBehaviour.TryCast(); - if (strOpt != null) - { - strOpt.Values = StringNameValues; - strOpt.Value = GetIndex(Value); - Warning("StringOption is valid"); - } - else - { - Error("StringOption is null."); - } - - Warning("OptionBehaviour is valid"); - } - else - { - Error("OptionBehaviour is null."); - } - - Warning("Data is valid"); - } - else + if (Data == null) { Error("Data is null."); + return; } + + var data = (StringGameSetting)Data; + data.Values = StringNameValues; + data.Index = GetIndex(Value); + + Warning("Data is valid"); + + if (OptionBehaviour == null) + { + Error("OptionBehaviour is null."); + return; + } + + Warning("OptionBehaviour is valid"); + var strOpt = OptionBehaviour.TryCast(); + + if (strOpt == null) + { + Error("StringOption is null."); + return; + } + + strOpt.Values = StringNameValues; + strOpt.Value = GetIndex(Value); + Warning("StringOption is valid"); + return; } /// @@ -112,12 +111,18 @@ public class ModdedStringOption : ModdedOption data.Title = StringName; data.Type = global::OptionTypes.String; - StringNameValues = [.. values.Select(MiraLocaleManager.GetOrCreateLocaleString)]; - data.Values = StringNameValues; - data.Index = GetIndex(Value); } + /// + protected override void OnParentModSet(IMiraPlugin plugin) + { + base.OnParentModSet(plugin); + + StringNameValues = [.. Values.Select(x => MiraLocaleManager.GetOrCreateLocaleString(plugin.IdBuilder.CreateStringOptionId(x)))]; + ((StringGameSetting)Data).Values = StringNameValues; + } + /// public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, PlayerOption playerOpt, Transform container) { diff --git a/MiraAPI/MiraApiPlugin.cs b/MiraAPI/MiraApiPlugin.cs index d68a87d..695699a 100644 --- a/MiraAPI/MiraApiPlugin.cs +++ b/MiraAPI/MiraApiPlugin.cs @@ -35,7 +35,7 @@ public partial class MiraApiPlugin : BasePlugin, IMiraPlugin public static CultureInfo Culture { get; internal set; } = new("en-US"); /// - public string OptionsTitleText => "MiraAPI"; + public string OptionsTitleText { get; } = "MiraAPI"; /// public bool DisplayOnOptionsMenu => false; diff --git a/MiraAPI/PluginLoading/IMiraPlugin.cs b/MiraAPI/PluginLoading/IMiraPlugin.cs index c77a97e..e91fe7f 100644 --- a/MiraAPI/PluginLoading/IMiraPlugin.cs +++ b/MiraAPI/PluginLoading/IMiraPlugin.cs @@ -1,6 +1,7 @@ using System.Globalization; using System.Linq; using BepInEx.Configuration; +using MiraAPI.Translation; namespace MiraAPI.PluginLoading; @@ -58,6 +59,11 @@ public interface IMiraPlugin /// string CustomOptionMenuTwoDescription => "Apply game settings for this mod!"; + /// + /// Gets the translation id builder for this mod. + /// + TranslationIdBuilder IdBuilder => TranslationIdBuilder.Default; + /// /// Gets the for the plugin. /// diff --git a/MiraAPI/Translation/TranslationIdBuilder.cs b/MiraAPI/Translation/TranslationIdBuilder.cs new file mode 100644 index 0000000..6af4e4a --- /dev/null +++ b/MiraAPI/Translation/TranslationIdBuilder.cs @@ -0,0 +1,82 @@ +using System; +using System.Diagnostics.CodeAnalysis; + +namespace MiraAPI.Translation; + +/// +/// A utility class that can build ids based on the provided id part. +/// +public class TranslationIdBuilder +{ + /// + /// Gets an instance of that has default behaviour. + /// + public static TranslationIdBuilder Default { get; } = new(); + + /// + /// Constructs a translation id for a provided enum option value. + /// + /// The type of the enum. + /// The enum option value. + /// The constructed translation id. + public virtual string CreateEnumOptionId(T value) + where T : Enum + { + return CreateEnumOptionId(value.ToString()); + } + + /// + /// Constructs a translation id for a provided enum option value. + /// + /// The type of the enum. + /// The enum option value. + /// The constructed translation id. + public virtual string CreateEnumOptionId(string value) + where T : Enum + { + return CreateEnumOptionId(value, typeof(T)); + } + + /// + /// Constructs a translation id for a provided enum option value. + /// + /// The enum option value. + /// The type of the enum. + /// The constructed translation id. + public virtual string CreateEnumOptionId(object value, Type enumType) + { + return CreateEnumOptionId(value.ToString()!, enumType); + } + + /// + /// Constructs a translation id for a provided enum option value. + /// + /// The enum option value. + /// The type of the enum. + /// The constructed translation id. + public virtual string CreateEnumOptionId(string value, Type enumType) + { + return value; + } + + /// + /// Constructs a translation id for a string option. + /// + /// The id part. + /// The constructed translation id. + [SuppressMessage("Naming", "CA1716:Identifiers should not match keywords", Justification = "Just confusing.")] + public virtual string CreateStringOptionId(string option) + { + return option; + } + + /// + /// Constructs a translation id for an option's title. + /// + /// The id part. + /// The constructed translation id. + public virtual string CreateOptionTitleId(string title) + { + return title; + } +}