From f7fd249a3413bbe3664829213b3f54f2a964fa14 Mon Sep 17 00:00:00 2001 From: Gurge44 Date: Wed, 28 Aug 2024 10:35:19 +0200 Subject: [PATCH] Some fixes and improvements --- CTA/CustomTeamAssigner/CustomRoles.cs | 2 ++ EHR.sln.DotSettings | 1 + Modules/ExtendedPlayerControl.cs | 18 +++++++++++++-- Modules/RPC.cs | 33 +++++++++++++++++++++++++-- Modules/Utils.cs | 5 +++- Patches/PlayerControlPatch.cs | 21 ++++++++++++----- Resources/Lang/en_US.json | 2 +- Roles/Crewmate/Grappler.cs | 5 ++-- Roles/Crewmate/Journalist.cs | 2 +- Roles/Crewmate/Negotiator.cs | 2 +- Roles/Impostor/Assumer.cs | 2 +- Roles/Impostor/Hypnotist.cs | 2 +- Roles/Neutral/Gaslighter.cs | 11 +++++---- Roles/Neutral/Shifter.cs | 1 + Roles/Neutral/Simon.cs | 2 +- Roles/Neutral/Tank.cs | 2 +- Roles/Neutral/Technician.cs | 5 ++-- Roles/RoleBase.cs | 8 ++++++- 18 files changed, 96 insertions(+), 28 deletions(-) diff --git a/CTA/CustomTeamAssigner/CustomRoles.cs b/CTA/CustomTeamAssigner/CustomRoles.cs index 1951b8db6..5f811525b 100644 --- a/CTA/CustomTeamAssigner/CustomRoles.cs +++ b/CTA/CustomTeamAssigner/CustomRoles.cs @@ -273,6 +273,7 @@ public enum CustomRoles Evolver, Executioner, Totocalcio, // Follower + Gaslighter, Glitch, God, FFF, // Hater @@ -329,6 +330,7 @@ public enum CustomRoles DarkHide, // Stalker Succubus, Sunnyboy, + Technician, Tank, Terrorist, Tiger, diff --git a/EHR.sln.DotSettings b/EHR.sln.DotSettings index 189c52d74..326108f5a 100644 --- a/EHR.sln.DotSettings +++ b/EHR.sln.DotSettings @@ -7,6 +7,7 @@ AU CD CK + CNO CTF DLL DY diff --git a/Modules/ExtendedPlayerControl.cs b/Modules/ExtendedPlayerControl.cs index 8c68882b9..0f58bb8e0 100644 --- a/Modules/ExtendedPlayerControl.cs +++ b/Modules/ExtendedPlayerControl.cs @@ -343,10 +343,24 @@ static class ExtendedPlayerControl AmongUsClient.Instance.FinishRpcImmediately(msg); } + public static bool HasAbilityCD(this PlayerControl pc) => Main.AbilityCD.ContainsKey(pc.PlayerId); public static void AddKCDAsAbilityCD(this PlayerControl pc) => AddAbilityCD(pc, (int)Math.Round(Main.AllPlayerKillCooldown.TryGetValue(pc.PlayerId, out var KCD) ? KCD : Options.DefaultKillCooldown)); public static void AddAbilityCD(this PlayerControl pc, bool includeDuration = true) => Utils.AddAbilityCD(pc.GetCustomRole(), pc.PlayerId, includeDuration); - public static void AddAbilityCD(this PlayerControl pc, int CD) => Main.AbilityCD[pc.PlayerId] = (TimeStamp, CD); - public static bool HasAbilityCD(this PlayerControl pc) => Main.AbilityCD.ContainsKey(pc.PlayerId); + + public static void AddAbilityCD(this PlayerControl pc, int CD) + { + Main.AbilityCD[pc.PlayerId] = (TimeStamp, CD); + SendRPC(CustomRPC.SyncAbilityCD, 1, pc.PlayerId, CD); + } + + public static void RemoveAbilityCD(this PlayerControl pc) + { + if (Main.AbilityCD.ContainsKey(pc.PlayerId)) + { + Main.AbilityCD.Remove(pc.PlayerId); + SendRPC(CustomRPC.SyncAbilityCD, 3, pc.PlayerId); + } + } public static float GetAbilityUseLimit(this PlayerControl pc) => Main.AbilityUseLimit.GetValueOrDefault(pc.PlayerId, float.NaN); public static float GetAbilityUseLimit(this byte playerId) => Main.AbilityUseLimit.GetValueOrDefault(playerId, float.NaN); diff --git a/Modules/RPC.cs b/Modules/RPC.cs index 5f6f49b07..d66344ed3 100644 --- a/Modules/RPC.cs +++ b/Modules/RPC.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using AmongUs.GameOptions; @@ -56,6 +57,7 @@ public enum CustomRPC RemoveSubRole, Arrow, FixModdedClientCNO, + SyncAbilityCD, // Roles SyncRoleData, @@ -365,6 +367,33 @@ internal class RPCHandlerPatch if (reader.ReadBoolean()) TargetArrow.ReceiveRPC(reader); else LocateArrow.ReceiveRPC(reader); break; + case CustomRPC.SyncAbilityCD: + { + switch (reader.ReadPackedInt32()) + { + case 1: + { + byte id = reader.ReadByte(); + int cd = reader.ReadPackedInt32(); + long ts = Utils.TimeStamp; + Main.AbilityCD[id] = (ts, cd); + break; + } + case 2: + { + Main.AbilityCD.Clear(); + break; + } + case 3: + { + byte id = reader.ReadByte(); + Main.AbilityCD.Remove(id); + break; + } + } + + break; + } case CustomRPC.SyncRoleData: { byte id = reader.ReadByte(); @@ -399,7 +428,7 @@ internal class RPCHandlerPatch case CustomRPC.SyncSentry: { byte id = reader.ReadByte(); - if (Main.PlayerStates[id].Role is not EHR.Impostor.Sentry sentry) break; + if (Main.PlayerStates[id].Role is not Impostor.Sentry sentry) break; sentry.MonitoredRoom = Utils.GetPlayerById(id).GetPlainShipRoom(); break; } @@ -912,7 +941,7 @@ internal static class RPC Main.Instance.StartCoroutine(VersionCheck()); return; - static System.Collections.IEnumerator VersionCheck() + static IEnumerator VersionCheck() { while (PlayerControl.LocalPlayer == null) yield return null; MessageWriter writer = AmongUsClient.Instance.StartRpc(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.VersionCheck); diff --git a/Modules/Utils.cs b/Modules/Utils.cs index 5da817f4f..952fbd1ab 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -2450,7 +2450,9 @@ public static class Utils { if (role.UsesPetInsteadOfKill()) { - Main.AbilityCD[playerId] = (TimeStamp, (int)Math.Round(Main.AllPlayerKillCooldown.TryGetValue(playerId, out var KCD) ? KCD : Options.DefaultKillCooldown)); + int kcd = (int)Math.Round(Main.AllPlayerKillCooldown.TryGetValue(playerId, out var KCD) ? KCD : Options.DefaultKillCooldown); + Main.AbilityCD[playerId] = (TimeStamp, kcd); + SendRPC(CustomRPC.SyncAbilityCD, 1, playerId, kcd); return; } @@ -2507,6 +2509,7 @@ public static class Utils CD = (int)Math.Round(CD * 0.75f); Main.AbilityCD[playerId] = (TimeStamp, CD); + SendRPC(CustomRPC.SyncAbilityCD, 1, playerId, CD); if (Options.UseUnshiftTrigger.GetBool() && role.SimpleAbilityTrigger() && (!role.IsNeutral() || Options.UseUnshiftTriggerForNKs.GetBool())) GetPlayerById(playerId)?.RpcResetAbilityCooldown(); diff --git a/Patches/PlayerControlPatch.cs b/Patches/PlayerControlPatch.cs index db09afce5..85554cb05 100644 --- a/Patches/PlayerControlPatch.cs +++ b/Patches/PlayerControlPatch.cs @@ -589,8 +589,15 @@ class MurderPlayerPatch } if (killer.Is(CustomRoles.Sniper)) + { if (!Options.UsePets.GetBool()) killer.RpcResetAbilityCooldown(); - else Main.AbilityCD[killer.PlayerId] = (TimeStamp, Options.DefaultShapeshiftCooldown.GetInt()); + else + { + int cd = Options.DefaultShapeshiftCooldown.GetInt(); + Main.AbilityCD[killer.PlayerId] = (TimeStamp, cd); + SendRPC(CustomRPC.SyncAbilityCD, 1, killer.PlayerId, cd); + } + } if (killer != __instance) { @@ -1089,6 +1096,7 @@ class ReportDeadBodyPatch } Main.AbilityCD.Clear(); + SendRPC(CustomRPC.SyncAbilityCD, 2); if (player.Is(CustomRoles.Damocles)) { @@ -1234,7 +1242,7 @@ static class FixedUpdatePatch var player = __instance; var playerId = player.PlayerId; var lpId = PlayerControl.LocalPlayer.PlayerId; - var localPlayer = player.PlayerId == lpId; // Updates that are independent of the player are only executed for the local player. + var localPlayer = playerId == lpId; // Updates that are independent of the player are only executed for the local player. bool lowLoad = false; if (Options.LowLoadMode.GetBool()) @@ -1297,9 +1305,9 @@ static class FixedUpdatePatch if (!GameStates.IsLobby) { - if (player.Is(CustomRoles.Spurt) && !Mathf.Approximately(Main.AllPlayerSpeed[player.PlayerId], Spurt.StartingSpeed[player.PlayerId]) && !inTask && !GameStates.IsMeeting) // fix ludicrous bug + if (player.Is(CustomRoles.Spurt) && !Mathf.Approximately(Main.AllPlayerSpeed[playerId], Spurt.StartingSpeed[playerId]) && !inTask && !GameStates.IsMeeting) // fix ludicrous bug { - Main.AllPlayerSpeed[player.PlayerId] = Spurt.StartingSpeed[player.PlayerId]; + Main.AllPlayerSpeed[playerId] = Spurt.StartingSpeed[playerId]; player.MarkDirtySettings(); } @@ -1336,7 +1344,7 @@ static class FixedUpdatePatch PlagueBearer.playerIdList.Remove(playerId); } - bool checkPos = inTask && player != null && alive && !Pelican.IsEaten(player.PlayerId); + bool checkPos = inTask && player != null && alive && !Pelican.IsEaten(playerId); if (checkPos) Asthmatic.OnCheckPlayerPosition(player); foreach (var state in Main.PlayerStates.Values) { @@ -1372,6 +1380,7 @@ static class FixedUpdatePatch if (timer.START_TIMESTAMP + timer.TOTALCD < TimeStamp || !alive) { Main.AbilityCD.Remove(playerId); + SendRPC(CustomRPC.SyncAbilityCD, 3, playerId); } if (!player.IsModClient() && timer.TOTALCD - (now - timer.START_TIMESTAMP) <= 60) NotifyRoles(SpecifySeer: player, SpecifyTarget: player); @@ -1434,7 +1443,7 @@ static class FixedUpdatePatch { if (GameStates.IsLobby) { - if (Main.PlayerVersion.TryGetValue(player.PlayerId, out var ver)) + if (Main.PlayerVersion.TryGetValue(playerId, out var ver)) { if (Main.ForkId != ver.forkId) __instance.cosmetics.nameText.text = $"{ver.forkId}\n{__instance?.name}"; diff --git a/Resources/Lang/en_US.json b/Resources/Lang/en_US.json index e6b565ae1..ef95a7415 100644 --- a/Resources/Lang/en_US.json +++ b/Resources/Lang/en_US.json @@ -2356,7 +2356,7 @@ "LoadingHint.25": "Meeting not ending when everyone voted?\nPress F6 to end the meeting while also counting the votes!", "LoadingHint.26": "Do you have a friend who thinks they understand everything, and you want to prove them wrong?\nTurn on the Chemist role and see their reaction!", "LoadingHint.27": "The Dev's favorite roles are:\nEcho, Penguin, Rift Maker, Bubble, Evolver, Rogue, Vengeance....\nand basically all crewmate roles :D", - "LoadingHint.28": "Did you know?\nEHR has 7 different game modes! Try them out!\nSwitch game modes using the ⇄ button next to the huge title in the top left of the settings menu!", + "LoadingHint.28": "Did you know?\nEHR has 9 different game modes! Try them out!\nSwitch game modes using the ⇄ button next to the huge title in the top left of the settings menu!", "LoadingHint.29": "Did you know?\nEHR has a unique game mode for expert gamers called Stop And Go!\nGive it a try after this game!", "LoadingHint.30": "Getting Crewmate over and over again? Didn't get to kill for the last half an hour?\nUnleash your bloodthirst in our Free For All game mode!", "LoadingHint.31": "Did you know?\nEHR has a custom Hide And Seek game mode with 12 special roles dedicated for this playstyle!", diff --git a/Roles/Crewmate/Grappler.cs b/Roles/Crewmate/Grappler.cs index 7f3f591c9..76b6703de 100644 --- a/Roles/Crewmate/Grappler.cs +++ b/Roles/Crewmate/Grappler.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using EHR.Modules; +using Hazel; namespace EHR.Crewmate { @@ -19,7 +20,7 @@ namespace EHR.Crewmate public override void SetupCustomOption() { - StartSetup(647250, TabGroup.CrewmateRoles, CustomRoles.Grappler) + StartSetup(647250) .AutoSetupOption(ref AbilityUseLimit, 0, new IntegerValueRule(0, 20, 1), OptionFormat.Times) .AutoSetupOption(ref AbilityUseGainWithEachTaskCompleted, 0.3f, new FloatValueRule(0f, 5f, 0.05f), OptionFormat.Times) .AutoSetupOption(ref AbilityChargesWhenFinishedTasks, 0.2f, new FloatValueRule(0f, 5f, 0.05f), OptionFormat.Times); @@ -56,7 +57,7 @@ namespace EHR.Crewmate return base.GetProgressText(playerId, comms) + (InUse ? "<#00ff00>\u271a" : string.Empty); } - public void ReceiveRPC(Hazel.MessageReader reader) + public void ReceiveRPC(MessageReader reader) { InUse = reader.ReadBoolean(); } diff --git a/Roles/Crewmate/Journalist.cs b/Roles/Crewmate/Journalist.cs index 074a16640..52ffef43d 100644 --- a/Roles/Crewmate/Journalist.cs +++ b/Roles/Crewmate/Journalist.cs @@ -15,7 +15,7 @@ namespace EHR.Crewmate public override void SetupCustomOption() { - StartSetup(647450, TabGroup.CrewmateRoles, CustomRoles.Journalist); + StartSetup(647450); } public override void Init() diff --git a/Roles/Crewmate/Negotiator.cs b/Roles/Crewmate/Negotiator.cs index 7705fa302..7e44d5ac6 100644 --- a/Roles/Crewmate/Negotiator.cs +++ b/Roles/Crewmate/Negotiator.cs @@ -24,7 +24,7 @@ namespace EHR.Crewmate public override void SetupCustomOption() { - StartSetup(647950, TabGroup.CrewmateRoles, CustomRoles.Negotiator) + StartSetup(647950) .AutoSetupOption(ref LowVision, 0.4f, new FloatValueRule(0f, 1f, 0.05f), OptionFormat.Multiplier) .AutoSetupOption(ref LowSpeed, 0.9f, new FloatValueRule(0.1f, 2f, 0.1f), OptionFormat.Multiplier) .AutoSetupOption(ref AbilityUseLimit, 0, new IntegerValueRule(0, 20, 1), OptionFormat.Times) diff --git a/Roles/Impostor/Assumer.cs b/Roles/Impostor/Assumer.cs index ac2adee20..6b5964f3c 100644 --- a/Roles/Impostor/Assumer.cs +++ b/Roles/Impostor/Assumer.cs @@ -21,7 +21,7 @@ namespace EHR.Impostor public override void SetupCustomOption() { - StartSetup(649250, TabGroup.ImpostorRoles, CustomRoles.Assumer) + StartSetup(649250) .AutoSetupOption(ref VoteReceiverDies, false) .AutoSetupOption(ref MinPlayersToAssume, 6, new IntegerValueRule(1, 15, 1), OptionFormat.Players) .AutoSetupOption(ref CanKill, true) diff --git a/Roles/Impostor/Hypnotist.cs b/Roles/Impostor/Hypnotist.cs index 15ba83a45..f1070682c 100644 --- a/Roles/Impostor/Hypnotist.cs +++ b/Roles/Impostor/Hypnotist.cs @@ -25,7 +25,7 @@ namespace EHR.Impostor public override void SetupCustomOption() { - StartSetup(647550, TabGroup.ImpostorRoles, CustomRoles.Hypnotist) + StartSetup(647550) .AutoSetupOption(ref AbilityCooldown, 30, new IntegerValueRule(0, 60, 1), OptionFormat.Seconds) .AutoSetupOption(ref AbilityDuration, 15, new IntegerValueRule(0, 30, 1), OptionFormat.Seconds) .AutoSetupOption(ref AbilityUseLimit, 1, new IntegerValueRule(0, 5, 1), OptionFormat.Times) diff --git a/Roles/Neutral/Gaslighter.cs b/Roles/Neutral/Gaslighter.cs index 9a890c011..ba5f77a5a 100644 --- a/Roles/Neutral/Gaslighter.cs +++ b/Roles/Neutral/Gaslighter.cs @@ -32,7 +32,7 @@ namespace EHR.Neutral public override void SetupCustomOption() { - StartSetup(648350, TabGroup.NeutralRoles, CustomRoles.Gaslighter) + StartSetup(648350) .AutoSetupOption(ref KillCooldown, 22.5f, new FloatValueRule(0f, 120f, 0.5f), OptionFormat.Seconds) .AutoSetupOption(ref WinCondition, 0, WinConditionOptions) .AutoSetupOption(ref CycleRepeats, false); @@ -55,6 +55,8 @@ namespace EHR.Neutral CycleFinished = false; } + public override bool CanUseKillButton(PlayerControl pc) => pc.IsAlive(); + public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = CurrentRound switch @@ -112,15 +114,16 @@ namespace EHR.Neutral CurrentRound++; } + var pc = GaslighterId.GetPlayer(); float limit = CurrentRound switch { Round.Knight => Monarch.KnightMax.GetFloat(), Round.Shield => Medic.SkillLimit, - _ => 0 + _ => float.NaN }; - GaslighterId.SetAbilityUseLimit(limit); + if (!float.IsNaN(limit)) GaslighterId.SetAbilityUseLimit(limit); + else pc?.RemoveAbilityCD(); - var pc = GaslighterId.GetPlayer(); pc?.ResetKillCooldown(); pc?.Notify(Translator.GetString($"Gaslighter.{CurrentRound}")); } diff --git a/Roles/Neutral/Shifter.cs b/Roles/Neutral/Shifter.cs index 7d9d45f9d..bdc695737 100644 --- a/Roles/Neutral/Shifter.cs +++ b/Roles/Neutral/Shifter.cs @@ -111,6 +111,7 @@ namespace EHR.Neutral } Main.AbilityCD.Remove(killer.PlayerId); + Utils.SendRPC(CustomRPC.SyncAbilityCD, 3, killer.PlayerId); killer.SyncSettings(); // ------------------------------------------------------------------------------------------ diff --git a/Roles/Neutral/Simon.cs b/Roles/Neutral/Simon.cs index d3faa42c3..893221243 100644 --- a/Roles/Neutral/Simon.cs +++ b/Roles/Neutral/Simon.cs @@ -187,7 +187,7 @@ namespace EHR.Neutral if (seer.IsModClient() && !hud && self) return string.Empty; if (self) return Translator.GetString(simon.DoMode ? "SimonDoMode" : "SimonDontMode"); - else if (simon.MarkedPlayers.TryGetValue(target.PlayerId, out var value)) return Translator.GetString(GetNotify(value.Instruction, value.DoAction, true)); + if (simon.MarkedPlayers.TryGetValue(target.PlayerId, out var value)) return Translator.GetString(GetNotify(value.Instruction, value.DoAction, true)); return string.Empty; } diff --git a/Roles/Neutral/Tank.cs b/Roles/Neutral/Tank.cs index 2679e050d..7279523ce 100644 --- a/Roles/Neutral/Tank.cs +++ b/Roles/Neutral/Tank.cs @@ -22,7 +22,7 @@ namespace EHR.Neutral public override void SetupCustomOption() { - StartSetup(646950, TabGroup.NeutralRoles, CustomRoles.Tank) + StartSetup(646950) .AutoSetupOption(ref Speed, 0.7f, new FloatValueRule(0.1f, 3f, 0.1f), OptionFormat.Multiplier) .AutoSetupOption(ref CanBeGuessed, false) .AutoSetupOption(ref CanBeKilled, true) diff --git a/Roles/Neutral/Technician.cs b/Roles/Neutral/Technician.cs index c753c231e..97f0f75cd 100644 --- a/Roles/Neutral/Technician.cs +++ b/Roles/Neutral/Technician.cs @@ -13,17 +13,16 @@ namespace EHR.Neutral private static OptionItem VentCooldown; private static OptionItem MaxInVentTime; private static readonly Dictionary PointGains = []; + private bool fixedSabotage; - public bool IsWon; - private PlayerControl TechnicianPC; public override bool IsEnable => On; public override void SetupCustomOption() { - StartSetup(646950, TabGroup.NeutralRoles, CustomRoles.Technician) + StartSetup(646450) .AutoSetupOption(ref WinsAlone, false) .AutoSetupOption(ref RequiredPoints, 5, new IntegerValueRule(1, 50, 1)) .AutoSetupOption(ref CanVent, false) diff --git a/Roles/RoleBase.cs b/Roles/RoleBase.cs index 10e2287aa..08d232076 100644 --- a/Roles/RoleBase.cs +++ b/Roles/RoleBase.cs @@ -194,8 +194,14 @@ namespace EHR } // Option setup simplifier - protected static OptionSetupHandler StartSetup(int id, TabGroup tab, CustomRoles role) + protected OptionSetupHandler StartSetup(int id) { + var role = Enum.Parse(this.GetType().Name, true); + var tab = TabGroup.OtherRoles; + if (role.IsImpostor()) tab = TabGroup.ImpostorRoles; + else if (role.IsNeutral(check: true)) tab = TabGroup.NeutralRoles; + else if (role.IsCrewmate()) tab = TabGroup.CrewmateRoles; + Options.SetupRoleOptions(id++, tab, role); return new(++id, tab, role); }