diff --git a/GameMode/CaptureTheFlag.cs b/GameMode/CaptureTheFlag.cs index 0669e3774..b5a7452e4 100644 --- a/GameMode/CaptureTheFlag.cs +++ b/GameMode/CaptureTheFlag.cs @@ -48,7 +48,7 @@ public static class CaptureTheFlag "CTF_GameEndCriteria.TimeLimit" ]; - public static (Color Color, string Team) WinnerData = (Color.white, "No one wins"); + public static (UnityEngine.Color Color, string Team) WinnerData = (Color.white, "No one wins"); private static Dictionary PlayerTeams = []; private static Dictionary TeamData = []; @@ -66,23 +66,23 @@ public static class CaptureTheFlag private static (Vector2 Position, string RoomName) BlueFlagBase => Main.CurrentMap switch { - MapNames.Skeld => (new(16.5f, -4.8f), Translator.GetString(SystemTypes.Nav.ToString())), - MapNames.MiraHQ => (new(-4.5f, 2.0f), Translator.GetString(SystemTypes.Launchpad.ToString())), - MapNames.Dleks => (new(-16.5f, -4.8f), Translator.GetString(SystemTypes.Nav.ToString())), - MapNames.Polus => (new(9.5f, -12.5f), Translator.GetString(SystemTypes.Electrical.ToString())), - MapNames.Airship => (new(-23.5f, -1.6f), Translator.GetString(SystemTypes.Cockpit.ToString())), - MapNames.Fungle => (new(-15.5f, -7.5f), Translator.GetString(SystemTypes.Kitchen.ToString())), + MapNames.Skeld => (new(16.5f, -4.8f), Translator.GetString(nameof(SystemTypes.Nav))), + MapNames.MiraHQ => (new(-4.5f, 2.0f), Translator.GetString(nameof(SystemTypes.Launchpad))), + MapNames.Dleks => (new(-16.5f, -4.8f), Translator.GetString(nameof(SystemTypes.Nav))), + MapNames.Polus => (new(9.5f, -12.5f), Translator.GetString(nameof(SystemTypes.Electrical))), + MapNames.Airship => (new(-23.5f, -1.6f), Translator.GetString(nameof(SystemTypes.Cockpit))), + MapNames.Fungle => (new(-15.5f, -7.5f), Translator.GetString(nameof(SystemTypes.Kitchen))), _ => (Vector2.zero, string.Empty) }; private static (Vector2 Position, string RoomName) YellowFlagBase => Main.CurrentMap switch { - MapNames.Skeld => (new(-20.5f, -5.5f), Translator.GetString(SystemTypes.Reactor.ToString())), - MapNames.MiraHQ => (new(17.8f, 23.0f), Translator.GetString(SystemTypes.Greenhouse.ToString())), - MapNames.Dleks => (new(20.5f, -5.5f), Translator.GetString(SystemTypes.Reactor.ToString())), - MapNames.Polus => (new(36.5f, -7.5f), Translator.GetString(SystemTypes.Laboratory.ToString())), - MapNames.Airship => (new(33.5f, -1.5f), Translator.GetString(SystemTypes.CargoBay.ToString())), - MapNames.Fungle => (new(22.2f, 13.7f), Translator.GetString(SystemTypes.Comms.ToString())), + MapNames.Skeld => (new(-20.5f, -5.5f), Translator.GetString(nameof(SystemTypes.Reactor))), + MapNames.MiraHQ => (new(17.8f, 23.0f), Translator.GetString(nameof(SystemTypes.Greenhouse))), + MapNames.Dleks => (new(20.5f, -5.5f), Translator.GetString(nameof(SystemTypes.Reactor))), + MapNames.Polus => (new(36.5f, -7.5f), Translator.GetString(nameof(SystemTypes.Laboratory))), + MapNames.Airship => (new(33.5f, -1.5f), Translator.GetString(nameof(SystemTypes.CargoBay))), + MapNames.Fungle => (new(22.2f, 13.7f), Translator.GetString(nameof(SystemTypes.Comms))), _ => (Vector2.zero, string.Empty) }; @@ -300,6 +300,7 @@ public static class CaptureTheFlag DefaultOutfits = Main.AllPlayerControls.ToDictionary(x => x.PlayerId, x => x.Data.DefaultOutfit); TemporarilyOutPlayers = []; ValidTag = false; + SendRPC(); } public static void OnGameStart() @@ -536,6 +537,44 @@ public static class CaptureTheFlag AURoleOptions.PhantomCooldown = 5f; } + private static void SendRPC() + { + var w = Utils.CreateRPC(CustomRPC.CTFSync); + + w.Write(WinnerData.Color); + w.Write(WinnerData.Team); + + w.Write(PlayerData.Count); + + foreach ((byte id, CTFPlayerData data) in PlayerData) + { + w.Write(id); + w.Write(data.FlagTime); + w.Write(data.TagCount); + } + + Utils.EndRPC(w); + } + + public static void ReceiveRPC(MessageReader reader) + { + WinnerData.Color = reader.ReadColor(); + WinnerData.Team = reader.ReadString(); + + int count = reader.ReadInt32(); + + for (int i = 0; i < count; i++) + { + byte id = reader.ReadByte(); + + if (!PlayerData.TryGetValue(id, out CTFPlayerData data)) + PlayerData[id] = data = new CTFPlayerData(); + + data.FlagTime = reader.ReadSingle(); + data.TagCount = reader.ReadInt32(); + } + } + private static Color GetTeamColor(this CTFTeam team) { return team switch @@ -594,6 +633,7 @@ public static class CaptureTheFlag WinnerData = (team.GetTeamColor(), team.GetTeamName()); CustomWinnerHolder.WinnerIds = Players; Logger.Info($"{team} team wins", "CTF"); + SendRPC(); } public void Update() diff --git a/GameMode/CustomHnS.cs b/GameMode/CustomHnS.cs index 6380cfb2c..4ebb4a95d 100644 --- a/GameMode/CustomHnS.cs +++ b/GameMode/CustomHnS.cs @@ -360,7 +360,7 @@ internal static class CustomHnS } // If there are no crew roles left, the game is over and only impostors win - if (alivePlayers.All(x => PlayerRoles[x.PlayerId].Interface.Team != Team.Crewmate)) + if (alivePlayers.All(x => PlayerRoles.TryGetValue(x.PlayerId, out var role) && role.Interface.Team != Team.Crewmate)) { reason = GameOverReason.HideAndSeek_ImpostorsByKills; SetWinners(CustomWinner.Seeker, Team.Impostor); @@ -387,14 +387,7 @@ internal static class CustomHnS public static void AddFoxesToWinners() { - List foxes = Main.PlayerStates.Where(x => x.Value.MainRole == CustomRoles.Fox).Select(x => x.Key).ToList(); - - foxes.RemoveAll(x => - { - PlayerControl pc = Utils.GetPlayerById(x); - return pc == null || !pc.IsAlive(); - }); - + List foxes = Main.PlayerStates.Values.Where(x => x.MainRole == CustomRoles.Fox && x.Player != null && x.Player.IsAlive()).Select(x => x.Player.PlayerId).ToList(); if (foxes.Count == 0) return; CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Fox); diff --git a/GameMode/HideAndSeekRoles/Hider.cs b/GameMode/HideAndSeekRoles/Hider.cs index 7dd469452..a7c2aca2d 100644 --- a/GameMode/HideAndSeekRoles/Hider.cs +++ b/GameMode/HideAndSeekRoles/Hider.cs @@ -74,16 +74,16 @@ internal class Hider : RoleBase, IHideAndSeekRole public static void OnSpecificTaskComplete(PlayerControl pc, PlayerTask task) { - int time = !AddTasksFromListPatch.DisableTasksSettings.TryGetValue(task.TaskType, out var setting) - ? TimeDecreaseOnOtherTaskComplete.GetInt() - : setting.Parent.Name switch - { - "DisableShortTasks" => TimeDecreaseOnShortTaskComplete.GetInt(), - "DisableCommonTasks" => TimeDecreaseOnCommonTaskComplete.GetInt(), - "DisableLongTasks" => TimeDecreaseOnLongTaskComplete.GetInt(), - "DisableOtherTasks" => TimeDecreaseOnSituationalTaskComplete.GetInt(), - _ => TimeDecreaseOnOtherTaskComplete.GetInt() - }; + if (task is not NormalPlayerTask npt) return; + + int time = npt.Length switch + { + NormalPlayerTask.TaskLength.Short => TimeDecreaseOnShortTaskComplete.GetInt(), + NormalPlayerTask.TaskLength.Common => TimeDecreaseOnCommonTaskComplete.GetInt(), + NormalPlayerTask.TaskLength.Long => TimeDecreaseOnLongTaskComplete.GetInt(), + NormalPlayerTask.TaskLength.None => TimeDecreaseOnSituationalTaskComplete.GetInt(), + _ => TimeDecreaseOnOtherTaskComplete.GetInt() + }; CustomHnS.TimeLeft -= time; pc.Notify(string.Format(Translator.GetString("TimeDecreased"), time)); diff --git a/GameMode/KingOfTheZones.cs b/GameMode/KingOfTheZones.cs index 19a01f11f..28e56890f 100644 --- a/GameMode/KingOfTheZones.cs +++ b/GameMode/KingOfTheZones.cs @@ -29,7 +29,7 @@ public static class KingOfTheZones private static OptionItem MaxGameLength; private static OptionItem SpawnProtectionTime; - public static (Color Color, string Team) WinnerData = (Color.white, "No one wins"); + public static (UnityEngine.Color Color, string Team) WinnerData = (Color.white, "No one wins"); private static readonly Dictionary>> DefaultZones = new() { @@ -251,6 +251,7 @@ public static class KingOfTheZones ChatCommands.Spectators.Do(x => Main.AllPlayerSpeed[x] = normalSpeed); GameGoing = false; + SendRPC(); } public static IEnumerator GameStart() @@ -307,7 +308,7 @@ public static class KingOfTheZones x => x.Key != id && x.Value == team, // ReSharper disable once AccessToModifiedClosure x => writer.RpcSetRole(x.Key.GetPlayer(), RoleTypes.Impostor, targetClientId)); - + if (writer.stream.Length > 800) { writer.SendMessage(); @@ -584,6 +585,7 @@ public static class KingOfTheZones Color color = winner.GetColor(); CustomWinnerHolder.WinnerIds = PlayerTeams.Where(x => x.Value == winner).Select(x => x.Key).ToHashSet(); WinnerData = (color, Utils.ColorString(color, GetString($"KOTZ.EndScreen.Winner.{winner}"))); + SendRPC(); return true; default: return WinnerData.Team != "No one wins"; @@ -592,6 +594,32 @@ public static class KingOfTheZones void ResetSkins() => DefaultOutfits.Select(x => (pc: x.Key.GetPlayer(), outfit: x.Value)).DoIf(x => x.pc != null && x.outfit != null, x => Utils.RpcChangeSkin(x.pc, x.outfit)); } + private static void SendRPC() + { + var w = Utils.CreateRPC(CustomRPC.KOTZSync); + + w.Write(WinnerData.Color); + w.Write(WinnerData.Team); + + w.Write(Points.Count); + + foreach ((KOTZTeam team, int points) in Points) + { + w.Write((int)team); + w.Write(points); + } + + Utils.EndRPC(w); + } + + public static void ReceiveRPC(MessageReader reader) + { + WinnerData.Color = reader.ReadColor(); + WinnerData.Team = reader.ReadString(); + + Loop.Times(reader.ReadInt32(), _ => Points[(KOTZTeam)reader.ReadInt32()] = reader.ReadInt32()); + } + private enum KOTZTeam { None, @@ -803,6 +831,7 @@ public static class KingOfTheZones CustomWinnerHolder.WinnerIds = PlayerTeams.Where(x => x.Value == winner).Select(x => x.Key).ToHashSet(); Color color = winner.GetColor(); WinnerData = (color, Utils.ColorString(color, GetString($"KOTZ.EndScreen.Winner.{winner}"))); + SendRPC(); Logger.Info($"Game ended. Winner: {winner} team", "KOTZ"); } diff --git a/GameMode/Speedrun.cs b/GameMode/Speedrun.cs index 66ec70ed3..79033e6e2 100644 --- a/GameMode/Speedrun.cs +++ b/GameMode/Speedrun.cs @@ -54,6 +54,7 @@ public static class Speedrun CanKill = []; Timers = Main.AllAlivePlayerControls.ToDictionary(x => x.PlayerId, _ => TimeLimit.GetInt() + 10); if (Options.CurrentGameMode == CustomGameMode.AllInOne) Timers.AdjustAllValues(x => x * AllInOneGameMode.SpeedrunTimeLimitMultiplier.GetInt()); + Utils.SendRPC(CustomRPC.SpeedrunSync, 1); } public static void ResetTimer(PlayerControl pc) @@ -75,6 +76,7 @@ public static class Speedrun if (TaskFinishWins.GetBool()) return; CanKill.Add(pc.PlayerId); + Utils.SendRPC(CustomRPC.SpeedrunSync, 2, pc.PlayerId); int kcd = KillCooldown.GetInt(); Main.AllPlayerKillCooldown[pc.PlayerId] = kcd; var sender = CustomRpcSender.Create("Speedrun.OnTaskFinish", SendOption.Reliable); @@ -88,13 +90,13 @@ public static class Speedrun public static string GetTaskBarText() { return string.Join('\n', Main.PlayerStates - .Join(Main.AllAlivePlayerControls, x => x.Key, x => x.PlayerId, (kvp, pc) => ( - Name: Utils.ColorString(Main.PlayerColors.GetValueOrDefault(kvp.Key, Color.white), pc.GetRealName()), + .Join(Main.AllAlivePlayerControls, x => x.Key, x => x.PlayerId, (kvp, _) => ( + Name: kvp.Key.ColoredPlayerName(), CompletedTasks: kvp.Value.TaskState.CompletedTasksCount, AllTasks: kvp.Value.TaskState.AllTasksCount, - Time: Timers.GetValueOrDefault(pc.PlayerId))) + Time: AmongUsClient.Instance.AmHost ? $" ({Timers.GetValueOrDefault(kvp.Key)}s)" : string.Empty)) .OrderByDescending(x => x.CompletedTasks) - .Select(x => x.CompletedTasks < x.AllTasks ? $"{x.Name}: {x.CompletedTasks}/{x.AllTasks} ({x.Time}s)" : $"{x.Name}: {Translator.GetString("Speedrun_KillingPlayer")} ({x.Time}s)")); + .Select(x => x.CompletedTasks < x.AllTasks ? $"{x.Name}: {x.CompletedTasks}/{x.AllTasks}{x.Time}" : $"{x.Name}: {Translator.GetString("Speedrun_KillingPlayer")}{x.Time}")); } public static string GetSuffixText(PlayerControl pc) diff --git a/Modules/ExtendedPlayerControl.cs b/Modules/ExtendedPlayerControl.cs index abb4000f9..6dd465728 100644 --- a/Modules/ExtendedPlayerControl.cs +++ b/Modules/ExtendedPlayerControl.cs @@ -1049,7 +1049,7 @@ internal static class ExtendedPlayerControl } sender.SendMessage(); - }, 0.6f, log: false); + }, 1f + (AmongUsClient.Instance.Ping / 1000f), log: false); } public static void ReactorFlash(this PlayerControl pc, float delay = 0f, float flashDuration = float.NaN) diff --git a/Modules/RPC.cs b/Modules/RPC.cs index 1baa2f138..3517f4fec 100644 --- a/Modules/RPC.cs +++ b/Modules/RPC.cs @@ -150,7 +150,10 @@ public enum CustomRPC FFASync, QuizSync, HotPotatoSync, - SoloPVPSync + SoloPVPSync, + CTFSync, + KOTZSync, + SpeedrunSync } public enum Sounds @@ -1160,6 +1163,23 @@ internal static class RPCHandlerPatch SoloPVP.KBScore[reader.ReadByte()] = reader.ReadPackedInt32(); break; } + case CustomRPC.CTFSync: + { + CaptureTheFlag.ReceiveRPC(reader); + break; + } + case CustomRPC.KOTZSync: + { + KingOfTheZones.ReceiveRPC(reader); + break; + } + case CustomRPC.SpeedrunSync: + { + if (reader.ReadPackedInt32() == 1) Speedrun.CanKill = []; + else Speedrun.CanKill.Add(reader.ReadByte()); + + break; + } } } catch (Exception e) { Utils.ThrowException(e); } diff --git a/Modules/Utils.cs b/Modules/Utils.cs index 8f1f1f6af..42c0d54a1 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -645,6 +645,12 @@ public static class Utils case InnerNetObject ino: w.WriteNetObject(ino); break; + case Color color: + w.Write(color); + break; + case Color32 color32: + w.Write(color32); + break; default: try { @@ -1044,9 +1050,7 @@ public static class Utils if (taskState.HasTasks) { if (IsActive(SystemTypes.Comms)) comms = true; - if (Camouflager.IsActive) comms = true; - //if (PlayerControl.LocalPlayer.myTasks.ToArray().Any(x => x.TaskType == TaskTypes.FixComms)) Comms = true; } return GetProgressText(pc.PlayerId, comms); @@ -3548,6 +3552,8 @@ public static class Utils nkShow &= neutralnum > 0; covenShow &= covenNum > 0; + if (!impShow && !nkShow && !covenShow) return string.Empty; + StringBuilder sb = new(); sb.Append(notify ? "<#777777>" : string.Empty); diff --git a/Patches/ChatCommandPatch.cs b/Patches/ChatCommandPatch.cs index ab826ee00..415bf0062 100644 --- a/Patches/ChatCommandPatch.cs +++ b/Patches/ChatCommandPatch.cs @@ -2226,19 +2226,7 @@ internal static class ChatCommands private static void SetRoleCommand(PlayerControl player, string text, string[] args) { - if (!AmongUsClient.Instance.AmHost) - { - RequestCommandProcessingFromHost(nameof(SetRoleCommand), text); - return; - } - - string subArgs = text.Remove(0, 8); - - if (!GameStates.IsLobby) - { - Utils.SendMessage(GetString("Message.OnlyCanUseInLobby"), player.PlayerId); - return; - } + string subArgs = string.Join(' ', args[1..]); if (!GuessManager.MsgToPlayerAndRole(subArgs, out byte resultId, out CustomRoles roleToSet, out _)) { diff --git a/Patches/ExilePatch.cs b/Patches/ExilePatch.cs index c3418c94a..03733f29d 100644 --- a/Patches/ExilePatch.cs +++ b/Patches/ExilePatch.cs @@ -185,24 +185,28 @@ internal static class ExileControllerWrapUpPatch if ((showRemainingKillers || ejectionNotify) && CustomGameMode.Standard.IsActiveOrIntegrated()) { string text = showRemainingKillers ? Utils.GetRemainingKillers(true) : string.Empty; - var r = IRandom.Instance; - var sender = CustomRpcSender.Create("ExileControllerWrapUpPatch.WrapUpFinalizer - 2", ejectionNotify ? SendOption.None : SendOption.Reliable); - var hasValue = false; + string finalText = ejectionNotify ? "<#ffffff>" + CheckForEndVotingPatch.EjectionText.Trim() : text; - foreach (PlayerControl pc in Main.AllAlivePlayerControls) + if (!string.IsNullOrEmpty(finalText)) { - string finalText = ejectionNotify ? "<#ffffff>" + CheckForEndVotingPatch.EjectionText.Trim() : text; - hasValue |= sender.Notify(pc, finalText, r.Next(7, 13)); + var r = IRandom.Instance; + var sender = CustomRpcSender.Create("ExileControllerWrapUpPatch.WrapUpFinalizer - 2", ejectionNotify ? SendOption.None : SendOption.Reliable); + var hasValue = false; - if (sender.stream.Length > 800) + foreach (PlayerControl pc in Main.AllAlivePlayerControls) { - sender.SendMessage(); - sender = CustomRpcSender.Create("ExileControllerWrapUpPatch.WrapUpFinalizer - 2", ejectionNotify ? SendOption.None : SendOption.Reliable); - hasValue = false; - } - } + hasValue |= sender.Notify(pc, finalText, r.Next(7, 13)); - sender.SendMessage(dispose: !hasValue); + if (sender.stream.Length > 800) + { + sender.SendMessage(); + sender = CustomRpcSender.Create("ExileControllerWrapUpPatch.WrapUpFinalizer - 2", ejectionNotify ? SendOption.None : SendOption.Reliable); + hasValue = false; + } + } + + sender.SendMessage(dispose: !hasValue); + } } LateTask.New(ChatManager.ClearChat, 3f, log: false); diff --git a/Patches/HudPatch.cs b/Patches/HudPatch.cs index 768f6343d..1e100ec95 100644 --- a/Patches/HudPatch.cs +++ b/Patches/HudPatch.cs @@ -773,7 +773,7 @@ internal static class TaskPanelBehaviourPatch break; - case CustomGameMode.HideAndSeek: + case CustomGameMode.HideAndSeek when AmongUsClient.Instance.AmHost: finalText += $"\r\n\r\n{CustomHnS.GetTaskBarText()}"; diff --git a/Patches/PlayerControlPatch.cs b/Patches/PlayerControlPatch.cs index a247f8333..3eec47c0c 100644 --- a/Patches/PlayerControlPatch.cs +++ b/Patches/PlayerControlPatch.cs @@ -2189,7 +2189,7 @@ internal static class GameDataCompleteTaskPatch if (CustomGameMode.HideAndSeek.IsActiveOrIntegrated() && CustomHnS.PlayerRoles[pc.PlayerId].Interface.Team == Team.Crewmate && pc.IsAlive()) { - var task = pc.myTasks[(Index)Convert.ToInt32(taskId)] as PlayerTask; + var task = pc.myTasks.Find((Il2CppSystem.Predicate)(x => taskId == x.Id)); Hider.OnSpecificTaskComplete(pc, task); } @@ -2217,9 +2217,7 @@ internal static class PlayerControlCompleteTaskPatch try { - var index = Convert.ToInt32(idx); - if (index >= __instance.myTasks.Count || index < 0) return; - var task = __instance.myTasks[(Index)index] as PlayerTask; + var task = __instance.myTasks.Find((Il2CppSystem.Predicate)(x => idx == x.Id)); Benefactor.OnTaskComplete(__instance, task); } catch (Exception e) { ThrowException(e); } diff --git a/Patches/TaskAssignPatch.cs b/Patches/TaskAssignPatch.cs index edea93123..cdb40ca4a 100644 --- a/Patches/TaskAssignPatch.cs +++ b/Patches/TaskAssignPatch.cs @@ -149,48 +149,48 @@ internal static class RpcSetTasksPatch // Default number of tasks var hasCommonTasks = true; - int NumLongTasks = Main.NormalOptions.NumLongTasks; - int NumShortTasks = Main.NormalOptions.NumShortTasks; + int numLongTasks = Main.NormalOptions.NumLongTasks; + int numShortTasks = Main.NormalOptions.NumShortTasks; if (Options.OverrideTasksData.AllData.TryGetValue(role, out Options.OverrideTasksData data) && data.DoOverride.GetBool()) { hasCommonTasks = data.AssignCommonTasks.GetBool(); // Whether to assign common tasks (regular tasks) // Even if assigned, it will not be reassigned and will be assigned the same common tasks as other crews. - NumLongTasks = data.NumLongTasks.GetInt(); // Number of long tasks to allocate - NumShortTasks = data.NumShortTasks.GetInt(); // Number of short tasks to allocate + numLongTasks = data.NumLongTasks.GetInt(); // Number of long tasks to allocate + numShortTasks = data.NumShortTasks.GetInt(); // Number of short tasks to allocate // Longs and shorts are constantly reallocated. - if (role is CustomRoles.Specter or CustomRoles.Haunter) Main.PlayerStates[pc.PlayerId].TaskState.AllTasksCount = NumLongTasks + NumShortTasks; + if (role is CustomRoles.Specter or CustomRoles.Haunter) Main.PlayerStates[pc.PlayerId].TaskState.AllTasksCount = numLongTasks + numShortTasks; } if (pc.Is(CustomRoles.Busy)) { - NumLongTasks += Options.BusyLongTasks.GetInt(); - NumShortTasks += Options.BusyShortTasks.GetInt(); + numLongTasks += Options.BusyLongTasks.GetInt(); + numShortTasks += Options.BusyShortTasks.GetInt(); } // Mad Snitch mission coverage if (pc.Is(CustomRoles.Snitch) && pc.Is(CustomRoles.Madmate)) { hasCommonTasks = false; - NumLongTasks = 0; - NumShortTasks = Options.MadSnitchTasks.GetInt(); + numLongTasks = 0; + numShortTasks = Options.MadSnitchTasks.GetInt(); } // GM and Lazy Guy have no tasks if (pc.Is(CustomRoles.GM) || pc.Is(CustomRoles.Needy) || Options.CurrentGameMode is CustomGameMode.SoloKombat or CustomGameMode.FFA or CustomGameMode.HotPotato or CustomGameMode.NaturalDisasters or CustomGameMode.RoomRush or CustomGameMode.Quiz or CustomGameMode.CaptureTheFlag or CustomGameMode.KingOfTheZones) { hasCommonTasks = false; - NumShortTasks = 0; - NumLongTasks = 0; + numShortTasks = 0; + numLongTasks = 0; } // Workhorse task assignment - if (pc.Is(CustomRoles.Workhorse)) (hasCommonTasks, NumLongTasks, NumShortTasks) = Workhorse.TaskData; + if (pc.Is(CustomRoles.Workhorse)) (hasCommonTasks, numLongTasks, numShortTasks) = Workhorse.TaskData; // Capitalism is going to harm people~ if (Capitalism.CapitalismAssignTask.TryGetValue(pc.PlayerId, out int extraTasksNum)) { - NumShortTasks += extraTasksNum; + numShortTasks += extraTasksNum; Capitalism.CapitalismAssignTask.Remove(pc.PlayerId); } @@ -198,10 +198,10 @@ internal static class RpcSetTasksPatch switch (hasCommonTasks) { - case false when NumLongTasks == 0 && NumShortTasks == 0: - NumShortTasks = 1; // Task 0 measures + case false when numLongTasks == 0 && numShortTasks == 0: + numShortTasks = 1; // Task 0 measures break; - case true when NumLongTasks == Main.NormalOptions.NumLongTasks && NumShortTasks == Main.NormalOptions.NumShortTasks: + case true when numLongTasks == Main.NormalOptions.NumLongTasks && numShortTasks == Main.NormalOptions.NumShortTasks: return; // If there are no changes } @@ -242,7 +242,7 @@ internal static class RpcSetTasksPatch // Use the task assignment function actually used on the Among Us side. ShipStatus.Instance.AddTasksFromList( ref start2, - NumLongTasks, + numLongTasks, TasksList, usedTaskTypes, LongTasks @@ -250,7 +250,7 @@ internal static class RpcSetTasksPatch ShipStatus.Instance.AddTasksFromList( ref start3, - NumShortTasks, + numShortTasks, TasksList, usedTaskTypes, ShortTasks diff --git a/Resources/Lang/en_US.json b/Resources/Lang/en_US.json index 64eee91ba..9f9e721ba 100644 --- a/Resources/Lang/en_US.json +++ b/Resources/Lang/en_US.json @@ -640,6 +640,7 @@ "NecroviewInfo": "See the team of the dead", "ReachInfo": "You have a longer kill range", "UndeadInfo": "You're on the Undead faction", + "CharmedInfo": "You've been Charmed by the Cultist", "BaitInfo": "Your killer self-reports your body", "TrapperInfo": "Freeze your killer for a few seconds", "OnboundInfo": "You can't be guessed", diff --git a/Roles/Neutral/Gamer.cs b/Roles/Neutral/Gamer.cs index 47dd6226b..0e1641441 100644 --- a/Roles/Neutral/Gamer.cs +++ b/Roles/Neutral/Gamer.cs @@ -67,7 +67,9 @@ public class Gamer : RoleBase { PlayerIdList.Add(playerId); GamerHealth[playerId] = SelfHealthMax.GetInt(); - foreach (PlayerControl pc in Main.AllAlivePlayerControls) PlayerHealth[pc.PlayerId] = HealthMax.GetInt(); + + foreach (PlayerControl pc in Main.AllAlivePlayerControls) + PlayerHealth[pc.PlayerId] = HealthMax.GetInt(); } public override void Remove(byte playerId) @@ -102,22 +104,22 @@ public class Gamer : RoleBase public static void ReceiveRPC(MessageReader reader) { - byte PlayerId = reader.ReadByte(); - int Health = reader.ReadInt32(); + byte playerId = reader.ReadByte(); + int health = reader.ReadInt32(); - if (GamerHealth.ContainsKey(PlayerId)) - GamerHealth[PlayerId] = Health; + if (GamerHealth.ContainsKey(playerId)) + GamerHealth[playerId] = health; else - PlayerHealth[PlayerId] = Health; + PlayerHealth[playerId] = health; } public override bool OnCheckMurder(PlayerControl killer, PlayerControl target) { - if (killer == null || target == null || target.Is(CustomRoles.Gamer) || !PlayerHealth.ContainsKey(target.PlayerId)) return false; + if (killer == null || target == null || target.Is(CustomRoles.Gamer) || !PlayerHealth.TryGetValue(target.PlayerId, out var targetHealth)) return false; killer.SetKillCooldown(); - if (PlayerHealth[target.PlayerId] - Damage.GetInt() < 1) + if (targetHealth - Damage.GetInt() < 1) { if (target.Is(CustomRoles.Pestilence)) { @@ -130,7 +132,7 @@ public class Gamer : RoleBase } PlayerHealth.Remove(target.PlayerId); - killer.Kill(target); + killer.RpcCheckAndMurder(target); Utils.NotifyRoles(SpecifySeer: killer, SpecifyTarget: target); return false; } @@ -172,29 +174,30 @@ public class Gamer : RoleBase if (seer.PlayerId == target.PlayerId) { - bool GetValue = GamerHealth.TryGetValue(target.PlayerId, out int value); - return GetValue && value > 0 ? Utils.ColorString(GetColor(value, true), $"【{value}/{SelfHealthMax.GetInt()}】") : string.Empty; + return GamerHealth.TryGetValue(target.PlayerId, out int value) && value > 0 + ? Utils.ColorString(GetColor(value, true), $"【{value}/{SelfHealthMax.GetInt()}】") + : string.Empty; } else { - bool GetValue = PlayerHealth.TryGetValue(target.PlayerId, out int value); - return GetValue && value > 0 ? Utils.ColorString(GetColor(value), $"【{value}/{HealthMax.GetInt()}】") : string.Empty; + return PlayerHealth.TryGetValue(target.PlayerId, out int value) && value > 0 + ? Utils.ColorString(GetColor(value), $"【{value}/{HealthMax.GetInt()}】") + : string.Empty; } } - private static Color32 GetColor(float Health, bool self = false) + private static Color32 GetColor(float health, bool self = false) { - var x = (int)(Health / (self ? SelfHealthMax.GetInt() : HealthMax.GetInt()) * 10 * 50); - var R = 255; - var G = 255; - var B = 0; + var x = (int)(health / (self ? SelfHealthMax.GetInt() : HealthMax.GetInt()) * 10 * 50); + var r = 255; + var g = 255; if (x > 255) - R -= x - 255; + r -= x - 255; else - G = x; + g = x; - return new((byte)R, (byte)G, (byte)B, byte.MaxValue); + return new((byte)r, (byte)g, 0, byte.MaxValue); } public override void SetButtonTexts(HudManager hud, byte id) diff --git a/Roles/Neutral/Tremor.cs b/Roles/Neutral/Tremor.cs index 69a1fd83f..c1b51db26 100644 --- a/Roles/Neutral/Tremor.cs +++ b/Roles/Neutral/Tremor.cs @@ -93,6 +93,7 @@ public class Tremor : RoleBase { Timer--; Utils.SendRPC(CustomRPC.SyncRoleData, pc.PlayerId, Timer); + Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc); LastUpdate = Utils.TimeStamp; } @@ -123,6 +124,7 @@ public class Tremor : RoleBase DoomTimer--; Utils.SendRPC(CustomRPC.SyncRoleData, pc.PlayerId, DoomTimer); + Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc); if (DoomTimer <= 0) {