mirror of
https://github.com/All-Of-Us-Mods/MiraAPI.git
synced 2026-10-19 15:51:48 +00:00
more stuff
This commit is contained in:
23 files changed
+283
-124
No files matched your search
@@ -27,19 +27,22 @@ public class ExampleOptions : AbstractOptionGroup
|
|||||||
[ModdedOptionVisibility(nameof(NumberOptVisibility))] // Can also target static methods
|
[ModdedOptionVisibility(nameof(NumberOptVisibility))] // Can also target static methods
|
||||||
public float NumberOpt { get; set; } = 4f;
|
public float NumberOpt { get; set; } = 4f;
|
||||||
|
|
||||||
|
[ModdedNumberOption("options.exampleOptions1.numberOpt", min: 0, max: 10, suffixType: MiraNumberSuffixes.Distance)]
|
||||||
|
public int NumberOpt2 { get; set; } = 4; // Can also be int!
|
||||||
|
|
||||||
[ModdedEnumOption("options.exampleOptions1.bestApi", typeof(Api), ["Mira API", "Mitochondria", "Reactor"])]
|
[ModdedEnumOption("options.exampleOptions1.bestApi", typeof(Api), ["Mira API", "Mitochondria", "Reactor"])]
|
||||||
|
public Api BestApi { get; set; } = Api.MiraAPI;
|
||||||
|
|
||||||
|
[ModdedEnumOption<Api>("options.exampleOptions1.worstApi", ["Mira API", "Mitochondria", "Reactor"])]
|
||||||
|
|
||||||
// These three can target both instance and static methods
|
// These three can target both instance and static methods
|
||||||
[ModdedOptionGetter(nameof(GetApi))] // Can also automatically resolve to {Option Name}Getter
|
[ModdedOptionGetter(nameof(GetApi))] // Can also automatically resolve to {Option Name}Getter
|
||||||
[ModdedOptionSetter(nameof(SetApi))] // Can also automatically resolve to {Option Name}Setter
|
[ModdedOptionSetter(nameof(SetApi))] // Can also automatically resolve to {Option Name}Setter
|
||||||
[ModdedOptionChanged(nameof(ApiChanged))] // Can also automatically resolve to {Option Name}Changed
|
[ModdedOptionChanged(nameof(ApiChanged))] // Can also automatically resolve to {Option Name}Changed
|
||||||
public Api BestApi { get; set; } = Api.MiraAPI;
|
|
||||||
|
|
||||||
[ModdedEnumOption<Api>("options.exampleOptions1.worstApi", ["Mira API", "Mitochondria", "Reactor"])]
|
|
||||||
public Api WorstApi { get; set; } = Api.MiraAPI;
|
public Api WorstApi { get; set; } = Api.MiraAPI;
|
||||||
|
|
||||||
[ModdedEnumOptionList<ValueState>("Value State {0}", ["None", "Primary", "Secondary"])]
|
[ModdedEnumOptionList<ValueState>("Value State {0}", ["None", "Primary", "Secondary"])]
|
||||||
public List<ValueState> ValueStates { get; } =
|
public List<ValueState> ValueStates { get; set; } =
|
||||||
[ValueState.Primary, ValueState.Secondary, ValueState.None, ValueState.None, ValueState.None];
|
[ValueState.Primary, ValueState.Secondary, ValueState.None, ValueState.None, ValueState.None];
|
||||||
|
|
||||||
public bool ToggleOpt1Visibility()
|
public bool ToggleOpt1Visibility()
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ Eliminate every other faction.</string>
|
|||||||
<string name="options.exampleOptions1.toggleOpt2">Toggle Opt 2</string>
|
<string name="options.exampleOptions1.toggleOpt2">Toggle Opt 2</string>
|
||||||
<string name="options.exampleOptions1.numberOpt">Number Opt</string>
|
<string name="options.exampleOptions1.numberOpt">Number Opt</string>
|
||||||
<string name="options.exampleOptions1.bestApi">Best API</string>
|
<string name="options.exampleOptions1.bestApi">Best API</string>
|
||||||
|
<string name="options.exampleOptions1.worstApi">Worst API</string>
|
||||||
<string name="options.exampleOptions2">Example Options 2</string>
|
<string name="options.exampleOptions2">Example Options 2</string>
|
||||||
<string name="options.exampleOptions2.youMustChoseAPlayer">YOU MUST CHOSE A PLAYER</string>
|
<string name="options.exampleOptions2.youMustChoseAPlayer">YOU MUST CHOSE A PLAYER</string>
|
||||||
<string name="options.exampleOptions2.ehWhatever">Eh whatever</string>
|
<string name="options.exampleOptions2.ehWhatever">Eh whatever</string>
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class ModdedEnumOptionAttribute(string title, Type enumType, string[]? va
|
|||||||
{
|
{
|
||||||
return HolderOption is ModdedEnumOption opt
|
return HolderOption is ModdedEnumOption opt
|
||||||
? Enum.ToObject(enumType, opt.Value)
|
? Enum.ToObject(enumType, opt.Value)
|
||||||
: throw new InvalidOperationException($"HolderOption for option \"{Title}\" with EnumType ${enumType.FullName} is not a ModdedEnumOption");
|
: throw new InvalidOperationException($"HolderOption for option \"{Title}\" with EnumType {enumType.FullName} is not a ModdedEnumOption");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,6 +65,6 @@ public class ModdedEnumOptionAttribute<T>(string title, string[]? values = null)
|
|||||||
{
|
{
|
||||||
return HolderOption is ModdedEnumOption<T> opt
|
return HolderOption is ModdedEnumOption<T> opt
|
||||||
? opt.Value
|
? opt.Value
|
||||||
: throw new InvalidOperationException($"HolderOption for option \"{Title}\" with EnumType ${typeof(T).FullName} is not a ModdedEnumOption");
|
: throw new InvalidOperationException($"HolderOption for option \"{Title}\" with EnumType {typeof(T).FullName} is not a ModdedEnumOption<{typeof(T).Name}>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,9 +28,16 @@ public class ModdedNumberOptionAttribute(
|
|||||||
{
|
{
|
||||||
internal override IModdedOption CreateOption(object? value, PropertyInfo property)
|
internal override IModdedOption CreateOption(object? value, PropertyInfo property)
|
||||||
{
|
{
|
||||||
|
var final = value switch
|
||||||
|
{
|
||||||
|
null => min + increment,
|
||||||
|
int integer => integer,
|
||||||
|
_ => (float)value,
|
||||||
|
};
|
||||||
|
|
||||||
return new ModdedNumberOption(
|
return new ModdedNumberOption(
|
||||||
Title,
|
Title,
|
||||||
(float)(value ?? min + increment),
|
final,
|
||||||
min,
|
min,
|
||||||
max,
|
max,
|
||||||
increment,
|
increment,
|
||||||
@@ -42,15 +49,28 @@ public class ModdedNumberOptionAttribute(
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void SetValue(object value)
|
public override void SetValue(object value)
|
||||||
{
|
{
|
||||||
var opt = HolderOption as ModdedNumberOption;
|
if (HolderOption is not ModdedNumberOption opt)
|
||||||
opt?.SetValue((float)value);
|
return;
|
||||||
|
|
||||||
|
var final = value switch
|
||||||
|
{
|
||||||
|
int integer => integer,
|
||||||
|
_ => (float)value,
|
||||||
|
};
|
||||||
|
opt.SetValue(final);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override object GetValue()
|
public override object GetValue()
|
||||||
{
|
{
|
||||||
return HolderOption is ModdedNumberOption opt
|
if (HolderOption is not ModdedNumberOption opt)
|
||||||
? (object)opt.Value
|
throw new InvalidOperationException($"HolderOption for option \"{Title}\" is not a ModdedNumberOption");
|
||||||
: throw new InvalidOperationException($"HolderOption for option \"{Title}\" is not a ModdedNumberOption");
|
|
||||||
|
var value = opt.Value;
|
||||||
|
|
||||||
|
if (ValueType == typeof(int))
|
||||||
|
return (int)Math.Round(value);
|
||||||
|
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,6 +13,7 @@ namespace MiraAPI.GameOptions.Attributes;
|
|||||||
public abstract class ModdedOptionAttribute(string title, Type? roleType = null, Type? modeType = null) : PropertyOptionAttribute
|
public abstract class ModdedOptionAttribute(string title, Type? roleType = null, Type? modeType = null) : PropertyOptionAttribute
|
||||||
{
|
{
|
||||||
internal IModdedOption? HolderOption { get; set; }
|
internal IModdedOption? HolderOption { get; set; }
|
||||||
|
internal Type ValueType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the title of the option.
|
/// Gets the title of the option.
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using MiraAPI.GameOptions.OptionTypes;
|
||||||
|
|
||||||
|
namespace MiraAPI.GameOptions.Attributes;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attribute for a <see cref="ModdedPlayerOption"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="title">The title of the option.</param>
|
||||||
|
/// <param name="allowNone">Whether the option includes a none option. If None is selected, value will return -1.</param>
|
||||||
|
[AttributeUsage(AttributeTargets.Property)]
|
||||||
|
public class ModdedPlayerOptionAttribute(
|
||||||
|
string title,
|
||||||
|
bool allowNone = true)
|
||||||
|
: ModdedOptionAttribute(title)
|
||||||
|
{
|
||||||
|
internal override IModdedOption? CreateOption(object? value, PropertyInfo property)
|
||||||
|
{
|
||||||
|
var option = new ModdedPlayerOption(Title, allowNone);
|
||||||
|
return option;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override object GetValue()
|
||||||
|
{
|
||||||
|
if (HolderOption is not ModdedPlayerOption opt)
|
||||||
|
throw new InvalidOperationException($"Holder option for {Title} is not a ModdedPlayerOption.");
|
||||||
|
|
||||||
|
if (ValueType == typeof(int))
|
||||||
|
return opt.Value;
|
||||||
|
|
||||||
|
return opt.SelectedPlayer!;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void SetValue(object value)
|
||||||
|
{
|
||||||
|
if (HolderOption is not ModdedPlayerOption opt)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var final = value switch
|
||||||
|
{
|
||||||
|
NetworkedPlayerInfo info => opt.Values.IndexOf(info),
|
||||||
|
_ => (int)value,
|
||||||
|
};
|
||||||
|
opt?.SetValue(final);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,7 +25,7 @@ public class ModdedStringOptionAttribute(
|
|||||||
public override object GetValue()
|
public override object GetValue()
|
||||||
{
|
{
|
||||||
return HolderOption is ModdedStringOption opt
|
return HolderOption is ModdedStringOption opt
|
||||||
? (object)opt.Value
|
? opt.Value
|
||||||
: throw new InvalidOperationException($"Holder option for {Title} is not a ModdedStringOption.");
|
: throw new InvalidOperationException($"Holder option for {Title} is not a ModdedStringOption.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public class ModdedToggleOptionAttribute(string title) : ModdedOptionAttribute(t
|
|||||||
public override object GetValue()
|
public override object GetValue()
|
||||||
{
|
{
|
||||||
return HolderOption is ModdedToggleOption opt
|
return HolderOption is ModdedToggleOption opt
|
||||||
? (object)opt.Value
|
? opt.Value
|
||||||
: throw new InvalidOperationException($"Holder option for {Title} is not a ModdedToggleOption.");
|
: throw new InvalidOperationException($"Holder option for {Title} is not a ModdedToggleOption.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,7 @@ public class ModdedEnumOptionListAttribute(string title, Type enumType, string[]
|
|||||||
{
|
{
|
||||||
return HolderOptionList?[idx] is ModdedEnumOption opt
|
return HolderOptionList?[idx] is ModdedEnumOption opt
|
||||||
? Enum.ToObject(enumType, opt.Value)
|
? Enum.ToObject(enumType, opt.Value)
|
||||||
: throw new InvalidOperationException($"HolderOption for option \"{GetFormattedTitle(idx)}\" with EnumType ${enumType.FullName} is not a ModdedEnumOption");
|
: throw new InvalidOperationException($"HolderOption for option \"{GetFormattedTitle(idx)}\" with EnumType {enumType.FullName} is not a ModdedEnumOption");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,6 +68,6 @@ public class ModdedEnumOptionListAttribute<T>(string title, string[]? values = n
|
|||||||
{
|
{
|
||||||
return HolderOptionList?[idx] is ModdedEnumOption<T> opt
|
return HolderOptionList?[idx] is ModdedEnumOption<T> opt
|
||||||
? opt.Value
|
? opt.Value
|
||||||
: throw new InvalidOperationException($"HolderOption for option \"{GetFormattedTitle(idx)}\" with EnumType ${typeof(T).FullName} is not a ModdedEnumOption");
|
: throw new InvalidOperationException($"HolderOption for option \"{GetFormattedTitle(idx)}\" with EnumType {typeof(T).FullName} is not a ModdedEnumOption<{typeof(T).FullName}>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -31,9 +31,16 @@ public class ModdedNumberOptionListAttribute(
|
|||||||
{
|
{
|
||||||
return new ModdedOptionList<ModdedNumberOption>(value.Count, idx =>
|
return new ModdedOptionList<ModdedNumberOption>(value.Count, idx =>
|
||||||
{
|
{
|
||||||
|
var final = value[idx] switch
|
||||||
|
{
|
||||||
|
null => min + increment,
|
||||||
|
int integer => integer,
|
||||||
|
_ => (float)value[idx]!,
|
||||||
|
};
|
||||||
|
|
||||||
return new(
|
return new(
|
||||||
GetFormattedTitle(idx),
|
GetFormattedTitle(idx),
|
||||||
(float)(value[idx] ?? min + increment),
|
final,
|
||||||
min,
|
min,
|
||||||
max,
|
max,
|
||||||
increment,
|
increment,
|
||||||
@@ -46,15 +53,28 @@ public class ModdedNumberOptionListAttribute(
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void SetValue(int idx, object value)
|
public override void SetValue(int idx, object value)
|
||||||
{
|
{
|
||||||
var opt = HolderOptionList?[idx] as ModdedNumberOption;
|
if (HolderOptionList?[idx] is not ModdedNumberOption opt)
|
||||||
opt?.SetValue((float)value);
|
return;
|
||||||
|
|
||||||
|
var final = value switch
|
||||||
|
{
|
||||||
|
int integer => integer,
|
||||||
|
_ => (float)value,
|
||||||
|
};
|
||||||
|
opt.SetValue(final);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override object GetValue(int idx)
|
public override object GetValue(int idx)
|
||||||
{
|
{
|
||||||
return HolderOptionList?[idx] is ModdedNumberOption opt
|
if (HolderOptionList?[idx] is not ModdedNumberOption opt)
|
||||||
? (object)opt.Value
|
throw new InvalidOperationException($"HolderOption for option \"{GetFormattedTitle(idx)}\" is not a ModdedNumberOption");
|
||||||
: throw new InvalidOperationException($"HolderOption for option \"{GetFormattedTitle(idx)}\" is not a ModdedNumberOption");
|
|
||||||
|
var value = opt.Value;
|
||||||
|
|
||||||
|
if (ValueType == typeof(int))
|
||||||
|
return (int)Math.Round(value);
|
||||||
|
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@ using System.Collections;
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using MiraAPI.Translation;
|
||||||
|
|
||||||
namespace MiraAPI.GameOptions.Attributes;
|
namespace MiraAPI.GameOptions.Attributes;
|
||||||
|
|
||||||
@@ -14,8 +15,8 @@ namespace MiraAPI.GameOptions.Attributes;
|
|||||||
public abstract class ModdedOptionListAttribute(string title) : PropertyOptionAttribute
|
public abstract class ModdedOptionListAttribute(string title) : PropertyOptionAttribute
|
||||||
{
|
{
|
||||||
internal IModdedOptionList? HolderOptionList { get; set; }
|
internal IModdedOptionList? HolderOptionList { get; set; }
|
||||||
|
internal IList? Value { get; set; }
|
||||||
internal object? Value { get; set; }
|
internal Type ValueType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the title of the options.
|
/// Gets the title of the options.
|
||||||
@@ -31,16 +32,16 @@ public abstract class ModdedOptionListAttribute(string title) : PropertyOptionAt
|
|||||||
/// <param name="value">The new values as an object.</param>
|
/// <param name="value">The new values as an object.</param>
|
||||||
public override void SetValue(object value)
|
public override void SetValue(object value)
|
||||||
{
|
{
|
||||||
Value = value;
|
Value = (IList)value;
|
||||||
var list = (IList)value;
|
|
||||||
if (list.Count != HolderOptionList!.Count)
|
if (Value.Count != HolderOptionList!.Count)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Value set to option list cannot change the list's length.");
|
throw new InvalidOperationException($"Value set to option list cannot change the list's length.");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < list.Count; i++)
|
for (int i = 0; i < Value.Count; i++)
|
||||||
{
|
{
|
||||||
SetValue(i, list[i]!);
|
SetValue(i, Value[i]!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,18 +78,19 @@ public abstract class ModdedOptionListAttribute(string title) : PropertyOptionAt
|
|||||||
[SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "I don't even know if this is worth it.")]
|
[SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "I don't even know if this is worth it.")]
|
||||||
protected string GetFormattedTitle(int index)
|
protected string GetFormattedTitle(int index)
|
||||||
{
|
{
|
||||||
Match match = Regex.Match(Title, @"\{(\d+)(?::[^}]+)?\}", default, Regex.InfiniteMatchTimeout);
|
var match = Regex.Match(Title.Translate(), @"\{(\d+)(?::[^}]+)?\}", default, Regex.InfiniteMatchTimeout);
|
||||||
|
|
||||||
if (match.Success)
|
if (!match.Success)
|
||||||
{
|
{
|
||||||
if (match.Groups.Count == 1 && match.Groups[0].Value == "0")
|
return Title + index;
|
||||||
{
|
|
||||||
return string.Format(Title, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
Error("ModdedOptionList Title cannot contain more than the first parameter for formatting.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (match.Value == "{0}" && !match.NextMatch().Success)
|
||||||
|
{
|
||||||
|
return string.Format(Title, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
Error($"ModdedOptionList Title of {Title} cannot contain more than the first parameter for formatting.");
|
||||||
return Title + index;
|
return Title + index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Reflection;
|
||||||
|
using MiraAPI.GameOptions.OptionTypes;
|
||||||
|
|
||||||
|
namespace MiraAPI.GameOptions.Attributes;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attribute for creating a list of player options.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="title">The option title.</param>
|
||||||
|
/// <param name="allowNone">Whether the option includes a none option. If None is selected, value will return -1.</param>
|
||||||
|
[AttributeUsage(AttributeTargets.Property)]
|
||||||
|
public class ModdedPlayerOptionListAttribute(
|
||||||
|
string title,
|
||||||
|
bool allowNone = true)
|
||||||
|
: ModdedOptionListAttribute(title)
|
||||||
|
{
|
||||||
|
internal override IModdedOptionList CreateOptionList(IList value, PropertyInfo property)
|
||||||
|
{
|
||||||
|
return new ModdedOptionList<ModdedPlayerOption>(value.Count, idx =>
|
||||||
|
{
|
||||||
|
return new(GetFormattedTitle(idx), allowNone);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void SetValue(int idx, object value)
|
||||||
|
{
|
||||||
|
if (HolderOptionList?[idx] is not ModdedPlayerOption opt)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var final = value switch
|
||||||
|
{
|
||||||
|
NetworkedPlayerInfo info => opt.Values.IndexOf(info),
|
||||||
|
_ => (int)value,
|
||||||
|
};
|
||||||
|
opt?.SetValue(final);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override object GetValue(int idx)
|
||||||
|
{
|
||||||
|
if (HolderOptionList?[idx] is not ModdedNumberOption opt)
|
||||||
|
throw new InvalidOperationException($"HolderOption for option \"{GetFormattedTitle(idx)}\" is not a ModdedNumberOption");
|
||||||
|
|
||||||
|
var value = opt.Value;
|
||||||
|
|
||||||
|
if (ValueType == typeof(int))
|
||||||
|
return (int)Math.Round(value);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,7 +36,7 @@ public class ModdedStringOptionListAttribute(
|
|||||||
public override object GetValue(int idx)
|
public override object GetValue(int idx)
|
||||||
{
|
{
|
||||||
return HolderOptionList?[idx] is ModdedStringOption opt
|
return HolderOptionList?[idx] is ModdedStringOption opt
|
||||||
? (object)opt.Value
|
? opt.Value
|
||||||
: throw new InvalidOperationException($"HolderOption for option \"{GetFormattedTitle(idx)}\" is not a ModdedStringOption");
|
: throw new InvalidOperationException($"HolderOption for option \"{GetFormattedTitle(idx)}\" is not a ModdedStringOption");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ public class ModdedToggleOptionListAttribute(string title) : ModdedOptionListAtt
|
|||||||
public override object GetValue(int idx)
|
public override object GetValue(int idx)
|
||||||
{
|
{
|
||||||
return HolderOptionList?[idx] is ModdedToggleOption opt
|
return HolderOptionList?[idx] is ModdedToggleOption opt
|
||||||
? (object)opt.Value
|
? opt.Value
|
||||||
: throw new InvalidOperationException($"Holder option for {GetFormattedTitle(idx)} is not a ModdedToggleOption.");
|
: throw new InvalidOperationException($"Holder option for {GetFormattedTitle(idx)} is not a ModdedToggleOption.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,14 +62,14 @@ public static class ModdedOptionsManager
|
|||||||
|
|
||||||
internal static bool RegisterGroup(Type type)
|
internal static bool RegisterGroup(Type type)
|
||||||
{
|
{
|
||||||
if (Activator.CreateInstance(type) is not AbstractOptionGroup group)
|
if (TypeToGroup.ContainsKey(type))
|
||||||
{
|
{
|
||||||
|
Error($"Group {type.Name} already exists.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TypeToGroup.ContainsKey(type))
|
if (Activator.CreateInstance(type) is not AbstractOptionGroup group)
|
||||||
{
|
{
|
||||||
Logger<MiraApiPlugin>.Error($"Group {type.Name} already exists.");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,17 +79,17 @@ public static class ModdedOptionsManager
|
|||||||
|
|
||||||
internal static bool RegisterGroup(Type type, MiraPluginInfo pluginInfo)
|
internal static bool RegisterGroup(Type type, MiraPluginInfo pluginInfo)
|
||||||
{
|
{
|
||||||
if (Activator.CreateInstance(type) is not AbstractOptionGroup group)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TypeToGroup.ContainsKey(type))
|
if (TypeToGroup.ContainsKey(type))
|
||||||
{
|
{
|
||||||
Error($"Group {type.Name} already exists.");
|
Error($"Group {type.Name} already exists.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Activator.CreateInstance(type) is not AbstractOptionGroup group)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof(AbstractGameMode).IsAssignableFrom(group.OptionableType))
|
if (typeof(AbstractGameMode).IsAssignableFrom(group.OptionableType))
|
||||||
{
|
{
|
||||||
if (GameModeOptionGroups.TryGetValue(group.OptionableType, out var oldList))
|
if (GameModeOptionGroups.TryGetValue(group.OptionableType, out var oldList))
|
||||||
@@ -117,7 +117,7 @@ public static class ModdedOptionsManager
|
|||||||
Groups.Add(group);
|
Groups.Add(group);
|
||||||
TypeToGroup.Add(type, group);
|
TypeToGroup.Add(type, group);
|
||||||
typeof(OptionGroupSingleton<>).MakeGenericType(type)
|
typeof(OptionGroupSingleton<>).MakeGenericType(type)
|
||||||
.GetField("_instance", BindingFlags.Static | BindingFlags.NonPublic)! // Message suppression points to here
|
.GetField("_instance", BindingFlags.Static | BindingFlags.NonPublic)!
|
||||||
.SetValue(null, group);
|
.SetValue(null, group);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,16 +164,21 @@ public static class ModdedOptionsManager
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var setterOriginal = property.GetSetMethod(true);
|
|
||||||
var setterPatch = typeof(ModdedOptionsManager).GetMethod(nameof(PropertySetterPatch));
|
|
||||||
PluginSingleton<MiraApiPlugin>.Instance.Harmony.Patch(setterOriginal, postfix: new HarmonyMethod(setterPatch));
|
|
||||||
|
|
||||||
var getterOriginal = property.GetGetMethod(true);
|
var getterOriginal = property.GetGetMethod(true);
|
||||||
var getterPatch = typeof(ModdedOptionsManager).GetMethod(nameof(PropertyGetterPatch));
|
var getterPatch = typeof(ModdedOptionsManager).GetMethod(nameof(PropertyGetterPatch));
|
||||||
PluginSingleton<MiraApiPlugin>.Instance.Harmony.Patch(getterOriginal, prefix: new HarmonyMethod(getterPatch));
|
PluginSingleton<MiraApiPlugin>.Instance.Harmony.Patch(getterOriginal, prefix: new HarmonyMethod(getterPatch));
|
||||||
|
|
||||||
|
var setterOriginal = property.GetSetMethod(true);
|
||||||
|
|
||||||
|
if (setterOriginal != null)
|
||||||
|
{
|
||||||
|
var setterPatch = typeof(ModdedOptionsManager).GetMethod(nameof(PropertySetterPatch));
|
||||||
|
PluginSingleton<MiraApiPlugin>.Instance.Harmony.Patch(setterOriginal, postfix: new HarmonyMethod(setterPatch));
|
||||||
|
}
|
||||||
|
|
||||||
OptionAttributes.Add(property, attribute);
|
OptionAttributes.Add(property, attribute);
|
||||||
attribute.HolderOption = option;
|
attribute.HolderOption = option;
|
||||||
|
attribute.ValueType = property.PropertyType;
|
||||||
|
|
||||||
var visibilityAttr = property.GetCustomAttribute<ModdedOptionVisibilityAttribute>();
|
var visibilityAttr = property.GetCustomAttribute<ModdedOptionVisibilityAttribute>();
|
||||||
var visibilityFunc = visibilityAttr?.GetVisibility(group, property);
|
var visibilityFunc = visibilityAttr?.GetVisibility(group, property);
|
||||||
@@ -220,9 +225,9 @@ public static class ModdedOptionsManager
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Func<int, string> configName = optionList.ConfigName ?? (i => property.Name + (i + 1));
|
var configName = optionList.ConfigName ?? (i => property.Name + (i + 1));
|
||||||
|
|
||||||
for (int i = 0; i < optionList.Count; i++)
|
for (var i = 0; i < optionList.Count; i++)
|
||||||
{
|
{
|
||||||
RegisterOption(optionList[i], group, configName(i), pluginInfo);
|
RegisterOption(optionList[i], group, configName(i), pluginInfo);
|
||||||
}
|
}
|
||||||
@@ -269,32 +274,41 @@ public static class ModdedOptionsManager
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var setterOriginal = property.GetSetMethod(true);
|
|
||||||
var setterPatch = typeof(ModdedOptionsManager).GetMethod(nameof(PropertySetterPatch));
|
|
||||||
PluginSingleton<MiraApiPlugin>.Instance.Harmony.Patch(setterOriginal, postfix: new HarmonyMethod(setterPatch));
|
|
||||||
|
|
||||||
var getterOriginal = property.GetGetMethod(true);
|
var getterOriginal = property.GetGetMethod(true);
|
||||||
var getterPatch = typeof(ModdedOptionsManager).GetMethod(nameof(PropertyGetterPatch));
|
var getterPatch = typeof(ModdedOptionsManager).GetMethod(nameof(PropertyGetterPatch));
|
||||||
PluginSingleton<MiraApiPlugin>.Instance.Harmony.Patch(getterOriginal, prefix: new HarmonyMethod(getterPatch));
|
PluginSingleton<MiraApiPlugin>.Instance.Harmony.Patch(getterOriginal, prefix: new HarmonyMethod(getterPatch));
|
||||||
|
|
||||||
|
var setterOriginal = property.GetSetMethod(true);
|
||||||
|
|
||||||
|
if (setterOriginal != null)
|
||||||
|
{
|
||||||
|
var setterPatch = typeof(ModdedOptionsManager).GetMethod(nameof(PropertySetterPatch));
|
||||||
|
PluginSingleton<MiraApiPlugin>.Instance.Harmony.Patch(setterOriginal, postfix: new HarmonyMethod(setterPatch));
|
||||||
|
}
|
||||||
|
|
||||||
var listType = propertyList.GetType();
|
var listType = propertyList.GetType();
|
||||||
|
|
||||||
if (PatchedListTypes.Add(listType))
|
if (PatchedListTypes.Add(listType))
|
||||||
{
|
{
|
||||||
var listIndex = listType.GetProperty("Item")!;
|
var listIndex = listType.GetProperty("Item")!;
|
||||||
|
|
||||||
var listSetterOriginal = listIndex.GetSetMethod(true);
|
|
||||||
var listSetterPatch = typeof(ModdedOptionsManager).GetMethod(nameof(PropertyListSetterPatch));
|
|
||||||
PluginSingleton<MiraApiPlugin>.Instance.Harmony.Patch(listSetterOriginal, postfix: new HarmonyMethod(listSetterPatch));
|
|
||||||
|
|
||||||
var listGetterOriginal = listIndex.GetGetMethod(true);
|
var listGetterOriginal = listIndex.GetGetMethod(true);
|
||||||
var listGetterPatch = typeof(ModdedOptionsManager).GetMethod(nameof(PropertyListGetterPatch));
|
var listGetterPatch = typeof(ModdedOptionsManager).GetMethod(nameof(PropertyListGetterPatch));
|
||||||
PluginSingleton<MiraApiPlugin>.Instance.Harmony.Patch(listGetterOriginal, prefix: new HarmonyMethod(listGetterPatch));
|
PluginSingleton<MiraApiPlugin>.Instance.Harmony.Patch(listGetterOriginal, prefix: new HarmonyMethod(listGetterPatch));
|
||||||
|
|
||||||
|
var listSetterOriginal = listIndex.GetSetMethod(true);
|
||||||
|
|
||||||
|
if (listSetterOriginal != null)
|
||||||
|
{
|
||||||
|
var listSetterPatch = typeof(ModdedOptionsManager).GetMethod(nameof(PropertyListSetterPatch));
|
||||||
|
PluginSingleton<MiraApiPlugin>.Instance.Harmony.Patch(listSetterOriginal, postfix: new HarmonyMethod(listSetterPatch));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionAttributes.Add(property, attribute);
|
OptionAttributes.Add(property, attribute);
|
||||||
attribute.HolderOptionList = optionList;
|
attribute.HolderOptionList = optionList;
|
||||||
attribute.Value = propertyVal;
|
attribute.Value = (IList)propertyVal;
|
||||||
|
attribute.ValueType = listType.GetGenericArguments()[0];
|
||||||
|
|
||||||
var valueType = property.PropertyType.GetGenericArguments()[0];
|
var valueType = property.PropertyType.GetGenericArguments()[0];
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public class ModdedEnumOption : ModdedOption<int>
|
|||||||
$"{ParentMod!.OptionsTitleText}.EnumOption.{TranslationController.Instance.GetString(StringName)}";
|
$"{ParentMod!.OptionsTitleText}.EnumOption.{TranslationController.Instance.GetString(StringName)}";
|
||||||
|
|
||||||
stringOption.SetUpFromData(Data, 20);
|
stringOption.SetUpFromData(Data, 20);
|
||||||
stringOption.OnValueChanged = (Il2CppSystem.Action<OptionBehaviour>)ValueChanged;
|
stringOption.OnValueChanged = (Action<OptionBehaviour>)ValueChanged;
|
||||||
|
|
||||||
// Changing the button text to make them more distinct from number options
|
// Changing the button text to make them more distinct from number options
|
||||||
stringOption.MinusBtn.ChangeButtonText("<");
|
stringOption.MinusBtn.ChangeButtonText("<");
|
||||||
@@ -153,7 +153,7 @@ public class ModdedEnumOption<T> : ModdedOption<T>
|
|||||||
$"{ParentMod!.OptionsTitleText}.EnumOption.{TranslationController.Instance.GetString(StringName)}";
|
$"{ParentMod!.OptionsTitleText}.EnumOption.{TranslationController.Instance.GetString(StringName)}";
|
||||||
|
|
||||||
stringOption.SetUpFromData(Data, 20);
|
stringOption.SetUpFromData(Data, 20);
|
||||||
stringOption.OnValueChanged = (Il2CppSystem.Action<OptionBehaviour>)ValueChanged;
|
stringOption.OnValueChanged = (Action<OptionBehaviour>)ValueChanged;
|
||||||
|
|
||||||
// Changing the button text to make them more distinct from number options
|
// Changing the button text to make them more distinct from number options
|
||||||
stringOption.MinusBtn.ChangeButtonText("<");
|
stringOption.MinusBtn.ChangeButtonText("<");
|
||||||
|
|||||||
@@ -78,8 +78,36 @@ public class ModdedNumberOption : ModdedOption<float>
|
|||||||
string? formatString = null,
|
string? formatString = null,
|
||||||
bool halfIncrements = false,
|
bool halfIncrements = false,
|
||||||
bool includeInPreset = true)
|
bool includeInPreset = true)
|
||||||
: this(title, defaultValue, min, max, increment, suffixType, zeroBehavior, negativeBehavior, halfIncrements, formatString, includeInPreset)
|
: base(title, defaultValue, includeInPreset)
|
||||||
{
|
{
|
||||||
|
Min = min;
|
||||||
|
Max = max;
|
||||||
|
Increment = increment;
|
||||||
|
SuffixType = suffixType;
|
||||||
|
ZeroWordValue = zeroBehavior;
|
||||||
|
ShiftIncrement = halfIncrements;
|
||||||
|
NegativeWordValue = negativeBehavior;
|
||||||
|
|
||||||
|
Value = Mathf.Clamp(defaultValue, min, max);
|
||||||
|
|
||||||
|
var data = ScriptableObject.CreateInstance<FloatGameSetting>();
|
||||||
|
data.Type = global::OptionTypes.Float;
|
||||||
|
data.Title = StringName;
|
||||||
|
data.Value = Value;
|
||||||
|
data.Increment = Increment;
|
||||||
|
data.ValidRange = new FloatRange(Min, Max);
|
||||||
|
data.FormatString = formatString ??
|
||||||
|
(defaultValue.IsInteger() &&
|
||||||
|
Increment.IsInteger() &&
|
||||||
|
Value.IsInteger() &&
|
||||||
|
Min.IsInteger() &&
|
||||||
|
Max.IsInteger() ? "0" : "0.0");
|
||||||
|
|
||||||
|
data.ZeroIsInfinity = ZeroInfinity;
|
||||||
|
data.SuffixType = (NumberSuffixes)SuffixType;
|
||||||
|
data.OptionName = FloatOptionNames.Invalid;
|
||||||
|
|
||||||
|
Data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -104,54 +132,10 @@ public class ModdedNumberOption : ModdedOption<float>
|
|||||||
string? formatString = null,
|
string? formatString = null,
|
||||||
bool zeroInfinity = false,
|
bool zeroInfinity = false,
|
||||||
bool includeInPreset = true)
|
bool includeInPreset = true)
|
||||||
: this(title, defaultValue, min, max, increment, suffixType, zeroInfinity ? "∞" : "#", "#", increment == 1f, formatString, includeInPreset)
|
: this(title, defaultValue, min, max, increment, zeroInfinity ? "∞" : "#", "#", suffixType, formatString, increment == 1f, includeInPreset)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModdedNumberOption(
|
|
||||||
string title,
|
|
||||||
float defaultValue,
|
|
||||||
float min,
|
|
||||||
float max,
|
|
||||||
float increment,
|
|
||||||
MiraNumberSuffixes suffixType,
|
|
||||||
string zeroBehavior,
|
|
||||||
string negativeBehavior,
|
|
||||||
bool shiftIncrement,
|
|
||||||
string? formatString,
|
|
||||||
bool includeInPreset)
|
|
||||||
: base(title, defaultValue, includeInPreset)
|
|
||||||
{
|
|
||||||
Min = min;
|
|
||||||
Max = max;
|
|
||||||
Increment = increment;
|
|
||||||
SuffixType = suffixType;
|
|
||||||
ZeroWordValue = zeroBehavior;
|
|
||||||
ShiftIncrement = shiftIncrement;
|
|
||||||
NegativeWordValue = negativeBehavior;
|
|
||||||
|
|
||||||
Value = Mathf.Clamp(defaultValue, min, max);
|
|
||||||
|
|
||||||
var data = ScriptableObject.CreateInstance<FloatGameSetting>();
|
|
||||||
data.Type = global::OptionTypes.Float;
|
|
||||||
data.Title = StringName;
|
|
||||||
data.Value = Value;
|
|
||||||
data.Increment = Increment;
|
|
||||||
data.ValidRange = new FloatRange(Min, Max);
|
|
||||||
data.FormatString = formatString ??
|
|
||||||
(defaultValue.IsInteger() &&
|
|
||||||
Increment.IsInteger() &&
|
|
||||||
Value.IsInteger() &&
|
|
||||||
Min.IsInteger() &&
|
|
||||||
Max.IsInteger() ? "0" : "0.0");
|
|
||||||
|
|
||||||
data.ZeroIsInfinity = ZeroInfinity;
|
|
||||||
data.SuffixType = (NumberSuffixes)SuffixType;
|
|
||||||
data.OptionName = FloatOptionNames.Invalid;
|
|
||||||
|
|
||||||
Data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override OptionBehaviour CreateOption(
|
public override OptionBehaviour CreateOption(
|
||||||
ToggleOption toggleOpt,
|
ToggleOption toggleOpt,
|
||||||
|
|||||||
@@ -29,6 +29,11 @@ public class ModdedPlayerOption : ModdedOption<int>
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool AllowNone { get; set; }
|
public bool AllowNone { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the player selected by this option. May be <c>null</c> if allowed to have <c>None</c> as an option.
|
||||||
|
/// </summary>
|
||||||
|
public NetworkedPlayerInfo? SelectedPlayer => Value == -1 ? null : Values[Value];
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ModdedPlayerOption"/> class.
|
/// Initializes a new instance of the <see cref="ModdedPlayerOption"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -64,7 +69,7 @@ public class ModdedPlayerOption : ModdedOption<int>
|
|||||||
Values = GetFilteredPlayers();
|
Values = GetFilteredPlayers();
|
||||||
|
|
||||||
playerOption.SetUpFromData(Data, 20);
|
playerOption.SetUpFromData(Data, 20);
|
||||||
playerOption.OnValueChanged = (Il2CppSystem.Action<OptionBehaviour>)ValueChanged;
|
playerOption.OnValueChanged = (Action<OptionBehaviour>)ValueChanged;
|
||||||
|
|
||||||
playerOption.Title = StringName;
|
playerOption.Title = StringName;
|
||||||
playerOption.TitleText.text = Title.Translate();
|
playerOption.TitleText.text = Title.Translate();
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ public class ModdedStringOption : ModdedOption<string>
|
|||||||
$"{ParentMod!.OptionsTitleText}.StringOption.{TranslationController.Instance.GetString(StringName)}";
|
$"{ParentMod!.OptionsTitleText}.StringOption.{TranslationController.Instance.GetString(StringName)}";
|
||||||
|
|
||||||
stringOption.SetUpFromData(Data, 20);
|
stringOption.SetUpFromData(Data, 20);
|
||||||
stringOption.OnValueChanged = (Il2CppSystem.Action<OptionBehaviour>)ValueChanged;
|
stringOption.OnValueChanged = (Action<OptionBehaviour>)ValueChanged;
|
||||||
|
|
||||||
// Changing the button text to make them more distinct from number options
|
// Changing the button text to make them more distinct from number options
|
||||||
stringOption.MinusBtn.ChangeButtonText("<");
|
stringOption.MinusBtn.ChangeButtonText("<");
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ namespace MiraAPI.GameOptions.OptionTypes;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ModdedToggleOption : ModdedOption<bool>
|
public class ModdedToggleOption : ModdedOption<bool>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the delegate that dictates how a toggle option's value is displayed.
|
||||||
|
/// </summary>
|
||||||
|
public Func<bool, string> DisplayValue { get; set; } = value => value ? "On" : "Off";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ModdedToggleOption"/> class.
|
/// Initializes a new instance of the <see cref="ModdedToggleOption"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -39,7 +44,7 @@ public class ModdedToggleOption : ModdedOption<bool>
|
|||||||
toggleOption.Title = StringName;
|
toggleOption.Title = StringName;
|
||||||
toggleOption.TitleText.text = Title.Translate();
|
toggleOption.TitleText.text = Title.Translate();
|
||||||
toggleOption.CheckMark.enabled = Value;
|
toggleOption.CheckMark.enabled = Value;
|
||||||
toggleOption.OnValueChanged = (Il2CppSystem.Action<OptionBehaviour>)ValueChanged;
|
toggleOption.OnValueChanged = (Action<OptionBehaviour>)ValueChanged;
|
||||||
|
|
||||||
OptionBehaviour = toggleOption;
|
OptionBehaviour = toggleOption;
|
||||||
|
|
||||||
@@ -76,7 +81,7 @@ public class ModdedToggleOption : ModdedOption<bool>
|
|||||||
ModdedOptionsManager.AddSettingsChangeMessage(
|
ModdedOptionsManager.AddSettingsChangeMessage(
|
||||||
HudManager.Instance.Notifier,
|
HudManager.Instance.Notifier,
|
||||||
StringName,
|
StringName,
|
||||||
newValue ? "On" : "Off",
|
DisplayValue(newValue).Translate(),
|
||||||
Configuration.PopUpTextColor,
|
Configuration.PopUpTextColor,
|
||||||
Configuration.PopUpIconTmp,
|
Configuration.PopUpIconTmp,
|
||||||
false);
|
false);
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ public sealed class HideAndSeekHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
|||||||
currentFinalHideTime = totalFinalHideTime;
|
currentFinalHideTime = totalFinalHideTime;
|
||||||
if (timerBar != null)
|
if (timerBar != null)
|
||||||
{
|
{
|
||||||
Object.Destroy(timerBar);
|
Destroy(timerBar);
|
||||||
}
|
}
|
||||||
|
|
||||||
finalHideAlertSfx = GameManagerCreator.Instance.HideAndSeekManagerPrefab.FinalHideAlertSFX;
|
finalHideAlertSfx = GameManagerCreator.Instance.HideAndSeekManagerPrefab.FinalHideAlertSFX;
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ public sealed class MiraHudHelper(nint cppPtr) : MonoBehaviour(cppPtr)
|
|||||||
var oldPos = settingsButton.transform.localPosition;
|
var oldPos = settingsButton.transform.localPosition;
|
||||||
settingsButton.transform.localPosition = new Vector3(oldPos.x, oldPos.y, -100);
|
settingsButton.transform.localPosition = new Vector3(oldPos.x, oldPos.y, -100);
|
||||||
var chatButton = instance.Chat.chatButton.gameObject;
|
var chatButton = instance.Chat.chatButton.gameObject;
|
||||||
ClonedChatButton = Object.Instantiate(chatButton, chatButton.transform.parent);
|
ClonedChatButton = Instantiate(chatButton, chatButton.transform.parent);
|
||||||
ClonedChatButton.SetActive(false);
|
ClonedChatButton.SetActive(false);
|
||||||
instance.Chat.chatButtonAspectPosition = ClonedChatButton.GetComponent<AspectPosition>();
|
instance.Chat.chatButtonAspectPosition = ClonedChatButton.GetComponent<AspectPosition>();
|
||||||
chatButton.GetComponent<AspectPosition>().Destroy();
|
chatButton.GetComponent<AspectPosition>().Destroy();
|
||||||
|
|||||||
@@ -313,9 +313,9 @@ public sealed class MiraPluginManager
|
|||||||
|
|
||||||
foreach (var property in type.GetProperties())
|
foreach (var property in type.GetProperties())
|
||||||
{
|
{
|
||||||
if (property.GetMethod?.IsStatic == true)
|
if (property.GetMethod?.IsStatic == true && property.GetCustomAttribute<MiraIgnoreAttribute>() == null)
|
||||||
{
|
{
|
||||||
Error($"Option property {property.Name} in {type.Name} must not be static.");
|
Error($"Non-ignored option property {property.Name} in {type.Name} must not be static.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,6 +325,12 @@ public sealed class MiraPluginManager
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (property.PropertyType.IsAssignableTo(typeof(IModdedOptionList)))
|
||||||
|
{
|
||||||
|
ModdedOptionsManager.RegisterPropertyOptionList(type, property, pluginInfo);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
var attribute = property.GetCustomAttribute<ModdedOptionAttribute>();
|
var attribute = property.GetCustomAttribute<ModdedOptionAttribute>();
|
||||||
if (attribute != null)
|
if (attribute != null)
|
||||||
{
|
{
|
||||||
@@ -332,11 +338,6 @@ public sealed class MiraPluginManager
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (property.PropertyType.IsAssignableTo(typeof(IModdedOptionList)))
|
|
||||||
{
|
|
||||||
ModdedOptionsManager.RegisterPropertyOptionList(type, property, pluginInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
var listAttr = property.GetCustomAttribute<ModdedOptionListAttribute>();
|
var listAttr = property.GetCustomAttribute<ModdedOptionListAttribute>();
|
||||||
if (listAttr != null)
|
if (listAttr != null)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in new issue
Block a user