Add cargo shuttle (#8686)

This commit is contained in:
metalgearsloth
2022-06-23 14:36:47 +10:00
committed by GitHub
parent b56b737b67
commit 77a8e16104
99 changed files with 4064 additions and 1356 deletions

View File

@@ -1,45 +1,46 @@
using Content.Client.Cargo.Components;
using Content.Client.Cargo.UI;
using Content.Shared.Access.Systems;
using Content.Shared.Cargo;
using Content.Shared.Cargo.BUI;
using Content.Shared.Cargo.Components;
using Content.Shared.Cargo.Events;
using Content.Shared.Cargo.Prototypes;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.ViewVariables;
using static Content.Shared.Cargo.Components.SharedCargoConsoleComponent;
using Robust.Client.Player;
using Robust.Shared.Prototypes;
using static Robust.Client.UserInterface.Controls.BaseButton;
namespace Content.Client.Cargo
namespace Content.Client.Cargo.BUI
{
public sealed class CargoConsoleBoundUserInterface : BoundUserInterface
public sealed class CargoOrderConsoleBoundUserInterface : BoundUserInterface
{
[ViewVariables]
private CargoConsoleMenu? _menu;
/// <summary>
/// This is the separate popup window for individual orders.
/// </summary>
[ViewVariables]
private CargoConsoleOrderMenu? _orderMenu;
[ViewVariables]
public CargoOrderDatabaseComponent? Orders { get; private set; }
[ViewVariables]
public bool RequestOnly { get; private set; }
[ViewVariables]
public int BankId { get; private set; }
[ViewVariables]
public string? BankName { get; private set; }
public string? AccountName { get; private set; }
[ViewVariables]
public int BankBalance { get; private set; }
[ViewVariables]
public (int CurrentCapacity, int MaxCapacity) ShuttleCapacity { get; private set; }
public int OrderCapacity { get; private set; }
[ViewVariables]
public int OrderCount { get; private set; }
/// <summary>
/// Currently selected product
/// </summary>
private CargoProductPrototype? _product;
public CargoConsoleBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
public CargoOrderConsoleBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
{
}
@@ -47,30 +48,29 @@ namespace Content.Client.Cargo
{
base.Open();
var entMan = IoCManager.Resolve<IEntityManager>();
if (!entMan.TryGetComponent(Owner.Owner, out CargoOrderDatabaseComponent? orders)) return;
var entityManager = IoCManager.Resolve<IEntityManager>();
var sysManager = entityManager.EntitySysManager;
var spriteSystem = sysManager.GetEntitySystem<SpriteSystem>();
_menu = new CargoConsoleMenu(IoCManager.Resolve<IPrototypeManager>(), spriteSystem);
var localPlayer = IoCManager.Resolve<IPlayerManager>()?.LocalPlayer?.ControlledEntity;
Orders = orders;
string orderRequester;
if (entityManager.TryGetComponent<MetaDataComponent>(localPlayer, out var metadata))
orderRequester = metadata.EntityName;
else
orderRequester = string.Empty;
_menu = new CargoConsoleMenu(this);
_orderMenu = new CargoConsoleOrderMenu();
_menu.OnClose += Close;
_menu.Populate();
Orders.OnDatabaseUpdated += _menu.PopulateOrders;
_menu.CallShuttleButton.OnPressed += (_) =>
{
SendMessage(new CargoConsoleShuttleMessage());
};
_menu.OnItemSelected += (args) =>
{
if (args.Button.Parent is not CargoProductRow row)
return;
_product = row.Product;
_orderMenu.Requester.Text = "";
_orderMenu.Requester.Text = orderRequester;
_orderMenu.Reason.Text = "";
_orderMenu.Amount.Value = 1;
_orderMenu.OpenCentered();
@@ -86,7 +86,15 @@ namespace Content.Client.Cargo
};
_menu.OpenCentered();
}
private void Populate(List<CargoOrderData> orders)
{
if (_menu == null) return;
_menu.PopulateProducts();
_menu.PopulateCategories();
_menu.PopulateOrders(orders);
}
protected override void UpdateState(BoundUserInterfaceState state)
@@ -95,17 +103,16 @@ namespace Content.Client.Cargo
if (state is not CargoConsoleInterfaceState cState)
return;
if (RequestOnly != cState.RequestOnly)
{
RequestOnly = cState.RequestOnly;
_menu?.UpdateRequestOnly();
}
BankId = cState.BankId;
BankName = cState.BankName;
BankBalance = cState.BankBalance;
ShuttleCapacity = cState.ShuttleCapacity;
_menu?.UpdateCargoCapacity();
_menu?.UpdateBankData();
OrderCapacity = cState.Capacity;
OrderCount = cState.Count;
BankBalance = cState.Balance;
AccountName = cState.Name;
Populate(cState.Orders);
_menu?.UpdateCargoCapacity(OrderCount, OrderCapacity);
_menu?.UpdateBankData(AccountName, BankBalance);
}
protected override void Dispose(bool disposing)
@@ -114,11 +121,6 @@ namespace Content.Client.Cargo
if (!disposing) return;
if (Orders != null && _menu != null)
{
Orders.OnDatabaseUpdated -= _menu.PopulateOrders;
}
_menu?.Dispose();
_orderMenu?.Dispose();
}
@@ -126,7 +128,7 @@ namespace Content.Client.Cargo
private bool AddOrder()
{
int orderAmt = _orderMenu?.Amount.Value ?? 0;
if (orderAmt < 1 || orderAmt > ShuttleCapacity.MaxCapacity)
if (orderAmt < 1 || orderAmt > OrderCapacity)
{
return false;
}
@@ -153,11 +155,12 @@ namespace Content.Client.Cargo
if (args.Button.Parent?.Parent is not CargoOrderRow row || row.Order == null)
return;
if (ShuttleCapacity.CurrentCapacity == ShuttleCapacity.MaxCapacity)
if (OrderCount >= OrderCapacity)
return;
SendMessage(new CargoConsoleApproveOrderMessage(row.Order.OrderNumber));
_menu?.UpdateCargoCapacity();
// Most of the UI isn't predicted anyway so.
// _menu?.UpdateCargoCapacity(OrderCount + row.Order.Amount, OrderCapacity);
}
}
}

