Files
TommyXL 7929a4b83e Optimization (Part 1?) (#589)
* Well lets try check this

* Some changes

* Change

* Well

* Change ControllerManager.Update

* Nothing

* Optimaze more?

* Fix error build

* Fix win check

* Change

* Fix

* Optimaze some roles in OnCheckPlayerPosition

* More optimaze

* Full optimaze roles in OnGlobalFixedUpdate

* Optimaze some add-ons

* ProgressText

* Change

* Optimaze NameNotifyManager

* Optimaze NotifyRoles and some roles

* Move the displayed version

* Some changes

* Optimaze OnFixedUpdate in some roles

* Fix bugs

* Optimaze IsActive & V4 version

* Optimaze MapRoom.DoorsUpdate

* Cache TryCatch in IsActive

* Change

* Fix

* More optimze TaskPanelBehaviour

* Cache GetRoleColor & ColorString & AllStringNames & Change RemoveHtmlTags

* Cache TryCast VentilationSystem & ICriticalSabotage & IUsable and more optimaze

* Fix CountAlivePlayers

* Fix exceptios

* Replace some CachedAllPlayerControls to EnumeratePlayerControls

* Replace some CachedAlivePlayerControls to EnumerateAlivePlayerControls

* Fixes

* Fix modded clients

* Fix errors

* Fix again

* Optimaze & add null check

* Fix crash in Starlight

* Use only Main.PluginVersion in LobbySharingAPI

* Optimaze code in FixedUpdate

* Fix

* Optimize GetProgressText for Roles

* Some changes in Translations

* Cache Enum.GetValues and StringBuilder

* Changes

* CustomRole.ColoredTextByRole()

* Optimaze Lobby & Meeting

* ColorStringPrefix => ColorPrefix

* Add null check

* Remove

* Fixes & optimaze

* Fixes

* Changes

* Fix

* Fix

* Fix

* Remove

* Fix

* Change

* Revert
2026-05-15 20:01:54 +02:00

354 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
namespace EHR.Modules.Extensions;
public static class FastVector2
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool Contains2D(this Bounds b, Vector2 p)
{
return
p.x >= b.min.x && p.x <= b.max.x &&
p.y >= b.min.y && p.y <= b.max.y;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool DistanceWithinRange(in Vector2 a, in Vector2 b, float range)
{
float dx = a.x - b.x;
float dy = a.y - b.y;
return dx * dx + dy * dy <= range * range;
}
/// <summary>
/// Finds all living players from origin in a given range.
/// </summary>
public static IEnumerable<PlayerControl> GetPlayersInRange(Vector2 origin, float range, Predicate<PlayerControl> predicate = null)
{
predicate ??= _ => true;
float rangeSq = range * range;
var players = Main.CachedAlivePlayerControls();
for (byte playerIndex = 0; playerIndex < players.Count; playerIndex++)
{
PlayerControl pc = players[playerIndex];
if (pc.inVent || !predicate(pc)) continue;
Vector2 p = pc.Pos();
float dx = p.x - origin.x;
float dy = p.y - origin.y;
float sq = dx * dx + dy * dy;
if (sq > rangeSq) continue;
yield return pc;
}
}
/// <summary>
/// Finds the closest position to origin within the given range.
/// Returns true if one was found.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryGetClosestInRange(
in Vector2 origin,
IEnumerable<Vector2> positions,
float range,
out Vector2 closest)
{
float rangeSq = range * range;
float minSq = float.MaxValue;
bool found = false;
closest = default(Vector2);
foreach (Vector2 p in positions)
{
float dx = p.x - origin.x;
float dy = p.y - origin.y;
float sq = dx * dx + dy * dy;
if (sq > rangeSq) continue;
if (sq < minSq)
{
minSq = sq;
closest = p;
found = true;
}
}
return found;
}
/// <summary>
/// Finds the closest position to origin.
/// Returns true if one was found.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryGetClosest(
in Vector2 origin,
IEnumerable<Vector2> positions,
out Vector2 closest)
{
float minSq = float.MaxValue;
bool found = false;
closest = default(Vector2);
foreach (Vector2 p in positions)
{
float dx = p.x - origin.x;
float dy = p.y - origin.y;
float sq = dx * dx + dy * dy;
if (sq < minSq)
{
minSq = sq;
closest = p;
found = true;
}
}
return found;
}
/// <summary>
/// Finds the closest living player to origin.
/// Returns true if one was found.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryGetClosestPlayer(
in Vector2 origin,
out PlayerControl closest,
[Annotations.InstantHandle] Predicate<PlayerControl> predicate = null)
{
predicate ??= _ => true;
float minSq = float.MaxValue;
bool found = false;
closest = null;
var players = Main.CachedAlivePlayerControls();
for (byte playerIndex = 0; playerIndex < players.Count; playerIndex++)
{
PlayerControl pc = players[playerIndex];
if (pc.inVent || !predicate(pc)) continue;
Vector2 p = pc.Pos();
float dx = p.x - origin.x;
float dy = p.y - origin.y;
float sq = dx * dx + dy * dy;
if (sq < minSq)
{
minSq = sq;
closest = pc;
found = true;
}
}
return found;
}
/// <summary>
/// Finds the closest living player to the source player, exempting themselves.
/// Returns true if one was found.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryGetClosestPlayerTo(
in PlayerControl source,
out PlayerControl closest,
[Annotations.InstantHandle] Predicate<PlayerControl> predicate = null)
{
predicate ??= _ => true;
Vector2 origin = source.Pos();
float minSq = float.MaxValue;
bool found = false;
closest = null;
var players = Main.CachedAlivePlayerControls();
for (byte playerIndex = 0; playerIndex < players.Count; playerIndex++)
{
PlayerControl pc = players[playerIndex];
if (pc.inVent || pc.PlayerId == source.PlayerId || !predicate(pc)) continue;
Vector2 p = pc.Pos();
float dx = p.x - origin.x;
float dy = p.y - origin.y;
float sq = dx * dx + dy * dy;
if (sq < minSq)
{
minSq = sq;
closest = pc;
found = true;
}
}
return found;
}
/// <summary>
/// Finds the closest living player to the source player within the given range, exempting themselves.
/// Returns true if one was found.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryGetClosestPlayerInRangeTo(
in PlayerControl source,
float range,
out PlayerControl closest,
[Annotations.InstantHandle] Predicate<PlayerControl> predicate = null)
{
predicate ??= _ => true;
Vector2 origin = source.Pos();
float rangeSq = range * range;
float minSq = float.MaxValue;
bool found = false;
closest = null;
var players = Main.CachedAlivePlayerControls();
for (byte playerIndex = 0; playerIndex < players.Count; playerIndex++)
{
PlayerControl pc = players[playerIndex];
if (pc.inVent || pc.PlayerId == source.PlayerId || !predicate(pc)) continue;
Vector2 p = pc.Pos();
float dx = p.x - origin.x;
float dy = p.y - origin.y;
float sq = dx * dx + dy * dy;
if (sq > rangeSq) continue;
if (sq < minSq)
{
minSq = sq;
closest = pc;
found = true;
}
}
return found;
}
/// <summary>
/// Finds the closest living player to origin within the given range.
/// Returns true if one was found.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryGetClosestPlayerInRange(
in Vector2 origin,
float range,
out PlayerControl closest,
Predicate<PlayerControl> predicate = null)
{
predicate ??= _ => true;
float rangeSq = range * range;
float minSq = float.MaxValue;
bool found = false;
closest = null;
var players = Main.CachedAlivePlayerControls();
for (byte playerIndex = 0; playerIndex < players.Count; playerIndex++)
{
PlayerControl pc = players[playerIndex];
if (pc.inVent || !predicate(pc)) continue;
Vector2 p = pc.Pos();
float dx = p.x - origin.x;
float dy = p.y - origin.y;
float sq = dx * dx + dy * dy;
if (sq > rangeSq) continue;
if (sq < minSq)
{
minSq = sq;
closest = pc;
found = true;
}
}
return found;
}
/// <summary>
/// Finds the closest position to origin within the given range from the values of the given dictionary,
/// and returns the key assiciated with it in the dictionary.
/// Returns true if one was found.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryGetClosestInRange<T>(
in Vector2 origin,
Dictionary<T, Vector2> positions,
float range,
out T closest,
Predicate<T> predicate = null)
{
predicate ??= _ => true;
float rangeSq = range * range;
float minSq = float.MaxValue;
bool found = false;
closest = default(T);
foreach ((T t, Vector2 p) in positions)
{
if (!predicate(t)) continue;
float dx = p.x - origin.x;
float dy = p.y - origin.y;
float sq = dx * dx + dy * dy;
if (sq > rangeSq) continue;
if (sq < minSq)
{
minSq = sq;
closest = t;
found = true;
}
}
return found;
}
/// <summary>
/// Finds the closest position to origin within the given range from the keys of the given dictionary,
/// and returns the value assiciated with it in the dictionary.
/// Returns true if one was found.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryGetClosestInRange<T>(
in Vector2 origin,
Dictionary<Vector2, T> positions,
float range,
out T closest,
Predicate<T> predicate = null)
{
predicate ??= _ => true;
float rangeSq = range * range;
float minSq = float.MaxValue;
bool found = false;
closest = default(T);
foreach ((Vector2 p, T t) in positions)
{
if (!predicate(t)) continue;
float dx = p.x - origin.x;
float dy = p.y - origin.y;
float sq = dx * dx + dy * dy;
if (sq > rangeSq) continue;
if (sq < minSq)
{
minSq = sq;
closest = t;
found = true;
}
}
return found;
}
}