parent
428ca45cdb
commit
0f3eb79aa7
|
|
@ -14,6 +14,7 @@ using Robust.Client.UserInterface;
|
|||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Timing;
|
||||
using Content.Client._Impstation.ReadyManifest; // Impstation - Ready Manifest
|
||||
|
||||
namespace Content.Client.Lobby
|
||||
{
|
||||
|
|
@ -31,6 +32,7 @@ namespace Content.Client.Lobby
|
|||
|
||||
private ClientGameTicker _gameTicker = default!;
|
||||
private ContentAudioSystem _contentAudioSystem = default!;
|
||||
private ReadyManifestSystem _readyManifest = default!; // Impstation - Ready Manifest
|
||||
|
||||
protected override Type? LinkedScreenType { get; } = typeof(LobbyGui);
|
||||
public LobbyGui? Lobby;
|
||||
|
|
@ -48,6 +50,7 @@ namespace Content.Client.Lobby
|
|||
_gameTicker = _entityManager.System<ClientGameTicker>();
|
||||
_contentAudioSystem = _entityManager.System<ContentAudioSystem>();
|
||||
_contentAudioSystem.LobbySoundtrackChanged += UpdateLobbySoundtrackInfo;
|
||||
_readyManifest = _entityManager.EntitySysManager.GetEntitySystem<ReadyManifestSystem>(); // Impstation - Ready Manifest
|
||||
|
||||
chatController.SetMainChat(true);
|
||||
|
||||
|
|
@ -69,6 +72,7 @@ namespace Content.Client.Lobby
|
|||
Lobby.CharacterPreview.CharacterSetupButton.OnPressed += OnSetupPressed;
|
||||
Lobby.ReadyButton.OnPressed += OnReadyPressed;
|
||||
Lobby.ReadyButton.OnToggled += OnReadyToggled;
|
||||
Lobby.ManifestButton.OnPressed += OnManifestPressed; // Impstation - Ready Manifest
|
||||
|
||||
_gameTicker.InfoBlobUpdated += UpdateLobbyUi;
|
||||
_gameTicker.LobbyStatusUpdated += LobbyStatusUpdated;
|
||||
|
|
@ -89,6 +93,7 @@ namespace Content.Client.Lobby
|
|||
Lobby!.CharacterPreview.CharacterSetupButton.OnPressed -= OnSetupPressed;
|
||||
Lobby!.ReadyButton.OnPressed -= OnReadyPressed;
|
||||
Lobby!.ReadyButton.OnToggled -= OnReadyToggled;
|
||||
Lobby!.ManifestButton.OnPressed -= OnManifestPressed; // Impstation - Ready Manifest
|
||||
|
||||
Lobby = null;
|
||||
}
|
||||
|
|
@ -120,6 +125,12 @@ namespace Content.Client.Lobby
|
|||
SetReady(args.Pressed);
|
||||
}
|
||||
|
||||
// Impstation - Ready Manifest
|
||||
private void OnManifestPressed(BaseButton.ButtonEventArgs args)
|
||||
{
|
||||
_readyManifest.RequestReadyManifest();
|
||||
}
|
||||
|
||||
public override void FrameUpdate(FrameEventArgs e)
|
||||
{
|
||||
if (_gameTicker.IsGameStarted)
|
||||
|
|
@ -182,6 +193,7 @@ namespace Content.Client.Lobby
|
|||
Lobby!.ReadyButton.ToggleMode = false;
|
||||
Lobby!.ReadyButton.Pressed = false;
|
||||
Lobby!.ObserveButton.Disabled = false;
|
||||
Lobby!.ManifestButton.Disabled = true; //imp
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -191,6 +203,7 @@ namespace Content.Client.Lobby
|
|||
Lobby!.ReadyButton.ToggleMode = true;
|
||||
Lobby!.ReadyButton.Disabled = false;
|
||||
Lobby!.ObserveButton.Disabled = true;
|
||||
Lobby!.ManifestButton.Disabled = false; // imp
|
||||
}
|
||||
|
||||
if (_gameTicker.ServerInfoBlob != null)
|
||||
|
|
|
|||
|
|
@ -36,6 +36,10 @@
|
|||
Align="Left"
|
||||
FontColorOverride="{x:Static maths:Color.DarkGray}"
|
||||
StyleClasses="LabelBig" HorizontalExpand="True" />
|
||||
<!-- Imp manifest button -->
|
||||
<Button Name="ManifestButton" Access="Public"
|
||||
Text="Manifest"
|
||||
StyleClasses="ButtonBig" MinWidth="137" />
|
||||
<Button Name="ReadyButton" Access="Public" ToggleMode="True"
|
||||
Text="{Loc 'ui-lobby-ready-up-button'}"
|
||||
StyleClasses="ButtonBig" MinWidth="137" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
using Content.Client.Eui;
|
||||
using Content.Shared.Eui;
|
||||
using Content.Shared.ReadyManifest;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Content.Client._Impstation.ReadyManifest;
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed class ReadyManifestEui : BaseEui
|
||||
{
|
||||
private readonly ReadyManifestUi _window;
|
||||
|
||||
public ReadyManifestEui()
|
||||
{
|
||||
_window = new();
|
||||
|
||||
_window.OnClose += () =>
|
||||
{
|
||||
SendMessage(new CloseEuiMessage());
|
||||
};
|
||||
}
|
||||
|
||||
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 ReadyManifestEuiState cast)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_window.RebuildUI(cast.JobCounts);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
using Content.Shared.ReadyManifest;
|
||||
|
||||
namespace Content.Client._Impstation.ReadyManifest;
|
||||
|
||||
public sealed class ReadyManifestSystem : EntitySystem
|
||||
{
|
||||
private HashSet<string> _departments = new();
|
||||
|
||||
public IReadOnlySet<string> Departments => _departments;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
}
|
||||
|
||||
public void RequestReadyManifest()
|
||||
{
|
||||
RaiseNetworkEvent(new RequestReadyManifestMessage());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<DefaultWindow xmlns="https://spacestation14.io"
|
||||
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
|
||||
Title="Ready Manifest"
|
||||
SetSize="450 750">
|
||||
<BoxContainer HorizontalExpand="True" VerticalExpand="True">
|
||||
<ScrollContainer HorizontalExpand="True" VerticalExpand="True">
|
||||
<BoxContainer Name="ReadyManifestListing" Orientation="Vertical"/>
|
||||
</ScrollContainer>
|
||||
</BoxContainer>
|
||||
</DefaultWindow>
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Client._Impstation.ReadyManifest;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class ReadyManifestUi : DefaultWindow
|
||||
{
|
||||
private readonly IEntitySystemManager _entitySystem;
|
||||
private readonly IPrototypeManager _prototypeManager;
|
||||
private readonly ISharedPlayerManager _playerManager;
|
||||
private readonly Dictionary<string, BoxContainer> _jobCategories;
|
||||
private readonly SpriteSystem _sprite;
|
||||
|
||||
public ReadyManifestUi()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
_jobCategories = new Dictionary<string, BoxContainer>();
|
||||
_prototypeManager = IoCManager.Resolve<IPrototypeManager>();
|
||||
_playerManager = IoCManager.Resolve<ISharedPlayerManager>();
|
||||
_entitySystem = IoCManager.Resolve<IEntitySystemManager>();
|
||||
_sprite = _entitySystem.GetEntitySystem<SpriteSystem>();
|
||||
}
|
||||
|
||||
// Currently rebuilds the UI every time it's updated, should probably split department lookup and job counts into separate functions
|
||||
public void RebuildUI(Dictionary<ProtoId<JobPrototype>, int> jobCounts)
|
||||
{
|
||||
ReadyManifestListing.DisposeAllChildren();
|
||||
|
||||
_jobCategories.Clear();
|
||||
var departments = new List<DepartmentPrototype>();
|
||||
|
||||
foreach (var department in _prototypeManager.EnumeratePrototypes<DepartmentPrototype>())
|
||||
{
|
||||
if (department.EditorHidden)
|
||||
continue;
|
||||
|
||||
departments.Add(department);
|
||||
}
|
||||
|
||||
departments.Sort(DepartmentUIComparer.Instance);
|
||||
|
||||
foreach (var department in departments)
|
||||
{
|
||||
var departmentName = Loc.GetString($"department-{department.ID}");
|
||||
|
||||
if (!_jobCategories.TryGetValue(department.ID, out var category))
|
||||
{
|
||||
category = new BoxContainer
|
||||
{
|
||||
Orientation = BoxContainer.LayoutOrientation.Vertical,
|
||||
HorizontalExpand = true,
|
||||
Name = department.ID,
|
||||
ToolTip = Loc.GetString("humanoid-profile-editor-jobs-amount-in-department-tooltip",
|
||||
("departmentName", departmentName))
|
||||
};
|
||||
|
||||
category.AddChild(new Label()
|
||||
{
|
||||
StyleClasses = { "LabelBig" },
|
||||
Text = Loc.GetString($"department-{department.ID}")
|
||||
});
|
||||
|
||||
_jobCategories[department.ID] = category;
|
||||
ReadyManifestListing.AddChild(category);
|
||||
}
|
||||
|
||||
var jobs = department.Roles.Select(jobId => _prototypeManager.Index(jobId))
|
||||
.Where(job => job.SetPreference)
|
||||
.ToArray();
|
||||
|
||||
Array.Sort(jobs, JobUIComparer.Instance);
|
||||
|
||||
foreach (var job in jobs)
|
||||
{
|
||||
|
||||
var gridContainer = new GridContainer()
|
||||
{
|
||||
HorizontalExpand = true,
|
||||
Columns = 2
|
||||
};
|
||||
|
||||
var jobContainer = new BoxContainer()
|
||||
{
|
||||
Orientation = BoxContainer.LayoutOrientation.Horizontal,
|
||||
};
|
||||
|
||||
var title = new RichTextLabel()
|
||||
{
|
||||
HorizontalExpand = true
|
||||
};
|
||||
title.SetMessage(job.LocalizedName + ":");
|
||||
|
||||
var icon = new TextureRect
|
||||
{
|
||||
TextureScale = new Vector2(2, 2),
|
||||
VerticalAlignment = VAlignment.Center,
|
||||
Margin = new Thickness(0, 0, 4, 0)
|
||||
};
|
||||
|
||||
var readyCount = new RichTextLabel()
|
||||
{
|
||||
HorizontalExpand = true
|
||||
};
|
||||
|
||||
if (jobCounts.ContainsKey(job.ID))
|
||||
{
|
||||
var jobCount = jobCounts[job.ID];
|
||||
var color = jobCount > 0 ? Color.White : Color.Red;
|
||||
readyCount.SetMessage(jobCount.ToString(), null, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
readyCount.SetMessage("0", null, Color.Red);
|
||||
}
|
||||
|
||||
var jobIcon = _prototypeManager.Index(job.Icon);
|
||||
icon.Texture = _sprite.Frame0(jobIcon.Icon);
|
||||
jobContainer.AddChild(icon);
|
||||
jobContainer.AddChild(title);
|
||||
gridContainer.AddChild(jobContainer);
|
||||
gridContainer.AddChild(readyCount);
|
||||
category.AddChild(gridContainer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -157,6 +157,7 @@ namespace Content.Server.GameTicking
|
|||
if (!_playerManager.TryGetSessionById(playerUserId, out var playerSession))
|
||||
continue;
|
||||
RaiseNetworkEvent(GetStatusMsg(playerSession), playerSession.Channel);
|
||||
RaiseLocalEvent(new PlayerToggleReadyEvent(playerSession)); //imp edit, for preround ready manifest // imp ready manifest
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -173,8 +174,16 @@ namespace Content.Server.GameTicking
|
|||
return;
|
||||
}
|
||||
|
||||
// imp edit start, no need to update if the player is already (un)readied
|
||||
var status = ready ? PlayerGameStatus.ReadyToPlay : PlayerGameStatus.NotReadyToPlay;
|
||||
if (_playerGameStatuses[player.UserId] == status)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// imp edit end
|
||||
_playerGameStatuses[player.UserId] = ready ? PlayerGameStatus.ReadyToPlay : PlayerGameStatus.NotReadyToPlay;
|
||||
RaiseNetworkEvent(GetStatusMsg(player), player.Channel);
|
||||
RaiseLocalEvent(new PlayerToggleReadyEvent(player)); //imp edit, for preround ready manifest
|
||||
// update server info to reflect new ready count
|
||||
UpdateInfoText();
|
||||
}
|
||||
|
|
@ -185,4 +194,15 @@ namespace Content.Server.GameTicking
|
|||
public bool UserHasJoinedGame(NetUserId userId)
|
||||
=> PlayerGameStatuses.TryGetValue(userId, out var status) && status == PlayerGameStatus.JoinedGame;
|
||||
}
|
||||
|
||||
//imp addition, for preround ready manifest
|
||||
public sealed class PlayerToggleReadyEvent : EntityEventArgs
|
||||
{
|
||||
public readonly ICommonSession PlayerSession;
|
||||
|
||||
public PlayerToggleReadyEvent(ICommonSession playerSession)
|
||||
{
|
||||
PlayerSession = playerSession;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
using Content.Server.EUI;
|
||||
using Content.Shared.ReadyManifest;
|
||||
|
||||
namespace Content.Server.ReadyManifest;
|
||||
|
||||
public sealed class ReadyManifestEui : BaseEui
|
||||
{
|
||||
private readonly ReadyManifestSystem _readyManifest;
|
||||
|
||||
/// <summary>
|
||||
/// Current owner of this UI, if it has one. This is
|
||||
/// to ensure that if a BUI is closed, the EUIs related
|
||||
/// to the BUI are closed as well.
|
||||
/// </summary>
|
||||
public readonly EntityUid? Owner;
|
||||
|
||||
public ReadyManifestEui(EntityUid? owner, ReadyManifestSystem readyManifestSystem)
|
||||
{
|
||||
Owner = owner;
|
||||
_readyManifest = readyManifestSystem;
|
||||
}
|
||||
|
||||
public override ReadyManifestEuiState GetNewState()
|
||||
{
|
||||
var entries = _readyManifest.GetReadyManifest();
|
||||
return new(entries);
|
||||
}
|
||||
|
||||
public override void Closed()
|
||||
{
|
||||
base.Closed();
|
||||
|
||||
_readyManifest.CloseEui(Player, Owner);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
using System.Linq;
|
||||
using Content.Server.EUI;
|
||||
using Content.Shared.CCVar;
|
||||
using Content.Shared.GameTicking;
|
||||
using Content.Shared.Roles;
|
||||
using Content.Shared.Preferences;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Content.Shared.ReadyManifest;
|
||||
using Content.Server.GameTicking;
|
||||
using Content.Server.Preferences.Managers;
|
||||
using Content.Server.GameTicking.Events;
|
||||
|
||||
namespace Content.Server.ReadyManifest;
|
||||
|
||||
public sealed class ReadyManifestSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly EuiManager _euiManager = default!;
|
||||
[Dependency] private readonly IConfigurationManager _configManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly GameTicker _gameTicker = default!;
|
||||
[Dependency] private readonly IServerPreferencesManager _prefsManager = default!;
|
||||
|
||||
private readonly Dictionary<ICommonSession, ReadyManifestEui> _openEuis = new();
|
||||
private Dictionary<ProtoId<JobPrototype>, int> _jobCounts = new();
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeNetworkEvent<RequestReadyManifestMessage>(OnRequestReadyManifest);
|
||||
SubscribeLocalEvent<RoundStartingEvent>(OnRoundStarting);
|
||||
SubscribeLocalEvent<PlayerToggleReadyEvent>(OnPlayerToggleReady);
|
||||
}
|
||||
|
||||
private void OnRoundStarting(RoundStartingEvent ev)
|
||||
{
|
||||
foreach (var (_, eui) in _openEuis)
|
||||
{
|
||||
eui.Close();
|
||||
}
|
||||
|
||||
_openEuis.Clear();
|
||||
}
|
||||
|
||||
private void OnRequestReadyManifest(RequestReadyManifestMessage message, EntitySessionEventArgs args)
|
||||
{
|
||||
if (args.SenderSession is not { } sessionCast
|
||||
|| !_configManager.GetCVar(CCVars.CrewManifestWithoutEntity))
|
||||
{
|
||||
return;
|
||||
}
|
||||
BuildReadyManifest();
|
||||
OpenEui(sessionCast, args.SenderSession.AttachedEntity);
|
||||
}
|
||||
|
||||
private void OnPlayerToggleReady(PlayerToggleReadyEvent ev)
|
||||
{
|
||||
var userId = ev.PlayerSession.Data.UserId;
|
||||
|
||||
if (!_prefsManager.TryGetCachedPreferences(userId, out var preferences))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HumanoidCharacterProfile profile = (HumanoidCharacterProfile) preferences.SelectedCharacter;
|
||||
var profileJobs = FilterPlayerJobs(profile);
|
||||
|
||||
if (_gameTicker.PlayerGameStatuses[userId] == PlayerGameStatus.ReadyToPlay)
|
||||
{
|
||||
foreach (var job in profileJobs)
|
||||
{
|
||||
if (_jobCounts.ContainsKey(job))
|
||||
{
|
||||
_jobCounts[job]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
_jobCounts.Add(job, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var job in profileJobs)
|
||||
{
|
||||
if (_jobCounts.ContainsKey(job))
|
||||
{
|
||||
_jobCounts[job]--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpdateEuis();
|
||||
}
|
||||
|
||||
private void BuildReadyManifest()
|
||||
{
|
||||
var jobCounts = new Dictionary<ProtoId<JobPrototype>, int>();
|
||||
|
||||
foreach (var (userId, status) in _gameTicker.PlayerGameStatuses)
|
||||
{
|
||||
if (status == PlayerGameStatus.ReadyToPlay)
|
||||
{
|
||||
HumanoidCharacterProfile profile;
|
||||
if (_prefsManager.TryGetCachedPreferences(userId, out var preferences))
|
||||
{
|
||||
profile = (HumanoidCharacterProfile) preferences.SelectedCharacter;
|
||||
var profileJobs = FilterPlayerJobs(profile);
|
||||
foreach (var jobId in profileJobs)
|
||||
{
|
||||
if (jobCounts.ContainsKey(jobId))
|
||||
{
|
||||
jobCounts[jobId]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
jobCounts.Add(jobId, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_jobCounts = jobCounts;
|
||||
}
|
||||
|
||||
|
||||
private List<ProtoId<JobPrototype>> FilterPlayerJobs(HumanoidCharacterProfile profile)
|
||||
{
|
||||
var jobs = profile.JobPriorities.Keys.Select(k => new ProtoId<JobPrototype>(k)).ToList();
|
||||
List<ProtoId<JobPrototype>> priorityJobs = new();
|
||||
foreach (var job in jobs)
|
||||
{
|
||||
var priority = profile.JobPriorities[job];
|
||||
if (priority == JobPriority.High || (_prototypeManager.Index(job).Weight >= 10 && priority > JobPriority.Never))
|
||||
{
|
||||
priorityJobs.Add(job);
|
||||
}
|
||||
}
|
||||
return priorityJobs;
|
||||
}
|
||||
|
||||
public Dictionary<ProtoId<JobPrototype>, int> GetReadyManifest()
|
||||
{
|
||||
return _jobCounts;
|
||||
}
|
||||
|
||||
public void OpenEui(ICommonSession session, EntityUid? owner = null)
|
||||
{
|
||||
|
||||
|
||||
if (_openEuis.ContainsKey(session))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var eui = new ReadyManifestEui(owner, this);
|
||||
_openEuis.Add(session, eui);
|
||||
_euiManager.OpenEui(eui, session);
|
||||
eui.StateDirty();
|
||||
}
|
||||
|
||||
private void UpdateEuis()
|
||||
{
|
||||
foreach (var (_, eui) in _openEuis)
|
||||
{
|
||||
eui.StateDirty();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Closes an EUI for a given player.
|
||||
/// </summary>
|
||||
/// <param name="session">The player's session.</param>
|
||||
/// <param name="owner">The owner of this EUI, if there was one.</param>
|
||||
public void CloseEui(ICommonSession session, EntityUid? owner = null)
|
||||
{
|
||||
if (!_openEuis.TryGetValue(session, out var eui))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (eui.Owner == owner)
|
||||
{
|
||||
_openEuis.Remove(session);
|
||||
eui.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
using Content.Shared.Eui;
|
||||
using Content.Shared.Roles;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.ReadyManifest;
|
||||
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class RequestReadyManifestMessage : EntityEventArgs
|
||||
{
|
||||
public NetEntity Id { get; }
|
||||
|
||||
public RequestReadyManifestMessage()
|
||||
{
|
||||
//Id = id;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class ReadyManifestEuiState : EuiStateBase
|
||||
{
|
||||
public Dictionary<ProtoId<JobPrototype>, int> JobCounts { get; }
|
||||
|
||||
public ReadyManifestEuiState(Dictionary<ProtoId<JobPrototype>, int> jobCounts)
|
||||
{
|
||||
JobCounts = jobCounts;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue