mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-19 15:51:58 +00:00
Optimize & Cache GetPlainShipRoom + FastVector2.GetPlayersInRange
This commit is contained in:
1 parent
df70a2a7db
commit
5809b5ef7c
25 files changed
+221
-111
No files matched your search
+1
-1
@@ -267,7 +267,7 @@ resharper_foreach_can_be_converted_to_query_using_another_get_enumerator_highlig
|
||||
resharper_foreach_can_be_partly_converted_to_query_using_another_get_enumerator_highlighting = none
|
||||
resharper_inconsistent_naming_highlighting = suggestion
|
||||
resharper_invert_if_highlighting = none
|
||||
resharper_loop_can_be_converted_to_query_highlighting = warning
|
||||
resharper_loop_can_be_converted_to_query_highlighting = hint
|
||||
resharper_mvc_action_not_resolved_highlighting = warning
|
||||
resharper_mvc_area_not_resolved_highlighting = warning
|
||||
resharper_mvc_controller_not_resolved_highlighting = warning
|
||||
|
||||
@@ -1363,7 +1363,7 @@ public static class BedWars
|
||||
}
|
||||
}
|
||||
|
||||
PlayerControl[] playersInRadius = Utils.GetPlayersInRadius(ShopAndItemGeneratorRange, NetObject.Position).ToArray();
|
||||
PlayerControl[] playersInRadius = FastVector2.GetPlayersInRange(ShopAndItemGeneratorRange, NetObject.Position).ToArray();
|
||||
|
||||
foreach (PlayerControl pc in playersInRadius)
|
||||
{
|
||||
|
||||
@@ -397,7 +397,7 @@ public static class Deathrace
|
||||
PowerUp powerUp = data.PowerUps[0];
|
||||
pc.RPCPlayCustomSound("Line");
|
||||
data.PowerUps.RemoveAt(0);
|
||||
PlayerControl[] playersInRange = Utils.GetPlayersInRadius(PowerUpEffectRange, pc.Pos()).Without(pc).ToArray();
|
||||
PlayerControl[] playersInRange = FastVector2.GetPlayersInRange(PowerUpEffectRange, pc.Pos()).Without(pc).ToArray();
|
||||
|
||||
switch (powerUp)
|
||||
{
|
||||
|
||||
@@ -695,12 +695,11 @@ public static class NaturalDisasters
|
||||
{
|
||||
LastHit = now;
|
||||
var hit = new Vector2(Random.Range(MapBounds.X.Left, MapBounds.X.Right), Random.Range(MapBounds.Y.Bottom, MapBounds.Y.Top));
|
||||
var cno = new Lightning(hit);
|
||||
|
||||
if (cno.playerControl.GetPlainShipRoom() != null)
|
||||
cno.Despawn();
|
||||
else
|
||||
if (hit.GetPlainShipRoom() == null)
|
||||
{
|
||||
_ = new Lightning(hit);
|
||||
|
||||
foreach (PlayerControl pc in Main.EnumerateAlivePlayerControls())
|
||||
{
|
||||
if (FastVector2.DistanceWithinRange(pc.Pos(), hit, Range / 2f))
|
||||
@@ -984,11 +983,9 @@ public static class NaturalDisasters
|
||||
{
|
||||
if (pc.onLadder || pc.inMovingPlat || pc.MyPhysics.Animations.IsPlayingAnyLadderAnimation()) continue;
|
||||
|
||||
PlainShipRoom room = pc.GetPlainShipRoom();
|
||||
|
||||
if (room != null && CollapsedRooms.Exists(x => x == room))
|
||||
if (CollapsedRooms.FindFirst(x => pc.IsInRoom(x), out PlainShipRoom collapsedRoom))
|
||||
{
|
||||
if (LastPosition.TryGetValue(pc.PlayerId, out Vector2 lastPos))
|
||||
if (LastPosition.TryGetValue(pc.PlayerId, out Vector2 lastPos) && !lastPos.IsInRoom(collapsedRoom))
|
||||
{
|
||||
RPC.PlaySoundRPC(pc.PlayerId, Sounds.ImpDiscovered);
|
||||
pc.TP(lastPos);
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using AmongUs.GameOptions;
|
||||
@@ -2209,25 +2210,85 @@ internal static class ExtendedPlayerControl
|
||||
return killerId == byte.MaxValue ? null : GetPlayerById(killerId);
|
||||
}
|
||||
|
||||
private static readonly Dictionary<byte, PlainShipRoom> PlayerRoomCache = [];
|
||||
|
||||
[SuppressMessage("ReSharper", "ForCanBeConvertedToForeach")]
|
||||
public static PlainShipRoom GetPlainShipRoom(this PlayerControl pc)
|
||||
{
|
||||
if (!pc.IsAlive() || Pelican.IsEaten(pc.PlayerId)) return null;
|
||||
if (!pc.IsAlive()) return null;
|
||||
|
||||
Il2CppReferenceArray<PlainShipRoom> rooms = ShipStatus.Instance.AllRooms;
|
||||
return rooms.Where(room => room.roomArea).FirstOrDefault(room => pc.Collider.IsTouching(room.roomArea));
|
||||
byte id = pc.PlayerId;
|
||||
Vector3 pos = pc.Pos();
|
||||
|
||||
if (PlayerRoomCache.TryGetValue(id, out var cached))
|
||||
{
|
||||
var area = cached.roomArea;
|
||||
if (area && area.bounds.Contains(pos)) return cached;
|
||||
}
|
||||
|
||||
var rooms = ShipStatus.Instance.AllRooms;
|
||||
for (int i = 0; i < rooms.Count; i++)
|
||||
{
|
||||
var room = rooms[i];
|
||||
var area = room.roomArea;
|
||||
|
||||
if (area && area.bounds.Contains(pos))
|
||||
{
|
||||
PlayerRoomCache[id] = room;
|
||||
return room;
|
||||
}
|
||||
}
|
||||
|
||||
PlayerRoomCache.Remove(id);
|
||||
return null;
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "ForCanBeConvertedToForeach")]
|
||||
public static PlainShipRoom GetPlainShipRoom(this Vector2 pos)
|
||||
{
|
||||
var rooms = ShipStatus.Instance.AllRooms;
|
||||
for (int i = 0; i < rooms.Count; i++)
|
||||
{
|
||||
var room = rooms[i];
|
||||
var area = room.roomArea;
|
||||
|
||||
if (area && area.bounds.Contains(pos))
|
||||
return room;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static bool IsInRoom(this Vector2 pos, PlainShipRoom room)
|
||||
{
|
||||
if (room == null) return false;
|
||||
var roomArea = room.roomArea;
|
||||
return roomArea && roomArea.bounds.Contains(pos);
|
||||
}
|
||||
|
||||
public static bool IsInRoom(this Vector2 pos, SystemTypes roomId)
|
||||
{
|
||||
PlainShipRoom room = roomId.GetRoomClass();
|
||||
if (room == null) return false;
|
||||
var roomArea = room.roomArea;
|
||||
return roomArea && roomArea.bounds.Contains(pos);
|
||||
}
|
||||
|
||||
public static bool IsInRoom(this PlayerControl pc, PlainShipRoom room)
|
||||
{
|
||||
if (room == null || !room.roomArea) return false;
|
||||
return pc.IsAlive() && pc.Collider.IsTouching(room.roomArea);
|
||||
if (room == null) return false;
|
||||
var roomArea = room.roomArea;
|
||||
if (!roomArea) return false;
|
||||
return pc.IsAlive() && roomArea.bounds.Contains(pc.Pos());
|
||||
}
|
||||
|
||||
public static bool IsInRoom(this PlayerControl pc, SystemTypes roomId)
|
||||
{
|
||||
if (!pc.IsAlive()) return false;
|
||||
PlainShipRoom room = roomId.GetRoomClass();
|
||||
return room != null && room.roomArea && pc.Collider.IsTouching(room.roomArea);
|
||||
if (room == null) return false;
|
||||
var roomArea = room.roomArea;
|
||||
return roomArea && roomArea.bounds.Contains(pc.Pos());
|
||||
}
|
||||
|
||||
public static PlainShipRoom GetRoomClass(this SystemTypes systemTypes)
|
||||
|
||||
@@ -13,6 +13,28 @@ public static class FastVector2
|
||||
return dx * dx + dy * dy <= range * range;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds all living players from origin in a given range
|
||||
/// </summary>
|
||||
public static IEnumerable<PlayerControl> GetPlayersInRange(float range, Vector2 origin)
|
||||
{
|
||||
float rangeSq = range * range;
|
||||
|
||||
foreach (PlayerControl pc in Main.EnumerateAlivePlayerControls())
|
||||
{
|
||||
if (pc.inVent) 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.
|
||||
@@ -48,6 +70,43 @@ public static class FastVector2
|
||||
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)
|
||||
{
|
||||
float rangeSq = range * range;
|
||||
float minSq = float.MaxValue;
|
||||
bool found = false;
|
||||
closest = null;
|
||||
|
||||
foreach (PlayerControl pc in Main.EnumerateAlivePlayerControls())
|
||||
{
|
||||
if (pc.inVent) 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.
|
||||
|
||||
+5
-5
@@ -2457,16 +2457,16 @@ public static class Utils
|
||||
|
||||
foreach (PlayerControl pc in Main.EnumerateAlivePlayerControls())
|
||||
{
|
||||
if (!pc.IsAlive() || Pelican.IsEaten(pc.PlayerId)) return null;
|
||||
if (!pc.IsAlive()) return null;
|
||||
|
||||
Vector3 position = pc.Pos();
|
||||
Il2CppReferenceArray<PlainShipRoom> rooms = ShipStatus.Instance.AllRooms;
|
||||
if (rooms == null) return null;
|
||||
|
||||
foreach (PlainShipRoom room in rooms)
|
||||
{
|
||||
if (!room.roomArea) continue;
|
||||
|
||||
if (!pc.Collider.IsTouching(room.roomArea)) continue;
|
||||
var roomArea = room.roomArea;
|
||||
if (!roomArea) continue;
|
||||
if (!roomArea.bounds.Contains(position)) continue;
|
||||
|
||||
string roomName = GetString($"{room.RoomId}");
|
||||
if (!playerRooms.TryAdd(roomName, 1)) playerRooms[roomName]++;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Linq;
|
||||
using AmongUs.GameOptions;
|
||||
using EHR.Modules;
|
||||
using EHR.Modules.Extensions;
|
||||
using Hazel;
|
||||
|
||||
namespace EHR.Roles;
|
||||
@@ -61,7 +62,7 @@ public class Banshee : CovenBase
|
||||
{
|
||||
float radius = Radius.GetFloat();
|
||||
Vector2 pos = pc.Pos();
|
||||
IEnumerable<PlayerControl> nearbyPlayers = Utils.GetPlayersInRadius(radius, pos).Without(pc);
|
||||
IEnumerable<PlayerControl> nearbyPlayers = FastVector2.GetPlayersInRange(radius, pos).Without(pc);
|
||||
|
||||
if (!HasNecronomicon) ScreechedPlayers = nearbyPlayers.Select(x => x.PlayerId).ToHashSet();
|
||||
else nearbyPlayers.Do(x => x.Suicide(PlayerState.DeathReason.Deafened, pc));
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using EHR.Modules;
|
||||
using EHR.Modules.Extensions;
|
||||
using Hazel;
|
||||
|
||||
namespace EHR.Roles;
|
||||
@@ -82,11 +83,7 @@ public class Dreamweaver : CovenBase
|
||||
{
|
||||
if (lowLoad || GameStates.IsMeeting || ExileController.Instance || !Main.IntroDestroyed || !pc.IsAlive() || !pc.Is(CustomRoles.Insane) || Main.KillTimers[pc.PlayerId] > 0f) return;
|
||||
|
||||
Vector2 pos = pc.Pos();
|
||||
PlayerControl[] nearbyPlayers = Utils.GetPlayersInRadius(1.5f, pos).Without(pc).ToArray();
|
||||
if (nearbyPlayers.Length == 0) return;
|
||||
|
||||
PlayerControl nearestPlayer = nearbyPlayers.MinBy(x => Vector2.Distance(x.Pos(), pos));
|
||||
if (!FastVector2.TryGetClosestPlayerInRange(pc.Pos(), 1.5f, out PlayerControl nearestPlayer)) return;
|
||||
|
||||
RoleBase roleBase = Main.PlayerStates[pc.PlayerId].Role;
|
||||
Type type = roleBase.GetType();
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AmongUs.GameOptions;
|
||||
using EHR.Modules.Extensions;
|
||||
|
||||
namespace EHR.Roles;
|
||||
|
||||
@@ -204,7 +205,7 @@ public class Empress : CovenBase
|
||||
|
||||
public override void OnPet(PlayerControl pc)
|
||||
{
|
||||
PlayerControl[] playersInRadius = Utils.GetPlayersInRadius(CoverageRange.GetFloat(), pc.Pos()).Where(x => x.Is(Team.Coven)).ToArray();
|
||||
PlayerControl[] playersInRadius = FastVector2.GetPlayersInRange(CoverageRange.GetFloat(), pc.Pos()).Where(x => x.Is(Team.Coven)).ToArray();
|
||||
float duration = CoverageDuration.GetFloat();
|
||||
float delay = CoverageDelay.GetFloat();
|
||||
LateTask.New(() =>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using EHR.Modules;
|
||||
using EHR.Modules.Extensions;
|
||||
using Hazel;
|
||||
|
||||
namespace EHR.Roles;
|
||||
@@ -14,7 +15,7 @@ public class Poache : CovenBase
|
||||
private static OptionItem CanVentAfterNecronomicon;
|
||||
|
||||
public static HashSet<byte> PoachedPlayers = [];
|
||||
private static List<(byte ID, long KillTimeStamp)> KillDelays = [];
|
||||
private static List<byte> KillDelays = [];
|
||||
|
||||
private byte PoacheId;
|
||||
|
||||
@@ -61,20 +62,20 @@ public class Poache : CovenBase
|
||||
PoachedPlayers.Add(target.PlayerId);
|
||||
Utils.SendRPC(CustomRPC.SyncRoleData, PoacheId, 1, target.PlayerId);
|
||||
}
|
||||
else KillDelays.Add((target.PlayerId, Utils.TimeStamp + KillDelay.GetInt()));
|
||||
else
|
||||
{
|
||||
KillDelays.Add(target.PlayerId);
|
||||
_ = new CountdownTimer(KillDelay.GetInt(), () =>
|
||||
{
|
||||
if (!KillDelays.Remove(target.PlayerId)) return;
|
||||
target.Suicide(PlayerState.DeathReason.Poison, realKiller: killer);
|
||||
}, onCanceled: () => KillDelays.Remove(target.PlayerId));
|
||||
}
|
||||
|
||||
killer.SetKillCooldown(AbilityCooldown.GetFloat());
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnGlobalFixedUpdate(PlayerControl pc, bool lowLoad)
|
||||
{
|
||||
if (lowLoad || GameStates.IsMeeting || ExileController.Instance || !Main.IntroDestroyed || !pc.IsAlive() || !KillDelays.FindFirst(x => x.ID == pc.PlayerId, out (byte ID, long KillTimeStamp) killData) || Utils.TimeStamp < killData.KillTimeStamp) return;
|
||||
|
||||
pc.Suicide(PlayerState.DeathReason.Poison, realKiller: PoacheId.GetPlayer());
|
||||
KillDelays.Remove(killData);
|
||||
}
|
||||
|
||||
public override void AfterMeetingTasks()
|
||||
{
|
||||
PoachedPlayers.Clear();
|
||||
@@ -83,7 +84,7 @@ public class Poache : CovenBase
|
||||
|
||||
public override void OnReportDeadBody()
|
||||
{
|
||||
KillDelays.ForEach(x => x.ID.GetPlayer()?.Suicide(PlayerState.DeathReason.Poison, realKiller: PoacheId.GetPlayer()));
|
||||
KillDelays.ForEach(x => x.GetPlayer()?.Suicide(PlayerState.DeathReason.Poison, realKiller: PoacheId.GetPlayer()));
|
||||
KillDelays.Clear();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AmongUs.GameOptions;
|
||||
using EHR.Modules.Extensions;
|
||||
|
||||
namespace EHR.Roles;
|
||||
|
||||
@@ -37,7 +38,7 @@ public class Siren : CovenBase
|
||||
"ECMO.OriginalTeam"
|
||||
];
|
||||
|
||||
private Dictionary<byte, long> EffectEndTS;
|
||||
private HashSet<byte> AffectedPlayers;
|
||||
private byte SirenId;
|
||||
|
||||
private Dictionary<byte, int> Stages;
|
||||
@@ -75,7 +76,7 @@ public class Siren : CovenBase
|
||||
{
|
||||
On = true;
|
||||
Stages = [];
|
||||
EffectEndTS = [];
|
||||
AffectedPlayers = [];
|
||||
SirenId = playerId;
|
||||
Instances.Add(this);
|
||||
}
|
||||
@@ -94,7 +95,7 @@ public class Siren : CovenBase
|
||||
{
|
||||
foreach (Siren instance in Instances)
|
||||
{
|
||||
if (instance.EffectEndTS.ContainsKey(playerId))
|
||||
if (instance.AffectedPlayers.Contains(playerId))
|
||||
{
|
||||
float vision = ReducedVision.GetFloat();
|
||||
opt.SetVision(false);
|
||||
@@ -117,7 +118,7 @@ public class Siren : CovenBase
|
||||
|
||||
public override bool OnVanish(PlayerControl pc)
|
||||
{
|
||||
PlayerControl[] nearbyPlayers = Utils.GetPlayersInRadius(SingRange.GetFloat(), pc.Pos()).Without(pc).Where(x => !x.Is(Team.Coven)).ToArray();
|
||||
PlayerControl[] nearbyPlayers = FastVector2.GetPlayersInRange(SingRange.GetFloat(), pc.Pos()).Without(pc).Where(x => !x.Is(Team.Coven)).ToArray();
|
||||
|
||||
foreach (PlayerControl player in nearbyPlayers)
|
||||
{
|
||||
@@ -129,13 +130,28 @@ public class Siren : CovenBase
|
||||
switch (stage)
|
||||
{
|
||||
case 1:
|
||||
EffectEndTS[player.PlayerId] = Utils.TimeStamp + Stage1EffectsLength.GetInt();
|
||||
AffectedPlayers.Add(player.PlayerId);
|
||||
_ = new CountdownTimer(Stage1EffectsLength.GetInt(), () =>
|
||||
{
|
||||
AffectedPlayers.Remove(player.PlayerId);
|
||||
player.MarkDirtySettings();
|
||||
}, onCanceled: () => AffectedPlayers.Remove(player.PlayerId));
|
||||
player.MarkDirtySettings();
|
||||
Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: player);
|
||||
break;
|
||||
case 2:
|
||||
AffectedPlayers.Add(player.PlayerId);
|
||||
_ = new CountdownTimer(Stage2EffectsLength.GetInt(), () =>
|
||||
{
|
||||
AffectedPlayers.Remove(player.PlayerId);
|
||||
ReportDeadBodyPatch.CanReport[player.PlayerId] = true;
|
||||
player.MarkDirtySettings();
|
||||
}, onCanceled: () =>
|
||||
{
|
||||
AffectedPlayers.Remove(player.PlayerId);
|
||||
ReportDeadBodyPatch.CanReport[player.PlayerId] = true;
|
||||
});
|
||||
ReportDeadBodyPatch.CanReport[player.PlayerId] = false;
|
||||
EffectEndTS[player.PlayerId] = Utils.TimeStamp + Stage2EffectsLength.GetInt();
|
||||
player.MarkDirtySettings();
|
||||
Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: player);
|
||||
break;
|
||||
@@ -148,16 +164,6 @@ public class Siren : CovenBase
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnGlobalFixedUpdate(PlayerControl pc, bool lowLoad)
|
||||
{
|
||||
if (lowLoad || !GameStates.IsInTask || ExileController.Instance || !pc.IsAlive() || !EffectEndTS.TryGetValue(pc.PlayerId, out var endTS) || endTS > Utils.TimeStamp) return;
|
||||
|
||||
ReportDeadBodyPatch.CanReport[pc.PlayerId] = true;
|
||||
Main.AllPlayerSpeed[pc.PlayerId] = Main.RealOptionsData.GetFloat(FloatOptionNames.PlayerSpeedMod);
|
||||
EffectEndTS.Remove(pc.PlayerId);
|
||||
pc.MarkDirtySettings();
|
||||
}
|
||||
|
||||
public override bool KnowRole(PlayerControl player, PlayerControl target)
|
||||
{
|
||||
if (base.KnowRole(player, target)) return true;
|
||||
|
||||
@@ -236,8 +236,16 @@ internal static class EffectExtenstions
|
||||
|
||||
break;
|
||||
case Effect.TimeBomb:
|
||||
Bombs.TryAdd(PickRandomPlayer().Pos(), (Utils.TimeStamp, IRandom.Instance.Next(MinimumEffectDuration, MaximumEffectDuration)));
|
||||
Utils.SendRPC(CustomRPC.SyncRoleData, randomizer.PlayerId, 1, Bombs.Last().Key, Bombs.Last().Value.PlaceTimeStamp, Bombs.Last().Value.ExplosionDelay);
|
||||
Vector2 randomPlayerPos = PickRandomPlayer().Pos();
|
||||
int bombTime = IRandom.Instance.Next(MinimumEffectDuration, MaximumEffectDuration);
|
||||
Bombs.TryAdd(randomPlayerPos, new CountdownTimer(bombTime, () =>
|
||||
{
|
||||
foreach (PlayerControl pc in FastVector2.GetPlayersInRange(RandomFloat, randomPlayerPos))
|
||||
pc.Suicide(PlayerState.DeathReason.RNG, randomizer);
|
||||
|
||||
Bombs.Remove(randomPlayerPos);
|
||||
}, onTick: () => Utils.NotifyRoles(SendOption: SendOption.None), onCanceled: () => Bombs.Remove(randomPlayerPos)));
|
||||
Utils.SendRPC(CustomRPC.SyncRoleData, randomizer.PlayerId, 1, randomPlayerPos, bombTime);
|
||||
break;
|
||||
case Effect.Tornado:
|
||||
Tornado.SpawnTornado(PickRandomPlayer());
|
||||
@@ -457,7 +465,7 @@ internal class Randomizer : RoleBase
|
||||
public static Dictionary<byte, float> AllPlayerDefaultSpeed = [];
|
||||
|
||||
public static Dictionary<Vector2, Vector2> Rifts = [];
|
||||
public static Dictionary<Vector2, (long PlaceTimeStamp, int ExplosionDelay)> Bombs = [];
|
||||
public static Dictionary<Vector2, CountdownTimer> Bombs = [];
|
||||
|
||||
public static Stopwatch TimeSinceLastMeeting;
|
||||
private static Dictionary<byte, long> LastTP = [];
|
||||
@@ -553,7 +561,7 @@ internal class Randomizer : RoleBase
|
||||
|
||||
if (!ReportDeadBodyPatch.MeetingStarted && TimeSinceLastMeeting.IsRunning && TimeSinceLastMeeting.Elapsed.TotalSeconds > 10f)
|
||||
{
|
||||
Effect effect = PickRandomEffect(pc.PlayerId);
|
||||
Effect effect = PickRandomEffect();
|
||||
effect.Apply(pc);
|
||||
}
|
||||
|
||||
@@ -585,7 +593,7 @@ internal class Randomizer : RoleBase
|
||||
CurrentEffects[pc.PlayerId].TryAdd(effect, (Utils.TimeStamp, duration));
|
||||
}
|
||||
|
||||
private static Effect PickRandomEffect(byte id)
|
||||
private static Effect PickRandomEffect()
|
||||
{
|
||||
long now = Utils.TimeStamp;
|
||||
|
||||
@@ -595,7 +603,6 @@ internal class Randomizer : RoleBase
|
||||
if (effect == Effect.GhostPlayer)
|
||||
{
|
||||
if (LastDeathEffect + 60 > now) return Effect.AddonRemove;
|
||||
|
||||
LastDeathEffect = now;
|
||||
}
|
||||
|
||||
@@ -661,7 +668,7 @@ internal class Randomizer : RoleBase
|
||||
LastDeathEffect = Utils.TimeStamp;
|
||||
Rifts.Clear();
|
||||
Bombs.Clear();
|
||||
Utils.SendRPC(CustomRPC.SyncRoleData, PlayerIdList[0], 3);
|
||||
Utils.SendRPC(CustomRPC.SyncRoleData, PlayerIdList[0], 2);
|
||||
|
||||
foreach (PlayerControl pc in Main.EnumeratePlayerControls())
|
||||
{
|
||||
@@ -678,41 +685,15 @@ internal class Randomizer : RoleBase
|
||||
LastDeathEffect = Utils.TimeStamp;
|
||||
}
|
||||
|
||||
public override void OnGlobalFixedUpdate(PlayerControl player, bool lowLoad)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (lowLoad || !Exists || !GameStates.IsInTask || Bombs.Count == 0 || Main.HasJustStarted) return;
|
||||
|
||||
long now = Utils.TimeStamp;
|
||||
PlayerControl randomizer = Utils.GetPlayerById(PlayerIdList.FirstOrDefault());
|
||||
|
||||
foreach (KeyValuePair<Vector2, (long PlaceTimeStamp, int ExplosionDelay)> bomb in Bombs)
|
||||
{
|
||||
if (bomb.Value.PlaceTimeStamp + bomb.Value.ExplosionDelay < now)
|
||||
{
|
||||
IEnumerable<PlayerControl> players = Utils.GetPlayersInRadius(RandomFloat, bomb.Key);
|
||||
foreach (PlayerControl pc in players) pc.Suicide(PlayerState.DeathReason.RNG, randomizer);
|
||||
|
||||
Bombs.Remove(bomb.Key);
|
||||
Utils.SendRPC(CustomRPC.SyncRoleData, randomizer.PlayerId, 2, bomb.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) { Logger.Exception(ex, "Randomizer"); }
|
||||
}
|
||||
|
||||
public void ReceiveRPC(MessageReader reader)
|
||||
{
|
||||
switch (reader.ReadPackedInt32())
|
||||
{
|
||||
case 1:
|
||||
Bombs.TryAdd(NetHelpers.ReadVector2(reader), (long.Parse(reader.ReadString()), reader.ReadPackedInt32()));
|
||||
Vector2 key = NetHelpers.ReadVector2(reader);
|
||||
Bombs.TryAdd(key, new CountdownTimer(reader.ReadPackedInt32(), () => Bombs.Remove(key), onCanceled: () => Bombs.Remove(key)));
|
||||
break;
|
||||
case 2:
|
||||
Bombs.Remove(NetHelpers.ReadVector2(reader));
|
||||
break;
|
||||
case 3:
|
||||
Bombs.Clear();
|
||||
break;
|
||||
}
|
||||
@@ -720,11 +701,8 @@ internal class Randomizer : RoleBase
|
||||
|
||||
public override string GetSuffix(PlayerControl seer, PlayerControl target, bool hud = false, bool meeting = false)
|
||||
{
|
||||
if (seer == null || seer.PlayerId != target.PlayerId || Bombs.Count == 0) return string.Empty;
|
||||
|
||||
KeyValuePair<Vector2, (long PlaceTimeStamp, int ExplosionDelay)> bomb = Bombs.FirstOrDefault(x => Vector2.Distance(x.Key, seer.Pos()) <= 5f);
|
||||
long time = bomb.Value.ExplosionDelay - (Utils.TimeStamp - bomb.Value.PlaceTimeStamp) + 1;
|
||||
return time < 0 ? string.Empty : $"<#ffff00>⚠ {time}</color>";
|
||||
if (seer == null || seer.PlayerId != target.PlayerId || Bombs.Count == 0 || !Bombs.FindFirst(x => FastVector2.DistanceWithinRange(x.Key, seer.Pos(), 5f), out KeyValuePair<Vector2, CountdownTimer> kvp)) return string.Empty;
|
||||
return $"<#ffff00>⚠ {(int)kvp.Value.Remaining.TotalSeconds}</color>";
|
||||
}
|
||||
|
||||
public override void OnCheckPlayerPosition(PlayerControl pc)
|
||||
|
||||
@@ -216,7 +216,7 @@ public class ToiletMaster : RoleBase
|
||||
int duration = RedPoopRoleBlockDuration.GetInt();
|
||||
List<PlayerControl> affectedPlayers = [];
|
||||
|
||||
Utils.GetPlayersInRadius(RedPoopRadius.GetFloat(), pos).Without(pc).Do(x =>
|
||||
FastVector2.GetPlayersInRange(RedPoopRadius.GetFloat(), pos).Without(pc).Do(x =>
|
||||
{
|
||||
x.BlockRole(duration);
|
||||
Main.AllPlayerSpeed[x.PlayerId] = Main.MinSpeed;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using AmongUs.GameOptions;
|
||||
using EHR.Modules;
|
||||
using EHR.Modules.Extensions;
|
||||
|
||||
namespace EHR.Roles;
|
||||
|
||||
@@ -84,7 +85,7 @@ public class Tree : RoleBase
|
||||
bool allKill = true;
|
||||
bool any = false;
|
||||
|
||||
Utils.GetPlayersInRadius(FallRadius.GetFloat(), pc.Pos()).Without(pc).Do(x =>
|
||||
FastVector2.GetPlayersInRange(FallRadius.GetFloat(), pc.Pos()).Without(pc).Do(x =>
|
||||
{
|
||||
any = true;
|
||||
if (IRandom.Instance.Next(100) < chance) x.Suicide(PlayerState.DeathReason.Fall, pc);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using EHR.Modules;
|
||||
using EHR.Modules.Extensions;
|
||||
using Hazel;
|
||||
|
||||
namespace EHR.Roles;
|
||||
@@ -52,7 +53,7 @@ public class Leery : RoleBase
|
||||
|
||||
Vector2 pos = pc.Pos();
|
||||
float radius = Radius.GetFloat();
|
||||
PlayerControl[] nearbyPlayers = Utils.GetPlayersInRadius(radius, pos).Without(pc).ToArray();
|
||||
PlayerControl[] nearbyPlayers = FastVector2.GetPlayersInRange(radius, pos).Without(pc).ToArray();
|
||||
|
||||
if (nearbyPlayers.Length == 0)
|
||||
{
|
||||
|
||||
@@ -26,7 +26,7 @@ public class PatrollingState(byte sentinelId, int patrolDuration, float patrolRa
|
||||
|
||||
private CountdownTimer Timer;
|
||||
|
||||
public IEnumerable<PlayerControl> NearbyKillers => GetPlayersInRadius(PatrolRadius, StartingPosition).Where(x => !x.Is(Team.Crewmate) && (!Sentinel.IsMadmate() || !x.Is(Team.Impostor)) && SentinelId != x.PlayerId);
|
||||
public IEnumerable<PlayerControl> NearbyKillers => FastVector2.GetPlayersInRange(PatrolRadius, StartingPosition).Where(x => !x.Is(Team.Crewmate) && (!Sentinel.IsMadmate() || !x.Is(Team.Impostor)) && SentinelId != x.PlayerId);
|
||||
|
||||
public void SetPlayer()
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AmongUs.GameOptions;
|
||||
using EHR.Modules.Extensions;
|
||||
using Hazel;
|
||||
|
||||
namespace EHR.Roles;
|
||||
@@ -82,7 +83,7 @@ internal class Bloodmoon : IGhostRole
|
||||
if (pc.RpcCheckAndMurder(player, true)) player.Suicide(PlayerState.DeathReason.LossOfBlood, pc);
|
||||
}
|
||||
|
||||
Utils.GetPlayersInRadius(7f, pc.Pos()).DoIf(x => !x.Is(Team.Impostor), x => x.Notify(string.Format(Translator.GetString("BloodmoonNearYou"), CustomRoles.Bloodmoon.ToColoredString()), sendOption: SendOption.None));
|
||||
FastVector2.GetPlayersInRange(7f, pc.Pos()).DoIf(x => !x.Is(Team.Impostor), x => x.Notify(string.Format(Translator.GetString("BloodmoonNearYou"), CustomRoles.Bloodmoon.ToColoredString()), sendOption: SendOption.None));
|
||||
}
|
||||
|
||||
public static void OnMeetingStart()
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Linq;
|
||||
using AmongUs.GameOptions;
|
||||
using EHR.Modules;
|
||||
using EHR.Modules.Extensions;
|
||||
using Hazel;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -67,13 +68,13 @@ public sealed class Stealth : RoleBase
|
||||
Collider2D roomArea = room.roomArea;
|
||||
SystemTypes roomName = room.RoomId;
|
||||
RpcDarken(roomName);
|
||||
return Main.EnumerateAlivePlayerControls().Where(player => player != StealthPC && player.Collider.IsTouching(roomArea));
|
||||
return Main.EnumerateAlivePlayerControls().Where(player => player != StealthPC && roomArea.bounds.Contains(player.Pos()));
|
||||
}
|
||||
|
||||
private IEnumerable<PlayerControl> FindPlayersInRange()
|
||||
{
|
||||
var pos = StealthPC.Pos();
|
||||
var inRange = Utils.GetPlayersInRadius(blindingRadius, pos).Without(StealthPC);
|
||||
var inRange = FastVector2.GetPlayersInRange(blindingRadius, pos).Without(StealthPC);
|
||||
if (excludeImpostors) inRange = inRange.Where(p => !p.Is(CustomRoleTypes.Impostor));
|
||||
return inRange;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AmongUs.GameOptions;
|
||||
using EHR.Modules;
|
||||
using EHR.Modules.Extensions;
|
||||
using Hazel;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -133,7 +134,7 @@ public class Venerer : RoleBase
|
||||
yield break;
|
||||
}
|
||||
|
||||
HashSet<byte> nearbyPlayers = Utils.GetPlayersInRadius(radius, pc.Pos()).Without(pc).Select(x => x.PlayerId).ToHashSet();
|
||||
HashSet<byte> nearbyPlayers = FastVector2.GetPlayersInRange(radius, pc.Pos()).Without(pc).Select(x => x.PlayerId).ToHashSet();
|
||||
frozenPlayers.Except(nearbyPlayers).Do(x =>
|
||||
{
|
||||
PlayerControl p = Utils.GetPlayerById(x);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Linq;
|
||||
using AmongUs.GameOptions;
|
||||
using EHR.Modules;
|
||||
using EHR.Modules.Extensions;
|
||||
using static EHR.Options;
|
||||
using static EHR.Translator;
|
||||
using static EHR.Utils;
|
||||
@@ -131,7 +132,7 @@ public class Sapper : RoleBase
|
||||
foreach (KeyValuePair<Vector2, long> bomb in Bombs.Where(bomb => bomb.Value + Delay.GetInt() < TimeStamp).ToArray())
|
||||
{
|
||||
var b = false;
|
||||
IEnumerable<PlayerControl> players = GetPlayersInRadius(Radius.GetFloat(), bomb.Key);
|
||||
IEnumerable<PlayerControl> players = FastVector2.GetPlayersInRange(Radius.GetFloat(), bomb.Key);
|
||||
|
||||
foreach (PlayerControl tg in players)
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Linq;
|
||||
using AmongUs.GameOptions;
|
||||
using EHR.Modules;
|
||||
using EHR.Modules.Extensions;
|
||||
using Hazel;
|
||||
using static EHR.Options;
|
||||
using static EHR.Utils;
|
||||
@@ -135,7 +136,7 @@ internal class Bubble : RoleBase
|
||||
return;
|
||||
}
|
||||
|
||||
IEnumerable<PlayerControl> players = GetPlayersInRadius(ExplosionRadius.GetFloat(), encasedPc.Pos());
|
||||
IEnumerable<PlayerControl> players = FastVector2.GetPlayersInRange(ExplosionRadius.GetFloat(), encasedPc.Pos());
|
||||
|
||||
var numDied = 0;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using AmongUs.GameOptions;
|
||||
using EHR.Modules.Extensions;
|
||||
|
||||
namespace EHR.Roles;
|
||||
|
||||
@@ -106,7 +107,7 @@ public class Explosivist : RoleBase
|
||||
|
||||
if (Explosive != null && (ExplodeTS <= Utils.TimeStamp || !pc.IsAlive()))
|
||||
{
|
||||
Utils.GetPlayersInRadius(ExplosionRadius.GetFloat(), Explosive.Position).Without(pc).Do(x => x.Suicide(PlayerState.DeathReason.Bombed, pc));
|
||||
FastVector2.GetPlayersInRange(ExplosionRadius.GetFloat(), Explosive.Position).Without(pc).Do(x => x.Suicide(PlayerState.DeathReason.Bombed, pc));
|
||||
|
||||
pc.RevertFreeze(RealPosition);
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@ public class Magician : RoleBase
|
||||
case 1: // Slowness for everyone nearby
|
||||
if (TempSpeeds.Count > 0) RevertSpeedChanges(true);
|
||||
|
||||
IEnumerable<PlayerControl> list = GetPlayersInRadius(SlownessRadius.GetFloat(), pc.Pos());
|
||||
IEnumerable<PlayerControl> list = FastVector2.GetPlayersInRange(SlownessRadius.GetFloat(), pc.Pos());
|
||||
|
||||
foreach (PlayerControl x in list)
|
||||
{
|
||||
@@ -260,7 +260,7 @@ public class Magician : RoleBase
|
||||
|
||||
break;
|
||||
case 6: // Blind everyone nearby
|
||||
IEnumerable<PlayerControl> players = GetPlayersInRadius(BlindRadius.GetFloat(), pc.Pos());
|
||||
IEnumerable<PlayerControl> players = FastVector2.GetPlayersInRange(BlindRadius.GetFloat(), pc.Pos());
|
||||
|
||||
foreach (PlayerControl x in players)
|
||||
{
|
||||
@@ -370,7 +370,7 @@ public class Magician : RoleBase
|
||||
foreach (KeyValuePair<Vector2, long> bomb in Bombs.Where(bomb => bomb.Value + BombDelay.GetInt() < TimeStamp).ToArray())
|
||||
{
|
||||
var b = false;
|
||||
IEnumerable<PlayerControl> players = GetPlayersInRadius(BombRadius.GetFloat(), bomb.Key);
|
||||
IEnumerable<PlayerControl> players = FastVector2.GetPlayersInRange(BombRadius.GetFloat(), bomb.Key);
|
||||
|
||||
foreach (PlayerControl tg in players)
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Linq;
|
||||
using AmongUs.GameOptions;
|
||||
using EHR.Modules;
|
||||
using EHR.Modules.Extensions;
|
||||
using Hazel;
|
||||
using static EHR.Options;
|
||||
using static EHR.Translator;
|
||||
@@ -152,7 +153,7 @@ internal class Mycologist : RoleBase
|
||||
|
||||
LateTask.New(() =>
|
||||
{
|
||||
InfectedPlayers.AddRange(GetPlayersInRadius(InfectRadius.GetFloat(), MycologistPC.Pos()).Select(x => x.PlayerId));
|
||||
InfectedPlayers.AddRange(FastVector2.GetPlayersInRange(InfectRadius.GetFloat(), MycologistPC.Pos()).Select(x => x.PlayerId));
|
||||
SendRPC();
|
||||
NotifyRoles(SpecifySeer: MycologistPC);
|
||||
}, InfectTime.GetFloat(), "Mycologist Infect Time");
|
||||
|
||||
Reference in new issue
Block a user