From 4bc7a0be425069baf05bf8f45683cccfe831f045 Mon Sep 17 00:00:00 2001 From: Gurge44 Date: Mon, 24 Nov 2025 11:40:18 +0100 Subject: [PATCH] some improvements --- GameMode/Deathrace.cs | 6 ++-- Modules/ExtendedPlayerControl.cs | 31 +++---------------- .../PlayerGameOptionsSender.cs | 3 +- Modules/Utils.cs | 22 ++++++------- Patches/ControlPatch.cs | 10 ++++-- Patches/HudPatch.cs | 3 -- Patches/IntroPatch.cs | 10 +++--- Patches/PlayerControlPatch.cs | 6 ++-- Patches/ShipStatusPatch.cs | 2 +- Roles/Crewmate/Sheriff.cs | 2 +- Roles/Crewmate/Transporter.cs | 2 +- Roles/Impostor/Deathpact.cs | 22 ++++++------- Roles/Neutral/Berserker.cs | 5 +++ Roles/Neutral/Thief.cs | 13 ++++++-- 14 files changed, 66 insertions(+), 71 deletions(-) diff --git a/GameMode/Deathrace.cs b/GameMode/Deathrace.cs index 24cc85fa5..763840af4 100644 --- a/GameMode/Deathrace.cs +++ b/GameMode/Deathrace.cs @@ -54,9 +54,9 @@ public static class Deathrace public static readonly Dictionary CoordinateChecks = new() { - [100] = new Vector2(-22f, 1.82f), // Left side of Cafeteria <-> Splash Zone passthrough - [101] = new Vector2(-8.15f, 19.12f), // Upper Deck: Central <-> Cafeteria hallway - [102] = new Vector2(10.43f, 14.74f) // Upper Deck: Lobby <-> Central hallway, right side + [100] = new Vector2(-22f, 1.82f), // (Fungle) Left side of Cafeteria <-> Splash Zone passthrough + [101] = new Vector2(-8.15f, 19.12f), // (Submerged) Upper Deck: Central <-> Cafeteria hallway + [102] = new Vector2(10.43f, 14.74f) // (Submerged) Upper Deck: Lobby <-> Central hallway, right side }; public static readonly Dictionary>> UsableVentIDs = new() diff --git a/Modules/ExtendedPlayerControl.cs b/Modules/ExtendedPlayerControl.cs index ca81aab75..9479b9d42 100644 --- a/Modules/ExtendedPlayerControl.cs +++ b/Modules/ExtendedPlayerControl.cs @@ -323,33 +323,10 @@ internal static class ExtendedPlayerControl pc.Exiled(); Main.PlayerStates[pc.PlayerId].SetDead(); - - CustomRpcSender.Create("Temporary Death", SendOption.Reliable) - .AutoStartRpc(pc.NetId, RpcCalls.Exiled) - .EndRpc() - .SendMessage(); - - pc.SyncSettings(); - - if (!pc.AmOwner) - { - var sender = CustomRpcSender.Create("Temporary Death (2)", SendOption.Reliable); - sender.StartMessage(pc.OwnerId); - sender.StartRpc(pc.NetId, RpcCalls.SetRole) - .Write((ushort)RoleTypes.GuardianAngel) - .Write(true) - .EndRpc(); - sender.StartRpc(pc.NetId, RpcCalls.ProtectPlayer) - .WriteNetObject(pc) - .Write(0) - .EndRpc(); - sender.SendMessage(); - } - else - { - pc.SetRole(RoleTypes.GuardianAngel); - pc.Data.Role.SetCooldown(); - } + + pc.RpcSetRoleGlobal(RoleTypes.GuardianAngel); + LateTask.New(pc.SyncSettings, 0.1f, log: false); + LateTask.New(pc.RpcResetAbilityCooldown, 0.2f, log: false); } // Saves some RPC calls for vanilla servers to make innersloth's rate limit happy diff --git a/Modules/GameOptionsSender/PlayerGameOptionsSender.cs b/Modules/GameOptionsSender/PlayerGameOptionsSender.cs index e51f14ed8..1ecdd549e 100644 --- a/Modules/GameOptionsSender/PlayerGameOptionsSender.cs +++ b/Modules/GameOptionsSender/PlayerGameOptionsSender.cs @@ -241,6 +241,8 @@ public sealed class PlayerGameOptionsSender(PlayerControl player) : GameOptionsS } case CustomGameMode.Standard: { + President.OnAnyoneApplyGameOptions(opt); + foreach (CustomRoles subRole in state.SubRoles) { if (subRole.IsGhostRole() && subRole != CustomRoles.EvilSpirit) @@ -466,7 +468,6 @@ public sealed class PlayerGameOptionsSender(PlayerControl player) : GameOptionsS Farmer.OnAnyoneApplyGameOptions(opt, player); Siren.ApplyGameOptionsForOthers(opt, player.PlayerId); Chef.ApplyGameOptionsForOthers(opt, player.PlayerId); - President.OnAnyoneApplyGameOptions(opt); Negotiator.OnAnyoneApplyGameOptions(opt, player.PlayerId); Wizard.OnAnyoneApplyGameOptions(opt, player.PlayerId); Curser.OnAnyoneApplyGameOptions(opt, player.PlayerId); diff --git a/Modules/Utils.cs b/Modules/Utils.cs index 89f8d7fa0..f143989d7 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -1443,14 +1443,14 @@ public static class Utils new List { - new($"{sb.Append("\n.").ToString().RemoveHtmlTags()}", playerId, GetString("GMRoles")), - new($"{impsb.Append("\n.").ToString().RemoveHtmlTags()}", playerId, ColorString(GetRoleColor(CustomRoles.Impostor), GetString("ImpostorRoles"))), - new($"{crewsb.Append("\n.").ToString().RemoveHtmlTags()}", playerId, ColorString(GetRoleColor(CustomRoles.Crewmate), GetString("CrewmateRoles"))), - new($"{neutralsb.Append("\n.").ToString().RemoveHtmlTags()}", playerId, GetString("NeutralRoles")), - new($"{covensb.Append("\n.").ToString().RemoveHtmlTags()}", playerId, GetString("CovenRoles")), - new($"{ghostsb.Append("\n.").ToString().RemoveHtmlTags()}", playerId, GetString("GhostRoles")), - new($"{addonsb.Append("\n.").ToString().RemoveHtmlTags()}", playerId, GetString("AddonRoles")) - }.SendMultipleMessages(); + new($"{sb.Append("\n.").ToString().RemoveHtmlTags().Trim()}", playerId, GetString("GMRoles")), + new($"{impsb.Append("\n.").ToString().RemoveHtmlTags().Trim()}", playerId, ColorString(GetRoleColor(CustomRoles.Impostor), GetString("ImpostorRoles"))), + new($"{crewsb.Append("\n.").ToString().RemoveHtmlTags().Trim()}", playerId, ColorString(GetRoleColor(CustomRoles.Crewmate), GetString("CrewmateRoles"))), + new($"{neutralsb.Append("\n.").ToString().RemoveHtmlTags().Trim()}", playerId, GetString("NeutralRoles")), + new($"{covensb.Append("\n.").ToString().RemoveHtmlTags().Trim()}", playerId, GetString("CovenRoles")), + new($"{ghostsb.Append("\n.").ToString().RemoveHtmlTags().Trim()}", playerId, GetString("GhostRoles")), + new($"{addonsb.Append("\n.").ToString().RemoveHtmlTags().Trim()}", playerId, GetString("AddonRoles")) + }.FindAll(x => x.Text.Length > 18).SendMultipleMessages(); } public static void ShowChildrenSettings(OptionItem option, ref StringBuilder sb, int deep = 0, bool f1 = false, bool disableColor = true) @@ -3023,15 +3023,15 @@ public static class Utils if (Devourer.HideNameOfConsumedPlayer.GetBool() && !GameStates.IsLobby && Devourer.PlayerIdList.Any(x => Main.PlayerStates[x].Role is Devourer { IsEnable: true } dv && dv.PlayerSkinsCosumed.Contains(target.PlayerId)) && !camouflageIsForMeeting) targetPlayerName = GetString("DevouredName"); - // Camouflage - if (Camouflage.IsCamouflage && !camouflageIsForMeeting) targetPlayerName = $"{targetPlayerName}"; - if (Options.CurrentGameMode == CustomGameMode.KingOfTheZones && Main.IntroDestroyed && !KingOfTheZones.GameGoing) targetPlayerName = EmptyMessage; var targetName = $"{targetRoleText}{targetPlayerName}{targetDeathReason}{TargetMark}"; targetName += GameStates.IsLobby || TargetSuffix.ToString() == string.Empty ? string.Empty : $"{newLineBeforeSuffix}{TargetSuffix}"; + // Camouflage + if (Camouflage.IsCamouflage && !camouflageIsForMeeting) targetName = $"{targetName}"; + targetName = targetName.Trim().Replace("color=", "").Replace("<#ffffff><#ffffff>", "<#ffffff>"); if (targetName.EndsWith("")) targetName = targetName.Remove(targetName.Length - 7); if (targetName.EndsWith("")) targetName = targetName.Remove(targetName.Length - 8); diff --git a/Patches/ControlPatch.cs b/Patches/ControlPatch.cs index 2e2c7f2f0..4e0a7847e 100644 --- a/Patches/ControlPatch.cs +++ b/Patches/ControlPatch.cs @@ -139,12 +139,18 @@ internal static class ControllerManagerUpdatePatch GameStartManager.Instance.countDownTimer = 0; } - if (Input.GetKeyDown(KeyCode.C) && GameStates.IsCountDown && GameStates.IsLobby) + if (Input.GetKeyDown(KeyCode.C) && GameStates.IsCountDown && GameStates.IsLobby && !HudManager.Instance.Chat.IsOpenOrOpening) { GameStartManager.Instance.ResetStartState(); Logger.SendInGame(GetString("CancelStartCountDown")); } + if (Input.GetKeyDown(KeyCode.Return) && GameStates.IsLobby && GameStartManager.InstanceExists && GameStartManager.Instance.startState == GameStartManager.StartingStates.NotStarting && !HudManager.Instance.Chat.IsOpenOrOpening && !OnGameJoinedPatch.JoiningGame) + { + Logger.Info("ENTER pressed: Starting game by host", "KeyCommand"); + GameStartManager.Instance.BeginGame(); + } + if (KeysDown(KeyCode.N, KeyCode.LeftShift, KeyCode.LeftControl)) { Main.IsChatCommand = true; @@ -205,7 +211,7 @@ internal static class ControllerManagerUpdatePatch Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].deathReason = PlayerState.DeathReason.etc; PlayerControl.LocalPlayer.RpcExileV2(); Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].SetDead(); - Utils.AfterPlayerDeathTasks(PlayerControl.LocalPlayer); + Utils.AfterPlayerDeathTasks(PlayerControl.LocalPlayer, GameStates.IsMeeting); Utils.SendMessage(GetString("HostKillSelfByCommand"), title: $"{GetString("DefaultSystemMessageTitle")}"); } diff --git a/Patches/HudPatch.cs b/Patches/HudPatch.cs index 3b3276ce5..c296a03db 100644 --- a/Patches/HudPatch.cs +++ b/Patches/HudPatch.cs @@ -193,9 +193,6 @@ internal static class HudManagerPatch button.cooldownTimerText.gameObject.SetActive(true); } } - - if (player.Is(CustomRoles.NotAssigned) && player.IsHost() && Main.GM.Value) - player.RpcSetCustomRole(CustomRoles.GM); CustomRoles role = player.GetCustomRole(); diff --git a/Patches/IntroPatch.cs b/Patches/IntroPatch.cs index 082a6ab63..81d372de4 100644 --- a/Patches/IntroPatch.cs +++ b/Patches/IntroPatch.cs @@ -1106,12 +1106,14 @@ internal static class IntroCutsceneDestroyPatch // for vanilla clients we use "Data.Disconnected" Main.AllPlayerControls.Do(x => x.roleAssigned = false); - PlayerControl[] aapc = Main.AllAlivePlayerControls; - - Utils.NumSnapToCallsThisRound = aapc.Length; - if (AmongUsClient.Instance.AmHost) { + Main.AllPlayerControls.DoIf(x => x.Is(CustomRoles.NotAssigned) && ((x.AmOwner && Main.GM.Value) || ChatCommands.Spectators.Contains(x.PlayerId)), x => x.RpcSetCustomRole(CustomRoles.GM)); + + PlayerControl[] aapc = Main.AllAlivePlayerControls; + + Utils.NumSnapToCallsThisRound = aapc.Length; + if (Main.NormalOptions.MapId != 4) { foreach (PlayerControl pc in aapc) diff --git a/Patches/PlayerControlPatch.cs b/Patches/PlayerControlPatch.cs index e60e8cba2..e72318e82 100644 --- a/Patches/PlayerControlPatch.cs +++ b/Patches/PlayerControlPatch.cs @@ -1997,9 +1997,6 @@ internal static class FixedUpdatePatch if (Devourer.HideNameOfConsumedPlayer.GetBool() && Devourer.PlayerIdList.Any(x => Main.PlayerStates[x].Role is Devourer { IsEnable: true } dv && dv.PlayerSkinsCosumed.Contains(target.PlayerId))) realName = GetString("DevouredName"); - // Camouflage - if (Camouflage.IsCamouflage) realName = $"{realName} "; - if (!self && Options.CurrentGameMode == CustomGameMode.KingOfTheZones && Main.IntroDestroyed && !KingOfTheZones.GameGoing) realName = EmptyMessage; @@ -2017,6 +2014,9 @@ internal static class FixedUpdatePatch string deathReason = !seer.IsAlive() && seer.KnowDeathReason(target) ? $"{newLineBeforeSuffix}『{ColorString(GetRoleColor(CustomRoles.Doctor), GetVitalText(target.PlayerId))}』" : string.Empty; target.cosmetics.nameText.text = $"{roleText}{realName}{deathReason}{Mark}{newLineBeforeSuffix}{Suffix}"; + + // Camouflage + if (Camouflage.IsCamouflage) target.cosmetics.nameText.text = $"{target.cosmetics.nameText.text}"; } } diff --git a/Patches/ShipStatusPatch.cs b/Patches/ShipStatusPatch.cs index c5dec4b8a..dbd3028d9 100644 --- a/Patches/ShipStatusPatch.cs +++ b/Patches/ShipStatusPatch.cs @@ -251,7 +251,7 @@ internal static class RepairSystemPatch [HarmonyPatch(typeof(ShipStatus), nameof(ShipStatus.CloseDoorsOfType))] internal static class CloseDoorsPatch { - public static bool Prefix( /*ShipStatus __instance, */ [HarmonyArgument(0)] SystemTypes room) + public static bool Prefix([HarmonyArgument(0)] SystemTypes room) { bool allow = !Options.DisableSabotage.GetBool() && Options.CurrentGameMode is not CustomGameMode.SoloPVP and not CustomGameMode.FFA and not CustomGameMode.StopAndGo and not CustomGameMode.HotPotato and not CustomGameMode.Speedrun and not CustomGameMode.CaptureTheFlag and not CustomGameMode.NaturalDisasters and not CustomGameMode.RoomRush and not CustomGameMode.KingOfTheZones and not CustomGameMode.Quiz and not CustomGameMode.TheMindGame and not CustomGameMode.BedWars and not CustomGameMode.Deathrace and not CustomGameMode.Mingle; diff --git a/Roles/Crewmate/Sheriff.cs b/Roles/Crewmate/Sheriff.cs index 80a7c2275..e4b1d80b4 100644 --- a/Roles/Crewmate/Sheriff.cs +++ b/Roles/Crewmate/Sheriff.cs @@ -104,7 +104,7 @@ public class Sheriff : RoleBase public override void SetKillCooldown(byte id) { - Main.AllPlayerKillCooldown[id] = CanUseKillButton(Utils.GetPlayerById(id)) ? KillCooldown.GetFloat() : 15f; + Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) diff --git a/Roles/Crewmate/Transporter.cs b/Roles/Crewmate/Transporter.cs index 15e8589fb..bc71d8762 100644 --- a/Roles/Crewmate/Transporter.cs +++ b/Roles/Crewmate/Transporter.cs @@ -56,7 +56,7 @@ internal class Transporter : RoleBase if (!shapeshifting) return true; if (shapeshifter == null || target == null || shapeshifter == target || !shapeshifter.IsAlive() || !target.IsAlive()) - return true; + return false; if (shapeshifter.GetAbilityUseLimit() < 1f) return false; diff --git a/Roles/Impostor/Deathpact.cs b/Roles/Impostor/Deathpact.cs index af4882e03..b9fee6aac 100644 --- a/Roles/Impostor/Deathpact.cs +++ b/Roles/Impostor/Deathpact.cs @@ -14,9 +14,9 @@ namespace EHR.Impostor; public class Deathpact : RoleBase { private const int Id = 1100; - public static List PlayerIdList = []; + private static List Instances = []; - public static List ActiveDeathpacts = []; + private static List ActiveDeathpacts = []; private static OptionItem KillCooldown; private static OptionItem ShapeshiftCooldown; @@ -26,12 +26,12 @@ public class Deathpact : RoleBase private static OptionItem ReduceVisionWhileInPact; private static OptionItem VisionWhileInPact; private static OptionItem KillDeathpactPlayersOnMeeting; + private byte DeathPactId; - public long DeathpactTime; + private long DeathpactTime; + private List PlayersInDeathpact = []; - public List PlayersInDeathpact = []; - - public override bool IsEnable => PlayerIdList.Count > 0 || Randomizer.Exists; + public override bool IsEnable => Instances.Count > 0 || Randomizer.Exists; public override void SetupCustomOption() { @@ -69,7 +69,7 @@ public class Deathpact : RoleBase public override void Init() { - PlayerIdList = []; + Instances = []; PlayersInDeathpact = []; DeathpactTime = 0; ActiveDeathpacts = []; @@ -78,7 +78,7 @@ public class Deathpact : RoleBase public override void Add(byte playerId) { - PlayerIdList.Add(playerId); + Instances.Add(this); PlayersInDeathpact = []; DeathpactTime = 0; DeathPactId = playerId; @@ -86,7 +86,7 @@ public class Deathpact : RoleBase public override void Remove(byte playerId) { - PlayerIdList.Remove(playerId); + Instances.Remove(this); } public override void ApplyGameOptions(IGameOptions opt, byte id) @@ -149,9 +149,7 @@ public class Deathpact : RoleBase { if (!ReduceVisionWhileInPact.GetBool()) return; - if (Main.PlayerStates[player.PlayerId].Role is not Deathpact { IsEnable: true } dp) return; - - if (dp.PlayersInDeathpact.Any(b => b.PlayerId == player.PlayerId) && dp.PlayersInDeathpact.Count == NumberOfPlayersInPact.GetInt()) + if (Instances.Exists(x => x.PlayersInDeathpact.Exists(b => b.PlayerId == player.PlayerId) && x.PlayersInDeathpact.Count == NumberOfPlayersInPact.GetInt())) { opt.SetVision(false); opt.SetFloat(FloatOptionNames.CrewLightMod, VisionWhileInPact.GetFloat()); diff --git a/Roles/Neutral/Berserker.cs b/Roles/Neutral/Berserker.cs index 8a118235d..bb97821a0 100644 --- a/Roles/Neutral/Berserker.cs +++ b/Roles/Neutral/Berserker.cs @@ -44,6 +44,11 @@ public class Berserker : RoleBase Instances.Add(this); } + public override void Remove(byte playerId) + { + Instances.Remove(this); + } + public override void SetKillCooldown(byte id) { if (Form < 2) base.SetKillCooldown(id); diff --git a/Roles/Neutral/Thief.cs b/Roles/Neutral/Thief.cs index f59dd7077..5e6c10ee0 100644 --- a/Roles/Neutral/Thief.cs +++ b/Roles/Neutral/Thief.cs @@ -1,17 +1,21 @@ -namespace EHR.Neutral; +using AmongUs.GameOptions; + +namespace EHR.Neutral; public class Thief : RoleBase { public static bool On; private static OptionItem CanStealCovenRoles; + private static OptionItem ImpostorVision; public override bool IsEnable => On; public override void SetupCustomOption() { StartSetup(656400) - .AutoSetupOption(ref CanStealCovenRoles, false); + .AutoSetupOption(ref CanStealCovenRoles, false) + .AutoSetupOption(ref ImpostorVision, false); } public override void Init() @@ -29,6 +33,11 @@ public class Thief : RoleBase return pc.IsAlive(); } + public override void ApplyGameOptions(IGameOptions opt, byte playerId) + { + opt.SetVision(ImpostorVision.GetBool()); + } + public override bool OnCheckMurder(PlayerControl killer, PlayerControl target) { bool success = target.IsImpostor() || target.Is(CustomRoles.Trickster) || target.IsMadmate() || target.Is(CustomRoles.Maverick) || target.IsNeutralKiller() || (target.Is(CustomRoleTypes.Coven) && CanStealCovenRoles.GetBool());