Compare commits

..
4 Commits
Author SHA1 Message Date
Faulo Fault fdd0574ddc Translated using Weblate (Spanish (Latin America))
Currently translated at 100.0% (77 of 77 strings)

Translation: Mira API/Mira API
Translate-URL: https://weblate.duikbo.at/projects/mira-api/mira-api/es_419/
2026-10-22 20:19:08 +00:00
Turret 08af14a890 Translated using Weblate (Polish)
Currently translated at 100.0% (77 of 77 strings)

Translation: Mira API/Mira API
Translate-URL: https://weblate.duikbo.at/projects/mira-api/mira-api/pl/
2026-10-20 14:19:07 +00:00
Anonymous e2a3dc782b Translated using Weblate (Russian)
Currently translated at 12.9% (10 of 77 strings)

Translation: Mira API/Mira API
Translate-URL: https://weblate.duikbo.at/projects/mira-api/mira-api/ru/
2026-10-19 06:19:07 +00:00
Anonymous 109dc796c5 Translated using Weblate (French)
Currently translated at 12.9% (10 of 77 strings)

Translation: Mira API/Mira API
Translate-URL: https://weblate.duikbo.at/projects/mira-api/mira-api/fr/
2026-10-19 06:19:07 +00:00
45 changed files with 541 additions and 831 deletions

No files matched your search

