Admin playerlist antag presentation rework (#35538)
* refactor(src): Minor refactor of Draw in "AdminNameOverlay. And new info about playtime player * fix(src): Add configure classic admin owerlay * fix * antag status indication rework * the cvars are free, you can just take them * update playerlist on cvar change * more overlay options * tweak(src): Use _antagLabelClassic and tweak style * tweak(src): Add config display overlay for startingJob and playTime * tweak(src): Vector2 is replaced by var * tweak(src): return to the end of the list * add new option checkboxes * passing ConfigurationManager through constructor, some format changes * made sorting values more futureproof * comments * labels * no point commenting this out when the overlay stack PR will uncomment it again anyway * sorting prototype * localize symbols because why not * symmetry * Revert "localize symbols because why not" This reverts commit 922d4030300285a45777d62fcfd9c74b25fe7a60. * layout and formatting stuff * fix errant space --------- Co-authored-by: Schrödinger <132720404+Schrodinger71@users.noreply.github.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Content.Client.Administration.Systems;
|
using Content.Client.Administration.Systems;
|
||||||
|
using Content.Client.Stylesheets;
|
||||||
using Content.Shared.CCVar;
|
using Content.Shared.CCVar;
|
||||||
using Content.Shared.Mind;
|
using Content.Shared.Mind;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
@@ -14,14 +15,17 @@ namespace Content.Client.Administration;
|
|||||||
|
|
||||||
internal sealed class AdminNameOverlay : Overlay
|
internal sealed class AdminNameOverlay : Overlay
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IConfigurationManager _config = default!;
|
|
||||||
|
|
||||||
private readonly AdminSystem _system;
|
private readonly AdminSystem _system;
|
||||||
private readonly IEntityManager _entityManager;
|
private readonly IEntityManager _entityManager;
|
||||||
private readonly IEyeManager _eyeManager;
|
private readonly IEyeManager _eyeManager;
|
||||||
private readonly EntityLookupSystem _entityLookup;
|
private readonly EntityLookupSystem _entityLookup;
|
||||||
private readonly IUserInterfaceManager _userInterfaceManager;
|
private readonly IUserInterfaceManager _userInterfaceManager;
|
||||||
private readonly Font _font;
|
private readonly Font _font;
|
||||||
|
private readonly Font _fontBold;
|
||||||
|
private bool _overlayClassic;
|
||||||
|
private bool _overlaySymbols;
|
||||||
|
private bool _overlayPlaytime;
|
||||||
|
private bool _overlayStartingJob;
|
||||||
|
|
||||||
//TODO make this adjustable via GUI
|
//TODO make this adjustable via GUI
|
||||||
private readonly ProtoId<RoleTypePrototype>[] _filter =
|
private readonly ProtoId<RoleTypePrototype>[] _filter =
|
||||||
@@ -29,17 +33,29 @@ internal sealed class AdminNameOverlay : Overlay
|
|||||||
private readonly string _antagLabelClassic = Loc.GetString("admin-overlay-antag-classic");
|
private readonly string _antagLabelClassic = Loc.GetString("admin-overlay-antag-classic");
|
||||||
private readonly Color _antagColorClassic = Color.OrangeRed;
|
private readonly Color _antagColorClassic = Color.OrangeRed;
|
||||||
|
|
||||||
public AdminNameOverlay(AdminSystem system, IEntityManager entityManager, IEyeManager eyeManager, IResourceCache resourceCache, EntityLookupSystem entityLookup, IUserInterfaceManager userInterfaceManager)
|
public AdminNameOverlay(
|
||||||
|
AdminSystem system,
|
||||||
|
IEntityManager entityManager,
|
||||||
|
IEyeManager eyeManager,
|
||||||
|
IResourceCache resourceCache,
|
||||||
|
EntityLookupSystem entityLookup,
|
||||||
|
IUserInterfaceManager userInterfaceManager,
|
||||||
|
IConfigurationManager config)
|
||||||
{
|
{
|
||||||
IoCManager.InjectDependencies(this);
|
|
||||||
|
|
||||||
_system = system;
|
_system = system;
|
||||||
_entityManager = entityManager;
|
_entityManager = entityManager;
|
||||||
_eyeManager = eyeManager;
|
_eyeManager = eyeManager;
|
||||||
_entityLookup = entityLookup;
|
_entityLookup = entityLookup;
|
||||||
_userInterfaceManager = userInterfaceManager;
|
_userInterfaceManager = userInterfaceManager;
|
||||||
ZIndex = 200;
|
ZIndex = 200;
|
||||||
_font = new VectorFont(resourceCache.GetResource<FontResource>("/Fonts/NotoSans/NotoSans-Regular.ttf"), 10);
|
// Setting this to a specific font would break the antag symbols
|
||||||
|
_font = resourceCache.NotoStack();
|
||||||
|
_fontBold = resourceCache.NotoStack(variation: "Bold");
|
||||||
|
|
||||||
|
config.OnValueChanged(CCVars.AdminOverlayClassic, (show) => { _overlayClassic = show; }, true);
|
||||||
|
config.OnValueChanged(CCVars.AdminOverlaySymbols, (show) => { _overlaySymbols = show; }, true);
|
||||||
|
config.OnValueChanged(CCVars.AdminOverlayPlaytime, (show) => { _overlayPlaytime = show; }, true);
|
||||||
|
config.OnValueChanged(CCVars.AdminOverlayStartingJob, (show) => { _overlayStartingJob = show; }, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override OverlaySpace Space => OverlaySpace.ScreenSpace;
|
public override OverlaySpace Space => OverlaySpace.ScreenSpace;
|
||||||
@@ -48,11 +64,6 @@ internal sealed class AdminNameOverlay : Overlay
|
|||||||
{
|
{
|
||||||
var viewport = args.WorldAABB;
|
var viewport = args.WorldAABB;
|
||||||
|
|
||||||
//TODO make this adjustable via GUI
|
|
||||||
var classic = _config.GetCVar(CCVars.AdminOverlayClassic);
|
|
||||||
var playTime = _config.GetCVar(CCVars.AdminOverlayPlaytime);
|
|
||||||
var startingJob = _config.GetCVar(CCVars.AdminOverlayStartingJob);
|
|
||||||
|
|
||||||
foreach (var playerInfo in _system.PlayerList)
|
foreach (var playerInfo in _system.PlayerList)
|
||||||
{
|
{
|
||||||
var entity = _entityManager.GetEntity(playerInfo.NetEntity);
|
var entity = _entityManager.GetEntity(playerInfo.NetEntity);
|
||||||
@@ -85,35 +96,51 @@ internal sealed class AdminNameOverlay : Overlay
|
|||||||
|
|
||||||
var currentOffset = Vector2.Zero;
|
var currentOffset = Vector2.Zero;
|
||||||
|
|
||||||
|
// Character name
|
||||||
args.ScreenHandle.DrawString(_font, screenCoordinates + currentOffset, playerInfo.CharacterName, uiScale, playerInfo.Connected ? Color.Aquamarine : Color.White);
|
args.ScreenHandle.DrawString(_font, screenCoordinates + currentOffset, playerInfo.CharacterName, uiScale, playerInfo.Connected ? Color.Aquamarine : Color.White);
|
||||||
currentOffset += lineoffset;
|
currentOffset += lineoffset;
|
||||||
|
|
||||||
|
// Username
|
||||||
args.ScreenHandle.DrawString(_font, screenCoordinates + currentOffset, playerInfo.Username, uiScale, playerInfo.Connected ? Color.Yellow : Color.White);
|
args.ScreenHandle.DrawString(_font, screenCoordinates + currentOffset, playerInfo.Username, uiScale, playerInfo.Connected ? Color.Yellow : Color.White);
|
||||||
currentOffset += lineoffset;
|
currentOffset += lineoffset;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(playerInfo.PlaytimeString) && playTime)
|
// Playtime
|
||||||
|
if (!string.IsNullOrEmpty(playerInfo.PlaytimeString) && _overlayPlaytime)
|
||||||
{
|
{
|
||||||
args.ScreenHandle.DrawString(_font, screenCoordinates + currentOffset, playerInfo.PlaytimeString, uiScale, playerInfo.Connected ? Color.Orange : Color.White);
|
args.ScreenHandle.DrawString(_font, screenCoordinates + currentOffset, playerInfo.PlaytimeString, uiScale, playerInfo.Connected ? Color.Orange : Color.White);
|
||||||
currentOffset += lineoffset;
|
currentOffset += lineoffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(playerInfo.StartingJob) && startingJob)
|
// Job
|
||||||
|
if (!string.IsNullOrEmpty(playerInfo.StartingJob) && _overlayStartingJob)
|
||||||
{
|
{
|
||||||
args.ScreenHandle.DrawString(_font, screenCoordinates + currentOffset, Loc.GetString(playerInfo.StartingJob), uiScale, playerInfo.Connected ? Color.GreenYellow : Color.White);
|
args.ScreenHandle.DrawString(_font, screenCoordinates + currentOffset, Loc.GetString(playerInfo.StartingJob), uiScale, playerInfo.Connected ? Color.GreenYellow : Color.White);
|
||||||
currentOffset += lineoffset;
|
currentOffset += lineoffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classic && playerInfo.Antag)
|
// Classic Antag Label
|
||||||
|
if (_overlayClassic && playerInfo.Antag)
|
||||||
{
|
{
|
||||||
args.ScreenHandle.DrawString(_font, screenCoordinates + currentOffset, _antagLabelClassic, uiScale, Color.OrangeRed);
|
var symbol = _overlaySymbols ? Loc.GetString("player-tab-antag-prefix") : string.Empty;
|
||||||
|
var label = _overlaySymbols
|
||||||
|
? Loc.GetString("player-tab-character-name-antag-symbol",
|
||||||
|
("symbol", symbol),
|
||||||
|
("name", _antagLabelClassic))
|
||||||
|
: _antagLabelClassic;
|
||||||
|
args.ScreenHandle.DrawString(_fontBold, screenCoordinates + currentOffset, label, uiScale, _antagColorClassic);
|
||||||
currentOffset += lineoffset;
|
currentOffset += lineoffset;
|
||||||
}
|
}
|
||||||
else if (!classic && _filter.Contains(playerInfo.RoleProto))
|
// Role Type
|
||||||
|
else if (!_overlayClassic && _filter.Contains(playerInfo.RoleProto))
|
||||||
{
|
{
|
||||||
var label = Loc.GetString(playerInfo.RoleProto.Name).ToUpper();
|
var symbol = _overlaySymbols && playerInfo.Antag ? playerInfo.RoleProto.Symbol : string.Empty;
|
||||||
|
var role = Loc.GetString(playerInfo.RoleProto.Name).ToUpper();
|
||||||
|
var label = _overlaySymbols
|
||||||
|
? Loc.GetString("player-tab-character-name-antag-symbol", ("symbol", symbol), ("name", role))
|
||||||
|
: role;
|
||||||
var color = playerInfo.RoleProto.Color;
|
var color = playerInfo.RoleProto.Color;
|
||||||
|
|
||||||
args.ScreenHandle.DrawString(_font, screenCoordinates + currentOffset, label, uiScale, color);
|
args.ScreenHandle.DrawString(_fontBold, screenCoordinates + currentOffset, label, uiScale, color);
|
||||||
currentOffset += lineoffset;
|
currentOffset += lineoffset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ namespace Content.Client.Administration.Systems
|
|||||||
[Dependency] private readonly IEyeManager _eyeManager = default!;
|
[Dependency] private readonly IEyeManager _eyeManager = default!;
|
||||||
[Dependency] private readonly EntityLookupSystem _entityLookup = default!;
|
[Dependency] private readonly EntityLookupSystem _entityLookup = default!;
|
||||||
[Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!;
|
[Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!;
|
||||||
|
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
|
||||||
|
|
||||||
private AdminNameOverlay _adminNameOverlay = default!;
|
private AdminNameOverlay _adminNameOverlay = default!;
|
||||||
|
|
||||||
@@ -22,7 +23,14 @@ namespace Content.Client.Administration.Systems
|
|||||||
|
|
||||||
private void InitializeOverlay()
|
private void InitializeOverlay()
|
||||||
{
|
{
|
||||||
_adminNameOverlay = new AdminNameOverlay(this, EntityManager, _eyeManager, _resourceCache, _entityLookup, _userInterfaceManager);
|
_adminNameOverlay = new AdminNameOverlay(
|
||||||
|
this,
|
||||||
|
EntityManager,
|
||||||
|
_eyeManager,
|
||||||
|
_resourceCache,
|
||||||
|
_entityLookup,
|
||||||
|
_userInterfaceManager,
|
||||||
|
_configurationManager);
|
||||||
_adminManager.AdminStatusUpdated += OnAdminStatusUpdated;
|
_adminManager.AdminStatusUpdated += OnAdminStatusUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,13 @@ using System.Linq;
|
|||||||
using Content.Client.Administration.Systems;
|
using Content.Client.Administration.Systems;
|
||||||
using Content.Client.UserInterface.Controls;
|
using Content.Client.UserInterface.Controls;
|
||||||
using Content.Shared.Administration;
|
using Content.Shared.Administration;
|
||||||
|
using Content.Shared.CCVar;
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
using Robust.Client.Player;
|
using Robust.Client.Player;
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
|
using Robust.Shared.Configuration;
|
||||||
using static Content.Client.Administration.UI.Tabs.PlayerTab.PlayerTabHeader;
|
using static Content.Client.Administration.UI.Tabs.PlayerTab.PlayerTabHeader;
|
||||||
using static Robust.Client.UserInterface.Controls.BaseButton;
|
using static Robust.Client.UserInterface.Controls.BaseButton;
|
||||||
|
|
||||||
@@ -16,6 +18,7 @@ namespace Content.Client.Administration.UI.Tabs.PlayerTab;
|
|||||||
public sealed partial class PlayerTab : Control
|
public sealed partial class PlayerTab : Control
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IEntityManager _entManager = default!;
|
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||||
|
[Dependency] private readonly IConfigurationManager _config = default!;
|
||||||
[Dependency] private readonly IPlayerManager _playerMan = default!;
|
[Dependency] private readonly IPlayerManager _playerMan = default!;
|
||||||
|
|
||||||
private const string ArrowUp = "↑";
|
private const string ArrowUp = "↑";
|
||||||
@@ -41,6 +44,10 @@ public sealed partial class PlayerTab : Control
|
|||||||
_adminSystem.OverlayEnabled += OverlayEnabled;
|
_adminSystem.OverlayEnabled += OverlayEnabled;
|
||||||
_adminSystem.OverlayDisabled += OverlayDisabled;
|
_adminSystem.OverlayDisabled += OverlayDisabled;
|
||||||
|
|
||||||
|
_config.OnValueChanged(CCVars.AdminPlayerlistSeparateSymbols, PlayerListSettingsChanged);
|
||||||
|
_config.OnValueChanged(CCVars.AdminPlayerlistHighlightedCharacterColor, PlayerListSettingsChanged);
|
||||||
|
_config.OnValueChanged(CCVars.AdminPlayerlistRoleTypeColor, PlayerListSettingsChanged);
|
||||||
|
|
||||||
OverlayButton.OnPressed += OverlayButtonPressed;
|
OverlayButton.OnPressed += OverlayButtonPressed;
|
||||||
ShowDisconnectedButton.OnPressed += ShowDisconnectedPressed;
|
ShowDisconnectedButton.OnPressed += ShowDisconnectedPressed;
|
||||||
|
|
||||||
@@ -106,6 +113,11 @@ public sealed partial class PlayerTab : Control
|
|||||||
|
|
||||||
#region ListContainer
|
#region ListContainer
|
||||||
|
|
||||||
|
private void PlayerListSettingsChanged(bool _)
|
||||||
|
{
|
||||||
|
RefreshPlayerList(_adminSystem.PlayerList);
|
||||||
|
}
|
||||||
|
|
||||||
private void RefreshPlayerList(IReadOnlyList<PlayerInfo> players)
|
private void RefreshPlayerList(IReadOnlyList<PlayerInfo> players)
|
||||||
{
|
{
|
||||||
_players = players;
|
_players = players;
|
||||||
@@ -196,8 +208,7 @@ public sealed partial class PlayerTab : Control
|
|||||||
Header.Username => Compare(x.Username, y.Username),
|
Header.Username => Compare(x.Username, y.Username),
|
||||||
Header.Character => Compare(x.CharacterName, y.CharacterName),
|
Header.Character => Compare(x.CharacterName, y.CharacterName),
|
||||||
Header.Job => Compare(x.StartingJob, y.StartingJob),
|
Header.Job => Compare(x.StartingJob, y.StartingJob),
|
||||||
Header.Antagonist => x.Antag.CompareTo(y.Antag),
|
Header.RoleType => y.SortWeight - x.SortWeight,
|
||||||
Header.RoleType => Compare(x.RoleProto.Name , y.RoleProto.Name),
|
|
||||||
Header.Playtime => TimeSpan.Compare(x.OverallPlaytime ?? default, y.OverallPlaytime ?? default),
|
Header.Playtime => TimeSpan.Compare(x.OverallPlaytime ?? default, y.OverallPlaytime ?? default),
|
||||||
_ => 1
|
_ => 1
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,11 +19,6 @@
|
|||||||
HorizontalExpand="True"
|
HorizontalExpand="True"
|
||||||
ClipText="True"/>
|
ClipText="True"/>
|
||||||
<customControls:VSeparator/>
|
<customControls:VSeparator/>
|
||||||
<Label Name="AntagonistLabel"
|
|
||||||
SizeFlagsStretchRatio="1"
|
|
||||||
HorizontalExpand="True"
|
|
||||||
ClipText="True"/>
|
|
||||||
<customControls:VSeparator/>
|
|
||||||
<Label Name="RoleTypeLabel"
|
<Label Name="RoleTypeLabel"
|
||||||
SizeFlagsStretchRatio="2"
|
SizeFlagsStretchRatio="2"
|
||||||
HorizontalExpand="True"
|
HorizontalExpand="True"
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
using Content.Shared.Administration;
|
using Content.Shared.Administration;
|
||||||
|
using Content.Shared.CCVar;
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
|
using Robust.Shared.Configuration;
|
||||||
|
|
||||||
namespace Content.Client.Administration.UI.Tabs.PlayerTab;
|
namespace Content.Client.Administration.UI.Tabs.PlayerTab;
|
||||||
|
|
||||||
@@ -14,16 +16,24 @@ public sealed partial class PlayerTabEntry : PanelContainer
|
|||||||
public PlayerTabEntry(PlayerInfo player, StyleBoxFlat styleBoxFlat)
|
public PlayerTabEntry(PlayerInfo player, StyleBoxFlat styleBoxFlat)
|
||||||
{
|
{
|
||||||
RobustXamlLoader.Load(this);
|
RobustXamlLoader.Load(this);
|
||||||
|
var config = IoCManager.Resolve<IConfigurationManager>();
|
||||||
|
|
||||||
UsernameLabel.Text = player.Username;
|
UsernameLabel.Text = player.Username;
|
||||||
if (!player.Connected)
|
if (!player.Connected)
|
||||||
UsernameLabel.StyleClasses.Add("Disabled");
|
UsernameLabel.StyleClasses.Add("Disabled");
|
||||||
JobLabel.Text = player.StartingJob;
|
JobLabel.Text = player.StartingJob;
|
||||||
CharacterLabel.Text = player.CharacterName;
|
var separateAntagSymbols = config.GetCVar(CCVars.AdminPlayerlistSeparateSymbols);
|
||||||
|
var genericAntagSymbol = player.Antag ? Loc.GetString("player-tab-antag-prefix") : string.Empty;
|
||||||
|
var roleSymbol = player.Antag ? player.RoleProto.Symbol : string.Empty;
|
||||||
|
var symbol = separateAntagSymbols ? roleSymbol : genericAntagSymbol;
|
||||||
|
CharacterLabel.Text = Loc.GetString("player-tab-character-name-antag-symbol", ("symbol", symbol), ("name", player.CharacterName));
|
||||||
|
|
||||||
|
if (player.Antag && config.GetCVar(CCVars.AdminPlayerlistHighlightedCharacterColor))
|
||||||
|
CharacterLabel.FontColorOverride = player.RoleProto.Color;
|
||||||
if (player.IdentityName != player.CharacterName)
|
if (player.IdentityName != player.CharacterName)
|
||||||
CharacterLabel.Text += $" [{player.IdentityName}]";
|
CharacterLabel.Text += $" [{player.IdentityName}]";
|
||||||
AntagonistLabel.Text = Loc.GetString(player.Antag ? "player-tab-is-antag-yes" : "player-tab-is-antag-no");
|
|
||||||
RoleTypeLabel.Text = Loc.GetString(player.RoleProto.Name);
|
RoleTypeLabel.Text = Loc.GetString(player.RoleProto.Name);
|
||||||
|
if (config.GetCVar(CCVars.AdminPlayerlistRoleTypeColor))
|
||||||
RoleTypeLabel.FontColorOverride = player.RoleProto.Color;
|
RoleTypeLabel.FontColorOverride = player.RoleProto.Color;
|
||||||
BackgroundColorPanel.PanelOverride = styleBoxFlat;
|
BackgroundColorPanel.PanelOverride = styleBoxFlat;
|
||||||
OverallPlaytimeLabel.Text = player.PlaytimeString;
|
OverallPlaytimeLabel.Text = player.PlaytimeString;
|
||||||
|
|||||||
@@ -25,13 +25,6 @@
|
|||||||
Text="{Loc player-tab-job}"
|
Text="{Loc player-tab-job}"
|
||||||
MouseFilter="Pass"/>
|
MouseFilter="Pass"/>
|
||||||
<cc:VSeparator/>
|
<cc:VSeparator/>
|
||||||
<Label Name="AntagonistLabel"
|
|
||||||
SizeFlagsStretchRatio="1"
|
|
||||||
HorizontalExpand="True"
|
|
||||||
ClipText="True"
|
|
||||||
Text="{Loc player-tab-antagonist}"
|
|
||||||
MouseFilter="Pass"/>
|
|
||||||
<cc:VSeparator/>
|
|
||||||
<Label Name="RoleTypeLabel"
|
<Label Name="RoleTypeLabel"
|
||||||
SizeFlagsStretchRatio="2"
|
SizeFlagsStretchRatio="2"
|
||||||
HorizontalExpand="True"
|
HorizontalExpand="True"
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ public sealed partial class PlayerTabHeader : Control
|
|||||||
UsernameLabel.OnKeyBindDown += UsernameClicked;
|
UsernameLabel.OnKeyBindDown += UsernameClicked;
|
||||||
CharacterLabel.OnKeyBindDown += CharacterClicked;
|
CharacterLabel.OnKeyBindDown += CharacterClicked;
|
||||||
JobLabel.OnKeyBindDown += JobClicked;
|
JobLabel.OnKeyBindDown += JobClicked;
|
||||||
AntagonistLabel.OnKeyBindDown += AntagonistClicked;
|
|
||||||
RoleTypeLabel.OnKeyBindDown += RoleTypeClicked;
|
RoleTypeLabel.OnKeyBindDown += RoleTypeClicked;
|
||||||
PlaytimeLabel.OnKeyBindDown += PlaytimeClicked;
|
PlaytimeLabel.OnKeyBindDown += PlaytimeClicked;
|
||||||
}
|
}
|
||||||
@@ -30,7 +29,6 @@ public sealed partial class PlayerTabHeader : Control
|
|||||||
Header.Username => UsernameLabel,
|
Header.Username => UsernameLabel,
|
||||||
Header.Character => CharacterLabel,
|
Header.Character => CharacterLabel,
|
||||||
Header.Job => JobLabel,
|
Header.Job => JobLabel,
|
||||||
Header.Antagonist => AntagonistLabel,
|
|
||||||
Header.RoleType => RoleTypeLabel,
|
Header.RoleType => RoleTypeLabel,
|
||||||
Header.Playtime => PlaytimeLabel,
|
Header.Playtime => PlaytimeLabel,
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(header), header, null)
|
_ => throw new ArgumentOutOfRangeException(nameof(header), header, null)
|
||||||
@@ -42,7 +40,6 @@ public sealed partial class PlayerTabHeader : Control
|
|||||||
UsernameLabel.Text = Loc.GetString("player-tab-username");
|
UsernameLabel.Text = Loc.GetString("player-tab-username");
|
||||||
CharacterLabel.Text = Loc.GetString("player-tab-character");
|
CharacterLabel.Text = Loc.GetString("player-tab-character");
|
||||||
JobLabel.Text = Loc.GetString("player-tab-job");
|
JobLabel.Text = Loc.GetString("player-tab-job");
|
||||||
AntagonistLabel.Text = Loc.GetString("player-tab-antagonist");
|
|
||||||
RoleTypeLabel.Text = Loc.GetString("player-tab-roletype");
|
RoleTypeLabel.Text = Loc.GetString("player-tab-roletype");
|
||||||
PlaytimeLabel.Text = Loc.GetString("player-tab-playtime");
|
PlaytimeLabel.Text = Loc.GetString("player-tab-playtime");
|
||||||
}
|
}
|
||||||
@@ -73,11 +70,6 @@ public sealed partial class PlayerTabHeader : Control
|
|||||||
HeaderClicked(args, Header.Job);
|
HeaderClicked(args, Header.Job);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AntagonistClicked(GUIBoundKeyEventArgs args)
|
|
||||||
{
|
|
||||||
HeaderClicked(args, Header.Antagonist);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RoleTypeClicked(GUIBoundKeyEventArgs args)
|
private void RoleTypeClicked(GUIBoundKeyEventArgs args)
|
||||||
{
|
{
|
||||||
HeaderClicked(args, Header.RoleType);
|
HeaderClicked(args, Header.RoleType);
|
||||||
@@ -97,7 +89,6 @@ public sealed partial class PlayerTabHeader : Control
|
|||||||
UsernameLabel.OnKeyBindDown -= UsernameClicked;
|
UsernameLabel.OnKeyBindDown -= UsernameClicked;
|
||||||
CharacterLabel.OnKeyBindDown -= CharacterClicked;
|
CharacterLabel.OnKeyBindDown -= CharacterClicked;
|
||||||
JobLabel.OnKeyBindDown -= JobClicked;
|
JobLabel.OnKeyBindDown -= JobClicked;
|
||||||
AntagonistLabel.OnKeyBindDown -= AntagonistClicked;
|
|
||||||
RoleTypeLabel.OnKeyBindDown -= RoleTypeClicked;
|
RoleTypeLabel.OnKeyBindDown -= RoleTypeClicked;
|
||||||
PlaytimeLabel.OnKeyBindDown -= PlaytimeClicked;
|
PlaytimeLabel.OnKeyBindDown -= PlaytimeClicked;
|
||||||
}
|
}
|
||||||
@@ -108,7 +99,6 @@ public sealed partial class PlayerTabHeader : Control
|
|||||||
Username,
|
Username,
|
||||||
Character,
|
Character,
|
||||||
Job,
|
Job,
|
||||||
Antagonist,
|
|
||||||
RoleType,
|
RoleType,
|
||||||
Playtime
|
Playtime
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,19 @@
|
|||||||
xmlns:ui="clr-namespace:Content.Client.Options.UI">
|
xmlns:ui="clr-namespace:Content.Client.Options.UI">
|
||||||
<BoxContainer Orientation="Vertical">
|
<BoxContainer Orientation="Vertical">
|
||||||
<ScrollContainer VerticalExpand="True" HScrollEnabled="False">
|
<ScrollContainer VerticalExpand="True" HScrollEnabled="False">
|
||||||
|
|
||||||
<BoxContainer Orientation="Vertical" Margin="8">
|
<BoxContainer Orientation="Vertical" Margin="8">
|
||||||
|
<Label Text="{Loc 'ui-options-admin-player-panel'}"
|
||||||
|
StyleClasses="LabelKeyText"/>
|
||||||
|
<CheckBox Name="PlayerlistSeparateSymbolsCheckBox" Text="{Loc 'ui-options-admin-playerlist-separate-symbols'}" />
|
||||||
|
<CheckBox Name="PlayerlistCharacterColorCheckBox" Text="{Loc 'ui-options-admin-playerlist-character-color'}" />
|
||||||
|
<CheckBox Name="PlayerlistRoleTypeColorCheckBox" Text="{Loc 'ui-options-admin-playerlist-roletype-color'}" />
|
||||||
|
<Label Text="{Loc 'ui-options-admin-overlay-title'}"
|
||||||
|
StyleClasses="LabelKeyText"/>
|
||||||
<CheckBox Name="EnableClassicOverlayCheckBox" Text="{Loc 'ui-options-enable-classic-overlay'}" />
|
<CheckBox Name="EnableClassicOverlayCheckBox" Text="{Loc 'ui-options-enable-classic-overlay'}" />
|
||||||
|
<CheckBox Name="EnableOverlaySymbolsCheckBox" Text="{Loc 'ui-options-enable-overlay-symbols'}" />
|
||||||
|
<CheckBox Name="EnableOverlayPlaytimeCheckBox" Text="{Loc 'ui-options-enable-overlay-playtime'}" />
|
||||||
|
<CheckBox Name="EnableOverlayStartingJobCheckBox" Text="{Loc 'ui-options-enable-overlay-starting-job'}" />
|
||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
</ScrollContainer>
|
</ScrollContainer>
|
||||||
<ui:OptionsTabControlRow Name="Control" Access="Public" />
|
<ui:OptionsTabControlRow Name="Control" Access="Public" />
|
||||||
|
|||||||
@@ -12,7 +12,14 @@ public sealed partial class AdminOptionsTab : Control
|
|||||||
{
|
{
|
||||||
RobustXamlLoader.Load(this);
|
RobustXamlLoader.Load(this);
|
||||||
|
|
||||||
|
Control.AddOptionCheckBox(CCVars.AdminPlayerlistSeparateSymbols, PlayerlistSeparateSymbolsCheckBox);
|
||||||
|
Control.AddOptionCheckBox(CCVars.AdminPlayerlistHighlightedCharacterColor, PlayerlistCharacterColorCheckBox);
|
||||||
|
Control.AddOptionCheckBox(CCVars.AdminPlayerlistRoleTypeColor, PlayerlistRoleTypeColorCheckBox);
|
||||||
|
|
||||||
Control.AddOptionCheckBox(CCVars.AdminOverlayClassic, EnableClassicOverlayCheckBox);
|
Control.AddOptionCheckBox(CCVars.AdminOverlayClassic, EnableClassicOverlayCheckBox);
|
||||||
|
Control.AddOptionCheckBox(CCVars.AdminOverlaySymbols, EnableOverlaySymbolsCheckBox);
|
||||||
|
Control.AddOptionCheckBox(CCVars.AdminOverlayPlaytime, EnableOverlayPlaytimeCheckBox);
|
||||||
|
Control.AddOptionCheckBox(CCVars.AdminOverlayStartingJob, EnableOverlayStartingJobCheckBox);
|
||||||
|
|
||||||
Control.Initialize();
|
Control.Initialize();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -221,6 +221,7 @@ public sealed class AdminSystem : EntitySystem
|
|||||||
var name = data.UserName;
|
var name = data.UserName;
|
||||||
var entityName = string.Empty;
|
var entityName = string.Empty;
|
||||||
var identityName = string.Empty;
|
var identityName = string.Empty;
|
||||||
|
var sortWeight = 0;
|
||||||
|
|
||||||
// Visible (identity) name can be different from real name
|
// Visible (identity) name can be different from real name
|
||||||
if (session?.AttachedEntity != null)
|
if (session?.AttachedEntity != null)
|
||||||
@@ -234,8 +235,10 @@ public sealed class AdminSystem : EntitySystem
|
|||||||
// Starting role, antagonist status and role type
|
// Starting role, antagonist status and role type
|
||||||
RoleTypePrototype roleType = new();
|
RoleTypePrototype roleType = new();
|
||||||
var startingRole = string.Empty;
|
var startingRole = string.Empty;
|
||||||
if (_minds.TryGetMind(session, out var mindId, out var mindComp))
|
if (_minds.TryGetMind(session, out var mindId, out var mindComp) && mindComp is not null)
|
||||||
{
|
{
|
||||||
|
sortWeight = _role.GetRoleCompByTime(mindComp)?.Comp.SortWeight ?? 0;
|
||||||
|
|
||||||
if (_proto.TryIndex(mindComp.RoleType, out var role))
|
if (_proto.TryIndex(mindComp.RoleType, out var role))
|
||||||
roleType = role;
|
roleType = role;
|
||||||
else
|
else
|
||||||
@@ -259,8 +262,19 @@ public sealed class AdminSystem : EntitySystem
|
|||||||
overallPlaytime = playTime;
|
overallPlaytime = playTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new PlayerInfo(name, entityName, identityName, startingRole, antag, roleType, GetNetEntity(session?.AttachedEntity), data.UserId,
|
return new PlayerInfo(
|
||||||
connected, _roundActivePlayers.Contains(data.UserId), overallPlaytime);
|
name,
|
||||||
|
entityName,
|
||||||
|
identityName,
|
||||||
|
startingRole,
|
||||||
|
antag,
|
||||||
|
roleType,
|
||||||
|
sortWeight,
|
||||||
|
GetNetEntity(session?.AttachedEntity),
|
||||||
|
data.UserId,
|
||||||
|
connected,
|
||||||
|
_roundActivePlayers.Contains(data.UserId),
|
||||||
|
overallPlaytime);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPanicBunkerChanged(bool enabled)
|
private void OnPanicBunkerChanged(bool enabled)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ public sealed record PlayerInfo(
|
|||||||
string StartingJob,
|
string StartingJob,
|
||||||
bool Antag,
|
bool Antag,
|
||||||
RoleTypePrototype RoleProto,
|
RoleTypePrototype RoleProto,
|
||||||
|
int SortWeight,
|
||||||
NetEntity? NetEntity,
|
NetEntity? NetEntity,
|
||||||
NetUserId SessionId,
|
NetUserId SessionId,
|
||||||
bool Connected,
|
bool Connected,
|
||||||
|
|||||||
@@ -47,11 +47,35 @@ public sealed partial class CCVars
|
|||||||
/// If true, the admin overlay will display the total time of the players
|
/// If true, the admin overlay will display the total time of the players
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly CVarDef<bool> AdminOverlayPlaytime =
|
public static readonly CVarDef<bool> AdminOverlayPlaytime =
|
||||||
CVarDef.Create("ui.admin_overlay_playtime", false, CVar.CLIENTONLY | CVar.ARCHIVE);
|
CVarDef.Create("ui.admin_overlay_playtime", true, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If true, the admin overlay will display the players starting position.
|
/// If true, the admin overlay will display the players starting position.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly CVarDef<bool> AdminOverlayStartingJob =
|
public static readonly CVarDef<bool> AdminOverlayStartingJob =
|
||||||
CVarDef.Create("ui.admin_overlay_starting_job", false, CVar.CLIENTONLY | CVar.ARCHIVE);
|
CVarDef.Create("ui.admin_overlay_starting_job", true, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If true, the admin window player tab will show different antag symbols for each role type
|
||||||
|
/// </summary>
|
||||||
|
public static readonly CVarDef<bool> AdminPlayerlistSeparateSymbols =
|
||||||
|
CVarDef.Create("ui.admin_playerlist_separate_symbols", false, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If true, characters with antag role types will have their names colored by their role type
|
||||||
|
/// </summary>
|
||||||
|
public static readonly CVarDef<bool> AdminPlayerlistHighlightedCharacterColor =
|
||||||
|
CVarDef.Create("ui.admin_playerlist_highlighted_character_color", true, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If true, the Role Types column will be colored
|
||||||
|
/// </summary>
|
||||||
|
public static readonly CVarDef<bool> AdminPlayerlistRoleTypeColor =
|
||||||
|
CVarDef.Create("ui.admin_playerlist_role_type_color", true, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If true, the admin overlay will show antag symbols
|
||||||
|
/// </summary>
|
||||||
|
public static readonly CVarDef<bool> AdminOverlaySymbols =
|
||||||
|
CVarDef.Create("ui.admin_overlay_symbols", true, CVar.CLIENTONLY | CVar.ARCHIVE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,4 +22,10 @@ public sealed partial class RoleTypePrototype : IPrototype
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField]
|
[DataField]
|
||||||
public Color Color { get; private set; } = Color.FromHex("#eeeeee");
|
public Color Color { get; private set; } = Color.FromHex("#eeeeee");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A symbol used to represent the role type.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public string Symbol = string.Empty;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,12 @@ public sealed partial class MindRoleComponent : BaseMindRoleComponent
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField]
|
[DataField]
|
||||||
public ProtoId<JobPrototype>? JobPrototype { get; set; }
|
public ProtoId<JobPrototype>? JobPrototype { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used to order the characters on by role/antag status. Highest numbers are shown first.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public int SortWeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Why does this base component actually exist? It does make auto-categorization easy, but before that it was useless?
|
// Why does this base component actually exist? It does make auto-categorization easy, but before that it was useless?
|
||||||
|
|||||||
@@ -211,20 +211,30 @@ public abstract class SharedRoleSystem : EntitySystem
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return the most recently specified role type, or Neutral
|
||||||
|
/// </summary>
|
||||||
private ProtoId<RoleTypePrototype> GetRoleTypeByTime(MindComponent mind)
|
private ProtoId<RoleTypePrototype> GetRoleTypeByTime(MindComponent mind)
|
||||||
{
|
{
|
||||||
// If any Mind Roles specify a Role Type, return the most recent. Otherwise return Neutral
|
var role = GetRoleCompByTime(mind);
|
||||||
|
return role?.Comp?.RoleType ?? "Neutral";
|
||||||
|
}
|
||||||
|
|
||||||
var roles = new List<ProtoId<RoleTypePrototype>>();
|
/// <summary>
|
||||||
|
/// Return the most recently specified role type's mind role entity, or null
|
||||||
|
/// </summary>
|
||||||
|
public Entity<MindRoleComponent>? GetRoleCompByTime(MindComponent mind)
|
||||||
|
{
|
||||||
|
var roles = new List<Entity<MindRoleComponent>>();
|
||||||
|
|
||||||
foreach (var role in mind.MindRoles)
|
foreach (var role in mind.MindRoles)
|
||||||
{
|
{
|
||||||
var comp = Comp<MindRoleComponent>(role);
|
var comp = Comp<MindRoleComponent>(role);
|
||||||
if (comp.RoleType is not null)
|
if (comp.RoleType is not null)
|
||||||
roles.Add(comp.RoleType.Value);
|
roles.Add((role, comp));
|
||||||
}
|
}
|
||||||
|
|
||||||
ProtoId<RoleTypePrototype> result = (roles.Count > 0) ? roles.LastOrDefault() : "Neutral";
|
Entity<MindRoleComponent>? result = roles.Count > 0 ? roles.LastOrDefault() : null;
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
player-tab-username = Username
|
player-tab-username = Username
|
||||||
player-tab-character = Character
|
player-tab-character = Character
|
||||||
player-tab-job = Job
|
player-tab-job = Job
|
||||||
player-tab-antagonist = Antagonist
|
|
||||||
player-tab-roletype = Role Type
|
player-tab-roletype = Role Type
|
||||||
player-tab-playtime = Playtime
|
player-tab-playtime = Playtime
|
||||||
player-tab-show-disconnected = Show Disconnected
|
player-tab-show-disconnected = Show Disconnected
|
||||||
@@ -11,3 +10,7 @@ player-tab-entry-tooltip = Playtime is displayed in days:hours:minutes.
|
|||||||
player-tab-filter-line-edit-placeholder = Filter
|
player-tab-filter-line-edit-placeholder = Filter
|
||||||
player-tab-is-antag-yes = YES
|
player-tab-is-antag-yes = YES
|
||||||
player-tab-is-antag-no = NO
|
player-tab-is-antag-no = NO
|
||||||
|
|
||||||
|
player-tab-character-name-antag-symbol = {$symbol} {$name}
|
||||||
|
|
||||||
|
player-tab-antag-prefix = 🗡
|
||||||
|
|||||||
@@ -337,4 +337,14 @@ ui-options-censor-nudity = Censor character nudity
|
|||||||
|
|
||||||
## Admin menu
|
## Admin menu
|
||||||
|
|
||||||
ui-options-enable-classic-overlay = Revert antag overlay to classic mode
|
ui-options-admin-player-panel = Admin Menu Players List
|
||||||
|
|
||||||
|
ui-options-admin-playerlist-separate-symbols = Show separate symbols for each antag role type
|
||||||
|
ui-options-admin-playerlist-character-color = Color names of antagonist characters
|
||||||
|
ui-options-admin-playerlist-roletype-color = Color role types
|
||||||
|
|
||||||
|
ui-options-admin-overlay-title = Admin Overlay
|
||||||
|
ui-options-enable-classic-overlay = Revert overlay to classic mode
|
||||||
|
ui-options-enable-overlay-symbols = Add antag symbol to text
|
||||||
|
ui-options-enable-overlay-playtime = Show playtime
|
||||||
|
ui-options-enable-overlay-starting-job = Show starting job
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
antag: true
|
antag: true
|
||||||
antagPrototype: GenericAntagonist
|
antagPrototype: GenericAntagonist
|
||||||
roleType: SoloAntagonist
|
roleType: SoloAntagonist
|
||||||
|
sortWeight: 50
|
||||||
|
|
||||||
#Observer
|
#Observer
|
||||||
- type: entity
|
- type: entity
|
||||||
@@ -23,6 +24,8 @@
|
|||||||
name: Observer Role
|
name: Observer Role
|
||||||
components:
|
components:
|
||||||
- type: ObserverRole
|
- type: ObserverRole
|
||||||
|
- type: MindRole
|
||||||
|
sortWeight: -10
|
||||||
|
|
||||||
#Ghost Roles
|
#Ghost Roles
|
||||||
- type: entity
|
- type: entity
|
||||||
@@ -48,6 +51,7 @@
|
|||||||
- type: MindRole
|
- type: MindRole
|
||||||
roleType: FreeAgent
|
roleType: FreeAgent
|
||||||
antagPrototype: GenericFreeAgent
|
antagPrototype: GenericFreeAgent
|
||||||
|
sortWeight: 30
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: MindRoleGhostRoleNeutral
|
parent: MindRoleGhostRoleNeutral
|
||||||
@@ -56,6 +60,7 @@
|
|||||||
components:
|
components:
|
||||||
- type: MindRole
|
- type: MindRole
|
||||||
roleType: FreeAgent
|
roleType: FreeAgent
|
||||||
|
sortWeight: 0 # Maybe 10?
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: MindRoleGhostRoleNeutral
|
parent: MindRoleGhostRoleNeutral
|
||||||
@@ -73,6 +78,7 @@
|
|||||||
- type: MindRole
|
- type: MindRole
|
||||||
roleType: SiliconAntagonist
|
roleType: SiliconAntagonist
|
||||||
antagPrototype: GenericSiliconAntagonist
|
antagPrototype: GenericSiliconAntagonist
|
||||||
|
sortWeight: 30
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: [ BaseMindRoleAntag, MindRoleGhostRoleNeutral ]
|
parent: [ BaseMindRoleAntag, MindRoleGhostRoleNeutral ]
|
||||||
@@ -94,6 +100,9 @@
|
|||||||
parent: MindRoleGhostRoleTeamAntagonist
|
parent: MindRoleGhostRoleTeamAntagonist
|
||||||
id: MindRoleGhostRoleTeamAntagonistFlock
|
id: MindRoleGhostRoleTeamAntagonistFlock
|
||||||
name: Ghost Role (Team Antagonist)
|
name: Ghost Role (Team Antagonist)
|
||||||
|
components:
|
||||||
|
- type: MindRole
|
||||||
|
sortWeight: 40
|
||||||
|
|
||||||
# The Job MindRole holds the mob's Job prototype
|
# The Job MindRole holds the mob's Job prototype
|
||||||
- type: entity
|
- type: entity
|
||||||
|
|||||||
@@ -5,34 +5,40 @@
|
|||||||
id: Neutral
|
id: Neutral
|
||||||
name: role-type-crew-aligned-name
|
name: role-type-crew-aligned-name
|
||||||
color: '#eeeeee'
|
color: '#eeeeee'
|
||||||
|
symbol: "🗡" # Should never be antag, but just in case.
|
||||||
|
|
||||||
- type: roleType
|
- type: roleType
|
||||||
id: SoloAntagonist
|
id: SoloAntagonist
|
||||||
name: role-type-solo-antagonist-name
|
name: role-type-solo-antagonist-name
|
||||||
color: '#d82000'
|
color: '#d82000'
|
||||||
|
symbol: "🗡"
|
||||||
|
|
||||||
- type: roleType
|
- type: roleType
|
||||||
id: TeamAntagonist
|
id: TeamAntagonist
|
||||||
name: role-type-team-antagonist-name
|
name: role-type-team-antagonist-name
|
||||||
color: '#d82000'
|
color: '#d82000'
|
||||||
|
symbol: "⚔"
|
||||||
|
|
||||||
- type: roleType
|
- type: roleType
|
||||||
id: FreeAgent
|
id: FreeAgent
|
||||||
name: role-type-free-agent-name
|
name: role-type-free-agent-name
|
||||||
color: '#ffff00'
|
color: '#ffff00'
|
||||||
|
symbol: "☯"
|
||||||
|
|
||||||
- type: roleType
|
- type: roleType
|
||||||
id: Familiar
|
id: Familiar
|
||||||
name: role-type-familiar-name
|
name: role-type-familiar-name
|
||||||
color: '#6495ed'
|
color: '#6495ed'
|
||||||
|
symbol: "🗡" # Should never be antag, but just in case.
|
||||||
|
|
||||||
- type: roleType
|
- type: roleType
|
||||||
id: Silicon
|
id: Silicon
|
||||||
name: role-type-silicon-name
|
name: role-type-silicon-name
|
||||||
color: '#6495ed'
|
color: '#6495ed'
|
||||||
|
symbol: "🗡" # Should never be antag, but just in case.
|
||||||
|
|
||||||
- type: roleType
|
- type: roleType
|
||||||
id: SiliconAntagonist
|
id: SiliconAntagonist
|
||||||
name: role-type-silicon-antagonist-name
|
name: role-type-silicon-antagonist-name
|
||||||
color: '#c832e6'
|
color: '#c832e6'
|
||||||
|
symbol: "⛞"
|
||||||
|
|||||||
Reference in New Issue
Block a user