diff --git a/source/Extensions/AmongUsExtensions.cs b/source/Extensions/AmongUsExtensions.cs index e1f9af7f6..11cb4f474 100644 --- a/source/Extensions/AmongUsExtensions.cs +++ b/source/Extensions/AmongUsExtensions.cs @@ -132,5 +132,11 @@ public static Texture2D CreateEmptyTexture(int width = 0, int height = 0) public static TMPro.TextMeshPro NameText(this PoolablePlayer p) => p.cosmetics.nameText; public static UnityEngine.SpriteRenderer myRend(this PlayerControl p) => p.cosmetics.currentBodySprite.BodySprite; + + // Add a method to calculate weighted role probabilities based on the session's role history. + public static Dictionary CalculateWeightedRoleProbabilities(PlayerControl player) { + // Placeholder for actual implementation + return new Dictionary(); + } } } \ No newline at end of file diff --git a/source/Patches/AmongUsClient_OnGameEnd.cs b/source/Patches/AmongUsClient_OnGameEnd.cs index 30f18ffa0..04ab7c405 100644 --- a/source/Patches/AmongUsClient_OnGameEnd.cs +++ b/source/Patches/AmongUsClient_OnGameEnd.cs @@ -10,8 +10,31 @@ namespace TownOfUs [HarmonyPatch(typeof(EndGameManager), nameof(EndGameManager.Start))] public class EndGameManager_SetEverythingUp { + // Implement a method to record the roles assigned to each player at the end of a game. + // Store the role history in a session-based collection. + private static Dictionary> _sessionRoleHistory = new Dictionary>(); + + public static void RecordSessionRoles() { + foreach (var player in PlayerControl.AllPlayerControls) { + var playerId = player.PlayerId; + var roleType = Role.GetRole(player)?.RoleType ?? RoleEnum.None; + + if (!_sessionRoleHistory.ContainsKey(playerId)) { + _sessionRoleHistory[playerId] = new List(); + } + if (_sessionRoleHistory[playerId].Count > CustomGameOptions.MaxRoleHistoryListSize) { + _sessionRoleHistory[playerId].RemoveRange(0, _sessionRoleHistory[playerId].Count - CustomGameOptions.MaxRoleHistoryListSize); + } + _sessionRoleHistory[playerId].Add(roleType); + } + } + public static void Prefix() { + if (CustomGameOptions.WeightedRoleSelection) + { + RecordSessionRoles(); // Record roles at the end of each game + } List losers = new List(); foreach (var role in Role.GetRoles(RoleEnum.Amnesiac)) { diff --git a/source/Patches/CustomGameOptions.cs b/source/Patches/CustomGameOptions.cs index 620d15606..bf4c8b868 100644 --- a/source/Patches/CustomGameOptions.cs +++ b/source/Patches/CustomGameOptions.cs @@ -30,6 +30,11 @@ public enum AdminDeadPlayers } public static class CustomGameOptions { + // Define a new game option to enable or disable the weighted role selection system. + public static bool WeightedRoleSelection = Generate.WeightedRoleSelection.Get(); + // Define a new game option to set the maximum size of the role history list. + public static int MaxRoleHistoryListSize = 100; // always value at 100 for better performance and user cannot modify it in the game + public static int MayorOn => (int)Generate.MayorOn.Get(); public static int JesterOn => (int)Generate.JesterOn.Get(); public static int SheriffOn => (int)Generate.SheriffOn.Get(); @@ -383,4 +388,4 @@ public static class CustomGameOptions public static bool HunterBodyReport => Generate.HunterBodyReport.Get(); public static bool DoomsayerCantObserve => Generate.DoomsayerCantObserve.Get(); } -} \ No newline at end of file +} diff --git a/source/Patches/CustomOption/Generate.cs b/source/Patches/CustomOption/Generate.cs index adf760409..cd7815899 100644 --- a/source/Patches/CustomOption/Generate.cs +++ b/source/Patches/CustomOption/Generate.cs @@ -505,6 +505,8 @@ public class Generate public static CustomNumberOption ChillDuration; public static CustomNumberOption ChillStartSpeed; + public static CustomToggleOption WeightedRoleSelection; + public static Func PercentFormat { get; } = value => $"{value:0}%"; private static Func CooldownFormat { get; } = value => $"{value:0.0#}s"; private static Func MultiplierFormat { get; } = value => $"{value:0.0#}x"; @@ -1297,7 +1299,6 @@ public static void GenerateAll() Frosty = new CustomHeaderOption(num++, MultiMenu.modifiers, "Frosty"); ChillDuration = new CustomNumberOption(num++, MultiMenu.modifiers, "Chill Duration", 10f, 1f, 15f, 1f, CooldownFormat); ChillStartSpeed = new CustomNumberOption(num++, MultiMenu.modifiers, "Chill Start Speed", 0.75f, 0.25f, 0.95f, 0.05f, MultiplierFormat); - Flash = new CustomHeaderOption(num++, MultiMenu.modifiers, "Flash"); FlashSpeed = new CustomNumberOption(num++, MultiMenu.modifiers, "Flash Speed", 1.25f, 1.05f, 2.5f, 0.05f, MultiplierFormat); @@ -1314,6 +1315,8 @@ public static void GenerateAll() Underdog = new CustomHeaderOption(num++, MultiMenu.modifiers, "Underdog"); UnderdogKillBonus = new CustomNumberOption(num++, MultiMenu.modifiers, "Kill Cooldown Bonus", 5f, 2.5f, 10f, 2.5f, CooldownFormat); UnderdogIncreasedKC = new CustomToggleOption(num++, MultiMenu.modifiers, "Increased Kill Cooldown When 2+ Imps", true); + + WeightedRoleSelection = new CustomToggleOption(num++, MultiMenu.main, "Record Roles On each game ends (weighted role selection)", true); } } } \ No newline at end of file