mirror of
https://github.com/All-Of-Us-Mods/MiraAPI.git
synced 2026-10-20 01:46:15 +00:00
optionable v1
This commit is contained in:
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)]
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace MiraAPI.GameOptions;
|
||||
|
||||
/// <summary>
|
||||
/// Interface for classes that can be used for option groups.
|
||||
/// </summary>
|
||||
public interface IOptionable;
|
||||
@@ -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";
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in new issue
Block a user