mirror of
https://github.com/D1GQ/BetterAmongUs.git
synced 2026-10-20 01:46:19 +00:00
Rework string building
This commit is contained in:
1 parent
7460720178
commit
69f4e3bef3
6 files changed
+157
-197
No files matched your search
@@ -1,12 +1,11 @@
|
||||
using AmongUs.GameOptions;
|
||||
using BetterAmongUs.Attributes;
|
||||
using BetterAmongUs.Attributes;
|
||||
using BetterAmongUs.Data;
|
||||
using BetterAmongUs.Generated;
|
||||
using BetterAmongUs.Modules.Support;
|
||||
using BetterAmongUs.MonoScripts.Extended;
|
||||
using BetterAmongUs.Structs;
|
||||
using BetterAmongUs.Utilities;
|
||||
using Il2CppInterop.Runtime.Attributes;
|
||||
using System.Text;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -23,8 +22,8 @@ internal sealed class MeetingInfoDisplay : PlayerInfoDisplay
|
||||
private Vector3 _infoPos;
|
||||
private Vector3 _TopPos;
|
||||
|
||||
private readonly StringBuilder _sbTag = new(256);
|
||||
private readonly StringBuilder _sbInfo = new(256);
|
||||
private readonly SplitStringBuilder _ssTag = new(100, '-');
|
||||
private readonly SplitStringBuilder _ssInfo = new(100, '-');
|
||||
private string _lastInfoText = "", _lastTopText = "";
|
||||
private int _lastUpdateFrame;
|
||||
private const int UPDATE_COOLDOWN = 5;
|
||||
@@ -75,8 +74,8 @@ internal sealed class MeetingInfoDisplay : PlayerInfoDisplay
|
||||
if (_pva == null)
|
||||
return;
|
||||
|
||||
_sbTag.Clear();
|
||||
_sbInfo.Clear();
|
||||
_ssTag.Clear();
|
||||
_ssInfo.Clear();
|
||||
|
||||
if (_player != null)
|
||||
{
|
||||
@@ -142,22 +141,21 @@ internal sealed class MeetingInfoDisplay : PlayerInfoDisplay
|
||||
if (_player == null || _player.Data == null || _player.ExtendedData() == null)
|
||||
return;
|
||||
|
||||
SetPlayerTags(_sbTag);
|
||||
FormatPlayerInfo(_sbTag, _sbInfo);
|
||||
SetPlayerTags(_ssTag);
|
||||
_ssInfo.Append(_player.GetRoleInfo(true));
|
||||
|
||||
string roleText = GetRoleText();
|
||||
UpdateNameTextPosition(roleText, _sbInfo.ToString());
|
||||
UpdateNameTextPosition(_ssInfo.ToString(), _ssInfo.ToString());
|
||||
|
||||
UpdateTextIfChanged(_infoText, _sbInfo.ToString(), ref _lastInfoText);
|
||||
UpdateTextIfChanged(_topText, roleText, ref _lastTopText);
|
||||
UpdateTextIfChanged(_infoText, _ssInfo.ToString(), ref _lastInfoText);
|
||||
UpdateTextIfChanged(_topText, _ssTag.ToString(), ref _lastTopText);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets player tags based on data from BetterDataManager.
|
||||
/// </summary>
|
||||
/// <param name="sbTag">StringBuilder for tag text.</param>
|
||||
/// <param name="ssTag">StringBuilder for tag text.</param>
|
||||
[HideFromIl2Cpp]
|
||||
private void SetPlayerTags(StringBuilder sbTag)
|
||||
private void SetPlayerTags(SplitStringBuilder ssTag)
|
||||
{
|
||||
if (_player == null)
|
||||
return;
|
||||
@@ -167,70 +165,10 @@ internal sealed class MeetingInfoDisplay : PlayerInfoDisplay
|
||||
|
||||
if (BetterDataManager.Files.BetterDataFile.TryGetCheatInfo(_player.Data, out var info))
|
||||
{
|
||||
sbTag.Append(info.title.ToColor(info.hexColor) + "+++");
|
||||
ssTag.Append(info.title.ToColor(info.hexColor));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formats player information tags into a readable string.
|
||||
/// </summary>
|
||||
/// <param name="sbTag">StringBuilder containing tags.</param>
|
||||
/// <param name="sbInfo">StringBuilder for formatted info.</param>
|
||||
[HideFromIl2Cpp]
|
||||
private static void FormatPlayerInfo(StringBuilder sbTag, StringBuilder sbInfo)
|
||||
{
|
||||
if (sbTag.Length == 0)
|
||||
return;
|
||||
|
||||
string tagString = sbTag.ToString();
|
||||
string[] tags = tagString.Split(["+++"], StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
for (int i = 0; i < tags.Length; i++)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(tags[i]))
|
||||
{
|
||||
sbInfo.Append(tags[i]);
|
||||
if (i < tags.Length - 1)
|
||||
{
|
||||
sbInfo.Append(" - ");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the role text for display.
|
||||
/// </summary>
|
||||
/// <returns>Formatted role text.</returns>
|
||||
private string GetRoleText()
|
||||
{
|
||||
if (_player == null) return string.Empty;
|
||||
|
||||
string roleHexColor = _player.IsImpostorTeam() ? "#ff1919" : "#8cffff";
|
||||
string role = $"<color={roleHexColor}>{_player.GetRoleName()}</color>";
|
||||
|
||||
if (!_player.IsImpostorTeam() && _player.myTasks.Count > 0)
|
||||
{
|
||||
int completedTasks = 0;
|
||||
foreach (var task in _player.Data.Tasks)
|
||||
{
|
||||
if (task.Complete)
|
||||
completedTasks++;
|
||||
}
|
||||
role += $" <color=#cbcbcb>({completedTasks}/{_player.Data.Tasks.Count})</color>";
|
||||
}
|
||||
|
||||
if (!_player.IsImpostorTeammate())
|
||||
{
|
||||
if ((PlayerControl.LocalPlayer.IsAlive() || PlayerControl.LocalPlayer.Is(RoleTypes.GuardianAngel)) && !_player.IsLocalPlayer())
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
return role;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates name text position based on role and info text presence.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using AmongUs.Data;
|
||||
using AmongUs.GameOptions;
|
||||
using BetterAmongUs.Attributes;
|
||||
using BetterAmongUs.Data;
|
||||
using BetterAmongUs.Data.Config;
|
||||
@@ -8,10 +7,9 @@ using BetterAmongUs.Modules;
|
||||
using BetterAmongUs.Modules.Support;
|
||||
using BetterAmongUs.MonoScripts.Extended;
|
||||
using BetterAmongUs.Patches.Gameplay.UI.Settings;
|
||||
using BetterAmongUs.Structs;
|
||||
using BetterAmongUs.Utilities;
|
||||
using HarmonyLib;
|
||||
using Il2CppInterop.Runtime.Attributes;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
@@ -30,9 +28,9 @@ internal class PlayerInfoDisplay : MonoBehaviour
|
||||
protected TextMeshPro? _topText;
|
||||
protected TextMeshPro? _bottomText;
|
||||
|
||||
private readonly StringBuilder _sbTag = new(256);
|
||||
private readonly StringBuilder _sbTagTop = new(256);
|
||||
private readonly StringBuilder _sbTagBottom = new(256);
|
||||
private readonly SplitStringBuilder _ssTag = new(100, '-');
|
||||
private readonly SplitStringBuilder _ssTagTop = new(100, '-');
|
||||
private readonly SplitStringBuilder _ssTagBottom = new(100, '-');
|
||||
private string _lastTopText = "", _lastBottomText = "", _lastInfoText = "";
|
||||
private int _lastUpdateFrame;
|
||||
private const int UPDATE_COOLDOWN = 10;
|
||||
@@ -132,9 +130,9 @@ internal class PlayerInfoDisplay : MonoBehaviour
|
||||
return;
|
||||
}
|
||||
|
||||
_sbTag.Clear();
|
||||
_sbTagTop.Clear();
|
||||
_sbTagBottom.Clear();
|
||||
_ssTag.Clear();
|
||||
_ssTagTop.Clear();
|
||||
_ssTagBottom.Clear();
|
||||
|
||||
UpdatePlayerInfo();
|
||||
UpdatePlayerHighlight();
|
||||
@@ -158,9 +156,6 @@ internal class PlayerInfoDisplay : MonoBehaviour
|
||||
if (_nameText == null)
|
||||
return;
|
||||
|
||||
if (_sbTag == null || _sbTagTop == null || _sbTagBottom == null)
|
||||
return;
|
||||
|
||||
if (_topText == null || _bottomText == null || _infoText == null)
|
||||
return;
|
||||
|
||||
@@ -195,20 +190,20 @@ internal class PlayerInfoDisplay : MonoBehaviour
|
||||
platform = TranslationStrings.Player_PlatformHidden.LocalizedString;
|
||||
|
||||
if (!_player.IsInShapeshift())
|
||||
SetPlayerOutline(_sbTag);
|
||||
SetPlayerOutline(_ssTag);
|
||||
|
||||
if (GameState.IsInGame && GameState.IsLobby && !GameState.IsFreePlay)
|
||||
{
|
||||
SetLobbyInfo(ref newName, betterData, _sbTag);
|
||||
SetLobbyInfo(ref newName, betterData, _ssTag);
|
||||
|
||||
_sbTagTop.Append($"<color=#9e9e9e>{platform}</color>+++")
|
||||
.Append($"<color=#ffd829>Lv: {_player.Data.PlayerLevel + 1}</color>+++");
|
||||
_ssTagTop.Append($"<color=#9e9e9e>{platform}</color>")
|
||||
.Append($"<color=#ffd829>Lv: {_player.Data.PlayerLevel + 1}</color>");
|
||||
|
||||
_sbTagBottom.Append($"<color={friendCodeColor}>{friendCode}</color>+++");
|
||||
_ssTagBottom.Append($"<color={friendCodeColor}>{friendCode}</color>");
|
||||
}
|
||||
else if ((GameState.IsInGame || GameState.IsFreePlay) && !GameState.IsHideNSeek)
|
||||
{
|
||||
SetInGameInfo(_sbTagTop);
|
||||
SetInGameInfo(_ssTagTop);
|
||||
}
|
||||
|
||||
if (!BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_NameOverride))
|
||||
@@ -236,18 +231,18 @@ internal class PlayerInfoDisplay : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
UpdateTextIfChanged(_topText, _sbTagTop, ref _lastTopText);
|
||||
UpdateTextIfChanged(_bottomText, _sbTagBottom, ref _lastBottomText);
|
||||
UpdateTextIfChanged(_infoText, _sbTag, ref _lastInfoText);
|
||||
UpdateTextIfChanged(_topText, _ssTagTop, ref _lastTopText);
|
||||
UpdateTextIfChanged(_bottomText, _ssTagBottom, ref _lastBottomText);
|
||||
UpdateTextIfChanged(_infoText, _ssTag, ref _lastInfoText);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates text if changed, optimizing performance.
|
||||
/// </summary>
|
||||
/// <param name="textMesh">TextMeshPro component to update.</param>
|
||||
/// <param name="sb">StringBuilder containing new text.</param>
|
||||
/// <param name="ss">StringBuilder containing new text.</param>
|
||||
/// <param name="lastValue">Reference to last value for comparison.</param>
|
||||
private static void UpdateTextIfChanged(TextMeshPro textMesh, StringBuilder sb, ref string lastValue)
|
||||
private static void UpdateTextIfChanged(TextMeshPro textMesh, SplitStringBuilder ss, ref string lastValue)
|
||||
{
|
||||
if (BAUModdedSupportFlags.HasFlag(BAUModdedSupportFlags.Disable_PlayerInfo))
|
||||
{
|
||||
@@ -258,7 +253,7 @@ internal class PlayerInfoDisplay : MonoBehaviour
|
||||
if (textMesh == null)
|
||||
return;
|
||||
|
||||
string newText = Utils.FormatInfo(sb);
|
||||
string newText = ss.ToString();
|
||||
if (newText != lastValue)
|
||||
{
|
||||
textMesh.SetText(newText);
|
||||
@@ -341,9 +336,9 @@ internal class PlayerInfoDisplay : MonoBehaviour
|
||||
/// <summary>
|
||||
/// Sets player outline based on data from BetterDataManager.
|
||||
/// </summary>
|
||||
/// <param name="sbTag">StringBuilder for tag text.</param>
|
||||
/// <param name="ssTag">StringBuilder for tag text.</param>
|
||||
[HideFromIl2Cpp]
|
||||
private void SetPlayerOutline(StringBuilder? sbTag)
|
||||
private void SetPlayerOutline(SplitStringBuilder? ssTag)
|
||||
{
|
||||
if (_player == null)
|
||||
return;
|
||||
@@ -358,9 +353,9 @@ internal class PlayerInfoDisplay : MonoBehaviour
|
||||
|
||||
if (BetterDataManager.Files.BetterDataFile.TryGetCheatInfo(_player.Data, out var info))
|
||||
{
|
||||
if (sbTag != null)
|
||||
if (ssTag.HasValue)
|
||||
{
|
||||
sbTag.Append(info.title.ToColor(info.hexColor) + "+++");
|
||||
ssTag.Value.Append(info.title.ToColor(info.hexColor));
|
||||
}
|
||||
_player.SetOutlineByHex(true, info.hexColor);
|
||||
}
|
||||
@@ -374,7 +369,7 @@ internal class PlayerInfoDisplay : MonoBehaviour
|
||||
/// Sets lobby specific information.
|
||||
/// </summary>
|
||||
[HideFromIl2Cpp]
|
||||
private void SetLobbyInfo(ref string newName, ExtendedPlayerInfo betterData, StringBuilder sbTag)
|
||||
private void SetLobbyInfo(ref string newName, ExtendedPlayerInfo betterData, SplitStringBuilder ssTag)
|
||||
{
|
||||
if (betterData == null)
|
||||
return;
|
||||
@@ -386,37 +381,20 @@ internal class PlayerInfoDisplay : MonoBehaviour
|
||||
{
|
||||
string verificationSymbol = betterData.IsVerifiedBetterUser || _player.IsLocalPlayer() ? "✓ " : "";
|
||||
|
||||
sbTag.AppendFormat("<color=#0dff00>{1}{0}</color>+++",
|
||||
ssTag.AppendFormat("<color=#0dff00>{1}{0}</color>",
|
||||
TranslationStrings.Player_BetterUser.LocalizedString, verificationSymbol);
|
||||
}
|
||||
sbTag.Append($"<color=#b554ff>ID: {_player.PlayerId}</color>+++");
|
||||
ssTag.Append($"<color=#b554ff>ID: {_player.PlayerId}</color>");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets in-game specific information.
|
||||
/// </summary>
|
||||
/// <param name="sbTagTop">StringBuilder for top tag text.</param>
|
||||
/// <param name="ssTagTop">StringBuilder for top tag text.</param>
|
||||
[HideFromIl2Cpp]
|
||||
private void SetInGameInfo(StringBuilder sbTagTop)
|
||||
private void SetInGameInfo(SplitStringBuilder ssTagTop)
|
||||
{
|
||||
if (_player.IsImpostorTeammate() || _player.IsLocalPlayer() ||
|
||||
!PlayerControl.LocalPlayer.IsAlive() && !PlayerControl.LocalPlayer.Is(RoleTypes.GuardianAngel))
|
||||
{
|
||||
string roleInfo = _player.GetRoleName().ToColor(_player.Data.Role.TeamColor);
|
||||
|
||||
if (!_player.IsImpostorTeam() && _player.myTasks.Count > 0)
|
||||
{
|
||||
int completedTasks = 0;
|
||||
foreach (var task in _player.Data.Tasks)
|
||||
{
|
||||
if (task.Complete)
|
||||
completedTasks++;
|
||||
}
|
||||
roleInfo += $" <color=#cbcbcb>({completedTasks}/{_player.Data.Tasks.Count})</color>";
|
||||
}
|
||||
|
||||
sbTagTop.Append(roleInfo + "+++");
|
||||
}
|
||||
ssTagTop.Append(_player.GetRoleInfo(true));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
using AmongUs.GameOptions;
|
||||
using BetterAmongUs.Data;
|
||||
using BetterAmongUs.Data;
|
||||
using BetterAmongUs.Data.Config;
|
||||
using BetterAmongUs.Generated;
|
||||
using BetterAmongUs.Modules;
|
||||
using BetterAmongUs.Modules.Support;
|
||||
using BetterAmongUs.MonoScripts.Extended;
|
||||
using BetterAmongUs.Structs;
|
||||
using BetterAmongUs.Utilities;
|
||||
using BetterAmongUs.Utilities.Extension;
|
||||
using HarmonyLib;
|
||||
using System.Text;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -234,21 +233,15 @@ internal static class ChatPatch
|
||||
if (localPlayer == null)
|
||||
return;
|
||||
|
||||
StringBuilder sbTag = new();
|
||||
StringBuilder sbInfo = new();
|
||||
SplitStringBuilder ssTag = new(100, '-');
|
||||
|
||||
string hashPuid = Utils.GetHashPuid(sourcePlayer);
|
||||
string friendCode = playerInfo.FriendCode;
|
||||
string playerName = playerInfo.ExtendedData()?.RealName ?? "???";
|
||||
|
||||
// Format role display with team color
|
||||
string Role = $"<size=75%><color={sourcePlayer.GetTeamHexColor()}>{sourcePlayer.GetRoleName()}</color></size>+++";
|
||||
|
||||
// In lobby, show player tags instead of roles
|
||||
if (GameState.IsLobby && !GameState.IsFreePlay)
|
||||
{
|
||||
Role = "";
|
||||
|
||||
var betterData = sourcePlayer.ExtendedData();
|
||||
if (betterData == null)
|
||||
return;
|
||||
@@ -256,50 +249,25 @@ internal static class ChatPatch
|
||||
// Show BAU user tag
|
||||
if (sourcePlayer.IsLocalPlayer() || betterData.IsBetterUser)
|
||||
{
|
||||
sbTag.AppendFormat("<color=#0dff00>{1}{0}</color>+++", TranslationStrings.Player_BetterUser, betterData.IsVerifiedBetterUser || sourcePlayer.IsLocalPlayer() ? "✓ " : "");
|
||||
ssTag.AppendFormat("<color=#0dff00>{1}{0}</color>", TranslationStrings.Player_BetterUser.LocalizedString, betterData.IsVerifiedBetterUser || sourcePlayer.IsLocalPlayer() ? "✓ " : "");
|
||||
}
|
||||
|
||||
// Show mod-specific tags based on player data
|
||||
if (BetterDataManager.Files.BetterDataFile.TryGetCheatInfo(sourcePlayer.Data, out var info))
|
||||
{
|
||||
sbTag.Append(info.title.ToColor(info.hexColor) + "+++");
|
||||
ssTag.Append(info.title.ToColor(info.hexColor));
|
||||
}
|
||||
}
|
||||
|
||||
// Hide roles from alive players (unless same team)
|
||||
if (!sourcePlayer.IsImpostorTeammate())
|
||||
{
|
||||
if (localPlayer.IsAlive() && !sourcePlayer.IsLocalPlayer())
|
||||
Role = "";
|
||||
}
|
||||
ssTag.Append(sourcePlayer.GetRoleInfo(false).Size(75f));
|
||||
|
||||
// Show role for dead players or if local player is Guardian Angel
|
||||
if ((localPlayer.Is(RoleTypes.GuardianAngel) && !sourcePlayer.IsAlive()) || !localPlayer.Is(RoleTypes.GuardianAngel))
|
||||
{
|
||||
sbTag.Append(Role);
|
||||
}
|
||||
|
||||
// Format tags with separators
|
||||
sbInfo.Append("<size=75%>");
|
||||
var parts = sbTag.ToString().Split("+++");
|
||||
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
{
|
||||
if (string.IsNullOrEmpty(parts[i])) continue;
|
||||
|
||||
sbInfo.Append(parts[i]);
|
||||
|
||||
if (i != parts.Length - 2)
|
||||
sbInfo.Append(" - ");
|
||||
}
|
||||
|
||||
sbInfo.Append("</size>");
|
||||
string infoText = ssTag.ToString().Size(75f);
|
||||
|
||||
// Position tags before local player name, after other players' names
|
||||
if (sourcePlayer.IsLocalPlayer())
|
||||
playerName = sbInfo + " " + playerName;
|
||||
playerName = infoText + " " + playerName;
|
||||
else
|
||||
playerName += " " + sbInfo;
|
||||
playerName += " " + infoText;
|
||||
|
||||
bubble.NameText.SetText(playerName);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
using BetterAmongUs.Utilities;
|
||||
using System.Text;
|
||||
|
||||
namespace BetterAmongUs.Structs;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a mutable string builder that concatenates text with a specified separator.
|
||||
/// </summary>
|
||||
internal readonly struct SplitStringBuilder(int capacity, char? separator = null)
|
||||
{
|
||||
private readonly char? _separator = separator;
|
||||
private readonly StringBuilder _value = new(capacity);
|
||||
|
||||
/// <summary>
|
||||
/// Appends a text segment to the current string with automatic separator insertion.
|
||||
/// </summary>
|
||||
/// <param name="text">The text segment to append.</param>
|
||||
/// <returns>The current <see cref="SplitStringBuilder"/> instance for fluent method chaining.</returns>
|
||||
internal SplitStringBuilder Append(string text)
|
||||
{
|
||||
if (Utils.RemoveHtmlText(text) == string.Empty)
|
||||
return this;
|
||||
|
||||
if (_value.Length > 0)
|
||||
{
|
||||
if (_separator != null)
|
||||
{
|
||||
_value.Append($" {_separator} ");
|
||||
}
|
||||
else
|
||||
{
|
||||
_value.Append(' ');
|
||||
}
|
||||
}
|
||||
|
||||
_value.Append(text);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Appends a formatted string to the current builder with automatic separator insertion.
|
||||
/// </summary>
|
||||
/// <param name="format">A composite format string.</param>
|
||||
/// <param name="strings">An array of objects to format.</param>
|
||||
/// <returns>The current <see cref="SplitStringBuilder"/> instance for fluent method chaining.</returns>
|
||||
internal SplitStringBuilder AppendFormat(string format, params string[] strings)
|
||||
{
|
||||
return Append(string.Format(format, strings));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all content from the string builder, resetting it to an empty state.
|
||||
/// </summary>
|
||||
internal void Clear()
|
||||
{
|
||||
_value.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the complete concatenated string with all appended segments.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The full string containing all appended text segments separated by the configured separator.
|
||||
/// Returns <see cref="string.Empty"/> if no text has been appended.
|
||||
/// </returns>
|
||||
public readonly override string ToString()
|
||||
{
|
||||
return _value.ToString();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using AmongUs.GameOptions;
|
||||
using BetterAmongUs.Modules;
|
||||
|
||||
namespace BetterAmongUs.Utilities;
|
||||
|
||||
@@ -83,23 +84,48 @@ internal static class RoleUtils
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a role type is cliant side and can be desynced.
|
||||
/// Gets the role information for a specified player, optionally including task progress.
|
||||
/// </summary>
|
||||
/// <param name="role">The role type to check.</param>
|
||||
/// <returns>True if the role can be desynced to other clients, false otherwise.</returns>
|
||||
internal static bool CanDesyncRole(this RoleTypes role)
|
||||
/// <param name="player">The player to get role information for.</param>
|
||||
/// <param name="displayTask">Whether to display the player's task completion progress.</param>
|
||||
/// <returns>Returns role info or <see cref="string.Empty"/> if the player's role information cannot be displayed.</returns>
|
||||
internal static string GetRoleInfo(this PlayerControl player, bool displayTask)
|
||||
{
|
||||
if (role is RoleTypes.Phantom or RoleTypes.Viper)
|
||||
if (!GameState.IsInGamePlay)
|
||||
{
|
||||
return false;
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
if (role is RoleTypes.Noisemaker)
|
||||
if (!player.IsLocalPlayer() && !player.IsImpostorTeammate())
|
||||
{
|
||||
return false;
|
||||
if (PlayerControl.LocalPlayer.IsAlive())
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
if (PlayerControl.LocalPlayer.Is(RoleTypes.GuardianAngel))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
string roleInfo = player.GetRoleName().ToColor(player.Data.Role.TeamColor);
|
||||
|
||||
if (!player.IsImpostorTeam() && player.myTasks.Count > 0)
|
||||
{
|
||||
if (displayTask)
|
||||
{
|
||||
int completedTasks = 0;
|
||||
foreach (var task in player.Data.Tasks)
|
||||
{
|
||||
if (task.Complete)
|
||||
completedTasks++;
|
||||
}
|
||||
roleInfo += $" <color=#cbcbcb>({completedTasks}/{player.Data.Tasks.Count})</color>";
|
||||
}
|
||||
}
|
||||
|
||||
return roleInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -43,26 +43,6 @@ internal static class Utils
|
||||
return text;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formats information from a StringBuilder, cleaning HTML and formatting separators.
|
||||
/// </summary>
|
||||
/// <param name="source">The StringBuilder containing the text to format.</param>
|
||||
/// <returns>The formatted string.</returns>
|
||||
internal static string FormatInfo(StringBuilder source)
|
||||
{
|
||||
if (source.Length == 0) return string.Empty;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (var part in source.ToString().Split("+++"))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(RemoveHtmlText(part)))
|
||||
{
|
||||
sb.Append(part).Append(" - ");
|
||||
}
|
||||
}
|
||||
return sb.ToString().TrimEnd(" - ".ToCharArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all HTML tags and formatting from a string.
|
||||
/// </summary>
|
||||
|
||||
Reference in new issue
Block a user