6
StarHorizon_Public/Content.Client/_NF/LateJoin/Controls/StationPickerControl.xaml.cs
2026-01-24 12:49:55 +03:00

162 lines
6.4 KiB
C#

using System.Linq;
using Content.Client._NF.LateJoin.Interfaces;
using Content.Client._NF.LateJoin.ListItems;
using Content.Client.Lobby;
using Content.Client.Players.PlayTimeTracking;
using Content.Shared.GameTicking;
using Content.Shared.Preferences;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
namespace Content.Client._NF.LateJoin.Controls;
[GenerateTypedNameReferences]
public sealed partial class StationPickerControl : PickerControl
{
[Dependency] private readonly ILocalizationManager _loc = default!;
[Dependency] private readonly IEntitySystemManager _entitySystem = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly JobRequirementsManager _jobReqs = default!;
[Dependency] private readonly IClientPreferencesManager _preferencesManager = default!;
private readonly SpriteSystem _spriteSystem;
public StationPickerControl()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_spriteSystem = _entitySystem.GetEntitySystem<SpriteSystem>();
}
private Dictionary<NetEntity, StationJobInformation> _lobbyJobs = new();
private StationListItem.ViewState? _lastSelectedStation;
public Action<NetEntity, string>? OnJobJoined;
public override void UpdateUi(IReadOnlyDictionary<NetEntity, StationJobInformation> obj)
{
_lobbyJobs = new Dictionary<NetEntity, StationJobInformation>(obj);
StationItemList.RemoveAllChildren();
foreach (var stationViewState in BuildStationViewStateList(_lobbyJobs))
{
var item = new StationListItem(stationViewState);
item.StationButton.OnPressed += _ => OnStationPressed(stationViewState);
StationItemList.AddChild(item);
}
// Build station jobs, the right section of the screen.
StationJobItemList.RemoveAllChildren();
if (_lastSelectedStation != null && obj.TryGetValue(_lastSelectedStation.StationEntity, out var stationInfo))
{
foreach (var jobViewState in BuildJobViewStateList(stationInfo))
{
var item = new JobListItem(jobViewState);
item.OnPressed += _ =>
{
OnJobJoined?.Invoke(_lastSelectedStation.StationEntity, jobViewState.JobId);
};
StationJobItemList.AddChild(item);
}
}
StationName.Text = _lastSelectedStation?.StationName ?? "";
StationDescription.Text = _lastSelectedStation?.StationDescription ?? "";
}
private void OnStationPressed(StationListItem.ViewState stationItemViewState)
{
_lastSelectedStation = stationItemViewState;
UpdateUi(_lobbyJobs);
}
private List<JobListItem.ViewState> BuildJobViewStateList(StationJobInformation jobInformation)
{
var viewStateList = new List<JobListItem.ViewState>();
foreach (var (jobPrototype, jobCount) in jobInformation.JobsAvailable)
{
if (_preferencesManager.Preferences?.SelectedCharacter is not HumanoidCharacterProfile profile)
{
continue;
}
var prototype = _prototypeManager.Index(jobPrototype);
var jobName = prototype.LocalizedName + jobCount.WrapJobCountInParentheses();
Texture? texture = null;
if (_prototypeManager.TryIndex(prototype.Icon, out var jobIcon))
{
texture = _spriteSystem.Frame0(jobIcon.Icon);
}
var buttonTooltip = "";
if (!_jobReqs.IsAllowed(prototype, profile, out var denyReason))
{
buttonTooltip = denyReason.ToString();
}
var isButtonDisabled = jobCount == 0 || !_jobReqs.IsAllowed(prototype, profile, out _);
var viewState = new JobListItem.ViewState(
jobId: jobPrototype,
jobName: jobName,
toolTip: buttonTooltip,
disabled: isButtonDisabled,
jobIcon: texture
);
viewStateList.Add(viewState);
}
return viewStateList;
}
/**
* Convert some raw dictionary data to a view state model that is more readable.
*
* @param obj Dictionary of station entities to job prototypes.
* @param stationNames Dictionary of station entities to station names.
* @return List of view states for each station.
*/
private List<StationListItem.ViewState> BuildStationViewStateList(
IReadOnlyDictionary<NetEntity, StationJobInformation> obj)
{
var stationList = obj.Where(kvp => kvp.Value.IsLateJoinStation).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
var viewStateList = new List<StationListItem.ViewState>();
foreach (var (stationEntity, stationJobInformation) in stationList)
{
var viewState = new StationListItem.ViewState(
stationEntity,
stationJobInformation.GetStationNameWithJobCount(),
stationJobInformation.StationDisplayInfo?.StationSubtext != null
? _loc.GetString(stationJobInformation.StationDisplayInfo.StationSubtext)
: "",
stationJobInformation.StationDisplayInfo?.StationDescription != null
? _loc.GetString(stationJobInformation.StationDisplayInfo.StationDescription)
: "",
_lastSelectedStation?.StationEntity == stationEntity,
stationJobInformation.StationDisplayInfo?.StationIcon?.CanonPath
);
// Always select the first station in the list if none is selected yet.
// This is because otherwise the right side of the screen would then be a blank space.
if (_lastSelectedStation == null)
{
_lastSelectedStation = viewState;
viewState.Selected = true;
}
viewStateList.Add(viewState);
}
// Sort 0 to the end of the list in the order it is in the dictionary.
// Sort 1 first, 2 second, etc.
return viewStateList
.OrderBy(viewState => (obj[viewState.StationEntity].StationDisplayInfo?.LobbySortOrder ?? 0) == 0
? int.MaxValue
: obj[viewState.StationEntity].StationDisplayInfo!.LobbySortOrder)
.ToList();
}
}