View File

@@ -0,0 +1,57 @@
using Content.Client.Cargo.UI;
using Content.Shared.Cargo.BUI;
using Content.Shared.Cargo.Events;
using Robust.Client.GameObjects;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Content.Client.Cargo.BUI;
public sealed class CargoShuttleConsoleBoundUserInterface : BoundUserInterface
{
private CargoShuttleMenu? _menu;
public CargoShuttleConsoleBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey) {}
protected override void Open()
{
base.Open();
_menu = new CargoShuttleMenu(IoCManager.Resolve<IGameTiming>(), IoCManager.Resolve<IPrototypeManager>(), EntitySystem.Get<SpriteSystem>());
_menu.ShuttleCallRequested += OnShuttleCall;
_menu.ShuttleRecallRequested += OnShuttleRecall;
_menu.OnClose += Close;
_menu.OpenCentered();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
_menu?.Dispose();
}
}
private void OnShuttleRecall()
{
SendMessage(new CargoRecallShuttleMessage());
}
private void OnShuttleCall()
{
SendMessage(new CargoCallShuttleMessage());
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
if (state is not CargoShuttleConsoleBoundUserInterfaceState cargoState) return;
_menu?.SetAccountName(cargoState.AccountName);
_menu?.SetShuttleName(cargoState.ShuttleName);
_menu?.SetShuttleETA(cargoState.ShuttleETA);
_menu?.SetOrders(cargoState.Orders);
_menu?.SetCanRecall(cargoState.CanRecall);
}
}

View File

@@ -1,56 +0,0 @@
using System;
using System.Collections.Generic;
using Content.Shared.Cargo;
using Content.Shared.Cargo.Components;
using Robust.Shared.GameObjects;
namespace Content.Client.Cargo.Components
{
[RegisterComponent]
public sealed class CargoOrderDatabaseComponent : SharedCargoOrderDatabaseComponent
{
private readonly List<CargoOrderData> _orders = new();
public IReadOnlyList<CargoOrderData> Orders => _orders;
/// <summary>
/// Event called when the database is updated.
/// </summary>
public event Action? OnDatabaseUpdated;
// TODO add account selector menu
/// <summary>
/// Removes all orders from the database.
/// </summary>
public void Clear()
{
_orders.Clear();
}
/// <summary>
/// Adds an order to the database.
/// </summary>
/// <param name="order">The order to be added.</param>
public void AddOrder(CargoOrderData order)
{
if (!_orders.Contains(order))
_orders.Add(order);
}
public override void HandleComponentState(ComponentState? curState, ComponentState? nextState)
{
base.HandleComponentState(curState, nextState);
if (curState is not CargoOrderDatabaseState state)
return;
Clear();
if (state.Orders == null)
return;
foreach (var order in state.Orders)
{
AddOrder(order);
}
OnDatabaseUpdated?.Invoke();
}
}
}

View File

