using System.Linq; using Content.Client._NF.LateJoin.Controls; using Content.Client._NF.LateJoin.Interfaces; using Content.Client.GameTicking.Managers; using Content.Client.UserInterface.Controls; using Content.Shared.GameTicking; using Robust.Client.AutoGenerated; using Robust.Client.UserInterface.XAML; using Robust.Shared.Console; using Robust.Shared.Utility; namespace Content.Client._NF.LateJoin.Windows; [GenerateTypedNameReferences] public sealed partial class PickerWindow : FancyWindow { [Dependency] private readonly IEntitySystemManager _entitySystem = default!; [Dependency] private readonly ILocalizationManager _loc = default!; [Dependency] private readonly IConsoleHost _consoleHost = default!; private readonly ClientGameTicker _gameTicker; private readonly ISawmill _sawmill; // Designed so you can implement your own tab controls, simply make your control and add the enum here. public enum PickerType { StationOrCrewLarge, Crew, Station, } public record PickerTab(PickerType Type, PickerControl Control); private PickerTab? _currentTab; public PickerWindow() { RobustXamlLoader.Load(this); IoCManager.InjectDependencies(this); _gameTicker = _entitySystem.GetEntitySystem(); _sawmill = Logger.GetSawmill("latejoin"); CrewTabButton.OnPressed += _ => { SetCurrentTab(PickerType.Crew); UpdateUi(_gameTicker.StationJobInformationList); }; StationTabButton.OnPressed += _ => { SetCurrentTab(PickerType.Station); UpdateUi(_gameTicker.StationJobInformationList); }; UpdateUi(_gameTicker.StationJobInformationList); } public new void OpenCentered() { base.OpenCentered(); // This is the place to change the default tab. if (_currentTab == null) { SetCurrentTab(PickerType.StationOrCrewLarge); } } protected override void EnteredTree() { base.EnteredTree(); _gameTicker.LobbyJobsAvailableUpdated += UpdateUi; } protected override void ExitedTree() { base.ExitedTree(); _gameTicker.LobbyJobsAvailableUpdated -= UpdateUi; } private void UpdateUi(IReadOnlyDictionary obj) { // This is the place where it filters out cargo stations and others that shouldn't be shown in the latejoin ui. var availableJobs = obj.Where(kvp => kvp.Value.JobsAvailable.Values.Count != 0) .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); var stationJobs = availableJobs.Where(kvp => kvp.Value.IsLateJoinStation) .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); var crewJobs = availableJobs.Where(kvp => !kvp.Value.IsLateJoinStation) .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); StationTabLabel.Text = _loc.GetString("frontier-lobby-station-title") + stationJobs.GetJobSumCountString(); StationTabButton.Disabled = !StationJobInformationExtensions.IsAnyStationAvailable(availableJobs) || _currentTab?.Type == PickerType.Station; CrewTabLabel.Text = _loc.GetString("frontier-lobby-crew-title") + crewJobs.GetJobSumCountString(); CrewTabButton.Disabled = !StationJobInformationExtensions.IsAnyCrewJobAvailable(availableJobs) || _currentTab?.Type == PickerType.Crew; _currentTab?.Control.UpdateUi(availableJobs); } private void SetCurrentTab(PickerType pickerType) { // Don't do anything when switching to same tab. if (_currentTab != null && _currentTab.Type == pickerType) { return; } ContentContainer.RemoveAllChildren(); switch (pickerType) { case PickerType.StationOrCrewLarge: var stationOrCrewLargeControl = new StationOrCrewLargeControl(); _currentTab = new PickerTab(pickerType, stationOrCrewLargeControl); // Child panel can change tab from within, set the tab change callback. stationOrCrewLargeControl.OnTabChange ??= SetCurrentTab; break; case PickerType.Crew: var crewPickerControl = new CrewPickerControl(); _currentTab = new PickerTab(pickerType, crewPickerControl); crewPickerControl.OnJobJoined ??= JoinGame; break; case PickerType.Station: var stationPickerControl = new StationPickerControl(); _currentTab = new PickerTab(pickerType, stationPickerControl); stationPickerControl.OnJobJoined ??= JoinGame; break; default: throw new ArgumentOutOfRangeException(); // This will never happen. Trust. } ContentContainer.AddChild(_currentTab.Control); UpdateUi(_gameTicker.StationJobInformationList); } private void JoinGame(NetEntity stationEntity, string jobId) { _sawmill.Info($"Late joining as ID: {jobId}"); _consoleHost.ExecuteCommand( $"joingame {CommandParsing.Escape(jobId)} {stationEntity}" ); Close(); } }