optionable v1

This commit is contained in:
XtraCube committed 2025-02-28 23:11:31 -05:00
1 parent 26afd47d2a
commit b67fdf5ab1
19 files changed
+76 -67

No files matched your search

@@ -6,12 +6,10 @@ using MiraAPI.Utilities;
namespace MiraAPI.Example.Options.Roles;
public class FreezerRoleSettings : AbstractOptionGroup
public class FreezerRoleSettings : AbstractOptionGroup<FreezerRole>
{
public override string GroupName => "Custom Role";
public override Type AdvancedRole => typeof(FreezerRole);
[ModdedNumberOption("Freeze Duration", 1, 15, 1, MiraNumberSuffixes.Seconds)]
public float FreezeDuration { get; set; } = 5;
@@ -7,12 +7,10 @@ using MiraAPI.Utilities;
namespace MiraAPI.Example.Options.Roles;
public class TeleporterOptions : AbstractOptionGroup
public class TeleporterOptions : AbstractOptionGroup<TeleporterRole>
{
public override string GroupName => "Teleporter";
public override Type AdvancedRole => typeof(TeleporterRole);
public ModdedNumberOption TeleportCooldown { get; set; } = new("Teleport Cooldown", 10, 5, 60, 2.5f, MiraNumberSuffixes.Seconds);
[ModdedNumberOption("Teleport Duration", 5, 25, 1, MiraNumberSuffixes.Seconds)]
+12 -5
View File
@@ -32,12 +32,19 @@ public abstract class AbstractOptionGroup
/// </summary>
public virtual uint GroupPriority => uint.MaxValue;
/// <summary>
/// Gets the role the group is associated with. This is used for the advanced role options menu.
/// </summary>
public virtual Type? AdvancedRole => null;
internal bool AllOptionsHidden { get; set; }
internal CategoryHeaderMasked? Header { get; set; }
}
/// <summary>
/// Base class for option groups. An option group is a collection of options that are displayed together in the options menu.
/// </summary>
/// <typeparam name="T">The type of the optionable that this group contains.</typeparam>
public abstract class AbstractOptionGroup<T> : AbstractOptionGroup, IOptionableGroup where T : IOptionable
{
/// <summary>
/// Gets the Optionable type of the group.
/// </summary>
public Type OptionableType => typeof(T);
}
@@ -8,12 +8,12 @@ namespace MiraAPI.GameOptions.Attributes;
/// Attribute for creating an enum option.
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class ModdedEnumOptionAttribute(string title, Type enumType, string[]? values = null, Type? roleType = null)
: ModdedOptionAttribute(title, roleType)
public class ModdedEnumOptionAttribute(string title, Type enumType, string[]? values = null)
: ModdedOptionAttribute(title)
{
internal override IModdedOption CreateOption(object? value, PropertyInfo property)
{
var opt = new ModdedEnumOption(Title, (int)(value ?? 0), enumType, values, RoleType);
var opt = new ModdedEnumOption(Title, (int)(value ?? 0), enumType, values);
return opt;
}
@@ -16,13 +16,12 @@ public class ModdedNumberOptionAttribute(
float increment = 1,
MiraNumberSuffixes suffixType = MiraNumberSuffixes.None,
string? formatString = null,
bool zeroInfinity = false,
Type? roleType = null)
: ModdedOptionAttribute(title, roleType)
bool zeroInfinity = false)
: ModdedOptionAttribute(title)
{
internal override IModdedOption CreateOption(object? value, PropertyInfo property)
{
return new ModdedNumberOption(Title, (float)(value ?? min+increment), min, max, increment, suffixType, formatString, zeroInfinity, RoleType);
return new ModdedNumberOption(Title, (float)(value ?? min+increment), min, max, increment, suffixType, formatString, zeroInfinity);
}
/// <inheritdoc />
@@ -8,13 +8,12 @@ namespace MiraAPI.GameOptions.Attributes;
/// Attribute for a toggle option.
/// </summary>
/// <param name="title">The option title.</param>
/// <param name="roleType">An optional role type.</param>
[AttributeUsage(AttributeTargets.Property)]
public class ModdedToggleOptionAttribute(string title, Type? roleType = null) : ModdedOptionAttribute(title, roleType)
public class ModdedToggleOptionAttribute(string title) : ModdedOptionAttribute(title)
{
internal override IModdedOption CreateOption(object? value, PropertyInfo property)
{
var toggleOpt = new ModdedToggleOption(Title, (bool)(value ?? false), RoleType);
var toggleOpt = new ModdedToggleOption(Title, (bool)(value ?? false));
return toggleOpt;
}
-1
View File
@@ -13,7 +13,6 @@ public interface IModdedOption
StringNames StringName { get; }
IMiraPlugin? ParentMod { get; set; }
BaseGameSetting Data { get; }
Type? AdvancedRole { get; set; }
OptionBehaviour? OptionBehaviour { get; }
Func<bool> Visible { get; set; }
ConfigDefinition? ConfigDefinition { get; set; }
+6
View File
@@ -0,0 +1,6 @@
namespace MiraAPI.GameOptions;
/// <summary>
/// Interface for classes that can be used for option groups.
/// </summary>
public interface IOptionable;
+14
View File
@@ -0,0 +1,14 @@
using System;
namespace MiraAPI.GameOptions;
/// <summary>
/// Interface for groups that have some type of "Optionable" class.
/// </summary>
public interface IOptionableGroup
{
/// <summary>
/// Gets the type of the Optionable class.
/// </summary>
Type OptionableType { get; }
}
@@ -119,10 +119,7 @@ public static class ModdedOptionsManager
option.ConfigDefinition = new ConfigDefinition(groupName, propertyName);
option.ParentMod = pluginInfo.MiraPlugin;
option.AdvancedRole = group.AdvancedRole;
pluginInfo.Options.Add(option);
ModdedOptions.Add(option.Id, option);
group.Options.Add(option);
}
@@ -27,8 +27,7 @@ public class ModdedEnumOption : ModdedOption<int>
/// <param name="defaultValue">The default value as an int.</param>
/// <param name="enumType">The Enum type.</param>
/// <param name="values">An option list of string values to use in place of the enum name.</param>
/// <param name="roleType">An optional role type to specify for a specific role.</param>
public ModdedEnumOption(string title, int defaultValue, Type enumType, string[]? values = null, Type? roleType = null) : base(title, defaultValue, roleType)
public ModdedEnumOption(string title, int defaultValue, Type enumType, string[]? values = null) : base(title, defaultValue)
{
Values = values ?? Enum.GetNames(enumType);
Data = ScriptableObject.CreateInstance<StringGameSetting>();
@@ -101,7 +100,6 @@ public class ModdedEnumOption : ModdedOption<int>
}
}
/// <summary>
/// An option for selecting an enum value.
/// </summary>
@@ -118,10 +116,8 @@ public class ModdedEnumOption<T> : ModdedOption<T> where T : Enum
/// </summary>
/// <param name="title">The title of the option.</param>
/// <param name="defaultValue">The default value as an int.</param>
/// <param name="enumType">The Enum type.</param>
/// <param name="values">An option list of string values to use in place of the enum name.</param>
/// <param name="roleType">An optional role type to specify for a specific role.</param>
public ModdedEnumOption(string title, T defaultValue, string[]? values = null, Type? roleType = null) : base(title, defaultValue, roleType)
public ModdedEnumOption(string title, T defaultValue, string[]? values = null) : base(title, defaultValue)
{
Values = values ?? Enum.GetNames(typeof(T));
Data = ScriptableObject.CreateInstance<StringGameSetting>();
@@ -48,7 +48,6 @@ public class ModdedNumberOption : ModdedOption<float>
/// <param name="suffixType">The suffix type.</param>
/// <param name="formatString">Optional format string for the option screen.</param>
/// <param name="zeroInfinity">Whether zero is infinity or not.</param>
/// <param name="roleType">An optional role type.</param>
public ModdedNumberOption(
string title,
float defaultValue,
@@ -57,8 +56,7 @@ public class ModdedNumberOption : ModdedOption<float>
float increment,
MiraNumberSuffixes suffixType,
string? formatString = null,
bool zeroInfinity = false,
Type? roleType = null) : base(title, defaultValue, roleType)
bool zeroInfinity = false) : base(title, defaultValue)
{
Min = min;
Max = max;
@@ -144,7 +142,7 @@ public class ModdedNumberOption : ModdedOption<float>
Value = Mathf.Clamp(newValue, Min, Max);
HudManager.Instance.Notifier.AddSettingsChangeMessage(
StringName,
Data?.GetValueString(Value),
Data.GetValueString(Value),
false);
if (OptionBehaviour is NumberOption opt)
@@ -72,11 +72,6 @@ public abstract class ModdedOption<T> : IModdedOption
/// </summary>
public Func<bool> Visible { get; set; }
/// <summary>
/// Gets or sets the advanced role of the option.
/// </summary>
public Type? AdvancedRole { get; set; }
/// <summary>
/// Gets or sets the option behaviour of the option.
/// </summary>
@@ -102,8 +97,7 @@ public abstract class ModdedOption<T> : IModdedOption
/// </summary>
/// <param name="title">The option title.</param>
/// <param name="defaultValue">The default value.</param>
/// <param name="roleType">The Role Type or null if it doesn't belong to a role.</param>
protected ModdedOption(string title, T defaultValue, Type? roleType)
protected ModdedOption(string title, T defaultValue)
{
Id = ModdedOptionsManager.NextId;
Title = title;
@@ -111,11 +105,6 @@ public abstract class ModdedOption<T> : IModdedOption
Value = defaultValue;
StringName = CustomStringName.CreateAndRegister(Title);
Visible = () => true;
if (roleType is not null && roleType.IsAssignableTo(typeof(ICustomRole)))
{
AdvancedRole = roleType;
}
}
internal void ValueChanged(OptionBehaviour optionBehaviour)
@@ -15,8 +15,7 @@ public class ModdedToggleOption : ModdedOption<bool>
/// </summary>
/// <param name="title">The option title.</param>
/// <param name="defaultValue">The default value.</param>
/// <param name="roleType">An optional role type.</param>
public ModdedToggleOption(string title, bool defaultValue, Type? roleType = null) : base(title, defaultValue, roleType)
public ModdedToggleOption(string title, bool defaultValue) : base(title, defaultValue)
{
Data = ScriptableObject.CreateInstance<CheckboxGameSetting>();
@@ -1,5 +1,7 @@
using System.Linq;
using HarmonyLib;
using MiraAPI.GameOptions;
using MiraAPI.Roles;
using MiraAPI.Utilities;
using MiraAPI.Utilities.Assets;
using Reactor.Localization.Utilities;
@@ -31,8 +33,8 @@ public static class GameOptionsMenuPatch
var num = 2.1f;
var filteredGroups =
GameSettingMenuPatches.SelectedMod?.OptionGroups.Where(
x => x.AdvancedRole is null) ?? [];
GameSettingMenuPatches.SelectedMod?.OptionGroups
.Where(x=> x is not IOptionableGroup) ?? [];
foreach (var group in filteredGroups)
{
@@ -99,7 +101,8 @@ public static class GameOptionsMenuPatch
__instance.MapPicker.gameObject.SetActive(false);
var filteredGroups = GameSettingMenuPatches.SelectedMod?.OptionGroups.Where(x => x.AdvancedRole is null) ?? [];
var filteredGroups = GameSettingMenuPatches.SelectedMod?.OptionGroups
.Where(x => x is not IOptionableGroup) ?? [];
foreach (var group in filteredGroups)
{
@@ -113,6 +113,8 @@ public static class GameSettingMenuPatches
menu.GameSettingsButton.gameObject.SetActive(true);
menu.RoleSettingsButton.gameObject.SetActive(true);
// TODO: reimplement this
/*
if (SelectedModIdx != 0)
{
if (SelectedMod?.Options.Where(x=>x.AdvancedRole==null).ToList().Count == 0)
@@ -129,7 +131,7 @@ public static class GameSettingMenuPatches
{
menu.RoleSettingsButton.transform.localPosition = menu.GameSettingsButton.transform.localPosition;
}
}
}*/
if (roles.roleChances != null && SelectedMod != null && SelectedMod.CustomRoles.Count != 0)
{
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using HarmonyLib;
using MiraAPI.GameOptions;
using MiraAPI.PluginLoading;
using MiraAPI.Roles;
using MiraAPI.Utilities;
@@ -125,7 +126,8 @@ public static class LobbyViewPanePatches
var num = 1.44f;
var filteredGroups = SelectedMod.OptionGroups.Where(x => x.GroupVisible.Invoke() && x.AdvancedRole is null);
var filteredGroups = SelectedMod.OptionGroups
.Where(x => x.GroupVisible.Invoke() && x is not IOptionableGroup);
foreach (var group in filteredGroups)
{
@@ -277,8 +279,9 @@ public static class LobbyViewPanePatches
viewSettingsInfoPanelRoleVariant.transform.localScale = Vector3.one;
viewSettingsInfoPanelRoleVariant.transform.localPosition = new Vector3(num2, num, -2f);
var advancedRoleOptions = SelectedMod.Options
.Where(x => x.AdvancedRole == customRole.GetType())
var advancedRoleOptions = SelectedMod.OptionGroups
.Where(x => x is IOptionableGroup optionGroup && optionGroup.OptionableType == customRole.GetType())
.SelectMany(x => x.Options)
.ToList();
if (numPerGame > 0 && advancedRoleOptions.Count > 0)
@@ -386,8 +389,9 @@ public static class LobbyViewPanePatches
var num = viewPanel.yPosStart;
var num2 = 1.08f;
var filteredOptions = SelectedMod.Options
.Where(x => x.AdvancedRole == roleType)
var filteredOptions = SelectedMod.OptionGroups
.Where(x => x is IOptionableGroup optionGroup && optionGroup.OptionableType == roleType)
.SelectMany(x=>x.Options)
.ToList();
for (var i = 0; i < filteredOptions.Count; i++)
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MiraAPI.GameOptions;
using MiraAPI.Networking;
using MiraAPI.Roles;
using MiraAPI.Utilities;
@@ -304,15 +305,14 @@ public static class RoleSettingMenuPatches
var hasImage = role.RoleScreenshot != null;
var num = hasImage ? -0.872f : -1;
var filteredOptions = GameSettingMenuPatches.SelectedMod?.Options.Where(x => x.AdvancedRole == role.GetType()) ?? [];
// TODO: create sub groups under the role settings.
var filteredOptions = GameSettingMenuPatches.SelectedMod?.OptionGroups
.Where(x=> x is IOptionableGroup optionableGroup && optionableGroup.OptionableType == role.GetType())
.SelectMany(x=>x.Options)
.ToList() ?? [];
foreach (var option in filteredOptions)
{
if (option.AdvancedRole is not null && option.AdvancedRole != role.GetType())
{
continue;
}
var newOpt = option.CreateOption(
__instance.checkboxOrigin,
__instance.numberOptionOrigin,
@@ -470,8 +470,8 @@ public static class RoleSettingMenuPatches
roleOptionSetting.titleText.horizontalAlignment = HorizontalAlignmentOptions.Left;
if (GameSettingMenuPatches.SelectedMod is null ||
GameSettingMenuPatches.SelectedMod.Options.Exists(
x => x.AdvancedRole != null && x.AdvancedRole.IsInstanceOfType(role)))
GameSettingMenuPatches.SelectedMod.OptionGroups
.Exists(x => x is IOptionableGroup optionGroup && optionGroup.OptionableType == role.GetType()))
{
var newButton = Object.Instantiate(roleOptionSetting.buttons[0], roleOptionSetting.transform);
newButton.name = "ConfigButton";
+2 -1
View File
@@ -1,5 +1,6 @@
using System.Text;
using BepInEx.Configuration;
using MiraAPI.GameOptions;
using MiraAPI.Modifiers;
using MiraAPI.PluginLoading;
using MiraAPI.Utilities;
@@ -11,7 +12,7 @@ namespace MiraAPI.Roles;
/// <summary>
/// Interface for custom roles.
/// </summary>
public interface ICustomRole
public interface ICustomRole : IOptionable
{
/// <summary>
/// Gets the name of the role.