@@ -3,7 +3,7 @@ using Robust.Client.Animations;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
namespace Content.Client.Cargo;
namespace Content.Client.Cargo.Systems;
public sealed partial class CargoSystem
{

View File

@@ -1,7 +1,7 @@
using Content.Shared.Cargo;
using Robust.Client.GameObjects;
namespace Content.Client.Cargo;
namespace Content.Client.Cargo.Systems;
public sealed partial class CargoSystem : SharedCargoSystem
{

View File

@@ -1,7 +1,8 @@
<DefaultWindow xmlns="https://spacestation14.io"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
SetSize="400 600"
MinSize="400 600">
<userInterface:FancyWindow xmlns="https://spacestation14.io"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
xmlns:userInterface="clr-namespace:Content.Client.UserInterface"
SetSize="600 600"
MinSize="600 600">
<BoxContainer Orientation="Vertical">
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'cargo-console-menu-account-name-label'}"
@@ -15,28 +16,12 @@
<Label Name="PointsLabel"
Text="0" />
</BoxContainer>
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'cargo-console-menu-shuttle-status-label'}"
StyleClasses="LabelKeyText" />
<Label Name="ShuttleStatusLabel"
Text="{Loc 'cargo-console-menu-shuttle-status-away-text'}" />
</BoxContainer>
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'cargo-console-menu-order-capacity-label'}"
StyleClasses="LabelKeyText" />
<Label Name="ShuttleCapacityLabel"
Text="0/20" />
</BoxContainer>
<BoxContainer Orientation="Horizontal">
<Button Name="CallShuttleButton"
Access="Public"
Text="{Loc 'cargo-console-menu-call-shuttle-button'}"
TextAlign="Center"
HorizontalExpand="True"/>
<Button Name="PermissionsButton"
Text="{Loc 'cargo-console-menu-permissions-button'}"
TextAlign="Center" />
</BoxContainer>
<BoxContainer Orientation="Horizontal">
<OptionButton Name="Categories"
Prefix="{Loc 'cargo-console-menu-categories-label'}"
@@ -80,4 +65,4 @@
</PanelContainer>
<TextureButton VerticalExpand="True" />
</BoxContainer>
</DefaultWindow>
</userInterface:FancyWindow>

View File

