Skip to content

Commit 9e34201

Browse files
committed
Merge remote-tracking branch 'refs/remotes/wizards/master'
2 parents 35d35e3 + b5a6f85 commit 9e34201

File tree

18 files changed

+449
-37
lines changed

18 files changed

+449
-37
lines changed

Content.Client/Administration/UI/Bwoink/BwoinkControl.xaml.cs

+37-4
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ public BwoinkControl()
9393
var ach = AHelpHelper.EnsurePanel(a.SessionId);
9494
var bch = AHelpHelper.EnsurePanel(b.SessionId);
9595

96+
// Pinned players first
97+
if (a.IsPinned != b.IsPinned)
98+
return a.IsPinned ? -1 : 1;
99+
96100
// First, sort by unread. Any chat with unread messages appears first. We just sort based on unread
97101
// status, not number of unread messages, so that more recent unread messages take priority.
98102
var aUnread = ach.Unread > 0;
@@ -104,15 +108,31 @@ public BwoinkControl()
104108
if (a.Connected != b.Connected)
105109
return a.Connected ? -1 : 1;
106110

107-
// Next, group by whether or not the players have participated in this round.
108-
// The ahelp window shows all players that have connected since server restart, this groups them all towards the bottom.
109-
if (a.ActiveThisRound != b.ActiveThisRound)
110-
return a.ActiveThisRound ? -1 : 1;
111+
// Sort connected players by New Player status, then by Antag status
112+
if (a.Connected && b.Connected)
113+
{
114+
var aNewPlayer = a.OverallPlaytime <= TimeSpan.FromMinutes(_cfg.GetCVar(CCVars.NewPlayerThreshold));
115+
var bNewPlayer = b.OverallPlaytime <= TimeSpan.FromMinutes(_cfg.GetCVar(CCVars.NewPlayerThreshold));
116+
117+
if (aNewPlayer != bNewPlayer)
118+
return aNewPlayer ? -1 : 1;
119+
120+
if (a.Antag != b.Antag)
121+
return a.Antag ? -1 : 1;
122+
}
123+
124+
// Sort disconnected players by participation in the round
125+
if (!a.Connected && !b.Connected)
126+
{
127+
if (a.ActiveThisRound != b.ActiveThisRound)
128+
return a.ActiveThisRound ? -1 : 1;
129+
}
111130

112131
// Finally, sort by the most recent message.
113132
return bch.LastMessage.CompareTo(ach.LastMessage);
114133
};
115134

135+
116136
Bans.OnPressed += _ =>
117137
{
118138
if (_currentPlayer is not null)
@@ -258,7 +278,20 @@ private void SwitchToChannel(NetUserId? ch)
258278

259279
public void PopulateList()
260280
{
281+
// Maintain existing pin statuses
282+
var pinnedPlayers = ChannelSelector.PlayerInfo.Where(p => p.IsPinned).ToDictionary(p => p.SessionId);
283+
261284
ChannelSelector.PopulateList();
285+
286+
// Restore pin statuses
287+
foreach (var player in ChannelSelector.PlayerInfo)
288+
{
289+
if (pinnedPlayers.TryGetValue(player.SessionId, out var pinnedPlayer))
290+
{
291+
player.IsPinned = pinnedPlayer.IsPinned;
292+
}
293+
}
294+
262295
UpdateButtons();
263296
}
264297
}

Content.Client/Administration/UI/CustomControls/PlayerListControl.xaml.cs

+16-5
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ public sealed partial class PlayerListControl : BoxContainer
2121

2222
private readonly IEntityManager _entManager;
2323
private readonly IUserInterfaceManager _uiManager;
24-
24+
2525
private PlayerInfo? _selectedPlayer;
2626

2727
private List<PlayerInfo> _playerList = new();
28-
private readonly List<PlayerInfo> _sortedPlayerList = new();
28+
private List<PlayerInfo> _sortedPlayerList = new();
2929

3030
public Comparison<PlayerInfo>? Comparison;
3131
public Func<PlayerInfo, string, string>? OverrideText;
@@ -110,19 +110,30 @@ private void FilterList()
110110
if (Comparison != null)
111111
_sortedPlayerList.Sort((a, b) => Comparison(a, b));
112112

