Station records (#8720)

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
Flipp Syder
2022-08-08 22:10:01 -07:00
committed by GitHub
parent 75dfbdb57f
commit 3d36a6e1f6
35 changed files with 1888 additions and 9 deletions

View File

@@ -0,0 +1,51 @@
using Content.Client.Eui;
using Content.Client.GameTicking.Managers;
using Content.Shared.CrewManifest;
using Content.Shared.Eui;
using JetBrains.Annotations;
namespace Content.Client.CrewManifest;
[UsedImplicitly]
public sealed class CrewManifestEui : BaseEui
{
private readonly ClientGameTicker _gameTicker;
private readonly CrewManifestUi _window;
public CrewManifestEui()
{
_gameTicker = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<ClientGameTicker>();
_window = new();
_window.OnClose += () =>
{
SendMessage(new CrewManifestEuiClosed());
};
}
public override void Opened()
{
base.Opened();
_window.OpenCentered();
}
public override void Closed()
{
base.Closed();
_window.Close();
}
public override void HandleState(EuiStateBase state)
{
base.HandleState(state);
if (state is not CrewManifestEuiState cast)
{
return;
}
_window.Populate(cast.StationName, cast.Entries);
}
}

View File

@@ -0,0 +1,82 @@
using Content.Client.GameTicking.Managers;
using Content.Shared.CrewManifest;
using Content.Shared.Roles;
using Robust.Shared.Prototypes;
namespace Content.Client.CrewManifest;
public sealed class CrewManifestSystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
private Dictionary<string, Dictionary<string, int>> _jobDepartmentLookup = new();
private HashSet<string> _departments = new();
public IReadOnlySet<string> Departments => _departments;
public override void Initialize()
{
base.Initialize();
BuildDepartmentLookup();
_prototypeManager.PrototypesReloaded += OnPrototypesReload;
}
public override void Shutdown()
{
_prototypeManager.PrototypesReloaded -= OnPrototypesReload;
}
/// <summary>
/// Requests a crew manifest from the server.
/// </summary>
/// <param name="uid">EntityUid of the entity we're requesting the crew manifest from.</param>
public void RequestCrewManifest(EntityUid uid)
{
RaiseNetworkEvent(new RequestCrewManifestMessage(uid));
}
private void OnPrototypesReload(PrototypesReloadedEventArgs _)
{
_jobDepartmentLookup.Clear();
_departments.Clear();
BuildDepartmentLookup();
}
private void BuildDepartmentLookup()
{
foreach (var department in _prototypeManager.EnumeratePrototypes<DepartmentPrototype>())
{
_departments.Add(department.ID);
for (var i = 1; i <= department.Roles.Count; i++)
{
if (!_jobDepartmentLookup.TryGetValue(department.Roles[i - 1], out var departments))
{
departments = new();
_jobDepartmentLookup.Add(department.Roles[i - 1], departments);
}
departments.Add(department.ID, i);
}
}
}
public int GetDepartmentOrder(string department, string jobPrototype)
{
if (!Departments.Contains(department))
{
return -1;
}
if (!_jobDepartmentLookup.TryGetValue(jobPrototype, out var departments))
{
return -1;
}
return departments.TryGetValue(department, out var order)
? order
: -1;
}
}

View File

@@ -0,0 +1,21 @@
<DefaultWindow xmlns="https://spacestation14.io"
xmlns:ui="clr-namespace:Content.Client.HUD.UI"
Title="{Loc 'crew-manifest-window-title'}"
MinSize="450 750">
<BoxContainer Orientation="Vertical" VerticalExpand="True" HorizontalExpand="True">
<ui:StripeBack Name="StationNameContainer">
<PanelContainer>
<Label Name="StationName" Align="Center" />
</PanelContainer>
</ui:StripeBack>
<BoxContainer HorizontalExpand="True" VerticalExpand="True">
<ScrollContainer HorizontalExpand="True" VerticalExpand="True">
<!-- this MIGHT have race conditions -->
<BoxContainer Name="CrewManifestListing" Orientation="Vertical" HorizontalExpand="True">
<Label Text="{Loc 'crew-manifest-no-valid-station'}" HorizontalExpand="True" />
</BoxContainer>
<!-- Crew manifest goes here. -->
</ScrollContainer>
</BoxContainer>
</BoxContainer>
</DefaultWindow>

View File