@@ -1,31 +1,24 @@
using System;
using System.Collections.Generic;
using Content.Client.Stylesheets;
using System.Linq;
using Content.Client.UserInterface;
using Content.Shared.Cargo;
using Content.Shared.Cargo.Prototypes;
using Robust.Client.AutoGenerated;
using Robust.Client.Graphics;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Client.Utility;
using Robust.Shared.IoC;
using Robust.Shared.Prototypes;
using Robust.Shared.Localization;
using Robust.Shared.Log;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
using static Robust.Client.UserInterface.Controls.BaseButton;
using static Robust.Client.UserInterface.Controls.BoxContainer;
namespace Content.Client.Cargo.UI
{
[GenerateTypedNameReferences]
public sealed partial class CargoConsoleMenu : DefaultWindow
public sealed partial class CargoConsoleMenu : FancyWindow
{
[Dependency]
private IPrototypeManager _prototypeManager = default!;
public CargoConsoleBoundUserInterface Owner { get; private set; }
private IPrototypeManager _protoManager;
private SpriteSystem _spriteSystem;
public event Action<ButtonEventArgs>? OnItemSelected;
public event Action<ButtonEventArgs>? OnOrderApproved;
@@ -34,25 +27,18 @@ namespace Content.Client.Cargo.UI
private readonly List<string> _categoryStrings = new();
private string? _category;
public CargoConsoleMenu(CargoConsoleBoundUserInterface owner)
public CargoConsoleMenu(IPrototypeManager protoManager, SpriteSystem spriteSystem)
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
Owner = owner;
_protoManager = protoManager;
_spriteSystem = spriteSystem;
Title = Loc.GetString(Owner.RequestOnly
? "cargo-console-menu-request-only-title"
: "cargo-console-menu-title");
Title = Loc.GetString("cargo-console-menu-title");
CallShuttleButton.OnPressed += OnCallShuttleButtonPressed;
SearchBar.OnTextChanged += OnSearchBarTextChanged;
Categories.OnItemSelected += OnCategoryItemSelected;
}
private void OnCallShuttleButtonPressed(ButtonEventArgs args)
{
}
private void OnCategoryItemSelected(OptionButton.ItemSelectedEventArgs args)
{
SetCategoryText(args.Id);
@@ -70,7 +56,7 @@ namespace Content.Client.Cargo.UI
Categories.SelectId(id);
}
public IEnumerable<CargoProductPrototype> ProductPrototypes => _prototypeManager.EnumeratePrototypes<CargoProductPrototype>();
public IEnumerable<CargoProductPrototype> ProductPrototypes => _protoManager.EnumeratePrototypes<CargoProductPrototype>();
/// <summary>
/// Populates the list of products that will actually be shown, using the current filters.
@@ -78,9 +64,12 @@ namespace Content.Client.Cargo.UI
public void PopulateProducts()
{
Products.RemoveAllChildren();
var products = ProductPrototypes.ToList();
products.Sort((x, y) =>
string.Compare(x.Name, y.Name, StringComparison.Ordinal));
var search = SearchBar.Text.Trim().ToLowerInvariant();
foreach (var prototype in ProductPrototypes)
foreach (var prototype in products)
{
// if no search or category
// else if search
@@ -94,7 +83,7 @@ namespace Content.Client.Cargo.UI
Product = prototype,
ProductName = { Text = prototype.Name },
PointCost = { Text = prototype.PointCost.ToString() },
Icon = { Texture = prototype.Icon.Frame0() },
Icon = { Texture = _spriteSystem.Frame0(prototype.Icon) },
};
button.MainButton.OnPressed += args =>
{
@@ -132,31 +121,20 @@ namespace Content.Client.Cargo.UI
/// <summary>
/// Populates the list of orders and requests.
/// </summary>
public void PopulateOrders()
public void PopulateOrders(IEnumerable<CargoOrderData> orders)
{
Orders.RemoveAllChildren();
Requests.RemoveAllChildren();
Orders.DisposeAllChildren();
Requests.DisposeAllChildren();
if (Owner.Orders == null)
foreach (var order in orders)
{
return;
}
foreach (var order in Owner.Orders.Orders)
{
if (!_prototypeManager.TryIndex<CargoProductPrototype>(order.ProductId, out CargoProductPrototype? product))
{
DebugTools.Assert(false);
Logger.ErrorS("cargo", $"Unable to find product name for {order.ProductId}");
continue;
}
var product = _protoManager.Index<CargoProductPrototype>(order.ProductId);
var productName = product.Name;
var row = new CargoOrderRow
{
Order = order,
Icon = { Texture = product.Icon.Frame0() },
Icon = { Texture = _spriteSystem.Frame0(product.Icon) },
ProductName =
{
Text = Loc.GetString(
@@ -177,43 +155,23 @@ namespace Content.Client.Cargo.UI
}
else
{
if (Owner.RequestOnly)
row.Approve.Visible = false;
else
row.Approve.OnPressed += (args) => { OnOrderApproved?.Invoke(args); };
// TODO: Disable based on access.
row.Approve.OnPressed += (args) => { OnOrderApproved?.Invoke(args); };
Requests.AddChild(row);
}
}
}
public void Populate()
public void UpdateCargoCapacity(int count, int capacity)
{
PopulateProducts();
PopulateCategories();
PopulateOrders();
// TODO: Rename + Loc.
ShuttleCapacityLabel.Text = $"{count}/{capacity}";
}
public void UpdateCargoCapacity()
public void UpdateBankData(string name, int points)
{
ShuttleCapacityLabel.Text = $"{Owner.ShuttleCapacity.CurrentCapacity}/{Owner.ShuttleCapacity.MaxCapacity}";
}
public void UpdateBankData()
{
AccountNameLabel.Text = Owner.BankName;
PointsLabel.Text = Owner.BankBalance.ToString();
}
/// <summary>
/// Show/Hide Call Shuttle button and Approve buttons
/// </summary>
public void UpdateRequestOnly()
{
CallShuttleButton.Visible = !Owner.RequestOnly;
foreach (CargoOrderRow row in Requests.Children)
{
row.Approve.Visible = !Owner.RequestOnly;
}
AccountNameLabel.Text = name;
PointsLabel.Text = points.ToString();
}
}
}

View File

@@ -1,4 +1,5 @@
using Content.Shared.Cargo;
using Content.Shared.Cargo.Prototypes;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;

View File

@@ -0,0 +1,47 @@
<userInterface:FancyWindow xmlns="https://spacestation14.io"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
xmlns:userInterface="clr-namespace:Content.Client.UserInterface"
SetSize="600 600"
MinSize="600 600">
<BoxContainer Orientation="Vertical">
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'cargo-console-menu-account-name-label'}"
StyleClasses="LabelKeyText" />
<Label Name="AccountNameLabel"
Text="{Loc 'cargo-console-menu-account-name-none-text'}" />
</BoxContainer>
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'cargo-console-menu-shuttle-name-label'}"
StyleClasses="LabelKeyText" />
<Label Name="ShuttleNameLabel"
Text="{Loc 'cargo-console-menu-shuttle-name-none-text'}" />
</BoxContainer>
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'cargo-console-menu-shuttle-status-label'}"
StyleClasses="LabelKeyText" />
<Label Name="ShuttleStatusLabel"
Text="{Loc 'cargo-console-menu-shuttle-status-away-text'}" />
</BoxContainer>
<Button Name="ShuttleCallButton"
Text="Call Shuttle"/>
<Button Name="ShuttleRecallButton"
Text="Recall Shuttle"
ToolTip="Needs to be out of range to recall."
Visible="False"/>
<Label Text="{Loc 'cargo-console-menu-orders-label'}" />
<PanelContainer VerticalExpand="True"
SizeFlagsStretchRatio="6">
<PanelContainer.PanelOverride>
<gfx:StyleBoxFlat BackgroundColor="#000000" />
</PanelContainer.PanelOverride>
<ScrollContainer VerticalExpand="True">
<BoxContainer Name="Orders"
Orientation="Vertical"
StyleClasses="transparentItemList"
VerticalExpand="True">
</BoxContainer>
</ScrollContainer>
</PanelContainer>
<TextureButton VerticalExpand="True" />
</BoxContainer>
</userInterface:FancyWindow>