113-
// Ensure pinned players are always at the top
114-
_sortedPlayerList.Sort((a, b) => a.IsPinned != b.IsPinned && a.IsPinned ? -1 : 1);
115-
116113
PlayerListContainer.PopulateList(_sortedPlayerList.Select(info => new PlayerListData(info)).ToList());
117114
if (_selectedPlayer != null)
118115
PlayerListContainer.Select(new PlayerListData(_selectedPlayer));
119116
}
120117

118+
121119
public void PopulateList(IReadOnlyList<PlayerInfo>? players = null)
122120
{
121+
// Maintain existing pin statuses
122+
var pinnedPlayers = _playerList.Where(p => p.IsPinned).ToDictionary(p => p.SessionId);
123+
123124
players ??= _adminSystem.PlayerList;
124125

125126
_playerList = players.ToList();
127+
128+
// Restore pin statuses
129+
foreach (var player in _playerList)
130+
{
131+
if (pinnedPlayers.TryGetValue(player.SessionId, out var pinnedPlayer))
132+
{
133+
player.IsPinned = pinnedPlayer.IsPinned;
134+
}
135+
}
136+
126137
if (_selectedPlayer != null && !_playerList.Contains(_selectedPlayer))
127138
_selectedPlayer = null;
128139

Content.Client/Lobby/LobbyUIController.cs

+1
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ private void OpenSavePanel()
275275
_logManager,
276276
_playerManager,
277277
_prototypeManager,
278+
_resourceCache,
278279
_requirements,
279280
_markings);
280281

Content.Client/Lobby/UI/HumanoidProfileEditor.xaml

+2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
<Button Name="ResetButton" Disabled="True" Text="{Loc 'humanoid-profile-editor-reset-button'}"/>
3939
<Button Name="ImportButton" Text="{Loc 'humanoid-profile-editor-import-button'}"/>
4040
<Button Name="ExportButton" Text="{Loc 'humanoid-profile-editor-export-button'}"/>
41+
<Button Name="ExportImageButton" Text="{Loc 'humanoid-profile-editor-export-image-button'}"/>
42+
<Button Name="OpenImagesButton" Text="{Loc 'humanoid-profile-editor-open-image-button'}"/>
4143
</BoxContainer>
4244
</ui:HighlightedContainer>
4345
</BoxContainer>

Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs

+47-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Content.Client.Lobby.UI.Roles;
77
using Content.Client.Message;
88
using Content.Client.Players.PlayTimeTracking;
9+
using Content.Client.Sprite;
910
using Content.Client.Stylesheets;
1011
using Content.Client.UserInterface.Systems.Guidebook;
1112
using Content.Shared._Sunrise.SunriseCCVars;
@@ -28,6 +29,7 @@
2829
using Robust.Client.UserInterface.XAML;
2930
using Robust.Client.Utility;
3031
using Robust.Shared.Configuration;
32+
using Robust.Shared.ContentPack;
3133
using Robust.Shared.Enums;
3234
using Robust.Shared.Prototypes;
3335
using Robust.Shared.Utility;
@@ -45,6 +47,7 @@ public sealed partial class HumanoidProfileEditor : BoxContainer
4547
private readonly IFileDialogManager _dialogManager;
4648
private readonly IPlayerManager _playerManager;
4749
private readonly IPrototypeManager _prototypeManager;
50+
private readonly IResourceManager _resManager;
4851
private readonly MarkingManager _markingManager;
4952
private readonly JobRequirementsManager _requirements;
5053
private readonly LobbyUIController _controller;
@@ -56,6 +59,7 @@ public sealed partial class HumanoidProfileEditor : BoxContainer
5659
private LoadoutWindow? _loadoutWindow;
5760

5861
private bool _exporting;
62+
private bool _imaging;
5963