@@ -0,0 +1,186 @@
using System.Linq;
using Content.Shared.CCVar;
using Content.Shared.CrewManifest;
using Content.Shared.Roles;
using Robust.Client.AutoGenerated;
using Robust.Client.ResourceManagement;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Client.Utility;
using Robust.Shared.Configuration;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Client.CrewManifest;
[GenerateTypedNameReferences]
public sealed partial class CrewManifestUi : DefaultWindow
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IResourceCache _resourceCache = default!;
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
[Dependency] private readonly IConfigurationManager _configManager = default!;
private readonly CrewManifestSystem _crewManifestSystem;
private EntityUid? _station;
public CrewManifestUi()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
_crewManifestSystem = _entitySystemManager.GetEntitySystem<CrewManifestSystem>();
StationName.AddStyleClass("LabelBig");
}
public void Populate(string name, CrewManifestEntries? entries)
{
CrewManifestListing.DisposeAllChildren();
CrewManifestListing.RemoveAllChildren();
StationNameContainer.Visible = entries != null;
StationName.Text = name;
if (entries == null) return;
var entryList = SortEntries(entries);
foreach (var item in entryList)
{
CrewManifestListing.AddChild(new CrewManifestSection(item.section, item.entries, _resourceCache, _crewManifestSystem));
}
}
private List<(string section, List<CrewManifestEntry> entries)> SortEntries(CrewManifestEntries entries)
{
var entryDict = new Dictionary<string, List<CrewManifestEntry>>();
foreach (var entry in entries.Entries)
{
foreach (var department in _prototypeManager.EnumeratePrototypes<DepartmentPrototype>())
{
// this is a little expensive, and could be better
if (department.Roles.Contains(entry.JobPrototype))
{
entryDict.GetOrNew(department.ID).Add(entry);
}
}
}
var entryList = new List<(string section, List<CrewManifestEntry> entries)>();
foreach (var (section, listing) in entryDict)
{
entryList.Add((section, listing));
}
var sortOrder = _configManager.GetCVar(CCVars.CrewManifestOrdering).Split(",").ToList();
entryList.Sort((a, b) =>
{
var ai = sortOrder.IndexOf(a.section);
var bi = sortOrder.IndexOf(b.section);
// this is up here so -1 == -1 occurs first
if (ai == bi)
return 0;
if (ai == -1)
return -1;
if (bi == -1)
return 1;
return ai.CompareTo(bi);
});
return entryList;
}
private sealed class CrewManifestSection : BoxContainer
{
public CrewManifestSection(string sectionTitle, List<CrewManifestEntry> entries, IResourceCache cache, CrewManifestSystem crewManifestSystem)
{
Orientation = LayoutOrientation.Vertical;
HorizontalExpand = true;
AddChild(new Label()
{
StyleClasses = { "LabelBig" },
Text = Loc.GetString(sectionTitle)
});
entries.Sort((a, b) =>
{
var posA = crewManifestSystem.GetDepartmentOrder(sectionTitle, a.JobPrototype);
var posB = crewManifestSystem.GetDepartmentOrder(sectionTitle, b.JobPrototype);
return posA.CompareTo(posB);
});
var gridContainer = new GridContainer()
{
HorizontalExpand = true,
Columns = 2
};
AddChild(gridContainer);
var path = new ResourcePath("/Textures/Interface/Misc/job_icons.rsi");
cache.TryGetResource(path, out RSIResource? rsi);
foreach (var entry in entries)
{
var name = new Label()
{
HorizontalExpand = true,
Text = entry.Name
};
var titleContainer = new BoxContainer()
{
Orientation = LayoutOrientation.Horizontal,
HorizontalExpand = true
};
var title = new Label()
{
Text = Loc.GetString(entry.JobTitle)
};
if (rsi != null)
{
var icon = new TextureRect()
{
TextureScale = (2, 2),
Stretch = TextureRect.StretchMode.KeepCentered
};
if (rsi.RSI.TryGetState(entry.JobIcon, out _))
{
var specifier = new SpriteSpecifier.Rsi(path, entry.JobIcon);
icon.Texture = specifier.Frame0();
}
else if (rsi.RSI.TryGetState("Unknown", out _))
{
var specifier = new SpriteSpecifier.Rsi(path, "Unknown");
icon.Texture = specifier.Frame0();
}
titleContainer.AddChild(icon);
titleContainer.AddChild(title);
}
else
{
titleContainer.AddChild(title);
}
gridContainer.AddChild(name);
gridContainer.AddChild(titleContainer);
}
}
}
}