diff --git a/Gamemodes/RRTimeTester.cs b/Gamemodes/RRTimeTester.cs index ec305f140..a40d7555e 100644 --- a/Gamemodes/RRTimeTester.cs +++ b/Gamemodes/RRTimeTester.cs @@ -29,7 +29,7 @@ public static class RRTimeTester Redo: HUDText = $"<#ffff00>{otherSystemTypesName}"; PlayerControl.LocalPlayer.TP(map.Positions.GetValueOrDefault(systemTypes, systemTypes.GetRoomClass().transform.position)); - yield return new WaitForSeconds(0.5f); + yield return new WaitForSecondsRealtime(0.5f); while (PlayerControl.LocalPlayer.IsInRoom(systemTypes)) yield return null; stopwatch.Restart(); while (PlayerControl.LocalPlayer.onLadder || PlayerControl.LocalPlayer.inMovingPlat || !PlayerControl.LocalPlayer.IsInRoom(otherSystemTypes)) diff --git a/Gamemodes/SoloPVP.cs b/Gamemodes/SoloPVP.cs index b7b9bbdab..9ac43ab8b 100644 --- a/Gamemodes/SoloPVP.cs +++ b/Gamemodes/SoloPVP.cs @@ -280,7 +280,7 @@ internal static class SoloPVP if (target.inVent || target.MyPhysics.Animations.IsPlayingEnterVentAnimation()) { LateTask.New(() => target.MyPhysics.RpcExitVent(target.GetClosestVent().Id), 0.6f, log: false); - yield return new WaitForSeconds(1.3f); + yield return new WaitForSecondsRealtime(1.3f); } while (target.inVent || target.inMovingPlat || target.onLadder || target.MyPhysics.Animations.IsPlayingAnyLadderAnimation() || target.MyPhysics.Animations.IsPlayingEnterVentAnimation()) diff --git a/Modules/CustomNetObject.cs b/Modules/CustomNetObject.cs index 952dfc60b..a39513ecf 100644 --- a/Modules/CustomNetObject.cs +++ b/Modules/CustomNetObject.cs @@ -259,7 +259,7 @@ namespace EHR catch { } } - protected void CreateNetObject(string sprite, Vector2 position) + protected void CreateNetObject(string sprite, Vector2 position, IEnumerable hideFrom = null, PlayerControl onlyVisibleTo = null) { if (GameStates.IsEnded || !AmongUsClient.Instance.AmHost || TryReusePooledObject(sprite, position)) return; @@ -396,6 +396,12 @@ namespace EHR playerControl.CachedPlayerData = PlayerControl.LocalPlayer.Data; + if (hideFrom != null || onlyVisibleTo) + { + yield return new WaitForSecondsRealtime(0.3f); + Hide(onlyVisibleTo ? Main.EnumerateAlivePlayerControls().Without(onlyVisibleTo) : hideFrom); + } + yield return new WaitForSecondsRealtime(0.15f); if (this is not ShapeshiftMenuElement) @@ -410,7 +416,7 @@ namespace EHR string visorId = PlayerControl.LocalPlayer.Data.Outfits[PlayerOutfitType.Default].VisorId; var sender = CustomRpcSender.Create("CustomNetObject.CreateNetObject", SendOption.Reliable, log: false); MessageWriter writer = sender.stream; - sender.StartMessage(); + sender.StartMessage(onlyVisibleTo ? onlyVisibleTo.OwnerId : -1); PlayerControl.LocalPlayer.Data.Outfits[PlayerOutfitType.Default].PlayerName = "
" + sprite; PlayerControl.LocalPlayer.Data.Outfits[PlayerOutfitType.Default].ColorId = 0; PlayerControl.LocalPlayer.Data.Outfits[PlayerOutfitType.Default].HatId = ""; @@ -514,11 +520,10 @@ namespace EHR private readonly long SpawnTimeStamp; private bool Gone; - public TornadoObject(Vector2 position, IEnumerable visibleList) + public TornadoObject(Vector2 position, PlayerControl tornado) { SpawnTimeStamp = Utils.TimeStamp; - CreateNetObject("<#0000>WWWWWW<#0000>WW\nWWWWWWW<#0000>W\nWWWWWWWW\nWWWWWWWW\nWWWWWWWW\nWWWWWWWW\n<#0000>WWWWWWW<#0000>W\nWWWWWW<#0000>WW", position); - LateTask.New(() => Hide(Main.EnumerateAlivePlayerControls().ExceptBy(visibleList, x => x.PlayerId)), 0.4f); + CreateNetObject("<#0000>WWWWWW<#0000>WW\nWWWWWWW<#0000>W\nWWWWWWWW\nWWWWWWWW\nWWWWWWWW\nWWWWWWWW\n<#0000>WWWWWWW<#0000>W\nWWWWWW<#0000>WW", position, onlyVisibleTo: tornado); } protected override void OnFixedUpdate() @@ -550,10 +555,9 @@ namespace EHR internal sealed class PlayerDetector : CustomNetObject { - public PlayerDetector(Vector2 position, List visibleList, out int id) + public PlayerDetector(Vector2 position, PlayerControl druid, out int id) { - CreateNetObject("<#0000>WWW<#0000>WWW<#0000>WW\nWW<#0000>WWWWW<#0000>W\nW<#0000>WWWW<#0000>WWW\nW<#0000>WWWWW<#0000>WW\nW<#0000>WWWWW<#0000>WW\nW<#0000>WWWW<#0000>WWW\n<#0000>WW<#0000>WWWWW<#0000>W\nWWW<#0000>WWW<#0000>WW", position); - LateTask.New(() => Hide(Main.EnumerateAlivePlayerControls().ExceptBy(visibleList, x => x.PlayerId)), 0.4f); + CreateNetObject("<#0000>WWW<#0000>WWW<#0000>WW\nWW<#0000>WWWWW<#0000>W\nW<#0000>WWWW<#0000>WWW\nW<#0000>WWWWW<#0000>WW\nW<#0000>WWWWW<#0000>WW\nW<#0000>WWWW<#0000>WWW\n<#0000>WW<#0000>WWWWW<#0000>W\nWWW<#0000>WWW<#0000>WW", position, onlyVisibleTo: druid); id = Id; } } @@ -562,12 +566,11 @@ namespace EHR { public readonly Adventurer.Resource Resource; - internal AdventurerItem(Vector2 position, Adventurer.Resource resource, IEnumerable visibleList) + internal AdventurerItem(Vector2 position, Adventurer.Resource resource, PlayerControl adventurer) { Resource = resource; (char Icon, Color Color) data = Adventurer.ResourceDisplayData[resource]; - CreateNetObject($"{Utils.ColorString(data.Color, data.Icon.ToString())}", position); - LateTask.New(() => Hide(Main.EnumerateAlivePlayerControls().ExceptBy(visibleList, x => x.PlayerId)), 0.4f); + CreateNetObject($"{Utils.ColorString(data.Color, data.Icon.ToString())}", position, onlyVisibleTo: adventurer); } } @@ -575,8 +578,7 @@ namespace EHR { internal Toilet(Vector2 position, IEnumerable hideList) { - CreateNetObject("<#0000>WWWWWWWWW<#0000>W\nWWWWWWWWWW\nWWWWWWWWWW\n<#0000>WWWWWWWWW<#0000>W\nWWWWWWWWW<#0000>W\nWWWWWWWWWW\n<#0000>WWWWWWWWWW\n<#0000>WWWWWWWWWW\n<#0000>WWWWWWW<#0000>WWW\nWWWWWW<#0000>WWWW", position); - LateTask.New(() => Hide(hideList), 0.4f); + CreateNetObject("<#0000>WWWWWWWWW<#0000>W\nWWWWWWWWWW\nWWWWWWWWWW\n<#0000>WWWWWWWWW<#0000>W\nWWWWWWWWW<#0000>W\nWWWWWWWWWW\n<#0000>WWWWWWWWWW\n<#0000>WWWWWWWWWW\n<#0000>WWWWWWW<#0000>WWW\nWWWWWW<#0000>WWWW", position, hideList); } } @@ -596,10 +598,9 @@ namespace EHR internal sealed class SprayedArea : CustomNetObject { - public SprayedArea(Vector2 position, IEnumerable visibleList) + public SprayedArea(Vector2 position, PlayerControl sprayer) { - CreateNetObject("<#0000>WWWW<#0000>WW\nWWWWW<#0000>W\nWWWWWW\nWWWWWW\n<#0000>WWWWW<#0000>W\nWWWW<#0000>WW", position); - LateTask.New(() => Hide(Main.EnumerateAlivePlayerControls().ExceptBy(visibleList, x => x.PlayerId)), 0.4f); + CreateNetObject("<#0000>WWWW<#0000>WW\nWWWWW<#0000>W\nWWWWWW\nWWWWWW\n<#0000>WWWWW<#0000>W\nWWWW<#0000>WW", position, onlyVisibleTo: sprayer); } public override void OnMeeting() @@ -612,8 +613,7 @@ namespace EHR { public CatcherTrap(Vector2 position, PlayerControl catcher) { - CreateNetObject("<#0000>WWWW<#0000>WW\nWWWWW<#0000>W\nWWWWWW\nWWWWWW\n<#0000>WWWWW<#0000>W\nWWWW<#0000>WW", position); - LateTask.New(() => Hide(Main.EnumerateAlivePlayerControls().Without(catcher)), 0.4f); + CreateNetObject("<#0000>WWWW<#0000>WW\nWWWWW<#0000>W\nWWWWWW\nWWWWWW\n<#0000>WWWWW<#0000>W\nWWWW<#0000>WW", position, onlyVisibleTo: catcher); } public override void OnMeeting() @@ -642,8 +642,7 @@ namespace EHR { public SoulObject(Vector2 position, PlayerControl whisperer) { - CreateNetObject("<#0000>WWWWW<#0000>W\nWWWWWW\nWWWWWW\nWWWWWW\n<#0000>WWWWWW\n<#0000>WWWW<#0000>WW", position); - LateTask.New(() => Hide(Main.EnumerateAlivePlayerControls().Without(whisperer)), 0.4f); + CreateNetObject("<#0000>WWWWW<#0000>W\nWWWWWW\nWWWWWW\nWWWWWW\n<#0000>WWWWWW\n<#0000>WWWW<#0000>WW", position, onlyVisibleTo: whisperer); } } @@ -875,10 +874,9 @@ namespace EHR internal sealed class ShapeshiftMenuElement : CustomNetObject { - public ShapeshiftMenuElement(byte visibleTo) + public ShapeshiftMenuElement(PlayerControl guesser) { - CreateNetObject(string.Empty, new Vector2(0f, 0f)); - LateTask.New(() => Hide(Main.EnumeratePlayerControls().Where(x => x.PlayerId != visibleTo)), 0.4f); + CreateNetObject(string.Empty, new Vector2(0f, 0f), onlyVisibleTo: guesser); } } diff --git a/Modules/EAC.cs b/Modules/EAC.cs index 8e4c7bf82..74e9bfef7 100644 --- a/Modules/EAC.cs +++ b/Modules/EAC.cs @@ -17,7 +17,6 @@ namespace EHR; internal static class EAC { public static int DeNum; - public static readonly HashSet InvalidReports = []; public static readonly Dictionary TimeSinceLastTaskCompletion = []; public static void WarnHost(int denum = 1) diff --git a/Modules/GuessManager.cs b/Modules/GuessManager.cs index 795cb3056..09562780d 100644 --- a/Modules/GuessManager.cs +++ b/Modules/GuessManager.cs @@ -1498,7 +1498,7 @@ public static class GuessManager cno = ExistingCNOs[i - alivePlayerControlsLength]; else { - cno = new ShapeshiftMenuElement(guesserId); + cno = new ShapeshiftMenuElement(guesser); ExistingCNOs.Add(cno); } diff --git a/Modules/Utils.cs b/Modules/Utils.cs index 1cc0c22a4..f6e0480aa 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -4262,7 +4262,6 @@ public static class Utils } LateTask.New(() => Asthmatic.RunChecks = true, 2f, log: false); - EAC.InvalidReports.Clear(); CustomNetObject.AfterMeeting(); diff --git a/Roles/Standard/Crewmate/Chaos/Tornado.cs b/Roles/Standard/Crewmate/Chaos/Tornado.cs index 466f87af1..e408c75e2 100644 --- a/Roles/Standard/Crewmate/Chaos/Tornado.cs +++ b/Roles/Standard/Crewmate/Chaos/Tornado.cs @@ -118,7 +118,7 @@ internal class Tornado : RoleBase long now = TimeStamp; Tornados.TryAdd(info, now); SendRPCAddTornado(true, info.Location, info.RoomName, now); - _ = new TornadoObject(info.Location, [pc.PlayerId]); + _ = new TornadoObject(info.Location, pc); } public override void OnCheckPlayerPosition(PlayerControl pc) diff --git a/Roles/Standard/Crewmate/Investigate/Druid.cs b/Roles/Standard/Crewmate/Investigate/Druid.cs index 4541eea02..5a69e9df9 100644 --- a/Roles/Standard/Crewmate/Investigate/Druid.cs +++ b/Roles/Standard/Crewmate/Investigate/Druid.cs @@ -144,7 +144,7 @@ public class Druid : RoleBase (Vector2 location, string roomName) = pc.GetPositionInfo(); Triggers.TryAdd(location, roomName); SendRPCAddTrigger(true, pc.PlayerId, location, roomName); - _ = new PlayerDetector(location, [pc.PlayerId], out int id); + _ = new PlayerDetector(location, pc, out int id); TriggerIds.TryAdd(location, id); } else @@ -156,7 +156,7 @@ public class Druid : RoleBase (Vector2 location, string roomName) = pc.GetPositionInfo(); Triggers.TryAdd(location, roomName); SendRPCAddTrigger(true, id, location, roomName); - _ = new PlayerDetector(location, [pc.PlayerId], out int oid); + _ = new PlayerDetector(location, pc, out int oid); TriggerIds.TryAdd(location, oid); }, onTick: () => pc.Notify(string.Format(GetString("DruidTimeLeft"), (int)Math.Ceiling(DelayTimer.Remaining.TotalSeconds)), 2f, overrideAll: true), onCanceled: () => DelayTimer = null); } diff --git a/Roles/Standard/Crewmate/Power/Adventurer.cs b/Roles/Standard/Crewmate/Power/Adventurer.cs index 86ab998b7..f94ae222c 100644 --- a/Roles/Standard/Crewmate/Power/Adventurer.cs +++ b/Roles/Standard/Crewmate/Power/Adventurer.cs @@ -298,7 +298,7 @@ internal class Adventurer : RoleBase Vector2 pos = pc.Pos(); LocateArrow.Add(AdventurerPC.PlayerId, pos); ResourceLocations[Resource.Random] = pos; - _ = new AdventurerItem(pos, Resource.Random, [AdventurerPC.PlayerId]); + _ = new AdventurerItem(pos, Resource.Random, AdventurerPC); LastRandomResourceTimeStamp = now; Utils.NotifyRoles(SpecifySeer: AdventurerPC, SpecifyTarget: AdventurerPC); } @@ -330,7 +330,7 @@ internal class Adventurer : RoleBase LocateArrow.Add(AdventurerPC.PlayerId, pcPos); ResourceLocations[Resource.Grouping] = pcPos; - _ = new AdventurerItem(pcPos, Resource.Grouping, [AdventurerPC.PlayerId]); + _ = new AdventurerItem(pcPos, Resource.Grouping, AdventurerPC); LastGroupingResourceTimeStamp = now; Utils.NotifyRoles(SpecifySeer: AdventurerPC, SpecifyTarget: AdventurerPC); } @@ -380,7 +380,7 @@ internal class Adventurer : RoleBase Vector2 pos = shapeshifter.Pos(); av.ResourceLocations[Resource.ShapeshiftSkin] = pos; HideObject(Resource.ShapeshiftSkin); - _ = new AdventurerItem(pos, Resource.ShapeshiftSkin, [av.AdventurerPC.PlayerId]); + _ = new AdventurerItem(pos, Resource.ShapeshiftSkin, av.AdventurerPC); } public static void OnAnyoneDead(PlayerControl target) @@ -392,7 +392,7 @@ internal class Adventurer : RoleBase Vector2 pos = target.Pos(); av.ResourceLocations[Resource.DeadBody] = pos; HideObject(Resource.DeadBody); - _ = new AdventurerItem(pos, Resource.DeadBody, [av.AdventurerPC.PlayerId]); + _ = new AdventurerItem(pos, Resource.DeadBody, av.AdventurerPC); } } } diff --git a/Roles/Standard/Crewmate/Power/Swapper.cs b/Roles/Standard/Crewmate/Power/Swapper.cs index 94338da32..ba5c770d8 100644 --- a/Roles/Standard/Crewmate/Power/Swapper.cs +++ b/Roles/Standard/Crewmate/Power/Swapper.cs @@ -224,7 +224,7 @@ public class Swapper : RoleBase { if (Starspawn.IsDayBreak) return; - if (CNO == null) CNO = CanSwapSelf.GetBool() ? new ShapeshiftMenuElement(shapeshifter.PlayerId) : null; + if (CNO == null) CNO = CanSwapSelf.GetBool() ? new ShapeshiftMenuElement(shapeshifter) : null; else if (CNO.playerControl.NetId == target.NetId) target = shapeshifter; SwapMsg(shapeshifter, $"/sw {target.PlayerId}"); diff --git a/Roles/Standard/Crewmate/Support/TimeMaster.cs b/Roles/Standard/Crewmate/Support/TimeMaster.cs index 88ff11e3f..6fd7726ad 100644 --- a/Roles/Standard/Crewmate/Support/TimeMaster.cs +++ b/Roles/Standard/Crewmate/Support/TimeMaster.cs @@ -73,7 +73,6 @@ internal class TimeMaster : RoleBase public override void Add(byte playerId) { On = true; - BackTrack = []; DesyncCommsActive = false; playerId.SetAbilityUseLimit(TimeMasterMaxUses.GetFloat()); } @@ -83,6 +82,8 @@ internal class TimeMaster : RoleBase On = false; Rewinding = false; RevivedPlayers = []; + TargetPosition = []; + BackTrack = []; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) @@ -163,7 +164,7 @@ internal class TimeMaster : RoleBase foreach ((byte playerId, Vector2 pos) in track) { PlayerControl player = playerId.GetPlayer(); - if (player == null || !player.IsAlive()) continue; + if (!player || !player.IsAlive()) continue; player.TP(pos); } @@ -182,6 +183,7 @@ internal class TimeMaster : RoleBase ps.Player.RpcRevive(); ps.Player.TP(deadBody.TruePosition); ps.Player.Notify(Translator.GetString("RevivedByTimeMaster"), 15f); + RevivedPlayers.Add(deadBody.ParentId); } if (TimeMasterRevivedKillerAlert.GetBool()) @@ -260,7 +262,6 @@ internal class TimeMaster : RoleBase { DesyncCommsActive = false; hasValue = true; - activateSabComms = false; } if (!hasValue) return; diff --git a/Roles/Standard/Neutral/Killing/Sprayer.cs b/Roles/Standard/Neutral/Killing/Sprayer.cs index 3c400a793..5915f568e 100644 --- a/Roles/Standard/Neutral/Killing/Sprayer.cs +++ b/Roles/Standard/Neutral/Killing/Sprayer.cs @@ -138,7 +138,7 @@ internal class Sprayer : RoleBase if (!IsEnable || SprayerId.GetAbilityUseLimit() <= 0 || SprayerPC.HasAbilityCD()) return; Vector2 pos = SprayerPC.Pos(); - Traps[pos] = new(pos, [SprayerId]); + Traps[pos] = new(pos, SprayerPC); SprayerPC.RpcRemoveAbilityUse(); if (SprayerId.GetAbilityUseLimit() > 0) SprayerPC.AddAbilityCD(CD.GetInt()); diff --git a/Roles/Standard/Neutral/Pariah/Magistrate.cs b/Roles/Standard/Neutral/Pariah/Magistrate.cs index 7e97f7766..f70b400af 100644 --- a/Roles/Standard/Neutral/Pariah/Magistrate.cs +++ b/Roles/Standard/Neutral/Pariah/Magistrate.cs @@ -44,9 +44,9 @@ public class Magistrate : RoleBase System.Collections.IEnumerator Coroutine() { - while (GameStates.IsMeeting || ExileController.Instance || AntiBlackout.SkipTasks) yield return new WaitForSeconds(5f); - yield return new WaitForSeconds(1f); - while (GameStates.IsMeeting || ExileController.Instance || AntiBlackout.SkipTasks) yield return new WaitForSeconds(2f); + while (GameStates.IsMeeting || ExileController.Instance || AntiBlackout.SkipTasks) yield return new WaitForSecondsRealtime(5f); + yield return new WaitForSecondsRealtime(1f); + while (GameStates.IsMeeting || ExileController.Instance || AntiBlackout.SkipTasks) yield return new WaitForSecondsRealtime(2f); if (GameStates.IsEnded || !GameStates.InGame) yield break; AfterMeetingTasks(); }