diff --git a/Gamemodes/CaptureTheFlag.cs b/Gamemodes/CaptureTheFlag.cs
index 18d9d0f73..d03909cf2 100644
--- a/Gamemodes/CaptureTheFlag.cs
+++ b/Gamemodes/CaptureTheFlag.cs
@@ -869,6 +869,8 @@ public static class CaptureTheFlag
.SendMessage();
}
+ bool notify = false;
+
if (TemporarilyOutPlayers.TryGetValue(__instance.PlayerId, out long endTS))
{
if (now >= endTS)
@@ -881,7 +883,7 @@ public static class CaptureTheFlag
SpawnProtectionTimes[__instance.PlayerId] = Utils.TimeStamp + SpawnProtectionTime.GetInt();
}
- if (!notified) Utils.NotifyRoles(SpecifySeer: __instance, SpecifyTarget: __instance, SendOption: SendOption.None);
+ notify = true;
}
if (SpawnProtectionTimes.TryGetValue(__instance.PlayerId, out long protectionEndTS))
@@ -889,9 +891,11 @@ public static class CaptureTheFlag
if (now >= protectionEndTS)
SpawnProtectionTimes.Remove(__instance.PlayerId);
- if (!notified)
- Utils.NotifyRoles(SpecifySeer: __instance, SpecifyTarget: __instance, SendOption: SendOption.None);
+ notify = true;
}
+
+ if (!notified && notify && PerSecondUpdateScheduler.ShouldRunUpdate(__instance.PlayerId))
+ Utils.NotifyRoles(SpecifySeer: __instance, SpecifyTarget: __instance, SendOption: SendOption.None);
}
}
}
diff --git a/Modules/CustomRpcSender.cs b/Modules/CustomRpcSender.cs
index 7b72ab337..cc2a1cae5 100644
--- a/Modules/CustomRpcSender.cs
+++ b/Modules/CustomRpcSender.cs
@@ -547,7 +547,7 @@ public static class CustomRpcSenderExtensions
sender.checkLength = false;
- if (sender.stream.Length + GetSetNameRpcSize(player.NetId, name) > 1100)
+ if (sender.stream.Length + GetSetNameRpcSize(player.NetId, name) > 1180)
{
bool packed = sender.packed;
sender.SendMessage();
diff --git a/Modules/Debugger.cs b/Modules/Debugger.cs
index c0125a886..dd2574007 100644
--- a/Modules/Debugger.cs
+++ b/Modules/Debugger.cs
@@ -239,6 +239,7 @@ public class CustomLogger
private const string UnityTag = "-unity";
+ private static string LastAppend;
private static CustomLogger PrivateInstance;
private float timer = 0.5f;
@@ -325,11 +326,18 @@ public class CustomLogger
string unityTag = fromUnity && !containsException ? UnityTag : string.Empty;
- Builder.Append($"""
+ string element = $"""
{message}
- """);
+ """;
+
+ if (LastAppend == element)
+ element = "+";
+ else
+ LastAppend = element;
+
+ Builder.Append(element);
#if DEBUG
Finish(false);
diff --git a/Modules/GameOptionsSender/PlayerGameOptionsSender.cs b/Modules/GameOptionsSender/PlayerGameOptionsSender.cs
index 8d3f01743..8d6a8bb4d 100644
--- a/Modules/GameOptionsSender/PlayerGameOptionsSender.cs
+++ b/Modules/GameOptionsSender/PlayerGameOptionsSender.cs
@@ -64,13 +64,21 @@ public sealed class PlayerGameOptionsSender(PlayerControl player) : GameOptionsS
if (PackedWriterMessages > 0 && PackedWriter != null)
{
- PackedWriter.EndMessage();
- var capturedWriter = PackedWriter;
- DataFlagRateLimiter.Enqueue(() =>
+ try
{
- AmongUsClient.Instance.SendOrDisconnect(capturedWriter);
- capturedWriter.Recycle();
- }, cleanup: capturedWriter.Recycle);
+ PackedWriter.EndMessage();
+ var capturedWriter = PackedWriter;
+ DataFlagRateLimiter.Enqueue(() =>
+ {
+ AmongUsClient.Instance.SendOrDisconnect(capturedWriter);
+ capturedWriter.Recycle();
+ }, cleanup: capturedWriter.Recycle);
+ }
+ catch
+ {
+ try { PackedWriter.Recycle(); }
+ catch { }
+ }
}
PackedWriter = MessageWriter.Get(SendOption.Reliable);
@@ -95,15 +103,23 @@ public sealed class PlayerGameOptionsSender(PlayerControl player) : GameOptionsS
{
if (PackedWriterMessages > 0)
{
- PackedWriter.EndMessage();
- Logger.Info($"PackedWriter flush queued - Length: {PackedWriter.Length}, Messages: {PackedWriterMessages}", "SendAllImmediately");
- var capturedWriter = PackedWriter;
- qa = DataFlagRateLimiter.Enqueue(() =>
+ try
{
- AmongUsClient.Instance.SendOrDisconnect(capturedWriter);
- capturedWriter.Recycle();
- Logger.Info("PackedWriter flush queue finished and sent", "SendAllImmediately");
- }, cleanup: capturedWriter.Recycle);
+ PackedWriter.EndMessage();
+ Logger.Info($"PackedWriter flush queued - Length: {PackedWriter.Length}, Messages: {PackedWriterMessages}", "SendAllImmediately");
+ var capturedWriter = PackedWriter;
+ qa = DataFlagRateLimiter.Enqueue(() =>
+ {
+ AmongUsClient.Instance.SendOrDisconnect(capturedWriter);
+ capturedWriter.Recycle();
+ Logger.Info("PackedWriter flush queue finished and sent", "SendAllImmediately");
+ }, cleanup: capturedWriter.Recycle);
+ }
+ catch
+ {
+ try { PackedWriter.Recycle(); }
+ catch { }
+ }
}
else
{
@@ -304,15 +320,23 @@ public sealed class PlayerGameOptionsSender(PlayerControl player) : GameOptionsS
if (PackedWriter.Length > 1000 || PackedWriterMessages >= AmongUsClient.Instance.GetMaxMessagePackingLimit())
{
- PackedWriter.EndMessage();
- Logger.Info($"PackedWriter flush queued - Length: {PackedWriter.Length}, Messages: {PackedWriterMessages}", "SendOptionsArray");
- var capturedWriter = PackedWriter;
- DataFlagRateLimiter.Enqueue(() =>
+ try
{
- AmongUsClient.Instance.SendOrDisconnect(capturedWriter);
- capturedWriter.Recycle();
- Logger.Info("PackedWriter flush queue finished and sent", "SendOptionsArray");
- }, cleanup: capturedWriter.Recycle);
+ PackedWriter.EndMessage();
+ Logger.Info($"PackedWriter flush queued - Length: {PackedWriter.Length}, Messages: {PackedWriterMessages}", "SendOptionsArray");
+ var capturedWriter = PackedWriter;
+ DataFlagRateLimiter.Enqueue(() =>
+ {
+ AmongUsClient.Instance.SendOrDisconnect(capturedWriter);
+ capturedWriter.Recycle();
+ Logger.Info("PackedWriter flush queue finished and sent", "SendOptionsArray");
+ }, cleanup: capturedWriter.Recycle);
+ }
+ catch
+ {
+ try { PackedWriter.Recycle(); }
+ catch { }
+ }
PackedWriterMessages = 0;
PackedWriter = MessageWriter.Get(SendOption.Reliable);
PackedWriter.StartMessage(26);
diff --git a/Resources/Lang/en_US.json b/Resources/Lang/en_US.json
index e5aa903d6..5839f5584 100644
--- a/Resources/Lang/en_US.json
+++ b/Resources/Lang/en_US.json
@@ -913,6 +913,7 @@
"Helper": "Helper",
"HelperInfo": "Complete Tasks For Others",
"HelperInfoLong": "(Crewmates):\\nAs the Helper, whenever you complete a task, a random crewmate will also have one of their tasks completed.",
+ "Helper.AbilityWorksAfterDeath": "Ability Works After Death",
"HelperCompletedTaskForYou": "The {0} completed a task for you!",
"Ignitor": "Ignitor",
"IgnitorInfo": "Light Candles for High Vision",
diff --git a/Roles/Standard/Crewmate/Support/Helper.cs b/Roles/Standard/Crewmate/Support/Helper.cs
index 1bd58e735..8507f6269 100644
--- a/Roles/Standard/Crewmate/Support/Helper.cs
+++ b/Roles/Standard/Crewmate/Support/Helper.cs
@@ -7,11 +7,14 @@ public class Helper : RoleBase
{
public static bool On;
+ private static OptionItem AbilityWorksAfterDeath;
+
public override bool IsEnable => On;
public override void SetupCustomOption()
{
StartSetup(651300)
+ .AutoSetupOption(ref AbilityWorksAfterDeath, true)
.CreateOverrideTasksData();
}
@@ -27,6 +30,7 @@ public class Helper : RoleBase
public override void OnTaskComplete(PlayerControl pc, int completedTaskCount, int totalTaskCount)
{
+ if (!AbilityWorksAfterDeath.GetBool() && !pc.IsAlive()) return;
var randomPlayer = Main.EnumeratePlayerControls().Without(pc).Where(x => x.Is(Team.Crewmate)).Select(x => (pc: x, ts: x.GetTaskState())).Where(x => !x.ts.IsTaskFinished && x.ts.HasTasks).Select(x => x.pc).RandomElement();
#if IL2CPP
var incompleteTasks = randomPlayer.myTasks.FindAll((Il2CppSystem.Predicate)(x => !x.IsComplete));
diff --git a/Roles/Standard/Impostor/Support/Blackmailer.cs b/Roles/Standard/Impostor/Support/Blackmailer.cs
index 13803d281..9240888b0 100644
--- a/Roles/Standard/Impostor/Support/Blackmailer.cs
+++ b/Roles/Standard/Impostor/Support/Blackmailer.cs
@@ -63,6 +63,7 @@ internal class Blackmailer : RoleBase
public override void AfterMeetingTasks()
{
+ NumBlackmailedThisRound = 0;
if (AbilityExpires.GetValue() == 0) BlackmailedPlayerIds.Clear();
}
diff --git a/Roles/Standard/Neutral/Benign/Amnesiac.cs b/Roles/Standard/Neutral/Benign/Amnesiac.cs
index 8d03c432d..d6c2be24e 100644
--- a/Roles/Standard/Neutral/Benign/Amnesiac.cs
+++ b/Roles/Standard/Neutral/Benign/Amnesiac.cs
@@ -276,7 +276,16 @@ public class Amnesiac : RoleBase
if (HasArrowsToDeadBodies.GetBool())
{
var pos = target.Pos();
- Instances.ForEach(x => LateTask.New(() => LocateArrow.Add(x.AmnesiacId, pos), IRandom.Instance.Next(ArrowMinDelay.GetInt(), ArrowMaxDelay.GetInt() + 1), "Amnesiac Arrow"));
+ Instances.ForEach(x =>
+ {
+ LateTask.New(() =>
+ {
+ LocateArrow.Add(x.AmnesiacId, pos);
+ var pc = x.AmnesiacId.GetPlayer();
+ if (!pc || !pc.IsAlive()) return;
+ Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc);
+ }, IRandom.Instance.Next(ArrowMinDelay.GetInt(), ArrowMaxDelay.GetInt() + 1), "Amnesiac Arrow");
+ });
}
}