From dcacd73c036c6f6104d5f95e67eef4d24f8b0571 Mon Sep 17 00:00:00 2001 From: Gurge44 Date: Mon, 15 Sep 2025 11:29:52 +0200 Subject: [PATCH] various fixes --- CTA/CustomTeamAssigner/CustomRoles.cs | 1 + GameMode/BedWars.cs | 2 +- Main.cs | 4 ++-- Modules/CustomRolesHelper.cs | 14 ++++++++++++++ Modules/ExtendedPlayerControl.cs | 6 ++++-- Modules/GuessManager.cs | 2 +- Modules/NameNotifyManager.cs | 4 +++- Modules/Utils.cs | 6 ++++-- Patches/CheckGameEndPatch.cs | 2 +- Patches/OnGameStartedPatch.cs | 2 +- Patches/PlayerControlPatch.cs | 15 ++++++--------- Resources/Lang/en_US.json | 1 + Roles/Crewmate/Scout.cs | 12 ++---------- Roles/Impostor/Cantankerous.cs | 8 +------- Roles/Impostor/Changeling.cs | 2 +- Roles/Impostor/Eraser.cs | 2 +- Roles/Impostor/Mastermind.cs | 12 ++++-------- Roles/Impostor/Sniper.cs | 2 +- Roles/Impostor/Venerer.cs | 3 ++- Roles/Neutral/Jackal.cs | 4 +--- 20 files changed, 52 insertions(+), 52 deletions(-) diff --git a/CTA/CustomTeamAssigner/CustomRoles.cs b/CTA/CustomTeamAssigner/CustomRoles.cs index 408d0cb71..1f22880c5 100644 --- a/CTA/CustomTeamAssigner/CustomRoles.cs +++ b/CTA/CustomTeamAssigner/CustomRoles.cs @@ -289,6 +289,7 @@ public enum CustomRoles Bubble, Chemist, Cherokious, + Clerk, Collector, Curser, Deathknight, diff --git a/GameMode/BedWars.cs b/GameMode/BedWars.cs index fdb40627b..fe076d583 100644 --- a/GameMode/BedWars.cs +++ b/GameMode/BedWars.cs @@ -1753,12 +1753,12 @@ public static class BedWars } } + Breaking.Remove(pc.PlayerId); NameNotifyManager.Notifies.Remove(pc.PlayerId); Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc); Layers.RemoveAt(Layers.Count - 1); data.Inventory.Adjust(topLayer, GetNextProtectReq()); UpdateStatus(); - Breaking.Remove(pc.PlayerId); if (Layers.Count == 0 && data.Team != Team) Broken(); } } diff --git a/Main.cs b/Main.cs index 453d46e9b..461818bdf 100644 --- a/Main.cs +++ b/Main.cs @@ -42,8 +42,8 @@ public class Main : BasePlugin private const string DebugKeyHash = "c0fd562955ba56af3ae20d7ec9e64c664f0facecef4b3e366e109306adeae29d"; private const string DebugKeySalt = "59687b"; private const string PluginGuid = "com.gurge44.endlesshostroles"; - public const string PluginVersion = "6.3.1"; - public const string PluginDisplayVersion = "6.3.1"; + public const string PluginVersion = "6.4.0"; + public const string PluginDisplayVersion = "6.4.0"; public const bool TestBuild = false; public const string NeutralColor = "#ffab1b"; diff --git a/Modules/CustomRolesHelper.cs b/Modules/CustomRolesHelper.cs index 4a763db6f..7ddbd1dd6 100644 --- a/Modules/CustomRolesHelper.cs +++ b/Modules/CustomRolesHelper.cs @@ -1230,6 +1230,20 @@ internal static class CustomRolesHelper CustomRoles.Wyrd; } + public static bool IncompatibleWithVenom(this CustomRoles role) + { + return role switch + { + CustomRoles.Bomber when !Bomber.BomberCanKill.GetBool() => true, + CustomRoles.Changeling when !Changeling.CanKillBeforeRoleChange.GetBool() => true, + CustomRoles.Eraser when Eraser.EraseMethod.GetValue() == 0 => true, + CustomRoles.Silencer when Silencer.SilenceMode.GetValue() == 0 => true, + CustomRoles.Sniper when !Sniper.CanKillWithBullets.GetBool() => true, + CustomRoles.Augmenter or CustomRoles.BallLightning or CustomRoles.Blackmailer or CustomRoles.Cantankerous or CustomRoles.Capitalism or CustomRoles.Consort or CustomRoles.Echo or CustomRoles.EvilDiviner or CustomRoles.FireWorks or CustomRoles.Framer or CustomRoles.Gangster or CustomRoles.Generator or CustomRoles.Hangman or CustomRoles.Inhibitor or CustomRoles.Kamikaze or CustomRoles.Mastermind or CustomRoles.Morphling or CustomRoles.Ninja or CustomRoles.Nullifier or CustomRoles.Penguin or CustomRoles.Puppeteer or CustomRoles.Saboteur or CustomRoles.Sapper or CustomRoles.Scavenger or CustomRoles.Swooper or CustomRoles.Undertaker or CustomRoles.Vampire or CustomRoles.Warlock or CustomRoles.Wasp or CustomRoles.Wiper or CustomRoles.Witch or CustomRoles.YinYanger => true, + _ => false + }; + } + public static RoleTypes GetRoleTypes(this CustomRoles role) { if (Enum.TryParse(role.GetVNRole(true).ToString().Replace("EHR", ""), true, out RoleTypes type)) return type; diff --git a/Modules/ExtendedPlayerControl.cs b/Modules/ExtendedPlayerControl.cs index 65fdcd1cd..7ea81eead 100644 --- a/Modules/ExtendedPlayerControl.cs +++ b/Modules/ExtendedPlayerControl.cs @@ -85,6 +85,9 @@ internal static class ExtendedPlayerControl public static bool CanUseVent(this PlayerControl player, int ventId) { + int? closestVentId = player.GetClosestVent()?.Id; + if (player.inVent && closestVentId == ventId) return true; + switch (Options.CurrentGameMode) { case CustomGameMode.RoomRush: @@ -96,9 +99,8 @@ internal static class ExtendedPlayerControl } if (player.Is(CustomRoles.Trainee) && MeetingStates.FirstMeeting) return false; - if (player.Is(CustomRoles.Blocked) && player.GetClosestVent()?.Id != ventId) return false; + if (player.Is(CustomRoles.Blocked) && closestVentId != ventId) return false; if (!GameStates.IsInTask || ExileController.Instance || AntiBlackout.SkipTasks || Main.Invisible.Contains(player.PlayerId)) return false; - if (player.inVent && player.GetClosestVent()?.Id == ventId) return true; return (player.CanUseImpostorVentButton() || player.GetRoleTypes() == RoleTypes.Engineer) && Main.PlayerStates.Values.All(x => x.Role.CanUseVent(player, ventId)); } diff --git a/Modules/GuessManager.cs b/Modules/GuessManager.cs index 33d4c5924..aa9144a5e 100644 --- a/Modules/GuessManager.cs +++ b/Modules/GuessManager.cs @@ -142,7 +142,7 @@ public static class GuessManager if ((pc.IsCrewmate() && target.IsCrewmate() && !Options.CrewCanGuessCrew.GetBool()) || (pc.IsImpostor() && target.IsImpostor() && !Options.ImpCanGuessImp.GetBool())) { - ShowMessage("GuessNotAllowed"); + ShowMessage("GuessTeamMate"); return true; } diff --git a/Modules/NameNotifyManager.cs b/Modules/NameNotifyManager.cs index 3c9697a45..96c0b7db8 100644 --- a/Modules/NameNotifyManager.cs +++ b/Modules/NameNotifyManager.cs @@ -20,7 +20,9 @@ public static class NameNotifyManager { if (!AmongUsClient.Instance.AmHost || pc == null) return; if (!GameStates.IsInTask) return; - if (!text.Contains("")) text = Utils.ColorString(Color.white, text); + + text = text.Trim(); + if (!text.Contains("") && !text.Contains("<#")) text = Utils.ColorString(Color.white, text); if (!text.Contains("{text}"; long expireTS = Utils.TimeStamp + (long)time; diff --git a/Modules/Utils.cs b/Modules/Utils.cs index e8dc17197..9a15455eb 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -298,8 +298,10 @@ public static class Utils { if (mapId is 1 or 5) { - var hqHudSystemType = systemType.CastFast(); - return hqHudSystemType is { IsActive: true }; + var hqHudSystemType = systemType.TryCast(); + // ReSharper disable once MergeIntoPattern + // For some reason, the game sometimes crashes here when trying to get_IsActive + return hqHudSystemType != null && hqHudSystemType.IsActive; } var hudOverrideSystemType = systemType.CastFast(); diff --git a/Patches/CheckGameEndPatch.cs b/Patches/CheckGameEndPatch.cs index 5f9b52913..c555de4a2 100644 --- a/Patches/CheckGameEndPatch.cs +++ b/Patches/CheckGameEndPatch.cs @@ -593,7 +593,7 @@ internal static class GameEndChecker foreach (PlayerState playerState in statesCoutingAsCrew) { - if (playerState.Player == null || !playerState.Player.IsAlive()) continue; + if (playerState.Player == null || !playerState.Player.IsAlive() || !Options.CrewAdvancedGameEndCheckingSettings[playerState.MainRole].GetBool()) continue; playerState.Role.ManipulateGameEndCheckCrew(out bool keepGameGoing, out int countsAs); crewKeepsGameGoing |= keepGameGoing; crew += countsAs - 1; diff --git a/Patches/OnGameStartedPatch.cs b/Patches/OnGameStartedPatch.cs index 3114787d0..4eb425fb4 100644 --- a/Patches/OnGameStartedPatch.cs +++ b/Patches/OnGameStartedPatch.cs @@ -739,7 +739,7 @@ internal static class StartGameHostPatch } } - if (kp.Value.IsImpostor() && kp.Value.GetRoleTypes() == RoleTypes.Impostor && !venomBanned) + if (kp.Value.IsImpostor() && kp.Value.GetRoleTypes() == RoleTypes.Impostor && !kp.Value.IncompatibleWithVenom() && !venomBanned) venomList.Add(player.PlayerId); } } diff --git a/Patches/PlayerControlPatch.cs b/Patches/PlayerControlPatch.cs index ff45d2e86..de5af2cfb 100644 --- a/Patches/PlayerControlPatch.cs +++ b/Patches/PlayerControlPatch.cs @@ -2012,7 +2012,7 @@ internal static class FixedUpdatePatch { target.cosmetics.nameText.text = changeTo; - var offset = 0.2f; + var offset = 0.1f; if (self && NameNotifyManager.GetNameNotify(seer, out string notify) && notify.Contains('\n')) { @@ -2039,7 +2039,7 @@ internal static class FixedUpdatePatch offset += 0.8f; if (Options.LargerRoleTextSize.GetBool()) - offset += 0.15f; + offset += 0.05f; roleText.transform.SetLocalY(offset); target.cosmetics.colorBlindText.transform.SetLocalY(-(offset + 0.2f)); @@ -2048,7 +2048,7 @@ internal static class FixedUpdatePatch else { // Restoring the position text coordinates to their initial values - roleText.transform.SetLocalY(0.2f); + roleText.transform.SetLocalY(0.1f); } } @@ -2110,9 +2110,7 @@ internal static class PlayerStartPatch if (__result || __instance == null || __instance.__4__this == null || __instance.__4__this.PlayerId >= 254 || __instance.__4__this.cosmetics == null) return; TextMeshPro nameText = __instance.__4__this.cosmetics.nameText; TextMeshPro roleText = Object.Instantiate(nameText, nameText.transform, true); - bool largerFontSize = Options.LargerRoleTextSize.GetBool(); - roleText.transform.localPosition = new(0f, largerFontSize ? 0.35f : 0.2f, 0f); - if (!largerFontSize) roleText.fontSize -= 0.9f; + if (!Options.LargerRoleTextSize.GetBool()) roleText.fontSize -= 0.9f; roleText.text = "RoleText"; roleText.gameObject.name = "RoleText"; roleText.enabled = false; @@ -2275,7 +2273,7 @@ internal static class GameDataCompleteTaskPatch { public static void Postfix(PlayerControl pc, uint taskId) { - if (GameStates.IsMeeting) return; + if (MeetingHud.Instance && MeetingHud.Instance.state != MeetingHud.VoteStates.Animating) return; if (Options.CurrentGameMode == CustomGameMode.HideAndSeek && CustomHnS.PlayerRoles[pc.PlayerId].Interface.Team == Team.Crewmate && pc.IsAlive()) { @@ -2294,8 +2292,7 @@ internal static class PlayerControlCompleteTaskPatch { public static bool Prefix(PlayerControl __instance) { - if (GameStates.IsMeeting) return false; - + if (MeetingHud.Instance && MeetingHud.Instance.state != MeetingHud.VoteStates.Animating) return false; return !Workhorse.OnCompleteTask(__instance) && Capitalism.AddTaskForPlayer(__instance); // Cancel task win } diff --git a/Resources/Lang/en_US.json b/Resources/Lang/en_US.json index ed079dc98..4c4cc085b 100644 --- a/Resources/Lang/en_US.json +++ b/Resources/Lang/en_US.json @@ -2263,6 +2263,7 @@ "BittenByInfectious": "You were infected by the Infectious!", "InfectiousBittenPlayer": "You successfully infected a player", "GuessNotAllowed": "Sorry, your role does not have access to guessing.", + "GuessTeamMate": "Sorry, you can't guess your teammates.", "GuessOnbound": "This player has the Onbound add-on, so your guess on them was canceled.", "GuessPhantom": "You can't guess a Specter, that allows them to win!", "DovesOfNeaceOnGuard": "Ability used, {0} uses remain", diff --git a/Roles/Crewmate/Scout.cs b/Roles/Crewmate/Scout.cs index d311922dd..72e82f8bc 100644 --- a/Roles/Crewmate/Scout.cs +++ b/Roles/Crewmate/Scout.cs @@ -29,8 +29,6 @@ public class Scout : RoleBase public override bool IsEnable => PlayerIdList.Count > 0; - public override bool SeesArrowsToDeadBodies => true; - public override void SetupCustomOption() { SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Scout); @@ -127,14 +125,7 @@ public class Scout : RoleBase public override string GetSuffix(PlayerControl seer, PlayerControl target, bool hud = false, bool meeting = false) { - if (seer == null || seer.PlayerId != TrackerId) return string.Empty; - - if (target != null && seer.PlayerId != target.PlayerId) return string.Empty; - - if (!TrackerTarget.ContainsKey(seer.PlayerId)) return string.Empty; - - if (GameStates.IsMeeting) return string.Empty; - + if (seer == null || seer.PlayerId != TrackerId || target != null && seer.PlayerId != target.PlayerId || !TrackerTarget.ContainsKey(seer.PlayerId) || GameStates.IsMeeting) return string.Empty; return TrackerTarget[seer.PlayerId].Aggregate(string.Empty, (current, trackTarget) => current + Utils.ColorString(CanGetColoredArrow.GetBool() ? Main.PlayerColors[trackTarget] : Color.white, TargetArrow.GetArrows(seer, trackTarget))) + LocateArrow.GetArrows(seer); } @@ -173,6 +164,7 @@ public class Scout : RoleBase { kvp.Value.Remove(player.PlayerId); TargetArrow.Remove(kvp.Key, player.PlayerId); + LocateArrow.Add(kvp.Key, player.Pos()); } } } diff --git a/Roles/Impostor/Cantankerous.cs b/Roles/Impostor/Cantankerous.cs index 06421db43..aa31f50af 100644 --- a/Roles/Impostor/Cantankerous.cs +++ b/Roles/Impostor/Cantankerous.cs @@ -68,14 +68,8 @@ public class Cantankerous : RoleBase } } - public override bool OnCheckMurder(PlayerControl killer, PlayerControl target) + public override void OnMurder(PlayerControl killer, PlayerControl target) { - if (!base.OnCheckMurder(killer, target)) return false; - - if (killer.GetAbilityUseLimit() <= 0) return false; - killer.RpcRemoveAbilityUse(); - - return true; } } \ No newline at end of file diff --git a/Roles/Impostor/Changeling.cs b/Roles/Impostor/Changeling.cs index f792f7160..f5bff642c 100644 --- a/Roles/Impostor/Changeling.cs +++ b/Roles/Impostor/Changeling.cs @@ -12,7 +12,7 @@ internal class Changeling : RoleBase public static readonly Dictionary ChangedRole = []; private static OptionItem CanPickPartnerRole; - private static OptionItem CanKillBeforeRoleChange; + public static OptionItem CanKillBeforeRoleChange; private static OptionItem AvailableRoles; private static readonly string[] AvailableRolesMode = diff --git a/Roles/Impostor/Eraser.cs b/Roles/Impostor/Eraser.cs index 28a6a1353..c53b80d54 100644 --- a/Roles/Impostor/Eraser.cs +++ b/Roles/Impostor/Eraser.cs @@ -23,7 +23,7 @@ internal class Eraser : RoleBase ]; private static OptionItem EraseLimitOpt; - private static OptionItem EraseMethod; + public static OptionItem EraseMethod; private static OptionItem WhenTargetIsNeutral; public static OptionItem HideVote; public static OptionItem CancelVote; diff --git a/Roles/Impostor/Mastermind.cs b/Roles/Impostor/Mastermind.cs index 4436a1b72..0a45bcbf6 100644 --- a/Roles/Impostor/Mastermind.cs +++ b/Roles/Impostor/Mastermind.cs @@ -106,14 +106,10 @@ public class Mastermind : RoleBase ManipulateDelays.Remove(x.Key); ManipulatedPlayers.TryAdd(x.Key, TimeStamp); - if (pc.HasKillButton()) - { - TempKCDs.TryAdd(pc.PlayerId, Main.KillTimers[pc.PlayerId]); - pc.SetKillCooldown(1f); - } - else - pc.RpcChangeRoleBasis(CustomRoles.SerialKiller); - + if (pc.HasKillButton()) TempKCDs.TryAdd(pc.PlayerId, Main.KillTimers[pc.PlayerId]); + else pc.RpcChangeRoleBasis(CustomRoles.SerialKiller); + + pc.SetKillCooldown(1f); NotifyRoles(SpecifySeer: MastermindPC, SpecifyTarget: pc); } } diff --git a/Roles/Impostor/Sniper.cs b/Roles/Impostor/Sniper.cs index 4af5fb4cc..8c6b25942 100644 --- a/Roles/Impostor/Sniper.cs +++ b/Roles/Impostor/Sniper.cs @@ -20,7 +20,7 @@ public class Sniper : RoleBase private static OptionItem SniperAimAssist; private static OptionItem SniperAimAssistOnshot; private static OptionItem ShapeshiftDuration; - private static OptionItem CanKillWithBullets; + public static OptionItem CanKillWithBullets; private static bool MeetingReset; private static int MaxBulletCount; diff --git a/Roles/Impostor/Venerer.cs b/Roles/Impostor/Venerer.cs index 647bf63c3..38feb61c5 100644 --- a/Roles/Impostor/Venerer.cs +++ b/Roles/Impostor/Venerer.cs @@ -88,12 +88,13 @@ public class Venerer : RoleBase switch (Stage) { case 1: + var outfit = pc.Data.DefaultOutfit; Utils.RpcChangeSkin(pc, new NetworkedPlayerInfo.PlayerOutfit().Set("", 15, "", "", "", "", "")); ChangedSkin = true; LateTask.New(() => { if (!ChangedSkin || pc == null || !pc.IsAlive()) return; - Utils.RpcChangeSkin(pc, Camouflage.PlayerSkins[pc.PlayerId]); + Utils.RpcChangeSkin(pc, outfit); ChangedSkin = false; }, AbilityDuration.GetInt(), log: false); break; diff --git a/Roles/Neutral/Jackal.cs b/Roles/Neutral/Jackal.cs index 024db953a..750509a95 100644 --- a/Roles/Neutral/Jackal.cs +++ b/Roles/Neutral/Jackal.cs @@ -193,10 +193,8 @@ public class Jackal : RoleBase private static bool CanBeSidekick(PlayerControl pc) { if (!CanRecruitImpostors.GetBool() && pc.Is(CustomRoleTypes.Impostor)) return false; - if (!CanRecruitMadmates.GetBool() && pc.IsMadmate()) return false; - - return pc != null && !pc.Is(CustomRoles.Sidekick) && !pc.Is(CustomRoles.Curser) && !pc.Is(CustomRoles.Loyal) && !pc.IsConverted() && pc.GetCustomRole().IsAbleToBeSidekicked(); + return pc != null && !pc.Is(CustomRoles.Sidekick) && !pc.Is(CustomRoles.Curser) && !pc.Is(CustomRoles.Loyal) && !pc.Is(CustomRoles.Bloodlust) && !pc.IsConverted() && pc.GetCustomRole().IsAbleToBeSidekicked(); } public override void OnFixedUpdate(PlayerControl pc)