diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 3a6129c7a6..84bc855437 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -11,7 +11,7 @@ jobs: name: Run Benchmarks runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.6.0 + - uses: actions/checkout@v4.2.2 with: submodules: 'recursive' - name: Get Engine version diff --git a/.github/workflows/build-docfx.yml b/.github/workflows/build-docfx.yml index 2842578abc..3ef0497496 100644 --- a/.github/workflows/build-docfx.yml +++ b/.github/workflows/build-docfx.yml @@ -8,7 +8,7 @@ jobs: docfx: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.6.0 + - uses: actions/checkout@v4.2.2 - name: Setup submodule run: | git submodule update --init --recursive @@ -19,7 +19,7 @@ jobs: cd RobustToolbox/ git submodule update --init --recursive - name: Setup .NET Core - uses: actions/setup-dotnet@v3.2.0 + uses: actions/setup-dotnet@v4.1.0 with: dotnet-version: 9.0.x diff --git a/.github/workflows/build-map-renderer.yml b/.github/workflows/build-map-renderer.yml index 57775a41cc..3d01618348 100644 --- a/.github/workflows/build-map-renderer.yml +++ b/.github/workflows/build-map-renderer.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Checkout Master - uses: actions/checkout@v3.6.0 + uses: actions/checkout@v4.2.2 - name: Setup Submodule run: | @@ -34,7 +34,7 @@ jobs: git submodule update --init --recursive - name: Setup .NET Core - uses: actions/setup-dotnet@v3.2.0 + uses: actions/setup-dotnet@v4.1.0 with: dotnet-version: 9.0.x diff --git a/.github/workflows/build-test-debug.yml b/.github/workflows/build-test-debug.yml index f263c20027..369239aecf 100644 --- a/.github/workflows/build-test-debug.yml +++ b/.github/workflows/build-test-debug.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Checkout Master - uses: actions/checkout@v3.6.0 + uses: actions/checkout@v4.2.2 - name: Setup Submodule run: | @@ -34,7 +34,7 @@ jobs: git submodule update --init --recursive - name: Setup .NET Core - uses: actions/setup-dotnet@v3.2.0 + uses: actions/setup-dotnet@v4.1.0 with: dotnet-version: 9.0.x diff --git a/.github/workflows/check-crlf.yml b/.github/workflows/check-crlf.yml index 0afcab734f..15e21f3f39 100644 --- a/.github/workflows/check-crlf.yml +++ b/.github/workflows/check-crlf.yml @@ -10,6 +10,6 @@ jobs: if: github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.6.0 + - uses: actions/checkout@v4.2.2 - name: Check for CRLF run: Tools/check_crlf.py diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d035843a23..02fd9d4046 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -16,11 +16,11 @@ jobs: - name: Install dependencies run: sudo apt-get install -y python3-paramiko python3-lxml - - uses: actions/checkout@v3.6.0 + - uses: actions/checkout@v4.2.2 with: submodules: 'recursive' - name: Setup .NET Core - uses: actions/setup-dotnet@v3.2.0 + uses: actions/setup-dotnet@v4.1.0 with: dotnet-version: 9.0.x diff --git a/.github/workflows/rsi-diff.yml b/.github/workflows/rsi-diff.yml index 98cc97e922..390ddcda6e 100644 --- a/.github/workflows/rsi-diff.yml +++ b/.github/workflows/rsi-diff.yml @@ -11,14 +11,14 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3.6.0 + uses: actions/checkout@v4.2.2 - name: Get changed files id: files uses: Ana06/get-changed-files@v2.3.0 with: format: 'space-delimited' - filter: | + filter: | **.rsi **.png diff --git a/.github/workflows/test-packaging.yml b/.github/workflows/test-packaging.yml index 05ca632de3..ed137a19d0 100644 --- a/.github/workflows/test-packaging.yml +++ b/.github/workflows/test-packaging.yml @@ -34,7 +34,7 @@ jobs: steps: - name: Checkout Master - uses: actions/checkout@v3.6.0 + uses: actions/checkout@v4.2.2 - name: Setup Submodule run: | @@ -49,7 +49,7 @@ jobs: git submodule update --init --recursive - name: Setup .NET Core - uses: actions/setup-dotnet@v3.2.0 + uses: actions/setup-dotnet@v4.1.0 with: dotnet-version: 9.0.x diff --git a/.github/workflows/update-credits.yml b/.github/workflows/update-credits.yml index 87babfa2a6..eb609556d4 100644 --- a/.github/workflows/update-credits.yml +++ b/.github/workflows/update-credits.yml @@ -4,19 +4,19 @@ on: workflow_dispatch: schedule: - cron: 0 0 * * 0 - + jobs: get_credits: runs-on: ubuntu-latest # Hey there fork dev! If you like to include your own contributors in this then you can probably just change this to your own repo # Do this in dump_github_contributors.ps1 too into your own repo if: github.repository == 'space-wizards/space-station-14' - + steps: - - uses: actions/checkout@v3.6.0 + - uses: actions/checkout@v4.2.2 with: ref: master - + - name: Get this week's Contributors shell: pwsh env: @@ -25,25 +25,25 @@ jobs: # TODO #- name: Get this week's Patreons - # run: Tools/script2dumppatreons > Resources/Credits/Patrons.yml - + # run: Tools/script2dumppatreons > Resources/Credits/Patrons.yml + # MAKE SURE YOU ENABLED "Allow GitHub Actions to create and approve pull requests" IN YOUR ACTIONS, OTHERWISE IT WILL MOST LIKELY FAIL - # For this you can use a pat token of an account with direct push access to the repo if you have protected branches. + # For this you can use a pat token of an account with direct push access to the repo if you have protected branches. # Uncomment this and comment the other line if you do this. # https://github.com/stefanzweifel/git-auto-commit-action#push-to-protected-branches - + #- name: Commit new credit files # uses: stefanzweifel/git-auto-commit-action@v4 # with: # commit_message: Update Credits # commit_author: PJBot - + # This will make a PR - name: Set current date as env variable run: echo "NOW=$(date +'%Y-%m-%dT%H-%M-%S')" >> $GITHUB_ENV - + - name: Create Pull Request uses: peter-evans/create-pull-request@v5 with: diff --git a/.github/workflows/validate-rgas.yml b/.github/workflows/validate-rgas.yml index 173cb48b7e..be86f976c7 100644 --- a/.github/workflows/validate-rgas.yml +++ b/.github/workflows/validate-rgas.yml @@ -12,7 +12,7 @@ jobs: if: github.actor != 'PJBot' && github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.6.0 + - uses: actions/checkout@v4.2.2 - name: Setup Submodule run: git submodule update --init - name: Pull engine updates diff --git a/.github/workflows/validate-rsis.yml b/.github/workflows/validate-rsis.yml index 3247f117ff..9ef90bda9c 100644 --- a/.github/workflows/validate-rsis.yml +++ b/.github/workflows/validate-rsis.yml @@ -13,7 +13,7 @@ jobs: name: Validate RSIs runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.6.0 + - uses: actions/checkout@v4.2.2 - name: Setup Submodule run: git submodule update --init - name: Pull engine updates diff --git a/.github/workflows/validate_mapfiles.yml b/.github/workflows/validate_mapfiles.yml index aaf1edcc28..53fa3b4ae4 100644 --- a/.github/workflows/validate_mapfiles.yml +++ b/.github/workflows/validate_mapfiles.yml @@ -12,7 +12,7 @@ jobs: if: github.actor != 'PJBot' && github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.6.0 + - uses: actions/checkout@v4.2.2 - name: Setup Submodule run: git submodule update --init - name: Pull engine updates diff --git a/.github/workflows/yaml-linter.yml b/.github/workflows/yaml-linter.yml index 1053bb4a3a..c10549bcb4 100644 --- a/.github/workflows/yaml-linter.yml +++ b/.github/workflows/yaml-linter.yml @@ -13,7 +13,7 @@ jobs: if: github.actor != 'PJBot' && github.event.pull_request.draft == false runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.6.0 + - uses: actions/checkout@v4.2.2 - name: Setup submodule run: | git submodule update --init --recursive @@ -24,7 +24,7 @@ jobs: cd RobustToolbox/ git submodule update --init --recursive - name: Setup .NET Core - uses: actions/setup-dotnet@v3.2.0 + uses: actions/setup-dotnet@v4.1.0 with: dotnet-version: 9.0.x - name: Install dependencies diff --git a/Content.Client/Administration/AdminNameOverlay.cs b/Content.Client/Administration/AdminNameOverlay.cs index 3c968ec17c..c0f31f1e3d 100644 --- a/Content.Client/Administration/AdminNameOverlay.cs +++ b/Content.Client/Administration/AdminNameOverlay.cs @@ -1,7 +1,10 @@ using System.Linq; using System.Numerics; using Content.Client.Administration.Systems; +using Content.Client.Stylesheets; +using Content.Shared.Administration; using Content.Shared.CCVar; +using Content.Shared.Ghost; using Content.Shared.Mind; using Robust.Client.Graphics; using Robust.Client.ResourceManagement; @@ -14,32 +17,54 @@ namespace Content.Client.Administration; internal sealed class AdminNameOverlay : Overlay { - [Dependency] private readonly IConfigurationManager _config = default!; - private readonly AdminSystem _system; private readonly IEntityManager _entityManager; private readonly IEyeManager _eyeManager; private readonly EntityLookupSystem _entityLookup; private readonly IUserInterfaceManager _userInterfaceManager; private readonly Font _font; + private readonly Font _fontBold; + private bool _overlayClassic; + private bool _overlaySymbols; + private bool _overlayPlaytime; + private bool _overlayStartingJob; + private float _ghostFadeDistance; + private float _ghostHideDistance; + private int _overlayStackMax; + private float _overlayMergeDistance; //TODO make this adjustable via GUI private readonly ProtoId[] _filter = ["SoloAntagonist", "TeamAntagonist", "SiliconAntagonist", "FreeAgent"]; private readonly string _antagLabelClassic = Loc.GetString("admin-overlay-antag-classic"); - 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; _entityManager = entityManager; _eyeManager = eyeManager; _entityLookup = entityLookup; _userInterfaceManager = userInterfaceManager; ZIndex = 200; - _font = new VectorFont(resourceCache.GetResource("/Fonts/NotoSans/NotoSans-Regular.ttf"), 10); + // Setting these to a specific ttf 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); + config.OnValueChanged(CCVars.AdminOverlayGhostHideDistance, (f) => { _ghostHideDistance = f; }, true); + config.OnValueChanged(CCVars.AdminOverlayGhostFadeDistance, (f) => { _ghostFadeDistance = f; }, true); + config.OnValueChanged(CCVars.AdminOverlayStackMax, (i) => { _overlayStackMax = i; }, true); + config.OnValueChanged(CCVars.AdminOverlayMergeDistance, (f) => { _overlayMergeDistance = f; }, true); } public override OverlaySpace Space => OverlaySpace.ScreenSpace; @@ -47,75 +72,147 @@ internal sealed class AdminNameOverlay : Overlay protected override void Draw(in OverlayDrawArgs args) { var viewport = args.WorldAABB; + var colorDisconnected = Color.White; + var uiScale = _userInterfaceManager.RootControl.UIScale; + var lineoffset = new Vector2(0f, 14f) * uiScale; + var drawnOverlays = new List<(Vector2,Vector2)>() ; // A saved list of the overlays already drawn - //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) + // Get all player positions before drawing overlays, so they can be sorted before iteration + var sortable = new List<(PlayerInfo, Box2, EntityUid, Vector2)>(); + foreach (var info in _system.PlayerList) { - var entity = _entityManager.GetEntity(playerInfo.NetEntity); + var entity = _entityManager.GetEntity(info.NetEntity); - // Otherwise the entity can not exist yet - if (entity == null || !_entityManager.EntityExists(entity)) - { + // If entity does not exist or is on a different map, skip + if (entity == null + || !_entityManager.EntityExists(entity) + || _entityManager.GetComponent(entity.Value).MapID != args.MapId) continue; - } - - // if not on the same map, continue - if (_entityManager.GetComponent(entity.Value).MapID != args.MapId) - { - continue; - } var aabb = _entityLookup.GetWorldAABB(entity.Value); - - // if not on screen, continue + // if not on screen, skip if (!aabb.Intersects(in viewport)) - { continue; - } - var uiScale = _userInterfaceManager.RootControl.UIScale; - var lineoffset = new Vector2(0f, 14f) * uiScale; - var screenCoordinates = _eyeManager.WorldToScreen(aabb.Center + - new Angle(-_eyeManager.CurrentEye.Rotation).RotateVec( - aabb.TopRight - aabb.Center)) + new Vector2(1f, 7f); + // Get on-screen coordinates of player + var screenCoordinates = _eyeManager.WorldToScreen(aabb.Center).Rounded(); + sortable.Add((info, aabb, entity.Value, screenCoordinates)); + } + + // Draw overlays for visible players, starting from the top of the screen + foreach (var info in sortable.OrderBy(s => s.Item4.Y).ToList()) + { + var playerInfo = info.Item1; + var aabb = info.Item2; + var entity = info.Item3; + var screenCoordinatesCenter = info.Item4; + //the center position is kept separately, for simpler position comparison later + var centerOffset = new Vector2(28f, -18f) * uiScale; + var screenCoordinates = screenCoordinatesCenter + centerOffset; + var alpha = 1f; + + //TODO make a smarter system where the starting offset can be modified by the predicted position and size of already-drawn overlays/stacks? var currentOffset = Vector2.Zero; - args.ScreenHandle.DrawString(_font, screenCoordinates + currentOffset, playerInfo.CharacterName, uiScale, playerInfo.Connected ? Color.Aquamarine : Color.White); + // Ghosts near the cursor are made transparent/invisible + // TODO would be "cheaper" if playerinfo already contained a ghost bool, this gets called every frame for every onscreen player! + if (_entityManager.HasComponent(entity)) + { + // We want the map positions here, so we don't have to worry about resolution and such shenanigans + var mobPosition = aabb.Center; + var mousePosition = _eyeManager + .ScreenToMap(_userInterfaceManager.MousePositionScaled.Position * uiScale) + .Position; + var dist = Vector2.Distance(mobPosition, mousePosition); + if (dist < _ghostHideDistance) + continue; + + alpha = Math.Clamp((dist - _ghostHideDistance) / (_ghostFadeDistance - _ghostHideDistance), 0f, 1f); + colorDisconnected.A = alpha; + } + + // If the new overlay text block is within merge distance of any previous ones + // merge them into a stack so they don't hide each other + var stack = drawnOverlays.FindAll(x => + Vector2.Distance(_eyeManager.ScreenToMap(x.Item1).Position, aabb.Center) <= _overlayMergeDistance); + if (stack.Count > 0) + { + screenCoordinates = stack.First().Item1 + centerOffset; + // Replacing this overlay's coordinates for the later save with the stack root's coordinates + // so that other overlays don't try to stack to these coordinates + screenCoordinatesCenter = stack.First().Item1; + + var i = 1; + foreach (var s in stack) + { + // additional entries after maximum stack size is reached will be drawn over the last entry + if (i <= _overlayStackMax - 1) + currentOffset = lineoffset + s.Item2 ; + i++; + } + } + + // Character name + var color = Color.Aquamarine; + color.A = alpha; + args.ScreenHandle.DrawString(_font, screenCoordinates + currentOffset, playerInfo.CharacterName, uiScale, playerInfo.Connected ? color : colorDisconnected); currentOffset += lineoffset; - args.ScreenHandle.DrawString(_font, screenCoordinates + currentOffset, playerInfo.Username, uiScale, playerInfo.Connected ? Color.Yellow : Color.White); + // Username + color = Color.Yellow; + color.A = alpha; + args.ScreenHandle.DrawString(_font, screenCoordinates + currentOffset, playerInfo.Username, uiScale, playerInfo.Connected ? color : colorDisconnected); 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); + color = Color.Orange; + color.A = alpha; + args.ScreenHandle.DrawString(_font, screenCoordinates + currentOffset, playerInfo.PlaytimeString, uiScale, playerInfo.Connected ? color : colorDisconnected); 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); + color = Color.GreenYellow; + color.A = alpha; + args.ScreenHandle.DrawString(_font, screenCoordinates + currentOffset, Loc.GetString(playerInfo.StartingJob), uiScale, playerInfo.Connected ? color : colorDisconnected); 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; + color = Color.OrangeRed; + color.A = alpha; + args.ScreenHandle.DrawString(_fontBold, screenCoordinates + currentOffset, label, uiScale, color); 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 color = playerInfo.RoleProto.Color; + 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; + color = playerInfo.RoleProto.Color; + color.A = alpha; + args.ScreenHandle.DrawString(_fontBold, screenCoordinates + currentOffset, label, uiScale, color); + currentOffset += lineoffset; + } - args.ScreenHandle.DrawString(_font, screenCoordinates + currentOffset, label, uiScale, color); - currentOffset += lineoffset; - } + //Save the coordinates and size of the text block, for stack merge check + drawnOverlays.Add((screenCoordinatesCenter, currentOffset)); } } } diff --git a/Content.Client/Administration/Systems/AdminSystem.Overlay.cs b/Content.Client/Administration/Systems/AdminSystem.Overlay.cs index ba6ce40ca0..ba56f4694f 100644 --- a/Content.Client/Administration/Systems/AdminSystem.Overlay.cs +++ b/Content.Client/Administration/Systems/AdminSystem.Overlay.cs @@ -14,6 +14,7 @@ namespace Content.Client.Administration.Systems [Dependency] private readonly IEyeManager _eyeManager = default!; [Dependency] private readonly EntityLookupSystem _entityLookup = default!; [Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!; + [Dependency] private readonly IConfigurationManager _configurationManager = default!; private AdminNameOverlay _adminNameOverlay = default!; @@ -22,7 +23,14 @@ namespace Content.Client.Administration.Systems 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; } diff --git a/Content.Client/Administration/UI/Bwoink/BwoinkControl.xaml b/Content.Client/Administration/UI/Bwoink/BwoinkControl.xaml index c3600d08f8..d53101f68e 100644 --- a/Content.Client/Administration/UI/Bwoink/BwoinkControl.xaml +++ b/Content.Client/Administration/UI/Bwoink/BwoinkControl.xaml @@ -2,14 +2,14 @@ xmlns="https://spacestation14.io" xmlns:cc="clr-namespace:Content.Client.Administration.UI.CustomControls"> - + - + diff --git a/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTab.xaml.cs b/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTab.xaml.cs index b7231869c9..b5b2b0e345 100644 --- a/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTab.xaml.cs +++ b/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTab.xaml.cs @@ -2,11 +2,13 @@ using System.Linq; using Content.Client.Administration.Systems; using Content.Client.UserInterface.Controls; using Content.Shared.Administration; +using Content.Shared.CCVar; using Robust.Client.AutoGenerated; using Robust.Client.Graphics; using Robust.Client.Player; using Robust.Client.UserInterface; using Robust.Client.UserInterface.XAML; +using Robust.Shared.Configuration; using static Content.Client.Administration.UI.Tabs.PlayerTab.PlayerTabHeader; using static Robust.Client.UserInterface.Controls.BaseButton; @@ -16,6 +18,7 @@ namespace Content.Client.Administration.UI.Tabs.PlayerTab; public sealed partial class PlayerTab : Control { [Dependency] private readonly IEntityManager _entManager = default!; + [Dependency] private readonly IConfigurationManager _config = default!; [Dependency] private readonly IPlayerManager _playerMan = default!; private const string ArrowUp = "↑"; @@ -41,6 +44,10 @@ public sealed partial class PlayerTab : Control _adminSystem.OverlayEnabled += OverlayEnabled; _adminSystem.OverlayDisabled += OverlayDisabled; + _config.OnValueChanged(CCVars.AdminPlayerlistSeparateSymbols, PlayerListSettingsChanged); + _config.OnValueChanged(CCVars.AdminPlayerlistHighlightedCharacterColor, PlayerListSettingsChanged); + _config.OnValueChanged(CCVars.AdminPlayerlistRoleTypeColor, PlayerListSettingsChanged); + OverlayButton.OnPressed += OverlayButtonPressed; ShowDisconnectedButton.OnPressed += ShowDisconnectedPressed; @@ -106,6 +113,11 @@ public sealed partial class PlayerTab : Control #region ListContainer + private void PlayerListSettingsChanged(bool _) + { + RefreshPlayerList(_adminSystem.PlayerList); + } + private void RefreshPlayerList(IReadOnlyList players) { _players = players; @@ -196,8 +208,7 @@ public sealed partial class PlayerTab : Control Header.Username => Compare(x.Username, y.Username), Header.Character => Compare(x.CharacterName, y.CharacterName), Header.Job => Compare(x.StartingJob, y.StartingJob), - Header.Antagonist => x.Antag.CompareTo(y.Antag), - Header.RoleType => Compare(x.RoleProto.Name , y.RoleProto.Name), + Header.RoleType => y.SortWeight - x.SortWeight, Header.Playtime => TimeSpan.Compare(x.OverallPlaytime ?? default, y.OverallPlaytime ?? default), _ => 1 }; diff --git a/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTabEntry.xaml b/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTabEntry.xaml index 54e51747fb..a30b909226 100644 --- a/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTabEntry.xaml +++ b/Content.Client/Administration/UI/Tabs/PlayerTab/PlayerTabEntry.xaml @@ -19,11 +19,6 @@ HorizontalExpand="True" ClipText="True"/> -