6064
/// <summary>
6165
/// If we're attempting to save.
@@ -111,6 +115,7 @@ public HumanoidProfileEditor(
111115
ILogManager logManager,
112116
IPlayerManager playerManager,
113117
IPrototypeManager prototypeManager,
118+
IResourceManager resManager,
114119
JobRequirementsManager requirements,
115120
MarkingManager markings)
116121
{
@@ -124,6 +129,7 @@ public HumanoidProfileEditor(
124129
_prototypeManager = prototypeManager;
125130
_markingManager = markings;
126131
_preferencesManager = preferencesManager;
132+
_resManager = resManager;
127133
_requirements = requirements;
128134
_controller = UserInterfaceManager.GetUIController<LobbyUIController>();
129135

@@ -137,6 +143,16 @@ public HumanoidProfileEditor(
137143
ExportProfile();
138144
};
139145

146+
ExportImageButton.OnPressed += args =>
147+
{
148+
ExportImage();
149+
};
150+
151+
OpenImagesButton.OnPressed += args =>
152+
{
153+
_resManager.UserData.OpenOsWindow(ContentSpriteSystem.Exports);
154+
};
155+
140156
ResetButton.OnPressed += args =>
141157
{
142158
SetProfile((HumanoidCharacterProfile?) _preferencesManager.Preferences?.SelectedCharacter, _preferencesManager.Preferences?.SelectedCharacterIndex);
@@ -441,7 +457,6 @@ public HumanoidProfileEditor(
441457
SpeciesInfoButton.OnPressed += OnSpeciesInfoButtonPressed;
442458

443459
UpdateSpeciesGuidebookIcon();
444-
ReloadPreview();
445460
IsDirty = false;
446461
}
447462

@@ -728,11 +743,12 @@ private void ReloadPreview()
728743
_entManager.DeleteEntity(PreviewDummy);
729744
PreviewDummy = EntityUid.Invalid;
730745

731-
if (Profile == null || !_prototypeManager.HasIndex<SpeciesPrototype>(Profile.Species))
746+
if (Profile == null || !_prototypeManager.HasIndex(Profile.Species))
732747
return;
733748

734749
PreviewDummy = _controller.LoadProfileEntity(Profile, JobOverride, ShowClothes.Pressed);
735750
SpriteView.SetEntity(PreviewDummy);
751+
_entManager.System<MetaDataSystem>().SetEntityName(PreviewDummy, Profile.Name);
736752
}
737753

738754
/// <summary>
@@ -1167,6 +1183,17 @@ protected override void Dispose(bool disposing)
11671183

11681184
_loadoutWindow?.Dispose();
11691185
_loadoutWindow = null;
1186+
}
1187+
1188+
protected override void EnteredTree()
1189+
{
1190+
base.EnteredTree();
1191+
ReloadPreview();
1192+
}
1193+
1194+
protected override void ExitedTree()
1195+
{
1196+
base.ExitedTree();
11701197
_entManager.DeleteEntity(PreviewDummy);
11711198
PreviewDummy = EntityUid.Invalid;
11721199
}
@@ -1237,6 +1264,11 @@ private void SetName(string newName)
12371264
{
12381265
Profile = Profile?.WithName(newName);
12391266
SetDirty();
1267+
1268+
if (!IsDirty)
1269+
return;
1270+
1271+
_entManager.System<MetaDataSystem>().SetEntityName(PreviewDummy, newName);
12401272
}
12411273

12421274
private void SetSpawnPriority(SpawnPriorityPreference newSpawnPriority)
@@ -1587,6 +1619,19 @@ private void RandomizeName()
15871619
UpdateNameEdit();
15881620
}
15891621

1622+
private async void ExportImage()
1623+
{
1624+
if (_imaging)
1625+
return;
1626+
1627+
var dir = SpriteView.OverrideDirection ?? Direction.South;
1628+
1629+
// I tried disabling the button but it looks sorta goofy as it only takes a frame or two to save
1630+
_imaging = true;
1631+
await _entManager.System<ContentSpriteSystem>().Export(PreviewDummy, dir, includeId: false);
1632+
_imaging = false;
1633+
}
1634+
15901635
private async void ImportProfile()
15911636
{
15921637
if (_exporting || CharacterSlot == null || Profile == null)

0 commit comments

Comments
 (0)