View File

@@ -0,0 +1,128 @@
using Content.Client.UserInterface;
using Content.Shared.Cargo;
using Content.Shared.Cargo.Prototypes;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Content.Client.Cargo.UI
{
[GenerateTypedNameReferences]
public sealed partial class CargoShuttleMenu : FancyWindow
{
private readonly IGameTiming _timing;
private readonly IPrototypeManager _protoManager;
private readonly SpriteSystem _spriteSystem;
public Action? ShuttleCallRequested;
public Action? ShuttleRecallRequested;
private TimeSpan? _shuttleEta;
public CargoShuttleMenu(IGameTiming timing, IPrototypeManager protoManager, SpriteSystem spriteSystem)
{
RobustXamlLoader.Load(this);
_timing = timing;
_protoManager = protoManager;
_spriteSystem = spriteSystem;
ShuttleCallButton.OnPressed += OnCallPressed;
ShuttleRecallButton.OnPressed += OnRecallPressed;
Title = Loc.GetString("cargo-shuttle-console-menu-title");
}
public void SetAccountName(string name)
{
AccountNameLabel.Text = name;
}
public void SetShuttleName(string name)
{
ShuttleNameLabel.Text = name;
}
public void SetShuttleETA(TimeSpan? eta)
{
_shuttleEta = eta;
if (eta == null)
{
ShuttleCallButton.Visible = false;
ShuttleRecallButton.Visible = true;
}
else
{
ShuttleRecallButton.Visible = false;
ShuttleCallButton.Visible = true;
ShuttleCallButton.Disabled = true;
}
}
private void OnRecallPressed(BaseButton.ButtonEventArgs obj)
{
ShuttleRecallRequested?.Invoke();
}
private void OnCallPressed(BaseButton.ButtonEventArgs obj)
{
ShuttleCallRequested?.Invoke();
}
public void SetOrders(List<CargoOrderData> orders)
{
Orders.DisposeAllChildren();
foreach (var order in orders)
{
var product = _protoManager.Index<CargoProductPrototype>(order.ProductId);
var productName = product.Name;
var row = new CargoOrderRow
{
Order = order,
Icon = { Texture = _spriteSystem.Frame0(product.Icon) },
ProductName =
{
Text = Loc.GetString(
"cargo-console-menu-populate-orders-cargo-order-row-product-name-text",
("productName", productName),
("orderAmount", order.Amount),
("orderRequester", order.Requester))
},
Description = {Text = Loc.GetString("cargo-console-menu-order-reason-description",
("reason", order.Reason))}
};
row.Approve.Visible = false;
row.Cancel.Visible = false;
Orders.AddChild(row);
}
}
public void SetCanRecall(bool canRecall)
{
ShuttleRecallButton.Disabled = !canRecall;
}
protected override void Draw(DrawingHandleScreen handle)
{
base.Draw(handle);
var remaining = _shuttleEta - _timing.CurTime;
if (remaining == null || remaining <= TimeSpan.Zero)
{
ShuttleStatusLabel.Text = $"Available";
ShuttleCallButton.Disabled = false;
}
else
{
ShuttleStatusLabel.Text = $"Available in: {remaining.Value.TotalSeconds:0.0}";
}
}
}
}

View File

