change IModdedOptionGroup to AbstractOptionGroup, update group singleton class, save options to config

This commit is contained in:
XtraCube committed 2024-08-23 23:22:29 -04:00
1 parent dcf6221671
commit a1219f0656
12 files changed
+64 -48

No files matched your search

+3 -3
View File
@@ -4,10 +4,10 @@ using UnityEngine;
namespace MiraAPI.Example.Options;
public class ExampleOptions : IModdedOptionGroup
public class ExampleOptions : AbstractOptionGroup
{
public string GroupName => "General Group";
public Color GroupColor => Color.red;
public override string GroupName => "General Group";
public override Color GroupColor => Color.red;
[ModdedToggleOption("Use Thing")]
public bool UseThing { get; set; } = false;
+2 -2
View File
@@ -3,9 +3,9 @@ using MiraAPI.GameOptions.OptionTypes;
namespace MiraAPI.Example.Options;
public class ExampleOptions2 : IModdedOptionGroup
public class ExampleOptions2 : AbstractOptionGroup
{
public string GroupName => "Example 2";
public override string GroupName => "Example 2";
public ModdedToggleOption UseThing { get; } = new("Use Thingy 5", false);
@@ -5,11 +5,11 @@ using MiraAPI.GameOptions.Attributes;
namespace MiraAPI.Example.Options.Roles;
public class CustomRole2Settings : IModdedOptionGroup
public class CustomRole2Settings : AbstractOptionGroup
{
public string GroupName => "Custom Role";
public override string GroupName => "Custom Role";
public Type AdvancedRole => typeof(CustomRole2);
public override Type AdvancedRole => typeof(CustomRole2);
[ModdedToggleOption("Teleportation ability")] public bool Teleport { get; set; } = true;
@@ -5,11 +5,11 @@ using MiraAPI.GameOptions.Attributes;
namespace MiraAPI.Example.Options.Roles;
public class CustomRoleSettings : IModdedOptionGroup
public class CustomRoleSettings : AbstractOptionGroup
{
public string GroupName => "Custom Role";
public override string GroupName => "Custom Role";
public Type AdvancedRole => typeof(CustomRole);
public override Type AdvancedRole => typeof(CustomRole);
[ModdedNumberOption("Testing level", min: 3, max: 9)] public float TestingLevel { get; set; } = 4;
@@ -1,27 +1,30 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace MiraAPI.GameOptions;
public interface IModdedOptionGroup
public abstract class AbstractOptionGroup
{
public List<IModdedOption> Options { get; } = [];
/// <summary>
/// The name of the group. Visible in options menu.
/// </summary>
public string GroupName { get; }
public abstract string GroupName { get; }
/// <summary>
/// A function that returns whether the group should be visible or not.
/// </summary>
public Func<bool> GroupVisible => () => true;
public virtual Func<bool> GroupVisible => () => true;
/// <summary>
/// The group color. This is used to color the group in the options menu.
/// </summary>
public Color GroupColor => Color.clear;
public virtual Color GroupColor => Color.clear;
/// <summary>
/// The role the group is associated with. This is used for the advanced role options menu.
/// </summary>
public Type AdvancedRole => null;
public virtual Type AdvancedRole => null;
}
+3 -1
View File
@@ -1,5 +1,6 @@
using MiraAPI.PluginLoading;
using System;
using BepInEx.Configuration;
using MiraAPI.Networking;
using UnityEngine;
@@ -9,12 +10,13 @@ public interface IModdedOption
{
public uint Id { get; }
public BaseGameSetting Data { get; }
public IMiraPlugin ParentMod { get; set; }
public IMiraPlugin ParentMod { get; init; }
public Type AdvancedRole { get; set; }
public OptionBehaviour OptionBehaviour { get; protected set; }
public string Title { get; }
public StringNames StringName { get; }
public Func<bool> Visible { get; set; }
public ConfigDefinition ConfigDefinition { get; }
public void ValueChanged(OptionBehaviour optionBehaviour);
public OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, Transform container);
public NetData GetNetData();
+9 -13
View File
@@ -14,20 +14,17 @@ namespace MiraAPI.GameOptions;
public class ModdedOptionsManager
{
private static readonly Dictionary<PropertyInfo, ModdedOptionAttribute> OptionAttributes = new();
private static readonly Dictionary<Type, IModdedOptionGroup> TypeToGroup = new();
private static readonly Dictionary<Type, AbstractOptionGroup> TypeToGroup = new();
public static readonly Dictionary<uint, IModdedOption> ModdedOptions = new();
public static readonly Dictionary<IModdedOptionGroup, List<IModdedOption>> Groups = new();
public static readonly List<AbstractOptionGroup> Groups = [];
public static uint NextId => _nextId++;
private static uint _nextId = 1;
internal static bool RegisterGroup(Type type, MiraPluginInfo pluginInfo)
{
var group = (IModdedOptionGroup)Activator.CreateInstance(type);
if (group == null)
if (Activator.CreateInstance(type) is not AbstractOptionGroup group)
{
Logger<MiraApiPlugin>.Error($"Failed to create group from {type.Name}");
return false;
@@ -39,7 +36,7 @@ public class ModdedOptionsManager
return false;
}
Groups.Add(group, []);
Groups.Add(group);
TypeToGroup.Add(type, group);
pluginInfo.OptionGroups.Add(group);
@@ -53,10 +50,8 @@ public class ModdedOptionsManager
Logger<MiraApiPlugin>.Error($"Failed to get group for {type.Name}");
return;
}
var option = (IModdedOption) property.GetValue(group);
if (option == null)
if (property.GetValue(group) is not IModdedOption option)
{
Logger<MiraApiPlugin>.Error($"Failed to get option for {property.Name}");
return;
@@ -101,14 +96,15 @@ public class ModdedOptionsManager
RegisterOption(option, group, pluginInfo);
}
private static void RegisterOption(IModdedOption option, IModdedOptionGroup group, MiraPluginInfo pluginInfo)
private static void RegisterOption(IModdedOption option, AbstractOptionGroup group, MiraPluginInfo pluginInfo)
{
option.ParentMod = pluginInfo.MiraPlugin;
option.AdvancedRole = group.AdvancedRole;
pluginInfo.Options.Add(option);
ModdedOptions.Add(option.Id, option);
Groups[group].Add(option);
group.Options.Add(option);
}
internal static void SyncAllOptions(int targetId=-1)
@@ -3,13 +3,13 @@ using System.Linq;
namespace MiraAPI.GameOptions;
public class ModdedGroupSingleton<T> where T : IModdedOptionGroup
public class OptionGroupSingleton<T> where T : AbstractOptionGroup
{
private static T _instance;
public static T Instance
{
get => _instance ??= ModdedOptionsManager.Groups.Keys.OfType<T>().Single();
get => _instance ??= ModdedOptionsManager.Groups.OfType<T>().Single();
set
{
if (_instance != null)
@@ -2,6 +2,7 @@
using MiraAPI.Roles;
using Reactor.Localization.Utilities;
using System;
using BepInEx.Configuration;
using MiraAPI.Networking;
using Reactor.Networking.Rpc;
using UnityEngine;
@@ -10,9 +11,20 @@ namespace MiraAPI.GameOptions.OptionTypes;
public abstract class ModdedOption<T> : IModdedOption
{
private readonly IMiraPlugin _parentMod;
public uint Id { get; }
public BaseGameSetting Data { get; protected init; }
public IMiraPlugin ParentMod { get; set; } = null;
public IMiraPlugin ParentMod
{
get => _parentMod;
init
{
_parentMod = value;
var entry = _parentMod.GetConfigFile().Bind(ConfigDefinition, DefaultValue);
Value = entry.Value;
}
}
public T Value { get; protected set; }
public T DefaultValue { get; init; }
public Action<T> ChangedEvent { get; set; }
@@ -21,9 +33,11 @@ public abstract class ModdedOption<T> : IModdedOption
public Func<bool> Visible { get; set; }
public Type AdvancedRole { get; set; }
public OptionBehaviour OptionBehaviour { get; set; }
public ConfigDefinition ConfigDefinition => new ("Options", Title);
protected ModdedOption(string title, T defaultValue, Type roleType) : this()
protected ModdedOption(string title, T defaultValue, Type roleType)
{
Id = ModdedOptionsManager.NextId;
Title = title;
DefaultValue = defaultValue;
Value = defaultValue;
@@ -36,11 +50,6 @@ public abstract class ModdedOption<T> : IModdedOption
}
}
private ModdedOption()
{
Id = ModdedOptionsManager.NextId;
}
public void ValueChanged(OptionBehaviour optionBehaviour)
{
SetValue(GetValueFromOptionBehaviour(optionBehaviour));
@@ -59,7 +68,13 @@ public abstract class ModdedOption<T> : IModdedOption
{
Rpc<SyncOptionsRpc>.Instance.Send(PlayerControl.LocalPlayer, [GetNetData()], true);
}
if (ParentMod is not null &&
ParentMod.GetConfigFile().TryGetEntry<T>(ConfigDefinition, out var entry))
{
entry.Value = Value;
}
OnValueChanged(newValue);
}
@@ -28,9 +28,9 @@ public static class GameOptionsMenuPatch
var filteredGroups = GameSettingMenuPatches.SelectedMod.OptionGroups.Where(x => x.GroupVisible.Invoke() && x.AdvancedRole is null);
foreach (IModdedOptionGroup group in filteredGroups)
foreach (AbstractOptionGroup group in filteredGroups)
{
var filteredOpts = ModdedOptionsManager.Groups[group].Where(x => x.Visible.Invoke()).ToList();
var filteredOpts = group.Options.Where(x => x.Visible.Invoke()).ToList();
if (filteredOpts.Count == 0)
{
continue;
+5 -5
View File
@@ -8,12 +8,12 @@ namespace MiraAPI.PluginLoading;
public class MiraPluginInfo(string id, IMiraPlugin miraPlugin, PluginInfo info)
{
public string PluginId { get; set; } = id;
public IMiraPlugin MiraPlugin { get; set; } = miraPlugin;
public PluginInfo PluginInfo { get; set; } = info;
public ConfigFile PluginConfig { get; set; } = miraPlugin.GetConfigFile();
public string PluginId { get; } = id;
public IMiraPlugin MiraPlugin { get; } = miraPlugin;
public PluginInfo PluginInfo { get; } = info;
public ConfigFile PluginConfig { get; } = miraPlugin.GetConfigFile();
public readonly List<IModdedOptionGroup> OptionGroups = [];
public readonly List<AbstractOptionGroup> OptionGroups = [];
public readonly List<IModdedOption> Options = [];
public readonly Dictionary<ushort, RoleBehaviour> CustomRoles = [];
+1 -1
View File
@@ -55,7 +55,7 @@ internal class MiraPluginManager
private static void RegisterAllOptions(Assembly assembly, MiraPluginInfo pluginInfo)
{
var filteredTypes = assembly.GetTypes().Where(type => type.IsAssignableTo(typeof(IModdedOptionGroup)));
var filteredTypes = assembly.GetTypes().Where(type => type.IsAssignableTo(typeof(AbstractOptionGroup)));
foreach (var type in filteredTypes)
{