mirror of
https://github.com/D1GQ/BetterAmongUs.git
synced 2026-10-19 15:51:52 +00:00
Add support to v18.0 and remove BetterRoleAssignment
This commit is contained in:
1 parent
6aea28e9e9
commit
eed3d24f9d
13 files changed
+61
-370
No files matched your search
@@ -79,7 +79,7 @@
|
||||
|
||||
<!-- NuGet Core Packages -->
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AmongUs.GameLibs.Steam" Version="2026.6.5" />
|
||||
<PackageReference Include="AmongUs.GameLibs.Steam" Version="2026.8.18" />
|
||||
<PackageReference Include="BepInEx.IL2CPP.MSBuild" Version="2.0.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
|
||||
@@ -44,7 +44,7 @@ internal sealed class ForceSkipCommand : BaseCommand
|
||||
if (!countVotes)
|
||||
{
|
||||
var states = Array.Empty<MeetingHud.VoterState>();
|
||||
MeetingHud.Instance.RpcVotingComplete(states, null, false);
|
||||
MeetingHud.Instance.RpcVotingComplete(states, null, false, false, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -57,11 +57,11 @@ internal sealed class ForceSkipCommand : BaseCommand
|
||||
PlayerVoteArea playerVoteArea = MeetingHud.Instance.playerStates[i];
|
||||
array[i] = new MeetingHud.VoterState
|
||||
{
|
||||
VoterId = playerVoteArea.TargetPlayerId,
|
||||
VotedForId = playerVoteArea.VotedFor
|
||||
VoterId = playerVoteArea.PlayerId,
|
||||
VotedForId = playerVoteArea.VotedForId
|
||||
};
|
||||
}
|
||||
MeetingHud.Instance.RpcVotingComplete(array, networkedPlayerInfo, tie);
|
||||
MeetingHud.Instance.RpcVotingComplete(array, networkedPlayerInfo, tie, false, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,26 +312,4 @@ internal interface IMonoExtension<T> : IMonoExtension where T : MonoBehaviour
|
||||
{
|
||||
OnExtensionAwake((T)baseMono);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for Unity's UnityEngine.Object types.
|
||||
/// </summary>
|
||||
public static class UnityObjectExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines whether a Unity object has been destroyed or is null.
|
||||
/// </summary>
|
||||
/// <param name="obj">The Unity object to check.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the object has been destroyed or is null; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// This method uses Unity's overloaded == operator which returns true for
|
||||
/// destroyed objects even though the C# reference still exists.
|
||||
/// </remarks>
|
||||
public static bool IsDestroyedOrNull(this UnityEngine.Object obj)
|
||||
{
|
||||
return obj == null;
|
||||
}
|
||||
}
|
||||
+1
-5
@@ -58,11 +58,7 @@ internal static class ModInfo
|
||||
/// </summary>
|
||||
internal static string[] SupportedAmongUsVersions =
|
||||
[
|
||||
"2026.6.5",
|
||||
"2026.4.7", // Andiroid only update
|
||||
"2026.3.31",
|
||||
"2026.3.17",
|
||||
"2025.11.18"
|
||||
"2026.8.18"
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -195,7 +195,7 @@ internal static class GameState
|
||||
if (!IsMeeting || MeetingHud.Instance == null)
|
||||
return false;
|
||||
|
||||
return MeetingHud.Instance.state is MeetingHud.VoteStates.Voted or MeetingHud.VoteStates.NotVoted;
|
||||
return MeetingHud.Instance.state is MeetingHud.MeetingStates.Voted or MeetingHud.MeetingStates.NotVoted;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ internal static class GameState
|
||||
if (!IsMeeting || MeetingHud.Instance == null)
|
||||
return false;
|
||||
|
||||
return MeetingHud.Instance.state == MeetingHud.VoteStates.Proceeding;
|
||||
return MeetingHud.Instance.state == MeetingHud.MeetingStates.Proceeding;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -354,7 +354,7 @@ public abstract class OptionItem
|
||||
/// Gets the boxed value of this option.
|
||||
/// </summary>
|
||||
/// <returns>The option value as an object.</returns>
|
||||
public abstract object GetBoxedValue();
|
||||
public abstract object? GetBoxedValue();
|
||||
|
||||
/// <summary>
|
||||
/// Represents a node in the option hierarchy tree for text formatting.
|
||||
@@ -399,7 +399,7 @@ public abstract class OptionItem<T> : OptionItem
|
||||
/// Gets the boxed value of this option.
|
||||
/// </summary>
|
||||
/// <returns>The option value as an object.</returns>
|
||||
public override sealed object GetBoxedValue()
|
||||
public override sealed object? GetBoxedValue()
|
||||
{
|
||||
return GetValue();
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using BetterAmongUs.Data.Config;
|
||||
using BetterAmongUs.Generated;
|
||||
using BetterAmongUs.Modules;
|
||||
using BetterAmongUs.Patches.Gameplay.UI.Chat;
|
||||
using BetterAmongUs.Utilities;
|
||||
using System.Text;
|
||||
using TMPro;
|
||||
@@ -56,7 +57,15 @@ internal sealed class BetterPingTracker : MonoBehaviour
|
||||
return;
|
||||
|
||||
// Update position and appearance
|
||||
aspectPosition.DistanceFromEdge = new Vector3(4f, 0.1f, -5);
|
||||
if (ChatPatch.IsChatVisible)
|
||||
{
|
||||
aspectPosition.DistanceFromEdge = new Vector3(4.6f, 0.1f, -5);
|
||||
}
|
||||
else
|
||||
{
|
||||
aspectPosition.DistanceFromEdge = new Vector3(4f, 0.1f, -5);
|
||||
}
|
||||
|
||||
aspectPosition.Alignment = AspectPosition.EdgeAlignments.RightTop;
|
||||
text.outlineWidth = 0.3f;
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ internal sealed class MeetingInfoDisplay : PlayerInfoDisplay
|
||||
var IdNumber = LevelDisplay.transform.Find("LevelNumber");
|
||||
IdLabel.gameObject.DestroyTextTranslators();
|
||||
IdLabel.GetComponent<TextMeshPro>().text = "ID";
|
||||
IdNumber.GetComponent<TextMeshPro>().text = pva.TargetPlayerId.ToString();
|
||||
IdNumber.GetComponent<TextMeshPro>().text = pva.PlayerId.Value.ToString();
|
||||
IdLabel.name = "IdLabel";
|
||||
IdNumber.name = "IdNumber";
|
||||
PlayerLevel.transform.position += new Vector3(0.23f, 0f);
|
||||
@@ -260,7 +260,7 @@ internal sealed class MeetingInfoDisplay : PlayerInfoDisplay
|
||||
/// <returns>Disconnect reason text.</returns>
|
||||
private string GetDisconnectText()
|
||||
{
|
||||
var playerData = GameData.Instance.GetPlayerById(_pva.TargetPlayerId);
|
||||
var playerData = GameData.Instance.GetPlayerById(_pva.PlayerId);
|
||||
if (playerData == null)
|
||||
return string.Empty;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using BepInEx.Unity.IL2CPP.Utils;
|
||||
using BetterAmongUs.Data.Config;
|
||||
using BetterAmongUs.Generated;
|
||||
using BetterAmongUs.Managers;
|
||||
using BetterAmongUs.Modules;
|
||||
using BetterAmongUs.Patches.Gameplay.UI.Chat;
|
||||
using BetterAmongUs.Utilities;
|
||||
using HarmonyLib;
|
||||
using System.Collections;
|
||||
@@ -53,26 +53,23 @@ internal static class HudManagerPatch
|
||||
if (__instance.Chat == null)
|
||||
return;
|
||||
|
||||
if (!BAUConfigs.ChatInGameplay.Value)
|
||||
{
|
||||
// Vanilla chat behavior: only show chat when dead or during meetings
|
||||
if (!PlayerControl.LocalPlayer.IsAlive())
|
||||
{
|
||||
__instance.Chat.gameObject.SetActive(true);
|
||||
}
|
||||
else if (GameState.IsInGamePlay && !(GameState.IsMeeting || GameState.IsExilling))
|
||||
{
|
||||
__instance.Chat.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// BAU chat behavior: always show chat when enabled
|
||||
if (__instance.Chat.gameObject.active == false)
|
||||
{
|
||||
__instance.Chat.gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
__instance.Chat.gameObject.SetActive(ChatPatch.IsChatVisible);
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(MatchInfoHudButton), nameof(MatchInfoHudButton.Update))]
|
||||
[HarmonyPrefix]
|
||||
private static bool MatchInfoHudButton_Update_Prefix(MatchInfoHudButton __instance)
|
||||
{
|
||||
if (ChatPatch.IsChatVisible)
|
||||
{
|
||||
__instance.aspectPosition.DistanceFromEdge = MatchInfoHudButton.adjustedDistanceFromEdge;
|
||||
}
|
||||
else
|
||||
{
|
||||
__instance.aspectPosition.DistanceFromEdge = MatchInfoHudButton.defaultDistanceFromEdge;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,6 @@
|
||||
using AmongUs.GameOptions;
|
||||
using BetterAmongUs.Modules;
|
||||
using BetterAmongUs.Modules.Support;
|
||||
using BetterAmongUs.MonoScripts.Extended;
|
||||
using BetterAmongUs.Patches.Gameplay.UI.Settings;
|
||||
using BetterAmongUs.Utilities;
|
||||
using BetterAmongUs.Utilities.Extension;
|
||||
using HarmonyLib;
|
||||
|
||||
namespace BetterAmongUs.Patches.Gameplay.Managers;
|
||||
@@ -12,9 +8,6 @@ namespace BetterAmongUs.Patches.Gameplay.Managers;
|
||||
[HarmonyPatch]
|
||||
internal static class RoleManagerPatch
|
||||
{
|
||||
internal static Dictionary<string, int> ImpostorMultiplier = []; // HashPuid, Multiplier
|
||||
private static readonly Random random = new();
|
||||
|
||||
[HarmonyPatch(typeof(RoleManager), nameof(RoleManager.SetRole))]
|
||||
[HarmonyPrefix]
|
||||
private static void RoleManager_SetRole_Prefix(RoleManager __instance, PlayerControl targetPlayer, RoleTypes roleType)
|
||||
@@ -28,305 +21,4 @@ internal static class RoleManagerPatch
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Better role assignment algorithm (replaces vanilla role assignment)
|
||||
[HarmonyPatch(typeof(RoleManager), nameof(RoleManager.SelectRoles))]
|
||||
[HarmonyPrefix]
|
||||
private static bool RoleManager_SelectRoles_Prefix()
|
||||
{
|
||||
// Skip BAU role assignment if other mods disabled it
|
||||
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_BetterRoleAlgorithm))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Use different algorithms for different game modes
|
||||
if (!GameState.IsHideNSeek)
|
||||
{
|
||||
RegularBetterRoleAssignment();
|
||||
}
|
||||
else
|
||||
{
|
||||
HideAndSeekBetterRoleAssignment();
|
||||
}
|
||||
|
||||
// Return false to prevent vanilla role assignment from running
|
||||
return false;
|
||||
}
|
||||
|
||||
internal static void RegularBetterRoleAssignment()
|
||||
{
|
||||
Logger_.LogHeader($"Better Role Assignment Has Started", "RoleManager");
|
||||
|
||||
// Initialize impostor multiplier tracking for all players
|
||||
foreach (var addplayer in BAUPlugin.AllPlayerControls.Where(pc => !ImpostorMultiplier.ContainsKey(Utils.GetHashPuid(pc))))
|
||||
ImpostorMultiplier[Utils.GetHashPuid(addplayer)] = 0;
|
||||
|
||||
int NumImpostors = GameOptionsManager.Instance.CurrentGameOptions.NumImpostors;
|
||||
int NumPlayers = BAUPlugin.AllPlayerControls.Count;
|
||||
|
||||
// Apply player count limits to impostor numbers
|
||||
var impostorLimits = new Dictionary<int, int>
|
||||
{
|
||||
{ 3, 1 },
|
||||
{ 5, 2 },
|
||||
{ 7, 3 }
|
||||
};
|
||||
|
||||
foreach (var limit in impostorLimits)
|
||||
{
|
||||
if (NumPlayers <= limit.Key)
|
||||
{
|
||||
NumImpostors = Math.Min(NumImpostors, limit.Value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
List<PlayerControl> Impostors = [];
|
||||
List<PlayerControl> Crewmates = [];
|
||||
|
||||
// Track available roles and their counts
|
||||
Dictionary<RoleTypes, int> ImpostorRoles = new() // Role, Amount
|
||||
{
|
||||
{ RoleTypes.Shapeshifter, 0 },
|
||||
{ RoleTypes.Phantom, 0 },
|
||||
{ RoleTypes.Viper, 0 }
|
||||
};
|
||||
|
||||
Dictionary<RoleTypes, int> CrewmateRoles = new() // Role, Amount
|
||||
{
|
||||
{ RoleTypes.Engineer, 0 },
|
||||
{ RoleTypes.Scientist, 0 },
|
||||
{ RoleTypes.Tracker, 0 },
|
||||
{ RoleTypes.Noisemaker, 0 },
|
||||
{ RoleTypes.Detective, 0 }
|
||||
};
|
||||
|
||||
List<RoleTypes> Roles = [.. ImpostorRoles.Keys, .. CrewmateRoles.Keys];
|
||||
|
||||
// Get role counts from game options
|
||||
foreach (RoleTypes role in Roles)
|
||||
{
|
||||
if (role.IsImpostorRole())
|
||||
ImpostorRoles[role] = GameOptionsManager.Instance.CurrentGameOptions.RoleOptions.GetNumPerGame(role);
|
||||
else
|
||||
CrewmateRoles[role] = GameOptionsManager.Instance.CurrentGameOptions.RoleOptions.GetNumPerGame(role);
|
||||
}
|
||||
|
||||
// Shuffle players for random role assignment
|
||||
List<PlayerControl> players = [.. BAUPlugin.AllPlayerControls.Where(player => !Impostors.Contains(player) && !Crewmates.Contains(player) && player.roleAssigned == false)];
|
||||
|
||||
int n = players.Count;
|
||||
while (n > 1)
|
||||
{
|
||||
n--;
|
||||
int k = random.Next(n + 1);
|
||||
PlayerControl value = players[k];
|
||||
players[k] = players[n];
|
||||
players[n] = value;
|
||||
}
|
||||
|
||||
// Assign roles to each player
|
||||
foreach (PlayerControl pc in players)
|
||||
{
|
||||
if (pc == null || pc.roleAssigned == true) continue;
|
||||
|
||||
// Check if player should be impostor based on multiplier and available slots
|
||||
if (Impostors.Count < NumImpostors && RNG() > ImpostorMultiplier[Utils.GetHashPuid(pc)])
|
||||
{
|
||||
var impRoles = ImpostorRoles.Shuffle();
|
||||
foreach (var kvp in impRoles)
|
||||
{
|
||||
// Assign special impostor role based on chance and availability
|
||||
if (RNG() <= GameOptionsManager.Instance.CurrentGameOptions.RoleOptions.GetChancePerGame(kvp.Key) && kvp.Value > 0)
|
||||
{
|
||||
ImpostorMultiplier[Utils.GetHashPuid(pc)] += 15; // Increase chance of being crewmate next game
|
||||
ImpostorRoles[kvp.Key]--;
|
||||
Impostors.Add(pc);
|
||||
pc.RpcSetRole(kvp.Key);
|
||||
|
||||
Logger_.LogPrivate($"Assigned {kvp.Key.GetRoleName()} role to {pc.Data.PlayerName}", "RoleManager");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If no special role assigned, give regular impostor
|
||||
if (!Impostors.Contains(pc))
|
||||
{
|
||||
ImpostorMultiplier[Utils.GetHashPuid(pc)] += 15;
|
||||
Impostors.Add(pc);
|
||||
pc.RpcSetRole(RoleTypes.Impostor);
|
||||
Logger_.LogPrivate($"Assigned {RoleTypes.Impostor.GetRoleName()} role to {pc.Data.PlayerName}", "RoleManager");
|
||||
}
|
||||
}
|
||||
else // Assign crewmate role
|
||||
{
|
||||
var crewRoles = CrewmateRoles.Shuffle();
|
||||
foreach (var kvp in crewRoles)
|
||||
{
|
||||
// Assign special crewmate role based on chance and availability
|
||||
if (RNG() <= GameOptionsManager.Instance.CurrentGameOptions.RoleOptions.GetChancePerGame(kvp.Key) && kvp.Value > 0)
|
||||
{
|
||||
ImpostorMultiplier[Utils.GetHashPuid(pc)] = 0; // Reset impostor chance
|
||||
CrewmateRoles[kvp.Key]--;
|
||||
Crewmates.Add(pc);
|
||||
pc.RpcSetRole(kvp.Key);
|
||||
|
||||
Logger_.LogPrivate($"Assigned {kvp.Key.GetRoleName()} role to {pc.Data.PlayerName}", "RoleManager");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If no special role assigned, give regular crewmate
|
||||
if (!Crewmates.Contains(pc))
|
||||
{
|
||||
ImpostorMultiplier[Utils.GetHashPuid(pc)] = 0;
|
||||
Crewmates.Add(pc);
|
||||
pc.RpcSetRole(RoleTypes.Crewmate);
|
||||
Logger_.LogPrivate($"Assigned {RoleTypes.Crewmate.GetRoleName()} role to {pc.Data.PlayerName}", "RoleManager");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Logger_.LogHeader($"Better Role Assignment Has Finished", "RoleManager");
|
||||
}
|
||||
|
||||
internal static void HideAndSeekBetterRoleAssignment()
|
||||
{
|
||||
Logger_.LogHeader($"Better Role Assignment Has Started", "RoleManager");
|
||||
|
||||
// Get impostor count from BAU settings (defaults to 1)
|
||||
int NumImpostors = GameOptionsManager.Instance.currentHideNSeekGameOptions.NumImpostors;
|
||||
|
||||
if (NumImpostors > BAUPlugin.AllPlayerControls.Count)
|
||||
NumImpostors = BAUPlugin.AllPlayerControls.Count;
|
||||
|
||||
List<NetworkedPlayerInfo> Impostors = [];
|
||||
List<NetworkedPlayerInfo> Crewmates = [];
|
||||
List<NetworkedPlayerInfo> CrewAndImps() => [.. Impostors, .. Crewmates];
|
||||
|
||||
// Get predefined impostor from settings
|
||||
var impId = GameOptionsManager.Instance.currentHideNSeekGameOptions.ImpostorPlayerID;
|
||||
if (impId != -1)
|
||||
{
|
||||
var player = Utils.PlayerFromPlayerId(impId);
|
||||
if (player != null)
|
||||
{
|
||||
if (Impostors.Count < NumImpostors)
|
||||
{
|
||||
Impostors.Add(player.Data);
|
||||
Logger_.LogPrivate($"Settings Assigned {RoleTypes.Impostor.GetRoleName()} role to {player.Data.PlayerName}", "RoleManager");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Shuffle remaining players for random role assignment
|
||||
List<PlayerControl> players = [.. BAUPlugin.AllPlayerControls.Where(player => !CrewAndImps().Contains(player.Data))];
|
||||
|
||||
int n = players.Count;
|
||||
while (n > 1)
|
||||
{
|
||||
n--;
|
||||
int k = random.Next(n + 1);
|
||||
PlayerControl value = players[k];
|
||||
players[k] = players[n];
|
||||
players[n] = value;
|
||||
}
|
||||
|
||||
// Assign roles to remaining players
|
||||
foreach (PlayerControl pc in players)
|
||||
{
|
||||
if (pc == null || pc.roleAssigned == true) continue;
|
||||
|
||||
if (Impostors.Count < NumImpostors)
|
||||
{
|
||||
Impostors.Add(pc.Data);
|
||||
Logger_.LogPrivate($"Assigned {RoleTypes.Impostor.GetRoleName()} role to {pc.Data.PlayerName}", "RoleManager");
|
||||
}
|
||||
else
|
||||
{
|
||||
Crewmates.Add(pc.Data);
|
||||
Logger_.LogPrivate($"Assigned {RoleTypes.Engineer.GetRoleName()} role to {pc.Data.PlayerName}", "RoleManager");
|
||||
}
|
||||
}
|
||||
|
||||
// Apply roles to all players
|
||||
foreach (var data in Impostors)
|
||||
{
|
||||
var player = Utils.PlayerFromPlayerId(data.PlayerId);
|
||||
player.RpcSetRole(RoleTypes.Impostor);
|
||||
}
|
||||
|
||||
foreach (var data in Crewmates)
|
||||
{
|
||||
var player = Utils.PlayerFromPlayerId(data.PlayerId);
|
||||
player.RpcSetRole(RoleTypes.Engineer);
|
||||
}
|
||||
|
||||
Logger_.LogHeader($"Better Role Assignment Has Finished", "RoleManager");
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(RoleManager), nameof(RoleManager.AssignRoleOnDeath))]
|
||||
[HarmonyPrefix]
|
||||
internal static bool RoleManager_AssignRoleOnDeath_Prefix(PlayerControl player)
|
||||
{
|
||||
// Track available ghost roles
|
||||
Dictionary<RoleTypes, int> GhostRoles = new() // Role, Amount
|
||||
{
|
||||
{ RoleTypes.GuardianAngel, 0 },
|
||||
};
|
||||
|
||||
List<RoleTypes> Roles = [.. GhostRoles.Keys];
|
||||
|
||||
foreach (RoleTypes role in Roles)
|
||||
{
|
||||
GhostRoles[role] = GameOptionsManager.Instance.CurrentGameOptions.RoleOptions.GetNumPerGame(role);
|
||||
}
|
||||
|
||||
// Deduct roles already assigned to dead players
|
||||
foreach (var allDeadPlayers in BAUPlugin.AllPlayerControls.Where(pc => !pc.IsAlive()))
|
||||
{
|
||||
for (int i = 0; i < Roles.Count; i++)
|
||||
{
|
||||
if (allDeadPlayers.Is(Roles[i]))
|
||||
{
|
||||
GhostRoles[Roles[i]]--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ghostRoles = GhostRoles.Shuffle();
|
||||
|
||||
// Assign ghost role based on chance and availability
|
||||
foreach (var kvp in ghostRoles)
|
||||
{
|
||||
if (player.IsImpostorTeam() && kvp.Key is RoleTypes.GuardianAngel) continue;
|
||||
|
||||
if (kvp.Value > 0 && RNG() <= GameOptionsManager.Instance.CurrentGameOptions.RoleOptions.GetChancePerGame(kvp.Key))
|
||||
{
|
||||
player.RpcSetRole(kvp.Key);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Assign default ghost role if no special role available
|
||||
player.RpcSetRole(player.Data.Role.DefaultGhostRole);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
internal static int RNG()
|
||||
{
|
||||
// Choose random number generator based on settings
|
||||
switch (BetterGameSettings.RoleRandomizer.GetStringIndex())
|
||||
{
|
||||
case 1:
|
||||
return UnityEngine.Random.Range(0, 100); // Unity RNG
|
||||
|
||||
default:
|
||||
Random Random = new Random();
|
||||
return Random.Next(0, 100); // .NET RNG
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,24 @@ internal static class ChatPatch
|
||||
|
||||
internal const string COMMAND_POSTFIX_ID = "<size=0%>IsCommand</size>";
|
||||
|
||||
internal static bool IsChatVisible
|
||||
{
|
||||
get
|
||||
{
|
||||
if (BAUConfigs.ChatInGameplay.Value)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!GameState.IsInGamePlay)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return !PlayerControl.LocalPlayer.IsAlive() || GameState.IsMeeting || GameState.IsExilling;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all chat bubbles from the chat.
|
||||
/// </summary>
|
||||
|
||||
@@ -32,7 +32,7 @@ internal static class MeetingHudPatch
|
||||
{
|
||||
if (pva == null) continue;
|
||||
|
||||
var target = Utils.PlayerFromPlayerId(pva.TargetPlayerId);
|
||||
var target = Utils.PlayerFromPlayerId(pva.PlayerId);
|
||||
if (target == null) continue;
|
||||
|
||||
pva.gameObject.AddComponent<MeetingInfoDisplay>().Init(target, pva);
|
||||
|
||||
@@ -140,7 +140,8 @@ internal static class RoleUtils
|
||||
{ RoleTypes.Engineer, "#8f8f8f" },
|
||||
{ RoleTypes.Noisemaker, "#fc7c7c" },
|
||||
{ RoleTypes.Tracker, "#59f002" },
|
||||
{ RoleTypes.Detective, "#0027FF" },
|
||||
{ RoleTypes.Detective, "#0027ff" },
|
||||
{ RoleTypes.Judge, "#e3d12b" },
|
||||
{ RoleTypes.ImpostorGhost, Colors.ImpostorRed.ColorToHex() },
|
||||
{ RoleTypes.Impostor, Colors.ImpostorRed.ColorToHex() },
|
||||
{ RoleTypes.Shapeshifter, "#f06102" },
|
||||
|
||||
Reference in new issue
Block a user