Revert "Fix role assignment"

This commit is contained in:
Atony authored and GitHub committed 2026-08-08 20:13:16 -05:00
1 parent b8b85e2bc3
commit d751819534
2 files changed
+93 -111

No files matched your search

@@ -0,0 +1,93 @@
using AmongUs.GameOptions;
using HarmonyLib;
using Il2CppSystem.Collections.Generic;
using System.Linq;
using MiraAPI.Roles;
namespace MiraAPI.Patches.Roles;
[HarmonyPatch(typeof(LogicRoleSelectionNormal))]
public static class LogicRoleSelectionNormalPatch
{
[HarmonyPrefix]
[HarmonyPatch(nameof(LogicRoleSelectionNormal.AssignRolesForTeam))]
public static bool AssignRolesForTeam(
LogicRoleSelectionNormal __instance,
List<NetworkedPlayerInfo> players,
IGameOptions opts,
RoleTeamTypes team,
int teamMax,
Il2CppSystem.Nullable<RoleTypes> defaultRole)
{
int num = 0;
var source = RoleManager.Instance.AllRoles.ToArray()
.Where(role => role.TeamType == team && !RoleManager.IsGhostRole(role.Role) &&
CustomRoleUtils.CanSpawnOnCurrentMode(role));
List<RoleTypes> list = new List<RoleTypes>();
IRoleOptionsCollection roleOptions = opts.RoleOptions;
var assignmentData = source.Where(x => !x.IsDead).Select(role =>
new RoleManager.RoleAssignmentData(
role,
roleOptions.GetNumPerGame(role.Role),
roleOptions.GetChancePerGame(role.Role))).ToList();
var source2 = CustomRoleUtils.GetPossibleRoles(assignmentData, x => x.Chance == 100);
var guaranteedRoles = source.Where(x => source2.Contains(((ushort)x.Role, 100)));
foreach (RoleManager.RoleAssignmentData roleAssignmentData in guaranteedRoles.Select((x) =>
new RoleManager.RoleAssignmentData(x, roleOptions.GetNumPerGame(x.Role), 100)))
{
while (true)
{
RoleManager.RoleAssignmentData roleAssignmentData2 = roleAssignmentData;
int count = roleAssignmentData2.Count;
roleAssignmentData2.Count = count - 1;
if (count <= 0)
{
break;
}
list.Add(roleAssignmentData.Role.Role);
}
}
__instance.AssignRolesFromList(players, teamMax, list, ref num);
var list2 = source.Where(x => !x.IsDead).Select(role =>
new RoleManager.RoleAssignmentData(
role,
roleOptions.GetNumPerGame(role.Role),
roleOptions.GetChancePerGame(role.Role))).ToList();
list.Clear();
foreach (RoleManager.RoleAssignmentData roleAssignmentData3 in list2)
{
for (int i = 0; i < roleAssignmentData3.Count; i++)
{
if (HashRandom.Next(101) < roleAssignmentData3.Chance)
{
list.Add(roleAssignmentData3.Role.Role);
}
}
}
__instance.AssignRolesFromList(players, teamMax, list, ref num);
var defaultRole2 = team is RoleTeamTypes.Crewmate ? RoleTypes.Crewmate : RoleTypes.Impostor;
try
{
defaultRole2 = defaultRole.Value;
}
catch
{
// Ignored
}
while (list.Count < players.Count && list.Count + num < teamMax)
{
list.Add(defaultRole2);
}
__instance.AssignRolesFromList(players, teamMax, list, ref num);
return false;
}
}
-111
View File
@@ -1,111 +0,0 @@
using System.Collections.Generic;
using AmongUs.GameOptions;
using HarmonyLib;
using System.Linq;
using InnerNet;
using MiraAPI.Roles;
namespace MiraAPI.Patches.Roles;
[HarmonyPatch(typeof(RoleManager))]
public static class SelectRolesPatch
{
public static bool ApiHandlesRoleSelect = true;
[HarmonyPrefix]
[HarmonyPatch(nameof(RoleManager.SelectRoles))]
public static bool SelectRoles()
{
if (!ApiHandlesRoleSelect)
{
return true;
}
Il2CppSystem.Collections.Generic.List<ClientData> list = new();
AmongUsClient.Instance.GetAllClients(list);
List<NetworkedPlayerInfo> list2 = list.ToArray()
.Where(c => c.Character != null && c.Character.Data != null && !c.Character.Data.Disconnected &&
!c.Character.Data.IsDead).OrderBy(c => c.Id).Select(c => c.Character.Data)
.ToList();
foreach (NetworkedPlayerInfo networkedPlayerInfo in GameData.Instance.AllPlayers)
{
if (networkedPlayerInfo.Object != null && networkedPlayerInfo.Object.isDummy)
{
list2.Add(networkedPlayerInfo);
}
}
IGameOptions currentGameOptions = GameOptionsManager.Instance.CurrentGameOptions;
int adjustedNumImpostors = GameOptionsManager.Instance.CurrentGameOptions.GetAdjustedNumImpostors(list2.Count);
AssignRolesForTeam(list2, currentGameOptions, RoleTeamTypes.Impostor, adjustedNumImpostors, RoleTypes.Impostor);
AssignRolesForTeam(list2, currentGameOptions, RoleTeamTypes.Crewmate, int.MaxValue, RoleTypes.Crewmate);
return false;
}
public static void AssignRolesForTeam(
List<NetworkedPlayerInfo> players,
IGameOptions opts,
RoleTeamTypes team,
int teamMax,
RoleTypes defaultRole)
{
int num = 0;
var source = RoleManager.Instance.AllRoles.ToArray()
.Where(role => role.TeamType == team && !RoleManager.IsGhostRole(role.Role) &&
CustomRoleUtils.CanSpawnOnCurrentMode(role));
List<RoleTypes> list = new List<RoleTypes>();
IRoleOptionsCollection roleOptions = opts.RoleOptions;
// Assign guaranteed roles first, just like the vanilla selector. This is
// important because the list of players is shared by both team passes.
foreach (var role in source.Where(x => roleOptions.GetChancePerGame(x.Role) == 100)
.Select(role => role.Role))
{
for (var i = 0; i < roleOptions.GetNumPerGame(role); i++)
{
list.Add(role);
}
}
AssignRolesFromList(players, teamMax, list, ref num);
// A 100% role was already assigned above. Including it here can consume
// another player and, more importantly, leaves the fallback count wrong.
list.Clear();
foreach (var role in source.Where(x =>
roleOptions.GetChancePerGame(x.Role) > 0 &&
roleOptions.GetChancePerGame(x.Role) < 100)
.Select(role => role.Role))
{
for (var i = 0; i < roleOptions.GetNumPerGame(role); i++)
{
if (HashRandom.Next(101) < roleOptions.GetChancePerGame(role))
{
list.Add(role);
}
}
}
AssignRolesFromList(players, teamMax, list, ref num);
// Assign the remaining players up to the requested team limit. The
// vanilla list has been consumed by AssignRolesFromList at this point,
// so checking list.Count can leave players unassigned.
while (players.Count > 0 && num < teamMax)
{
list.Add(defaultRole);
AssignRolesFromList(players, teamMax, list, ref num);
}
}
private static void AssignRolesFromList(List<NetworkedPlayerInfo> players, int teamMax, List<RoleTypes> roleList, ref int rolesAssigned)
{
while (roleList.Count > 0 && players.Count > 0 && rolesAssigned < teamMax)
{
int index = HashRandom.FastNext(roleList.Count);
RoleTypes roleType = roleList[index];
roleList.RemoveAt(index);
int index2 = HashRandom.FastNext(players.Count);
players[index2].Object.RpcSetRole(roleType, false);
players.RemoveAt(index2);
rolesAssigned++;
}
}
}