mirror of
https://github.com/All-Of-Us-Mods/MiraAPI.git
synced 2026-10-22 07:35:55 +00:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08af14a890 | ||
|
|
e2a3dc782b | ||
|
|
109dc796c5 |
No files matched your search
@@ -14,13 +14,8 @@ public sealed class ModdedOptionChangedAttribute(string? methodName = null, Type
|
||||
{
|
||||
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 (notFound)
|
||||
Error($"Method {MemberName} does not exist in {type.FullName}");
|
||||
|
||||
if (ResolveMethod(group, property, out var type, out var instanceGetter) is not { } method)
|
||||
return null;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (ResolveMethod(group, property, out var type, out var instanceGetter, out var notFound) is not { } method)
|
||||
{
|
||||
if (notFound)
|
||||
Error($"Method {MemberName} does not exist in {type.FullName}");
|
||||
|
||||
if (ResolveMethod(group, property, out var type, out var instanceGetter) is not { } method)
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!ValidateListSignature(method, typeof(void), out var hasIndex, valueType))
|
||||
return null;
|
||||
|
||||
@@ -14,13 +14,8 @@ public sealed class ModdedOptionGetterAttribute(string? methodName = null, Type?
|
||||
{
|
||||
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 (notFound)
|
||||
Error($"Method {MemberName} does not exist in {type.FullName}");
|
||||
|
||||
if (ResolveMethod(group, property, out var type, out var instanceGetter) is not { } method)
|
||||
return null;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (ResolveMethod(group, property, out var type, out var instanceGetter, out var notFound) is not { } method)
|
||||
{
|
||||
if (notFound)
|
||||
Error($"Method {MemberName} does not exist in {type.FullName}");
|
||||
|
||||
if (ResolveMethod(group, property, out var type, out var instanceGetter) is not { } method)
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!ValidateListSignature(method, valueType, out var hasIndex, valueType))
|
||||
return null;
|
||||
|
||||
@@ -4,7 +4,6 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using MiraAPI.Utilities;
|
||||
|
||||
namespace MiraAPI.GameOptions.Attributes;
|
||||
|
||||
@@ -128,7 +127,7 @@ public abstract class ModdedOptionMemberAttribute(string? memberName, Type? hold
|
||||
}
|
||||
|
||||
/// <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>
|
||||
/// <param name="group">The option group instance the property belongs to.</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"/>
|
||||
/// if the resolved member is an instance member on an <see cref="AbstractOptionGroup"/>; otherwise, <see langword="null"/>.
|
||||
/// </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>
|
||||
[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 flags = BindingFlags.Static | BindingFlags.Public;
|
||||
|
||||
MemberName ??= property.Name + defaultSuffix;
|
||||
|
||||
type = holderType ?? groupType;
|
||||
instanceGetter = null;
|
||||
MemberName ??= property.Name + defaultSuffix;
|
||||
|
||||
if (type.IsAssignableTo(typeof(AbstractOptionGroup)))
|
||||
{
|
||||
@@ -162,69 +158,12 @@ public abstract class ModdedOptionMemberAttribute(string? memberName, Type? hold
|
||||
.GetProperty(nameof(OptionGroupSingleton<>.Instance))!
|
||||
.GetGetMethod();
|
||||
}
|
||||
else if (!type.IsStatic())
|
||||
else
|
||||
{
|
||||
flags |= BindingFlags.Instance;
|
||||
|
||||
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;
|
||||
instanceGetter = null;
|
||||
}
|
||||
|
||||
var member = type.GetMember(MemberName, flags).FirstOrDefault();
|
||||
notFound = true;
|
||||
|
||||
if (member == null)
|
||||
return null;
|
||||
|
||||
notFound = false;
|
||||
|
||||
if (instanceGetter == null)
|
||||
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"/>
|
||||
/// if the resolved method is an instance method on an <see cref="AbstractOptionGroup"/>; otherwise, <see langword="null"/>.
|
||||
/// </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>
|
||||
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>
|
||||
|
||||
@@ -14,13 +14,8 @@ public sealed class ModdedOptionSetterAttribute(string? methodName = null, Type?
|
||||
{
|
||||
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 (notFound)
|
||||
Error($"Method {MemberName} does not exist in {type.FullName}");
|
||||
|
||||
if (ResolveMethod(group, property, out var type, out var instanceGetter) is not { } method)
|
||||
return null;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (ResolveMethod(group, property, out var type, out var instanceGetter, out var notFound) is not { } method)
|
||||
{
|
||||
if (notFound)
|
||||
Error($"Method {MemberName} does not exist in {type.FullName}");
|
||||
|
||||
if (ResolveMethod(group, property, out var type, out var instanceGetter) is not { } method)
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!ValidateListSignature(method, valueType, out var hasIndex, valueType, valueType))
|
||||
return null;
|
||||
|
||||
@@ -20,11 +20,9 @@ public sealed class ModdedOptionVisibilityAttribute(string? memberName = null, T
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -109,11 +107,9 @@ public sealed class ModdedOptionVisibilityAttribute(string? memberName = null, T
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -77,11 +77,6 @@ public interface IModdedOption
|
||||
/// </summary>
|
||||
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>
|
||||
/// Gets or sets the <see cref="BepInEx.Configuration.ConfigDefinition"/> for the option, used for BepInEx configuration.
|
||||
/// </summary>
|
||||
|
||||
File renamed without changes.
@@ -365,11 +365,11 @@ public static class ModdedOptionsManager
|
||||
|
||||
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
|
||||
// we don't know how other plugins handle their configs
|
||||
@@ -388,7 +388,6 @@ public static class ModdedOptionsManager
|
||||
continue;
|
||||
}
|
||||
|
||||
option.ShowNotification = showNotifs;
|
||||
option.HandleNetData(netData.Data);
|
||||
}
|
||||
|
||||
@@ -398,7 +397,7 @@ public static class ModdedOptionsManager
|
||||
plugin.PluginConfig.SaveOnConfigSet = oldConfigSetting[plugin];
|
||||
}
|
||||
|
||||
if (LobbyInfoPane.InstanceExists)
|
||||
if (LobbyInfoPane.Instance)
|
||||
{
|
||||
LobbyInfoPane.Instance.RefreshPane();
|
||||
}
|
||||
|
||||
@@ -93,16 +93,13 @@ public class ModdedEnumOption : ModdedOption<int>
|
||||
/// <inheritdoc />
|
||||
protected override void OnValueChanged(int newValue)
|
||||
{
|
||||
if (ShowNotification)
|
||||
{
|
||||
ModdedOptionsManager.AddSettingsChangeMessage(
|
||||
HudManager.Instance.Notifier,
|
||||
StringName,
|
||||
Data.GetValueString(newValue),
|
||||
Configuration.PopUpTextColor,
|
||||
Configuration.PopUpIconTmp,
|
||||
false);
|
||||
}
|
||||
ModdedOptionsManager.AddSettingsChangeMessage(
|
||||
HudManager.Instance.Notifier,
|
||||
StringName,
|
||||
Data.GetValueString(newValue),
|
||||
Configuration.PopUpTextColor,
|
||||
Configuration.PopUpIconTmp,
|
||||
false);
|
||||
if (!OptionBehaviour)
|
||||
{
|
||||
return;
|
||||
@@ -199,17 +196,13 @@ public class ModdedEnumOption<T> : ModdedOption<T>
|
||||
/// <inheritdoc />
|
||||
protected override void OnValueChanged(T newValue)
|
||||
{
|
||||
if (ShowNotification)
|
||||
{
|
||||
ModdedOptionsManager.AddSettingsChangeMessage(
|
||||
HudManager.Instance.Notifier,
|
||||
StringName,
|
||||
Data.GetValueString(Convert.ToInt32(newValue, NumberFormatInfo.InvariantInfo)),
|
||||
Configuration.PopUpTextColor,
|
||||
Configuration.PopUpIconTmp,
|
||||
false);
|
||||
}
|
||||
|
||||
ModdedOptionsManager.AddSettingsChangeMessage(
|
||||
HudManager.Instance.Notifier,
|
||||
StringName,
|
||||
Data.GetValueString(Convert.ToInt32(newValue, NumberFormatInfo.InvariantInfo)),
|
||||
Configuration.PopUpTextColor,
|
||||
Configuration.PopUpIconTmp,
|
||||
false);
|
||||
if (!OptionBehaviour)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -199,16 +199,13 @@ public class ModdedNumberOption : ModdedOption<float>
|
||||
protected override void OnValueChanged(float newValue)
|
||||
{
|
||||
Value = Mathf.Clamp(newValue, Min, Max);
|
||||
if (ShowNotification)
|
||||
{
|
||||
ModdedOptionsManager.AddSettingsChangeMessage(
|
||||
HudManager.Instance.Notifier,
|
||||
StringName,
|
||||
Data.GetValueString(newValue),
|
||||
Configuration.PopUpTextColor,
|
||||
Configuration.PopUpIconTmp,
|
||||
false);
|
||||
}
|
||||
ModdedOptionsManager.AddSettingsChangeMessage(
|
||||
HudManager.Instance.Notifier,
|
||||
StringName,
|
||||
Data.GetValueString(newValue),
|
||||
Configuration.PopUpTextColor,
|
||||
Configuration.PopUpIconTmp,
|
||||
false);
|
||||
|
||||
if (OptionBehaviour is NumberOption opt)
|
||||
{
|
||||
|
||||
@@ -79,9 +79,6 @@ public abstract class ModdedOption<T> : IModdedOption
|
||||
/// <inheritdoc />
|
||||
public bool IncludeInPreset { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool ShowNotification { get; set; } = true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public OptionBehaviour? OptionBehaviour { get; protected set; }
|
||||
|
||||
@@ -159,11 +156,10 @@ public abstract class ModdedOption<T> : IModdedOption
|
||||
entry.Value = _value;
|
||||
}
|
||||
|
||||
Rpc<SyncOptionsRpc>.Instance.Send(PlayerControl.LocalPlayer, new MiraOptionNetData(true, [GetNetData()]), true);
|
||||
Rpc<SyncOptionsRpc>.Instance.Send(PlayerControl.LocalPlayer, [GetNetData()], true);
|
||||
}
|
||||
|
||||
OnValueChanged(_value);
|
||||
ShowNotification = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -99,17 +99,13 @@ public class ModdedToggleOption : ModdedOption<bool>
|
||||
/// <inheritdoc />
|
||||
protected override void OnValueChanged(bool newValue)
|
||||
{
|
||||
if (ShowNotification)
|
||||
{
|
||||
ModdedOptionsManager.AddSettingsChangeMessage(
|
||||
HudManager.Instance.Notifier,
|
||||
StringName,
|
||||
(newValue ? OnValue : OffValue).Translate(),
|
||||
Configuration.PopUpTextColor,
|
||||
Configuration.PopUpIconTmp,
|
||||
false);
|
||||
}
|
||||
|
||||
ModdedOptionsManager.AddSettingsChangeMessage(
|
||||
HudManager.Instance.Notifier,
|
||||
StringName,
|
||||
(newValue ? OnValue : OffValue).Translate(),
|
||||
Configuration.PopUpTextColor,
|
||||
Configuration.PopUpIconTmp,
|
||||
false);
|
||||
if (!OptionBehaviour)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Il2CppInterop.Runtime.Attributes;
|
||||
using MiraAPI.GameOptions;
|
||||
using MiraAPI.PluginLoading;
|
||||
@@ -97,48 +96,6 @@ public abstract class BaseModifier : IOptionable
|
||||
/// </summary>
|
||||
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>
|
||||
/// Gets whether the modifier is forcibly shown or disabled in the wiki screen.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Globalization;
|
||||
using MiraAPI.GameModes;
|
||||
using MiraAPI.GameModes;
|
||||
using MiraAPI.PluginLoading;
|
||||
|
||||
namespace MiraAPI.Modifiers.Types;
|
||||
|
||||
@@ -9,32 +9,29 @@ namespace MiraAPI.Networking;
|
||||
[RegisterCustomRpc((uint)MiraRpc.SyncGameOptions)]
|
||||
#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.)
|
||||
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
|
||||
{
|
||||
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);
|
||||
return;
|
||||
}*/
|
||||
}
|
||||
|
||||
var info = data.Data;
|
||||
writer.Write(data.ShouldShowNotifications);
|
||||
writer.WritePacked((uint)info.Length);
|
||||
foreach (var netData in info)
|
||||
writer.WritePacked((uint)data.Length);
|
||||
foreach (var netData in data)
|
||||
{
|
||||
writer.WritePacked(netData.Id);
|
||||
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 data = new NetData[length];
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ModdedOptionsManager.HandleSyncOptions(data.ShouldShowNotifications, data.Data ?? []);
|
||||
ModdedOptionsManager.HandleSyncOptions(data ?? []);
|
||||
}
|
||||
}
|
||||
@@ -5,41 +5,32 @@ using Reactor.Networking.Rpc;
|
||||
|
||||
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)]
|
||||
#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.)
|
||||
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
|
||||
{
|
||||
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);
|
||||
return;
|
||||
}*/
|
||||
}
|
||||
|
||||
var info = data.Data;
|
||||
writer.Write(data.ShouldShowNotifications);
|
||||
writer.WritePacked((uint)info.Length);
|
||||
foreach (var netData in info)
|
||||
writer.WritePacked((uint)data.Length);
|
||||
foreach (var netData in data)
|
||||
{
|
||||
writer.WritePacked(netData.Id);
|
||||
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 data = new NetData[length];
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CustomRoleManager.HandleSyncRoleOptions(data.ShouldShowNotifications, data.Data ?? []);
|
||||
CustomRoleManager.HandleSyncRoleOptions(data ?? []);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
using HarmonyLib;
|
||||
using MiraAPI.GameModes;
|
||||
using MiraAPI.GameOptions;
|
||||
using MiraAPI.Roles;
|
||||
|
||||
namespace MiraAPI.Patches.GameModes;
|
||||
|
||||
@@ -57,17 +55,4 @@ internal static class GameStartManagerPatches
|
||||
__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);
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ public static class HudManagerPatches
|
||||
|
||||
public static IEnumerator CoResizeUI()
|
||||
{
|
||||
while (!HudManager.InstanceExists) yield return null;
|
||||
while (!HudManager.Instance) yield return null;
|
||||
|
||||
yield return new WaitForSeconds(0.01f);
|
||||
ResizeUI(LocalSettingsTabSingleton<MiraApiSettings>.Instance.ButtonUIFactorSlider.Value);
|
||||
|
||||
@@ -495,7 +495,7 @@ public static class RoleSettingMenuPatches
|
||||
|
||||
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;
|
||||
|
||||
@@ -754,8 +754,7 @@ public static class RoleGuidePatches
|
||||
modifier.ModifierCategoryTitle,
|
||||
modifier.ParentMod.MiraPlugin.GetAbbreviatedModName(),
|
||||
null,
|
||||
modifier,
|
||||
modifier.TypeId));
|
||||
modifier));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -791,8 +790,7 @@ public static class RoleGuidePatches
|
||||
roleBehaviour.GetCategoryTitle(),
|
||||
modId,
|
||||
roleBehaviour,
|
||||
null,
|
||||
(uint)roleBehaviour.Role));
|
||||
null));
|
||||
}
|
||||
|
||||
_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 string Title { get; } = title;
|
||||
@@ -938,7 +936,6 @@ public static class RoleGuidePatches
|
||||
public string ModId { get; } = modId;
|
||||
public RoleBehaviour? Role { get; } = role;
|
||||
public GameModifier? Modifier { get; } = modifier;
|
||||
public uint TypeId { get; } = typeId;
|
||||
public int Amount { get; set; }
|
||||
public int Chance { get; set; }
|
||||
public float Likelihood { get; set; }
|
||||
@@ -1160,9 +1157,7 @@ public static class RoleGuidePatches
|
||||
entry.Visible = entry.CanShow && MatchesSearch(entry, searchText);
|
||||
if (entry.Panel)
|
||||
{
|
||||
dynamic entryType = entry.Modifier != null ? entry.Modifier : entry.Role!;
|
||||
var text = GetPanelCountText(entryType, entry.Amount, entry.Chance, entry.ModId);
|
||||
SetPanelCount(entry.Panel!, text);
|
||||
SetPanelCount(entry.Panel!, entry.Amount, entry.Chance, entry.ModId);
|
||||
if (!entry.Visible && entry.Panel!.gameObject.activeSelf)
|
||||
{
|
||||
entry.Panel.gameObject.SetActive(false);
|
||||
@@ -1187,58 +1182,16 @@ public static class RoleGuidePatches
|
||||
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)
|
||||
{
|
||||
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)
|
||||
.OrderByDescending(p => p.Title.Equals(searchText, StringComparison.OrdinalIgnoreCase))
|
||||
.ThenByDescending(p =>
|
||||
p.Title.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
|
||||
p.Category.Contains(searchText, StringComparison.OrdinalIgnoreCase));
|
||||
return [.. _sortMethod is SortingMethod.Alphabetical
|
||||
? 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)
|
||||
@@ -1698,15 +1651,10 @@ public static class RoleGuidePatches
|
||||
|
||||
public static Sprite GetRandomRoleIcon()
|
||||
{
|
||||
var roles = GetActiveRoles().Shuffle().ToList();
|
||||
foreach (var role in roles)
|
||||
var aliveRole = PlayerControl.LocalPlayer.Data?.Role;
|
||||
if (aliveRole != null && aliveRole.RoleIconSolid != null)
|
||||
{
|
||||
if (role.RoleIconSolid == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return role.RoleIconSolid;
|
||||
return aliveRole.RoleIconSolid;
|
||||
}
|
||||
|
||||
return GetRandomFactionIcon();
|
||||
@@ -1845,22 +1793,21 @@ public static class RoleGuidePatches
|
||||
return false;
|
||||
}
|
||||
|
||||
__instance.roleCount.text = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"{0} at {1}%",
|
||||
numPerGame.ToString(CultureInfo.InvariantCulture),
|
||||
chancePerGame);
|
||||
if (role is ICustomRole customRole)
|
||||
{
|
||||
__instance.roleName.text = customRole.RoleName;
|
||||
__instance.roleDescription.text =
|
||||
$"<size=60%>{role.GetCategoryTitle()}</size>\n" + customRole.RoleMedDescription;
|
||||
__instance.roleIcon.sprite = customRole.Configuration.Icon?.LoadAsset();
|
||||
var text = GetCustomRolePanelCountText(customRole, numPerGame, chancePerGame, customRole.ParentMod.MiraPlugin.GetAbbreviatedModName());
|
||||
SetPanelCount(__instance, text);
|
||||
__instance.roleCount.text += $" ({customRole.ParentMod.MiraPlugin.GetAbbreviatedModName()})";
|
||||
}
|
||||
else
|
||||
{
|
||||
__instance.roleCount.text = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"{0} at {1}%",
|
||||
numPerGame.ToString(CultureInfo.InvariantCulture),
|
||||
chancePerGame);
|
||||
__instance.roleName.text = role.NiceName;
|
||||
__instance.roleDescription.text = $"<size=60%>{role.GetCategoryTitle()}</size>\n" + role.BlurbMed;
|
||||
__instance.roleIcon.sprite = role.RoleIconColor;
|
||||
@@ -1876,20 +1823,9 @@ public static class RoleGuidePatches
|
||||
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 string GetCustomRolePanelCountText(ICustomRole custom, int amount, int chance, string modId)
|
||||
private static void SetPanelCount(MatchInfoRolePanel panel, int amount, int chance, string modId)
|
||||
{
|
||||
return custom.GetAmountText(amount, chance, modId);
|
||||
}
|
||||
|
||||
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(
|
||||
panel.roleCount.text = string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"{0} at {1}% ({2})",
|
||||
amount.ToString(CultureInfo.InvariantCulture),
|
||||
@@ -1897,18 +1833,6 @@ public static class RoleGuidePatches
|
||||
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(
|
||||
this MatchInfoRolePanel instance,
|
||||
RoleBehaviour role,
|
||||
@@ -1921,16 +1845,14 @@ public static class RoleGuidePatches
|
||||
instance.roleDescription.text =
|
||||
$"<size=60%>{role.GetCategoryTitle()}</size>\n" + customRole.RoleMedDescription;
|
||||
instance.roleIcon.sprite = customRole.Configuration.Icon?.LoadAsset();
|
||||
var text = GetCustomRolePanelCountText(customRole, numPerGame, chancePerGame, customRole.ParentMod.MiraPlugin.GetAbbreviatedModName());
|
||||
SetPanelCount(instance, text);
|
||||
SetPanelCount(instance, numPerGame, chancePerGame, customRole.ParentMod.MiraPlugin.GetAbbreviatedModName());
|
||||
}
|
||||
else
|
||||
{
|
||||
instance.roleName.text = role.NiceName;
|
||||
instance.roleDescription.text = $"<size=60%>{role.GetCategoryTitle()}</size>\n" + role.BlurbMed;
|
||||
instance.roleIcon.sprite = role.RoleIconColor;
|
||||
var text = GetPanelCountText(role, numPerGame, chancePerGame, "AU");
|
||||
SetPanelCount(instance, text);
|
||||
SetPanelCount(instance, numPerGame, chancePerGame, "AU");
|
||||
}
|
||||
|
||||
instance.roleIcon.SetSizeLimit(0.13f);
|
||||
@@ -1951,8 +1873,7 @@ public static class RoleGuidePatches
|
||||
instance.roleDescription.text =
|
||||
$"<size=60%>{modifier.ModifierCategoryTitle}</size>\n" + modifier.ModifierMedDescription;
|
||||
instance.roleIcon.sprite = modifier.ModifierIcon?.LoadAsset();
|
||||
var text = GetPanelCountText(modifier, numPerGame, chancePerGame, modifier.ParentMod.MiraPlugin.GetAbbreviatedModName());
|
||||
SetPanelCount(instance, text);
|
||||
SetPanelCount(instance, numPerGame, chancePerGame, modifier.ParentMod.MiraPlugin.GetAbbreviatedModName());
|
||||
|
||||
instance.roleIcon.SetSizeLimit(0.13f);
|
||||
instance.roleIcon.material.SetInt(PlayerMaterial.MaskLayer, 50);
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<resources>
|
||||
<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="Roles">Rôles</string>
|
||||
<string name="Modifier">Modificateur</string>
|
||||
<string name="Modifiers">Modificateurs</string>
|
||||
<string name="MiraApi.RoleTeam.Crewmate">Coéquipier</string>
|
||||
<string name="MiraApi.RoleTeam.Crewmate.Short">Équipage</string>
|
||||
<string name="MiraApi.RoleTeam.Impostor">Imposteur</string>
|
||||
<string name="MiraApi.RoleTeam.Impostor.Short">Impo</string>
|
||||
<string name="MiraApi.RoleTeam.Neutral">Neutre</string>
|
||||
<string name="MiraApi.RoleTeam.Neutral.Short">Neutre</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="Roles">Rôles</string>
|
||||
<string name="Modifier">Modificateur</string>
|
||||
<string name="Modifiers">Modificateurs</string>
|
||||
<string name="MiraApi.RoleTeam.Crewmate">Coéquipier</string>
|
||||
<string name="MiraApi.RoleTeam.Crewmate.Short">Équipage</string>
|
||||
<string name="MiraApi.RoleTeam.Impostor">Imposteur</string>
|
||||
<string name="MiraApi.RoleTeam.Impostor.Short">Impo</string>
|
||||
<string name="MiraApi.RoleTeam.Neutral">Neutre</string>
|
||||
<string name="MiraApi.RoleTeam.Neutral.Short">Neutre</string>
|
||||
</resources>
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<resources>
|
||||
<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="Modifier">Modyfikator</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.Neutral.Group">Role Neutralne</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>
|
||||
@@ -1,14 +1,14 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<resources>
|
||||
<string name="MiraApi.TopRightButtonScaleFactor">Множитель разрешения верх.-правого интерфейса</string>
|
||||
<string name="MiraApi.WikiOnBottomRow">Кнопка вики под основным интерфейсом</string>
|
||||
<string name="Roles">Роли</string>
|
||||
<string name="Modifier">Атрибут</string>
|
||||
<string name="Modifiers">Атрибуты</string>
|
||||
<string name="MiraApi.RoleTeam.Crewmate">Член Экипажа</string>
|
||||
<string name="MiraApi.RoleTeam.Crewmate.Short">Экипаж</string>
|
||||
<string name="MiraApi.RoleTeam.Impostor">Предатель</string>
|
||||
<string name="MiraApi.RoleTeam.Impostor.Short">Пред</string>
|
||||
<string name="MiraApi.RoleTeam.Neutral">Нейтрал</string>
|
||||
<string name="MiraApi.RoleTeam.Neutral.Short">Нейт</string>
|
||||
<string name="MiraApi.TopRightButtonScaleFactor">Множитель разрешения верх.-правого интерфейса</string>
|
||||
<string name="MiraApi.WikiOnBottomRow">Кнопка вики под основным интерфейсом</string>
|
||||
<string name="Roles">Роли</string>
|
||||
<string name="Modifier">Атрибут</string>
|
||||
<string name="Modifiers">Атрибуты</string>
|
||||
<string name="MiraApi.RoleTeam.Crewmate">Член Экипажа</string>
|
||||
<string name="MiraApi.RoleTeam.Crewmate.Short">Экипаж</string>
|
||||
<string name="MiraApi.RoleTeam.Impostor">Предатель</string>
|
||||
<string name="MiraApi.RoleTeam.Impostor.Short">Пред</string>
|
||||
<string name="MiraApi.RoleTeam.Neutral">Нейтрал</string>
|
||||
<string name="MiraApi.RoleTeam.Neutral.Short">Нейт</string>
|
||||
</resources>
|
||||
@@ -280,11 +280,11 @@ public static class CustomRoleManager
|
||||
|
||||
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
|
||||
// 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 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
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using BepInEx.Configuration;
|
||||
using Il2CppInterop.Runtime.Attributes;
|
||||
@@ -93,48 +92,6 @@ public interface ICustomRole : IOptionable
|
||||
_ => 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>
|
||||
/// Gets the <see cref="Color"/> of the role.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace MiraAPI.Utilities;
|
||||
|
||||
public class BasicGuideComparer(IEnumerable<uint> activeIds) : IComparer<uint>
|
||||
{
|
||||
public int Compare(uint x, uint y)
|
||||
{
|
||||
if (x == null && y == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (x == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (y == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
var xActive = activeIds.Contains(x);
|
||||
var yActive = activeIds.Contains(y);
|
||||
|
||||
if (xActive && !yActive)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!xActive && yActive)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user