diff --git a/AmongUsRevamped.cs b/AmongUsRevamped.cs index d3db82e..8fb93dd 100644 --- a/AmongUsRevamped.cs +++ b/AmongUsRevamped.cs @@ -103,7 +103,9 @@ public partial class Main : BasePlugin Rose = 13, Banana = 14, Gray = 15, - Tan = 16 + Tan = 16, + Coral = 17, + Fortegreen = 18 } // Innersloth now censors messages with more than 5 numbers. This is the best bypass I can give diff --git a/Modules/CustomOptionsHolder.cs b/Modules/CustomOptionsHolder.cs index 3a54da7..d92d9af 100644 --- a/Modules/CustomOptionsHolder.cs +++ b/Modules/CustomOptionsHolder.cs @@ -26,6 +26,11 @@ namespace AmongUsRevamped "None", "0 Kill Cooldown", "Shift And Seek", "Speedrun" }; + public static readonly string[] colorLevels = + { + "Moderators", "Everyone", "Nobody" + }; + //System public static OptionItem Gamemode; @@ -50,6 +55,11 @@ namespace AmongUsRevamped public static OptionItem WaitAutoStart; public static OptionItem PlayerAutoStart; + public static OptionItem TabGroupMisc; + + public static OptionItem StartCountdown; + public static OptionItem ColorCommandLevel; + public static OptionItem AllowFortegreen; public static OptionItem NoGameEnd; //Mod @@ -222,9 +232,15 @@ namespace AmongUsRevamped .SetValueFormat(OptionFormat.Seconds); PlayerAutoStart = IntegerOptionItem.Create(64422, "Players Needed To Auto Start", new(1, 15, 1), 1, TabGroup.SystemSettings, false); - NoGameEnd = BooleanOptionItem.Create(60380, "No Game End", false, TabGroup.SystemSettings, false) - .SetColor(Color.red) - .SetHeader(true); + TabGroupMisc = TextOptionItem.Create(60379, "Miscelleneous", TabGroup.SystemSettings) + .SetColor(Color.green); + + StartCountdown = IntegerOptionItem.Create(60380, "Default Starting Countdown", new(1, 600, 1), 5, TabGroup.SystemSettings, false) + .SetValueFormat(OptionFormat.Seconds); + ColorCommandLevel = StringOptionItem.Create(60381, "Who Can use Color Commands", colorLevels, 0, TabGroup.SystemSettings, false); + AllowFortegreen = BooleanOptionItem.Create(60382, "Allow Fortegreen Color", false, TabGroup.SystemSettings, false); + NoGameEnd = BooleanOptionItem.Create(60383, "No Game End", false, TabGroup.SystemSettings, false) + .SetColor(Color.red); // Gamemode Settings TabGroupHNS = TextOptionItem.Create(70000, "Hide and Seek", TabGroup.GamemodeSettings) diff --git a/Modules/Hotkeys.cs b/Modules/Hotkeys.cs new file mode 100644 index 0000000..a341ed3 --- /dev/null +++ b/Modules/Hotkeys.cs @@ -0,0 +1,45 @@ +using AmongUs.Data; +using Hazel; +using InnerNet; +using UnityEngine; + +namespace AmongUsRevamped; + +[HarmonyPatch(typeof(ControllerManager), nameof(ControllerManager.Update))] +internal class Hotkeys +{ + public static void Postfix() + { + bool Shift = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift); + bool Enter = Input.GetKeyDown(KeyCode.Return); + + if (Input.GetKey(KeyCode.L) && Shift && Enter) + { + MessageWriter writer = AmongUsClient.Instance.StartEndGame(); + writer.Write((byte)GameOverReason.ImpostorDisconnect); + AmongUsClient.Instance.FinishEndGame(writer); + } + + if (Input.GetKey(KeyCode.M) && Shift && Enter && Utils.InGame) + { + if (Utils.IsMeeting) + { + MeetingHud.Instance.RpcClose(); + } + else + { + PlayerControl.LocalPlayer.ReportDeadBody(PlayerControl.LocalPlayer.Data); + } + } + + if (Shift && GameStartManager.InstanceExists && GameStartManager.Instance.startState == GameStartManager.StartingStates.Countdown && !HudManager.Instance.Chat.IsOpenOrOpening) + { + GameStartManager.Instance.countDownTimer = 0; + } + + if ((!AmongUsClient.Instance.IsGameStarted || !Utils.IsOnlineGame) && Utils.CanMove && PlayerControl.LocalPlayer.Collider != null) + { + PlayerControl.LocalPlayer.Collider.enabled = !Input.GetKey(KeyCode.LeftControl); + } + } +} \ No newline at end of file diff --git a/Modules/Utils.cs b/Modules/Utils.cs index adece03..292df39 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -32,9 +32,10 @@ public static class Utils public static bool IsLobby => AmongUsClient.Instance.GameState == InnerNetClient.GameStates.Joined; public static bool InGame => AmongUsClient.Instance && AmongUsClient.Instance.GameState == InnerNetClient.GameStates.Started; public static bool isHideNSeek => GameOptionsManager.Instance.CurrentGameOptions.GameMode == GameModes.HideNSeek; + public static bool IsOnlineGame => AmongUsClient.Instance.NetworkMode == NetworkModes.OnlineGame; public static bool IsShip => ShipStatus.Instance != null; - public static bool IsCanMove => PlayerControl.LocalPlayer?.CanMove is true; + public static bool CanMove => PlayerControl.LocalPlayer?.CanMove is true; public static bool IsDead => PlayerControl.LocalPlayer?.Data?.IsDead is true; public static bool IsFreePlay => AmongUsClient.Instance.NetworkMode == NetworkModes.FreePlay; diff --git a/Modules/Zoom.cs b/Modules/Zoom.cs index b95f552..05cd9ea 100644 --- a/Modules/Zoom.cs +++ b/Modules/Zoom.cs @@ -17,8 +17,8 @@ public static class Zoom public static void Postfix() { bool canZoom = - (Utils.IsShip && !Utils.IsMeeting && Utils.IsCanMove && PlayerControl.LocalPlayer.Data.IsDead) - || (Utils.IsLobby && Utils.IsCanMove); + (Utils.IsShip && !Utils.IsMeeting && Utils.CanMove && PlayerControl.LocalPlayer.Data.IsDead) + || (Utils.IsLobby && Utils.CanMove); if (!canZoom) { diff --git a/Patches/ChatPatches.cs b/Patches/ChatPatches.cs index 0f63933..88a200c 100644 --- a/Patches/ChatPatches.cs +++ b/Patches/ChatPatches.cs @@ -39,8 +39,6 @@ internal static class SendChatPatch { string text = __instance.freeChatField.textArea.text.Trim(); - if (__instance.timeSinceLastMessage < 3f || OnGameJoinedPatch.WaitingForChat) return false; - if (text == "/h" || text == "/help" || text == "/cmd" || text == "/commands") { HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, $"{allCommandsFull}"); @@ -49,6 +47,8 @@ internal static class SendChatPatch return false; } + if (__instance.timeSinceLastMessage < 3f || OnGameJoinedPatch.WaitingForChat) return false; + if (text == "/l" || text == "/lastgame" || text == "/win" || text == "/winner") { if (string.IsNullOrEmpty(NormalGameEndChecker.LastWinReason) || Utils.InGame) return false; @@ -103,6 +103,20 @@ internal static class SendChatPatch else { + bool col1 = text.StartsWith("/col ") || text.StartsWith("/cor "); + bool col2 = text.StartsWith("/color "); + + bool col3 = text.StartsWith("/colour "); + + string argCol = text.Substring(col1 ? 5 : col2 ? 7 : col3 ? 8 : 0).Trim(); + + if (Utils.TryGetColorId(argCol, out byte colId)) + { + PlayerControl.LocalPlayer.RpcSetColor(colId); + __instance.freeChatField.textArea.Clear(); + __instance.freeChatField.textArea.SetText(string.Empty); + } + bool isKick = text.StartsWith("/kick "); bool isBan = text.StartsWith("/ban "); @@ -170,10 +184,9 @@ public static class RPCHandlerPatch string text = subReader.ReadString(); Logger.Info($" {__instance.Data.PlayerName}: {text}", "SendChat"); - if (!Utils.IsPlayerModerator(__instance.Data.FriendCode) || !Options.ModeratorCanUseCommand.GetBool()) return; - if (text == "/h" || text == "/help" || text == "/cmd" || text == "/commands") { + if (!Utils.IsPlayerModerator(__instance.Data.FriendCode) || !Options.ModeratorCanUseCommand.GetBool()) return; OnGameJoinedPatch.WaitingForChat = true; new LateTask(() => @@ -194,26 +207,31 @@ public static class RPCHandlerPatch if (text == "/l" || text == "/lastgame" || text == "/win" || text == "/winner") { + if (!Utils.IsPlayerModerator(__instance.Data.FriendCode) || !Options.ModeratorCanUseCommand.GetBool()) return; if (string.IsNullOrEmpty(NormalGameEndChecker.LastWinReason) || Utils.InGame) return; Utils.ModeratorChatCommand($"{NormalGameEndChecker.LastWinReason}", "", false); } if (text == "/0kc" || text == "/0kcd" || text == "/0killcooldown") { + if (!Utils.IsPlayerModerator(__instance.Data.FriendCode) || !Options.ModeratorCanUseCommand.GetBool()) return; Utils.ModeratorChatCommand($"{SendChatPatch.noKcdMode}", "", false); } if (text == "/sns" || text == "/shiftandseek" || text == "/shift&seek") { + if (!Utils.IsPlayerModerator(__instance.Data.FriendCode) || !Options.ModeratorCanUseCommand.GetBool()) return; Utils.ModeratorChatCommand($"{SendChatPatch.SnSModeOne}", $"{SendChatPatch.SnSModeTwo}", true); } if (text == "/sp" || text == "/sr" || text == "/speedrun") { + if (!Utils.IsPlayerModerator(__instance.Data.FriendCode) || !Options.ModeratorCanUseCommand.GetBool()) return; Utils.ModeratorChatCommand($"{SendChatPatch.speedrunMode}", "", false); } if (text == "/r" || text == "/roles" || text == "/gamemode" || text == "/gm") { + if (!Utils.IsPlayerModerator(__instance.Data.FriendCode) || !Options.ModeratorCanUseCommand.GetBool()) return; switch (Options.Gamemode.GetValue()) { case 0: @@ -236,6 +254,24 @@ public static class RPCHandlerPatch else { + + bool col1 = text.StartsWith("/col ") || text.StartsWith("/cor "); + bool col2 = text.StartsWith("/color "); + + bool col3 = text.StartsWith("/colour "); + + string argCol = text.Substring(col1 ? 5 : col2 ? 7 : col3 ? 8 : 0).Trim(); + + if (Utils.TryGetColorId(argCol, out byte colId)) + { + if (Options.ColorCommandLevel.GetValue() == 0 && Utils.IsPlayerModerator(__instance.Data.FriendCode) || Options.ColorCommandLevel.GetValue() == 1) + { + if (colId > 17 && !Options.AllowFortegreen.GetBool()) return; + __instance.RpcSetColor(colId); + } + } + + if (!Utils.IsPlayerModerator(__instance.Data.FriendCode)) return; // Banning works by name and color. Commands are seperated incase someone has a color as their name bool isKick = text.StartsWith("/kick "); bool isBan = text.StartsWith("/ban "); @@ -284,4 +320,17 @@ public static class RPCHandlerPatch } } } +} + +[HarmonyPatch(typeof(HudManager), nameof(HudManager.Update))] +public static class HudManager_Update +{ + public static void Postfix(HudManager __instance) + { + if (Main.GM.Value) + { + __instance.Chat.gameObject.SetActive(true); + __instance.MapButton.gameObject.SetActive(true); + } + } } \ No newline at end of file diff --git a/Patches/EndGamePatches.cs b/Patches/EndGamePatches.cs index 8df93ae..a505aaf 100644 --- a/Patches/EndGamePatches.cs +++ b/Patches/EndGamePatches.cs @@ -67,28 +67,4 @@ class HNSGameEndChecker if (Options.NoGameEnd.GetBool()) return false; else return true; } -} - -[HarmonyPatch(typeof(ControllerManager), nameof(ControllerManager.Update))] -internal class ControllerManagerUpdatePatch -{ - public static void Postfix() - { - if (Input.GetKey(KeyCode.L) && Input.GetKey(KeyCode.LeftShift) && Input.GetKeyDown(KeyCode.Return)) - { - MessageWriter writer = AmongUsClient.Instance.StartEndGame(); - writer.Write((byte)GameOverReason.ImpostorDisconnect); - AmongUsClient.Instance.FinishEndGame(writer); - } - - if (Input.GetKey(KeyCode.M) && Input.GetKey(KeyCode.LeftShift) && Input.GetKeyDown(KeyCode.Return) && Utils.InGame) - { - if (Utils.IsMeeting) - { - MeetingHud.Instance.RpcClose(); - } - else - PlayerControl.LocalPlayer.ReportDeadBody(PlayerControl.LocalPlayer.Data); - } - } } \ No newline at end of file diff --git a/Patches/GameStartManagerPatch.cs b/Patches/GameStartManagerPatch.cs index ec9aa12..703da22 100644 --- a/Patches/GameStartManagerPatch.cs +++ b/Patches/GameStartManagerPatch.cs @@ -5,6 +5,9 @@ namespace AmongUsRevamped; [HarmonyPatch(typeof(GameStartManager), nameof(GameStartManager.Update))] public static class GameStartManagerUpdatePatch { + public static bool CustomTimerApplied; + public static bool Autostarting; + public static void Prefix(GameStartManager __instance) { if (!AmongUsClient.Instance.AmHost || AmongUsClient.Instance == null) return; @@ -13,9 +16,23 @@ public static class GameStartManagerUpdatePatch if (Main.AutoStart.Value && OnGameJoinedPatch.AutoStartCheck && GameStartManager.InstanceExists && GameStartManager.Instance.startState != GameStartManager.StartingStates.Countdown && GameData.Instance?.PlayerCount >= Options.PlayerAutoStart.GetInt()) { - GameStartManager.Instance.startState = GameStartManager.StartingStates.Countdown; - GameStartManager.Instance.countDownTimer = Options.AutoStartTimer.GetFloat(); - GameStartManager.Instance?.StartButton.gameObject.SetActive(false); + GameStartManager.Instance.startState = GameStartManager.StartingStates.Countdown; + GameStartManager.Instance.countDownTimer = Options.AutoStartTimer.GetFloat(); + GameStartManager.Instance?.StartButton.gameObject.SetActive(false); + Autostarting = true; + } + + if (__instance.startState == GameStartManager.StartingStates.Countdown && !CustomTimerApplied && !Autostarting) + { + __instance.countDownTimer = Options.StartCountdown.GetInt(); + CustomTimerApplied = true; + + } + + if (__instance.startState != GameStartManager.StartingStates.Countdown) + { + Autostarting = false; + CustomTimerApplied = false; } } } \ No newline at end of file diff --git a/Patches/PlayerControlPatches.cs b/Patches/PlayerControlPatches.cs index c77364c..6c608ae 100644 --- a/Patches/PlayerControlPatches.cs +++ b/Patches/PlayerControlPatches.cs @@ -43,8 +43,6 @@ class FixedUpdateInGamePatch if (Options.SNSSettingsOverride.GetBool() && g == null) { - Main.NormalOptions.NumEmergencyMeetings = 0; - Main.NormalOptions.TaskBarMode = 0; } }