-3
View File
@@ -104,6 +104,3 @@ dotnet_diagnostic.S1244.severity = none
# S2325: Methods and properties that don't access instance data should be static # S2325: Methods and properties that don't access instance data should be static
dotnet_diagnostic.S2325.severity = none dotnet_diagnostic.S2325.severity = none
# IDE0005: Using directive is unnecessary.
dotnet_diagnostic.IDE0005.severity = warning
+1 -1
View File
@@ -8,7 +8,7 @@
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile> <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<VersionPrefix>0.6.0</VersionPrefix> <VersionPrefix>0.5.0</VersionPrefix>
<VersionSuffix>dev</VersionSuffix> <VersionSuffix>dev</VersionSuffix>
<Authors>All Of Us, XtraCube, Angxl</Authors> <Authors>All Of Us, XtraCube, Angxl</Authors>
+6 -9
View File
@@ -1,17 +1,14 @@
using System.Reflection; using MiraAPI.Utilities.Assets;
using MiraAPI.Utilities.Assets;
namespace MiraAPI.Example; namespace MiraAPI.Example;
public static class ExampleAssets public static class ExampleAssets
{ {
private static readonly Assembly _assembly = typeof(MiraAssets).Assembly; public static LoadableResourceAsset ExampleButton { get; } = new("MiraAPI.Example.Resources.ExampleButton.png");
public static LoadableResourceAsset CallMeetingButton { get; } = new("MiraAPI.Example.Resources.CallMeeting.png");
public static LoadableResourceAsset ExampleButton { get; } = new("MiraAPI.Example.Resources.ExampleButton.png", _assembly);
public static LoadableResourceAsset CallMeetingButton { get; } = new("MiraAPI.Example.Resources.CallMeeting.png", _assembly);
// Credit to EpicHorrors for the teleport button asset. // Credit to EpicHorrors for the teleport button asset.
public static LoadableResourceAsset TeleportButton { get; } = new("MiraAPI.Example.Resources.TeleportButton.png", _assembly); public static LoadableResourceAsset TeleportButton { get; } = new("MiraAPI.Example.Resources.TeleportButton.png");
public static LoadableResourceAsset SharpshootButton { get; } = new("MiraAPI.Example.Resources.SharpshootButton.png", _assembly); public static LoadableResourceAsset SharpshootButton { get; } = new("MiraAPI.Example.Resources.SharpshootButton.png");
public static LoadableResourceAsset Banner { get; } = new("MiraAPI.Example.Resources.FortniteBanner.jpeg", _assembly); public static LoadableResourceAsset Banner { get; } = new("MiraAPI.Example.Resources.FortniteBanner.jpeg");
} }
+2 -2
View File
@@ -31,7 +31,7 @@ public static class ExampleEventHandlers
MiraEventManager.RegisterEventHandler<CompleteTaskEvent>(@event => MiraEventManager.RegisterEventHandler<CompleteTaskEvent>(@event =>
{ {
Logger<ExamplePlugin>.Info($"{@event.Player.Data.PlayerName} completed {@event.Task.TaskType}"); Logger<ExamplePlugin>.Info($"{@event.Player.Data.PlayerName} completed {@event.Task.TaskType.ToString()}");
}); });
// You can also unregister event handlers using the handle returned from RegisterEventHandler. // You can also unregister event handlers using the handle returned from RegisterEventHandler.
@@ -89,7 +89,7 @@ public static class ExampleEventHandlers
[RegisterEvent] [RegisterEvent]
public static void UpdateSystemEventHandler(UpdateSystemEvent @event) public static void UpdateSystemEventHandler(UpdateSystemEvent @event)
{ {
Logger<ExamplePlugin>.Error(@event.SystemType); Logger<ExamplePlugin>.Error(@event.SystemType.ToString());
} }
// Example event handler // Example event handler
+2 -2
View File
@@ -35,7 +35,7 @@ public static class MiraEventManager
} }
catch (Exception ex) catch (Exception ex)
{ {
Error($"Error invoking event handler for {typeof(T).Name}: {ex}"); Error($"Error invoking event handler for {typeof(T).Name}: {ex.ToString()}");
} }
} }
@@ -65,7 +65,7 @@ public static class MiraEventManager
} }
catch (Exception ex) catch (Exception ex)
{ {
Error($"Error invoking event handler for {type.Name}: {ex}"); Error($"Error invoking event handler for {type.Name}: {ex.ToString()}");
} }
} }
@@ -14,13 +14,8 @@ public sealed class ModdedOptionChangedAttribute(string? methodName = null, Type
{ {
internal Delegate? GetChanged(AbstractOptionGroup group, PropertyInfo property, IModdedOption option) internal Delegate? GetChanged(AbstractOptionGroup group, PropertyInfo property, IModdedOption option)
{ {
if (ResolveMethod(group, property, out var type, out var instanceGetter, out var notFound) is not { } method) if (ResolveMethod(group, property, out var type, out var instanceGetter) is not { } method)
{
if (notFound)
Error($"Method {MemberName} does not exist in {type.FullName}");
return null; return null;
}
var valueType = option.GetValueType(); var valueType = option.GetValueType();
@@ -33,13 +28,8 @@ public sealed class ModdedOptionChangedAttribute(string? methodName = null, Type
internal Func<int, Delegate?>? GetListChanged(AbstractOptionGroup group, PropertyInfo property, Type valueType) internal Func<int, Delegate?>? GetListChanged(AbstractOptionGroup group, PropertyInfo property, Type valueType)
{ {
if (ResolveMethod(group, property, out var type, out var instanceGetter, out var notFound) is not { } method) if (ResolveMethod(group, property, out var type, out var instanceGetter) is not { } method)
{
if (notFound)
Error($"Method {MemberName} does not exist in {type.FullName}");
return null; return null;
}
if (!ValidateListSignature(method, typeof(void), out var hasIndex, valueType)) if (!ValidateListSignature(method, typeof(void), out var hasIndex, valueType))
return null; return null;
@@ -14,13 +14,8 @@ public sealed class ModdedOptionGetterAttribute(string? methodName = null, Type?
{ {
internal Delegate? GetGetter(AbstractOptionGroup group, PropertyInfo property, IModdedOption option) internal Delegate? GetGetter(AbstractOptionGroup group, PropertyInfo property, IModdedOption option)
{ {
if (ResolveMethod(group, property, out var type, out var instanceGetter, out var notFound) is not { } method) if (ResolveMethod(group, property, out var type, out var instanceGetter) is not { } method)
{
if (notFound)
Error($"Method {MemberName} does not exist in {type.FullName}");
return null; return null;
}
var valueType = option.GetValueType(); var valueType = option.GetValueType();
@@ -33,13 +28,8 @@ public sealed class ModdedOptionGetterAttribute(string? methodName = null, Type?
internal Func<int, Delegate?>? GetListGetter(AbstractOptionGroup group, PropertyInfo property, Type valueType) internal Func<int, Delegate?>? GetListGetter(AbstractOptionGroup group, PropertyInfo property, Type valueType)
{ {
if (ResolveMethod(group, property, out var type, out var instanceGetter, out var notFound) is not { } method) if (ResolveMethod(group, property, out var type, out var instanceGetter) is not { } method)
{
if (notFound)
Error($"Method {MemberName} does not exist in {type.FullName}");
return null; return null;
}
if (!ValidateListSignature(method, valueType, out var hasIndex, valueType)) if (!ValidateListSignature(method, valueType, out var hasIndex, valueType))
return null; return null;
@@ -4,7 +4,6 @@ using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Reflection.Emit; using System.Reflection.Emit;
using MiraAPI.Utilities;
namespace MiraAPI.GameOptions.Attributes; namespace MiraAPI.GameOptions.Attributes;
@@ -128,7 +127,7 @@ public abstract class ModdedOptionMemberAttribute(string? memberName, Type? hold
} }
/// <summary> /// <summary>
/// Resolves the target <see cref="MemberInfo"/> (property, field or method) and its associated singleton instance getter, if applicable. /// Resolves the target <see cref="MemberInfo"/> (property or method) and its associated singleton instance getter, if applicable.
/// </summary> /// </summary>
/// <param name="group">The option group instance the property belongs to.</param> /// <param name="group">The option group instance the property belongs to.</param>
/// <param name="property">The option property decorated with this attribute.</param> /// <param name="property">The option property decorated with this attribute.</param>
@@ -137,18 +136,15 @@ public abstract class ModdedOptionMemberAttribute(string? memberName, Type? hold
/// When this method returns, contains the <see cref="OptionGroupSingleton{T}.Instance"/> getter <see cref="MethodInfo"/> /// When this method returns, contains the <see cref="OptionGroupSingleton{T}.Instance"/> getter <see cref="MethodInfo"/>
/// if the resolved member is an instance member on an <see cref="AbstractOptionGroup"/>; otherwise, <see langword="null"/>. /// if the resolved member is an instance member on an <see cref="AbstractOptionGroup"/>; otherwise, <see langword="null"/>.
/// </param> /// </param>
/// <param name="notFound">When this method returns, contains a flag that indicates if the member was not found, as null can be returned from other circumstances too.</param>
/// <returns>The resolved <see cref="MemberInfo"/> if found; otherwise, <see langword="null"/>.</returns> /// <returns>The resolved <see cref="MemberInfo"/> if found; otherwise, <see langword="null"/>.</returns>
[SuppressMessage("Major Code Smell", "S3011:Reflection should not be used to increase accessibility of classes, methods, or fields", Justification = "It is safe.")] [SuppressMessage("Major Code Smell", "S3011:Reflection should not be used to increase accessibility of classes, methods, or fields", Justification = "It is safe.")]
protected MemberInfo? ResolveMember(AbstractOptionGroup group, PropertyInfo property, out Type type, out MethodInfo? instanceGetter, out bool notFound) protected MemberInfo? ResolveMember(AbstractOptionGroup group, PropertyInfo property, out Type type, out MethodInfo? instanceGetter)
{ {
var groupType = group.GetType(); var groupType = group.GetType();
var flags = BindingFlags.Static | BindingFlags.Public; var flags = BindingFlags.Static | BindingFlags.Public;
MemberName ??= property.Name + defaultSuffix;
type = holderType ?? groupType; type = holderType ?? groupType;
instanceGetter = null; MemberName ??= property.Name + defaultSuffix;
if (type.IsAssignableTo(typeof(AbstractOptionGroup))) if (type.IsAssignableTo(typeof(AbstractOptionGroup)))
{ {
@@ -162,69 +158,12 @@ public abstract class ModdedOptionMemberAttribute(string? memberName, Type? hold
.GetProperty(nameof(OptionGroupSingleton<>.Instance))! .GetProperty(nameof(OptionGroupSingleton<>.Instance))!
.GetGetMethod(); .GetGetMethod();
} }
else if (!type.IsStatic()) else
{ {
flags |= BindingFlags.Instance; instanceGetter = null;
var canSearchPrivates = type.GetCustomAttribute<SearchPrivateAttribute>() != null;
if (canSearchPrivates)
flags |= BindingFlags.NonPublic;
var getterFlags = BindingFlags.Static | BindingFlags.Public | (canSearchPrivates ? BindingFlags.NonPublic : BindingFlags.Default);
foreach (var method in type.GetMethods(getterFlags))
{
if (method.GetParameters().Length > 0 || (method.GetCustomAttribute<InstanceGetterAttribute>() == null && method.Name != "GetInstance"))
continue;
instanceGetter = method;
break;
}
if (instanceGetter == null)
{
foreach (var prop in type.GetProperties(getterFlags))
{
if (prop.GetCustomAttribute<InstanceGetterAttribute>() == null && prop.Name != "Instance")
continue;
var getMethod = prop.GetGetMethod(canSearchPrivates);
if (getMethod == null)
continue;
instanceGetter = getMethod;
break;
}
}
if (instanceGetter == null)
{
Error($"No valid static instance getter (method GetInstance or property Instance) found in instanced type {type.Name}. Try renaming the method/property, or decorate it with InstanceGetterAttribute.");
notFound = false;
return null;
}
if (!instanceGetter.ReturnType.IsAssignableTo(type))
{
Error($"Found instance getter {instanceGetter.Name}, but the return type did not match what was expected ({type.Name}).");
notFound = false;
return null;
}
}
else if (type.GetCustomAttribute<SearchPrivateAttribute>() != null)
{
flags |= BindingFlags.NonPublic;
} }
var member = type.GetMember(MemberName, flags).FirstOrDefault(); var member = type.GetMember(MemberName, flags).FirstOrDefault();
notFound = true;
if (member == null)
return null;
notFound = false;
if (instanceGetter == null) if (instanceGetter == null)
return member; return member;
@@ -257,11 +196,10 @@ public abstract class ModdedOptionMemberAttribute(string? memberName, Type? hold
/// When this method returns, contains the <see cref="OptionGroupSingleton{T}.Instance"/> getter <see cref="MethodInfo"/> /// When this method returns, contains the <see cref="OptionGroupSingleton{T}.Instance"/> getter <see cref="MethodInfo"/>
/// if the resolved method is an instance method on an <see cref="AbstractOptionGroup"/>; otherwise, <see langword="null"/>. /// if the resolved method is an instance method on an <see cref="AbstractOptionGroup"/>; otherwise, <see langword="null"/>.
/// </param> /// </param>
/// <param name="notFound">When this method returns, contains a flag that indicates if the member was not found, as null can be returned from other circumstances too.</param>
/// <returns>The resolved <see cref="MethodInfo"/> if found; otherwise, <see langword="null"/>.</returns> /// <returns>The resolved <see cref="MethodInfo"/> if found; otherwise, <see langword="null"/>.</returns>
protected MethodInfo? ResolveMethod(AbstractOptionGroup group, PropertyInfo property, out Type type, out MethodInfo? instanceGetter, out bool notFound) protected MethodInfo? ResolveMethod(AbstractOptionGroup group, PropertyInfo property, out Type type, out MethodInfo? instanceGetter)
{ {
return ResolveMember(group, property, out type, out instanceGetter, out notFound) as MethodInfo; return ResolveMember(group, property, out type, out instanceGetter) as MethodInfo;
} }
/// <summary> /// <summary>
@@ -14,13 +14,8 @@ public sealed class ModdedOptionSetterAttribute(string? methodName = null, Type?
{ {
internal Delegate? GetSetter(AbstractOptionGroup group, PropertyInfo property, IModdedOption option) internal Delegate? GetSetter(AbstractOptionGroup group, PropertyInfo property, IModdedOption option)
{ {
if (ResolveMethod(group, property, out var type, out var instanceGetter, out var notFound) is not { } method) if (ResolveMethod(group, property, out var type, out var instanceGetter) is not { } method)
{
if (notFound)
Error($"Method {MemberName} does not exist in {type.FullName}");
return null; return null;
}
var valueType = option.GetValueType(); var valueType = option.GetValueType();
@@ -33,13 +28,8 @@ public sealed class ModdedOptionSetterAttribute(string? methodName = null, Type?
internal Func<int, Delegate?>? GetListSetter(AbstractOptionGroup group, PropertyInfo property, Type valueType) internal Func<int, Delegate?>? GetListSetter(AbstractOptionGroup group, PropertyInfo property, Type valueType)
{ {
if (ResolveMethod(group, property, out var type, out var instanceGetter, out var notFound) is not { } method) if (ResolveMethod(group, property, out var type, out var instanceGetter) is not { } method)
{
if (notFound)
Error($"Method {MemberName} does not exist in {type.FullName}");
return null; return null;
}
if (!ValidateListSignature(method, valueType, out var hasIndex, valueType, valueType)) if (!ValidateListSignature(method, valueType, out var hasIndex, valueType, valueType))
return null; return null;
@@ -20,11 +20,9 @@ public sealed class ModdedOptionVisibilityAttribute(string? memberName = null, T
internal Func<bool>? GetVisibility(AbstractOptionGroup group, PropertyInfo property) internal Func<bool>? GetVisibility(AbstractOptionGroup group, PropertyInfo property)
{ {
if (ResolveMember(group, property, out Type type, out var instanceGetter, out var notFound) is not { } member) if (ResolveMember(group, property, out Type type, out var instanceGetter) is not { } member)
{ {
if (notFound) Error($"Member {MemberName} does not exist in {type.FullName}");
Error($"Member {MemberName} does not exist in {type.FullName}");
return null; return null;
} }
@@ -109,11 +107,9 @@ public sealed class ModdedOptionVisibilityAttribute(string? memberName = null, T
internal Func<int, Delegate?>? GetListVisibility(AbstractOptionGroup group, PropertyInfo property) internal Func<int, Delegate?>? GetListVisibility(AbstractOptionGroup group, PropertyInfo property)
{ {
if (ResolveMember(group, property, out Type type, out var instanceGetter, out var notFound) is not { } member) if (ResolveMember(group, property, out Type type, out var instanceGetter) is not { } member)
{ {
if (notFound) Error($"Member {MemberName} does not exist in {type.FullName}");
Error($"Member {MemberName} does not exist in {type.FullName}");
return null; return null;
} }
@@ -1,15 +0,0 @@
using System;
namespace MiraAPI.GameOptions.Attributes;
/// <summary>
/// An attribute used to mark a method or property as one that returns an instance of the class it's declared in.
/// </summary>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property)]
public sealed class InstanceGetterAttribute : Attribute;
/// <summary>
/// An attribute used to mark a class as one whose reflection search should include private members.
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public sealed class SearchPrivateAttribute : Attribute;
-5
View File
@@ -77,11 +77,6 @@ public interface IModdedOption
/// </summary> /// </summary>
bool IncludeInPreset { get; set; } bool IncludeInPreset { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the option should show a notification, toggled on by an overall option synchronization.
/// </summary>
public bool ShowNotification { get; set; }
/// <summary> /// <summary>
/// Gets or sets the <see cref="BepInEx.Configuration.ConfigDefinition"/> for the option, used for BepInEx configuration. /// Gets or sets the <see cref="BepInEx.Configuration.ConfigDefinition"/> for the option, used for BepInEx configuration.
/// </summary> /// </summary>
File renamed without changes.
+3 -4
View File
@@ -365,11 +365,11 @@ public static class ModdedOptionsManager
while (chunks.Count > 0) while (chunks.Count > 0)
{ {
Rpc<SyncOptionsRpc>.Instance.SendTo(PlayerControl.LocalPlayer, targetId, new MiraOptionNetData(false, chunks.Dequeue())); Rpc<SyncOptionsRpc>.Instance.SendTo(PlayerControl.LocalPlayer, targetId, chunks.Dequeue());
} }
} }
internal static void HandleSyncOptions(bool showNotifs, NetData[] data) internal static void HandleSyncOptions(NetData[] data)
{ {
// necessary to disable then re-enable this setting // necessary to disable then re-enable this setting
// we don't know how other plugins handle their configs // we don't know how other plugins handle their configs
@@ -388,7 +388,6 @@ public static class ModdedOptionsManager
continue; continue;
} }
option.ShowNotification = showNotifs;
option.HandleNetData(netData.Data); option.HandleNetData(netData.Data);
} }
@@ -398,7 +397,7 @@ public static class ModdedOptionsManager
plugin.PluginConfig.SaveOnConfigSet = oldConfigSetting[plugin]; plugin.PluginConfig.SaveOnConfigSet = oldConfigSetting[plugin];
} }
if (LobbyInfoPane.InstanceExists) if (LobbyInfoPane.Instance)
{ {
LobbyInfoPane.Instance.RefreshPane(); LobbyInfoPane.Instance.RefreshPane();
} }
@@ -93,17 +93,13 @@ public class ModdedEnumOption : ModdedOption<int>
/// <inheritdoc /> /// <inheritdoc />
protected override void OnValueChanged(int newValue) protected override void OnValueChanged(int newValue)
{ {
if (ShowNotification) ModdedOptionsManager.AddSettingsChangeMessage(
{ HudManager.Instance.Notifier,
ModdedOptionsManager.AddSettingsChangeMessage( StringName,
HudManager.Instance.Notifier, Data.GetValueString(newValue),
StringName, Configuration.PopUpTextColor,
Data.GetValueString(newValue), Configuration.PopUpIconTmp,
Configuration.PopUpTextColor, false);
Configuration.PopUpIconTmp,
false);
}
if (!OptionBehaviour) if (!OptionBehaviour)
{ {
return; return;
@@ -200,17 +196,13 @@ public class ModdedEnumOption<T> : ModdedOption<T>
/// <inheritdoc /> /// <inheritdoc />
protected override void OnValueChanged(T newValue) protected override void OnValueChanged(T newValue)
{ {
if (ShowNotification) ModdedOptionsManager.AddSettingsChangeMessage(
{ HudManager.Instance.Notifier,
ModdedOptionsManager.AddSettingsChangeMessage( StringName,
HudManager.Instance.Notifier, Data.GetValueString(Convert.ToInt32(newValue, NumberFormatInfo.InvariantInfo)),
StringName, Configuration.PopUpTextColor,
Data.GetValueString(Convert.ToInt32(newValue, NumberFormatInfo.InvariantInfo)), Configuration.PopUpIconTmp,
Configuration.PopUpTextColor, false);
Configuration.PopUpIconTmp,
false);
}
if (!OptionBehaviour) if (!OptionBehaviour)
{ {
return; return;
@@ -199,16 +199,13 @@ public class ModdedNumberOption : ModdedOption<float>
protected override void OnValueChanged(float newValue) protected override void OnValueChanged(float newValue)
{ {
Value = Mathf.Clamp(newValue, Min, Max); Value = Mathf.Clamp(newValue, Min, Max);
if (ShowNotification) ModdedOptionsManager.AddSettingsChangeMessage(
{ HudManager.Instance.Notifier,
ModdedOptionsManager.AddSettingsChangeMessage( StringName,
HudManager.Instance.Notifier, Data.GetValueString(newValue),
StringName, Configuration.PopUpTextColor,
Data.GetValueString(newValue), Configuration.PopUpIconTmp,
Configuration.PopUpTextColor, false);
Configuration.PopUpIconTmp,
false);
}
if (OptionBehaviour is NumberOption opt) if (OptionBehaviour is NumberOption opt)
{ {
@@ -79,9 +79,6 @@ public abstract class ModdedOption<T> : IModdedOption
/// <inheritdoc /> /// <inheritdoc />
public bool IncludeInPreset { get; set; } public bool IncludeInPreset { get; set; }
/// <inheritdoc />
public bool ShowNotification { get; set; } = true;
/// <inheritdoc /> /// <inheritdoc />
public OptionBehaviour? OptionBehaviour { get; protected set; } public OptionBehaviour? OptionBehaviour { get; protected set; }
@@ -159,11 +156,10 @@ public abstract class ModdedOption<T> : IModdedOption
entry.Value = _value; entry.Value = _value;
} }
Rpc<SyncOptionsRpc>.Instance.Send(PlayerControl.LocalPlayer, new MiraOptionNetData(true, [GetNetData()]), true); Rpc<SyncOptionsRpc>.Instance.Send(PlayerControl.LocalPlayer, [GetNetData()], true);
} }
OnValueChanged(_value); OnValueChanged(_value);
ShowNotification = true;
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -99,17 +99,13 @@ public class ModdedToggleOption : ModdedOption<bool>
/// <inheritdoc /> /// <inheritdoc />
protected override void OnValueChanged(bool newValue) protected override void OnValueChanged(bool newValue)
{ {
if (ShowNotification) ModdedOptionsManager.AddSettingsChangeMessage(
{ HudManager.Instance.Notifier,
ModdedOptionsManager.AddSettingsChangeMessage( StringName,
HudManager.Instance.Notifier, (newValue ? OnValue : OffValue).Translate(),
StringName, Configuration.PopUpTextColor,
(newValue ? OnValue : OffValue).Translate(), Configuration.PopUpIconTmp,
Configuration.PopUpTextColor, false);
Configuration.PopUpIconTmp,
false);
}
if (!OptionBehaviour) if (!OptionBehaviour)
{ {
return; return;
+1 -1
View File
@@ -102,7 +102,7 @@ public partial class MiraApiPlugin : BasePlugin, IMiraPlugin
PluginManager = new MiraPluginManager(); PluginManager = new MiraPluginManager();
PluginManager.Initialize(this, this); PluginManager.Initialize(this, this);
MiraLocaleManager.Register("mira.api", typeof(MiraApiPlugin).Assembly); MiraLocaleManager.Register("mira.api");
LocalizationManager.Register(new MiraLocalizationProvider()); LocalizationManager.Register(new MiraLocalizationProvider());
IL2CPPChainloader.Instance.Finished += IL2CPPChainloader.Instance.Finished +=
-43
View File
@@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using Il2CppInterop.Runtime.Attributes; using Il2CppInterop.Runtime.Attributes;
using MiraAPI.GameOptions; using MiraAPI.GameOptions;
using MiraAPI.PluginLoading; using MiraAPI.PluginLoading;
@@ -97,48 +96,6 @@ public abstract class BaseModifier : IOptionable
/// </summary> /// </summary>
public virtual string ModifierCategoryTitle => MiraLocaleManager.Get("Modifier"); public virtual string ModifierCategoryTitle => MiraLocaleManager.Get("Modifier");
/// <summary>
/// Gets a value indicating whether to exclude the "amount" from the displayed amount text within the role guide.
/// </summary>
public virtual bool ShowModifierAsUnique => false;
/// <summary>
/// Gets the displayed amount and chance of the modifier. Used in the role guide.
/// By default, 0 amount or chance results in a complete 0 amount and chance, so override if necessary.
/// </summary>
/// <param name="amount">The amount of the modifier.</param>
/// <param name="chance">The chance of the modifier.</param>
/// <param name="source">The mod source of the modifier.</param>
/// <returns>The <see cref="string"/> result.</returns>
public virtual string GetAmountText(int amount, int chance, string source)
{
if (amount == 0)
{
chance = 0;
}
if (ShowModifierAsUnique)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0}% ({1})",
chance.ToString(CultureInfo.InvariantCulture),
source);
}
if (chance == 0)
{
amount = 0;
}
return string.Format(
CultureInfo.InvariantCulture,
"{0} at {1}% ({2})",
amount.ToString(CultureInfo.InvariantCulture),
chance.ToString(CultureInfo.InvariantCulture),
source);
}
/// <summary> /// <summary>
/// Gets whether the modifier is forcibly shown or disabled in the wiki screen. /// Gets whether the modifier is forcibly shown or disabled in the wiki screen.
/// </summary> /// </summary>
+4 -4
View File
@@ -77,7 +77,7 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
} }
catch (Exception e) catch (Exception e)
{ {
Error($"Error while deactivating modifier {modifier.ModifierName}: {e}"); Error($"Error while deactivating modifier {modifier.ModifierName}: {e.ToString()}");
} }
Modifiers.Remove(modifier); Modifiers.Remove(modifier);
@@ -95,7 +95,7 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
} }
catch (Exception e) catch (Exception e)
{ {
Error($"Error while activating modifier {modifier.ModifierName}: {e}"); Error($"Error while activating modifier {modifier.ModifierName}: {e.ToString()}");
} }
if (modifier is TimedModifier { AutoStart: true } timer) if (modifier is TimedModifier { AutoStart: true } timer)
@@ -122,7 +122,7 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
} }
catch (Exception e) catch (Exception e)
{ {
Error($"Error while (fixed) updating modifier {modifier.ModifierName}: {e}"); Error($"Error while (fixed) updating modifier {modifier.ModifierName}: {e.ToString()}");
} }
} }
@@ -153,7 +153,7 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
} }
catch (Exception e) catch (Exception e)
{ {
Error($"Error while updating modifier {modifier.ModifierName}: {e}"); Error($"Error while updating modifier {modifier.ModifierName}: {e.ToString()}");
} }
} }
} }
+2 -2
View File
@@ -571,7 +571,7 @@ public static class CustomMurderRpc
} }
catch (Exception e) catch (Exception e)
{ {
Error($"Error with kill animation: {e}"); Error($"Error with kill animation: {e.ToString()}");
} }
} }
@@ -705,7 +705,7 @@ public static class CustomMurderRpc
} }
catch (Exception e) catch (Exception e)
{ {
Error($"Error with kill animation: {e}"); Error($"Error with kill animation: {e.ToString()}");
} }
} }
+10 -13
View File
@@ -9,32 +9,29 @@ namespace MiraAPI.Networking;
[RegisterCustomRpc((uint)MiraRpc.SyncGameOptions)] [RegisterCustomRpc((uint)MiraRpc.SyncGameOptions)]
#pragma warning disable SA1515 // Single-line comment should be preceded by blank line (Justification: ReSharper suppression.) #pragma warning disable SA1515 // Single-line comment should be preceded by blank line (Justification: ReSharper suppression.)
// ReSharper disable once ClassNeverInstantiated.Global (Justification: Instantiated by Reactor.) // ReSharper disable once ClassNeverInstantiated.Global (Justification: Instantiated by Reactor.)
internal sealed class SyncOptionsRpc(MiraApiPlugin plugin, uint id) : PlayerCustomRpc<MiraApiPlugin, MiraOptionNetData>(plugin, id) internal sealed class SyncOptionsRpc(MiraApiPlugin plugin, uint id) : PlayerCustomRpc<MiraApiPlugin, NetData[]>(plugin, id)
#pragma warning restore SA1515 // Single-line comment should be preceded by blank line #pragma warning restore SA1515 // Single-line comment should be preceded by blank line
{ {
public override RpcLocalHandling LocalHandling => RpcLocalHandling.None; public override RpcLocalHandling LocalHandling => RpcLocalHandling.None;
public override void Write(MessageWriter writer, MiraOptionNetData data) public override void Write(MessageWriter writer, NetData[]? data)
{ {
/*if (data == null) if (data == null)
{ {
writer.WritePacked(0U); writer.WritePacked(0U);
return; return;
}*/ }
var info = data.Data; writer.WritePacked((uint)data.Length);
writer.Write(data.ShouldShowNotifications); foreach (var netData in data)
writer.WritePacked((uint)info.Length);
foreach (var netData in info)
{ {
writer.WritePacked(netData.Id); writer.WritePacked(netData.Id);
writer.WriteBytesAndSize(netData.Data); writer.WriteBytesAndSize(netData.Data);
} }
} }
public override MiraOptionNetData Read(MessageReader reader) public override NetData[] Read(MessageReader reader)
{ {
var shouldShowNotif = reader.ReadBoolean();
var length = reader.ReadPackedUInt32(); var length = reader.ReadPackedUInt32();
var data = new NetData[length]; var data = new NetData[length];
for (var i = 0; i < length; i++) for (var i = 0; i < length; i++)
@@ -44,16 +41,16 @@ internal sealed class SyncOptionsRpc(MiraApiPlugin plugin, uint id) : PlayerCust
data[i] = new NetData(dataId, bytes); data[i] = new NetData(dataId, bytes);
} }
return new MiraOptionNetData(shouldShowNotif, data); return data;
} }
public override void Handle(PlayerControl playerControl, MiraOptionNetData data) public override void Handle(PlayerControl playerControl, NetData[]? data)
{ {
if (AmongUsClient.Instance.HostId != playerControl.OwnerId) if (AmongUsClient.Instance.HostId != playerControl.OwnerId)
{ {
return; return;
} }
ModdedOptionsManager.HandleSyncOptions(data.ShouldShowNotifications, data.Data ?? []); ModdedOptionsManager.HandleSyncOptions(data ?? []);
} }
} }
+10 -19
View File
@@ -5,41 +5,32 @@ using Reactor.Networking.Rpc;
namespace MiraAPI.Networking; namespace MiraAPI.Networking;
internal readonly struct MiraOptionNetData(bool showNotif, NetData[] data)
{
public bool ShouldShowNotifications { get; } = showNotif;
public NetData[] Data { get; } = data;
}
[RegisterCustomRpc((uint)MiraRpc.SyncRoleOptions)] [RegisterCustomRpc((uint)MiraRpc.SyncRoleOptions)]
#pragma warning disable SA1515 // Single-line comment should be preceded by blank line (Justification: ReSharper suppression.) #pragma warning disable SA1515 // Single-line comment should be preceded by blank line (Justification: ReSharper suppression.)
// ReSharper disable once ClassNeverInstantiated.Global (Justification: Instantiated by Reactor.) // ReSharper disable once ClassNeverInstantiated.Global (Justification: Instantiated by Reactor.)
internal sealed class SyncRoleOptionsRpc(MiraApiPlugin plugin, uint id) : PlayerCustomRpc<MiraApiPlugin, MiraOptionNetData>(plugin, id) internal sealed class SyncRoleOptionsRpc(MiraApiPlugin plugin, uint id) : PlayerCustomRpc<MiraApiPlugin, NetData[]>(plugin, id)
#pragma warning restore SA1515 // Single-line comment should be preceded by blank line #pragma warning restore SA1515 // Single-line comment should be preceded by blank line
{ {
public override RpcLocalHandling LocalHandling => RpcLocalHandling.None; public override RpcLocalHandling LocalHandling => RpcLocalHandling.None;
public override void Write(MessageWriter writer, MiraOptionNetData data) public override void Write(MessageWriter writer, NetData[]? data)
{ {
/*if (data == null) if (data == null)
{ {
writer.WritePacked(0U); writer.WritePacked(0U);
return; return;
}*/ }
var info = data.Data; writer.WritePacked((uint)data.Length);
writer.Write(data.ShouldShowNotifications); foreach (var netData in data)
writer.WritePacked((uint)info.Length);
foreach (var netData in info)
{ {
writer.WritePacked(netData.Id); writer.WritePacked(netData.Id);
writer.WriteBytesAndSize(netData.Data); writer.WriteBytesAndSize(netData.Data);
} }
} }
public override MiraOptionNetData Read(MessageReader reader) public override NetData[] Read(MessageReader reader)
{ {
var shouldShowNotif = reader.ReadBoolean();
var length = reader.ReadPackedUInt32(); var length = reader.ReadPackedUInt32();
var data = new NetData[length]; var data = new NetData[length];
for (var i = 0; i < length; i++) for (var i = 0; i < length; i++)
@@ -49,16 +40,16 @@ internal sealed class SyncRoleOptionsRpc(MiraApiPlugin plugin, uint id) : Player
data[i] = new NetData(dataId, bytes); data[i] = new NetData(dataId, bytes);
} }
return new MiraOptionNetData(shouldShowNotif, data); return data;
} }
public override void Handle(PlayerControl playerControl, MiraOptionNetData data) public override void Handle(PlayerControl playerControl, NetData[]? data)
{ {
if (AmongUsClient.Instance.HostId != playerControl.OwnerId) if (AmongUsClient.Instance.HostId != playerControl.OwnerId)
{ {
return; return;
} }
CustomRoleManager.HandleSyncRoleOptions(data.ShouldShowNotifications, data.Data ?? []); CustomRoleManager.HandleSyncRoleOptions(data ?? []);
} }
} }
+1 -2
View File
@@ -3,7 +3,6 @@ using System.Reflection;
using HarmonyLib; using HarmonyLib;
using MiraAPI.Events; using MiraAPI.Events;
using MiraAPI.Events.Vanilla.Usables; using MiraAPI.Events.Vanilla.Usables;
using UnityEngine;
namespace MiraAPI.Patches.Events; namespace MiraAPI.Patches.Events;
@@ -28,7 +27,7 @@ public static class CanUsePatches
[HarmonyPriority(Priority.Last)] [HarmonyPriority(Priority.Last)]
[HarmonyPrefix] [HarmonyPrefix]
public static bool CanUsePatch(MonoBehaviour __instance, [HarmonyArgument(1)] out bool canUse, [HarmonyArgument(2)] out bool couldUse) public static bool CanUsePatch(Il2CppSystem.Object __instance, [HarmonyArgument(1)] out bool canUse, [HarmonyArgument(2)] out bool couldUse)
{ {
canUse = couldUse = false; canUse = couldUse = false;
+1 -2
View File
@@ -3,7 +3,6 @@ using System.Reflection;
using HarmonyLib; using HarmonyLib;
using MiraAPI.Events; using MiraAPI.Events;
using MiraAPI.Events.Vanilla.Usables; using MiraAPI.Events.Vanilla.Usables;
using UnityEngine;
namespace MiraAPI.Patches.Events; namespace MiraAPI.Patches.Events;
@@ -26,7 +25,7 @@ public static class UsePatches
[HarmonyPriority(Priority.Last)] [HarmonyPriority(Priority.Last)]
[HarmonyPrefix] [HarmonyPrefix]
public static bool UsePatch(MonoBehaviour __instance) public static bool UsePatch(Il2CppSystem.Object __instance)
{ {
var @event = new PlayerUseEvent(__instance.Cast<IUsable>()); var @event = new PlayerUseEvent(__instance.Cast<IUsable>());
MiraEventManager.InvokeEvent(@event); MiraEventManager.InvokeEvent(@event);
+2 -4
View File
@@ -186,11 +186,9 @@ public static class TaskAdderPatches
systemTypes = SystemTypes.UpperEngine; systemTypes = SystemTypes.UpperEngine;
} }
var systemType = systemTypes.ToString(); if (!folders.TryGetValue(systemTypes.ToString(), out var taskFolder3))
if (!folders.TryGetValue(systemType, out var taskFolder3))
{ {
taskFolder3 = folders[systemType] = Object.Instantiate(__instance.RootFolderPrefab, __instance.transform); taskFolder3 = folders[systemTypes.ToString()] = Object.Instantiate(__instance.RootFolderPrefab, __instance.transform);
taskFolder3.SetFolderColor(TaskFolder.FolderColor.Tan); taskFolder3.SetFolderColor(TaskFolder.FolderColor.Tan);
taskFolder3.gameObject.SetActive(false); taskFolder3.gameObject.SetActive(false);
taskFolder3.FolderName = systemTypes == SystemTypes.UpperEngine taskFolder3.FolderName = systemTypes == SystemTypes.UpperEngine
@@ -1,7 +1,5 @@
using HarmonyLib; using HarmonyLib;
using MiraAPI.GameModes; using MiraAPI.GameModes;
using MiraAPI.GameOptions;
using MiraAPI.Roles;
namespace MiraAPI.Patches.GameModes; namespace MiraAPI.Patches.GameModes;
@@ -57,17 +55,4 @@ internal static class GameStartManagerPatches
__instance.MinPlayers = 1; __instance.MinPlayers = 1;
} }
} }
[HarmonyPrefix, HarmonyPatch(nameof(GameStartManager.BeginGame))]
public static void Prefix(GameStartManager __instance)
{
if (!AmongUsClient.Instance.AmHost)
{
return;
}
ModdedOptionsManager.SyncAllOptions();
CustomRoleManager.SyncAllRoleSettings();
GameModeOption.RpcSyncGamemode(PlayerControl.LocalPlayer, GameModeOption.Value);
}
} }
+1 -1
View File
@@ -29,7 +29,7 @@ public static class HudManagerPatches
public static IEnumerator CoResizeUI() public static IEnumerator CoResizeUI()
{ {
while (!HudManager.InstanceExists) yield return null; while (!HudManager.Instance) yield return null;
yield return new WaitForSeconds(0.01f); yield return new WaitForSeconds(0.01f);
ResizeUI(LocalSettingsTabSingleton<MiraApiSettings>.Instance.ButtonUIFactorSlider.Value); ResizeUI(LocalSettingsTabSingleton<MiraApiSettings>.Instance.ButtonUIFactorSlider.Value);
@@ -495,7 +495,7 @@ public static class RoleSettingMenuPatches
if (AmongUsClient.Instance.AmHost) if (AmongUsClient.Instance.AmHost)
{ {
Rpc<SyncRoleOptionsRpc>.Instance.Send(PlayerControl.LocalPlayer, new MiraOptionNetData(true, [role.GetNetData()]), true); Rpc<SyncRoleOptionsRpc>.Instance.Send(PlayerControl.LocalPlayer, [role.GetNetData()], true);
} }
GameOptionsManager.Instance.GameHostOptions = GameOptionsManager.Instance.CurrentGameOptions; GameOptionsManager.Instance.GameHostOptions = GameOptionsManager.Instance.CurrentGameOptions;
+21 -100
View File
@@ -754,8 +754,7 @@ public static class RoleGuidePatches
modifier.ModifierCategoryTitle, modifier.ModifierCategoryTitle,
modifier.ParentMod.MiraPlugin.GetAbbreviatedModName(), modifier.ParentMod.MiraPlugin.GetAbbreviatedModName(),
null, null,
modifier, modifier));
modifier.TypeId));
} }
} }
@@ -791,8 +790,7 @@ public static class RoleGuidePatches
roleBehaviour.GetCategoryTitle(), roleBehaviour.GetCategoryTitle(),
modId, modId,
roleBehaviour, roleBehaviour,
null, null));
(uint)roleBehaviour.Role));
} }
_roleEntriesMode = activeModeType; _roleEntriesMode = activeModeType;
@@ -930,7 +928,7 @@ public static class RoleGuidePatches
} }
} }
private sealed class DetailedPanel(string title, string category, string modId, RoleBehaviour? role, GameModifier? modifier, uint typeId) private sealed class DetailedPanel(string title, string category, string modId, RoleBehaviour? role, GameModifier? modifier)
{ {
public MatchInfoRolePanel? Panel { get; set; } public MatchInfoRolePanel? Panel { get; set; }
public string Title { get; } = title; public string Title { get; } = title;
@@ -938,7 +936,6 @@ public static class RoleGuidePatches
public string ModId { get; } = modId; public string ModId { get; } = modId;
public RoleBehaviour? Role { get; } = role; public RoleBehaviour? Role { get; } = role;
public GameModifier? Modifier { get; } = modifier; public GameModifier? Modifier { get; } = modifier;
public uint TypeId { get; } = typeId;
public int Amount { get; set; } public int Amount { get; set; }
public int Chance { get; set; } public int Chance { get; set; }
public float Likelihood { get; set; } public float Likelihood { get; set; }
@@ -1160,9 +1157,7 @@ public static class RoleGuidePatches
entry.Visible = entry.CanShow && MatchesSearch(entry, searchText); entry.Visible = entry.CanShow && MatchesSearch(entry, searchText);
if (entry.Panel) if (entry.Panel)
{ {
dynamic entryType = entry.Modifier != null ? entry.Modifier : entry.Role!; SetPanelCount(entry.Panel!, entry.Amount, entry.Chance, entry.ModId);
var text = GetPanelCountText(entryType, entry.Amount, entry.Chance, entry.ModId);
SetPanelCount(entry.Panel!, text);
if (!entry.Visible && entry.Panel!.gameObject.activeSelf) if (!entry.Visible && entry.Panel!.gameObject.activeSelf)
{ {
entry.Panel.gameObject.SetActive(false); entry.Panel.gameObject.SetActive(false);
@@ -1187,58 +1182,16 @@ public static class RoleGuidePatches
return shown; return shown;
} }
public static IEnumerable<GameModifier> GetActiveModifiers()
{
return PlayerControl.LocalPlayer.GetModifiers<GameModifier>();
}
public static IEnumerable<RoleBehaviour> GetActiveRoles()
{
IEnumerable<RoleBehaviour> comparisons = [];
var curRole = PlayerControl.LocalPlayer.Data.Role;
comparisons = comparisons.AddItem(curRole);
if (PlayerControl.LocalPlayer && PlayerControl.LocalPlayer.Data && PlayerControl.LocalPlayer.Data.IsDead &&
!comparisons.Any(x => x.Role == PlayerControl.LocalPlayer.Data.RoleWhenAlive.Value))
{
comparisons = comparisons.AddItem(RoleManager.Instance.GetRole(PlayerControl.LocalPlayer.Data.RoleWhenAlive.Value));
}
return comparisons;
}
public static List<uint> GetActiveIds()
{
var activeModifiers = GetActiveModifiers();
List<uint> comparisons = activeModifiers.Select(x => x.TypeId).ToList();
comparisons.AddRange(GetActiveRoles().Select(x => (uint)x.Role));
return comparisons;
}
private static List<DetailedPanel> SortEntries(List<DetailedPanel> entries, string searchText) private static List<DetailedPanel> SortEntries(List<DetailedPanel> entries, string searchText)
{ {
var activeModifiers = PlayerControl.LocalPlayer.GetModifiers<GameModifier>().Select(x => x.TypeId);
var roles = GetActiveRoles().Select(x => (uint)x.Role).ToList();
List<uint> comparisons = activeModifiers.ToList();
comparisons.AddRange(roles);
var comparer = new BasicGuideComparer(comparisons);
var sorted = entries.Where(p => p.Visible) var sorted = entries.Where(p => p.Visible)
.OrderByDescending(p => p.Title.Equals(searchText, StringComparison.OrdinalIgnoreCase)) .OrderByDescending(p => p.Title.Equals(searchText, StringComparison.OrdinalIgnoreCase))
.ThenByDescending(p => .ThenByDescending(p =>
p.Title.Contains(searchText, StringComparison.OrdinalIgnoreCase) || p.Title.Contains(searchText, StringComparison.OrdinalIgnoreCase) ||
p.Category.Contains(searchText, StringComparison.OrdinalIgnoreCase)) p.Category.Contains(searchText, StringComparison.OrdinalIgnoreCase));
.ThenBy(x => x.Modifier != null ? x.Modifier.TypeId : (uint)x.Role!.Role, comparer); return [.. _sortMethod is SortingMethod.Alphabetical
return
[
.. _sortMethod is SortingMethod.Alphabetical
? sorted.ThenBy(p => p.GetSortKey(_sortGrouping)) ? sorted.ThenBy(p => p.GetSortKey(_sortGrouping))
: sorted.ThenByDescending(p => p.GetSortKey(_sortGrouping)) : sorted.ThenByDescending(p => p.GetSortKey(_sortGrouping))];
];
} }
private static bool MatchesSearch(DetailedPanel entry, string searchText) private static bool MatchesSearch(DetailedPanel entry, string searchText)
@@ -1698,15 +1651,10 @@ public static class RoleGuidePatches
public static Sprite GetRandomRoleIcon() public static Sprite GetRandomRoleIcon()
{ {
var roles = GetActiveRoles().Shuffle().ToList(); var aliveRole = PlayerControl.LocalPlayer.Data?.Role;
foreach (var role in roles) if (aliveRole != null && aliveRole.RoleIconSolid != null)
{ {
if (role.RoleIconSolid == null) return aliveRole.RoleIconSolid;
{
continue;
}
return role.RoleIconSolid;
} }
return GetRandomFactionIcon(); return GetRandomFactionIcon();
@@ -1845,22 +1793,21 @@ public static class RoleGuidePatches
return false; return false;
} }
__instance.roleCount.text = string.Format(
CultureInfo.InvariantCulture,
"{0} at {1}%",
numPerGame.ToString(CultureInfo.InvariantCulture),
chancePerGame);
if (role is ICustomRole customRole) if (role is ICustomRole customRole)
{ {
__instance.roleName.text = customRole.RoleName; __instance.roleName.text = customRole.RoleName;
__instance.roleDescription.text = __instance.roleDescription.text =
$"<size=60%>{role.GetCategoryTitle()}</size>\n" + customRole.RoleMedDescription; $"<size=60%>{role.GetCategoryTitle()}</size>\n" + customRole.RoleMedDescription;
__instance.roleIcon.sprite = customRole.Configuration.Icon?.LoadAsset(); __instance.roleIcon.sprite = customRole.Configuration.Icon?.LoadAsset();
var text = GetCustomRolePanelCountText(customRole, numPerGame, chancePerGame, customRole.ParentMod.MiraPlugin.GetAbbreviatedModName()); __instance.roleCount.text += $" ({customRole.ParentMod.MiraPlugin.GetAbbreviatedModName()})";
SetPanelCount(__instance, text);
} }
else else
{ {
__instance.roleCount.text = string.Format(
CultureInfo.InvariantCulture,
"{0} at {1}%",
numPerGame.ToString(CultureInfo.InvariantCulture),
chancePerGame);
__instance.roleName.text = role.NiceName; __instance.roleName.text = role.NiceName;
__instance.roleDescription.text = $"<size=60%>{role.GetCategoryTitle()}</size>\n" + role.BlurbMed; __instance.roleDescription.text = $"<size=60%>{role.GetCategoryTitle()}</size>\n" + role.BlurbMed;
__instance.roleIcon.sprite = role.RoleIconColor; __instance.roleIcon.sprite = role.RoleIconColor;
@@ -1876,20 +1823,9 @@ public static class RoleGuidePatches
return false; return false;
} }
// NOTE: This is specifically meant to be a different method name as to not have the game check this method and the GetPanelCountText method made for roles overall. private static void SetPanelCount(MatchInfoRolePanel panel, int amount, int chance, string modId)
private static string GetCustomRolePanelCountText(ICustomRole custom, int amount, int chance, string modId)
{ {
return custom.GetAmountText(amount, chance, modId); panel.roleCount.text = string.Format(
}
private static string GetPanelCountText(RoleBehaviour role, int amount, int chance, string modId)
{
if (role is ICustomRole custom)
{
return custom.GetAmountText(amount, chance, modId);
}
return string.Format(
CultureInfo.InvariantCulture, CultureInfo.InvariantCulture,
"{0} at {1}% ({2})", "{0} at {1}% ({2})",
amount.ToString(CultureInfo.InvariantCulture), amount.ToString(CultureInfo.InvariantCulture),
@@ -1897,18 +1833,6 @@ public static class RoleGuidePatches
modId); modId);
} }
private static string GetPanelCountText(BaseModifier modifier, int amount, int chance, string modId)
{
return modifier.GetAmountText(amount, chance, modId);
}
private static void SetPanelCount(MatchInfoRolePanel panel, string amountChanceText)
{
panel.roleCount.text = string.Format(
CultureInfo.InvariantCulture,
amountChanceText);
}
public static void SetRolePanel( public static void SetRolePanel(
this MatchInfoRolePanel instance, this MatchInfoRolePanel instance,
RoleBehaviour role, RoleBehaviour role,
@@ -1921,16 +1845,14 @@ public static class RoleGuidePatches
instance.roleDescription.text = instance.roleDescription.text =
$"<size=60%>{role.GetCategoryTitle()}</size>\n" + customRole.RoleMedDescription; $"<size=60%>{role.GetCategoryTitle()}</size>\n" + customRole.RoleMedDescription;
instance.roleIcon.sprite = customRole.Configuration.Icon?.LoadAsset(); instance.roleIcon.sprite = customRole.Configuration.Icon?.LoadAsset();
var text = GetCustomRolePanelCountText(customRole, numPerGame, chancePerGame, customRole.ParentMod.MiraPlugin.GetAbbreviatedModName()); SetPanelCount(instance, numPerGame, chancePerGame, customRole.ParentMod.MiraPlugin.GetAbbreviatedModName());
SetPanelCount(instance, text);
} }
else else
{ {
instance.roleName.text = role.NiceName; instance.roleName.text = role.NiceName;
instance.roleDescription.text = $"<size=60%>{role.GetCategoryTitle()}</size>\n" + role.BlurbMed; instance.roleDescription.text = $"<size=60%>{role.GetCategoryTitle()}</size>\n" + role.BlurbMed;
instance.roleIcon.sprite = role.RoleIconColor; instance.roleIcon.sprite = role.RoleIconColor;
var text = GetPanelCountText(role, numPerGame, chancePerGame, "AU"); SetPanelCount(instance, numPerGame, chancePerGame, "AU");
SetPanelCount(instance, text);
} }
instance.roleIcon.SetSizeLimit(0.13f); instance.roleIcon.SetSizeLimit(0.13f);
@@ -1951,8 +1873,7 @@ public static class RoleGuidePatches
instance.roleDescription.text = instance.roleDescription.text =
$"<size=60%>{modifier.ModifierCategoryTitle}</size>\n" + modifier.ModifierMedDescription; $"<size=60%>{modifier.ModifierCategoryTitle}</size>\n" + modifier.ModifierMedDescription;
instance.roleIcon.sprite = modifier.ModifierIcon?.LoadAsset(); instance.roleIcon.sprite = modifier.ModifierIcon?.LoadAsset();
var text = GetPanelCountText(modifier, numPerGame, chancePerGame, modifier.ParentMod.MiraPlugin.GetAbbreviatedModName()); SetPanelCount(instance, numPerGame, chancePerGame, modifier.ParentMod.MiraPlugin.GetAbbreviatedModName());
SetPanelCount(instance, text);
instance.roleIcon.SetSizeLimit(0.13f); instance.roleIcon.SetSizeLimit(0.13f);
instance.roleIcon.material.SetInt(PlayerMaterial.MaskLayer, 50); instance.roleIcon.material.SetInt(PlayerMaterial.MaskLayer, 50);
+40 -34
View File
@@ -25,26 +25,6 @@ public class MiraPluginInfo
PluginId = info.Metadata.GUID; PluginId = info.Metadata.GUID;
} }
/// <summary>
/// Gets the plugin's ID, as defined in the plugin's BepInEx metadata.
/// </summary>
public string PluginId { get; }
/// <summary>
/// Gets the plugin's instance as an <see cref="IMiraPlugin"/>.
/// </summary>
public IMiraPlugin MiraPlugin { get; }
/// <summary>
/// Gets the plugin's BepInEx metadata.
/// </summary>
public PluginInfo PluginInfo { get; }
/// <summary>
/// Gets the plugin's <see cref="ConfigFile"/>.
/// </summary>
public ConfigFile PluginConfig { get; }
/// <summary> /// <summary>
/// Gets a <see cref="IReadOnlyCollection{T}"/> of this <see cref="IMiraPlugin"/>'s <see cref="BaseModifier"/>s. This is not safe for <see cref="BaseModifier"/>s with constructors. /// Gets a <see cref="IReadOnlyCollection{T}"/> of this <see cref="IMiraPlugin"/>'s <see cref="BaseModifier"/>s. This is not safe for <see cref="BaseModifier"/>s with constructors.
/// </summary> /// </summary>
@@ -65,6 +45,15 @@ public class MiraPluginInfo
/// </summary> /// </summary>
public ReadOnlyDictionary<ushort, RoleBehaviour> Roles { get; private set; } = null!; public ReadOnlyDictionary<ushort, RoleBehaviour> Roles { get; private set; } = null!;
/// <summary>
/// Gets a read only dictionary of Game Mode IDs and the AbstractGameMode object they are associated with.
/// </summary>
/// <returns>Read only dictionary of IDs and Game Modes.</returns>
public ReadOnlyDictionary<uint, AbstractGameMode> GetModes()
{
return new ReadOnlyDictionary<uint, AbstractGameMode>(GameModes);
}
/// <summary> /// <summary>
/// Gets a <see cref="IReadOnlyCollection{T}"/> of this <see cref="IMiraPlugin"/>'s <see cref="CustomActionButton"/>. /// Gets a <see cref="IReadOnlyCollection{T}"/> of this <see cref="IMiraPlugin"/>'s <see cref="CustomActionButton"/>.
/// </summary> /// </summary>
@@ -85,15 +74,6 @@ public class MiraPluginInfo
/// </summary> /// </summary>
public IReadOnlyCollection<OptionPreset> Presets { get; internal set; } = null!; public IReadOnlyCollection<OptionPreset> Presets { get; internal set; } = null!;
/// <summary>
/// Gets a read only dictionary of Game Mode IDs and the AbstractGameMode object they are associated with.
/// </summary>
/// <returns>Read only dictionary of IDs and Game Modes.</returns>
public ReadOnlyDictionary<uint, AbstractGameMode> GetModes()
{
return new ReadOnlyDictionary<uint, AbstractGameMode>(GameModes);
}
internal void SavePublicCollections() internal void SavePublicCollections()
{ {
Presets = [.. InternalPresets]; Presets = [.. InternalPresets];
@@ -107,13 +87,39 @@ public class MiraPluginInfo
} }
internal List<OptionPreset> InternalPresets { get; } = []; internal List<OptionPreset> InternalPresets { get; } = [];
internal List<IModdedOption> InternalOptions { get; } = [];
internal List<BaseModifier> InternalModifiers { get; } = [];
internal List<CustomActionButton> InternalButtons { get; } = [];
internal List<AbstractOptionGroup> InternalOptionGroups { get; } = []; internal List<AbstractOptionGroup> InternalOptionGroups { get; } = [];
internal List<MeetingActionButton> InternalMeetingButtons { get; } = [];
internal List<TargetedMeetingButton> InternalTargetedMeetingButtons { get; } = []; internal List<IModdedOption> InternalOptions { get; } = [];
internal List<BaseModifier> InternalModifiers { get; } = [];
internal Dictionary<uint, AbstractGameMode> GameModes { get; } = []; internal Dictionary<uint, AbstractGameMode> GameModes { get; } = [];
internal Dictionary<ushort, RoleBehaviour> InternalRoles { get; } = []; internal Dictionary<ushort, RoleBehaviour> InternalRoles { get; } = [];
internal List<CustomActionButton> InternalButtons { get; } = [];
internal List<TargetedMeetingButton> InternalTargetedMeetingButtons { get; } = [];
internal List<MeetingActionButton> InternalMeetingButtons { get; } = [];
/// <summary>
/// Gets the plugin's ID, as defined in the plugin's BepInEx metadata.
/// </summary>
public string PluginId { get; }
/// <summary>
/// Gets the plugin's instance as an <see cref="IMiraPlugin"/>.
/// </summary>
public IMiraPlugin MiraPlugin { get; }
/// <summary>
/// Gets the plugin's BepInEx metadata.
/// </summary>
public PluginInfo PluginInfo { get; }
/// <summary>
/// Gets the plugin's <see cref="ConfigFile"/>.
/// </summary>
public ConfigFile PluginConfig { get; }
} }
+193 -103
View File
@@ -4,7 +4,6 @@ using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using BepInEx;
using BepInEx.Configuration; using BepInEx.Configuration;
using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP;
using HarmonyLib; using HarmonyLib;
@@ -25,6 +24,7 @@ using MiraAPI.Roles;
using MiraAPI.Translation; using MiraAPI.Translation;
using MiraAPI.Utilities; using MiraAPI.Utilities;
using Reactor.Networking; using Reactor.Networking;
using Reactor.Utilities;
namespace MiraAPI.PluginLoading; namespace MiraAPI.PluginLoading;
@@ -49,14 +49,100 @@ public sealed class MiraPluginManager
Instance = this; Instance = this;
CustomGameModeManager.RegisterDefaultMode(); CustomGameModeManager.RegisterDefaultMode();
CustomGameModeManager.GetAndSetGameMode(); CustomGameModeManager.GetAndSetGameMode();
if (IL2CPPChainloader.Instance.Plugins.TryGetValue(MiraApiPlugin.Id, out var newPlugin)) if (IL2CPPChainloader.Instance.Plugins.TryGetValue(MiraApiPlugin.Id, out var newPlugin))
{ {
var info = RegisterPlugin(typeof(MiraPluginManager).Assembly, apiPlugin, newPlugin, miraApiPlugin, true); var assembly = Assembly.GetCallingAssembly();
var info = new MiraPluginInfo(apiPlugin, newPlugin);
var roles = new List<Type>();
var oldConfigSetting = info.PluginConfig.SaveOnConfigSet;
info.PluginConfig.SaveOnConfigSet = false;
foreach (var type in assembly.GetTypes())
{
if (type.IsAbstract || type.GetCustomAttribute<MiraIgnoreAttribute>() != null)
{
continue;
}
foreach (var method in AccessTools.GetDeclaredMethods(type))
{
var eventAttribute = method.GetCustomAttribute<RegisterEventAttribute>();
if (eventAttribute == null)
{
continue;
}
if (!method.IsStatic)
{
Error($"Event method {method.Name} in {type.Name} must be static.");
continue;
}
var parameters = method.GetParameters();
if (parameters.Length != 1 || !parameters[0].ParameterType.IsSubclassOf(typeof(MiraEvent)))
{
Error($"Invalid event registration method {method.Name} in {type.Name}");
continue;
}
var paramType = parameters[0].ParameterType;
MiraEventManager.RegisterEventHandler(paramType, method, eventAttribute.Priority);
}
if (RegisterModifier(type, info))
{
continue;
}
if (RegisterOptions(type, info))
{
continue;
}
if (RegisterLocalTabs(type, miraApiPlugin))
{
continue;
}
if (RegisterRole(type, info, out var role))
{
roles.Add(role);
continue;
}
if (RegisterButton(type, info))
{
continue;
}
if (RegisterGameOver(type))
{
continue;
}
if (RegisterGameModeAttribute(type, info))
{
continue;
}
RegisterColorClasses(type);
RegisterKeybinds(type, miraApiPlugin);
}
info.PluginConfig.Save();
info.PluginConfig.SaveOnConfigSet = oldConfigSetting;
MiraApiConfig = info.PluginConfig; MiraApiConfig = info.PluginConfig;
info.InternalOptionGroups.Sort((x, y) => x.GroupPriority.CompareTo(y.GroupPriority));
QueuedRoleRegistrations.Add(info, roles);
_registeredPlugins.Add(assembly, info);
MiraApiPluginInfo = info; MiraApiPluginInfo = info;
info.SavePublicCollections();
PresetManager.CreateDefaultPreset(info);
PresetManager.LoadPresets(info);
Info($"Registering Mira API as mod."); Info($"Registering Mira API as mod.");
} }
@@ -67,14 +153,110 @@ public sealed class MiraPluginManager
return; return;
} }
RegisterPlugin(assembly, miraPlugin, pluginInfo, plugin, false); var info = new MiraPluginInfo(miraPlugin, pluginInfo);
var roles = new List<Type>();
var oldConfigSetting = info.PluginConfig.SaveOnConfigSet;
info.PluginConfig.SaveOnConfigSet = false;
foreach (var type in assembly.GetTypes())
{
if (type.GetCustomAttribute<MiraIgnoreAttribute>() != null)
{
continue;
}
foreach (var method in AccessTools.GetDeclaredMethods(type))
{
var eventAttribute = method.GetCustomAttribute<RegisterEventAttribute>();
if (eventAttribute == null)
{
continue;
}
if (!method.IsStatic)
{
Error($"Event method {method.Name} in {type.Name} must be static.");
continue;
}
var parameters = method.GetParameters();
if (parameters.Length != 1 || !parameters[0].ParameterType.IsSubclassOf(typeof(MiraEvent)))
{
Error($"Invalid event registration method {method.Name} in {type.Name}");
continue;
}
var paramType = parameters[0].ParameterType;
MiraEventManager.RegisterEventHandler(paramType, method, eventAttribute.Priority);
}
if (RegisterModifier(type, info))
{
continue;
}
if (RegisterOptions(type, info))
{
continue;
}
if (RegisterLocalTabs(type, plugin))
{
continue;
}
if (RegisterRole(type, info, out var role))
{
roles.Add(role);
continue;
}
if (RegisterButton(type, info))
{
continue;
}
if (RegisterGameOver(type))
{
continue;
}
if (RegisterMeetingAbility(type, info))
{
continue;
}
if (RegisterTargetedMeetingAbility(type, info))
{
continue;
}
if (RegisterGameModeAttribute(type, info))
{
continue;
}
RegisterColorClasses(type);
RegisterKeybinds(type, plugin);
}
info.PluginConfig.Save();
info.PluginConfig.SaveOnConfigSet = oldConfigSetting;
info.InternalOptionGroups.Sort((x, y) => x.GroupPriority.CompareTo(y.GroupPriority));
QueuedRoleRegistrations.Add(info, roles);
_registeredPlugins.Add(assembly, info);
info.SavePublicCollections();
PresetManager.CreateDefaultPreset(info);
PresetManager.LoadPresets(info);
Info($"Registering mod {pluginInfo.Metadata.GUID} with Mira API."); Info($"Registering mod {pluginInfo.Metadata.GUID} with Mira API.");
}; };
IL2CPPChainloader.Instance.Finished += PaletteManager.RegisterAllColors;
IL2CPPChainloader.Instance.Finished += () => IL2CPPChainloader.Instance.Finished += () =>
{ {
PaletteManager.RegisterAllColors();
// Save all buttons into a read-only collection for easy access // Save all buttons into a read-only collection for easy access
CustomButtonManager.Buttons = new ReadOnlyCollection<CustomActionButton>(CustomButtonManager.CustomButtons); CustomButtonManager.Buttons = new ReadOnlyCollection<CustomActionButton>(CustomButtonManager.CustomButtons);
CustomButtonManager.EventTypes = new ReadOnlyDictionary<Type, Type>(CustomButtonManager.ButtonEventTypes); CustomButtonManager.EventTypes = new ReadOnlyDictionary<Type, Type>(CustomButtonManager.ButtonEventTypes);
@@ -87,101 +269,9 @@ public sealed class MiraPluginManager
ModifierManager.Modifiers = new ReadOnlyCollection<BaseModifier>(ModifierManager.InternalModifiers); ModifierManager.Modifiers = new ReadOnlyCollection<BaseModifier>(ModifierManager.InternalModifiers);
}; };
}
private MiraPluginInfo RegisterPlugin(Assembly assembly, IMiraPlugin plugin, PluginInfo pluginInfo, BasePlugin basePlugin, bool isMira) RegisterKeybinds(typeof(MiraGlobalKeybinds), PluginSingleton<MiraApiPlugin>.Instance);
{ RegisterLocalTabs(typeof(MiraApiSettings), PluginSingleton<MiraApiPlugin>.Instance);
var info = new MiraPluginInfo(plugin, pluginInfo);
var roles = new List<Type>();
var oldConfigSetting = info.PluginConfig.SaveOnConfigSet;
info.PluginConfig.SaveOnConfigSet = false;
ProcessAssemblyTypes(assembly, info, basePlugin, roles, isMira);
info.PluginConfig.Save();
info.PluginConfig.SaveOnConfigSet = oldConfigSetting;
info.InternalOptionGroups.Sort((x, y) => x.GroupPriority.CompareTo(y.GroupPriority));
QueuedRoleRegistrations.Add(info, roles);
_registeredPlugins.Add(assembly, info);
info.SavePublicCollections();
PresetManager.CreateDefaultPreset(info);
PresetManager.LoadPresets(info);
return info;
}
private static void ProcessAssemblyTypes(Assembly assembly, MiraPluginInfo info, BasePlugin basePlugin, List<Type> roles, bool isMira)
{
foreach (var type in assembly.GetTypes())
{
if ((isMira && type.IsAbstract) || type.GetCustomAttribute<MiraIgnoreAttribute>() != null)
continue;
RegisterEvents(type);
if (RegisterModifier(type, info))
continue;
if (RegisterOptions(type, info))
continue;
if (RegisterLocalTabs(type, basePlugin))
continue;
if (RegisterRole(type, info, out var role))
{
roles.Add(role);
continue;
}
if (RegisterButton(type, info))
continue;
if (RegisterGameOver(type))
continue;
if (RegisterMeetingAbility(type, info))
continue;
if (RegisterTargetedMeetingAbility(type, info))
continue;
if (RegisterGameModeAttribute(type, info))
continue;
RegisterColorClasses(type);
RegisterKeybinds(type, basePlugin);
}
}
private static void RegisterEvents(Type type)
{
foreach (var method in AccessTools.GetDeclaredMethods(type))
{
var eventAttribute = method.GetCustomAttribute<RegisterEventAttribute>();
if (eventAttribute == null)
continue;
if (!method.IsStatic)
{
Error($"Event method {method.Name} in {type.Name} must be static.");
continue;
}
var parameters = method.GetParameters();
if (parameters.Length != 1 || !parameters[0].ParameterType.IsSubclassOf(typeof(MiraEvent)))
{
Error($"Invalid event registration method {method.Name} in {type.Name}");
continue;
}
var paramType = parameters[0].ParameterType;
MiraEventManager.RegisterEventHandler(paramType, method, eventAttribute.Priority);
}
} }
/// <summary> /// <summary>
@@ -268,7 +358,7 @@ public sealed class MiraPluginManager
} }
catch (Exception e) catch (Exception e)
{ {
Error($"Failed to register options for {type.Name}: {e}"); Error($"Failed to register options for {type.Name}: {e.ToString()}");
} }
return false; return false;
@@ -453,7 +543,7 @@ public sealed class MiraPluginManager
} }
catch (Exception e) catch (Exception e)
{ {
Error($"Failed to register options for {type.Name}: {e}"); Error($"Failed to register options for {type.Name}: {e.ToString()}");
} }
return false; return false;
+40 -1
View File
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<resources> <resources>
<string name="MiraApi.TopRightButtonScaleFactor">Factor de Escala de la IU superior derecha</string> <string name="MiraApi.TopRightButtonScaleFactor">Factor de Escala de la IU superior derecha</string>
<string name="MiraApi.WikiOnBottomRow">Botón de Wiki debajo de la IU principal</string> <string name="MiraApi.WikiOnBottomRow">Botón debajo de la IU principal</string>
<string name="Roles">Roles</string> <string name="Roles">Roles</string>
<string name="Modifier">Modificador</string> <string name="Modifier">Modificador</string>
<string name="Modifiers">Modificadores</string> <string name="Modifiers">Modificadores</string>
@@ -40,4 +40,43 @@ Sobrevive al temporizador o elimina a la Tripulación.</string>
<string name="MiraApi.RoleTeam.Impostor.Group">Roles de Impostor</string> <string name="MiraApi.RoleTeam.Impostor.Group">Roles de Impostor</string>
<string name="MiraApi.RoleTeam.Neutral.Group">Roles Neutrales</string> <string name="MiraApi.RoleTeam.Neutral.Group">Roles Neutrales</string>
<string name="MiraApi.RoleTeam.Other">Otros</string> <string name="MiraApi.RoleTeam.Other">Otros</string>
<string name="MiraApi.MatchInfoGuide">Guía de Partida</string>
<string name="MiraApi.MatchInfoGuideScaleFactor">Factor de Escala de la Guía de Partida</string>
<string name="MiraApi.WikiTabPosition">Posición de la Pestaña de Botones</string>
<string name="MiraApi.WikiTabPosition.LeftSide">Izquierda</string>
<string name="MiraApi.WikiTabPosition.RightSide">Derecha</string>
<string name="MiraApi.WikiTabPosition.Below">Debajo de la IU</string>
<string name="MiraApi.EnableVariableColors">Activar Colores Variables</string>
<string name="MiraApi.Gamemode">Modo de Juego</string>
<string name="MiraApi.ModifierDisplay.Page">Página</string>
<string name="MiraApi.Page">Página</string>
<string name="MiraApi.Main">Principal</string>
<string name="MiraApi.AbilityType.Basic">Habilidad</string>
<string name="MiraApi.AbilityType.Indirect">Habilidad Indirecta</string>
<string name="MiraApi.Wiki.VanillaSettings">Vanilla</string>
<string name="MiraApi.Wiki.SearchResults">Resultados de búsqueda</string>
<string name="MiraApi.Wiki.PreviousPage">Anterior</string>
<string name="MiraApi.Wiki.NextPage">Siguiente</string>
<string name="MiraApi.Wiki.NoResultsFound">Sin resultados</string>
<string name="On">Sí</string>
<string name="Off">No</string>
<string name="Enabled">Activado</string>
<string name="Disabled">Desactivado</string>
<string name="Active">Activo</string>
<string name="Inactive">Inactivo</string>
<string name="Activated">Activado</string>
<string name="Deactivated">Desactivado</string>
<string name="MiraApi.AbilityType.Interaction">Habilidad de Interacción</string>
<string name="MiraApi.AbilityType.Radius">Habilidad de Radio</string>
<string name="MiraApi.AbilityType.Menu">Habilidad de Menú</string>
<string name="MiraApi.AbilityType.Meeting">Habilidad de Reunión</string>
<string name="MiraApi.AbilityType.SelectiveMeeting">Habilidad Selectiva de Reunión</string>
<string name="MiraApi.AbilityType.MeetingMenu">Habilidad de Menú de Reunión</string>
<string name="Options">Opciones</string>
<string name="MiraApi.Wiki.PlayersTab">Lista de Jugadores</string>
<string name="MiraApi.Wiki.SettingsTab">Opciones de Partida</string>
<string name="MiraApi.Wiki.SearchPlaceholder">Buscar...</string>
<string name="MiraApi.Wiki.FilterLabel">Filtrar</string>
<string name="MiraApi.Wiki.GroupingLabel">Agrupar</string>
<string name="MiraApi.Wiki.OrderLabel">Ordenar</string>
</resources> </resources>
+11 -11
View File
@@ -1,14 +1,14 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<resources> <resources>
<string name="MiraApi.TopRightButtonScaleFactor">Échelle de tailles de boutons</string> <string name="MiraApi.TopRightButtonScaleFactor">Échelle de tailles de boutons</string>
<string name="MiraApi.WikiOnBottomRow">Bouton pour le Wiki sous l'interface principale</string> <string name="MiraApi.WikiOnBottomRow">Bouton pour le Wiki sous l'interface principale</string>
<string name="Roles">Rôles</string> <string name="Roles">Rôles</string>
<string name="Modifier">Modificateur</string> <string name="Modifier">Modificateur</string>
<string name="Modifiers">Modificateurs</string> <string name="Modifiers">Modificateurs</string>
<string name="MiraApi.RoleTeam.Crewmate">Coéquipier</string> <string name="MiraApi.RoleTeam.Crewmate">Coéquipier</string>
<string name="MiraApi.RoleTeam.Crewmate.Short">Équipage</string> <string name="MiraApi.RoleTeam.Crewmate.Short">Équipage</string>
<string name="MiraApi.RoleTeam.Impostor">Imposteur</string> <string name="MiraApi.RoleTeam.Impostor">Imposteur</string>
<string name="MiraApi.RoleTeam.Impostor.Short">Impo</string> <string name="MiraApi.RoleTeam.Impostor.Short">Impo</string>
<string name="MiraApi.RoleTeam.Neutral">Neutre</string> <string name="MiraApi.RoleTeam.Neutral">Neutre</string>
<string name="MiraApi.RoleTeam.Neutral.Short">Neutre</string> <string name="MiraApi.RoleTeam.Neutral.Short">Neutre</string>
</resources> </resources>
+40 -1
View File
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<resources> <resources>
<string name="MiraApi.TopRightButtonScaleFactor">Skala Przycisków w Prawym Górnym</string> <string name="MiraApi.TopRightButtonScaleFactor">Skala Przycisków w Prawym Górnym</string>
<string name="MiraApi.WikiOnBottomRow">Pokaż Wiki w Dolnym Rzędzie</string> <string name="MiraApi.WikiOnBottomRow">Pokaż Przycisk w Dolnym Rzędzie</string>
<string name="Roles">Role</string> <string name="Roles">Role</string>
<string name="Modifier">Modyfikator</string> <string name="Modifier">Modyfikator</string>
<string name="Modifiers">Modyfikatory</string> <string name="Modifiers">Modyfikatory</string>
@@ -40,4 +40,43 @@ Przeżyj przez wymagany czas, albo zabij chowających.</string>
<string name="MiraApi.RoleTeam.Impostor.Group">Role Intruzów</string> <string name="MiraApi.RoleTeam.Impostor.Group">Role Intruzów</string>
<string name="MiraApi.RoleTeam.Neutral.Group">Role Neutralne</string> <string name="MiraApi.RoleTeam.Neutral.Group">Role Neutralne</string>
<string name="MiraApi.RoleTeam.Other">Inne</string> <string name="MiraApi.RoleTeam.Other">Inne</string>
<string name="MiraApi.MatchInfoGuide">Informacje O Meczu</string>
<string name="MiraApi.WikiTabPosition.LeftSide">Po Lewo</string>
<string name="MiraApi.WikiTabPosition.RightSide">Po Prawo</string>
<string name="MiraApi.WikiTabPosition.Below">Poniżej UI</string>
<string name="MiraApi.Gamemode">Tryb Gry</string>
<string name="MiraApi.MatchInfoGuideScaleFactor">Skala Menu Z Informacjami O Meczu</string>
<string name="MiraApi.WikiTabPosition">Położenie Przycisków Informacji O Meczu</string>
<string name="MiraApi.ModifierDisplay.Page">Strona</string>
<string name="MiraApi.Page">Strona</string>
<string name="MiraApi.Main">Główne</string>
<string name="MiraApi.AbilityType.Basic">Umiejętność</string>
<string name="MiraApi.AbilityType.Indirect">Umiejętność Pośrednia</string>
<string name="MiraApi.AbilityType.Interaction">Umiejętność Interakcyjna</string>
<string name="MiraApi.AbilityType.Radius">Umiejętność z Zasięgiem</string>
<string name="MiraApi.AbilityType.Menu">Umiejętność z Menu</string>
<string name="MiraApi.AbilityType.Meeting">Umiejętność na Spotkaniu</string>
<string name="MiraApi.AbilityType.SelectiveMeeting">Umiejętność na Spotkaniu z Wyborem</string>
<string name="MiraApi.AbilityType.MeetingMenu">Umiejętność z Menu na Spotkaniu</string>
<string name="Options">Opcję</string>
<string name="MiraApi.Wiki.PlayersTab">Lista Graczy</string>
<string name="MiraApi.Wiki.SettingsTab">Ustawienia Gry</string>
<string name="MiraApi.Wiki.SearchPlaceholder">Wyszukaj...</string>
<string name="MiraApi.Wiki.FilterLabel">Filtruj</string>
<string name="MiraApi.Wiki.OrderLabel">Kolejność</string>
<string name="MiraApi.Wiki.GroupingLabel">Grupuj</string>
<string name="MiraApi.Wiki.VanillaSettings">Vanilla</string>
<string name="MiraApi.Wiki.SearchResults">Wyniki Wyszukiwania</string>
<string name="MiraApi.Wiki.PreviousPage">Poprzednia</string>
<string name="MiraApi.Wiki.NextPage">Następna</string>
<string name="MiraApi.Wiki.NoResultsFound">Brak Wyników</string>
<string name="On">Wł</string>
<string name="Off">Wył</string>
<string name="Enabled">Włączone</string>
<string name="Disabled">Wyłączone</string>
<string name="Active">Aktywne</string>
<string name="Inactive">Nieaktywne</string>
<string name="Activated">Aktywowane</string>
<string name="Deactivated">Dezaktywowane</string>
<string name="MiraApi.EnableVariableColors">Włącz Kolory Zmienne</string>
</resources> </resources>
+11 -11
View File
@@ -1,14 +1,14 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<resources> <resources>
<string name="MiraApi.TopRightButtonScaleFactor">Множитель разрешения верх.-правого интерфейса</string> <string name="MiraApi.TopRightButtonScaleFactor">Множитель разрешения верх.-правого интерфейса</string>
<string name="MiraApi.WikiOnBottomRow">Кнопка вики под основным интерфейсом</string> <string name="MiraApi.WikiOnBottomRow">Кнопка вики под основным интерфейсом</string>
<string name="Roles">Роли</string> <string name="Roles">Роли</string>
<string name="Modifier">Атрибут</string> <string name="Modifier">Атрибут</string>
<string name="Modifiers">Атрибуты</string> <string name="Modifiers">Атрибуты</string>
<string name="MiraApi.RoleTeam.Crewmate">Член Экипажа</string> <string name="MiraApi.RoleTeam.Crewmate">Член Экипажа</string>
<string name="MiraApi.RoleTeam.Crewmate.Short">Экипаж</string> <string name="MiraApi.RoleTeam.Crewmate.Short">Экипаж</string>
<string name="MiraApi.RoleTeam.Impostor">Предатель</string> <string name="MiraApi.RoleTeam.Impostor">Предатель</string>
<string name="MiraApi.RoleTeam.Impostor.Short">Пред</string> <string name="MiraApi.RoleTeam.Impostor.Short">Пред</string>
<string name="MiraApi.RoleTeam.Neutral">Нейтрал</string> <string name="MiraApi.RoleTeam.Neutral">Нейтрал</string>
<string name="MiraApi.RoleTeam.Neutral.Short">Нейт</string> <string name="MiraApi.RoleTeam.Neutral.Short">Нейт</string>
</resources> </resources>
+3 -6
View File
@@ -280,11 +280,11 @@ public static class CustomRoleManager
while (data.Count > 0) while (data.Count > 0)
{ {
Rpc<SyncRoleOptionsRpc>.Instance.SendTo(PlayerControl.LocalPlayer, targetId, new MiraOptionNetData(false, data.Dequeue())); Rpc<SyncRoleOptionsRpc>.Instance.SendTo(PlayerControl.LocalPlayer, targetId, data.Dequeue());
} }
} }
internal static void HandleSyncRoleOptions(bool showNotifs, NetData[] data) internal static void HandleSyncRoleOptions(NetData[] data)
{ {
// necessary to disable then re-enable this setting // necessary to disable then re-enable this setting
// we don't know how other plugins handle their configs // we don't know how other plugins handle their configs
@@ -312,10 +312,7 @@ public static class CustomRoleManager
var num = BitConverter.ToInt32(netData.Data, 0); var num = BitConverter.ToInt32(netData.Data, 0);
var chance = BitConverter.ToInt32(netData.Data, 4); var chance = BitConverter.ToInt32(netData.Data, 4);
if (showNotifs) HudManager.Instance.Notifier.AddRoleSettingsChangeMessage(role.StringName, num, chance, role.TeamType, false);
{
HudManager.Instance.Notifier.AddRoleSettingsChangeMessage(role.StringName, num, chance, role.TeamType, false);
}
try try
{ {
-43
View File
@@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Text; using System.Text;
using BepInEx.Configuration; using BepInEx.Configuration;
using Il2CppInterop.Runtime.Attributes; using Il2CppInterop.Runtime.Attributes;
@@ -93,48 +92,6 @@ public interface ICustomRole : IOptionable
_ => MiraLocaleManager.Get("MiraApi.RoleTeam.Other"), _ => MiraLocaleManager.Get("MiraApi.RoleTeam.Other"),
}; };
/// <summary>
/// Gets a value indicating whether to exclude the "amount" from the displayed amount text within the role guide.
/// </summary>
public virtual bool ShowRoleAsUnique => Configuration.MaxRoleCount == 1;
/// <summary>
/// Gets the displayed amount and chance of the role. Used in the role guide.
/// By default, 0 amount or chance results in a complete 0 amount and chance, so override if necessary.
/// </summary>
/// <param name="amount">The amount of the role.</param>
/// <param name="chance">The chance of the role.</param>
/// <param name="source">The mod source of the role.</param>
/// <returns>The <see cref="string"/> result.</returns>
public virtual string GetAmountText(int amount, int chance, string source)
{
if (amount == 0)
{
chance = 0;
}
if (ShowRoleAsUnique)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0}% ({1})",
chance.ToString(CultureInfo.InvariantCulture),
source);
}
if (chance == 0)
{
amount = 0;
}
return string.Format(
CultureInfo.InvariantCulture,
"{0} at {1}% ({2})",
amount.ToString(CultureInfo.InvariantCulture),
chance.ToString(CultureInfo.InvariantCulture),
source);
}
/// <summary> /// <summary>
/// Gets the <see cref="Color"/> of the role. /// Gets the <see cref="Color"/> of the role.
/// </summary> /// </summary>
+11 -37
View File
@@ -72,7 +72,6 @@ public static class MiraLocaleManager
/// </summary> /// </summary>
public static Dictionary<MiraLanguage, string> LangCultureList { get; } = new() public static Dictionary<MiraLanguage, string> LangCultureList { get; } = new()
{ {
// Vanilla
{ MiraLanguage.English, "en-US" }, { MiraLanguage.English, "en-US" },
{ MiraLanguage.Latam, "es-419" }, { MiraLanguage.Latam, "es-419" },
{ MiraLanguage.Brazilian, "pt-BR" }, { MiraLanguage.Brazilian, "pt-BR" },
@@ -89,17 +88,15 @@ public static class MiraLocaleManager
{ MiraLanguage.SChinese, "zh-CN" }, { MiraLanguage.SChinese, "zh-CN" },
{ MiraLanguage.TChinese, "zh-TW" }, { MiraLanguage.TChinese, "zh-TW" },
{ MiraLanguage.Irish, "ga-IE" }, { MiraLanguage.Irish, "ga-IE" },
{ MiraLanguage.Polish, "pl-PL" }, // Custom
// Custom { MiraLanguage.Turkish, "tr-TR" }, // Custom
{ MiraLanguage.Polish, "pl-PL" }, { MiraLanguage.Swedish, "sv-SE" }, // Custom
{ MiraLanguage.Turkish, "tr-TR" }, { MiraLanguage.Lithuanian, "lt-LT" }, // Custom
{ MiraLanguage.Swedish, "sv-SE" }, { MiraLanguage.Czech, "cs-CZ" }, // Custom
{ MiraLanguage.Lithuanian, "lt-LT" }, { MiraLanguage.LChinese, "lzh-CN" }, // Custom
{ MiraLanguage.Czech, "cs-CZ" }, { MiraLanguage.Greek, "el-GR" }, // Custom
{ MiraLanguage.LChinese, "lzh-CN" }, { MiraLanguage.Arabic, "arb" }, // Custom
{ MiraLanguage.Greek, "el-GR" }, { MiraLanguage.Hebrew, "heb" }, // Custom
{ MiraLanguage.Arabic, "arb" },
{ MiraLanguage.Hebrew, "heb" },
}; };
/// <summary> /// <summary>
@@ -126,47 +123,24 @@ public static class MiraLocaleManager
/// Call once per mod during plugin Load(). /// Call once per mod during plugin Load().
/// </summary> /// </summary>
/// <param name="modGuid">The mod GUID (e.g., "mira.example").</param> /// <param name="modGuid">The mod GUID (e.g., "mira.example").</param>
[Obsolete("Pass typeof(YourPlugin).Assembly directly to Register for better performance.")]
public static void Register(string modGuid) public static void Register(string modGuid)
{ {
var callingAssembly = Assembly.GetCallingAssembly(); var callingAssembly = Assembly.GetCallingAssembly();
LoadInternalStrings(callingAssembly, callingAssembly.GetName().Name!, modGuid); LoadInternalStrings(callingAssembly, callingAssembly.GetName().Name!, modGuid);
} }
/// <summary>
/// Registers translations for a mod.
/// Call once per mod during plugin Load().
/// </summary>
/// <param name="modGuid">The mod GUID (e.g., "mira.example").</param>
/// <param name="assembly">The <see cref="Assembly"/> to load the strings from.</param>
public static void Register(string modGuid, Assembly assembly)
{
LoadInternalStrings(assembly, assembly.GetName().Name!, modGuid);
}
/// <summary> /// <summary>
/// Registers translations for a mod. /// Registers translations for a mod.
/// Call once per mod during plugin Load(). /// Call once per mod during plugin Load().
/// </summary> /// </summary>
/// <param name="modGuid">The mod GUID (e.g., "mira.example").</param> /// <param name="modGuid">The mod GUID (e.g., "mira.example").</param>
/// <param name="internalName">The mod's root namespace (e.g., "mira.api").</param> /// <param name="internalName">The mod's root namespace (e.g., "mira.api").</param>
[Obsolete("Pass typeof(YourPlugin).Assembly directly to Register for better performance.")]
public static void Register(string modGuid, string internalName) public static void Register(string modGuid, string internalName)
{ {
var callingAssembly = Assembly.GetCallingAssembly(); var callingAssembly = Assembly.GetCallingAssembly();
LoadInternalStrings(callingAssembly, internalName, modGuid);
}
/// <summary> LoadInternalStrings(callingAssembly, internalName, modGuid);
/// Registers translations for a mod.
/// Call once per mod during plugin Load().
/// </summary>
/// <param name="modGuid">The mod GUID (e.g., "mira.example").</param>
/// <param name="internalName">The mod's root namespace (e.g., "mira.api").</param>
/// <param name="assembly">The <see cref="Assembly"/> to load the strings from.</param>
public static void Register(string modGuid, string internalName, Assembly assembly)
{
LoadInternalStrings(assembly, internalName, modGuid);
} }
/// <summary> /// <summary>
@@ -1,4 +1,3 @@
using System;
using System.Reflection; using System.Reflection;
using UnityEngine; using UnityEngine;
@@ -7,39 +6,17 @@ namespace MiraAPI.Utilities.Assets;
/// <summary> /// <summary>
/// A utility class for loading .WAV audio assets from the DLL's embedded resources. /// A utility class for loading .WAV audio assets from the DLL's embedded resources.
/// </summary> /// </summary>
public class LoadableAudioResourceAsset : LoadableAsset<AudioClip> /// <param name="path">The path of the wave file.</param>
public class LoadableAudioResourceAsset(string path) : LoadableAsset<AudioClip>
{ {
private readonly string _path; private readonly Assembly _assembly = Assembly.GetCallingAssembly();
private readonly Assembly _assembly;
/// <summary>
/// Initializes a new instance of the <see cref="LoadableAudioResourceAsset"/> class with the provided resource path and the assembly containing the asset.
/// </summary>
/// <param name="path">The path of the wave file.</param>
/// <param name="assembly">The <see cref="Assembly"/> containing the asset.</param>
public LoadableAudioResourceAsset(string path, Assembly assembly)
{
_path = path;
_assembly = assembly;
}
/// <summary>
/// Initializes a new instance of the <see cref="LoadableAudioResourceAsset"/> class with the provided resource path.
/// </summary>
/// <param name="path">The path of the wave file.</param>
[Obsolete("Pass typeof(YourPlugin).Assembly directly to the constructor for better performance.")]
public LoadableAudioResourceAsset(string path)
{
_path = path;
_assembly = Assembly.GetCallingAssembly();
}
/// <inheritdoc /> /// <inheritdoc />
public override AudioClip LoadAsset() public override AudioClip LoadAsset()
{ {
if (!LoadedAsset) if (!LoadedAsset)
{ {
LoadedAsset = AudioTools.LoadAudioFromResources(_path, _assembly); LoadedAsset = AudioTools.LoadAudioFromResources(path, _assembly);
} }
return LoadedAsset!; return LoadedAsset!;
@@ -1,5 +1,4 @@
using System; using System.Reflection;
using System.Reflection;
using UnityEngine; using UnityEngine;
namespace MiraAPI.Utilities.Assets; namespace MiraAPI.Utilities.Assets;
@@ -7,44 +6,18 @@ namespace MiraAPI.Utilities.Assets;
/// <summary> /// <summary>
/// A utility class for loading assets from embedded resources. /// A utility class for loading assets from embedded resources.
/// </summary> /// </summary>
public class LoadableResourceAsset : LoadableAsset<Sprite> /// <param name="path">The path to the embedded resource.</param>
/// <param name="pixelsPerUnit">The pixels per unit for the loaded sprite.</param>
public class LoadableResourceAsset(string path, float pixelsPerUnit = 100f) : LoadableAsset<Sprite>
{ {
private readonly string _path; private readonly Assembly _assembly = Assembly.GetCallingAssembly();
private readonly float _pixelsPerUnit;
private readonly Assembly _assembly;
/// <summary>
/// Initializes a new instance of the <see cref="LoadableResourceAsset"/> class with the provided resource path and the assembly containing the asset.
/// </summary>
/// <param name="path">The path to the embedded resource.</param>
/// <param name="assembly">The <see cref="Assembly"/> containing the asset.</param>
/// <param name="pixelsPerUnit">The pixels per unit for the loaded sprite.</param>
public LoadableResourceAsset(string path, Assembly assembly, float pixelsPerUnit = 100f)
{
_path = path;
_assembly = assembly;
_pixelsPerUnit = pixelsPerUnit;
}
/// <summary>
/// Initializes a new instance of the <see cref="LoadableResourceAsset"/> class with the provided resource path and the assembly containing the asset.
/// </summary>
/// <param name="path">The path to the embedded resource.</param>
/// <param name="pixelsPerUnit">The pixels per unit for the loaded sprite.</param>
[Obsolete("Pass typeof(YourPlugin).Assembly directly to the constructor for better performance.")]
public LoadableResourceAsset(string path, float pixelsPerUnit = 100f)
{
_path = path;
_pixelsPerUnit = pixelsPerUnit;
_assembly = Assembly.GetCallingAssembly();
}
/// <inheritdoc /> /// <inheritdoc />
public override Sprite LoadAsset() public override Sprite LoadAsset()
{ {
if (!LoadedAsset) if (!LoadedAsset)
{ {
LoadedAsset = SpriteTools.LoadSpriteFromPath(_path, _assembly, _pixelsPerUnit); LoadedAsset = SpriteTools.LoadSpriteFromPath(path, _assembly, pixelsPerUnit);
} }
return LoadedAsset!; return LoadedAsset!;
+66 -69
View File
@@ -1,5 +1,4 @@
using System.Reflection; using Reactor.Utilities;
using Reactor.Utilities;
using UnityEngine; using UnityEngine;
namespace MiraAPI.Utilities.Assets; namespace MiraAPI.Utilities.Assets;
@@ -9,13 +8,11 @@ namespace MiraAPI.Utilities.Assets;
/// </summary> /// </summary>
public static class MiraAssets public static class MiraAssets
{ {
private static readonly Assembly _assembly = typeof(MiraAssets).Assembly;
static MiraAssets() static MiraAssets()
{ {
var boxTex = SpriteTools.LoadTextureFromResourcePath( var boxTex = SpriteTools.LoadTextureFromResourcePath(
"MiraAPI.Resources.RoundedBox.png", "MiraAPI.Resources.RoundedBox.png",
_assembly); System.Reflection.Assembly.GetExecutingAssembly());
var boxSprite = Sprite.Create( var boxSprite = Sprite.Create(
boxTex, boxTex,
new Rect(0, 0, boxTex.width, boxTex.height), new Rect(0, 0, boxTex.width, boxTex.height),
@@ -61,7 +58,7 @@ public static class MiraAssets
/// <summary> /// <summary>
/// Gets the empty <see cref="Sprite"/> asset. /// Gets the empty <see cref="Sprite"/> asset.
/// </summary> /// </summary>
public static LoadableResourceAsset Empty { get; } = new("MiraAPI.Resources.Empty.png", _assembly); public static LoadableResourceAsset Empty { get; } = new("MiraAPI.Resources.Empty.png");
/// <summary> /// <summary>
/// Gets the RoundedBox <see cref="Sprite"/>, which is a rounded rectangle used for UI elements. /// Gets the RoundedBox <see cref="Sprite"/>, which is a rounded rectangle used for UI elements.
@@ -71,312 +68,312 @@ public static class MiraAssets
/// <summary> /// <summary>
/// Gets the Next Button sprite. /// Gets the Next Button sprite.
/// </summary> /// </summary>
public static LoadableResourceAsset NextButton { get; } = new("MiraAPI.Resources.NextButton.png", _assembly); public static LoadableResourceAsset NextButton { get; } = new("MiraAPI.Resources.NextButton.png");
/// <summary> /// <summary>
/// Gets the Mira settings icon. /// Gets the Mira settings icon.
/// </summary> /// </summary>
public static LoadableResourceAsset SettingsIcon { get; } = new("MiraAPI.Resources.Settings.png", _assembly); public static LoadableResourceAsset SettingsIcon { get; } = new("MiraAPI.Resources.Settings.png");
/// <summary> /// <summary>
/// Gets the highlighted Next Button sprite. /// Gets the highlighted Next Button sprite.
/// </summary> /// </summary>
public static LoadableResourceAsset NextButtonActive { get; } = new("MiraAPI.Resources.NextButtonActive.png", _assembly); public static LoadableResourceAsset NextButtonActive { get; } = new("MiraAPI.Resources.NextButtonActive.png");
/// <summary> /// <summary>
/// Gets the Cog icon used in Role Settings Menu. /// Gets the Cog icon used in Role Settings Menu.
/// </summary> /// </summary>
public static LoadableResourceAsset Cog { get; } = new("MiraAPI.Resources.Cog.png", _assembly); public static LoadableResourceAsset Cog { get; } = new("MiraAPI.Resources.Cog.png");
/// <summary> /// <summary>
/// Gets the Checkmark Box used in the Settings Menu. /// Gets the Checkmark Box used in the Settings Menu.
/// </summary> /// </summary>
public static LoadableResourceAsset CheckmarkBox { get; } = new("MiraAPI.Resources.CheckMarkBox.png", _assembly); public static LoadableResourceAsset CheckmarkBox { get; } = new("MiraAPI.Resources.CheckMarkBox.png");
/// <summary> /// <summary>
/// Gets the Reset Box used in the Settings Menu. /// Gets the Reset Box used in the Settings Menu.
/// </summary> /// </summary>
public static LoadableResourceAsset ResetButton { get; } = new("MiraAPI.Resources.ResetButton.png", _assembly); public static LoadableResourceAsset ResetButton { get; } = new("MiraAPI.Resources.ResetButton.png");
/// <summary> /// <summary>
/// Gets the Checkmark used in the Settings Menu. /// Gets the Checkmark used in the Settings Menu.
/// </summary> /// </summary>
public static LoadableResourceAsset Checkmark { get; } = new("MiraAPI.Resources.Checkmark.png", _assembly); public static LoadableResourceAsset Checkmark { get; } = new("MiraAPI.Resources.Checkmark.png");
/// <summary> /// <summary>
/// Gets the white CategoryHeader used in the Settings Menu. /// Gets the white CategoryHeader used in the Settings Menu.
/// </summary> /// </summary>
public static LoadableResourceAsset CategoryHeader { get; } = new("MiraAPI.Resources.CategoryHeader.png", _assembly); public static LoadableResourceAsset CategoryHeader { get; } = new("MiraAPI.Resources.CategoryHeader.png");
/// <summary> /// <summary>
/// Gets the sprite used for the Keybind icons. /// Gets the sprite used for the Keybind icons.
/// </summary> /// </summary>
public static LoadableResourceAsset KeybindButton { get; } = new("MiraAPI.Resources.KeybindButton.png", _assembly); public static LoadableResourceAsset KeybindButton { get; } = new("MiraAPI.Resources.KeybindButton.png");
/// <summary> /// <summary>
/// Gets the sprite used for crewmate role files in TaskAdderGame. /// Gets the sprite used for crewmate role files in TaskAdderGame.
/// </summary> /// </summary>
public static LoadableResourceAsset CrewmateFile { get; } = new("MiraAPI.Resources.CrewmateFile.png", _assembly); public static LoadableResourceAsset CrewmateFile { get; } = new("MiraAPI.Resources.CrewmateFile.png");
/// <summary> /// <summary>
/// Gets the sprite used for impostor role files in TaskAdderGame. /// Gets the sprite used for impostor role files in TaskAdderGame.
/// </summary> /// </summary>
public static LoadableResourceAsset ImpostorFile { get; } = new("MiraAPI.Resources.ImpostorFile.png", _assembly); public static LoadableResourceAsset ImpostorFile { get; } = new("MiraAPI.Resources.ImpostorFile.png");
/// <summary> /// <summary>
/// Gets the sprite used for custom team role files in TaskAdderGame. /// Gets the sprite used for custom team role files in TaskAdderGame.
/// </summary> /// </summary>
public static LoadableResourceAsset CustomTeamFile { get; } = new("MiraAPI.Resources.CustomFile.png", _assembly); public static LoadableResourceAsset CustomTeamFile { get; } = new("MiraAPI.Resources.CustomFile.png");
/// <summary> /// <summary>
/// Gets the sprite used for modifier file in TaskAdderGame. /// Gets the sprite used for modifier file in TaskAdderGame.
/// </summary> /// </summary>
public static LoadableResourceAsset ModifierFile { get; } = new("MiraAPI.Resources.ModifierFile.png", _assembly); public static LoadableResourceAsset ModifierFile { get; } = new("MiraAPI.Resources.ModifierFile.png");
/// <summary> /// <summary>
/// Gets the sprite used for the Classic gamemode. /// Gets the sprite used for the Classic gamemode.
/// </summary> /// </summary>
public static LoadableResourceAsset ClassicGamemodeIcon { get; } = new("MiraAPI.Resources.ClassicGamemodeIcon.png", _assembly); public static LoadableResourceAsset ClassicGamemodeIcon { get; } = new("MiraAPI.Resources.ClassicGamemodeIcon.png");
/// <summary> /// <summary>
/// Gets the sprite used for the Hide n Seek gamemode. /// Gets the sprite used for the Hide n Seek gamemode.
/// </summary> /// </summary>
public static LoadableResourceAsset HnSGamemodeIcon { get; } = new("MiraAPI.Resources.HnSGamemodeIcon.png", _assembly); public static LoadableResourceAsset HnSGamemodeIcon { get; } = new("MiraAPI.Resources.HnSGamemodeIcon.png");
/// <summary> /// <summary>
/// Gets the sprite used for timed modifier file in TaskAdderGame. /// Gets the sprite used for timed modifier file in TaskAdderGame.
/// </summary> /// </summary>
public static LoadableResourceAsset TimedModifierFile { get; } = new("MiraAPI.Resources.TimedModifierFile.png", _assembly); public static LoadableResourceAsset TimedModifierFile { get; } = new("MiraAPI.Resources.TimedModifierFile.png");
/// <summary> /// <summary>
/// Gets the sprite used for the new chat button while hovering. /// Gets the sprite used for the new chat button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset ChatHoverSprite { get; } = new("MiraAPI.Resources.NormalChatHover.png", _assembly); public static LoadableResourceAsset ChatHoverSprite { get; } = new("MiraAPI.Resources.NormalChatHover.png");
/// <summary> /// <summary>
/// Gets the sprite used for the new chat button while hovering. /// Gets the sprite used for the new chat button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset ChatIdleSprite { get; } = new("MiraAPI.Resources.NormalChatIdle.png", _assembly); public static LoadableResourceAsset ChatIdleSprite { get; } = new("MiraAPI.Resources.NormalChatIdle.png");
/// <summary> /// <summary>
/// Gets the sprite used for the new chat button while hovering. /// Gets the sprite used for the new chat button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset ChatOpenSprite { get; } = new("MiraAPI.Resources.NormalChatOpen.png", _assembly); public static LoadableResourceAsset ChatOpenSprite { get; } = new("MiraAPI.Resources.NormalChatOpen.png");
/// <summary> /// <summary>
/// Gets the sprite used for players button while hovering. /// Gets the sprite used for players button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset WikiPlayersButtonHoverSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarPlayersButtonHover.png", _assembly); public static LoadableResourceAsset WikiPlayersButtonHoverSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarPlayersButtonHover.png");
/// <summary> /// <summary>
/// Gets the sprite used for the players button while hovering. /// Gets the sprite used for the players button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset WikiPlayersButtonIdleSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarPlayersButtonIdle.png", _assembly); public static LoadableResourceAsset WikiPlayersButtonIdleSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarPlayersButtonIdle.png");
/// <summary> /// <summary>
/// Gets the sprite used for the players button while hovering. /// Gets the sprite used for the players button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset WikiPlayersButtonOpenSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarPlayersButtonOpen.png", _assembly); public static LoadableResourceAsset WikiPlayersButtonOpenSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarPlayersButtonOpen.png");
/// <summary> /// <summary>
/// Gets the sprite used for the settings button while hovering. /// Gets the sprite used for the settings button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset WikiSettingsButtonHoverSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarSettingsButtonHover.png", _assembly); public static LoadableResourceAsset WikiSettingsButtonHoverSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarSettingsButtonHover.png");
/// <summary> /// <summary>
/// Gets the sprite used for the settings button while hovering. /// Gets the sprite used for the settings button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset WikiSettingsButtonIdleSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarSettingsButtonIdle.png", _assembly); public static LoadableResourceAsset WikiSettingsButtonIdleSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarSettingsButtonIdle.png");
/// <summary> /// <summary>
/// Gets the sprite used for the settings button while hovering. /// Gets the sprite used for the settings button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset WikiSettingsButtonOpenSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarSettingsButtonOpen.png", _assembly); public static LoadableResourceAsset WikiSettingsButtonOpenSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarSettingsButtonOpen.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset WikiRolesButtonHoverSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarRolesButtonHover.png", _assembly); public static LoadableResourceAsset WikiRolesButtonHoverSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarRolesButtonHover.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset WikiRolesButtonIdleSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarRolesButtonIdle.png", _assembly); public static LoadableResourceAsset WikiRolesButtonIdleSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarRolesButtonIdle.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset WikiRolesButtonOpenSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarRolesButtonOpen.png", _assembly); public static LoadableResourceAsset WikiRolesButtonOpenSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarRolesButtonOpen.png");
/// <summary> /// <summary>
/// Gets the sprite used for the modifiers button while hovering. /// Gets the sprite used for the modifiers button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset WikiModifiersButtonHoverSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarModifiersButtonHover.png", _assembly); public static LoadableResourceAsset WikiModifiersButtonHoverSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarModifiersButtonHover.png");
/// <summary> /// <summary>
/// Gets the sprite used for the modifiers button while hovering. /// Gets the sprite used for the modifiers button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset WikiModifiersButtonIdleSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarModifiersButtonIdle.png", _assembly); public static LoadableResourceAsset WikiModifiersButtonIdleSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarModifiersButtonIdle.png");
/// <summary> /// <summary>
/// Gets the sprite used for the modifiers button while hovering. /// Gets the sprite used for the modifiers button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset WikiModifiersButtonOpenSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarModifiersButtonOpen.png", _assembly); public static LoadableResourceAsset WikiModifiersButtonOpenSprite { get; } = new("MiraAPI.Resources.Wiki.SidebarModifiersButtonOpen.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset GroupCountHoverSprite { get; } = new("MiraAPI.Resources.Wiki.GroupCountHover.png", _assembly); public static LoadableResourceAsset GroupCountHoverSprite { get; } = new("MiraAPI.Resources.Wiki.GroupCountHover.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset GroupCountIdleSprite { get; } = new("MiraAPI.Resources.Wiki.GroupCountIdle.png", _assembly); public static LoadableResourceAsset GroupCountIdleSprite { get; } = new("MiraAPI.Resources.Wiki.GroupCountIdle.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset GroupFactionHoverSprite { get; } = new("MiraAPI.Resources.Wiki.GroupFactionHover.png", _assembly); public static LoadableResourceAsset GroupFactionHoverSprite { get; } = new("MiraAPI.Resources.Wiki.GroupFactionHover.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset GroupFactionIdleSprite { get; } = new("MiraAPI.Resources.Wiki.GroupFactionIdle.png", _assembly); public static LoadableResourceAsset GroupFactionIdleSprite { get; } = new("MiraAPI.Resources.Wiki.GroupFactionIdle.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset GroupNoneHoverSprite { get; } = new("MiraAPI.Resources.Wiki.GroupNoneHover.png", _assembly); public static LoadableResourceAsset GroupNoneHoverSprite { get; } = new("MiraAPI.Resources.Wiki.GroupNoneHover.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset GroupNoneIdleSprite { get; } = new("MiraAPI.Resources.Wiki.GroupNoneIdle.png", _assembly); public static LoadableResourceAsset GroupNoneIdleSprite { get; } = new("MiraAPI.Resources.Wiki.GroupNoneIdle.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset SearchClearHoverSprite { get; } = new("MiraAPI.Resources.Wiki.SearchClearHover.png", _assembly); public static LoadableResourceAsset SearchClearHoverSprite { get; } = new("MiraAPI.Resources.Wiki.SearchClearHover.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset SearchClearIdleSprite { get; } = new("MiraAPI.Resources.Wiki.SearchClearIdle.png", _assembly); public static LoadableResourceAsset SearchClearIdleSprite { get; } = new("MiraAPI.Resources.Wiki.SearchClearIdle.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset SearchIconHoverSprite { get; } = new("MiraAPI.Resources.Wiki.SearchIconHover.png", _assembly); public static LoadableResourceAsset SearchIconHoverSprite { get; } = new("MiraAPI.Resources.Wiki.SearchIconHover.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset SearchIconIdleSprite { get; } = new("MiraAPI.Resources.Wiki.SearchIconIdle.png", _assembly); public static LoadableResourceAsset SearchIconIdleSprite { get; } = new("MiraAPI.Resources.Wiki.SearchIconIdle.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset SortingAzHoverSprite { get; } = new("MiraAPI.Resources.Wiki.SortingAzHover.png", _assembly); public static LoadableResourceAsset SortingAzHoverSprite { get; } = new("MiraAPI.Resources.Wiki.SortingAzHover.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset SortingAzIdleSprite { get; } = new("MiraAPI.Resources.Wiki.SortingAzIdle.png", _assembly); public static LoadableResourceAsset SortingAzIdleSprite { get; } = new("MiraAPI.Resources.Wiki.SortingAzIdle.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset SortingZaHoverSprite { get; } = new("MiraAPI.Resources.Wiki.SortingZaHover.png", _assembly); public static LoadableResourceAsset SortingZaHoverSprite { get; } = new("MiraAPI.Resources.Wiki.SortingZaHover.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset SortingZaIdleSprite { get; } = new("MiraAPI.Resources.Wiki.SortingZaIdle.png", _assembly); public static LoadableResourceAsset SortingZaIdleSprite { get; } = new("MiraAPI.Resources.Wiki.SortingZaIdle.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset VisibleAllHoverSprite { get; } = new("MiraAPI.Resources.Wiki.VisibleAllHover.png", _assembly); public static LoadableResourceAsset VisibleAllHoverSprite { get; } = new("MiraAPI.Resources.Wiki.VisibleAllHover.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset VisibleAllIdleSprite { get; } = new("MiraAPI.Resources.Wiki.VisibleAllIdle.png", _assembly); public static LoadableResourceAsset VisibleAllIdleSprite { get; } = new("MiraAPI.Resources.Wiki.VisibleAllIdle.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset VisibleOffHoverSprite { get; } = new("MiraAPI.Resources.Wiki.VisibleOffHover.png", _assembly); public static LoadableResourceAsset VisibleOffHoverSprite { get; } = new("MiraAPI.Resources.Wiki.VisibleOffHover.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset VisibleOffIdleSprite { get; } = new("MiraAPI.Resources.Wiki.VisibleOffIdle.png", _assembly); public static LoadableResourceAsset VisibleOffIdleSprite { get; } = new("MiraAPI.Resources.Wiki.VisibleOffIdle.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset VisibleOnHoverSprite { get; } = new("MiraAPI.Resources.Wiki.VisibleOnHover.png", _assembly); public static LoadableResourceAsset VisibleOnHoverSprite { get; } = new("MiraAPI.Resources.Wiki.VisibleOnHover.png");
/// <summary> /// <summary>
/// Gets the sprite used for the roles button while hovering. /// Gets the sprite used for the roles button while hovering.
/// </summary> /// </summary>
public static LoadableResourceAsset VisibleOnIdleSprite { get; } = new("MiraAPI.Resources.Wiki.VisibleOnIdle.png", _assembly); public static LoadableResourceAsset VisibleOnIdleSprite { get; } = new("MiraAPI.Resources.Wiki.VisibleOnIdle.png");
/// <summary> /// <summary>
/// Gets the sprite used for crewmates. /// Gets the sprite used for crewmates.
/// </summary> /// </summary>
public static LoadableResourceAsset IconCrewmate { get; } = new("MiraAPI.Resources.Wiki.IconCrewmate.png", _assembly); public static LoadableResourceAsset IconCrewmate { get; } = new("MiraAPI.Resources.Wiki.IconCrewmate.png");
/// <summary> /// <summary>
/// Gets the sprite used for impostors. /// Gets the sprite used for impostors.
/// </summary> /// </summary>
public static LoadableResourceAsset IconImpostor { get; } = new("MiraAPI.Resources.Wiki.IconImpostor.png", _assembly); public static LoadableResourceAsset IconImpostor { get; } = new("MiraAPI.Resources.Wiki.IconImpostor.png");
/// <summary> /// <summary>
/// Gets the sprite used for neutrals. /// Gets the sprite used for neutrals.
/// </summary> /// </summary>
public static LoadableResourceAsset IconNeutral { get; } = new("MiraAPI.Resources.Wiki.IconNeutral.png", _assembly); public static LoadableResourceAsset IconNeutral { get; } = new("MiraAPI.Resources.Wiki.IconNeutral.png");
/// <summary> /// <summary>
/// Gets the sprite used for the player list. /// Gets the sprite used for the player list.
/// </summary> /// </summary>
public static LoadableResourceAsset IconPlayerList { get; } = new("MiraAPI.Resources.Wiki.IconPlayerList.png", _assembly); public static LoadableResourceAsset IconPlayerList { get; } = new("MiraAPI.Resources.Wiki.IconPlayerList.png");
/// <summary> /// <summary>
/// Gets the sprite used for settings. /// Gets the sprite used for settings.
/// </summary> /// </summary>
public static LoadableResourceAsset IconSettings { get; } = new("MiraAPI.Resources.Wiki.IconSettings.png", _assembly); public static LoadableResourceAsset IconSettings { get; } = new("MiraAPI.Resources.Wiki.IconSettings.png");
/// <summary> /// <summary>
/// Gets the sprite used for terminology. /// Gets the sprite used for terminology.
/// </summary> /// </summary>
public static LoadableResourceAsset IconTerminology { get; } = new("MiraAPI.Resources.Wiki.IconTerminology.png", _assembly); public static LoadableResourceAsset IconTerminology { get; } = new("MiraAPI.Resources.Wiki.IconTerminology.png");
/// <summary> /// <summary>
/// Gets the Page switching sprite. /// Gets the Page switching sprite.
/// </summary> /// </summary>
public static LoadableResourceAsset PageLeftHover { get; } = new("MiraAPI.Resources.Wiki.PageLeftHover.png", _assembly); public static LoadableResourceAsset PageLeftHover { get; } = new("MiraAPI.Resources.Wiki.PageLeftHover.png");
/// <summary> /// <summary>
/// Gets the Page switching sprite. /// Gets the Page switching sprite.
/// </summary> /// </summary>
public static LoadableResourceAsset PageLeftIdle { get; } = new("MiraAPI.Resources.Wiki.PageLeftIdle.png", _assembly); public static LoadableResourceAsset PageLeftIdle { get; } = new("MiraAPI.Resources.Wiki.PageLeftIdle.png");
/// <summary> /// <summary>
/// Gets the Page switching sprite. /// Gets the Page switching sprite.
/// </summary> /// </summary>
public static LoadableResourceAsset PageRightHover { get; } = new("MiraAPI.Resources.Wiki.PageRightHover.png", _assembly); public static LoadableResourceAsset PageRightHover { get; } = new("MiraAPI.Resources.Wiki.PageRightHover.png");
/// <summary> /// <summary>
/// Gets the Page switching sprite. /// Gets the Page switching sprite.
/// </summary> /// </summary>
public static LoadableResourceAsset PageRightIdle { get; } = new("MiraAPI.Resources.Wiki.PageRightIdle.png", _assembly); public static LoadableResourceAsset PageRightIdle { get; } = new("MiraAPI.Resources.Wiki.PageRightIdle.png");
/// <summary> /// <summary>
/// Gets the sprite used below the tab icons in the wiki. /// Gets the sprite used below the tab icons in the wiki.
/// </summary> /// </summary>
public static LoadableResourceAsset TabButtonContainer { get; } = new("MiraAPI.Resources.Wiki.TabButtonContainer.png", _assembly); public static LoadableResourceAsset TabButtonContainer { get; } = new("MiraAPI.Resources.Wiki.TabButtonContainer.png");
internal static LoadableResourceAsset BlankSprite { get; } = new("MiraAPI.Resources.BlankSprite.png", _assembly); internal static LoadableResourceAsset BlankSprite { get; } = new("MiraAPI.Resources.BlankSprite.png");
} }
-31
View File
@@ -1,31 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace MiraAPI.Utilities;
/// <summary>
/// A comparer used to sort role/modifier IDs based on which ones are currently active.
/// </summary>
/// <param name="activeIds">The collection of currently active IDs.</param>
public class BasicGuideComparer(IEnumerable<uint> activeIds) : IComparer<uint>
{
/// <inheritdoc/>
public int Compare(uint x, uint y)
{
var xActive = activeIds.Contains(x);
var yActive = activeIds.Contains(y);
if (xActive && !yActive)
{
return -1;
}
if (!xActive && yActive)
{
return 1;
}
return 0;
}
}
+2 -15
View File
@@ -492,29 +492,16 @@ public static class Extensions
} }
/// <summary> /// <summary>
/// Gets a proper string for an <see cref="Enum"/> (with spaces). /// Gets a proper string for an <see cref="Enum"/>. (with spaces).
/// </summary> /// </summary>
/// <param name="enum">The <see cref="Enum"/> you would like to change.</param> /// <param name="enum">The <see cref="Enum"/> you would like to change.</param>
/// <returns>A proper string for the provided <see cref="Enum"/>.</returns> /// <returns>A proper string for the <see cref="Enum"/>.</returns>
public static string ToDisplayString(this Enum @enum) public static string ToDisplayString(this Enum @enum)
{ {
var regex = new Regex(@"([^\^])([A-Z][a-z$])", default, Regex.InfiniteMatchTimeout); var regex = new Regex(@"([^\^])([A-Z][a-z$])", default, Regex.InfiniteMatchTimeout);
return regex.Replace(@enum.ToString(), m => $"{m.Groups[1].Value} {m.Groups[2].Value}"); return regex.Replace(@enum.ToString(), m => $"{m.Groups[1].Value} {m.Groups[2].Value}");
} }
/// <summary>
/// Gets a proper string for a(n) <typeparamref name="T"/> value (with spaces).
/// </summary>
/// <typeparam name="T">The type of the enum value.</typeparam>
/// <param name="enum">The <typeparamref name="T"/> enum value you would like to change.</param>
/// <returns>A proper string for the provided <typeparamref name="T"/> value.</returns>
public static string ToDisplayString<T>(this T @enum)
where T : struct, Enum
{
var regex = new Regex(@"([^\^])([A-Z][a-z$])", default, Regex.InfiniteMatchTimeout);
return regex.Replace(@enum.ToString(), m => $"{m.Groups[1].Value} {m.Groups[2].Value}");
}
/// <summary> /// <summary>
/// Gets the constructors of a type that match the specified arguments. /// Gets the constructors of a type that match the specified arguments.
/// </summary> /// </summary>