From e9f1c1aaf19ad100e39d7543e42b525542211c7c Mon Sep 17 00:00:00 2001 From: Ape <155788660+ApeMV@users.noreply.github.com> Date: Sun, 1 Feb 2026 20:19:24 +0100 Subject: [PATCH] Lighting the stars + like so many other stuff --- AmongUsRevamped.csproj | 2 +- Modules/CustomRoleAssigner.cs | 62 ----------------- Modules/CustomRoleManagement.cs | 115 +++++++++++++++++++++++++++++++ Modules/Utils.cs | 22 ++++-- Patches/ChatPatches.cs | 10 +-- Patches/CredentialsPatch.cs | 47 ++++++++++++- Patches/DleksPatch.cs | 116 ++++++++++++++++++-------------- Patches/IntroPatch.cs | 28 ++++++++ Patches/NumberOptionsPatch.cs | 6 +- Patches/OnGameStartedPatch.cs | 7 +- Resources/Language/Strings.cs | 8 ++- 11 files changed, 284 insertions(+), 139 deletions(-) delete mode 100644 Modules/CustomRoleAssigner.cs create mode 100644 Modules/CustomRoleManagement.cs create mode 100644 Patches/IntroPatch.cs diff --git a/AmongUsRevamped.csproj b/AmongUsRevamped.csproj index b1dd16a..179354f 100644 --- a/AmongUsRevamped.csproj +++ b/AmongUsRevamped.csproj @@ -14,7 +14,7 @@ - + diff --git a/Modules/CustomRoleAssigner.cs b/Modules/CustomRoleAssigner.cs deleted file mode 100644 index 503d0b5..0000000 --- a/Modules/CustomRoleAssigner.cs +++ /dev/null @@ -1,62 +0,0 @@ -using AmongUs.GameOptions; -using System; -using InnerNet; -using UnityEngine; - -namespace AmongUsRevamped; - -public static class CustomRolesAssigner -{ - private static readonly System.Random random = new System.Random(); - - public static void AssignRoles() - { - List<(string roleName, int percentage)> crewmateRoles = new List<(string, int)> - { - ("Jester", Options.JesterPerc.GetInt()), - ("Mayor", Options.MayorPerc.GetInt()) - }; - - List<(string roleName, int percentage)> impostorRoles = new List<(string, int)> - { - - }; - - List availablePlayers = new List(); - foreach (var player in PlayerControl.AllPlayerControls) - { - availablePlayers.Add(player); - } - - availablePlayers = availablePlayers.OrderBy(x => random.Next()).ToList(); - - Dictionary playerRoles = new Dictionary(); - HashSet assignedRoles = new HashSet(); - - foreach (var player in availablePlayers) - { - bool isCrewmate = !player.Data.Role.IsImpostor; - - List<(string roleName, int percentage)> rolesToAssign = isCrewmate ? crewmateRoles : impostorRoles; - - foreach (var (roleName, percentage) in rolesToAssign) - { - if (assignedRoles.Contains(roleName)) - continue; - - int randomValue = random.Next(0, 101); - - Logger.Info($"{roleName}, Value: {randomValue}, Percentage: {percentage}", "StartGameCustomRole1"); - - if (randomValue <= percentage && !playerRoles.ContainsKey(player)) - { - playerRoles[player] = roleName; - assignedRoles.Add(roleName); - Logger.Info($"({player.PlayerId}) {player.Data.PlayerName} -> {roleName}", "StartGameCustomRole2"); - - break; - } - } - } - } -} \ No newline at end of file diff --git a/Modules/CustomRoleManagement.cs b/Modules/CustomRoleManagement.cs new file mode 100644 index 0000000..82d4687 --- /dev/null +++ b/Modules/CustomRoleManagement.cs @@ -0,0 +1,115 @@ +using AmongUs.GameOptions; +using System; +using InnerNet; +using UnityEngine; + +namespace AmongUsRevamped; + +public static class CustomRoleManagement +{ + public static Dictionary PlayerRoles = new Dictionary(); + private static readonly System.Random random = new System.Random(); + + public static void AssignRoles() + { + // crewmateRoles = assigned with crewmate role base + // impostorRoles = assigned with impostor role base + List<(string roleName, int percentage)> crewmateRoles = new List<(string, int)> + { + ("Jester", Options.JesterPerc.GetInt()), + ("Mayor", Options.MayorPerc.GetInt()) + }; + + List<(string roleName, int percentage)> impostorRoles = new List<(string, int)> + { + + }; + + List availablePlayers = new List(); + foreach (var player in PlayerControl.AllPlayerControls) + { + availablePlayers.Add(player); + } + + availablePlayers = availablePlayers.OrderBy(x => random.Next()).ToList(); + PlayerRoles.Clear(); + HashSet assignedRoles = new HashSet(); + + foreach (var player in availablePlayers) + { + bool isCrewmate = !player.Data.Role.IsImpostor; + + List<(string roleName, int percentage)> rolesToAssign = isCrewmate ? crewmateRoles : impostorRoles; + + foreach (var (roleName, percentage) in rolesToAssign) + { + if (assignedRoles.Contains(roleName)) + continue; + + int randomValue = random.Next(0, 101); + + Logger.Info($"{roleName}, Value: {randomValue}, Percentage: {percentage}", "StartGameCustomRole1"); + + if (randomValue <= percentage && !PlayerRoles.ContainsKey(player.PlayerId)) + { + PlayerRoles[player.PlayerId] = roleName; + assignedRoles.Add(roleName); + Logger.Info($"({player.PlayerId}) {player.Data.PlayerName} -> {roleName}", "StartGameCustomRole2"); + + break; + } + } + } + } + + public static string GetActiveRoles() + { + var crewmateRoles = new List(); + var neutralRoles = new List(); + var impostorRoles = new List(); + var lines = new List(); + + if (Options.MayorPerc.GetInt() > 1) crewmateRoles.Add($"Mayor ({Options.MayorPerc.GetInt()}%)"); + + if (Options.JesterPerc.GetInt() > 1) neutralRoles.Add($"Jester ({Options.JesterPerc.GetInt()})%"); + + void AddCategory(string header, List roles) + { + if (roles.Count == 0) return; + + if (lines.Count > 0) lines.Add(""); + + lines.Add(header); + lines.AddRange(roles); + } + + AddCategory("Crewmate:", crewmateRoles); + AddCategory("Neutral:", neutralRoles); + AddCategory("Impostor:", impostorRoles); + + return lines.Count > 0 ? string.Join("\n", lines) : string.Empty; + } + + public static void SendRoleMessages(Dictionary roleMessages) + { + HashSet sentRoles = new HashSet(); + + var players = PlayerControl.AllPlayerControls.ToArray().ToList(); + float delay = 0f; + + foreach (var player in players) + { + if (!PlayerRoles.TryGetValue(player.PlayerId, out string role)) continue; + if (!roleMessages.ContainsKey(role)) continue; + if (sentRoles.Contains(role)) continue; + + new LateTask(() => + { + Utils.SendPrivateMessage(player, roleMessages[role]); + }, delay, "SendRoleMessage"); + + sentRoles.Add(role); + delay += 2.2f; + } + } +} \ No newline at end of file diff --git a/Modules/Utils.cs b/Modules/Utils.cs index b3397ac..04e98ff 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -134,9 +134,16 @@ public static class Utils string name = region.Name; + // Joining games shows incorrect regions + if (!AmongUsClient.Instance.AmHost) + { + name = ""; + return name; + } + if (AmongUsClient.Instance.NetworkMode != NetworkModes.OnlineGame) { - name = "Local Game"; + name = "Server: Local Game"; return name; } @@ -145,9 +152,9 @@ public static class Utils // Official servers name = name switch { - "North America" => "NA", - "Europe" => "EU", - "Asia" => "AS", + "North America" => "Server: NA", + "Europe" => "Server: EU", + "Asia" => "Server: AS", _ => name }; @@ -160,11 +167,11 @@ public static class Utils { // Modded Servers if (ip.Contains("au-eu")) - name = "MEU"; + name = "Server: MEU"; else if (ip.Contains("au-as")) - name = "MAS"; + name = "Server: MAS"; else - name = "MNA"; + name = "Server: MNA"; return name; } @@ -191,6 +198,7 @@ public static class Utils LateTask.Tasks.Clear(); FixedUpdateInGamePatch.ProcessedModerators.Clear(); NormalGameEndChecker.ImpCheckComplete = false; + CreateOptionsPickerPatch.SetDleks2 = false; } public static PlayerControl[] AllAlivePlayerControls diff --git a/Patches/ChatPatches.cs b/Patches/ChatPatches.cs index 7a611c0..e46f211 100644 --- a/Patches/ChatPatches.cs +++ b/Patches/ChatPatches.cs @@ -113,7 +113,7 @@ internal static class SendChatPatch return false; } - if (text == "/aur" || text == "/amongusrevamped") + if (text == "/aur" || text == "/amongusrevamped" || text == "/socials" || text == "/github" || text == "/discord") { Utils.ChatCommand(__instance, $"{String.SocialsAll}", "", false); return false; @@ -142,10 +142,7 @@ internal static class SendChatPatch switch (Options.Gamemode.GetValue()) { case 0: - PlayerControl.LocalPlayer.RpcSendChat($"Custom roles:\nThere are no custom roles."); - __instance.timeSinceLastMessage = 0.8f; - __instance.freeChatField.textArea.Clear(); - __instance.freeChatField.textArea.SetText(string.Empty); + Utils.ChatCommand(__instance, $"CUSTOM ROLES:\n\n{CustomRoleManagement.GetActiveRoles()}", "", false); break; case 1: @@ -161,6 +158,9 @@ internal static class SendChatPatch break; } + __instance.timeSinceLastMessage = 0.8f; + __instance.freeChatField.textArea.Clear(); + __instance.freeChatField.textArea.SetText(string.Empty); return false; } diff --git a/Patches/CredentialsPatch.cs b/Patches/CredentialsPatch.cs index 5ce6815..708f44c 100644 --- a/Patches/CredentialsPatch.cs +++ b/Patches/CredentialsPatch.cs @@ -1,7 +1,9 @@ using System; using System.Text; +using Il2CppInterop.Runtime.InteropTypes.Arrays; using TMPro; using UnityEngine; +using UnityEngine.SceneManagement; //https://github.com/Gurge44/EndlessHostRoles/blob/main/Patches/CredentialsPatch.cs namespace AmongUsRevamped @@ -123,8 +125,12 @@ namespace AmongUsRevamped Sb.Append(Utils.InGame ? " - " : "\r\n"); Sb.Append($"Ping: {ping}"); - AppendSeparator(); - Sb.Append($"Server: {Utils.GetRegionName()}"); + + if (Utils.GetRegionName() != "") + { + AppendSeparator(); + Sb.Append(Utils.GetRegionName()); + } if (Main.ShowFps.Value && LastFPS.Count > 0) { @@ -244,4 +250,39 @@ public static class MainMenuManagerStartPatch } } } -} \ No newline at end of file +} + +#if !ANDROID +[HarmonyPatch(typeof(ServerDropdown), nameof(ServerDropdown.FillServerOptions))] +public static class ServerDropdownPatch +{ + public static bool Prefix(ServerDropdown __instance) + { + if (SceneManager.GetActiveScene().name == "FindAGame") return true; + SpriteRenderer bg = __instance.background; + bg.size = new Vector2(4, 1); + ServerManager sm = ServerManager.Instance; + TranslationController tc = TranslationController.Instance; + int totalCols = Mathf.Max(1, Mathf.CeilToInt(sm.AvailableRegions.Length / (float)5)); + int rowLimit = Mathf.Min(sm.AvailableRegions.Length, 5); + + for (var index = 0; index < sm.AvailableRegions.Length; index++) + { + IRegionInfo ri = sm.AvailableRegions[index]; + var b = __instance.ButtonPool.Get(); + b.transform.localPosition = new Vector3(((index / 5) - ((totalCols - 1) / 2f)) * 3.15f, __instance.y_posButton - (0.5f * (index % 5)), -1f); + b.Text.text = tc.GetStringWithDefault(ri.TranslateName, ri.Name, new Il2CppReferenceArray(0)); + b.Text.ForceMeshUpdate(); + b.Button.OnClick.RemoveAllListeners(); + b.Button.OnClick.AddListener((Action)(() => __instance.ChooseOption(ri))); + __instance.controllerSelectable.Add(b.Button); + } + + float h = 1.2f + (0.5f * (rowLimit - 1)); + float w = totalCols > 1 ? (3.15f * (totalCols - 1)) + bg.size.x : bg.size.x; + bg.transform.localPosition = new Vector3(0f, __instance.initialYPos - ((h - 1.2f) / 2f), 0f); + bg.size = new Vector2(w, h); + return false; + } +} +#endif \ No newline at end of file diff --git a/Patches/DleksPatch.cs b/Patches/DleksPatch.cs index 29b1ada..030664e 100644 --- a/Patches/DleksPatch.cs +++ b/Patches/DleksPatch.cs @@ -30,77 +30,91 @@ class CreateOptionsPickerPatch [HarmonyPostfix] public static void Postfix_Initialize(CreateGameMapPicker __instance) { + float delay = SceneManager.GetActiveScene().name == "MainMenu" ? 0.2f : 0f; if (SceneManager.GetActiveScene().name == "FindAGame") return; - if (SetDleks2 && SceneManager.GetActiveScene().name == "MainMenu") return; new LateTask(() => { - SetDleks2 = true; - int DleksPos = 3; - MapSelectButton[] AllMapButton = __instance.transform.GetComponentsInChildren(); + int DleksPos = 3; + + MapSelectButton[] AllMapButton = __instance.transform.GetComponentsInChildren(); + AllMapButton = AllMapButton.Where(x => x.gameObject.name != "DleksButton").ToArray(); - if (AllMapButton != null) - { - GameObject dlekS_ehT = UnityEngine.Object.Instantiate(AllMapButton[0].gameObject, __instance.transform); - dlekS_ehT.transform.position = AllMapButton[DleksPos].transform.position; - dlekS_ehT.transform.SetSiblingIndex(DleksPos + 2); - MapSelectButton dlekS_ehT_MapButton = dlekS_ehT.GetComponent(); - DleksButton = dlekS_ehT_MapButton; - foreach (var icon in dlekS_ehT_MapButton.MapIcon) + if (AllMapButton != null) { - if (icon == null || icon.transform == null) continue; - icon.flipX = true; - } - dlekS_ehT_MapButton.Button.OnClick.RemoveAllListeners(); - dlekS_ehT_MapButton.Button.OnClick.AddListener((UnityEngine.Events.UnityAction)(() => - { - __instance.SelectMap(__instance.AllMapIcons[0]); - - if (__instance.selectedButton) + GameObject dlekS_ehT = null; + if (!SetDleks2 || SceneManager.GetActiveScene().name != "MainMenu") { - __instance.selectedButton.Button.SelectButton(false); + dlekS_ehT = UnityEngine.Object.Instantiate(AllMapButton[0].gameObject, __instance.transform); + dlekS_ehT.name = "DleksButton"; + SetDleks2 = true; } - __instance.selectedButton = dlekS_ehT_MapButton; - __instance.selectedButton.Button.SelectButton(true); - __instance.selectedMapId = 3; - - if (!Utils.isHideNSeek) - Main.NormalOptions.MapId = 0; - else if (Utils.isHideNSeek) - Main.HideNSeekOptions.MapId = 0; - - __instance.MapImage.sprite = Utils.LoadSprite($"AmongUsRevamped.Resources.Images.DleksBanner.png", 100f); - __instance.MapName.sprite = Utils.LoadSprite($"AmongUsRevamped.Resources.Images.DleksBanner-Wordart.png", 100f); - })); - - for (int i = DleksPos; i < AllMapButton.Length; i++) - { - AllMapButton[i].transform.localPosition += new Vector3(0.625f, 0f, 0f); - } - - if (DleksButton != null) - { - if (SetDleks) + else { + dlekS_ehT = __instance.transform.Find("DleksButton")?.gameObject; + } + + if (dlekS_ehT == null) return; + dlekS_ehT.name = "DleksButton"; + dlekS_ehT.transform.position = AllMapButton[DleksPos].transform.position; + dlekS_ehT.transform.SetSiblingIndex(DleksPos + 2); + MapSelectButton dlekS_ehT_MapButton = dlekS_ehT.GetComponent(); + DleksButton = dlekS_ehT_MapButton; + + foreach (var icon in dlekS_ehT_MapButton.MapIcon) + { + if (icon == null || icon.transform == null) continue; + icon.flipX = true; + } + dlekS_ehT_MapButton.Button.OnClick.RemoveAllListeners(); + dlekS_ehT_MapButton.Button.OnClick.AddListener((UnityEngine.Events.UnityAction)(() => + { + __instance.SelectMap(__instance.AllMapIcons[0]); + if (__instance.selectedButton) { __instance.selectedButton.Button.SelectButton(false); } - DleksButton.Button.SelectButton(true); - __instance.selectedButton = DleksButton; + __instance.selectedButton = dlekS_ehT_MapButton; + __instance.selectedButton.Button.SelectButton(true); __instance.selectedMapId = 3; + if (!Utils.isHideNSeek) + Main.NormalOptions.MapId = 0; + else if (Utils.isHideNSeek) + Main.HideNSeekOptions.MapId = 0; + __instance.MapImage.sprite = Utils.LoadSprite($"AmongUsRevamped.Resources.Images.DleksBanner.png", 100f); __instance.MapName.sprite = Utils.LoadSprite($"AmongUsRevamped.Resources.Images.DleksBanner-Wordart.png", 100f); - } - else + })); + + for (int i = DleksPos; i < AllMapButton.Length; i++) { - DleksButton.Button.SelectButton(false); + AllMapButton[i].transform.localPosition += new Vector3(0.625f, 0f, 0f); + } + + if (DleksButton != null) + { + if (SetDleks) + { + if (__instance.selectedButton) + { + __instance.selectedButton.Button.SelectButton(false); + } + DleksButton.Button.SelectButton(true); + __instance.selectedButton = DleksButton; + __instance.selectedMapId = 3; + + __instance.MapImage.sprite = Utils.LoadSprite($"AmongUsRevamped.Resources.Images.DleksBanner.png", 100f); + __instance.MapName.sprite = Utils.LoadSprite($"AmongUsRevamped.Resources.Images.DleksBanner-Wordart.png", 100f); + } + else + { + DleksButton.Button.SelectButton(false); + } } } - } - - }, 0.2f, "ApplyDleks"); + }, delay, "ApplyDleks"); } [HarmonyPatch(typeof(GameOptionsMapPicker), nameof(GameOptionsMapPicker.FixedUpdate))] diff --git a/Patches/IntroPatch.cs b/Patches/IntroPatch.cs new file mode 100644 index 0000000..424e47e --- /dev/null +++ b/Patches/IntroPatch.cs @@ -0,0 +1,28 @@ +using Hazel; +using InnerNet; +using System; +using UnityEngine; + +namespace AmongUsRevamped; + +[HarmonyPatch(typeof(HudManager), nameof(HudManager.CoShowIntro))] +internal static class CoShowIntroPatch +{ + public static void Postfix(IntroCutscene __instance) + { + Logger.Info("Intro initiated", "d"); + + if (!AmongUsClient.Instance.AmHost) return; + + if ((Options.Gamemode.GetValue() == 0 || Options.Gamemode.GetValue() == 1) && !Utils.isHideNSeek) + { + CustomRoleManagement.AssignRoles(); + } + + CustomRoleManagement.SendRoleMessages(new Dictionary + { + { "Jester", $"{String.Jester}"}, + { "Mayor", $"{String.Mayor}"} + }); + } +} \ No newline at end of file diff --git a/Patches/NumberOptionsPatch.cs b/Patches/NumberOptionsPatch.cs index 7789f52..5f3dcfd 100644 --- a/Patches/NumberOptionsPatch.cs +++ b/Patches/NumberOptionsPatch.cs @@ -11,7 +11,7 @@ public static class NumberOption_Increase { if (ModGameOptionsMenu.TabIndex >= 3) return true; - if (Utils.isHideNSeek || Utils.InGame && !Utils.isHideNSeek && __instance.Title != StringNames.GameNumImpostors && __instance.Title != StringNames.GamePlayerSpeed) + if (Utils.isHideNSeek || Utils.IsLobby && !Utils.isHideNSeek && __instance.Title != StringNames.GameNumImpostors && __instance.Title != StringNames.GamePlayerSpeed) { __instance.Value += __instance.Increment; __instance.UpdateValue(); @@ -30,7 +30,7 @@ public static class NumberOption_Decrease { if (ModGameOptionsMenu.TabIndex >= 3) return true; - if (Utils.isHideNSeek || Utils.InGame && !Utils.isHideNSeek && __instance.Title != StringNames.GameNumImpostors && __instance.Title != StringNames.GamePlayerSpeed) + if (Utils.isHideNSeek || Utils.IsLobby && !Utils.isHideNSeek && __instance.Title != StringNames.GameNumImpostors && __instance.Title != StringNames.GamePlayerSpeed) { __instance.Value -= __instance.Increment; __instance.UpdateValue(); @@ -49,7 +49,7 @@ public static class NumberOption_Initialize { if (ModGameOptionsMenu.TabIndex >= 3) return; - if (Utils.isHideNSeek || Utils.InGame && !Utils.isHideNSeek && __instance.Title != StringNames.GameNumImpostors && __instance.Title != StringNames.GamePlayerSpeed) + if (Utils.isHideNSeek || Utils.IsLobby && !Utils.isHideNSeek && __instance.Title != StringNames.GameNumImpostors && __instance.Title != StringNames.GamePlayerSpeed) { __instance.ValidRange = new FloatRange(-900f, 900f); } diff --git a/Patches/OnGameStartedPatch.cs b/Patches/OnGameStartedPatch.cs index 9802395..029a337 100644 --- a/Patches/OnGameStartedPatch.cs +++ b/Patches/OnGameStartedPatch.cs @@ -5,7 +5,7 @@ using UnityEngine; namespace AmongUsRevamped; [HarmonyPatch(typeof(AmongUsClient), nameof(AmongUsClient.CoStartGame))] -internal class ApplyCustomImpostorCount +internal class CoStartGamePatch { public static void Postfix(AmongUsClient __instance) { @@ -16,11 +16,6 @@ internal class ApplyCustomImpostorCount NormalGameEndChecker.imps.Clear(); NormalGameEndChecker.LastWinReason = ""; - if ((Options.Gamemode.GetValue() == 0 || Options.Gamemode.GetValue() == 1) && !Utils.isHideNSeek) - { - CustomRolesAssigner.AssignRoles(); - } - if (Main.GM.Value) { if (Options.Gamemode.GetValue() == 3) diff --git a/Resources/Language/Strings.cs b/Resources/Language/Strings.cs index cae1c57..8baeee5 100644 --- a/Resources/Language/Strings.cs +++ b/Resources/Language/Strings.cs @@ -33,5 +33,11 @@ public static class String return $"/kick, /ban - Bans or kicks a player by name\n/ckick, /cban - Bans or kicks a player by color";}} public static string SocialsAll{get{ - return $"AUR socials:\n\ng i t h u b . c o m /\nApeMV/AmongUsRevamped\n\nd i s c o r d . g g / 83Zhzhyhya";}} + return $"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";}} + + public static string Mayor{get{ + return $"PRIVATE:\n\nYour role is Mayor!\n\nYou are a crewmate with i total votes. Use your voting power to eject Impostors.";}} + + public static string Jester{get{ + return $"PRIVATE:\n\nYour role is Jester!\nYou are NOT a crewmate!\n\nYou win by getting voted. Act as suspicious as possible.";}} }