@@ -1,45 +0,0 @@
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
namespace Content.Client.Cargo.UI
{
public sealed class GalacticBankSelectionMenu : DefaultWindow
{
private readonly ItemList _accounts;
private int _accountCount;
private string[] _accountNames = System.Array.Empty<string>();
private int[] _accountIds = System.Array.Empty<int>();
private int _selectedAccountId = -1;
public GalacticBankSelectionMenu(CargoConsoleBoundUserInterface owner)
{
MinSize = SetSize = (300, 300);
IoCManager.InjectDependencies(this);
Title = Loc.GetString("galactic-bank-selection-menu-title");
_accounts = new ItemList { SelectMode = ItemList.ItemListSelectMode.Single };
Contents.AddChild(_accounts);
}
public void Populate(int accountCount, string[] accountNames, int[] accountIds, int selectedAccountId)
{
_accountCount = accountCount;
_accountNames = accountNames;
_accountIds = accountIds;
_selectedAccountId = selectedAccountId;
_accounts.Clear();
for (var i = 0; i < _accountCount; i++)
{
var id = _accountIds[i];
_accounts.AddItem($"ID: {id} || {_accountNames[i]}");
if (id == _selectedAccountId)
_accounts[id].Selected = true;
}
}
}
}

View File

@@ -74,7 +74,6 @@ namespace Content.Client.Entry
factory.RegisterClass<SharedLatheComponent>();
factory.RegisterClass<SharedSpawnPointComponent>();
factory.RegisterClass<SharedVendingMachineComponent>();
factory.RegisterClass<SharedCargoConsoleComponent>();
factory.RegisterClass<SharedReagentDispenserComponent>();
factory.RegisterClass<SharedChemMasterComponent>();
factory.RegisterClass<SharedGravityGeneratorComponent>();

View File

@@ -24,6 +24,7 @@ public sealed class RadarConsoleBoundUserInterface : BoundUserInterface
base.UpdateState(state);
if (state is not RadarConsoleBoundInterfaceState cState) return;
_window?.SetMatrix(cState.Coordinates, cState.Angle);
_window?.UpdateState(cState);
}
}

View File

@@ -65,6 +65,8 @@ public sealed class ShuttleConsoleBoundUserInterface : BoundUserInterface
{
base.UpdateState(state);
if (state is not ShuttleConsoleBoundInterfaceState cState) return;
_window?.SetMatrix(cState.Coordinates, cState.Angle);
_window?.UpdateState(cState);
}
}

View File

@@ -2,20 +2,4 @@ using Content.Shared.Shuttles.Events;
namespace Content.Client.Shuttles.Systems;
public sealed class DockingSystem : EntitySystem
{
public void StartAutodock(EntityUid uid)
{
RaiseNetworkEvent(new AutodockRequestMessage {Entity = uid});
}
public void StopAutodock(EntityUid uid)
{
RaiseNetworkEvent(new StopAutodockRequestMessage() {Entity = uid});
}
public void Undock(EntityUid uid)
{
RaiseNetworkEvent(new UndockRequestMessage() {Entity = uid});
}
}
public sealed class DockingSystem : EntitySystem {}

View File

@@ -31,6 +31,9 @@ public class DockingControl : Control
public EntityUid? ViewedDock;
public EntityUid? GridEntity;
public EntityCoordinates? Coordinates;
public Angle? Angle;
/// <summary>
/// Stored by GridID then by docks
/// </summary>
@@ -69,11 +72,12 @@ public class DockingControl : Control
handle.DrawLine((MidPoint, MidPoint) - aExtent, (MidPoint, MidPoint) + aExtent, gridLines);
}
if (!_entManager.TryGetComponent<TransformComponent>(ViewedDock, out var xform) ||
if (Coordinates == null ||
Angle == null ||
!_entManager.TryGetComponent<TransformComponent>(GridEntity, out var gridXform)) return;
var rotation = Matrix3.CreateRotation(xform.LocalRotation);
var matrix = Matrix3.CreateTranslation(-xform.LocalPosition);
var rotation = Matrix3.CreateRotation(Angle.Value);
var matrix = Matrix3.CreateTranslation(-Coordinates.Value.Position);
// Draw the fixtures around the dock before drawing it
if (_entManager.TryGetComponent<FixturesComponent>(GridEntity, out var fixtures))
@@ -128,7 +132,7 @@ public class DockingControl : Control
ScalePosition(rotation.Transform(new Vector2(0.5f, -0.5f)))), Color.Green);
// Draw nearby grids
var worldPos = gridXform.WorldMatrix.Transform(xform.LocalPosition);
var worldPos = gridXform.WorldMatrix.Transform(Coordinates.Value.Position);
var gridInvMatrix = gridXform.InvWorldMatrix;
Matrix3.Multiply(in gridInvMatrix, in matrix, out var invMatrix);

View File

