diff --git a/Roles/HideAndSeek/Dasher.cs b/Roles/HideAndSeek/Dasher.cs
index 498b465d4..ad23f33c0 100644
--- a/Roles/HideAndSeek/Dasher.cs
+++ b/Roles/HideAndSeek/Dasher.cs
@@ -1,5 +1,6 @@
using AmongUs.GameOptions;
using EHR.Gamemodes;
+using EHR.Modules.Extensions;
namespace EHR.Roles;
@@ -7,12 +8,12 @@ public class Dasher : RoleBase, IHideAndSeekRole
{
public static bool On;
- public static OptionItem DashCooldown;
- public static OptionItem DashDuration;
- public static OptionItem DashSpeed;
- public static OptionItem UseLimit;
- public static OptionItem Vision;
- public static OptionItem Speed;
+ private static OptionItem DashCooldown;
+ private static OptionItem DashDuration;
+ private static OptionItem DashSpeed;
+ private static OptionItem UseLimit;
+ private static OptionItem Vision;
+ private static OptionItem Speed;
private DashStatus DashStatus;
@@ -114,7 +115,7 @@ public class Dasher : RoleBase, IHideAndSeekRole
if (DashStatus.IsDashing || pc.GetAbilityUseLimit() < 1f) return;
DashStatus.IsDashing = true;
- DashStatus.Timer = new(DashStatus.Duration, () =>
+ _ = new CountdownTimer(DashStatus.Duration, () =>
{
DashStatus.IsDashing = false;
pc.MarkDirtySettings();
diff --git a/Roles/HideAndSeek/IHideAndSeekRole.cs b/Roles/HideAndSeek/IHideAndSeekRole.cs
index de0c0ac7b..0aeb7db36 100644
--- a/Roles/HideAndSeek/IHideAndSeekRole.cs
+++ b/Roles/HideAndSeek/IHideAndSeekRole.cs
@@ -13,7 +13,6 @@ internal interface IHideAndSeekRole
public class DashStatus
{
- public CountdownTimer Timer { get; set; }
public bool IsDashing { get; set; }
public int Cooldown { get; init; } = 20;
public int Duration { get; init; } = 5;
diff --git a/Roles/HideAndSeek/Jet.cs b/Roles/HideAndSeek/Jet.cs
index 742103358..5046cf5b4 100644
--- a/Roles/HideAndSeek/Jet.cs
+++ b/Roles/HideAndSeek/Jet.cs
@@ -1,4 +1,5 @@
using AmongUs.GameOptions;
+using EHR.Modules.Extensions;
namespace EHR.Roles;
@@ -6,12 +7,12 @@ public class Jet : RoleBase, IHideAndSeekRole
{
public static bool On;
- public static OptionItem DashCooldown;
- public static OptionItem DashDuration;
- public static OptionItem DashSpeed;
- public static OptionItem UseLimit;
- public static OptionItem Vision;
- public static OptionItem Speed;
+ private static OptionItem DashCooldown;
+ private static OptionItem DashDuration;
+ private static OptionItem DashSpeed;
+ private static OptionItem UseLimit;
+ private static OptionItem Vision;
+ private static OptionItem Speed;
private DashStatus DashStatus;
@@ -88,7 +89,7 @@ public class Jet : RoleBase, IHideAndSeekRole
{
if (pc.HasAbilityCD() || DashStatus.IsDashing || pc.GetAbilityUseLimit() < 1f) return;
DashStatus.IsDashing = true;
- DashStatus.Timer = new(DashStatus.Duration, () =>
+ _ = new CountdownTimer(DashStatus.Duration, () =>
{
DashStatus.IsDashing = false;
pc.MarkDirtySettings();
diff --git a/Roles/Standard/Coven/Summoner.cs b/Roles/Standard/Coven/Summoner.cs
index b2b429a61..53908bdae 100644
--- a/Roles/Standard/Coven/Summoner.cs
+++ b/Roles/Standard/Coven/Summoner.cs
@@ -58,6 +58,7 @@ public class Summoner : CovenBase
SummonerId = playerId;
Changed = false;
SummonedPlayerId = byte.MaxValue;
+ SummonedPlayerTimer = null;
playerId.SetAbilityUseLimit(AbilityUseLimit.GetFloat());
}
@@ -100,11 +101,12 @@ public class Summoner : CovenBase
{
SummonedPlayerTimer = new(SummonedTimeToKill.GetFloat(), () =>
{
+ SummonedPlayerTimer = null;
SummonedPlayerId = byte.MaxValue;
if (summoned == null || !summoned.IsAlive()) return;
state.SetDead();
summoned.RpcExileV2();
- }, onTick: () => Utils.NotifyRoles(SpecifySeer: summoned, SpecifyTarget: summoned));
+ }, onTick: () => Utils.NotifyRoles(SpecifySeer: summoned, SpecifyTarget: summoned), onCanceled: () => SummonedPlayerTimer = null);
RPC.PlaySoundRPC(SummonedPlayerId, Sounds.SpawnSound);
GhostRolesManager.RemoveGhostRole(SummonedPlayerId);
@@ -158,7 +160,8 @@ public class Summoner : CovenBase
if (instance.SummonedPlayerId == killer.PlayerId)
{
AdditionalWinners.Add(instance.SummonedPlayerId);
- instance.SummonedPlayerTimer.Dispose();
+ instance.SummonedPlayerTimer?.Dispose();
+ instance.SummonedPlayerTimer = null;
killer.RpcExileV2();
Main.PlayerStates[instance.SummonedPlayerId].SetDead();
instance.SummonedPlayerId = byte.MaxValue;
@@ -184,11 +187,11 @@ public class Summoner : CovenBase
{
case 1:
SummonedPlayerId = reader.ReadByte();
- SummonedPlayerTimer = new(SummonedTimeToKill.GetFloat());
+ SummonedPlayerTimer = new(SummonedTimeToKill.GetFloat(), () => SummonedPlayerTimer = null, onCanceled: () => SummonedPlayerTimer = null);
break;
case 2:
SummonedPlayerId = byte.MaxValue;
- SummonedPlayerTimer.Dispose();
+ SummonedPlayerTimer?.Dispose();
SummonedPlayerTimer = null;
break;
}
diff --git a/Roles/Standard/Crewmate/Killing/Sentinel.cs b/Roles/Standard/Crewmate/Killing/Sentinel.cs
index 7be2eb47b..f6cf5d228 100644
--- a/Roles/Standard/Crewmate/Killing/Sentinel.cs
+++ b/Roles/Standard/Crewmate/Killing/Sentinel.cs
@@ -40,7 +40,11 @@ public class PatrollingState(byte sentinelId, int patrolDuration, float patrolRa
StartingPosition = Sentinel.Pos();
NearbyKillers.Do(x => x.Notify(string.Format(GetString("KillerNotifyPatrol"), PatrolDuration)));
Sentinel.MarkDirtySettings();
- Timer = new CountdownTimer(PatrolDuration, FinishPatrolling, onTick: CheckPlayerPositions, onCanceled: () => IsPatrolling = false);
+ Timer = new CountdownTimer(PatrolDuration, FinishPatrolling, onTick: CheckPlayerPositions, onCanceled: () =>
+ {
+ Timer = null;
+ IsPatrolling = false;
+ });
}
private void CheckPlayerPositions()
@@ -64,6 +68,7 @@ public class PatrollingState(byte sentinelId, int patrolDuration, float patrolRa
private void FinishPatrolling()
{
+ Timer = null;
IsPatrolling = false;
NearbyKillers.Do(x => x.Suicide(PlayerState.DeathReason.Patrolled, Sentinel));
Sentinel.MarkDirtySettings();
diff --git a/Roles/Standard/Crewmate/Miscellaneous/Addict.cs b/Roles/Standard/Crewmate/Miscellaneous/Addict.cs
index 725cf8487..a5f397b89 100644
--- a/Roles/Standard/Crewmate/Miscellaneous/Addict.cs
+++ b/Roles/Standard/Crewmate/Miscellaneous/Addict.cs
@@ -55,11 +55,12 @@ public class Addict : RoleBase
PlayerIdList.Add(playerId);
SuicideTimer = new CountdownTimer(TimeLimit.GetFloat(), () =>
{
+ SuicideTimer = null;
+
var player = playerId.GetPlayer();
if (player == null || !player.IsAlive()) return;
player.Suicide();
- SuicideTimer = null;
if (player.AmOwner)
Achievements.Type.OutOfTime.Complete();
@@ -95,11 +96,12 @@ public class Addict : RoleBase
SuicideTimer?.Dispose();
SuicideTimer = new CountdownTimer(TimeLimit.GetFloat(), () =>
{
+ SuicideTimer = null;
+
var player = AddictId.GetPlayer();
if (player == null || !player.IsAlive()) return;
player.Suicide();
- SuicideTimer = null;
if (player.AmOwner)
Achievements.Type.OutOfTime.Complete();
diff --git a/Roles/Standard/Crewmate/Support/Aid.cs b/Roles/Standard/Crewmate/Support/Aid.cs
index e676b0e63..6078765c0 100644
--- a/Roles/Standard/Crewmate/Support/Aid.cs
+++ b/Roles/Standard/Crewmate/Support/Aid.cs
@@ -115,7 +115,7 @@ public class Aid : RoleBase
public void ReceiveRPC(MessageReader reader)
{
byte id = reader.ReadByte();
- ShieldedPlayers[id] = new CountdownTimer(AidDur.GetInt(), onCanceled: () => ShieldedPlayers.Remove(id));
+ ShieldedPlayers[id] = new CountdownTimer(AidDur.GetInt(), () => ShieldedPlayers.Remove(id), onCanceled: () => ShieldedPlayers.Remove(id));
}
public override string GetSuffix(PlayerControl seer, PlayerControl target, bool hud = false, bool meeting = false)
diff --git a/Roles/Standard/Impostor/Killing/BountyHunter.cs b/Roles/Standard/Impostor/Killing/BountyHunter.cs
index c33b296af..9b21231d3 100644
--- a/Roles/Standard/Impostor/Killing/BountyHunter.cs
+++ b/Roles/Standard/Impostor/Killing/BountyHunter.cs
@@ -148,7 +148,7 @@ public class BountyHunter : RoleBase
if (Timer.Remaining.TotalSeconds > 15) return;
Utils.NotifyRoles(SpecifySeer: player, SpecifyTarget: player, SendOption: SendOption.None);
- });
+ }, onCanceled: () => Timer = null);
Utils.SendRPC(CustomRPC.SyncRoleData, playerId, true);
Logger.Info($"{player.GetNameWithRole().RemoveHtmlTags()}: Reset Target", "BountyHunter");
diff --git a/Roles/Standard/Impostor/Killing/Mercenary.cs b/Roles/Standard/Impostor/Killing/Mercenary.cs
index b0a398d69..1f508c64c 100644
--- a/Roles/Standard/Impostor/Killing/Mercenary.cs
+++ b/Roles/Standard/Impostor/Killing/Mercenary.cs
@@ -53,17 +53,12 @@ public class Mercenary : RoleBase
Timer?.Dispose();
Timer = new CountdownTimer(TimeLimit.GetInt() + add, () =>
{
+ Timer = null;
+
var player = MercenaryId.GetPlayer();
-
- if (player == null || !player.IsAlive())
- {
- Timer.Dispose();
- Timer = null;
- return;
- }
+ if (player == null || !player.IsAlive()) return;
player.Suicide();
- Timer = null;
if (player.AmOwner)
Achievements.Type.OutOfTime.Complete();
diff --git a/Roles/Standard/Impostor/Killing/Wasp.cs b/Roles/Standard/Impostor/Killing/Wasp.cs
index c2eb0188f..b97300b37 100644
--- a/Roles/Standard/Impostor/Killing/Wasp.cs
+++ b/Roles/Standard/Impostor/Killing/Wasp.cs
@@ -91,7 +91,7 @@ public class Wasp : RoleBase
{
target.Suicide(PlayerState.DeathReason.Stung, killer);
DelayedKills.Remove(target.PlayerId);
- });
+ }, cancelOnMeeting: false, onCanceled: DelayedKills.Clear);
else
MeetingKills.Add(target.PlayerId);
@@ -154,7 +154,7 @@ public class Wasp : RoleBase
target.SyncSettings();
target.SetKillCooldown(StingCooldown.GetInt());
}
- }, onTick: () => Utils.NotifyRoles(SpecifySeer: target, SpecifyTarget: target));
+ }, onTick: () => Utils.NotifyRoles(SpecifySeer: target, SpecifyTarget: target), cancelOnMeeting: false, onCanceled: () => SwarmModeEnd = null);
Utils.SendRPC(CustomRPC.SyncRoleData, WaspPC.PlayerId);
target.SyncSettings();
target.SetKillCooldown(0.01f);
diff --git a/Roles/Standard/Impostor/Miscellaneous/AntiAdminer.cs b/Roles/Standard/Impostor/Miscellaneous/AntiAdminer.cs
index 132f58357..71018d2a5 100644
--- a/Roles/Standard/Impostor/Miscellaneous/AntiAdminer.cs
+++ b/Roles/Standard/Impostor/Miscellaneous/AntiAdminer.cs
@@ -100,7 +100,7 @@ internal class AntiAdminer : RoleBase
{
foreach (PlayerControl player in PlayersNearDevices.Keys.ToValidPlayers().Where(x => x.IsAlive()))
Utils.NotifyRoles(SpecifySeer: player, SpecifyTarget: player);
- });
+ }, onCanceled: () => ExtraAbilityTimer = null);
pc.RpcResetAbilityCooldown();
Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc);
diff --git a/Roles/Standard/Impostor/Miscellaneous/Gambler.cs b/Roles/Standard/Impostor/Miscellaneous/Gambler.cs
index 046231f40..d2227ea41 100644
--- a/Roles/Standard/Impostor/Miscellaneous/Gambler.cs
+++ b/Roles/Standard/Impostor/Miscellaneous/Gambler.cs
@@ -162,14 +162,9 @@ public class Gambler : RoleBase
killer.Notify(string.Format(GetString("GamblerGet.DelayedKill"), KillDelay.GetInt()));
WaitingDelayedKills.TryAdd(target.PlayerId, new CountdownTimer(KillDelay.GetInt(), () =>
{
- if (target == null || !target.IsAlive())
- {
- WaitingDelayedKills.Remove(target.PlayerId);
- return;
- }
-
- target.Suicide(PlayerState.DeathReason.Poison, killer);
WaitingDelayedKills.Remove(target.PlayerId);
+ if (target == null || !target.IsAlive()) return;
+ target.Suicide(PlayerState.DeathReason.Poison, killer);
}));
return false;
case 2: // Shield
diff --git a/Roles/Standard/Impostor/Support/Deathpact.cs b/Roles/Standard/Impostor/Support/Deathpact.cs
index 7047913fc..5e753e4de 100644
--- a/Roles/Standard/Impostor/Support/Deathpact.cs
+++ b/Roles/Standard/Impostor/Support/Deathpact.cs
@@ -145,7 +145,7 @@ public class Deathpact : RoleBase
}
PlayersInDeathpact.ForEach(x => NotifyRoles(SpecifySeer: x, SpecifyTarget: x, SendOption: SendOption.None));
- });
+ }, cancelOnMeeting: false, onCanceled: () => DeathpactTime = null);
ActiveDeathpacts.Add(pc.PlayerId);
if (ShowArrowsToOtherPlayersInPact.GetBool())
diff --git a/Roles/Standard/Neutral/Killing/Amogus.cs b/Roles/Standard/Neutral/Killing/Amogus.cs
index 863d008eb..278b1b8b5 100644
--- a/Roles/Standard/Neutral/Killing/Amogus.cs
+++ b/Roles/Standard/Neutral/Killing/Amogus.cs
@@ -23,14 +23,14 @@ public class Amogus : RoleBase
private static OptionItem CanVent;
private static OptionItem ImpostorVision;
- private CountdownTimer AmogusFormEndTS;
+ private CountdownTimer AmogusFormTimer;
private byte AmogusID;
private Levels CurrentLevel;
public int ExtraVotes;
public override bool IsEnable => On;
- public override bool SeesArrowsToDeadBodies => CurrentLevel >= Levels.SuspiciousSus && SuspiciousSusArrowsToBodies.GetBool() && AmogusFormEndTS != null;
+ public override bool SeesArrowsToDeadBodies => CurrentLevel >= Levels.SuspiciousSus && SuspiciousSusArrowsToBodies.GetBool() && AmogusFormTimer != null;
public override void SetupCustomOption()
{
@@ -57,7 +57,7 @@ public class Amogus : RoleBase
On = true;
Instances.Add(this);
AmogusID = playerId;
- AmogusFormEndTS = null;
+ AmogusFormTimer = null;
CurrentLevel = (Levels)StartingLevel.GetValue();
ExtraVotes = 0;
}
@@ -76,7 +76,7 @@ public class Amogus : RoleBase
public override bool CanUseKillButton(PlayerControl pc)
{
- return AmogusFormEndTS == null;
+ return AmogusFormTimer == null;
}
public override void ApplyGameOptions(IGameOptions opt, byte id)
@@ -103,12 +103,12 @@ public class Amogus : RoleBase
if (CurrentLevel >= Levels.SuspiciousSus)
Main.EnumerateAlivePlayerControls().Do(x => TargetArrow.Add(AmogusID, x.PlayerId));
- AmogusFormEndTS = new CountdownTimer(AbilityDuration.GetInt(), () =>
+ AmogusFormTimer = new CountdownTimer(AbilityDuration.GetInt(), () =>
{
if (pc == null || !pc.IsAlive()) return;
FormExpired();
Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc);
- }, onCanceled: () => AmogusFormEndTS = null);
+ }, onCanceled: () => AmogusFormTimer = null);
Utils.SendRPC(CustomRPC.SyncRoleData, AmogusID, 1);
Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc);
}
@@ -124,7 +124,7 @@ public class Amogus : RoleBase
TargetArrow.RemoveAllTarget(AmogusID);
LocateArrow.RemoveAllTarget(AmogusID);
- AmogusFormEndTS = null;
+ AmogusFormTimer = null;
}
public override void OnMurder(PlayerControl killer, PlayerControl target)
@@ -154,13 +154,13 @@ public class Amogus : RoleBase
public override void OnReportDeadBody()
{
- AmogusFormEndTS?.Dispose();
+ AmogusFormTimer?.Dispose();
FormExpired();
}
public static void OnAnyoneDead(PlayerControl target)
{
- Instances.DoIf(x => x.CurrentLevel >= Levels.SuspiciousSus && x.AmogusFormEndTS != null, x => TargetArrow.Remove(x.AmogusID, target.PlayerId));
+ Instances.DoIf(x => x.CurrentLevel >= Levels.SuspiciousSus && x.AmogusFormTimer != null, x => TargetArrow.Remove(x.AmogusID, target.PlayerId));
}
public void ReceiveRPC(MessageReader reader)
@@ -168,7 +168,7 @@ public class Amogus : RoleBase
switch (reader.ReadPackedInt32())
{
case 1:
- AmogusFormEndTS = new CountdownTimer(AbilityDuration.GetInt(), () => AmogusFormEndTS = null, onCanceled: () => AmogusFormEndTS = null);
+ AmogusFormTimer = new CountdownTimer(AbilityDuration.GetInt(), () => AmogusFormTimer = null, onCanceled: () => AmogusFormTimer = null);
break;
case 2:
CurrentLevel = (Levels)reader.ReadPackedInt32();
@@ -184,7 +184,7 @@ public class Amogus : RoleBase
if (seer.PlayerId != AmogusID || seer.PlayerId != target.PlayerId || (seer.IsModdedClient() && !hud) || meeting) return string.Empty;
var sb = new StringBuilder();
- if (AmogusFormEndTS != null) sb.Append($"\u25a9 ({(int)Math.Ceiling(AmogusFormEndTS.Remaining.TotalSeconds)}s)\n");
+ if (AmogusFormTimer != null) sb.Append($"\u25a9 ({(int)Math.Ceiling(AmogusFormTimer.Remaining.TotalSeconds)}s)\n");
if (!hud) sb.Append("");
sb.Append(string.Format(Translator.GetString("Amogus.Suffix"), Translator.GetString($"Amogus.Levels.{CurrentLevel}")));
if (!hud) sb.Append("");
diff --git a/Roles/Standard/Neutral/Killing/Duality.cs b/Roles/Standard/Neutral/Killing/Duality.cs
index cddf2b248..c63dc1d83 100644
--- a/Roles/Standard/Neutral/Killing/Duality.cs
+++ b/Roles/Standard/Neutral/Killing/Duality.cs
@@ -100,6 +100,7 @@ public class Duality : RoleBase
if (pc == null || !pc.IsAlive()) return;
pc.Suicide();
if (pc.AmOwner) Achievements.Type.OutOfTime.Complete();
+ Timer = null;
}, onTick: () =>
{
if (pc == null || !pc.IsAlive())
@@ -109,7 +110,7 @@ public class Duality : RoleBase
}
Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc);
- });
+ }, onCanceled: () => Timer = null);
Utils.SendRPC(CustomRPC.SyncRoleData, DualityId, KillingPhase);
}
@@ -117,7 +118,7 @@ public class Duality : RoleBase
{
KillingPhase = reader.ReadBoolean();
Timer?.Dispose();
- Timer = new CountdownTimer(Time.GetInt());
+ Timer = new CountdownTimer(Time.GetInt(), () => Timer = null, onCanceled: () => Timer = null);
}
public override string GetSuffix(PlayerControl seer, PlayerControl target, bool hud = false, bool meeting = false)
diff --git a/Roles/Standard/Neutral/Killing/NoteKiller.cs b/Roles/Standard/Neutral/Killing/NoteKiller.cs
index 5f626dcae..d9ec4d509 100644
--- a/Roles/Standard/Neutral/Killing/NoteKiller.cs
+++ b/Roles/Standard/Neutral/Killing/NoteKiller.cs
@@ -42,7 +42,7 @@ public class NoteKiller : RoleBase
public static Dictionary RealNames = [];
private static Dictionary ShownClues = [];
- private static CountdownTimer ShowClueEndTimeStamp;
+ private static CountdownTimer ShowClueTimer;
public static int Kills;
public static bool CanGuess;
@@ -72,7 +72,7 @@ public class NoteKiller : RoleBase
RealNames = [];
ShownClues = [];
- ShowClueEndTimeStamp = null;
+ ShowClueTimer = null;
Kills = 0;
LateTask.New(() =>
@@ -155,14 +155,14 @@ public class NoteKiller : RoleBase
Utils.SendRPC(CustomRPC.SyncRoleData, NoteKillerID, 1, data.ID, shownClue);
}
- ShowClueEndTimeStamp = new CountdownTimer(ClueShowDuration.GetInt(), () =>
+ ShowClueTimer = new CountdownTimer(ClueShowDuration.GetInt(), () =>
{
- ShowClueEndTimeStamp = null;
+ ShowClueTimer = null;
ShownClues.Clear();
Utils.NotifyRoles(SpecifySeer: pc);
}, onTick: () => Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc, SendOption: SendOption.None), onCanceled: () =>
{
- ShowClueEndTimeStamp = null;
+ ShowClueTimer = null;
ShownClues.Clear();
});
Utils.SendRPC(CustomRPC.SyncRoleData, NoteKillerID, 2);
@@ -188,13 +188,13 @@ public class NoteKiller : RoleBase
ShownClues[reader.ReadByte()] = reader.ReadString();
break;
case 2:
- ShowClueEndTimeStamp = new CountdownTimer(ClueShowDuration.GetInt(), () =>
+ ShowClueTimer = new CountdownTimer(ClueShowDuration.GetInt(), () =>
{
- ShowClueEndTimeStamp = null;
+ ShowClueTimer = null;
ShownClues.Clear();
}, onCanceled: () =>
{
- ShowClueEndTimeStamp = null;
+ ShowClueTimer = null;
ShownClues.Clear();
});
break;
@@ -206,8 +206,8 @@ public class NoteKiller : RoleBase
if (seer.PlayerId == target.PlayerId && CustomRoles.NoteKiller.RoleExist() && seer.PlayerId != NoteKillerID && !meeting && RealNames.TryGetValue(seer.PlayerId, out string ownName))
return MeetingStates.FirstMeeting ? string.Format(Translator.GetString("NoteKiller.OthersSelfSuffix"), CustomRoles.NoteKiller.ToColoredString(), ownName) : string.Format(Translator.GetString("NoteKiller.OthersSelfSuffixShort"), ownName);
- if (seer.PlayerId != NoteKillerID || meeting || ShowClueEndTimeStamp == null || ShownClues.Count == 0) return string.Empty;
+ if (seer.PlayerId != NoteKillerID || meeting || ShowClueTimer == null || ShownClues.Count == 0) return string.Empty;
if (ShownClues.TryGetValue(target.PlayerId, out string clue)) return clue;
- return seer.PlayerId == target.PlayerId ? $"\u25a9 ({(int)Math.Ceiling(ShowClueEndTimeStamp.Remaining.TotalSeconds)}s)" : string.Empty;
+ return seer.PlayerId == target.PlayerId ? $"\u25a9 ({(int)Math.Ceiling(ShowClueTimer.Remaining.TotalSeconds)}s)" : string.Empty;
}
}
\ No newline at end of file
diff --git a/Roles/Standard/Neutral/Killing/Quarry.cs b/Roles/Standard/Neutral/Killing/Quarry.cs
index ff558c287..b42120e31 100644
--- a/Roles/Standard/Neutral/Killing/Quarry.cs
+++ b/Roles/Standard/Neutral/Killing/Quarry.cs
@@ -130,7 +130,7 @@ public class Quarry : RoleBase
Utils.NotifyRoles(SpecifySeer: shapeshifter, SpecifyTarget: shapeshifter);
Utils.NotifyRoles(SpecifySeer: target, SpecifyTarget: target);
- });
+ }, cancelOnMeeting: false, onCanceled: () => SeekTimer = null);
TargetId = target.PlayerId;
TargetKCD = Main.KillTimers[TargetId];
Utils.SendRPC(CustomRPC.SyncRoleData, QuarryId, 1, TargetId);