diff --git a/AmongUsRevamped.cs b/AmongUsRevamped.cs index 0de767b..ff4cccc 100644 --- a/AmongUsRevamped.cs +++ b/AmongUsRevamped.cs @@ -42,7 +42,7 @@ public partial class Main : BasePlugin public static bool HasArgumentException; public static string CredentialsText; - public const string ModVersion = "v1.6.0"; + public const string ModVersion = "v1.6.1"; public static float GameTimer; diff --git a/Modules/BanManager.cs b/Modules/BanManager.cs index c223135..1ef39c6 100644 --- a/Modules/BanManager.cs +++ b/Modules/BanManager.cs @@ -22,6 +22,7 @@ public static class BanManager public static string RemoveHtmlTags(this string str) => Regex.Replace(str, "<[^>]*?>", ""); private static readonly string DenyNameListPath = $"{DataPath}/AUR-DATA/DenyNameList.txt"; private static string BanListPath = $"{DataPath}/AUR-DATA/Banlist.txt"; + private static string BanWordPath = $"{DataPath}/AUR-DATA/Bannedwords.txt"; private static string VipListPath = $"{DataPath}/AUR-DATA/VIP.txt"; private static string ModeratorListPath = $"{DataPath}/AUR-DATA/Moderator.txt"; private static string AdminListPath = $"{DataPath}/AUR-DATA/Admin.txt"; @@ -42,6 +43,11 @@ public static class BanManager Logger.Warn("Creating a new Banlist.txt file", "BanManager"); File.Create(BanListPath).Close(); } + if (!File.Exists(BanWordPath)) + { + Logger.Warn("Creating a new Banlist.txt file", "BanManager"); + File.Create(BanWordPath).Close(); + } if (!File.Exists(VipListPath)) { Logger.Warn("Creating a new VIP.txt file", "BanManager"); @@ -172,22 +178,39 @@ public static class BanManager { AmongUsClient.Instance.KickPlayer(client.Id, false); Logger.Info($" {name} was kicked because their name was in DenyNameList.txt", "Kick"); - Logger.SendInGame($" {name} was kicked because their name was in DenyNameList.txt"); + Logger.SendInGame($"{name} was kicked because their name was in DenyNameList.txt"); return true; } else return false; } -} -[HarmonyPatch(typeof(BanMenu), nameof(BanMenu.Select))] -class BanMenuSelectPatch -{ - public static void Postfix(BanMenu __instance, int clientId) + public static bool IsWordBanned(PlayerControl player, string input) { - ClientData recentClient = AmongUsClient.Instance.GetRecentClient(clientId); - if (recentClient == null) return; + if (input == "" || !AmongUsClient.Instance.AmHost) return false; - if (!BanManager.CheckBanList(recentClient?.FriendCode, recentClient?.GetHashedPuid())) - __instance.BanButton.GetComponent().SetEnabledColors(); + var bannedWords = File.ReadAllLines(BanWordPath); + + if (bannedWords.Where(code => !string.IsNullOrWhiteSpace(code)).Any(code => input.Contains(code, StringComparison.OrdinalIgnoreCase))) + { + AmongUsClient.Instance.KickPlayer(player.Data.ClientId, false); + Logger.Info($" {player.Data.PlayerName} was kicked because they sent a banned word", "Kick"); + Logger.SendInGame($"{player.Data.PlayerName} was kicked because they sent a banned word"); + return true; + } + else return false; + + } + + [HarmonyPatch(typeof(BanMenu), nameof(BanMenu.Select))] + class BanMenuSelectPatch + { + public static void Postfix(BanMenu __instance, int clientId) + { + ClientData recentClient = AmongUsClient.Instance.GetRecentClient(clientId); + if (recentClient == null) return; + + if (!BanManager.CheckBanList(recentClient?.FriendCode, recentClient?.GetHashedPuid())) + __instance.BanButton.GetComponent().SetEnabledColors(); + } } } diff --git a/Modules/CustomOptionsHolder.cs b/Modules/CustomOptionsHolder.cs index fdb171a..c0debc5 100644 --- a/Modules/CustomOptionsHolder.cs +++ b/Modules/CustomOptionsHolder.cs @@ -54,7 +54,7 @@ namespace AmongUsRevamped public static readonly string[] gameModes = { - "None", "0 Kill Cooldown", "Shift And Seek", "Speedrun" + "Standard", "0 Kill Cooldown", "Shift And Seek", "Speedrun" }; public static readonly string[] accessLevels = @@ -123,6 +123,7 @@ namespace AmongUsRevamped public static OptionItem DecontaminationDoorOpenTimeOnMiraHQ; public static OptionItem DecontaminationTimeOnPolus; public static OptionItem DecontaminationDoorOpenTimeOnPolus; + public static OptionItem DisableSporeTrigger; public static OptionItem DisableDevices; private static OptionItem DisableSkeldDevices; @@ -147,8 +148,8 @@ namespace AmongUsRevamped public static OptionItem TabGroupTasks; public static OptionItem OverrideTaskSettings; - public static OptionItem AllPlayersSameTasks; + public static OptionItem TaskPercentNeededToWin; public static OptionItem DisableMiraTasks; @@ -359,7 +360,7 @@ namespace AmongUsRevamped SlashKickCmd = StringOptionItem.Create(60405, Translator.Get("slashKickCmd"), accessLevels, 2, TabGroup.SystemSettings, false); SlashBanCmd = StringOptionItem.Create(60406, Translator.Get("slashBanCmd"), accessLevels, 2, TabGroup.SystemSettings, false); SlashEndMeetingCmd = StringOptionItem.Create(60407, Translator.Get("slashEndMeetingCmd"), accessLevels, 3, TabGroup.SystemSettings, false); - SlashStartAndEndGameCmd = StringOptionItem.Create(60403, Translator.Get("slashStartAndEndGameCmd"), accessLevels, 3, TabGroup.SystemSettings, false); + SlashStartAndEndGameCmd = StringOptionItem.Create(60408, Translator.Get("slashStartAndEndGameCmd"), accessLevels, 3, TabGroup.SystemSettings, false); // Custom role settings @@ -388,7 +389,7 @@ namespace AmongUsRevamped // Gamemode Settings TabGroupStandard = TextOptionItem.Create(69998, Translator.Get("tabGroupStandard"), TabGroup.GamemodeSettings) .SetColor(Color.white); - ChatBeforeFirstMeeting = BooleanOptionItem.Create(69999, Translator.Get("chatBeforeFirstMeeting"), true, TabGroup.GamemodeSettings, false); + ChatBeforeFirstMeeting = BooleanOptionItem.Create(69999, Translator.Get("chatBeforeFirstMeeting"), false, TabGroup.GamemodeSettings, false); TabGroupHNS = TextOptionItem.Create(70000, Translator.Get("tabGroupHNS"), TabGroup.GamemodeSettings) .SetColor(Color.green); @@ -489,6 +490,9 @@ namespace AmongUsRevamped .SetValueFormat(OptionFormat.Seconds) .SetColor(new Color32(19, 188, 233, byte.MaxValue)); + DisableSporeTrigger = BooleanOptionItem.Create(60558, Translator.Get("disableSporeTrigger"), false, TabGroup.ModSettings, false) + .SetColor(new Color32(19, 188, 233, byte.MaxValue)); + DisableDevices = BooleanOptionItem.Create(22900, Translator.Get("disableDevices"), false, TabGroup.ModSettings, false) .SetColor(Color.red); @@ -541,99 +545,97 @@ namespace AmongUsRevamped .SetParent(DisableAirshipDevices) .SetColor(new Color32(255, 153, 153, byte.MaxValue)); - DisableFungleDevices = BooleanOptionItem.Create(22925, "Disable Fungle Devices", false, TabGroup.ModSettings, false) + DisableFungleDevices = BooleanOptionItem.Create(22925, Translator.Get("disableFungleDevices"), false, TabGroup.ModSettings, false) .SetParent(DisableDevices) .SetColor(new Color32(255, 153, 153, byte.MaxValue)); - DisableFungleCamera = BooleanOptionItem.Create(22926, "Disable Fungle Camera", false, TabGroup.ModSettings, false) + DisableFungleCamera = BooleanOptionItem.Create(22926, Translator.Get("disableFungleCamera"), false, TabGroup.ModSettings, false) .SetParent(DisableFungleDevices) .SetColor(new Color32(255, 153, 153, byte.MaxValue)); - DisableFungleVital = BooleanOptionItem.Create(22927, "Disable Fungle Vitals", false, TabGroup.ModSettings, false) + DisableFungleVital = BooleanOptionItem.Create(22927, Translator.Get("disableFungleVital"), false, TabGroup.ModSettings, false) .SetParent(DisableFungleDevices) .SetColor(new Color32(255, 153, 153, byte.MaxValue)); - - TabGroupTasks = TextOptionItem.Create(22997, "Tasks", TabGroup.ModSettings) + TabGroupTasks = TextOptionItem.Create(22995, Translator.Get("tabGroupTasks"), TabGroup.ModSettings) .SetColor(Color.yellow); - AllPlayersSameTasks = BooleanOptionItem.Create(22998, "Everyone has same tasks", false, TabGroup.ModSettings, false) + TaskPercentNeededToWin = IntegerOptionItem.Create(22996, Translator.Get("taskPercentNeededToWin"), new(30, 100, 5), 100, TabGroup.ModSettings, false) + .SetColor(new Color32(255, 255, 153, byte.MaxValue)) + .SetValueFormat(OptionFormat.Percent); + AllPlayersSameTasks = BooleanOptionItem.Create(22998, Translator.Get("allPlayersSameTasks"), false, TabGroup.ModSettings, false) + .SetColor(new Color32(255, 255, 153, byte.MaxValue)); + OverrideTaskSettings = BooleanOptionItem.Create(22999, Translator.Get("overrideTaskSettings"), false, TabGroup.ModSettings, false) .SetColor(new Color32(255, 255, 153, byte.MaxValue)); - OverrideTaskSettings = BooleanOptionItem.Create(22999, "<#ffd>Di<#ffb>sa<#ff9>bl<#ffb>e T<#ffd>as<#ffb>ks", false, TabGroup.ModSettings, false) - .SetColor(new Color32(239, 89, 175, byte.MaxValue)); - DisableMiraTasks = BooleanOptionItem.Create(23000, "Disable Mira HQ Tasks", false, TabGroup.ModSettings, false) + DisableMiraTasks = BooleanOptionItem.Create(23000, Translator.Get("disableMiraTasks"), false, TabGroup.ModSettings, false) .SetColor(new Color32(173, 216, 230, byte.MaxValue)) .SetParent(OverrideTaskSettings); - DisableBuyBeverage = BooleanOptionItem.Create(23001, "Disable Buy Beverage", false, TabGroup.ModSettings, false) + DisableBuyBeverage = BooleanOptionItem.Create(23001, Translator.Get("disableBuyBeverage"), false, TabGroup.ModSettings, false) .SetParent(DisableMiraTasks); - DisableMeasureWeather = BooleanOptionItem.Create(23002, "Disable Measure Weather", false, TabGroup.ModSettings, false) + DisableMeasureWeather = BooleanOptionItem.Create(23002, Translator.Get("disableMeasureWeather"), false, TabGroup.ModSettings, false) .SetParent(DisableMiraTasks); - DisableProcessData = BooleanOptionItem.Create(23003, "Disable Process Data", false, TabGroup.ModSettings, false) + DisableProcessData = BooleanOptionItem.Create(23003, Translator.Get("disableProcessData"), false, TabGroup.ModSettings, false) .SetParent(DisableMiraTasks); - DisableRunDiagnostics = BooleanOptionItem.Create(23004, "Disable Run Diagnostics", false, TabGroup.ModSettings, false) + DisableRunDiagnostics = BooleanOptionItem.Create(23004, Translator.Get("disableRunDiagnostics"), false, TabGroup.ModSettings, false) .SetParent(DisableMiraTasks); - DisableSortSamples = BooleanOptionItem.Create(23005, "Disable Sort Samples", false, TabGroup.ModSettings, false) + DisableSortSamples = BooleanOptionItem.Create(23005, Translator.Get("disableSortSamples"), false, TabGroup.ModSettings, false) .SetParent(DisableMiraTasks); - - - DisablePolusTasks = BooleanOptionItem.Create(23100, "Disable Polus Tasks", false, TabGroup.ModSettings, false) + DisablePolusTasks = BooleanOptionItem.Create(23100, Translator.Get("disablePolusTasks"), false, TabGroup.ModSettings, false) .SetColor(new Color32(173, 216, 230, byte.MaxValue)) .SetParent(OverrideTaskSettings); - DisableActivateWeatherNodes = BooleanOptionItem.Create(23101, "Disable Activate Weather Nodes", false, TabGroup.ModSettings, false) + DisableActivateWeatherNodes = BooleanOptionItem.Create(23101, Translator.Get("disableActivateWeatherNodes"), false, TabGroup.ModSettings, false) .SetParent(DisablePolusTasks); - DisableAlignTelescope = BooleanOptionItem.Create(23102, "Disable Align Telescope", false, TabGroup.ModSettings, false) + DisableAlignTelescope = BooleanOptionItem.Create(23102, Translator.Get("disableAlignTelescope"), false, TabGroup.ModSettings, false) .SetParent(DisablePolusTasks); - DisableFillCanisters = BooleanOptionItem.Create(23103, "Disable Fill Canisters", false, TabGroup.ModSettings, false) + DisableFillCanisters = BooleanOptionItem.Create(23103, Translator.Get("disableFillCanisters"), false, TabGroup.ModSettings, false) .SetParent(DisablePolusTasks); - DisableInsertKeys = BooleanOptionItem.Create(23104, "Disable Insert Keys", false, TabGroup.ModSettings, false) + DisableInsertKeys = BooleanOptionItem.Create(23104, Translator.Get("disableInsertKeys"), false, TabGroup.ModSettings, false) .SetParent(DisablePolusTasks); - DisableOpenWaterways = BooleanOptionItem.Create(23105, "Disable Open Waterways", false, TabGroup.ModSettings, false) + DisableOpenWaterways = BooleanOptionItem.Create(23105, Translator.Get("disableOpenWaterways"), false, TabGroup.ModSettings, false) .SetParent(DisablePolusTasks); - DisableRebootWifi = BooleanOptionItem.Create(23106, "Disable Reboot Wifi", false, TabGroup.ModSettings, false) + DisableRebootWifi = BooleanOptionItem.Create(23106, Translator.Get("disableRebootWifi"), false, TabGroup.ModSettings, false) .SetParent(DisablePolusTasks); - DisableRepairDrill = BooleanOptionItem.Create(23107, "Disable Repair Drill", false, TabGroup.ModSettings, false) + DisableRepairDrill = BooleanOptionItem.Create(23107, Translator.Get("disableRepairDrill"), false, TabGroup.ModSettings, false) .SetParent(DisablePolusTasks); - DisableScanBoardingPass = BooleanOptionItem.Create(23108, "Disable Scan Boarding Pass", false, TabGroup.ModSettings, false) + DisableScanBoardingPass = BooleanOptionItem.Create(23108, Translator.Get("disableScanBoardingPass"), false, TabGroup.ModSettings, false) .SetParent(DisablePolusTasks); - - - DisableAirshipTasks = BooleanOptionItem.Create(23200, "Disable Airship Tasks", false, TabGroup.ModSettings, false) + DisableAirshipTasks = BooleanOptionItem.Create(23200, Translator.Get("disableAirshipTasks"), false, TabGroup.ModSettings, false) .SetColor(new Color32(173, 216, 230, byte.MaxValue)) .SetParent(OverrideTaskSettings); - DisableCleanToilet = BooleanOptionItem.Create(23201, "Disable Clean Toilet", false, TabGroup.ModSettings, false) + DisableCleanToilet = BooleanOptionItem.Create(23201, Translator.Get("disableCleanToilet"), false, TabGroup.ModSettings, false) .SetParent(DisableAirshipTasks); - DisableDecontaminate = BooleanOptionItem.Create(23202, "Disable Decontaminate", false, TabGroup.ModSettings, false) + DisableDecontaminate = BooleanOptionItem.Create(23202, Translator.Get("disableDecontaminate"), false, TabGroup.ModSettings, false) .SetParent(DisableAirshipTasks); - DisableDevelopPhotos = BooleanOptionItem.Create(23203, "Disable Develop Photos", false, TabGroup.ModSettings, false) + DisableDevelopPhotos = BooleanOptionItem.Create(23203, Translator.Get("disableDevelopPhotos"), false, TabGroup.ModSettings, false) .SetParent(DisableAirshipTasks); - DisableDressMannequin = BooleanOptionItem.Create(23204, "Disable Dress Mannequin", false, TabGroup.ModSettings, false) + DisableDressMannequin = BooleanOptionItem.Create(23204, Translator.Get("disableDressMannequin"), false, TabGroup.ModSettings, false) .SetParent(DisableAirshipTasks); - DisableFixShower = BooleanOptionItem.Create(23205, "Disable Fix Shower", false, TabGroup.ModSettings, false) + DisableFixShower = BooleanOptionItem.Create(23205, Translator.Get("disableFixShower"), false, TabGroup.ModSettings, false) .SetParent(DisableAirshipTasks); - DisableMakeBurger = BooleanOptionItem.Create(23206, "Disable Make Burger", false, TabGroup.ModSettings, false) + DisableMakeBurger = BooleanOptionItem.Create(23206, Translator.Get("disableMakeBurger"), false, TabGroup.ModSettings, false) .SetParent(DisableAirshipTasks); - DisablePickUpTowels = BooleanOptionItem.Create(23207, "Disable Pick Up Towels", false, TabGroup.ModSettings, false) + DisablePickUpTowels = BooleanOptionItem.Create(23207, Translator.Get("disablePickUpTowels"), false, TabGroup.ModSettings, false) .SetParent(DisableAirshipTasks); - DisablePolishRuby = BooleanOptionItem.Create(23208, "Disable Polish Ruby", false, TabGroup.ModSettings, false) + DisablePolishRuby = BooleanOptionItem.Create(23208, Translator.Get("disablePolishRuby"), false, TabGroup.ModSettings, false) .SetParent(DisableAirshipTasks); - DisablePutAwayPistols = BooleanOptionItem.Create(23209, "Disable Put Away Pistols", false, TabGroup.ModSettings, false) + DisablePutAwayPistols = BooleanOptionItem.Create(23209, Translator.Get("disablePutAwayPistols"), false, TabGroup.ModSettings, false) .SetParent(DisableAirshipTasks); - DisablePutAwayRifles = BooleanOptionItem.Create(23210, "Disable Put Away Rifles", false, TabGroup.ModSettings, false) + DisablePutAwayRifles = BooleanOptionItem.Create(23210, Translator.Get("disablePutAwayRifles"), false, TabGroup.ModSettings, false) .SetParent(DisableAirshipTasks); - DisableRewindTapes = BooleanOptionItem.Create(23211, "Disable Rewind Tapes", false, TabGroup.ModSettings, false) + DisableRewindTapes = BooleanOptionItem.Create(23211, Translator.Get("disableRewindTapes"), false, TabGroup.ModSettings, false) .SetParent(DisableAirshipTasks); - DisableResetBreaker = BooleanOptionItem.Create(23212, "Disable Reset Breaker Task", false, TabGroup.ModSettings, false) + DisableResetBreaker = BooleanOptionItem.Create(23212, Translator.Get("disableResetBreaker"), false, TabGroup.ModSettings, false) .SetParent(DisableAirshipTasks); - DisableSortRecords = BooleanOptionItem.Create(23213, "Disable Sort Records", false, TabGroup.ModSettings, false) + DisableSortRecords = BooleanOptionItem.Create(23213, Translator.Get("disableSortRecords"), false, TabGroup.ModSettings, false) .SetParent(DisableAirshipTasks); - DisableStartFans = BooleanOptionItem.Create(23214, "Disable Start Fans", false, TabGroup.ModSettings, false) + DisableStartFans = BooleanOptionItem.Create(23214, Translator.Get("disableStartFans"), false, TabGroup.ModSettings, false) .SetParent(DisableAirshipTasks); - DisableUnlockSafe = BooleanOptionItem.Create(23215, "Disable Unlock Safe Task", false, TabGroup.ModSettings, false) + DisableUnlockSafe = BooleanOptionItem.Create(23215, Translator.Get("disableUnlockSafe"), false, TabGroup.ModSettings, false) .SetParent(DisableAirshipTasks); diff --git a/Modules/CustomRoleManagement.cs b/Modules/CustomRoleManagement.cs index 3337792..3b0f3ac 100644 --- a/Modules/CustomRoleManagement.cs +++ b/Modules/CustomRoleManagement.cs @@ -11,6 +11,12 @@ public static class CustomRoleManagement public static Dictionary PlayerRoles = new Dictionary(); private static readonly System.Random random = new System.Random(); + public static string GetRole(byte playerId) + { + PlayerRoles.TryGetValue(playerId, out string role); + return role ?? "None"; + } + public static void AssignRoles() { // crewmateRoles = assigned with crewmate role base @@ -108,7 +114,7 @@ public static class CustomRoleManagement private static int PendingRoleMessages = 0; public static void SendRoleMessages(Dictionary roleMessages) { - if (PlayerRoles.Count == 0) return; + if (PlayerRoles.Count == 0 || PlayerControl.LocalPlayer.Data.IsDead) return; HashSet sentRoles = new HashSet(); diff --git a/Modules/Utils.cs b/Modules/Utils.cs index a94d1f4..3b0b490 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -204,14 +204,22 @@ public static class Utils HandlingGameEnd = false; OnGameJoinedPatch.AutoStartCheck = false; Main.GameTimer = 0f; + NormalGameEndChecker.canUpdateWinnerText = true; MurderPlayerPatch.misfireCount.Clear(); MurderPlayerPatch.killCount.Clear(); + LateTask.Tasks.Clear(); NormalGameEndChecker.ImpCheckComplete = false; CreateOptionsPickerPatch.SetDleks2 = false; CanCallMeetings = true; + CustomRoleManagement.HandlingRoleMessages = false; PlayerControlSetRolePatch.FirstAssign = true; + PlayerControlCompleteTaskPatch.playerTasksCompleted.Clear(); + PlayerControlCompleteTaskPatch.tasksPerPlayer.Clear(); + PlayerControlCompleteTaskPatch.tasksInitiated = false; + PlayerControlCompleteTaskPatch.ignoredCompletedTasks = 0; + PlayerControlCompleteTaskPatch.ignoredTasks = 0; } public static PlayerControl[] AllAlivePlayerControls @@ -465,7 +473,6 @@ public static class Utils AmongUsClient.Instance.FinishEndGame(writer); HandlingGameEnd = false; Logger.Info($"{gameOverReason}", "ContinueEndGame"); - Logger.Info(" -------- GAME ENDED --------", "ContinueEndGame"); } public static void DumpLog() diff --git a/Patches/ChatPatches.cs b/Patches/ChatPatches.cs index 007bba8..d6b0589 100644 --- a/Patches/ChatPatches.cs +++ b/Patches/ChatPatches.cs @@ -328,6 +328,8 @@ public static class RPCHandlerPatch } } + BanManager.IsWordBanned(__instance, text); + bool col1 = text.StartsWith("/col ") || text.StartsWith("/cor "); bool col2 = text.StartsWith("/color "); bool col3 = text.StartsWith("/colour "); @@ -485,6 +487,13 @@ public static class RPCHandlerPatch } } + + if (text == "/r jester"){ + Utils.ModeratorChatCommand(Translator.Get("jesterPublic"), "", false);} + + if (text == "/r mayor"){ + Utils.ModeratorChatCommand(Translator.Get("mayorPublic", Options.MayorExtraVoteCount.GetInt()), "", false);} + break; } } diff --git a/Patches/EndGamePatches.cs b/Patches/EndGamePatches.cs index c0b20b6..0db784b 100644 --- a/Patches/EndGamePatches.cs +++ b/Patches/EndGamePatches.cs @@ -39,36 +39,41 @@ class NormalGameEndChecker ImpCheckComplete = true; } - CheckWinnerText("Default"); + CheckWinnerText(""); return true; } - + public static bool canUpdateWinnerText; + public static string customRoles { get; set; } public static void CheckWinnerText(string Winner) { - var customRoles = CustomRoleManagement.PlayerToCustomRole(); var impostorList = string.Join(", ", imps.Select(p => p.Data.PlayerName)); - + + if (!canUpdateWinnerText) return; + if (Winner == "Jester") { LastWinReason = $"Jester wins! (Voted)\n\nImpostors: {impostorList}" + (string.IsNullOrEmpty(customRoles) ? "" : "\n\n" + customRoles); + canUpdateWinnerText = false; + return; } - if (Winner != "Default") return; - - if (Utils.AliveImpostors == 0) + if (Utils.AliveImpostors == 0 || Winner == "Crewmate") { LastWinReason = $"Crewmates win!\n\nImpostors: {impostorList}" + (string.IsNullOrEmpty(customRoles) ? "" : "\n\n" + customRoles); + canUpdateWinnerText = false; } - else if (Utils.AliveImpostors >= Utils.AliveCrewmates) + else if (Utils.AliveImpostors >= Utils.AliveCrewmates || Winner == "Impostor") { LastWinReason = $"Impostors win!\n\nImpostor: {impostorList}" + (string.IsNullOrEmpty(customRoles) ? "" : "\n\n" + customRoles); + canUpdateWinnerText = false; } - else if (GameData.Instance != null && GameData.Instance.TotalTasks > 0 && GameData.Instance.CompletedTasks >= GameData.Instance.TotalTasks) + else if (GameData.Instance != null && GameData.Instance.TotalTasks > 0 && GameData.Instance.CompletedTasks >= GameData.Instance.TotalTasks || Winner == "CrewmateTasks") { - LastWinReason = $"Crewmates win! (Tasks)\n\nImpostors: {impostorList}" + (string.IsNullOrEmpty(customRoles) ? "" : "\n\n" + customRoles); + LastWinReason = $"Crewmates win! ({Options.TaskPercentNeededToWin.GetInt()}% Tasks)\n\nImpostors: {impostorList}" + (string.IsNullOrEmpty(customRoles) ? "" : "\n\n" + customRoles); + canUpdateWinnerText = false; } - else if (Options.Gamemode.GetValue() < 2) + else if (Options.Gamemode.GetValue() < 2 || Winner == "ImpostorSabotage") { LastWinReason = $"Impostors win! (Sabotage)\n\nImpostors: {impostorList}" + (string.IsNullOrEmpty(customRoles) ? "" : "\n\n" + customRoles); } diff --git a/Patches/ExilePatch.cs b/Patches/ExilePatch.cs index f529d64..1997848 100644 --- a/Patches/ExilePatch.cs +++ b/Patches/ExilePatch.cs @@ -18,7 +18,22 @@ class ExileControllerWrapUpPatch if (p.PlayerId == ejectedPlayer.PlayerId) { pc = p; - break; + } + + if (ejectedPlayer == PlayerControl.LocalPlayer.Data) + { + if (p.Data.Role.IsImpostor) + { + p.cosmetics.nameText.text = $"{p.Data.PlayerName}({MurderPlayerPatch.killCount[p.Data.PlayerId]}†)"; + } + else + { + if (!PlayerControlCompleteTaskPatch.playerTasksCompleted.ContainsKey(p)) + { + PlayerControlCompleteTaskPatch.playerTasksCompleted[p] = 0; + } + p.cosmetics.nameText.text = $"{p.Data.PlayerName}({PlayerControlCompleteTaskPatch.playerTasksCompleted[p]}/{PlayerControlCompleteTaskPatch.tasksPerPlayer[p]})"; + } } } diff --git a/Patches/IntroPatch.cs b/Patches/IntroPatch.cs index 06c9bc9..c9dad4a 100644 --- a/Patches/IntroPatch.cs +++ b/Patches/IntroPatch.cs @@ -15,6 +15,7 @@ internal static class CoShowIntroPatch if (!AmongUsClient.Instance.AmHost) return; + NormalGameEndChecker.customRoles = CustomRoleManagement.PlayerToCustomRole(); CustomRoleManagement.SendRoleMessages(new Dictionary { { "Jester", Translator.Get("jesterPriv")}, @@ -24,6 +25,11 @@ internal static class CoShowIntroPatch foreach (var p in PlayerControl.AllPlayerControls) { p.cosmetics.nameText.text = p.Data.PlayerName; + + MurderPlayerPatch.killCount[p.Data.PlayerId] = 0; + MurderPlayerPatch.misfireCount[p.Data.PlayerId] = 0; + PlayerControlCompleteTaskPatch.playerTasksCompleted[p] = 0; + PlayerControlCompleteTaskPatch.tasksPerPlayer[p] = 0; } if (Options.DisableAnnoyingMeetingCalls.GetBool()) diff --git a/Patches/JoinAndLeavePatches.cs b/Patches/JoinAndLeavePatches.cs index 429c08f..6583451 100644 --- a/Patches/JoinAndLeavePatches.cs +++ b/Patches/JoinAndLeavePatches.cs @@ -99,4 +99,16 @@ class OnPlayerJoinedPatch } } } +} + +[HarmonyPatch(typeof(AmongUsClient), nameof(AmongUsClient.OnPlayerLeft))] +class OnPlayerLeftPatch +{ + static void Postfix([HarmonyArgument(0)] ClientData client) + { + if (!AmongUsClient.Instance.AmHost || !Utils.InGame) return; + { + PlayerControlCompleteTaskPatch.CalculateTaskWin(); + } + } } \ No newline at end of file diff --git a/Patches/PlayerControlPatches.cs b/Patches/PlayerControlPatches.cs index de55b2f..c09d5b6 100644 --- a/Patches/PlayerControlPatches.cs +++ b/Patches/PlayerControlPatches.cs @@ -60,21 +60,13 @@ internal static class MurderPlayerPatch { foreach (var p in PlayerControl.AllPlayerControls) { - int totalTasks = p.Data.Tasks.Count; - int tasksCompleted = 0; - - if (PlayerControlCompleteTaskPatch.playerTasksCompleted.ContainsKey(p)) - { - tasksCompleted = PlayerControlCompleteTaskPatch.playerTasksCompleted[p]; - } - if (p.Data.Role.IsImpostor) { - p.cosmetics.nameText.text = $"{p.Data.PlayerName}({killCount[__instance.Data.PlayerId]}†"; + p.cosmetics.nameText.text = $"{p.Data.PlayerName}({killCount[__instance.Data.PlayerId]}†)"; } else { - p.cosmetics.nameText.text = $"{p.Data.PlayerName}({tasksCompleted}/{totalTasks})"; + p.cosmetics.nameText.text = $"{p.Data.PlayerName}({PlayerControlCompleteTaskPatch.playerTasksCompleted[p]}/{PlayerControlCompleteTaskPatch.tasksPerPlayer[p]})"; } } } @@ -146,26 +138,68 @@ internal static class CheckShapeshiftPatch class PlayerControlCompleteTaskPatch { public static Dictionary playerTasksCompleted = new Dictionary(); + public static Dictionary tasksPerPlayer = new Dictionary(); + public static List ignoredRoles = new List {"Jester"}; + public static int ignoredTasks; + public static int ignoredCompletedTasks; + public static bool tasksInitiated; public static void Postfix(PlayerControl __instance, uint idx) { - int totalTasks = 0; - int tasksCompleted = 0; + if (!AmongUsClient.Instance.AmHost) return; - foreach (var task in __instance.Data.Tasks) + foreach (var p in PlayerControl.AllPlayerControls) { - totalTasks++; - if (task.Complete) tasksCompleted++; + if (ignoredRoles.Contains(CustomRoleManagement.GetRole(p.PlayerId)) && !tasksInitiated) + { + ignoredTasks += p.Data.Tasks.Count; + tasksInitiated = true; + } + + if (!playerTasksCompleted.ContainsKey(p)) + { + playerTasksCompleted[p] = 0; + } + tasksPerPlayer[p] = p.Data.Tasks.Count; } - playerTasksCompleted[__instance] = tasksCompleted; + playerTasksCompleted[__instance]++; + + if (ignoredRoles.Contains(CustomRoleManagement.GetRole(__instance.PlayerId))) + { + ignoredCompletedTasks = playerTasksCompleted[__instance]; + } Logger.Info($" {__instance.Data.PlayerName} completed {idx}", "TaskPatch"); - if (!PlayerControl.LocalPlayer.Data.IsDead) return; + if (Options.Gamemode.GetValue() != 3) CalculateTaskWin(); - TMP_Text nameText = __instance.cosmetics.nameText; - nameText.text = $"{__instance.Data.PlayerName}({tasksCompleted}/{totalTasks})"; + if (PlayerControl.LocalPlayer.Data.IsDead) + { + TMP_Text nameText = __instance.cosmetics.nameText; + nameText.text = $"{__instance.Data.PlayerName}({playerTasksCompleted[__instance]}/{tasksPerPlayer[__instance]})"; + } + } + public static void CalculateTaskWin() + { + Logger.Info($" Checking if {GameData.Instance.CompletedTasks} - {ignoredCompletedTasks} >= ({GameData.Instance.TotalTasks} - {ignoredTasks}) * 0.01 * {Options.TaskPercentNeededToWin.GetInt()}", "TaskPatch"); + if ((GameData.Instance.CompletedTasks - ignoredCompletedTasks) >= (GameData.Instance.TotalTasks - ignoredTasks)*0.01*Options.TaskPercentNeededToWin.GetInt()) + { + Utils.ContinueEndGame((byte)GameOverReason.CrewmatesByVote); + NormalGameEndChecker.CheckWinnerText("CrewmateTasks"); + } + } +} + +[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.CheckSporeTrigger))] +public static class PlayerControlCheckSporeTriggerPatch +{ + public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] Mushroom mushroom) + { + if (!AmongUsClient.Instance.AmHost) return true; + + if (Options.DisableSporeTrigger.GetBool()) return false; + else return true; } } diff --git a/Resources/Language/English.json b/Resources/Language/English.json index a71ac3a..0d42123 100644 --- a/Resources/Language/English.json +++ b/Resources/Language/English.json @@ -85,6 +85,7 @@ "decontaminationDoorOpenTimeOnMiraHQ": "Mira HQ Door Open Duration", "decontaminationTimeOnPolus": "Polus Decon Duration", "decontaminationDoorOpenTimeOnPolus": "Polus Door Open Duration", + "disableSporeTrigger": "Disable Spores On The Fungle", "disableDevices": "Disable Devices", "disableSkeldDevices": "Disable Skeld Devices", @@ -109,6 +110,7 @@ "tabGroupTasks": "Tasks", "allPlayersSameTasks": "Everyone has same tasks", "overrideTaskSettings": "Disable Tasks", + "taskPercentNeededToWin": "% Tasks completed for crewmates to win", "disableMiraTasks": "Disable Mira HQ Tasks", "disableBuyBeverage": "Disable Buy Beverage", @@ -139,10 +141,10 @@ "disablePutAwayPistols": "Disable Put Away Pistols", "disablePutAwayRifles": "Disable Put Away Rifles", "disableRewindTapes": "Disable Rewind Tapes", - "disableResetBreaker": "Disable Reset Breaker Task", + "disableResetBreaker": "Disable Reset Breakers", "disableSortRecords": "Disable Sort Records", "disableStartFans": "Disable Start Fans", - "disableUnlockSafe": "Disable Unlock Safe Task", + "disableUnlockSafe": "Disable Unlock Safe", "disableFungleTasks": "Disable Fungle Tasks", "disableBuildSandcastle": "Disable Build Sandcastle", @@ -216,10 +218,10 @@ "mayorVentToMeeting": "Can Vent To Call Meetings", "Jester": "Jester", - "jesterPublic": "Jester:\n\nThe Jester wins alone by getting voted. Their goal is to act as suspicious as possible.", + "jesterPublic": "Jester:\n\nThe Jester wins alone by getting voted. They must act as suspicious as possible.", "jesterPriv": "Your role is Jester!\nYou are NOT a crewmate!\n\nYou win by getting voted. Act as suspicious as possible.", "jesterCanVent": "Can Vent", "customRoleAnnouncement": "Custom Roles are enabled!\n\nIf you have a Custom Role, it will show in a message below this one.", - "roleDescriptionHelp": "Your Role can be seen at the start of meetings. It is shown by a private text, looking like the host." + "roleDescriptionHelp": "Your Custom Role can be seen at the start of meetings. It is shown by an obvious private text" }