@@ -3,6 +3,7 @@ using Content.Client.UserInterface;
using Content.Shared.Shuttles.BUIStates;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Map;
namespace Content.Client.Shuttles.UI;
@@ -19,4 +20,9 @@ public sealed partial class RadarConsoleWindow : FancyWindow,
{
RadarScreen.UpdateState(scc);
}
public void SetMatrix(EntityCoordinates? coordinates, Angle? angle)
{
RadarScreen.SetMatrix(coordinates, angle);
}
}

View File

@@ -25,9 +25,11 @@ public sealed class RadarControl : Control
private const float GridLinesDistance = 32f;
/// <summary>
/// Entity used to transform all of the radar objects.
/// Used to transform all of the radar objects. Typically is a shuttle console parented to a grid.
/// </summary>
private EntityUid? _entity;
private EntityCoordinates? _coordinates;
private Angle? _rotation;
private float _radarMinRange = 64f;
private float _radarMaxRange = 256f;
@@ -61,6 +63,12 @@ public sealed class RadarControl : Control
MinSize = (SizeFull, SizeFull);
}
public void SetMatrix(EntityCoordinates? coordinates, Angle? angle)
{
_coordinates = coordinates;
_rotation = angle;
}
public void UpdateState(RadarConsoleBoundInterfaceState ls)
{
_radarMaxRange = ls.MaxRange;
@@ -74,7 +82,6 @@ public sealed class RadarControl : Control
if (_radarMaxRange < _radarMinRange)
_radarMinRange = _radarMaxRange;
_entity = ls.Entity;
_docks.Clear();
foreach (var state in ls.Docks)
@@ -109,7 +116,7 @@ public sealed class RadarControl : Control
handle.DrawCircle((MidPoint, MidPoint), ScaledMinimapRadius, Color.Black);
// No data
if (_entity == null)
if (_coordinates == null || _rotation == null)
{
Clear();
return;
@@ -135,8 +142,8 @@ public sealed class RadarControl : Control
var xformQuery = _entManager.GetEntityQuery<TransformComponent>();
var fixturesQuery = _entManager.GetEntityQuery<FixturesComponent>();
var bodyQuery = _entManager.GetEntityQuery<PhysicsComponent>();
var xform = xformQuery.GetComponent(_entity.Value);
var mapPosition = xform.MapPosition;
var mapPosition = _coordinates.Value.ToMap(_entManager);
if (mapPosition.MapId == MapId.Nullspace)
{
@@ -144,28 +151,30 @@ public sealed class RadarControl : Control
return;
}
// Can also use ourGridBody.LocalCenter
var offset = xform.Coordinates.Position;
var offsetMatrix = Matrix3.CreateTranslation(-offset);
var offset = _coordinates.Value.Position;
Matrix3 matrix;
// Draw our grid in detail
var ourGridId = xform.GridUid;
var ourGridId = _coordinates.Value.GetGridUid(_entManager);
if (ourGridId != null)
{
matrix = xform.InvWorldMatrix;
var offsetMatrix = Matrix3.CreateInverseTransform(offset.X, offset.Y, (float) _rotation.Value.Theta);
var ourGridFixtures = fixturesQuery.GetComponent(ourGridId.Value);
// Draw our grid; use non-filled boxes so it doesn't look awful.
DrawGrid(handle, offsetMatrix, ourGridFixtures, Color.Yellow);
DrawDocks(handle, ourGridId.Value, offsetMatrix);
var ourGridMatrix = xformQuery.GetComponent(ourGridId.Value).InvWorldMatrix;
Matrix3.Multiply(in ourGridMatrix, in offsetMatrix, out matrix);
}
else
{
matrix = Matrix3.CreateTranslation(-offset);
}
var invertedPosition = xform.Coordinates.Position - offset;
var invertedPosition = _coordinates.Value.Position - offset;
invertedPosition.Y = -invertedPosition.Y;
// Don't need to transform the InvWorldMatrix again as it's already offset to its position.

View File

@@ -7,6 +7,7 @@ using Robust.Client.Graphics;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Map;
using Robust.Shared.Utility;
namespace Content.Client.Shuttles.UI;
@@ -17,10 +18,7 @@ public sealed partial class ShuttleConsoleWindow : FancyWindow,
{
private readonly IEntityManager _entManager;
/// <summary>
/// EntityUid of the open console.
/// </summary>
private EntityUid? _entity;
private EntityUid? _shuttleUid;
/// <summary>
/// Currently selected dock button for camera.
@@ -84,9 +82,14 @@ public sealed partial class ShuttleConsoleWindow : FancyWindow,
UndockPressed?.Invoke(DockingScreen.ViewedDock.Value);
}
public void SetMatrix(EntityCoordinates? coordinates, Angle? angle)
{
_shuttleUid = coordinates?.EntityId;
RadarScreen.SetMatrix(coordinates, angle);
}
public void UpdateState(ShuttleConsoleBoundInterfaceState scc)
{
_entity = scc.Entity;
UpdateDocks(scc.Docks);
RadarScreen.UpdateState(scc);
MaxRadarRange.Text = $"{scc.MaxRange:0}";
@@ -110,21 +113,16 @@ public sealed partial class ShuttleConsoleWindow : FancyWindow,
DockPorts.DisposeAllChildren();
DockingScreen.Docks = _docks;
if (!_entManager.TryGetComponent<TransformComponent>(_entity, out var xform)
|| !xform.GridUid.HasValue)
{
// TODO: Show Placeholder
return;
}
if (_docks.TryGetValue(xform.GridUid.Value, out var gridDocks))
// TODO: Show Placeholder
if (_shuttleUid != null && _docks.TryGetValue(_shuttleUid.Value, out var gridDocks))
{
var index = 1;
foreach (var state in gridDocks)
{
var ent = state.Entity;
var pressed = ent == DockingScreen.ViewedDock;
var pressed = state.Entity == DockingScreen.ViewedDock;
string suffix;
if (state.Connected)
@@ -143,21 +141,26 @@ public sealed partial class ShuttleConsoleWindow : FancyWindow,
Pressed = pressed,
};
button.OnMouseEntered += args => OnDockMouseEntered(args, ent);
button.OnMouseExited += args => OnDockMouseExited(args, ent);
button.OnToggled += args => OnDockToggled(args, ent);
if (pressed)
{
_selectedDock = button;
}
button.OnMouseEntered += args => OnDockMouseEntered(args, state);
button.OnMouseExited += args => OnDockMouseExited(args, state);
button.OnToggled += args => OnDockToggled(args, state);
DockPorts.AddChild(button);
index++;
}
}
}
private void OnDockMouseEntered(GUIMouseHoverEventArgs obj, EntityUid uid)
private void OnDockMouseEntered(GUIMouseHoverEventArgs obj, DockingInterfaceState state)
{
RadarScreen.HighlightedDock = uid;
RadarScreen.HighlightedDock = state.Entity;
}
private void OnDockMouseExited(GUIMouseHoverEventArgs obj, EntityUid uid)
private void OnDockMouseExited(GUIMouseHoverEventArgs obj, DockingInterfaceState state)
{
RadarScreen.HighlightedDock = null;
}
@@ -165,10 +168,18 @@ public sealed partial class ShuttleConsoleWindow : FancyWindow,
/// <summary>
/// Shows a docking camera instead of radar screen.
/// </summary>
private void OnDockToggled(BaseButton.ButtonEventArgs obj, EntityUid ent)
private void OnDockToggled(BaseButton.ButtonEventArgs obj, DockingInterfaceState state)
{
var ent = state.Entity;
if (_selectedDock != null)
{
// If it got untoggled via other means then we'll stop viewing the old dock.
if (DockingScreen.ViewedDock != null && DockingScreen.ViewedDock != state.Entity)
{
StopAutodockPressed?.Invoke(DockingScreen.ViewedDock.Value);
}
_selectedDock.Pressed = false;
_selectedDock = null;
}
@@ -187,15 +198,23 @@ public sealed partial class ShuttleConsoleWindow : FancyWindow,
}
else
{
// DebugTools.Assert(DockingScreen.ViewedDock == null);
_entManager.TryGetComponent<TransformComponent>(_entity, out var xform);
if (_shuttleUid != null)
{
DockingScreen.Coordinates = state.Coordinates;
DockingScreen.Angle = state.Angle;
}
else
{
DockingScreen.Coordinates = null;
DockingScreen.Angle = null;
}
UndockButton.Disabled = false;
RadarScreen.Visible = false;
DockingScreen.Visible = true;
DockingScreen.ViewedDock = ent;
StartAutodockPressed?.Invoke(ent);
DockingScreen.GridEntity = xform?.GridUid;
DockingScreen.GridEntity = _shuttleUid;
_selectedDock = obj.Button;
}
}
@@ -215,9 +234,8 @@ public sealed partial class ShuttleConsoleWindow : FancyWindow,
{
base.Draw(handle);
if (!_entManager.TryGetComponent<TransformComponent>(_entity, out var entXform) ||
!_entManager.TryGetComponent<PhysicsComponent>(entXform.GridUid, out var gridBody) ||
!_entManager.TryGetComponent<TransformComponent>(entXform.GridUid, out var gridXform))
if (!_entManager.TryGetComponent<PhysicsComponent>(_shuttleUid, out var gridBody) ||
!_entManager.TryGetComponent<TransformComponent>(_shuttleUid, out var gridXform))
{
return;
}