diff --git a/AmongUsRevamped.cs b/AmongUsRevamped.cs index 7e5fccb..0060401 100644 --- a/AmongUsRevamped.cs +++ b/AmongUsRevamped.cs @@ -30,11 +30,11 @@ public partial class Main : BasePlugin public static ConfigEntry Preset5 { get; private set; } public static ConfigEntry GM { get; private set; } - public static ConfigEntry UnlockFps { get; private set; } public static ConfigEntry ShowFps { get; private set; } public static ConfigEntry AutoStart { get; private set; } public static ConfigEntry DarkTheme { get; private set; } public static ConfigEntry LobbyMusic { get; private set; } + public static ConfigEntry DisableInfoWhenDead { get; private set; } public static NormalGameOptionsV10 NormalOptions => GameOptionsManager.Instance != null ? GameOptionsManager.Instance.currentNormalGameOptions : null; public static HideNSeekGameOptionsV10 HideNSeekOptions => GameOptionsManager.Instance != null ? GameOptionsManager.Instance.currentHideNSeekGameOptions : null; @@ -42,7 +42,7 @@ public partial class Main : BasePlugin public static bool HasArgumentException; public static string CredentialsText; - public const string ModVersion = "v1.7.2"; + public const string ModVersion = "v1.7.3"; public static float GameTimer; @@ -85,11 +85,11 @@ public partial class Main : BasePlugin AutoStart = Config.Bind("Client Options", "Auto Start", false); GM = Config.Bind("Client Options", "Game Master", false); - UnlockFps = Config.Bind("Client Options", "Unlock FPS", false); ShowFps = Config.Bind("Client Options", "Show FPS", false); AutoStart = Config.Bind("Client Options", "Auto Start", false); DarkTheme = Config.Bind("Client Options", "Dark Theme", false); LobbyMusic = Config.Bind("Client Options", "Lobby Music", false); + DisableInfoWhenDead = Config.Bind("Client Options", "Disable Task/Kill View", false); Translator.Init(); BanManager.Init(); diff --git a/Modules/CustomOptionsHolder.cs b/Modules/CustomOptionsHolder.cs index b10eefc..93983d9 100644 --- a/Modules/CustomOptionsHolder.cs +++ b/Modules/CustomOptionsHolder.cs @@ -38,12 +38,6 @@ namespace AmongUsRevamped taskOptionsLoad = Task.Run(Load); } - //[HarmonyPatch(typeof(MainMenuManager), nameof(MainMenuManager.Start)), HarmonyPostfix] - //public static void WaitOptionsLoad() - //{ - //taskOptionsLoad.Wait(); - //} - public const int PresetId = 0; private static readonly string[] presets = @@ -62,6 +56,15 @@ namespace AmongUsRevamped "Everyone", "VIP And Above", "Moderator And Above", "Admin", "Only You" }; + public static readonly string[] crewmateAbilities = + { + "Mayor", "Workhorse", "Jester", "Speedrunner", "None" + }; + public static readonly string[] impostorAbilities = + { + "Tyrant", "Stealer", "Juggernaut", "None" + }; + //System public static OptionItem Gamemode; @@ -284,20 +287,54 @@ namespace AmongUsRevamped public static OptionItem TabGroupSpeedrun; public static OptionItem SpeedrunSettingsOverride; public static OptionItem GameAutoEndsAfter; + public static OptionItem EngineerMode; - // Roles -/* + // Abilities public static OptionItem TabGroupCrewmate; - public static OptionItem MayorPerc; - public static OptionItem MayorExtraVoteCount; - public static OptionItem MayorVentToMeeting; - public static OptionItem TabGroupNeutral; - public static OptionItem JesterPerc; - public static OptionItem JesterCanVent; + public static OptionItem OverrideCrewmate; + public static OptionItem CrewmateAbility; + + public static OptionItem OverrideScientist; + public static OptionItem ScientistAbility; + + public static OptionItem OverrideEngineer; + public static OptionItem EngineerAbility; + + public static OptionItem OverrideNoisemaker; + public static OptionItem NoisemakerAbility; + + public static OptionItem OverrideTracker; + public static OptionItem TrackerAbility; + + public static OptionItem OverrideDetective; + public static OptionItem DetectiveAbility; + + public static OptionItem TabGroupCrewmateAbilities; + public static OptionItem ExtraVotesCrewmate; + public static OptionItem ExtraVotesPerTask; + public static OptionItem SpeedrunnerShortTasks; + public static OptionItem SpeedrunnerLongTasks; public static OptionItem TabGroupImpostor; -*/ + + public static OptionItem OverrideImpostor; + public static OptionItem ImpostorAbility; + + public static OptionItem OverrideShapeshifter; + public static OptionItem ShapeshifterAbility; + + public static OptionItem OverridePhantom; + public static OptionItem PhantomAbility; + + public static OptionItem OverrideViper; + public static OptionItem ViperAbility; + + public static OptionItem TabGroupImpostorAbilities; + public static OptionItem ExtraVotesImpostor; + public static OptionItem ExtraVotesPerKill; + public static OptionItem KillsNeededForJuggernaut; + public static bool IsLoaded = false; public static void Load() @@ -338,7 +375,7 @@ namespace AmongUsRevamped AutoSendGameInfo = BooleanOptionItem.Create(60150, Translator.Get("autoSendGameInfo"), true, TabGroup.SystemSettings, false); AutoRejoinLobby = BooleanOptionItem.Create(60210, Translator.Get("autoRejoinLobby"), false, TabGroup.SystemSettings, false); - AutoStartTimer = IntegerOptionItem.Create(64420, Translator.Get("autoStartTimer"), new(1, 600, 1), 5, TabGroup.SystemSettings, false) + AutoStartTimer = IntegerOptionItem.Create(64420, Translator.Get("autoStartTimer"), new(1, 5, 1), 5, TabGroup.SystemSettings, false) .SetValueFormat(OptionFormat.Seconds); WaitAutoStart = IntegerOptionItem.Create(64421, Translator.Get("waitAutoStart"), new(10, 600, 10), 300, TabGroup.SystemSettings, false) .SetValueFormat(OptionFormat.Seconds); @@ -364,37 +401,66 @@ namespace AmongUsRevamped SlashEndMeetingCmd = StringOptionItem.Create(60407, Translator.Get("slashEndMeetingCmd"), accessLevels, 3, TabGroup.SystemSettings, false); SlashStartAndEndGameCmd = StringOptionItem.Create(60408, Translator.Get("slashStartAndEndGameCmd"), accessLevels, 3, TabGroup.SystemSettings, false); - - // Custom role settings -/* - TabGroupCrewmate = TextOptionItem.Create(100000, Translator.Get("tabGroupCrewmate"), TabGroup.CustomRoleSettings) + // Ability settings + TabGroupCrewmate = TextOptionItem.Create(100000, Translator.Get("tabGroupCrewmate"), TabGroup.AbilitySettings) .SetColor(CL.Hex("#8cffff")); - MayorPerc = IntegerOptionItem.Create(100001, Translator.Get("Mayor"), new(0, 100, 5), 0, TabGroup.CustomRoleSettings, false) - .SetValueFormat(OptionFormat.Percent) - .SetColor(CL.Hex("#204d42")); - MayorExtraVoteCount = IntegerOptionItem.Create(100002, Translator.Get("mayorExtraVoteCount"), new(1, 15, 1), 1, TabGroup.CustomRoleSettings, false) - .SetValueFormat(OptionFormat.Level) - .SetParent(MayorPerc); - MayorVentToMeeting = BooleanOptionItem.Create(100003, Translator.Get("mayorVentToMeeting"), true, TabGroup.CustomRoleSettings, false) - .SetParent(MayorPerc); - TabGroupNeutral = TextOptionItem.Create(101000, Translator.Get("tabGroupNeutral"), TabGroup.CustomRoleSettings) - .SetColor(CL.Hex("#FFFF99")); - JesterPerc = IntegerOptionItem.Create(101001, Translator.Get("Jester"), new(0, 100, 5), 0, TabGroup.CustomRoleSettings, false) - .SetValueFormat(OptionFormat.Percent) - .SetColor(CL.Hex("#ec62a5")); - JesterCanVent = BooleanOptionItem.Create(101002, Translator.Get("jesterCanVent"), false, TabGroup.CustomRoleSettings, false) - .SetParent(JesterPerc); + CrewmateAbility = StringOptionItem.Create(100002, Translator.Get("crewmateAbility"), crewmateAbilities, 4, TabGroup.AbilitySettings, false) + .SetColor(CL.Hex("#8cffff")); - TabGroupImpostor = TextOptionItem.Create(102000, Translator.Get("tabGroupImpostor"), TabGroup.CustomRoleSettings) + ScientistAbility = StringOptionItem.Create(100101, Translator.Get("scientistAbility"), crewmateAbilities, 4, TabGroup.AbilitySettings, false) + .SetColor(CL.Hex("#8cffff")); + + EngineerAbility = StringOptionItem.Create(100201, Translator.Get("engineerAbility"), crewmateAbilities, 4, TabGroup.AbilitySettings, false) + .SetColor(CL.Hex("#8cffff")); + + NoisemakerAbility = StringOptionItem.Create(100301, Translator.Get("noisemakerAbility"), crewmateAbilities, 4, TabGroup.AbilitySettings, false) + .SetColor(CL.Hex("#8cffff")); + + TrackerAbility = StringOptionItem.Create(100401, Translator.Get("trackerAbility"), crewmateAbilities, 4, TabGroup.AbilitySettings, false) + .SetColor(CL.Hex("#8cffff")); + + DetectiveAbility = StringOptionItem.Create(100501, Translator.Get("detectiveAbility"), crewmateAbilities, 4, TabGroup.AbilitySettings, false) + .SetColor(CL.Hex("#8cffff")); + + TabGroupCrewmateAbilities = TextOptionItem.Create(101000, Translator.Get("tabGroupCrewmateAbilities"), TabGroup.AbilitySettings) + .SetColor(CL.Hex("#8cffff")); + ExtraVotesCrewmate = IntegerOptionItem.Create(101001, Translator.Get("extraVotesCrewmate"), new(1, 15, 1), 1, TabGroup.AbilitySettings, false) + .SetValueFormat(OptionFormat.Level); + ExtraVotesPerTask = FloatOptionItem.Create(101002, Translator.Get("extraVotesPerTask"), new(0.25f, 3f, 0.25f), 0.5f, TabGroup.AbilitySettings, false) + .SetValueFormat(OptionFormat.Level); + SpeedrunnerShortTasks = IntegerOptionItem.Create(101003, Translator.Get("speedrunnerShortTasks"), new(0, 15, 1), 1, TabGroup.AbilitySettings, false) + .SetValueFormat(OptionFormat.Level); + SpeedrunnerLongTasks = IntegerOptionItem.Create(101004, Translator.Get("speedrunnerLongTasks"), new(0, 15, 1), 1, TabGroup.AbilitySettings, false) + .SetValueFormat(OptionFormat.Level); + + TabGroupImpostor = TextOptionItem.Create(102000, Translator.Get("tabGroupImpostor"), TabGroup.AbilitySettings) .SetColor(CL.Hex("#ff1919")); -*/ + + ImpostorAbility = StringOptionItem.Create(100002, Translator.Get("impostorAbility"), impostorAbilities, 3, TabGroup.AbilitySettings, false) + .SetColor(CL.Hex("#ff1919")); + + ShapeshifterAbility = StringOptionItem.Create(102101, Translator.Get("shapeshifterAbility"), impostorAbilities, 3, TabGroup.AbilitySettings, false) + .SetColor(CL.Hex("#ff1919")); + + PhantomAbility = StringOptionItem.Create(102201, Translator.Get("phantomAbility"), impostorAbilities, 3, TabGroup.AbilitySettings, false) + .SetColor(CL.Hex("#ff1919")); + + + ViperAbility = StringOptionItem.Create(102301, Translator.Get("viperAbility"), impostorAbilities, 3, TabGroup.AbilitySettings, false) + .SetColor(CL.Hex("#ff1919")); + + TabGroupImpostorAbilities = TextOptionItem.Create(103000, Translator.Get("tabGroupImpostorAbilities"), TabGroup.AbilitySettings) + .SetColor(CL.Hex("#ff1919")); + ExtraVotesImpostor = IntegerOptionItem.Create(103001, Translator.Get("extraVotesImpostor"), new(1, 15, 1), 1, TabGroup.AbilitySettings, false) + .SetValueFormat(OptionFormat.Level); + ExtraVotesPerKill = FloatOptionItem.Create(103002, Translator.Get("extraVotesPerKill"), new(0.25f, 3f, 0.25f), 0.5f, TabGroup.AbilitySettings, false) + .SetValueFormat(OptionFormat.Level); + KillsNeededForJuggernaut = IntegerOptionItem.Create(103003, Translator.Get("killsNeededForJuggernaut"), new(3, 15, 1), 7, TabGroup.AbilitySettings, false) + .SetValueFormat(OptionFormat.Level); + // Gamemode Settings -/* - TabGroupStandard = TextOptionItem.Create(69998, Translator.Get("tabGroupStandard"), TabGroup.GamemodeSettings) - .SetColor(Color.white); - ChatBeforeFirstMeeting = BooleanOptionItem.Create(69999, Translator.Get("chatBeforeFirstMeeting"), false, TabGroup.GamemodeSettings, false); -*/ + TabGroupHNS = TextOptionItem.Create(70000, Translator.Get("tabGroupHNS"), TabGroup.GamemodeSettings) .SetColor(Color.green); NumSeekers = IntegerOptionItem.Create(70001, Translator.Get("numSeekers"), new(1, 15, 1), 1, TabGroup.GamemodeSettings, false) @@ -441,6 +507,7 @@ namespace AmongUsRevamped SpeedrunSettingsOverride = BooleanOptionItem.Create(70076, Translator.Get("speedrunSettingsOverride"), true, TabGroup.GamemodeSettings, false); GameAutoEndsAfter = IntegerOptionItem.Create(70077, Translator.Get("gameAutoEndsAfter"), new(0, 600, 10), 300, TabGroup.GamemodeSettings, false) .SetValueFormat(OptionFormat.Seconds); + EngineerMode = BooleanOptionItem.Create(70078, Translator.Get("engineerMode"), false, TabGroup.GamemodeSettings, false); // Gameplay Settings TabGroupSabotages = TextOptionItem.Create(60450, Translator.Get("tabGroupSabotages"), TabGroup.ModSettings) diff --git a/Modules/CustomRoleManagement.cs b/Modules/CustomRoleManagement.cs index 941a30e..00d61dd 100644 --- a/Modules/CustomRoleManagement.cs +++ b/Modules/CustomRoleManagement.cs @@ -6,7 +6,146 @@ using UnityEngine; namespace AmongUsRevamped; // It was a fun ride, but this won't last. +// Edit: WE ARE SO BACK +public static class AbilityManagement +{ + public static bool IsMayor(PlayerControl player) + { + if (player.Data.RoleType == RoleTypes.Crewmate && Options.CrewmateAbility.GetValue() == 0 || + player.Data.RoleType == RoleTypes.Scientist && Options.ScientistAbility.GetValue() == 0 || + player.Data.RoleType == RoleTypes.Engineer && Options.EngineerAbility.GetValue() == 0 || + player.Data.RoleType == RoleTypes.Noisemaker && Options.NoisemakerAbility.GetValue() == 0 || + player.Data.RoleType == RoleTypes.Tracker && Options.TrackerAbility.GetValue() == 0 || + player.Data.RoleType == RoleTypes.Detective && Options.DetectiveAbility.GetValue() == 0) + { + return true; + } + else return false; + } + + public static bool IsWorkhorse(PlayerControl player) + { + if (player.Data.RoleType == RoleTypes.Crewmate && Options.CrewmateAbility.GetValue() == 1 || + player.Data.RoleType == RoleTypes.Scientist && Options.ScientistAbility.GetValue() == 1 || + player.Data.RoleType == RoleTypes.Engineer && Options.EngineerAbility.GetValue() == 1 || + player.Data.RoleType == RoleTypes.Noisemaker && Options.NoisemakerAbility.GetValue() == 1 || + player.Data.RoleType == RoleTypes.Tracker && Options.TrackerAbility.GetValue() == 1 || + player.Data.RoleType == RoleTypes.Detective && Options.DetectiveAbility.GetValue() == 1) + { + return true; + } + else return false; + } + + public static bool IsJester(PlayerControl player) + { + if (player.Data.RoleType == RoleTypes.Crewmate && Options.CrewmateAbility.GetValue() == 2 || + player.Data.RoleType == RoleTypes.Scientist && Options.ScientistAbility.GetValue() == 2 || + player.Data.RoleType == RoleTypes.Engineer && Options.EngineerAbility.GetValue() == 2 || + player.Data.RoleType == RoleTypes.Noisemaker && Options.NoisemakerAbility.GetValue() == 2 || + player.Data.RoleType == RoleTypes.Tracker && Options.TrackerAbility.GetValue() == 2 || + player.Data.RoleType == RoleTypes.Detective && Options.DetectiveAbility.GetValue() == 2) + { + return true; + } + else return false; + } + + public static bool IsSpeedrunner(PlayerControl player) + { + if (player.Data.RoleType == RoleTypes.Crewmate && Options.CrewmateAbility.GetValue() == 3 || + player.Data.RoleType == RoleTypes.Scientist && Options.ScientistAbility.GetValue() == 3 || + player.Data.RoleType == RoleTypes.Engineer && Options.EngineerAbility.GetValue() == 3 || + player.Data.RoleType == RoleTypes.Noisemaker && Options.NoisemakerAbility.GetValue() == 3 || + player.Data.RoleType == RoleTypes.Tracker && Options.TrackerAbility.GetValue() == 3 || + player.Data.RoleType == RoleTypes.Detective && Options.DetectiveAbility.GetValue() == 3) + { + return true; + } + else return false; + } + + public static bool IsTyrant(PlayerControl player) + { + if (player.Data.RoleType == RoleTypes.Impostor && Options.ImpostorAbility.GetValue() == 0 || + player.Data.RoleType == RoleTypes.Shapeshifter && Options.ShapeshifterAbility.GetValue() == 0 || + player.Data.RoleType == RoleTypes.Phantom && Options.PhantomAbility.GetValue() == 0 || + player.Data.RoleType == RoleTypes.Viper && Options.ViperAbility.GetValue() == 0) + { + return true; + } + else return false; + } + + public static bool IsStealer(PlayerControl player) + { + if (player.Data.RoleType == RoleTypes.Impostor && Options.ImpostorAbility.GetValue() == 1 || + player.Data.RoleType == RoleTypes.Shapeshifter && Options.ShapeshifterAbility.GetValue() == 1 || + player.Data.RoleType == RoleTypes.Phantom && Options.PhantomAbility.GetValue() == 1 || + player.Data.RoleType == RoleTypes.Viper && Options.ViperAbility.GetValue() == 1) + { + return true; + } + else return false; + } + + public static bool IsJuggernaut(PlayerControl player) + { + if (player.Data.RoleType == RoleTypes.Impostor && Options.ImpostorAbility.GetValue() == 2 || + player.Data.RoleType == RoleTypes.Shapeshifter && Options.ShapeshifterAbility.GetValue() == 2 || + player.Data.RoleType == RoleTypes.Phantom && Options.PhantomAbility.GetValue() == 2 || + player.Data.RoleType == RoleTypes.Viper && Options.ViperAbility.GetValue() == 2) + { + return true; + } + else return false; + } + + public static string RoleList() + { + var firstLines = new List(); + + if (Options.CrewmateAbility.GetValue() != 4) firstLines.Add($"Crewmate: {Options.CrewmateAbility.GetString()}"); + if (Options.ScientistAbility.GetValue() != 4) firstLines.Add($"Scientist: {Options.ScientistAbility.GetString()}"); + if (Options.EngineerAbility.GetValue() != 4) firstLines.Add($"Engineer: {Options.EngineerAbility.GetString()}"); + if (Options.NoisemakerAbility.GetValue() != 4) firstLines.Add($"Noisemaker: {Options.NoisemakerAbility.GetString()}"); + if (Options.TrackerAbility.GetValue() != 4) firstLines.Add($"Tracker: {Options.TrackerAbility.GetString()}"); + + var secondLines = new List(); + + if (Options.DetectiveAbility.GetValue() != 4) secondLines.Add($"Detective: {Options.DetectiveAbility.GetString()}"); + if (Options.ImpostorAbility.GetValue() != 3) secondLines.Add($"Impostor: {Options.ImpostorAbility.GetString()}"); + if (Options.ShapeshifterAbility.GetValue() != 3) secondLines.Add($"Shapeshifter: {Options.ShapeshifterAbility.GetString()}"); + if (Options.PhantomAbility.GetValue() != 3) secondLines.Add($"Phantom: {Options.PhantomAbility.GetString()}"); + if (Options.ViperAbility.GetValue() != 3) secondLines.Add($"Viper: {Options.ViperAbility.GetString()}"); + + string firstText = firstLines.Count > 0 ? "ABILITIES:\n\n" + string.Join("\n", firstLines) : ""; + string secondText = secondLines.Count > 0 ? "\n" + string.Join("\n", secondLines) : ""; + + return firstText + secondText; + } + + public static void SendRoleList(ChatController c, string text, bool moderator) + { + if (text.Length <= 120) + { + if (moderator) Utils.ModeratorChatCommand(text, "", false); + else Utils.ChatCommand(c, text, "", false); + return; + } + + int splitIndex = text.LastIndexOf('\n', 120); + + if (splitIndex <= 0) splitIndex = 120; + + string first = text[..splitIndex]; + string second = text[(splitIndex + 1)..]; + + if (moderator) Utils.ModeratorChatCommand(first, second, true); + else Utils.ChatCommand(c, first, second, true); + } +} /* public static class CustomRoleManagement { diff --git a/Modules/OptionItem/OptionItem.cs b/Modules/OptionItem/OptionItem.cs index fdf5172..7294cd4 100644 --- a/Modules/OptionItem/OptionItem.cs +++ b/Modules/OptionItem/OptionItem.cs @@ -215,6 +215,7 @@ namespace AmongUsRevamped { SystemSettings, //CustomRoleSettings, + AbilitySettings, ModSettings, GamemodeSettings, diff --git a/Modules/Utils.cs b/Modules/Utils.cs index b1e2515..6ce07c4 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -77,6 +77,8 @@ public static class Utils case TabGroup.CustomRoleSettings: return "Custom Roles"; */ + case TabGroup.AbilitySettings: + return "Ability Settings"; case TabGroup.ModSettings: return "Gameplay Settings"; case TabGroup.GamemodeSettings: @@ -212,16 +214,18 @@ public static class Utils LateTask.Tasks.Clear(); NormalGameEndChecker.ImpCheckComplete = false; - //CreateOptionsPickerPatch.SetDleks2 = false; + CreateOptionsPickerPatch.SetDleks2 = false; CanCallMeetings = true; //CustomRoleManagement.HandlingRoleMessages = false; PlayerControlSetRolePatch.FirstAssign = true; + PlayerControlSetRolePatch.Jesters.Clear(); PlayerControlCompleteTaskPatch.playerTasksCompleted.Clear(); PlayerControlCompleteTaskPatch.tasksPerPlayer.Clear(); PlayerControlCompleteTaskPatch.tasksInitiated = false; PlayerControlCompleteTaskPatch.ignoredCompletedTasks = 0; PlayerControlCompleteTaskPatch.ignoredTasks = 0; + } public static PlayerControl[] AllAlivePlayerControls diff --git a/Patches/ChatPatches.cs b/Patches/ChatPatches.cs index fbb0dcc..f4e42c9 100644 --- a/Patches/ChatPatches.cs +++ b/Patches/ChatPatches.cs @@ -150,16 +150,35 @@ internal static class SendChatPatch if (string.IsNullOrEmpty(NormalGameEndChecker.LastWinReason) || Utils.InGame) return false; Utils.ChatCommand(__instance, $"{NormalGameEndChecker.LastWinReason}", "", false); return false; - } -/* + } if (text == "/r jester"){ Utils.ChatCommand(__instance, Translator.Get("jesterPublic"), "", false); return false;} if (text == "/r mayor"){ - Utils.ChatCommand(__instance, Translator.Get("mayorPublic", Options.MayorExtraVoteCount.GetInt()), "", false); + Utils.ChatCommand(__instance, Translator.Get("mayorPublic", Options.ExtraVotesCrewmate.GetInt()), "", false); return false;} -*/ + + if (text == "/r tyrant"){ + Utils.ChatCommand(__instance, Translator.Get("tyrantPublic", Options.ExtraVotesImpostor.GetInt()), "", false); + return false;} + + if (text == "/r workhorse"){ + Utils.ChatCommand(__instance, Translator.Get("workhorsePublic", Options.ExtraVotesPerTask.GetFloat()), "", false); + return false;} + + if (text == "/r stealer"){ + Utils.ChatCommand(__instance, Translator.Get("stealerPublic", Options.ExtraVotesPerKill.GetFloat()), "", false); + return false;} + + if (text == "/r juggernaut"){ + Utils.ChatCommand(__instance, Translator.Get("juggernautPublic", Options.KillsNeededForJuggernaut.GetInt()), "", false); + return false;} + + if (text == "/r speedrunner"){ + Utils.ChatCommand(__instance, Translator.Get("speedrunnerPublic"), "", false); + return false;} + if (text == "/aur" || text == "/amongusrevamped" || text == "/socials") { Utils.ChatCommand(__instance, Translator.Get("socialsAll"), "", false); @@ -189,7 +208,7 @@ internal static class SendChatPatch switch (Options.Gamemode.GetValue()) { case 0: - //Utils.ChatCommand(__instance, $"Enabled Custom Roles:\n\n{CustomRoleManagement.GetActiveRoles()}", "", false); + AbilityManagement.SendRoleList(__instance, AbilityManagement.RoleList(), false); break; case 1: @@ -400,7 +419,7 @@ public static class RPCHandlerPatch } } - if (/*CustomRoleManagement.HandlingRoleMessages || */OnGameJoinedPatch.WaitingForChat) return; + if (/*CustomRoleManagement.HandlingRoleMessages || */OnGameJoinedPatch.WaitingForChat || GameStartManagerUpdatePatch.CountingDown) return; if (text == "/h" || text == "/help") { @@ -476,7 +495,7 @@ public static class RPCHandlerPatch switch (Options.Gamemode.GetValue()) { case 0: - //Utils.ModeratorChatCommand($"Enabled Custom Roles:\n\n{CustomRoleManagement.GetActiveRoles()}", "", false); + AbilityManagement.SendRoleList(DestroyableSingleton.Instance.Chat, AbilityManagement.RoleList(), true); break; case 1: @@ -493,13 +512,28 @@ 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);} -*/ + Utils.ModeratorChatCommand(Translator.Get("mayorPublic", Options.ExtraVotesCrewmate.GetInt()), "", false);} + + if (text == "/r tyrant"){ + Utils.ModeratorChatCommand(Translator.Get("tyrantPublic", Options.ExtraVotesImpostor.GetInt()), "", false);} + + if (text == "/r workhorse"){ + Utils.ModeratorChatCommand(Translator.Get("workhorsePublic", Options.ExtraVotesPerTask.GetFloat()), "", false);} + + if (text == "/r stealer"){ + Utils.ModeratorChatCommand(Translator.Get("stealerPublic", Options.ExtraVotesPerKill.GetFloat()), "", false);} + + if (text == "/r juggernaut"){ + Utils.ModeratorChatCommand(Translator.Get("juggernautPublic", Options.KillsNeededForJuggernaut.GetInt()), "", false);} + + if (text == "/r speedrunner"){ + Utils.ModeratorChatCommand(Translator.Get("speedrunnerPublic"), "", false);} + break; } } diff --git a/Patches/ClientOptionsPatch.cs b/Patches/ClientOptionsPatch.cs index 2e81f82..7bb5704 100644 --- a/Patches/ClientOptionsPatch.cs +++ b/Patches/ClientOptionsPatch.cs @@ -10,11 +10,11 @@ namespace AmongUsRevamped public static class OptionsMenuBehaviourStartPatch { private static ClientOptionItem GM; - private static ClientOptionItem UnlockFPS; private static ClientOptionItem ShowFPS; private static ClientOptionItem AutoStart; private static ClientOptionItem DarkTheme; private static ClientOptionItem LobbyMusic; + private static ClientOptionItem DisableInfoWhenDead; public static void Postfix(OptionsMenuBehaviour __instance) { @@ -31,20 +31,12 @@ namespace AmongUsRevamped } } - if (UnlockFPS == null || UnlockFPS.ToggleButton == null) - { - UnlockFPS = ClientOptionItem.Create(Translator.Get("unlockFPS"), Main.UnlockFps, __instance, UnlockFPSButtonToggle); - - static void UnlockFPSButtonToggle() - { - Application.targetFrameRate = Main.UnlockFps.Value ? 120 : 60; - Logger.SendInGame($"FPS Set To {Application.targetFrameRate}"); - } - } - if (ShowFPS == null || ShowFPS.ToggleButton == null) ShowFPS = ClientOptionItem.Create(Translator.Get("showFPS"), Main.ShowFps, __instance); + if (DisableInfoWhenDead == null || DisableInfoWhenDead.ToggleButton == null) + DisableInfoWhenDead = ClientOptionItem.Create(Translator.Get("disableInfoWhenDead"), Main.DisableInfoWhenDead, __instance); + if (AutoStart == null || AutoStart.ToggleButton == null) { AutoStart = ClientOptionItem.Create(Translator.Get("autoStart"), Main.AutoStart, __instance, AutoStartButtonToggle); diff --git a/Patches/DleksPatch.cs b/Patches/DleksPatch.cs index 6eb77c6..953c8f6 100644 --- a/Patches/DleksPatch.cs +++ b/Patches/DleksPatch.cs @@ -1,31 +1,31 @@ using System; using UnityEngine; +using UnityEngine.AddressableAssets; using UnityEngine.SceneManagement; namespace AmongUsRevamped; -// DateTime spoofing is patched as of April 2026 - -/* -[HarmonyPatch(typeof(AmongUsDateTime), nameof(AmongUsDateTime.UtcNow), MethodType.Getter)] -public static class AmongUsDateTime_UtcNow -{ - public static bool Prefix(ref Il2CppSystem.DateTime __result) - { - if (!CreateOptionsPickerPatch.SetDleks) return true; - - var managedDate = new DateTime(DateTime.UtcNow.Year, 4, 2, 7, 1, 0, DateTimeKind.Utc); - __result = new Il2CppSystem.DateTime(managedDate.Ticks); - - return false; - } -} - class CreateOptionsPickerPatch { public static bool SetDleks = false; public static bool SetDleks2; private static bool InitiatedDleks; + private static bool isSkeldFlipped = false; + public static bool FlippedSkeld + { + get => isSkeldFlipped; + set + { + if (AmongUsClient.Instance == null || isSkeldFlipped == value) return; + + AssetReference temp = AmongUsClient.Instance.ShipPrefabs[3]; + AmongUsClient.Instance.ShipPrefabs[3] = AmongUsClient.Instance.ShipPrefabs[0]; + AmongUsClient.Instance.ShipPrefabs[0] = temp; + + isSkeldFlipped = value; + } + } + private static MapSelectButton DleksButton; [HarmonyPatch] public static class GameOptionsMapPickerPatch @@ -83,6 +83,8 @@ class CreateOptionsPickerPatch dlekS_ehT_MapButton.Button.OnClick.RemoveAllListeners(); dlekS_ehT_MapButton.Button.OnClick.AddListener((UnityEngine.Events.UnityAction)(() => { + FlippedSkeld = true; + __instance.SelectMap(__instance.AllMapIcons[0]); if (__instance.selectedButton) @@ -139,6 +141,8 @@ class CreateOptionsPickerPatch if (__instance.MapName == null) return false; + FlippedSkeld = (__instance.selectedMapId == 3); + if (DleksButton != null) SetDleks = __instance.selectedMapId == 3; if (__instance.selectedMapId == 3) @@ -230,5 +234,4 @@ class CreateOptionsPickerPatch transform2.position = position2; } } -} -*/ \ No newline at end of file +} \ No newline at end of file diff --git a/Patches/EndGamePatches.cs b/Patches/EndGamePatches.cs index 0db784b..5af8a00 100644 --- a/Patches/EndGamePatches.cs +++ b/Patches/EndGamePatches.cs @@ -53,24 +53,38 @@ class NormalGameEndChecker if (Winner == "Jester") { - LastWinReason = $"Jester wins! (Voted)\n\nImpostors: {impostorList}" + (string.IsNullOrEmpty(customRoles) ? "" : "\n\n" + customRoles); + LastWinReason = $"Jester wins! (Voted)\n\nImpostors: {impostorList}"; + canUpdateWinnerText = false; + return; + } + + if (Winner == "Juggernaut") + { + LastWinReason = $"Impostors win! (Juggernaut killed {Options.KillsNeededForJuggernaut.GetInt()} players)\n\nImpostor: {impostorList}"; + canUpdateWinnerText = false; + return; + } + + if (Winner == "Speedrunner") + { + LastWinReason = $"Crewmates win! (Speedrunner finished tasks)\n\nImpostor: {impostorList}"; canUpdateWinnerText = false; return; } if (Utils.AliveImpostors == 0 || Winner == "Crewmate") { - LastWinReason = $"Crewmates win!\n\nImpostors: {impostorList}" + (string.IsNullOrEmpty(customRoles) ? "" : "\n\n" + customRoles); + LastWinReason = $"Crewmates win!\n\nImpostors: {impostorList}"; canUpdateWinnerText = false; } else if (Utils.AliveImpostors >= Utils.AliveCrewmates || Winner == "Impostor") { - LastWinReason = $"Impostors win!\n\nImpostor: {impostorList}" + (string.IsNullOrEmpty(customRoles) ? "" : "\n\n" + customRoles); + LastWinReason = $"Impostors win!\n\nImpostor: {impostorList}"; canUpdateWinnerText = false; } else if (GameData.Instance != null && GameData.Instance.TotalTasks > 0 && GameData.Instance.CompletedTasks >= GameData.Instance.TotalTasks || Winner == "CrewmateTasks") { - LastWinReason = $"Crewmates win! ({Options.TaskPercentNeededToWin.GetInt()}% Tasks)\n\nImpostors: {impostorList}" + (string.IsNullOrEmpty(customRoles) ? "" : "\n\n" + customRoles); + LastWinReason = $"Crewmates win! ({Options.TaskPercentNeededToWin.GetInt()}% Tasks)\n\nImpostors: {impostorList}"; canUpdateWinnerText = false; } else if (Options.Gamemode.GetValue() < 2 || Winner == "ImpostorSabotage") diff --git a/Patches/ExilePatch.cs b/Patches/ExilePatch.cs index d441021..c6289cb 100644 --- a/Patches/ExilePatch.cs +++ b/Patches/ExilePatch.cs @@ -17,6 +17,7 @@ class ExileControllerWrapUpPatch if (ejectedPlayer == null) return; PlayerControl pc = null; + PlayerControl exiledPlayer = ejectedPlayer.Object; foreach (var p in PlayerControl.AllPlayerControls) { if (p.PlayerId == ejectedPlayer.PlayerId) @@ -42,27 +43,15 @@ class ExileControllerWrapUpPatch } Logger.Info($" {ejectedPlayer.PlayerName} was ejected", "ExileController"); -/* - if (CustomRoleManagement.PlayerRoles.TryGetValue(ejectedPlayer.PlayerId, out var role) && role == "Jester") + + if (PlayerControlSetRolePatch.Jesters.Contains(exiledPlayer)) { - Utils.CustomWinnerEndGame(pc, 1); + Logger.Info($"Jester {ejectedPlayer.PlayerName} wins", "ExilePatch"); + Utils.CustomWinnerEndGame(exiledPlayer, 1); NormalGameEndChecker.CheckWinnerText("Jester"); return; } - if (CustomRoleManagement.HandlingRoleMessages) - { - Logger.Info(" SRM2 is called before SRM1 finished. This should not happen.", "ExileController"); - } - else - { - CustomRoleManagement.SendRoleMessages(new Dictionary - { - { "Jester", Translator.Get("jesterPriv")}, - { "Mayor", Translator.Get("mayorPriv", Options.MayorExtraVoteCount.GetInt())}, - }); - } -*/ } } diff --git a/Patches/GameSettingMenuPatch.cs b/Patches/GameSettingMenuPatch.cs index 03c2f9f..538b6d0 100644 --- a/Patches/GameSettingMenuPatch.cs +++ b/Patches/GameSettingMenuPatch.cs @@ -120,8 +120,11 @@ namespace AmongUsRevamped __instance.MenuDescriptionText.text = "Custom Role enabling and settings."; break; */ + case TabGroup.AbilitySettings: + __instance.MenuDescriptionText.text = "Ability settings to enhance vanilla roles."; + break; case TabGroup.ModSettings: - __instance.MenuDescriptionText.text = "Gameplay Settings to improve the in-game experience."; + __instance.MenuDescriptionText.text = "Gameplay settings to improve the in-game experience."; break; case TabGroup.GamemodeSettings: __instance.MenuDescriptionText.text = "Situational settings to apply for specific gamemodes."; diff --git a/Patches/GameStartManagerPatch.cs b/Patches/GameStartManagerPatch.cs index 23dacac..f413ec8 100644 --- a/Patches/GameStartManagerPatch.cs +++ b/Patches/GameStartManagerPatch.cs @@ -9,6 +9,7 @@ public static class GameStartManagerUpdatePatch { public static bool CustomTimerApplied; public static bool Autostarting; + public static bool CountingDown; public static void Prefix(GameStartManager __instance) { @@ -27,11 +28,16 @@ public static class GameStartManagerUpdatePatch Autostarting = true; } - if (__instance.startState == GameStartManager.StartingStates.Countdown && !CustomTimerApplied && !Autostarting) + if (__instance.startState == GameStartManager.StartingStates.Countdown) { - __instance.countDownTimer = Options.StartCountdown.GetInt(); - CustomTimerApplied = true; + CountingDown = true; + if (!CustomTimerApplied && !Autostarting) + { + __instance.countDownTimer = Options.StartCountdown.GetInt(); + CustomTimerApplied = true; + } } + else CountingDown = false; if (__instance.startState != GameStartManager.StartingStates.Countdown) { diff --git a/Patches/IntroPatch.cs b/Patches/IntroPatch.cs index 53fcd12..1776b87 100644 --- a/Patches/IntroPatch.cs +++ b/Patches/IntroPatch.cs @@ -14,21 +14,9 @@ internal static class CoShowIntroPatch Logger.Info(" Intro initiated", "CoShowIntro"); if (!AmongUsClient.Instance.AmHost) return; -/* - NormalGameEndChecker.customRoles = CustomRoleManagement.PlayerToCustomRole(); - if (CustomRoleManagement.PlayerRoles.Count != 0 && !Utils.isHideNSeek && Options.Gamemode.GetValue() < 2) - { - _ = new LateTask(() => - { - CustomRoleManagement.SendRoleMessages(new Dictionary - { - { "Jester", Translator.Get("jesterPriv")}, - { "Mayor", Translator.Get("mayorPriv", Options.MayorExtraVoteCount.GetInt())}, - }); - }, 1f, "BlockACKick"); - } -*/ + Utils.ModeratorChatCommand(Translator.Get("abilitiesGenericOne", Options.CrewmateAbility.GetString(), Options.ScientistAbility.GetString(), Options.EngineerAbility.GetString(), Options.NoisemakerAbility.GetString(), Options.TrackerAbility.GetString()), Translator.Get("abilitiesGenericTwo", Options.DetectiveAbility.GetString(), Options.ImpostorAbility.GetString(), Options.ShapeshifterAbility.GetString(), Options.PhantomAbility.GetString(), Options.ViperAbility.GetString()), true); + foreach (var p in PlayerControl.AllPlayerControls) { p.cosmetics.nameText.text = p.Data.PlayerName; diff --git a/Patches/MeetingPatches.cs b/Patches/MeetingPatches.cs index 49aca2a..7d67926 100644 --- a/Patches/MeetingPatches.cs +++ b/Patches/MeetingPatches.cs @@ -2,8 +2,6 @@ namespace AmongUsRevamped; -//Old Patch for Mayor -/* [HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.CheckForEndVoting))] public static class CheckForEndVotingPatch { @@ -22,18 +20,33 @@ public static class CheckForEndVotingPatch byte voterId = ps.TargetPlayerId; byte votedFor = ps.VotedFor; + PlayerControl pc = GameData.Instance.GetPlayerById(voterId)?.Object; + if (pc == null) continue; if (votedFor == byte.MaxValue) continue; + if (!votes.ContainsKey(votedFor)) votes[votedFor] = 0; visualVotes.Add(new MeetingHud.VoterState { VoterId = voterId, VotedForId = votedFor }); - if (CustomRoleManagement.PlayerRoles.TryGetValue(voterId, out string role) && role == "Mayor") - { - int extraVotes = Options.MayorExtraVoteCount.GetInt(); - if (!votes.TryGetValue(votedFor, out int currentVotes)) currentVotes = 0; - votes[votedFor] = currentVotes + extraVotes; + if (!PlayerControlCompleteTaskPatch.playerTasksCompleted.ContainsKey(pc)) PlayerControlCompleteTaskPatch.playerTasksCompleted[pc] = 0; + if (!MurderPlayerPatch.killCount.ContainsKey(voterId)) MurderPlayerPatch.killCount[voterId] = 0; - for (int i = 0; i < extraVotes; i++) - visualVotes.Add(new MeetingHud.VoterState { VoterId = voterId, VotedForId = votedFor }); + int extraVotes = 0; + int extraVotesCrewmate = Options.ExtraVotesCrewmate.GetInt(); + int extraVotesImpostor = Options.ExtraVotesImpostor.GetInt(); + int extraVotesPerTask = (int)(Options.ExtraVotesPerTask.GetFloat()*PlayerControlCompleteTaskPatch.playerTasksCompleted[pc]+0.1f); + int extraVotesPerKill = (int)(Options.ExtraVotesPerKill.GetFloat()*MurderPlayerPatch.killCount[voterId]+0.1f); + + if (!votes.TryGetValue(votedFor, out int currentVotes)) currentVotes = 0; + + if (AbilityManagement.IsMayor(pc)) extraVotes += extraVotesCrewmate; + if (AbilityManagement.IsTyrant(pc)) extraVotes += extraVotesImpostor; + if (AbilityManagement.IsWorkhorse(pc)) extraVotes += extraVotesPerTask; + if (AbilityManagement.IsStealer(pc)) extraVotes += extraVotesPerKill; + + for (int i = 0; i < extraVotes; i++) + { + visualVotes.Add(new MeetingHud.VoterState { VoterId = voterId, VotedForId = votedFor }); + votes[votedFor]++; } } @@ -46,7 +59,6 @@ public static class CheckForEndVotingPatch return false; } } -*/ [HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.Start))] class MeetingHudStartPatch @@ -67,7 +79,7 @@ class MeetingHudStartPatch } } - if (player == null || !PlayerControl.LocalPlayer.Data.IsDead) continue; + if (player == null || !PlayerControl.LocalPlayer.Data.IsDead || Main.DisableInfoWhenDead.Value) continue; var textTemplate = playerState.NameText; var taskText = GetProgressText(player); diff --git a/Patches/OnGameStartedPatch.cs b/Patches/OnGameStartedPatch.cs index 116cffd..5568bdb 100644 --- a/Patches/OnGameStartedPatch.cs +++ b/Patches/OnGameStartedPatch.cs @@ -15,12 +15,7 @@ internal class CoStartGamePatch Logger.Info(" -------- GAME STARTED --------", "StartGame"); Logger.Info($" Gamemode: {Options.Gamemode.GetValue()}", "StartGame"); Logger.Info($" Players: {PlayerControl.AllPlayerControls.Count}", "StartGame"); -/* - if ((Options.Gamemode.GetValue() == 0 || Options.Gamemode.GetValue() == 1) && !Utils.isHideNSeek) - { - CustomRoleManagement.AssignRoles(); - } -*/ + NormalGameEndChecker.imps.Clear(); NormalGameEndChecker.LastWinReason = ""; @@ -33,6 +28,7 @@ class PlayerControlSetRolePatch private static int i; public static bool FirstAssign; private static HashSet Seekers = new(); + public static HashSet Jesters = new(); private static readonly System.Random rand = new System.Random(); public static bool Prefix(PlayerControl __instance, ref RoleTypes roleType, ref bool canOverrideRole) @@ -48,34 +44,7 @@ class PlayerControlSetRolePatch roleType = RoleTypes.CrewmateGhost; return true; } -/* - if (CustomRoleManagement.PlayerRoles.TryGetValue(__instance.PlayerId, out var role) && role == "Mayor" && Options.Gamemode.GetValue() < 2) - { - if (Options.MayorVentToMeeting.GetBool()) - { - roleType = RoleTypes.Engineer; - Logger.Info($"{__instance.Data.PlayerName} is Engineer due to being Mayor", "SetRolePatch"); - } - else - { - roleType = RoleTypes.Crewmate; - } - Logger.Info($" {__instance.Data.PlayerName} | {oldRole} -> {roleType}", "ChangedRoleBase"); - } - if (CustomRoleManagement.PlayerRoles.TryGetValue(__instance.PlayerId, out var r) && r == "Jester" && Options.Gamemode.GetValue() < 2) - { - if (Options.JesterCanVent.GetBool()) - { - roleType = RoleTypes.Engineer; - Logger.Info($"{__instance.Data.PlayerName} is Engineer due to being Jester", "SetRolePatch"); - } - else - { - roleType = RoleTypes.Crewmate; - } - Logger.Info($" {__instance.Data.PlayerName} | {oldRole} -> {roleType}", "ChangedRoleBase"); - } -*/ + if (Utils.isHideNSeek && i == 0) { int seekersCount = Options.NumSeekers.GetInt(); @@ -113,7 +82,9 @@ class PlayerControlSetRolePatch PlayerControl.LocalPlayer.myTasks.Clear(); return true; } - roleType = RoleTypes.Crewmate; + + if (Options.EngineerMode.GetBool()) roleType = RoleTypes.Engineer; + else roleType = RoleTypes.Crewmate; } i++; @@ -124,6 +95,16 @@ class PlayerControlSetRolePatch i = 0; Logger.Info("PCSRP successful", "RoleManaging"); } + + if (roleType == RoleTypes.Crewmate && Options.CrewmateAbility.GetValue() == 2 || + roleType == RoleTypes.Scientist && Options.ScientistAbility.GetValue() == 2 || + roleType == RoleTypes.Engineer && Options.EngineerAbility.GetValue() == 2 || + roleType == RoleTypes.Noisemaker && Options.NoisemakerAbility.GetValue() == 2 || + roleType == RoleTypes.Tracker && Options.TrackerAbility.GetValue() == 2 || + roleType == RoleTypes.Detective && Options.DetectiveAbility.GetValue() == 2) + { + Jesters.Add(__instance); + } return true; } diff --git a/Patches/PlayerControlPatches.cs b/Patches/PlayerControlPatches.cs index af30859..b94df3e 100644 --- a/Patches/PlayerControlPatches.cs +++ b/Patches/PlayerControlPatches.cs @@ -57,7 +57,7 @@ internal static class MurderPlayerPatch killCount[playerId]++; Logger.Info($" {__instance.Data.PlayerName} killed {target.Data.PlayerName}", "MurderPlayer"); - if (target == PlayerControl.LocalPlayer || PlayerControl.LocalPlayer.Data.IsDead) + if ((target == PlayerControl.LocalPlayer || PlayerControl.LocalPlayer.Data.IsDead) && !Main.DisableInfoWhenDead.Value) { foreach (var p in PlayerControl.AllPlayerControls) { @@ -73,6 +73,13 @@ internal static class MurderPlayerPatch } } + if (Options.Gamemode.GetValue() < 2 && AbilityManagement.IsJuggernaut(__instance) && killCount[__instance.PlayerId] >= Options.KillsNeededForJuggernaut.GetInt()) + { + Logger.Info("Juggernaut win", "MurderPlayer"); + Utils.ContinueEndGame((byte)GameOverReason.ImpostorsByVote); + NormalGameEndChecker.CheckWinnerText("Juggernaut"); + } + //2 = Shift and Seek if (Options.Gamemode.GetValue() == 2 && !Utils.isHideNSeek) { @@ -174,6 +181,16 @@ class PlayerControlCompleteTaskPatch */ Logger.Info($" {__instance.Data.PlayerName} completed {idx}", "TaskPatch"); + if (Options.Gamemode.GetValue() < 2) + { + if (AbilityManagement.IsSpeedrunner(__instance) && !__instance.Data.IsDead && playerTasksCompleted[__instance] >= __instance.Data.Tasks.Count) + { + Logger.Info($"Speedrunner {__instance.Data.PlayerName} won", "TaskPatch"); + Utils.ContinueEndGame((byte)GameOverReason.CrewmatesByVote); + NormalGameEndChecker.CheckWinnerText("Speedrunner"); + } + } + if (Options.Gamemode.GetValue() != 3) CalculateTaskWin(); if (Options.Gamemode.GetValue() == 3) @@ -186,7 +203,7 @@ class PlayerControlCompleteTaskPatch } } - if (PlayerControl.LocalPlayer.Data.IsDead) + if (PlayerControl.LocalPlayer.Data.IsDead && !Main.DisableInfoWhenDead.Value) { TMP_Text nameText = __instance.cosmetics.nameText; nameText.text = $"{__instance.Data.PlayerName}({playerTasksCompleted[__instance]}/{tasksPerPlayer[__instance]})"; diff --git a/Patches/TaskAssignPatch.cs b/Patches/TaskAssignPatch.cs index 767d6d8..2fd60e0 100644 --- a/Patches/TaskAssignPatch.cs +++ b/Patches/TaskAssignPatch.cs @@ -136,7 +136,7 @@ internal static class RpcSetTasksPatch if (!Options.AllPlayersSameTasks.GetBool()) { - RerollTasks(ref taskTypeIds); + RerollTasks(pc, ref taskTypeIds); return; } @@ -155,23 +155,26 @@ internal static class RpcSetTasksPatch } - - private static void RerollTasks(ref Il2CppStructArray taskTypeIds) + private static void RerollTasks(PlayerControl pc, ref Il2CppStructArray taskTypeIds) { // Default number of tasks bool hasCommonTasks = true; + int numCommonTasks = Main.NormalOptions.NumCommonTasks; int numLongTasks = Main.NormalOptions.NumLongTasks; int numShortTasks = Main.NormalOptions.NumShortTasks; + if (AbilityManagement.IsSpeedrunner(pc)) + { + numLongTasks = Options.SpeedrunnerLongTasks.GetInt(); + numShortTasks = Options.SpeedrunnerShortTasks.GetInt(); + } + if (taskTypeIds.Length == 0) hasCommonTasks = false; switch (hasCommonTasks) { - case false when numLongTasks == 0 && numShortTasks == 0: - numShortTasks = 1; - break; - case true when numLongTasks == Main.NormalOptions.NumLongTasks && numShortTasks == Main.NormalOptions.NumShortTasks: - return; + case false when numLongTasks == 0 && numShortTasks == 0: numShortTasks = 1; break; + case true when numLongTasks == Main.NormalOptions.NumLongTasks && numShortTasks == Main.NormalOptions.NumShortTasks: return; } Il2CppSystem.Collections.Generic.List TasksList = new(); @@ -180,24 +183,28 @@ internal static class RpcSetTasksPatch Il2CppSystem.Collections.Generic.HashSet UsedTaskTypes = new(); + var start0 = 0; var start1 = 0; var start2 = 0; - // Long tasks + Il2CppSystem.Collections.Generic.List CommonTasks = new(); + foreach (var task in ShipStatus.Instance.CommonTasks) CommonTasks.Add(task); + Shuffle(CommonTasks); + + ShipStatus.Instance.AddTasksFromList(ref start0, numCommonTasks, TasksList, UsedTaskTypes, CommonTasks); + Il2CppSystem.Collections.Generic.List LongTasks = new(); foreach (var task in ShipStatus.Instance.LongTasks) LongTasks.Add(task); Shuffle(LongTasks); ShipStatus.Instance.AddTasksFromList(ref start1, numLongTasks, TasksList, UsedTaskTypes, LongTasks); - // Short tasks Il2CppSystem.Collections.Generic.List ShortTasks = new(); foreach (var task in ShipStatus.Instance.ShortTasks) ShortTasks.Add(task); Shuffle(ShortTasks); ShipStatus.Instance.AddTasksFromList(ref start2, numShortTasks, TasksList, UsedTaskTypes, ShortTasks); - // Apply result taskTypeIds = new Il2CppStructArray(TasksList.Count); for (int i = 0; i < TasksList.Count; i++) taskTypeIds[i] = TasksList[i]; } @@ -212,4 +219,5 @@ internal static class RpcSetTasksPatch list[r] = tmp; } } + } \ No newline at end of file diff --git a/Resources/Language/English.json b/Resources/Language/English.json index d4698fe..80c5f83 100644 --- a/Resources/Language/English.json +++ b/Resources/Language/English.json @@ -7,6 +7,7 @@ "autoStart": "Auto Start", "enableDarkTheme": "Enable Dark Theme", "enableLobbyMusic": "Lobby Music", + "disableInfoWhenDead": "Disable Task/Kill View", "gameMasterWarning":"You will now spectate games until GM is turned off. WARNING: Custom role notifications will not work with this setting on!", @@ -76,6 +77,7 @@ "tabGroupSpeedrun": "Speedrun", "speedrunSettingsOverride": "Auto Update Settings", "gameAutoEndsAfter": "Game automatically ends after", + "engineerMode": "All Crewmates Are Engineer", "tabGroupSabotages": "Sabotages", "deadImpostorsCanSabotage": "Dead Impostors Can Sabotage", @@ -222,17 +224,41 @@ "socialsAll": "AUR socials:\n\ng i t h u b . c o m /\nApeMV/AmongUsRevamped\n\nd i s c o r d . g g /\n83Zhzhyhya", "translationReloaded": "Your file has successfully been reset.\nTo apply the changes, restart your game.", - "Mayor": "Mayor", - "mayorPublic": "Mayor:\n\nThe Mayor is a crewmate with {0} extra vote(s). Depending on settings, they can vent to call a meeting.", - "mayorPriv": "Your role is Mayor!\n\nYou are a crewmate with {0} extra vote(s). If you are an Engineer, vent to call a meeting.", - "mayorExtraVoteCount": "Extra Votes", - "mayorVentToMeeting": "Can Vent To Call Meetings", + "mayorPublic": "Mayor:\n\nThe Mayor is a Crewmate with {0} additional vote(s). Use them wisely.", + "tyrantPublic": "Tyrant:\n\nThe Tyrant is an Impostor with {0} additional vote(s). Use them wisely.", - "Jester": "Jester", - "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", + "juggernautPublic": "Juggernaut:\n\nThe Impostors instantly win if the Juggernaut gains {0} kills.", + "speedrunnerPublic": "Speedrunner:\n\nThe Crewmates win if the Speedrunner completes tasks and is alive. The Speedrunner has more tasks.", + + "stealerPublic": "Stealer:\n\nThe Stealer gains {0} additional vote(s) per killed player. Votes are rounded down.", + "workhorsePublic": "Workhorse:\n\nThe Workhorse gains {0} additional vote(s) per completed task. Votes are rounded down.", + + "jesterPublic": "Jester:\n\nThe Jester is a Crewmate who can also win alone by getting voted.", "customRoleAnnouncement": "Custom Roles are enabled!\n\nIf you have a Custom Role, it will show in a message below this one.", - "roleDescriptionHelp": "Your Custom Role can be seen at the start of meetings. It is shown by an obvious private text" + + "tabGroupCrewmateAbilities": "Crewmate Ability Settings", + "crewmateAbility": "Crewmate (Role) Ability", + "scientistAbility": "Scientist Ability", + "engineerAbility": "Engineer Ability", + "noisemakerAbility": "Noisemaker Ability", + "trackerAbility": "Tracker Ability", + "detectiveAbility": "Detective Ability", + + "extraVotesCrewmate": "Extra Votes For Mayor", + "extraVotesPerTask": "Extra Votes Per Task For Workhorse", + "speedrunnerShortTasks": "Short Tasks For Speedrunner", + "speedrunnerLongTasks": "Long Tasks For Speedrunner", + + "tabGroupImpostorAbilities": "Impostor Ability Settings", + "impostorAbility": "Impostor (Role) Ability", + "shapeshifterAbility": "Shapeshifter Ability", + "phantomAbility": "Phantom Ability", + "viperAbility": "Viper Ability", + + "extraVotesImpostor": "Extra Votes For Tyrant", + "extraVotesPerKill": "Extra Votes Per Kill For Stealer", + "killsNeededForJuggernaut": "Kills Needed For Juggernaut", + + "ability": "Ability" }