mirror of
https://github.com/All-Of-Us-Mods/MiraAPI.git
synced 2026-10-20 01:46:15 +00:00
Merge branch 'dev' into commission
# Conflicts: # MiraAPI/Utilities/Extensions.cs
This commit is contained in:
commit
16ff2f8492
7 files changed
+215
-57
No files matched your search
@@ -0,0 +1,21 @@
|
|||||||
|
namespace MiraAPI.Events.Vanilla.Gameplay;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked before RpcEndGame is called, allowing cancellation of the game end entirely.
|
||||||
|
/// </summary>
|
||||||
|
public class BeforeGameEndEvent : MiraCancelableEvent
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the reason for the game end.
|
||||||
|
/// </summary>
|
||||||
|
public GameOverReason Reason { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="BeforeGameEndEvent"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reason">The reason for the game end.</param>
|
||||||
|
public BeforeGameEndEvent(GameOverReason reason)
|
||||||
|
{
|
||||||
|
Reason = reason;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using BepInEx.Configuration;
|
using BepInEx.Configuration;
|
||||||
@@ -175,7 +176,10 @@ public static class ModdedOptionsManager
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="__originalMethod">The original setter method.</param>
|
/// <param name="__originalMethod">The original setter method.</param>
|
||||||
/// <param name="value">The new object value.</param>
|
/// <param name="value">The new object value.</param>
|
||||||
|
#pragma warning disable CA1707
|
||||||
|
[SuppressMessage("ReSharper", "InconsistentNaming", Justification = "Harmony naming convention")]
|
||||||
public static void PropertySetterPatch(MethodBase __originalMethod, object value)
|
public static void PropertySetterPatch(MethodBase __originalMethod, object value)
|
||||||
|
#pragma warning restore CA1707
|
||||||
{
|
{
|
||||||
var attribute = OptionAttributes.First(pair => pair.Key.GetSetMethod() == __originalMethod).Value;
|
var attribute = OptionAttributes.First(pair => pair.Key.GetSetMethod() == __originalMethod).Value;
|
||||||
attribute.SetValue(value);
|
attribute.SetValue(value);
|
||||||
@@ -187,7 +191,10 @@ public static class ModdedOptionsManager
|
|||||||
/// <param name="__originalMethod">The original getter method.</param>
|
/// <param name="__originalMethod">The original getter method.</param>
|
||||||
/// <param name="__result">The result of the property getter.</param>
|
/// <param name="__result">The result of the property getter.</param>
|
||||||
/// <returns>False so the original getter gets skipped.</returns>
|
/// <returns>False so the original getter gets skipped.</returns>
|
||||||
|
#pragma warning disable CA1707
|
||||||
|
[SuppressMessage("ReSharper", "InconsistentNaming", Justification = "Harmony naming convention")]
|
||||||
public static bool PropertyGetterPatch(MethodBase __originalMethod, ref object __result)
|
public static bool PropertyGetterPatch(MethodBase __originalMethod, ref object __result)
|
||||||
|
#pragma warning restore CA1707
|
||||||
{
|
{
|
||||||
var attribute = OptionAttributes.First(pair => pair.Key.GetGetMethod() == __originalMethod).Value;
|
var attribute = OptionAttributes.First(pair => pair.Key.GetGetMethod() == __originalMethod).Value;
|
||||||
__result = attribute.GetValue();
|
__result = attribute.GetValue();
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ public abstract class ModdedOption<T> : IModdedOption
|
|||||||
entry.Value = Value;
|
entry.Value = Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rpc<SyncOptionsRpc>.Instance.Send(PlayerControl.LocalPlayer, [GetNetData()]);
|
Rpc<SyncOptionsRpc>.Instance.Send(PlayerControl.LocalPlayer, [GetNetData()], true);
|
||||||
}
|
}
|
||||||
|
|
||||||
OnValueChanged(newValue);
|
OnValueChanged(newValue);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Globalization;
|
|||||||
using MiraAPI.Events;
|
using MiraAPI.Events;
|
||||||
using MiraAPI.Events.Mira;
|
using MiraAPI.Events.Mira;
|
||||||
using MiraAPI.Patches;
|
using MiraAPI.Patches;
|
||||||
|
using MiraAPI.Utilities;
|
||||||
using MiraAPI.Utilities.Assets;
|
using MiraAPI.Utilities.Assets;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Events;
|
using UnityEngine.Events;
|
||||||
@@ -36,6 +37,11 @@ public abstract class CustomActionButton
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract LoadableAsset<Sprite> Sprite { get; }
|
public abstract LoadableAsset<Sprite> Sprite { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the format string for the cooldown timer.
|
||||||
|
/// </summary>
|
||||||
|
public virtual string CooldownTimerFormatString => "0";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the button's effect duration in seconds. If the button has no effect, set to 0.
|
/// Gets the button's effect duration in seconds. If the button has no effect, set to 0.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -446,12 +452,12 @@ public abstract class CustomActionButton
|
|||||||
{
|
{
|
||||||
Button.SetFillUp(Timer, EffectDuration);
|
Button.SetFillUp(Timer, EffectDuration);
|
||||||
|
|
||||||
Button.cooldownTimerText.text = Mathf.CeilToInt(Timer).ToString(NumberFormatInfo.InvariantInfo);
|
Button.cooldownTimerText.text = Timer.ToString(CooldownTimerFormatString, NumberFormatInfo.InvariantInfo);
|
||||||
Button.cooldownTimerText.gameObject.SetActive(true);
|
Button.cooldownTimerText.gameObject.SetActive(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Button.SetCoolDown(Timer, Cooldown);
|
Button.SetCooldownFormat(Timer, Cooldown, CooldownTimerFormatString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,29 +5,44 @@ using MiraAPI.GameEnd;
|
|||||||
|
|
||||||
namespace MiraAPI.Patches.Events;
|
namespace MiraAPI.Patches.Events;
|
||||||
|
|
||||||
[HarmonyPatch(typeof(EndGameManager), nameof(EndGameManager.SetEverythingUp))]
|
|
||||||
internal static class EndGamePatches
|
internal static class EndGamePatches
|
||||||
{
|
{
|
||||||
public static bool Prefix(EndGameManager __instance)
|
[HarmonyPatch(typeof(GameManager), nameof(GameManager.RpcEndGame))]
|
||||||
|
public static class GameManagerPatches
|
||||||
{
|
{
|
||||||
if (CustomGameOver.Instance is not { } gameOver)
|
public static bool Prefix(GameOverReason endReason)
|
||||||
{
|
{
|
||||||
return true;
|
var @event = new BeforeGameEndEvent(endReason);
|
||||||
}
|
MiraEventManager.InvokeEvent(@event);
|
||||||
|
|
||||||
var result = gameOver.BeforeEndGameSetup(__instance);
|
return !@event.IsCancelled;
|
||||||
return result;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Postfix(EndGameManager __instance)
|
[HarmonyPatch(typeof(EndGameManager), nameof(EndGameManager.SetEverythingUp))]
|
||||||
|
public static class EndGameManagerPatches
|
||||||
{
|
{
|
||||||
if (CustomGameOver.Instance is { } gameOver)
|
public static bool Prefix(EndGameManager __instance)
|
||||||
{
|
{
|
||||||
gameOver.AfterEndGameSetup(__instance);
|
if (CustomGameOver.Instance is not { } gameOver)
|
||||||
CustomGameOver.Instance = null;
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = gameOver.BeforeEndGameSetup(__instance);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
var @event = new GameEndEvent(__instance);
|
public static void Postfix(EndGameManager __instance)
|
||||||
MiraEventManager.InvokeEvent(@event);
|
{
|
||||||
|
if (CustomGameOver.Instance is { } gameOver)
|
||||||
|
{
|
||||||
|
gameOver.AfterEndGameSetup(__instance);
|
||||||
|
CustomGameOver.Instance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var @event = new GameEndEvent(__instance);
|
||||||
|
MiraEventManager.InvokeEvent(@event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,6 +37,22 @@ public static class OptionsPatches
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(StringOption), nameof(StringOption.UpdateValue))]
|
||||||
|
[HarmonyPatch(typeof(NumberOption), nameof(NumberOption.UpdateValue))]
|
||||||
|
public static bool UpdateValuePrefix(OptionBehaviour __instance)
|
||||||
|
{
|
||||||
|
return !__instance.IsCustom();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(NumberOption), nameof(NumberOption.AdjustButtonsActiveState))]
|
||||||
|
[HarmonyPatch(typeof(StringOption), nameof(StringOption.AdjustButtonsActiveState))]
|
||||||
|
public static bool AdjustButtonsPrefix(OptionBehaviour __instance)
|
||||||
|
{
|
||||||
|
return !__instance.IsCustom();
|
||||||
|
}
|
||||||
|
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(typeof(NumberOption), nameof(NumberOption.Initialize))]
|
[HarmonyPatch(typeof(NumberOption), nameof(NumberOption.Initialize))]
|
||||||
public static bool NumberInit(NumberOption __instance)
|
public static bool NumberInit(NumberOption __instance)
|
||||||
@@ -46,17 +62,84 @@ public static class OptionsPatches
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
__instance.TitleText.text =
|
__instance.TitleText.text = TranslationController.Instance.GetString(__instance.Title, Array.Empty<Object>());
|
||||||
TranslationController.Instance.GetString(__instance.Title, Array.Empty<Object>());
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
[HarmonyPatch(typeof(NumberOption), nameof(NumberOption.UpdateValue))]
|
[HarmonyPatch(typeof(NumberOption), nameof(NumberOption.Increase))]
|
||||||
public static bool NumberUpdate(NumberOption __instance)
|
public static bool NumberIncrease(NumberOption __instance)
|
||||||
{
|
{
|
||||||
return !__instance.IsCustom();
|
if (!__instance.IsCustom())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
__instance.Value += __instance.Increment;
|
||||||
|
if (__instance.Value > __instance.ValidRange.max)
|
||||||
|
{
|
||||||
|
__instance.Value = __instance.ValidRange.min;
|
||||||
|
}
|
||||||
|
__instance.OnValueChanged.Invoke(__instance);
|
||||||
|
__instance.AdjustButtonsActiveState();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(NumberOption), nameof(NumberOption.Decrease))]
|
||||||
|
public static bool NumberDecrease(NumberOption __instance)
|
||||||
|
{
|
||||||
|
if (!__instance.IsCustom())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
__instance.Value -= __instance.Increment;
|
||||||
|
if (__instance.Value < __instance.ValidRange.min)
|
||||||
|
{
|
||||||
|
__instance.Value = __instance.ValidRange.max;
|
||||||
|
}
|
||||||
|
__instance.OnValueChanged.Invoke(__instance);
|
||||||
|
__instance.AdjustButtonsActiveState();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(StringOption), nameof(StringOption.Increase))]
|
||||||
|
public static bool StringOptionIncrease(StringOption __instance)
|
||||||
|
{
|
||||||
|
if (!__instance.IsCustom())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
__instance.Value += 1;
|
||||||
|
if (__instance.Value >= __instance.Values.Length)
|
||||||
|
{
|
||||||
|
__instance.Value = 0;
|
||||||
|
}
|
||||||
|
__instance.OnValueChanged.Invoke(__instance);
|
||||||
|
__instance.AdjustButtonsActiveState();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPrefix]
|
||||||
|
[HarmonyPatch(typeof(StringOption), nameof(StringOption.Decrease))]
|
||||||
|
public static bool StringOptionDecrease(StringOption __instance)
|
||||||
|
{
|
||||||
|
if (!__instance.IsCustom())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
__instance.Value -= 1;
|
||||||
|
if (__instance.Value < 0)
|
||||||
|
{
|
||||||
|
__instance.Value = __instance.Values.Length - 1;
|
||||||
|
}
|
||||||
|
__instance.OnValueChanged.Invoke(__instance);
|
||||||
|
__instance.AdjustButtonsActiveState();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPrefix]
|
[HarmonyPrefix]
|
||||||
@@ -68,19 +151,9 @@ public static class OptionsPatches
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
__instance.TitleText.text =
|
__instance.TitleText.text = TranslationController.Instance.GetString(__instance.Title, Array.Empty<Object>());
|
||||||
TranslationController.Instance.GetString(__instance.Title, Array.Empty<Object>());
|
__instance.ValueText.text = TranslationController.Instance.GetString(__instance.Values[__instance.Value], Array.Empty<Object>());
|
||||||
__instance.ValueText.text = TranslationController.Instance.GetString(
|
|
||||||
__instance.Values[__instance.Value],
|
|
||||||
Array.Empty<Object>());
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPrefix]
|
|
||||||
[HarmonyPatch(typeof(StringOption), nameof(StringOption.UpdateValue))]
|
|
||||||
public static bool StringUpdate(StringOption __instance)
|
|
||||||
{
|
|
||||||
return !__instance.IsCustom();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
@@ -83,7 +84,52 @@ public static class Extensions
|
|||||||
analytics.MinigameClosed(data, taskType, realtimeSinceStartup, isComplete);
|
analytics.MinigameClosed(data, taskType, realtimeSinceStartup, isComplete);
|
||||||
self.StartCoroutine(self.CoDestroySelf());
|
self.StartCoroutine(self.CoDestroySelf());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the cooldown of a button with a formatted string.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="button">The ActionButton to set the cooldown for.</param>
|
||||||
|
/// <param name="timer">The current timer value.</param>
|
||||||
|
/// <param name="maxTimer">The maximum timer value.</param>
|
||||||
|
/// <param name="format">The format string to use for the timer text.</param>
|
||||||
|
public static void SetCooldownFormat(this ActionButton button, float timer, float maxTimer, string format="0")
|
||||||
|
{
|
||||||
|
var num = Mathf.Clamp(timer / maxTimer, 0f, 1f);
|
||||||
|
button.isCoolingDown = num > 0f;
|
||||||
|
button.SetCooldownFill(num);
|
||||||
|
if (button.isCoolingDown)
|
||||||
|
{
|
||||||
|
button.cooldownTimerText.text = timer.ToString(format, NumberFormatInfo.InvariantInfo);
|
||||||
|
button.cooldownTimerText.gameObject.SetActive(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
button.cooldownTimerText.gameObject.SetActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the fill-up variant of a cooldown button with a formatted string.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="button">The ActionButton to set the cooldown for.</param>
|
||||||
|
/// <param name="timer">The current timer value.</param>
|
||||||
|
/// <param name="maxTimer">The maximum timer value.</param>
|
||||||
|
/// <param name="format">The format string to use for the timer text.</param>
|
||||||
|
public static void SetFillUpFormat(this ActionButton button, float timer, float maxTimer, string format="0")
|
||||||
|
{
|
||||||
|
var num = Mathf.Clamp(timer / maxTimer, 0f, 1f);
|
||||||
|
button.isCoolingDown = num > 0f;
|
||||||
|
if (button.isCoolingDown && timer < 3f)
|
||||||
|
{
|
||||||
|
button.graphic.transform.localPosition = button.position + (Vector3)UnityEngine.Random.insideUnitCircle * 0.05f;
|
||||||
|
button.cooldownTimerText.text = timer.ToString(format, NumberFormatInfo.InvariantInfo);
|
||||||
|
button.cooldownTimerText.gameObject.SetActive(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
button.graphic.transform.localPosition = button.position;
|
||||||
|
}
|
||||||
|
button.SetCooldownFill(num);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a PlayerControl from their PlayerVoteArea in a meeting.
|
/// Gets a PlayerControl from their PlayerVoteArea in a meeting.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -145,6 +191,12 @@ public static class Extensions
|
|||||||
return component;
|
return component;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the maximum value from a dictionary of integers, returning the key and value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="self">The dictionary to search.</param>
|
||||||
|
/// <param name="tie">Whether there is a tie for the maximum value.</param>
|
||||||
|
/// <returns>The key-value pair with the maximum value.</returns>
|
||||||
public static KeyValuePair<byte, int> MaxPair(this Dictionary<byte, int> self, out bool tie)
|
public static KeyValuePair<byte, int> MaxPair(this Dictionary<byte, int> self, out bool tie)
|
||||||
{
|
{
|
||||||
tie = true;
|
tie = true;
|
||||||
@@ -164,6 +216,12 @@ public static class Extensions
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the maximum value from a dictionary of floats, returning the key and value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="self">The dictionary to search.</param>
|
||||||
|
/// <param name="tie">Whether there is a tie for the maximum value.</param>
|
||||||
|
/// <returns>The key-value pair with the maximum value.</returns>
|
||||||
public static KeyValuePair<byte, float> MaxPair(this Dictionary<byte, float> self, out bool tie)
|
public static KeyValuePair<byte, float> MaxPair(this Dictionary<byte, float> self, out bool tie)
|
||||||
{
|
{
|
||||||
tie = true;
|
tie = true;
|
||||||
@@ -385,18 +443,6 @@ public static class Extensions
|
|||||||
return new Color(color.r - amount, color.g - amount, color.b - amount);
|
return new Color(color.r - amount, color.g - amount, color.b - amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets an alternate color based on the original color.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="color">The original color.</param>
|
|
||||||
/// <param name="amount">The amount to darken or lighten the original color by between 0.0 and 1.0.</param>
|
|
||||||
/// <returns>An alternate color that has been darkened or lightened.</returns>
|
|
||||||
[Obsolete("Use FindAlternateColor for WACG compliance.")]
|
|
||||||
public static Color GetAlternateColor(this Color color, float amount = 0.45f)
|
|
||||||
{
|
|
||||||
return color.IsColorDark() ? LightenColor(color, amount) : DarkenColor(color, amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Lightens a color by a specified amount.
|
/// Lightens a color by a specified amount.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -408,16 +454,6 @@ public static class Extensions
|
|||||||
return new Color(color.r + amount, color.g + amount, color.b + amount);
|
return new Color(color.r + amount, color.g + amount, color.b + amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Checks if a color is dark.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="color">The color to check.</param>
|
|
||||||
/// <returns>True if the color is dark, false otherwise.</returns>
|
|
||||||
public static bool IsColorDark(this Color color)
|
|
||||||
{
|
|
||||||
return color.r < 0.5f && color is { g: < 0.5f, b: < 0.5f };
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the nearest dead body to a player.
|
/// Gets the nearest dead body to a player.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
Reference in new issue
Block a user