diff --git a/MiraAPI/GameOptions/IModdedOptionList.cs b/MiraAPI/GameOptions/IModdedOptionList.cs index da6da53..26f9bee 100644 --- a/MiraAPI/GameOptions/IModdedOptionList.cs +++ b/MiraAPI/GameOptions/IModdedOptionList.cs @@ -1,9 +1,7 @@ using System; using System.Collections.Generic; using BepInEx.Configuration; -using MiraAPI.Networking; using MiraAPI.PluginLoading; -using UnityEngine; namespace MiraAPI.GameOptions; @@ -23,15 +21,9 @@ public interface IModdedOptionList IReadOnlyList Ids { get; } /// - /// Gets or sets the titles of the options. - /// The end title will equal this value with its index appended (e.g., Title1). + /// Gets the titles of the options. /// - string Title { get; set; } - - /// - /// Gets or sets a value indicating whether the first option's title has a 0, else starts with 1. - /// - bool ZeroIndexTitle { get; set; } + IReadOnlyList Titles { get; } /// /// Gets the StringName for the options, used for localization. @@ -64,42 +56,9 @@ public interface IModdedOptionList bool IncludeInPreset { get; set; } /// - /// Gets the array of ConfigDefinition for the options, used for BepInEx configuration. + /// Gets the set of ConfigDefinition for the options, used for BepInEx configuration. /// - ConfigDefinition?[] ConfigDefinitions { get; } - - /// - /// Creates the option behaviour for the modded option at index . - /// - /// The option's index. - /// The ToggleOption template. - /// The NumberOption template. - /// The StringOption template. - /// The PlayerOption template. - /// >The Transform container for the option. - /// The created OptionBehaviour object. - OptionBehaviour CreateOption(int idx, ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, PlayerOption playerOpt, Transform container); - - /// - /// Gets the value at index as a float. - /// - /// The option's index. - /// The value of the option as a float. - float GetFloatData(int idx); - - /// - /// Gets the NetData for the option at index , used for network synchronization. - /// - /// The option's index. - /// Returns the NetData object for the option. - NetData GetNetData(int idx); - - /// - /// Handles incoming network data for the option at index . - /// - /// The option's index. - /// The byte array representing the network data. - void HandleNetData(int idx, byte[] data); + IReadOnlyList ConfigDefinitions { get; } /// /// Saves the options to a preset configuration file. diff --git a/MiraAPI/GameOptions/OptionTypes/ModdedOptionList.cs b/MiraAPI/GameOptions/OptionTypes/ModdedOptionList.cs index 927bcb2..aca5b28 100644 --- a/MiraAPI/GameOptions/OptionTypes/ModdedOptionList.cs +++ b/MiraAPI/GameOptions/OptionTypes/ModdedOptionList.cs @@ -1,43 +1,33 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Linq; using BepInEx.Configuration; -using MiraAPI.Networking; using MiraAPI.PluginLoading; -using Reactor.Localization.Utilities; -using Reactor.Networking.Rpc; -using Reactor.Utilities; -using UnityEngine; namespace MiraAPI.GameOptions.OptionTypes; /// /// Represents a modded option list. /// -public abstract class ModdedOptionList : IModdedOptionList +/// The type of options. +public class ModdedOptionList : IModdedOptionList where T : IModdedOption { - protected IMiraPlugin? _parentMod; + private IMiraPlugin? _parentMod; /// public int Count { get; } /// - public IReadOnlyList Ids { get; } + public IReadOnlyList Ids => FromOptions(o => o.Id); /// - public string Title { get; set; } - - /// - public bool ZeroIndexTitle { get; set; } + public IReadOnlyList Titles => FromOptions(o => o.Title); /// - public IReadOnlyList StringNames { get; } - - protected readonly BaseGameSetting[] _data; + public IReadOnlyList StringNames => FromOptions(o => o.StringName); /// - public IReadOnlyList Data => _data; + public IReadOnlyList Data => FromOptions(o => o.Data); /// public IMiraPlugin? ParentMod @@ -48,233 +38,10 @@ public abstract class ModdedOptionList : IModdedOptionList if (_parentMod != null || value == null) return; _parentMod = value; - OnParentModChange(); - } - } - - protected abstract void OnParentModChange(); - - /// - public Func Visible { get; set; } - - /// - public bool IncludeInPreset { get; set; } - - protected readonly OptionBehaviour?[] _optionBehaviours; - - /// - public IReadOnlyList OptionBehaviours => _optionBehaviours; - - /// - public ConfigDefinition?[] ConfigDefinitions { get; set; } - - /// - /// Initializes a new instance of the class. - /// - /// The options' title. - /// The option list's length. - /// Whether to include the options in the preset. - /// Whether the first option's title index is 0, else 1. - protected ModdedOptionList(string title, int count, bool includeInPreset = true, bool zeroIndexTitle = false) - { - Count = count; - ZeroIndexTitle = zeroIndexTitle; - - var range = Enumerable.Range(0, Count); - var titleOffset = ZeroIndexTitle ? 0 : 1; - - Ids = range.Select(_ => ModdedOptionsManager.NextId).ToList(); - Title = title; - StringNames = range.Select(i => CustomStringName.CreateAndRegister($"{Title}{i + titleOffset}")).ToList(); - Visible = _ => true; - IncludeInPreset = includeInPreset; - - _optionBehaviours = range.Select(_ => null).ToArray(); - ConfigDefinitions = range.Select(_ => null).ToArray(); - } - - /// - public abstract void SaveToPreset(ConfigFile presetConfig, bool saveDefault = false); - - /// - public abstract void Bind(ConfigFile config); - - /// - public abstract void LoadFromPreset(ConfigFile presetConfig); - - /// - public abstract float GetFloatData(int idx); - - /// - public abstract NetData GetNetData(int idx); - - /// - public abstract void HandleNetData(int idx, byte[] data); - - /// - public abstract OptionBehaviour CreateOption( - int idx, - ToggleOption toggleOpt, - NumberOption numberOpt, - StringOption stringOpt, - PlayerOption playerOpt, - Transform container); -} - -/// -/// Represents a modded option list. -/// -/// The value type. -public abstract class ModdedOptionList : ModdedOptionList -{ - protected override void OnParentModChange() - { - var configFile = _parentMod!.GetConfigFile(); - for (int i = 0; i < Count; i++) - { - var entry = configFile.Bind(ConfigDefinitions[i], DefaultValue(i)); - Values[i] = entry.Value; - } - } - - /// - /// Gets the list of values of the options. - /// - public T[] Values { get; } - - /// - /// Gets the list of default value of the options. - /// - public Func DefaultValue { get; } - - /// - /// Gets or sets the event that is invoked when the value of an option changes. - /// - public Action? ChangedEvent { get; set; } - - /// - /// Initializes a new instance of the class. - /// - /// The options' title. - /// The option list's length. - /// The default values. - /// Whether to include the options in the preset. - /// Whether the first option's title index is 0, else 1. - protected ModdedOptionList(string title, int count, Func defaultValues, bool includeInPreset = true, bool zeroIndexTitle = false) - : base(title, count, includeInPreset, zeroIndexTitle) - { - DefaultValue = defaultValues; - Values = Enumerable.Range(0, Count).Select(defaultValues).ToArray(); - } - - internal void ValueChanged(int idx, OptionBehaviour optionBehaviour) - { - SetValue(idx, GetValueFromOptionBehaviour(idx, optionBehaviour)); - } - - /// - /// Sets the value of the option. - /// - /// The option's index. - /// The new value. - /// Whether to send the value to other players. - public void SetValue(int idx, T newValue, bool sendRpc = true) - { - var oldVal = Values[idx]; - Values[idx] = newValue; - - if (Values[idx]?.Equals(oldVal) == false) - { - ChangedEvent?.Invoke(idx, Values[idx]); - } - - if (sendRpc && AmongUsClient.Instance.AmHost) - { - if (ParentMod?.GetConfigFile().TryGetEntry(ConfigDefinitions[idx], out var entry) == true) + foreach (var option in Options) { - entry.Value = Values[idx]; + option.ParentMod = _parentMod!; } - - Rpc.Instance.Send(PlayerControl.LocalPlayer, [GetNetData(idx)], true); // This might not work - } - - OnValueChanged(idx, newValue); - } - - /// - public override void SaveToPreset(ConfigFile presetConfig, bool saveDefault = false) - { - if (ConfigDefinitions.Any(d => d is null)) - { - Error($"Attempted to save {Title} to preset, but some ConfigDefinitions are null."); - return; - } - Bind(presetConfig); - for (int i = 0; i < Count; i++) - { - presetConfig[ConfigDefinitions[i]].BoxedValue = saveDefault ? DefaultValue(i) : Values[i]; - } - } - - /// - public override void Bind(ConfigFile config) - { - for (int i = 0; i < Count; i++) - { - config.Bind(ConfigDefinitions[i], DefaultValue(i)); - } - } - - /// - public override void LoadFromPreset(ConfigFile presetConfig) - { - for (int i = 0; i < Count; i++) - { - if (presetConfig.TryGetEntry(ConfigDefinitions[i], out ConfigEntry entry)) - { - SetValue(i, entry.Value, false); - } - else - { - Error($"Attempted to load {Title} from preset, but ConfigDefinition {i} is not found in preset."); - } - } - } - - /// - /// Handles the value changed event. - /// - /// The option's index. - /// The new value. - protected abstract void OnValueChanged(int idx, T newValue); - - /// - /// Gets the value from the option behaviour. - /// - /// The option's index. - /// The OptionBehaviour. - /// The value. - public abstract T GetValueFromOptionBehaviour(int idx, OptionBehaviour optionBehaviour); - - /// - /// Indexes the option for its value of type . - /// - /// The option's index. - /// value of type . - public T this[int idx] => Values[idx]; -} - -/// -/// Represents a modded option list. -/// -/// The option's type. -public class ModdedOptionsList : ModdedOptionList where T : IModdedOption -{ - protected override void OnParentModChange() - { - foreach (var option in Options) - { - option.ParentMod = _parentMod!; } } @@ -283,28 +50,39 @@ public class ModdedOptionsList : ModdedOptionList where T : IModdedOption /// public T[] Options { get; } - /// - /// Gets the default option from its index. - /// - public Func DefaultOption { get; } + /// + public Func Visible { get; set; } + + /// + public bool IncludeInPreset { get; set; } + + /// + public IReadOnlyList OptionBehaviours => FromOptions(o => o.OptionBehaviour); + + /// + public IReadOnlyList ConfigDefinitions => FromOptions(o => o.ConfigDefinition); /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The options' title. /// The option list's length. - /// The default option. + /// The option factory to instantiate the options from. /// Whether to include the options in the preset. - /// Whether the first option's title index is 0, else 1. - protected ModdedOptionsList(string title, int count, Func defaultOption, bool includeInPreset = true, bool zeroIndexTitle = false) - : base(title, count, includeInPreset, zeroIndexTitle) + public ModdedOptionList(int count, Func optionFactory, bool includeInPreset = true) { - DefaultOption = defaultOption; - Options = Enumerable.Range(0, Count).Select(defaultOption).ToArray(); + Count = count; + Visible = _ => true; + IncludeInPreset = includeInPreset; + Options = Enumerable.Range(0, Count).Select(optionFactory).ToArray(); + } + + internal IReadOnlyList FromOptions(Func getter) + { + return Options.Select(getter).ToArray(); } /// - public override void SaveToPreset(ConfigFile presetConfig, bool saveDefault = false) + public void SaveToPreset(ConfigFile presetConfig, bool saveDefault = false) { foreach (var option in Options) { @@ -313,7 +91,7 @@ public class ModdedOptionsList : ModdedOptionList where T : IModdedOption } /// - public override void Bind(ConfigFile config) + public void Bind(ConfigFile config) { foreach (var option in Options) { @@ -322,7 +100,7 @@ public class ModdedOptionsList : ModdedOptionList where T : IModdedOption } /// - public override void LoadFromPreset(ConfigFile presetConfig) + public void LoadFromPreset(ConfigFile presetConfig) { foreach (var option in Options) { @@ -330,30 +108,6 @@ public class ModdedOptionsList : ModdedOptionList where T : IModdedOption } } - /// - public override float GetFloatData(int idx) - { - return Options[idx].GetFloatData(); - } - - /// - public override NetData GetNetData(int idx) - { - return Options[idx].GetNetData(); - } - - /// - public override void HandleNetData(int idx, byte[] data) - { - Options[idx].HandleNetData(data); - } - - /// - public override OptionBehaviour CreateOption(int idx, ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, PlayerOption playerOpt, Transform container) - { - return _optionBehaviours[idx] = Options[idx].CreateOption(toggleOpt, numberOpt, stringOpt, playerOpt, container); - } - /// /// Indexes the option of type . ///