mirror of
https://github.com/All-Of-Us-Mods/MiraAPI.git
synced 2026-10-19 15:51:48 +00:00
document Extensions.cs
This commit is contained in:
1 parent
b139fbe51d
commit
592e636903
5 files changed
+153
-32
No files matched your search
@@ -22,6 +22,5 @@ public partial class ExamplePlugin : BasePlugin, IMiraPlugin
|
||||
public override void Load()
|
||||
{
|
||||
Harmony.PatchAll();
|
||||
AddComponent<MiraDebugWindow>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ public class MiraDebugWindow(IntPtr ptr) : MonoBehaviour(ptr)
|
||||
}
|
||||
})
|
||||
{
|
||||
Enabled = true
|
||||
Enabled = true,
|
||||
};
|
||||
|
||||
public void OnGUI()
|
||||
|
||||
@@ -52,7 +52,7 @@ public static class ModifierManager
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!plrs.Any(x=>IsGameModifierValid(x, mod, modifier.Key)))
|
||||
if (!plrs.Exists(x=>IsGameModifierValid(x, mod, modifier.Key)))
|
||||
{
|
||||
Logger<MiraApiPlugin>.Warning("No players are valid for modifier: " + mod.ModifierName);
|
||||
continue;
|
||||
@@ -79,25 +79,25 @@ public static class ModifierManager
|
||||
{
|
||||
shuffledModifiers = shuffledModifiers.GetRange(0, plrs.Count);
|
||||
}
|
||||
|
||||
|
||||
while (shuffledModifiers.Count > 0)
|
||||
{
|
||||
var id = shuffledModifiers[0];
|
||||
|
||||
var mod = (GameModifier)Activator.CreateInstance(IdToTypeModifiers[id]);
|
||||
|
||||
|
||||
if (mod is null)
|
||||
{
|
||||
Logger<MiraApiPlugin>.Error($"Failed to create instance of {IdToTypeModifiers[id].Name}");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!plrs.Any(x=>IsGameModifierValid(x, mod, id)))
|
||||
|
||||
if (!plrs.Exists(x=>IsGameModifierValid(x, mod, id)))
|
||||
{
|
||||
shuffledModifiers.RemoveAt(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
var plr = plrs.Random();
|
||||
|
||||
if (!IsGameModifierValid(plr, mod, id))
|
||||
|
||||
+144
-22
@@ -35,13 +35,29 @@ public static class Extensions
|
||||
return type is { IsClass: true, IsAbstract: true, IsSealed: true };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a darkened version of a color.
|
||||
/// </summary>
|
||||
/// <param name="color">The original color.</param>
|
||||
/// <param name="darknessAmount">A darkness amount between 0 and 255.</param>
|
||||
/// <returns>The darkened color.</returns>
|
||||
public static Color32 GetShadowColor(this Color32 color, byte darknessAmount)
|
||||
{
|
||||
return
|
||||
new Color32((byte)Mathf.Clamp(color.r - darknessAmount, 0, 255), (byte)Mathf.Clamp(color.g - darknessAmount, 0, 255),
|
||||
(byte)Mathf.Clamp(color.b - darknessAmount, 0, 255), byte.MaxValue);
|
||||
new Color32(
|
||||
(byte)Mathf.Clamp(color.r - darknessAmount, 0, 255),
|
||||
(byte)Mathf.Clamp(color.g - darknessAmount, 0, 255),
|
||||
(byte)Mathf.Clamp(color.b - darknessAmount, 0, 255),
|
||||
byte.MaxValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Truncates a string to a specified length.
|
||||
/// </summary>
|
||||
/// <param name="value">The original string.</param>
|
||||
/// <param name="maxLength">The maximum length.</param>
|
||||
/// <param name="truncationSuffix">An option suffix to attach at the end of the truncated string.</param>
|
||||
/// <returns>A truncated string of maxLength with the attached suffix.</returns>
|
||||
public static string? Truncate(this string? value, int maxLength, string truncationSuffix = "…")
|
||||
{
|
||||
return value?.Length > maxLength
|
||||
@@ -49,6 +65,12 @@ public static class Extensions
|
||||
: value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Chunks a collection of NetData into smaller arrays.
|
||||
/// </summary>
|
||||
/// <param name="dataCollection">A collection of NetData objects.</param>
|
||||
/// <param name="chunkSize">The max chunk size in bytes.</param>
|
||||
/// <returns>A Queue of NetData arrays.</returns>
|
||||
public static Queue<NetData[]> ChunkNetData(this IEnumerable<NetData> dataCollection, int chunkSize)
|
||||
{
|
||||
Queue<NetData[]> chunks = [];
|
||||
@@ -83,14 +105,23 @@ public static class Extensions
|
||||
return chunks;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Determines if a given OptionBehaviour is for a custom option.
|
||||
/// </summary>
|
||||
/// <param name="optionBehaviour">The OptionBehaviour to be tested.</param>
|
||||
/// <returns>True if the OptionBehaviour is for a custom options, false otherwise.</returns>
|
||||
public static bool IsCustom(this OptionBehaviour optionBehaviour)
|
||||
{
|
||||
return ModdedOptionsManager.ModdedOptions.Values.Any(opt => opt.OptionBehaviour && opt.OptionBehaviour.Equals(optionBehaviour));
|
||||
}
|
||||
|
||||
public static readonly Dictionary<PlayerControl, ModifierComponent> ModifierComponents = new();
|
||||
private static readonly Dictionary<PlayerControl, ModifierComponent> ModifierComponents = [];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ModifierComponent for a player.
|
||||
/// </summary>
|
||||
/// <param name="player">The PlayerControl object.</param>
|
||||
/// <returns>A ModifierComponent if there is one, null otherwise.</returns>
|
||||
public static ModifierComponent? GetModifierComponent(this PlayerControl player)
|
||||
{
|
||||
if (ModifierComponents.TryGetValue(player, out var component))
|
||||
@@ -107,6 +138,12 @@ public static class Extensions
|
||||
return component;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Randomizes a list.
|
||||
/// </summary>
|
||||
/// <param name="list">The list object.</param>
|
||||
/// <typeparam name="T">The type of object the list contains.</typeparam>
|
||||
/// <returns>A randomized list made from the original list.</returns>
|
||||
public static List<T> Randomize<T>(this List<T> list)
|
||||
{
|
||||
List<T> randomizedList = [];
|
||||
@@ -120,39 +157,88 @@ public static class Extensions
|
||||
return randomizedList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a modifier by its type, or null if the player doesn't have it.
|
||||
/// </summary>
|
||||
/// <param name="player">The PlayerControl object.</param>
|
||||
/// <typeparam name="T">The Type of the Modifier.</typeparam>
|
||||
/// <returns>The Modifier if it is found, null otherwise.</returns>
|
||||
public static T? GetModifier<T>(this PlayerControl? player) where T : BaseModifier
|
||||
{
|
||||
return player?.GetModifierComponent()?.ActiveModifiers.Find(x => x is T) as T;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a player has a modifier.
|
||||
/// </summary>
|
||||
/// <param name="player">The PlayerControl object.</param>
|
||||
/// <typeparam name="T">The Type of the Modifier.</typeparam>
|
||||
/// <returns>True if the Modifier is present, false otherwise.</returns>
|
||||
public static bool HasModifier<T>(this PlayerControl? player) where T : BaseModifier
|
||||
{
|
||||
return player?.GetModifierComponent() != null && player.GetModifierComponent()!.ActiveModifiers.Exists(x => x is T);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a player has a modifier by its ID.
|
||||
/// </summary>
|
||||
/// <param name="player">The PlayerControl object.</param>
|
||||
/// <param name="id">The Modifier ID.</param>
|
||||
/// <returns>True if the Modifier is present, false otherwise.</returns>
|
||||
public static bool HasModifier(this PlayerControl? player, uint id)
|
||||
{
|
||||
return player?.GetModifierComponent() != null && player.GetModifierComponent()!.ActiveModifiers.Exists(x => x.ModifierId == id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remote Procedure Call to remove a modifier from a player.
|
||||
/// </summary>
|
||||
/// <param name="target">The player to remove the modifier from.</param>
|
||||
/// <param name="modifierId">The ID of the modifier.</param>
|
||||
[MethodRpc((uint)MiraRpc.RemoveModifier)]
|
||||
public static void RpcRemoveModifier(this PlayerControl target, uint modifierId)
|
||||
{
|
||||
target.GetModifierComponent()?.RemoveModifier(modifierId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remote Procedure Call to remove a modifier from a player.
|
||||
/// </summary>
|
||||
/// <param name="player">The player to remove the modifier from.</param>
|
||||
/// <typeparam name="T">The Type of the Modifier.</typeparam>
|
||||
public static void RpcRemoveModifier<T>(this PlayerControl player) where T : BaseModifier
|
||||
{
|
||||
if (!ModifierManager.TypeToIdModifiers.TryGetValue(typeof(T), out var id))
|
||||
{
|
||||
Logger<MiraApiPlugin>.Error($"Cannot add modifier {typeof(T).Name} because it is not registered.");
|
||||
return;
|
||||
}
|
||||
|
||||
player.RpcRemoveModifier(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remote Procedure Call to add a modifier to a player.
|
||||
/// </summary>
|
||||
/// <param name="target">The player to add the modifier to.</param>
|
||||
/// <param name="modifierId">The modifier ID.</param>
|
||||
[MethodRpc((uint)MiraRpc.AddModifier)]
|
||||
public static BaseModifier? RpcAddModifier(this PlayerControl target, uint modifierId)
|
||||
public static void RpcAddModifier(this PlayerControl target, uint modifierId)
|
||||
{
|
||||
if (ModifierManager.IdToTypeModifiers.TryGetValue(modifierId, out var type))
|
||||
{
|
||||
return target.GetModifierComponent()?.AddModifier(type);
|
||||
target.GetModifierComponent()?.AddModifier(type);
|
||||
return;
|
||||
}
|
||||
|
||||
Logger<MiraApiPlugin>.Error($"Cannot add modifier with id {modifierId} because it is not registered.");
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remote Procedure Call to add a modifier to a player.
|
||||
/// </summary>
|
||||
/// <param name="player">The player to add the modifier to.</param>
|
||||
/// <typeparam name="T">The modifier Type.</typeparam>
|
||||
public static void RpcAddModifier<T>(this PlayerControl player) where T : BaseModifier
|
||||
{
|
||||
if (!ModifierManager.TypeToIdModifiers.TryGetValue(typeof(T), out var id))
|
||||
@@ -164,46 +250,82 @@ public static class Extensions
|
||||
player.RpcAddModifier(id);
|
||||
}
|
||||
|
||||
public static void RpcRemoveModifier<T>(this PlayerControl player) where T : BaseModifier
|
||||
{
|
||||
if (!ModifierManager.TypeToIdModifiers.TryGetValue(typeof(T), out var id))
|
||||
{
|
||||
Logger<MiraApiPlugin>.Error($"Cannot add modifier {typeof(T).Name} because it is not registered.");
|
||||
return;
|
||||
}
|
||||
|
||||
player.RpcAddModifier(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Darkens a color by a specified amount.
|
||||
/// </summary>
|
||||
/// <param name="color">The original color.</param>
|
||||
/// <param name="amount">A float amount between 0 and 1.</param>
|
||||
/// <returns>The darkened color.</returns>
|
||||
public static Color DarkenColor(this Color color, float amount = 0.45f)
|
||||
{
|
||||
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>
|
||||
public static Color GetAlternateColor(this Color color, float amount = 0.45f)
|
||||
{
|
||||
return color.IsColorDark() ? LightenColor(color, amount) : DarkenColor(color, amount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lightens a color by a specified amount.
|
||||
/// </summary>
|
||||
/// <param name="color">The original color.</param>
|
||||
/// <param name="amount">A float amount between 0.0 and 1.0.</param>
|
||||
/// <returns>The lightened color.</returns>
|
||||
public static Color LightenColor(this Color color, float amount = 0.45f)
|
||||
{
|
||||
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>
|
||||
/// Gets the nearest dead body to a player.
|
||||
/// </summary>
|
||||
/// <param name="playerControl">The player object.</param>
|
||||
/// <param name="radius">The radius to search within.</param>
|
||||
/// <returns>The dead body if it is found, or null there is none within the radius.</returns>
|
||||
public static DeadBody? GetNearestDeadBody(this PlayerControl playerControl, float radius)
|
||||
{
|
||||
return Helpers.GetNearestDeadBodies(playerControl.GetTruePosition(), radius).FirstOrDefault(component => component && !component.Reported);
|
||||
return Helpers.GetNearestDeadBodies(playerControl.GetTruePosition(), radius).Find(component => component && !component.Reported);
|
||||
}
|
||||
|
||||
public static T? GetNearestObjectOfType<T>(this PlayerControl playerControl, float radius, string? colliderTag = null, System.Func<T, bool>? predicate = null) where T : Component
|
||||
/// <summary>
|
||||
/// Finds the nearest object of a specified type to a player. It will only work if the object has a collider.
|
||||
/// </summary>
|
||||
/// <param name="playerControl">The player object.</param>
|
||||
/// <param name="radius">The radius to search within.</param>
|
||||
/// <param name="colliderTag">An optional collider tag.</param>
|
||||
/// <param name="predicate">Optional predicate to test if the object is valid.</param>
|
||||
/// <typeparam name="T">The type of the object.</typeparam>
|
||||
/// <returns>The object if it was found, or null if there is none within the radius.</returns>
|
||||
public static T? GetNearestObjectOfType<T>(this PlayerControl playerControl, float radius, string? colliderTag = null, Predicate<T>? predicate = null) where T : Component
|
||||
{
|
||||
return Helpers.GetNearestObjectsOfType<T>(playerControl.GetTruePosition(), radius, colliderTag).FirstOrDefault(predicate ?? (component => component));
|
||||
return Helpers.GetNearestObjectsOfType<T>(playerControl.GetTruePosition(), radius, colliderTag).Find(predicate ?? (component => component));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the nearest player to a player.
|
||||
/// </summary>
|
||||
/// <param name="playerControl">The player object.</param>
|
||||
/// <param name="includeImpostors">Whether impostors should be included in the search.</param>
|
||||
/// <param name="distance">The radius to search within.</param>
|
||||
/// <param name="ignoreColliders">Whether colliders should be ignored when searching.</param>
|
||||
/// <returns>The closest player if there is one, false otherwise.</returns>
|
||||
public static PlayerControl? GetClosestPlayer(this PlayerControl playerControl, bool includeImpostors, float distance, bool ignoreColliders = false)
|
||||
{
|
||||
if (!ShipStatus.Instance)
|
||||
@@ -217,4 +339,4 @@ public static class Extensions
|
||||
|
||||
return filteredPlayers.First();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ public static class Helpers
|
||||
.Select(collider2D => collider2D.GetComponent<DeadBody>()).ToList();
|
||||
}
|
||||
|
||||
public static List<T> GetNearestObjectsOfType<T>(Vector2 source, float radius, string colliderTag = null) where T : Component
|
||||
public static List<T> GetNearestObjectsOfType<T>(Vector2 source, float radius, string? colliderTag = null) where T : Component
|
||||
{
|
||||
var results = new Il2CppSystem.Collections.Generic.List<Collider2D>();
|
||||
Physics2D.OverlapCircle(source, radius, Filter, results);
|
||||
|
||||
Reference in new issue
Block a user