Add cargo shuttle (#8686)
This commit is contained in:
@@ -1,45 +1,46 @@
|
|||||||
using Content.Client.Cargo.Components;
|
|
||||||
using Content.Client.Cargo.UI;
|
using Content.Client.Cargo.UI;
|
||||||
|
using Content.Shared.Access.Systems;
|
||||||
using Content.Shared.Cargo;
|
using Content.Shared.Cargo;
|
||||||
|
using Content.Shared.Cargo.BUI;
|
||||||
using Content.Shared.Cargo.Components;
|
using Content.Shared.Cargo.Components;
|
||||||
|
using Content.Shared.Cargo.Events;
|
||||||
|
using Content.Shared.Cargo.Prototypes;
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Client.Player;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.ViewVariables;
|
|
||||||
using static Content.Shared.Cargo.Components.SharedCargoConsoleComponent;
|
|
||||||
using static Robust.Client.UserInterface.Controls.BaseButton;
|
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]
|
[ViewVariables]
|
||||||
private CargoConsoleMenu? _menu;
|
private CargoConsoleMenu? _menu;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is the separate popup window for individual orders.
|
||||||
|
/// </summary>
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private CargoConsoleOrderMenu? _orderMenu;
|
private CargoConsoleOrderMenu? _orderMenu;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public CargoOrderDatabaseComponent? Orders { get; private set; }
|
public string? AccountName { get; private set; }
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
public bool RequestOnly { get; private set; }
|
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
public int BankId { get; private set; }
|
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
public string? BankName { get; private set; }
|
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public int BankBalance { get; private set; }
|
public int BankBalance { get; private set; }
|
||||||
|
|
||||||
[ViewVariables]
|
[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;
|
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();
|
base.Open();
|
||||||
|
|
||||||
var entMan = IoCManager.Resolve<IEntityManager>();
|
var entityManager = IoCManager.Resolve<IEntityManager>();
|
||||||
if (!entMan.TryGetComponent(Owner.Owner, out CargoOrderDatabaseComponent? orders)) return;
|
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();
|
_orderMenu = new CargoConsoleOrderMenu();
|
||||||
|
|
||||||
_menu.OnClose += Close;
|
_menu.OnClose += Close;
|
||||||
|
|
||||||
_menu.Populate();
|
|
||||||
|
|
||||||
Orders.OnDatabaseUpdated += _menu.PopulateOrders;
|
|
||||||
|
|
||||||
_menu.CallShuttleButton.OnPressed += (_) =>
|
|
||||||
{
|
|
||||||
SendMessage(new CargoConsoleShuttleMessage());
|
|
||||||
};
|
|
||||||
_menu.OnItemSelected += (args) =>
|
_menu.OnItemSelected += (args) =>
|
||||||
{
|
{
|
||||||
if (args.Button.Parent is not CargoProductRow row)
|
if (args.Button.Parent is not CargoProductRow row)
|
||||||
return;
|
return;
|
||||||
_product = row.Product;
|
_product = row.Product;
|
||||||
_orderMenu.Requester.Text = "";
|
_orderMenu.Requester.Text = orderRequester;
|
||||||
_orderMenu.Reason.Text = "";
|
_orderMenu.Reason.Text = "";
|
||||||
_orderMenu.Amount.Value = 1;
|
_orderMenu.Amount.Value = 1;
|
||||||
_orderMenu.OpenCentered();
|
_orderMenu.OpenCentered();
|
||||||
@@ -86,7 +86,15 @@ namespace Content.Client.Cargo
|
|||||||
};
|
};
|
||||||
|
|
||||||
_menu.OpenCentered();
|
_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)
|
protected override void UpdateState(BoundUserInterfaceState state)
|
||||||
@@ -95,17 +103,16 @@ namespace Content.Client.Cargo
|
|||||||
|
|
||||||
if (state is not CargoConsoleInterfaceState cState)
|
if (state is not CargoConsoleInterfaceState cState)
|
||||||
return;
|
return;
|
||||||
if (RequestOnly != cState.RequestOnly)
|
|
||||||
{
|
OrderCapacity = cState.Capacity;
|
||||||
RequestOnly = cState.RequestOnly;
|
OrderCount = cState.Count;
|
||||||
_menu?.UpdateRequestOnly();
|
BankBalance = cState.Balance;
|
||||||
}
|
|
||||||
BankId = cState.BankId;
|
AccountName = cState.Name;
|
||||||
BankName = cState.BankName;
|
|
||||||
BankBalance = cState.BankBalance;
|
Populate(cState.Orders);
|
||||||
ShuttleCapacity = cState.ShuttleCapacity;
|
_menu?.UpdateCargoCapacity(OrderCount, OrderCapacity);
|
||||||
_menu?.UpdateCargoCapacity();
|
_menu?.UpdateBankData(AccountName, BankBalance);
|
||||||
_menu?.UpdateBankData();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
protected override void Dispose(bool disposing)
|
||||||
@@ -114,11 +121,6 @@ namespace Content.Client.Cargo
|
|||||||
|
|
||||||
if (!disposing) return;
|
if (!disposing) return;
|
||||||
|
|
||||||
if (Orders != null && _menu != null)
|
|
||||||
{
|
|
||||||
Orders.OnDatabaseUpdated -= _menu.PopulateOrders;
|
|
||||||
}
|
|
||||||
|
|
||||||
_menu?.Dispose();
|
_menu?.Dispose();
|
||||||
_orderMenu?.Dispose();
|
_orderMenu?.Dispose();
|
||||||
}
|
}
|
||||||
@@ -126,7 +128,7 @@ namespace Content.Client.Cargo
|
|||||||
private bool AddOrder()
|
private bool AddOrder()
|
||||||
{
|
{
|
||||||
int orderAmt = _orderMenu?.Amount.Value ?? 0;
|
int orderAmt = _orderMenu?.Amount.Value ?? 0;
|
||||||
if (orderAmt < 1 || orderAmt > ShuttleCapacity.MaxCapacity)
|
if (orderAmt < 1 || orderAmt > OrderCapacity)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -153,11 +155,12 @@ namespace Content.Client.Cargo
|
|||||||
if (args.Button.Parent?.Parent is not CargoOrderRow row || row.Order == null)
|
if (args.Button.Parent?.Parent is not CargoOrderRow row || row.Order == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ShuttleCapacity.CurrentCapacity == ShuttleCapacity.MaxCapacity)
|
if (OrderCount >= OrderCapacity)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SendMessage(new CargoConsoleApproveOrderMessage(row.Order.OrderNumber));
|
SendMessage(new CargoConsoleApproveOrderMessage(row.Order.OrderNumber));
|
||||||
_menu?.UpdateCargoCapacity();
|
// Most of the UI isn't predicted anyway so.
|
||||||
|
// _menu?.UpdateCargoCapacity(OrderCount + row.Order.Amount, OrderCapacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,7 @@ using Robust.Client.Animations;
|
|||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
|
|
||||||
namespace Content.Client.Cargo;
|
namespace Content.Client.Cargo.Systems;
|
||||||
|
|
||||||
public sealed partial class CargoSystem
|
public sealed partial class CargoSystem
|
||||||
{
|
{
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using Content.Shared.Cargo;
|
using Content.Shared.Cargo;
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
|
|
||||||
namespace Content.Client.Cargo;
|
namespace Content.Client.Cargo.Systems;
|
||||||
|
|
||||||
public sealed partial class CargoSystem : SharedCargoSystem
|
public sealed partial class CargoSystem : SharedCargoSystem
|
||||||
{
|
{
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
<DefaultWindow xmlns="https://spacestation14.io"
|
<userInterface:FancyWindow xmlns="https://spacestation14.io"
|
||||||
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
|
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
|
||||||
SetSize="400 600"
|
xmlns:userInterface="clr-namespace:Content.Client.UserInterface"
|
||||||
MinSize="400 600">
|
SetSize="600 600"
|
||||||
|
MinSize="600 600">
|
||||||
<BoxContainer Orientation="Vertical">
|
<BoxContainer Orientation="Vertical">
|
||||||
<BoxContainer Orientation="Horizontal">
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc 'cargo-console-menu-account-name-label'}"
|
<Label Text="{Loc 'cargo-console-menu-account-name-label'}"
|
||||||
@@ -15,28 +16,12 @@
|
|||||||
<Label Name="PointsLabel"
|
<Label Name="PointsLabel"
|
||||||
Text="0" />
|
Text="0" />
|
||||||
</BoxContainer>
|
</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">
|
<BoxContainer Orientation="Horizontal">
|
||||||
<Label Text="{Loc 'cargo-console-menu-order-capacity-label'}"
|
<Label Text="{Loc 'cargo-console-menu-order-capacity-label'}"
|
||||||
StyleClasses="LabelKeyText" />
|
StyleClasses="LabelKeyText" />
|
||||||
<Label Name="ShuttleCapacityLabel"
|
<Label Name="ShuttleCapacityLabel"
|
||||||
Text="0/20" />
|
Text="0/20" />
|
||||||
</BoxContainer>
|
</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">
|
<BoxContainer Orientation="Horizontal">
|
||||||
<OptionButton Name="Categories"
|
<OptionButton Name="Categories"
|
||||||
Prefix="{Loc 'cargo-console-menu-categories-label'}"
|
Prefix="{Loc 'cargo-console-menu-categories-label'}"
|
||||||
@@ -80,4 +65,4 @@
|
|||||||
</PanelContainer>
|
</PanelContainer>
|
||||||
<TextureButton VerticalExpand="True" />
|
<TextureButton VerticalExpand="True" />
|
||||||
</BoxContainer>
|
</BoxContainer>
|
||||||
</DefaultWindow>
|
</userInterface:FancyWindow>
|
||||||
|
|||||||
@@ -1,31 +1,24 @@
|
|||||||
using System;
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
using Content.Client.UserInterface;
|
||||||
using Content.Client.Stylesheets;
|
|
||||||
using Content.Shared.Cargo;
|
using Content.Shared.Cargo;
|
||||||
|
using Content.Shared.Cargo.Prototypes;
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.GameObjects;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
using Robust.Client.Utility;
|
using Robust.Client.Utility;
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Localization;
|
|
||||||
using Robust.Shared.Log;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
using static Robust.Client.UserInterface.Controls.BaseButton;
|
using static Robust.Client.UserInterface.Controls.BaseButton;
|
||||||
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
|
||||||
|
|
||||||
namespace Content.Client.Cargo.UI
|
namespace Content.Client.Cargo.UI
|
||||||
{
|
{
|
||||||
[GenerateTypedNameReferences]
|
[GenerateTypedNameReferences]
|
||||||
public sealed partial class CargoConsoleMenu : DefaultWindow
|
public sealed partial class CargoConsoleMenu : FancyWindow
|
||||||
{
|
{
|
||||||
[Dependency]
|
private IPrototypeManager _protoManager;
|
||||||
private IPrototypeManager _prototypeManager = default!;
|
private SpriteSystem _spriteSystem;
|
||||||
|
|
||||||
public CargoConsoleBoundUserInterface Owner { get; private set; }
|
|
||||||
|
|
||||||
public event Action<ButtonEventArgs>? OnItemSelected;
|
public event Action<ButtonEventArgs>? OnItemSelected;
|
||||||
public event Action<ButtonEventArgs>? OnOrderApproved;
|
public event Action<ButtonEventArgs>? OnOrderApproved;
|
||||||
@@ -34,25 +27,18 @@ namespace Content.Client.Cargo.UI
|
|||||||
private readonly List<string> _categoryStrings = new();
|
private readonly List<string> _categoryStrings = new();
|
||||||
private string? _category;
|
private string? _category;
|
||||||
|
|
||||||
public CargoConsoleMenu(CargoConsoleBoundUserInterface owner)
|
public CargoConsoleMenu(IPrototypeManager protoManager, SpriteSystem spriteSystem)
|
||||||
{
|
{
|
||||||
RobustXamlLoader.Load(this);
|
RobustXamlLoader.Load(this);
|
||||||
IoCManager.InjectDependencies(this);
|
_protoManager = protoManager;
|
||||||
Owner = owner;
|
_spriteSystem = spriteSystem;
|
||||||
|
|
||||||
Title = Loc.GetString(Owner.RequestOnly
|
Title = Loc.GetString("cargo-console-menu-title");
|
||||||
? "cargo-console-menu-request-only-title"
|
|
||||||
: "cargo-console-menu-title");
|
|
||||||
|
|
||||||
CallShuttleButton.OnPressed += OnCallShuttleButtonPressed;
|
|
||||||
SearchBar.OnTextChanged += OnSearchBarTextChanged;
|
SearchBar.OnTextChanged += OnSearchBarTextChanged;
|
||||||
Categories.OnItemSelected += OnCategoryItemSelected;
|
Categories.OnItemSelected += OnCategoryItemSelected;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnCallShuttleButtonPressed(ButtonEventArgs args)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnCategoryItemSelected(OptionButton.ItemSelectedEventArgs args)
|
private void OnCategoryItemSelected(OptionButton.ItemSelectedEventArgs args)
|
||||||
{
|
{
|
||||||
SetCategoryText(args.Id);
|
SetCategoryText(args.Id);
|
||||||
@@ -70,7 +56,7 @@ namespace Content.Client.Cargo.UI
|
|||||||
Categories.SelectId(id);
|
Categories.SelectId(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<CargoProductPrototype> ProductPrototypes => _prototypeManager.EnumeratePrototypes<CargoProductPrototype>();
|
public IEnumerable<CargoProductPrototype> ProductPrototypes => _protoManager.EnumeratePrototypes<CargoProductPrototype>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Populates the list of products that will actually be shown, using the current filters.
|
/// 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()
|
public void PopulateProducts()
|
||||||
{
|
{
|
||||||
Products.RemoveAllChildren();
|
Products.RemoveAllChildren();
|
||||||
|
var products = ProductPrototypes.ToList();
|
||||||
|
products.Sort((x, y) =>
|
||||||
|
string.Compare(x.Name, y.Name, StringComparison.Ordinal));
|
||||||
|
|
||||||
var search = SearchBar.Text.Trim().ToLowerInvariant();
|
var search = SearchBar.Text.Trim().ToLowerInvariant();
|
||||||
foreach (var prototype in ProductPrototypes)
|
foreach (var prototype in products)
|
||||||
{
|
{
|
||||||
// if no search or category
|
// if no search or category
|
||||||
// else if search
|
// else if search
|
||||||
@@ -94,7 +83,7 @@ namespace Content.Client.Cargo.UI
|
|||||||
Product = prototype,
|
Product = prototype,
|
||||||
ProductName = { Text = prototype.Name },
|
ProductName = { Text = prototype.Name },
|
||||||
PointCost = { Text = prototype.PointCost.ToString() },
|
PointCost = { Text = prototype.PointCost.ToString() },
|
||||||
Icon = { Texture = prototype.Icon.Frame0() },
|
Icon = { Texture = _spriteSystem.Frame0(prototype.Icon) },
|
||||||
};
|
};
|
||||||
button.MainButton.OnPressed += args =>
|
button.MainButton.OnPressed += args =>
|
||||||
{
|
{
|
||||||
@@ -132,31 +121,20 @@ namespace Content.Client.Cargo.UI
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Populates the list of orders and requests.
|
/// Populates the list of orders and requests.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void PopulateOrders()
|
public void PopulateOrders(IEnumerable<CargoOrderData> orders)
|
||||||
{
|
{
|
||||||
Orders.RemoveAllChildren();
|
Orders.DisposeAllChildren();
|
||||||
Requests.RemoveAllChildren();
|
Requests.DisposeAllChildren();
|
||||||
|
|
||||||
if (Owner.Orders == null)
|
foreach (var order in orders)
|
||||||
{
|
{
|
||||||
return;
|
var product = _protoManager.Index<CargoProductPrototype>(order.ProductId);
|
||||||
}
|
|
||||||
|
|
||||||
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 productName = product.Name;
|
var productName = product.Name;
|
||||||
|
|
||||||
var row = new CargoOrderRow
|
var row = new CargoOrderRow
|
||||||
{
|
{
|
||||||
Order = order,
|
Order = order,
|
||||||
Icon = { Texture = product.Icon.Frame0() },
|
Icon = { Texture = _spriteSystem.Frame0(product.Icon) },
|
||||||
ProductName =
|
ProductName =
|
||||||
{
|
{
|
||||||
Text = Loc.GetString(
|
Text = Loc.GetString(
|
||||||
@@ -177,43 +155,23 @@ namespace Content.Client.Cargo.UI
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Owner.RequestOnly)
|
// TODO: Disable based on access.
|
||||||
row.Approve.Visible = false;
|
|
||||||
else
|
|
||||||
row.Approve.OnPressed += (args) => { OnOrderApproved?.Invoke(args); };
|
row.Approve.OnPressed += (args) => { OnOrderApproved?.Invoke(args); };
|
||||||
Requests.AddChild(row);
|
Requests.AddChild(row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Populate()
|
public void UpdateCargoCapacity(int count, int capacity)
|
||||||
{
|
{
|
||||||
PopulateProducts();
|
// TODO: Rename + Loc.
|
||||||
PopulateCategories();
|
ShuttleCapacityLabel.Text = $"{count}/{capacity}";
|
||||||
PopulateOrders();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateCargoCapacity()
|
public void UpdateBankData(string name, int points)
|
||||||
{
|
{
|
||||||
ShuttleCapacityLabel.Text = $"{Owner.ShuttleCapacity.CurrentCapacity}/{Owner.ShuttleCapacity.MaxCapacity}";
|
AccountNameLabel.Text = name;
|
||||||
}
|
PointsLabel.Text = points.ToString();
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Content.Shared.Cargo;
|
using Content.Shared.Cargo;
|
||||||
|
using Content.Shared.Cargo.Prototypes;
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
|
|||||||
47
Content.Client/Cargo/UI/CargoShuttleMenu.xaml
Normal file
47
Content.Client/Cargo/UI/CargoShuttleMenu.xaml
Normal 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>
|
||||||
128
Content.Client/Cargo/UI/CargoShuttleMenu.xaml.cs
Normal file
128
Content.Client/Cargo/UI/CargoShuttleMenu.xaml.cs
Normal 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}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -74,7 +74,6 @@ namespace Content.Client.Entry
|
|||||||
factory.RegisterClass<SharedLatheComponent>();
|
factory.RegisterClass<SharedLatheComponent>();
|
||||||
factory.RegisterClass<SharedSpawnPointComponent>();
|
factory.RegisterClass<SharedSpawnPointComponent>();
|
||||||
factory.RegisterClass<SharedVendingMachineComponent>();
|
factory.RegisterClass<SharedVendingMachineComponent>();
|
||||||
factory.RegisterClass<SharedCargoConsoleComponent>();
|
|
||||||
factory.RegisterClass<SharedReagentDispenserComponent>();
|
factory.RegisterClass<SharedReagentDispenserComponent>();
|
||||||
factory.RegisterClass<SharedChemMasterComponent>();
|
factory.RegisterClass<SharedChemMasterComponent>();
|
||||||
factory.RegisterClass<SharedGravityGeneratorComponent>();
|
factory.RegisterClass<SharedGravityGeneratorComponent>();
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ public sealed class RadarConsoleBoundUserInterface : BoundUserInterface
|
|||||||
base.UpdateState(state);
|
base.UpdateState(state);
|
||||||
if (state is not RadarConsoleBoundInterfaceState cState) return;
|
if (state is not RadarConsoleBoundInterfaceState cState) return;
|
||||||
|
|
||||||
|
_window?.SetMatrix(cState.Coordinates, cState.Angle);
|
||||||
_window?.UpdateState(cState);
|
_window?.UpdateState(cState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ public sealed class ShuttleConsoleBoundUserInterface : BoundUserInterface
|
|||||||
{
|
{
|
||||||
base.UpdateState(state);
|
base.UpdateState(state);
|
||||||
if (state is not ShuttleConsoleBoundInterfaceState cState) return;
|
if (state is not ShuttleConsoleBoundInterfaceState cState) return;
|
||||||
|
|
||||||
|
_window?.SetMatrix(cState.Coordinates, cState.Angle);
|
||||||
_window?.UpdateState(cState);
|
_window?.UpdateState(cState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,20 +2,4 @@ using Content.Shared.Shuttles.Events;
|
|||||||
|
|
||||||
namespace Content.Client.Shuttles.Systems;
|
namespace Content.Client.Shuttles.Systems;
|
||||||
|
|
||||||
public sealed class DockingSystem : EntitySystem
|
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});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ public class DockingControl : Control
|
|||||||
public EntityUid? ViewedDock;
|
public EntityUid? ViewedDock;
|
||||||
public EntityUid? GridEntity;
|
public EntityUid? GridEntity;
|
||||||
|
|
||||||
|
public EntityCoordinates? Coordinates;
|
||||||
|
public Angle? Angle;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stored by GridID then by docks
|
/// Stored by GridID then by docks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -69,11 +72,12 @@ public class DockingControl : Control
|
|||||||
handle.DrawLine((MidPoint, MidPoint) - aExtent, (MidPoint, MidPoint) + aExtent, gridLines);
|
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;
|
!_entManager.TryGetComponent<TransformComponent>(GridEntity, out var gridXform)) return;
|
||||||
|
|
||||||
var rotation = Matrix3.CreateRotation(xform.LocalRotation);
|
var rotation = Matrix3.CreateRotation(Angle.Value);
|
||||||
var matrix = Matrix3.CreateTranslation(-xform.LocalPosition);
|
var matrix = Matrix3.CreateTranslation(-Coordinates.Value.Position);
|
||||||
|
|
||||||
// Draw the fixtures around the dock before drawing it
|
// Draw the fixtures around the dock before drawing it
|
||||||
if (_entManager.TryGetComponent<FixturesComponent>(GridEntity, out var fixtures))
|
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);
|
ScalePosition(rotation.Transform(new Vector2(0.5f, -0.5f)))), Color.Green);
|
||||||
|
|
||||||
// Draw nearby grids
|
// Draw nearby grids
|
||||||
var worldPos = gridXform.WorldMatrix.Transform(xform.LocalPosition);
|
var worldPos = gridXform.WorldMatrix.Transform(Coordinates.Value.Position);
|
||||||
var gridInvMatrix = gridXform.InvWorldMatrix;
|
var gridInvMatrix = gridXform.InvWorldMatrix;
|
||||||
Matrix3.Multiply(in gridInvMatrix, in matrix, out var invMatrix);
|
Matrix3.Multiply(in gridInvMatrix, in matrix, out var invMatrix);
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using Content.Client.UserInterface;
|
|||||||
using Content.Shared.Shuttles.BUIStates;
|
using Content.Shared.Shuttles.BUIStates;
|
||||||
using Robust.Client.AutoGenerated;
|
using Robust.Client.AutoGenerated;
|
||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
|
using Robust.Shared.Map;
|
||||||
|
|
||||||
namespace Content.Client.Shuttles.UI;
|
namespace Content.Client.Shuttles.UI;
|
||||||
|
|
||||||
@@ -19,4 +20,9 @@ public sealed partial class RadarConsoleWindow : FancyWindow,
|
|||||||
{
|
{
|
||||||
RadarScreen.UpdateState(scc);
|
RadarScreen.UpdateState(scc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetMatrix(EntityCoordinates? coordinates, Angle? angle)
|
||||||
|
{
|
||||||
|
RadarScreen.SetMatrix(coordinates, angle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,9 +25,11 @@ public sealed class RadarControl : Control
|
|||||||
private const float GridLinesDistance = 32f;
|
private const float GridLinesDistance = 32f;
|
||||||
|
|
||||||
/// <summary>
|
/// <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>
|
/// </summary>
|
||||||
private EntityUid? _entity;
|
private EntityCoordinates? _coordinates;
|
||||||
|
|
||||||
|
private Angle? _rotation;
|
||||||
|
|
||||||
private float _radarMinRange = 64f;
|
private float _radarMinRange = 64f;
|
||||||
private float _radarMaxRange = 256f;
|
private float _radarMaxRange = 256f;
|
||||||
@@ -61,6 +63,12 @@ public sealed class RadarControl : Control
|
|||||||
MinSize = (SizeFull, SizeFull);
|
MinSize = (SizeFull, SizeFull);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetMatrix(EntityCoordinates? coordinates, Angle? angle)
|
||||||
|
{
|
||||||
|
_coordinates = coordinates;
|
||||||
|
_rotation = angle;
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateState(RadarConsoleBoundInterfaceState ls)
|
public void UpdateState(RadarConsoleBoundInterfaceState ls)
|
||||||
{
|
{
|
||||||
_radarMaxRange = ls.MaxRange;
|
_radarMaxRange = ls.MaxRange;
|
||||||
@@ -74,7 +82,6 @@ public sealed class RadarControl : Control
|
|||||||
if (_radarMaxRange < _radarMinRange)
|
if (_radarMaxRange < _radarMinRange)
|
||||||
_radarMinRange = _radarMaxRange;
|
_radarMinRange = _radarMaxRange;
|
||||||
|
|
||||||
_entity = ls.Entity;
|
|
||||||
_docks.Clear();
|
_docks.Clear();
|
||||||
|
|
||||||
foreach (var state in ls.Docks)
|
foreach (var state in ls.Docks)
|
||||||
@@ -109,7 +116,7 @@ public sealed class RadarControl : Control
|
|||||||
handle.DrawCircle((MidPoint, MidPoint), ScaledMinimapRadius, Color.Black);
|
handle.DrawCircle((MidPoint, MidPoint), ScaledMinimapRadius, Color.Black);
|
||||||
|
|
||||||
// No data
|
// No data
|
||||||
if (_entity == null)
|
if (_coordinates == null || _rotation == null)
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
return;
|
return;
|
||||||
@@ -135,8 +142,8 @@ public sealed class RadarControl : Control
|
|||||||
var xformQuery = _entManager.GetEntityQuery<TransformComponent>();
|
var xformQuery = _entManager.GetEntityQuery<TransformComponent>();
|
||||||
var fixturesQuery = _entManager.GetEntityQuery<FixturesComponent>();
|
var fixturesQuery = _entManager.GetEntityQuery<FixturesComponent>();
|
||||||
var bodyQuery = _entManager.GetEntityQuery<PhysicsComponent>();
|
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)
|
if (mapPosition.MapId == MapId.Nullspace)
|
||||||
{
|
{
|
||||||
@@ -144,28 +151,30 @@ public sealed class RadarControl : Control
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can also use ourGridBody.LocalCenter
|
var offset = _coordinates.Value.Position;
|
||||||
var offset = xform.Coordinates.Position;
|
|
||||||
var offsetMatrix = Matrix3.CreateTranslation(-offset);
|
|
||||||
Matrix3 matrix;
|
Matrix3 matrix;
|
||||||
|
|
||||||
// Draw our grid in detail
|
// Draw our grid in detail
|
||||||
var ourGridId = xform.GridUid;
|
var ourGridId = _coordinates.Value.GetGridUid(_entManager);
|
||||||
if (ourGridId != null)
|
if (ourGridId != null)
|
||||||
{
|
{
|
||||||
matrix = xform.InvWorldMatrix;
|
var offsetMatrix = Matrix3.CreateInverseTransform(offset.X, offset.Y, (float) _rotation.Value.Theta);
|
||||||
var ourGridFixtures = fixturesQuery.GetComponent(ourGridId.Value);
|
var ourGridFixtures = fixturesQuery.GetComponent(ourGridId.Value);
|
||||||
// Draw our grid; use non-filled boxes so it doesn't look awful.
|
// Draw our grid; use non-filled boxes so it doesn't look awful.
|
||||||
DrawGrid(handle, offsetMatrix, ourGridFixtures, Color.Yellow);
|
DrawGrid(handle, offsetMatrix, ourGridFixtures, Color.Yellow);
|
||||||
|
|
||||||
DrawDocks(handle, ourGridId.Value, offsetMatrix);
|
DrawDocks(handle, ourGridId.Value, offsetMatrix);
|
||||||
|
|
||||||
|
var ourGridMatrix = xformQuery.GetComponent(ourGridId.Value).InvWorldMatrix;
|
||||||
|
|
||||||
|
Matrix3.Multiply(in ourGridMatrix, in offsetMatrix, out matrix);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
matrix = Matrix3.CreateTranslation(-offset);
|
matrix = Matrix3.CreateTranslation(-offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
var invertedPosition = xform.Coordinates.Position - offset;
|
var invertedPosition = _coordinates.Value.Position - offset;
|
||||||
invertedPosition.Y = -invertedPosition.Y;
|
invertedPosition.Y = -invertedPosition.Y;
|
||||||
// Don't need to transform the InvWorldMatrix again as it's already offset to its position.
|
// Don't need to transform the InvWorldMatrix again as it's already offset to its position.
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using Robust.Client.Graphics;
|
|||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Client.Shuttles.UI;
|
namespace Content.Client.Shuttles.UI;
|
||||||
@@ -17,10 +18,7 @@ public sealed partial class ShuttleConsoleWindow : FancyWindow,
|
|||||||
{
|
{
|
||||||
private readonly IEntityManager _entManager;
|
private readonly IEntityManager _entManager;
|
||||||
|
|
||||||
/// <summary>
|
private EntityUid? _shuttleUid;
|
||||||
/// EntityUid of the open console.
|
|
||||||
/// </summary>
|
|
||||||
private EntityUid? _entity;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Currently selected dock button for camera.
|
/// Currently selected dock button for camera.
|
||||||
@@ -84,9 +82,14 @@ public sealed partial class ShuttleConsoleWindow : FancyWindow,
|
|||||||
UndockPressed?.Invoke(DockingScreen.ViewedDock.Value);
|
UndockPressed?.Invoke(DockingScreen.ViewedDock.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetMatrix(EntityCoordinates? coordinates, Angle? angle)
|
||||||
|
{
|
||||||
|
_shuttleUid = coordinates?.EntityId;
|
||||||
|
RadarScreen.SetMatrix(coordinates, angle);
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateState(ShuttleConsoleBoundInterfaceState scc)
|
public void UpdateState(ShuttleConsoleBoundInterfaceState scc)
|
||||||
{
|
{
|
||||||
_entity = scc.Entity;
|
|
||||||
UpdateDocks(scc.Docks);
|
UpdateDocks(scc.Docks);
|
||||||
RadarScreen.UpdateState(scc);
|
RadarScreen.UpdateState(scc);
|
||||||
MaxRadarRange.Text = $"{scc.MaxRange:0}";
|
MaxRadarRange.Text = $"{scc.MaxRange:0}";
|
||||||
@@ -110,21 +113,16 @@ public sealed partial class ShuttleConsoleWindow : FancyWindow,
|
|||||||
DockPorts.DisposeAllChildren();
|
DockPorts.DisposeAllChildren();
|
||||||
DockingScreen.Docks = _docks;
|
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;
|
var index = 1;
|
||||||
|
|
||||||
foreach (var state in gridDocks)
|
foreach (var state in gridDocks)
|
||||||
{
|
{
|
||||||
var ent = state.Entity;
|
var pressed = state.Entity == DockingScreen.ViewedDock;
|
||||||
var pressed = ent == DockingScreen.ViewedDock;
|
|
||||||
string suffix;
|
string suffix;
|
||||||
|
|
||||||
if (state.Connected)
|
if (state.Connected)
|
||||||
@@ -143,21 +141,26 @@ public sealed partial class ShuttleConsoleWindow : FancyWindow,
|
|||||||
Pressed = pressed,
|
Pressed = pressed,
|
||||||
};
|
};
|
||||||
|
|
||||||
button.OnMouseEntered += args => OnDockMouseEntered(args, ent);
|
if (pressed)
|
||||||
button.OnMouseExited += args => OnDockMouseExited(args, ent);
|
{
|
||||||
button.OnToggled += args => OnDockToggled(args, ent);
|
_selectedDock = button;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.OnMouseEntered += args => OnDockMouseEntered(args, state);
|
||||||
|
button.OnMouseExited += args => OnDockMouseExited(args, state);
|
||||||
|
button.OnToggled += args => OnDockToggled(args, state);
|
||||||
DockPorts.AddChild(button);
|
DockPorts.AddChild(button);
|
||||||
index++;
|
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;
|
RadarScreen.HighlightedDock = null;
|
||||||
}
|
}
|
||||||
@@ -165,10 +168,18 @@ public sealed partial class ShuttleConsoleWindow : FancyWindow,
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Shows a docking camera instead of radar screen.
|
/// Shows a docking camera instead of radar screen.
|
||||||
/// </summary>
|
/// </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 (_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.Pressed = false;
|
||||||
_selectedDock = null;
|
_selectedDock = null;
|
||||||
}
|
}
|
||||||
@@ -187,15 +198,23 @@ public sealed partial class ShuttleConsoleWindow : FancyWindow,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// DebugTools.Assert(DockingScreen.ViewedDock == null);
|
if (_shuttleUid != null)
|
||||||
_entManager.TryGetComponent<TransformComponent>(_entity, out var xform);
|
{
|
||||||
|
DockingScreen.Coordinates = state.Coordinates;
|
||||||
|
DockingScreen.Angle = state.Angle;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DockingScreen.Coordinates = null;
|
||||||
|
DockingScreen.Angle = null;
|
||||||
|
}
|
||||||
|
|
||||||
UndockButton.Disabled = false;
|
UndockButton.Disabled = false;
|
||||||
RadarScreen.Visible = false;
|
RadarScreen.Visible = false;
|
||||||
DockingScreen.Visible = true;
|
DockingScreen.Visible = true;
|
||||||
DockingScreen.ViewedDock = ent;
|
DockingScreen.ViewedDock = ent;
|
||||||
StartAutodockPressed?.Invoke(ent);
|
StartAutodockPressed?.Invoke(ent);
|
||||||
DockingScreen.GridEntity = xform?.GridUid;
|
DockingScreen.GridEntity = _shuttleUid;
|
||||||
_selectedDock = obj.Button;
|
_selectedDock = obj.Button;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -215,9 +234,8 @@ public sealed partial class ShuttleConsoleWindow : FancyWindow,
|
|||||||
{
|
{
|
||||||
base.Draw(handle);
|
base.Draw(handle);
|
||||||
|
|
||||||
if (!_entManager.TryGetComponent<TransformComponent>(_entity, out var entXform) ||
|
if (!_entManager.TryGetComponent<PhysicsComponent>(_shuttleUid, out var gridBody) ||
|
||||||
!_entManager.TryGetComponent<PhysicsComponent>(entXform.GridUid, out var gridBody) ||
|
!_entManager.TryGetComponent<TransformComponent>(_shuttleUid, out var gridXform))
|
||||||
!_entManager.TryGetComponent<TransformComponent>(entXform.GridUid, out var gridXform))
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
39
Content.IntegrationTests/Tests/CargoTest.cs
Normal file
39
Content.IntegrationTests/Tests/CargoTest.cs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using Content.Server.Cargo.Systems;
|
||||||
|
using Content.Shared.Cargo.Prototypes;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.IntegrationTests.Tests;
|
||||||
|
|
||||||
|
[TestFixture]
|
||||||
|
public sealed class CargoTest
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public async Task NoArbitrage()
|
||||||
|
{
|
||||||
|
await using var pairTracker = await PoolManager.GetServerClient(new PoolSettings() {NoClient = true});
|
||||||
|
var server = pairTracker.Pair.Server;
|
||||||
|
|
||||||
|
var entManager = server.ResolveDependency<IEntityManager>();
|
||||||
|
var mapManager = server.ResolveDependency<IMapManager>();
|
||||||
|
var protoManager = server.ResolveDependency<IPrototypeManager>();
|
||||||
|
var pricing = server.ResolveDependency<IEntitySystemManager>().GetEntitySystem<PricingSystem>();
|
||||||
|
|
||||||
|
await server.WaitAssertion(() =>
|
||||||
|
{
|
||||||
|
var mapId = mapManager.CreateMap();
|
||||||
|
|
||||||
|
foreach (var proto in protoManager.EnumeratePrototypes<CargoProductPrototype>())
|
||||||
|
{
|
||||||
|
var ent = entManager.SpawnEntity(proto.Product, new MapCoordinates(Vector2.Zero, mapId));
|
||||||
|
var price = pricing.GetPrice(ent);
|
||||||
|
|
||||||
|
Assert.That(price, Is.LessThan(proto.PointCost), $"Found arbitrage on {proto.ID} cargo product!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -57,8 +57,6 @@ public sealed partial class AtmosphereSystem
|
|||||||
mixtures[5].AdjustMoles(Gas.Plasma, Atmospherics.MolesCellGasMiner);
|
mixtures[5].AdjustMoles(Gas.Plasma, Atmospherics.MolesCellGasMiner);
|
||||||
mixtures[5].Temperature = 5000f;
|
mixtures[5].Temperature = 5000f;
|
||||||
|
|
||||||
var entMan = IoCManager.Resolve<IEntityManager>();
|
|
||||||
|
|
||||||
foreach (var gid in args)
|
foreach (var gid in args)
|
||||||
{
|
{
|
||||||
if(!EntityUid.TryParse(gid, out var euid))
|
if(!EntityUid.TryParse(gid, out var euid))
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
namespace Content.Server.Cargo
|
|
||||||
{
|
|
||||||
public sealed class CargoBankAccount : ICargoBankAccount
|
|
||||||
{
|
|
||||||
[ViewVariables]
|
|
||||||
public int Id { get; }
|
|
||||||
[ViewVariables]
|
|
||||||
public string Name { get; }
|
|
||||||
|
|
||||||
private int _balance;
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
|
||||||
public int Balance
|
|
||||||
{
|
|
||||||
get => _balance;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_balance == value)
|
|
||||||
return;
|
|
||||||
_balance = value;
|
|
||||||
OnBalanceChange?.Invoke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public event Action? OnBalanceChange;
|
|
||||||
|
|
||||||
public CargoBankAccount(int id, string name, int balance)
|
|
||||||
{
|
|
||||||
Id = id;
|
|
||||||
Name = name;
|
|
||||||
Balance = balance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using System.Linq;
|
|
||||||
using Content.Shared.Cargo;
|
|
||||||
|
|
||||||
namespace Content.Server.Cargo
|
|
||||||
{
|
|
||||||
public sealed class CargoOrderDatabase
|
|
||||||
{
|
|
||||||
private readonly Dictionary<int, CargoOrderData> _orders = new();
|
|
||||||
private int _orderNumber = 0;
|
|
||||||
|
|
||||||
public CargoOrderDatabase(int id)
|
|
||||||
{
|
|
||||||
Id = id;
|
|
||||||
CurrentOrderSize = 0;
|
|
||||||
MaxOrderSize = 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Id { get; private set; }
|
|
||||||
public int CurrentOrderSize { get; private set; }
|
|
||||||
public int MaxOrderSize { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes all orders from the database.
|
|
||||||
/// </summary>
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
_orders.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a list of all orders.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>A list of orders</returns>
|
|
||||||
public List<CargoOrderData> GetOrders()
|
|
||||||
{
|
|
||||||
return _orders.Values.ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TryGetOrder(int id, [NotNullWhen(true)] out CargoOrderData? order)
|
|
||||||
{
|
|
||||||
return _orders.TryGetValue(id, out order);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<CargoOrderData> SpliceApproved()
|
|
||||||
{
|
|
||||||
var orders = _orders.Values.Where(order => order.Approved).ToList();
|
|
||||||
foreach (var order in orders)
|
|
||||||
_orders.Remove(order.OrderNumber);
|
|
||||||
return orders;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds an order to the database.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="requester">The person who requested the item.</param>
|
|
||||||
/// <param name="reason">The reason the product was requested.</param>
|
|
||||||
/// <param name="productId">The ID of the product requested.</param>
|
|
||||||
/// <param name="amount">The amount of the products requested.</param>
|
|
||||||
/// <param name="payingAccountId">The ID of the bank account paying for the order.</param>
|
|
||||||
/// <param name="approved">Whether the order will be bought when the orders are processed.</param>
|
|
||||||
public void AddOrder(string requester, string reason, string productId, int amount, int payingAccountId)
|
|
||||||
{
|
|
||||||
var order = new CargoOrderData(_orderNumber, requester, reason, productId, amount, payingAccountId);
|
|
||||||
if (Contains(order))
|
|
||||||
return;
|
|
||||||
_orders.Add(_orderNumber, order);
|
|
||||||
_orderNumber += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes an order from the database.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="order">The order to be removed.</param>
|
|
||||||
/// <returns>Whether it could be removed or not</returns>
|
|
||||||
public bool RemoveOrder(int orderNumber)
|
|
||||||
{
|
|
||||||
return _orders.Remove(orderNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Approves an order in the database.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="order">The order to be approved.</param>
|
|
||||||
public bool ApproveOrder(string approver, int orderNumber)
|
|
||||||
{
|
|
||||||
if (CurrentOrderSize == MaxOrderSize ||
|
|
||||||
!_orders.TryGetValue(orderNumber, out var order) ||
|
|
||||||
order.Approved)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (CurrentOrderSize + order.Amount > MaxOrderSize)
|
|
||||||
{
|
|
||||||
AddOrder(
|
|
||||||
order.Requester,
|
|
||||||
Loc.GetString("cargo-order-database-order-overflow-message", ("placeholder", order.Reason.Replace(" (Overflow)", string.Empty))),
|
|
||||||
order.ProductId,
|
|
||||||
order.Amount - MaxOrderSize - CurrentOrderSize, order.PayingAccountId);
|
|
||||||
|
|
||||||
order.Amount = MaxOrderSize - CurrentOrderSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
order.Approved = true;
|
|
||||||
order.Approver = approver;
|
|
||||||
|
|
||||||
CurrentOrderSize += order.Amount;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns whether the database contains the order or not.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="order">The order to check</param>
|
|
||||||
/// <returns>Whether the database contained the order or not.</returns>
|
|
||||||
public bool Contains(CargoOrderData order)
|
|
||||||
{
|
|
||||||
return _orders.ContainsValue(order);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Clears the current order capacity. This allows more orders to be processed and is invoked after an order is dispatched.
|
|
||||||
/// </summary>
|
|
||||||
public void ClearOrderCapacity()
|
|
||||||
{
|
|
||||||
CurrentOrderSize = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,205 +0,0 @@
|
|||||||
using Content.Server.Cargo.Systems;
|
|
||||||
using Content.Server.Power.Components;
|
|
||||||
using Content.Server.UserInterface;
|
|
||||||
using Content.Shared.Cargo;
|
|
||||||
using Content.Shared.Cargo.Components;
|
|
||||||
using Content.Shared.Sound;
|
|
||||||
using Content.Server.MachineLinking.Components;
|
|
||||||
using Content.Shared.MachineLinking;
|
|
||||||
using Robust.Server.GameObjects;
|
|
||||||
using Robust.Shared.Audio;
|
|
||||||
using Robust.Shared.Player;
|
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
|
||||||
|
|
||||||
namespace Content.Server.Cargo.Components
|
|
||||||
{
|
|
||||||
[RegisterComponent]
|
|
||||||
public sealed class CargoConsoleComponent : SharedCargoConsoleComponent
|
|
||||||
{
|
|
||||||
[Dependency] private readonly IEntityManager _entMan = default!;
|
|
||||||
|
|
||||||
private CargoBankAccount? _bankAccount;
|
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
public CargoBankAccount? BankAccount
|
|
||||||
{
|
|
||||||
get => _bankAccount;
|
|
||||||
private set
|
|
||||||
{
|
|
||||||
if (_bankAccount == value)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_bankAccount != null)
|
|
||||||
{
|
|
||||||
_bankAccount.OnBalanceChange -= UpdateUIState;
|
|
||||||
}
|
|
||||||
|
|
||||||
_bankAccount = value;
|
|
||||||
|
|
||||||
if (value != null)
|
|
||||||
{
|
|
||||||
value.OnBalanceChange += UpdateUIState;
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateUIState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[DataField("requestOnly")]
|
|
||||||
private bool _requestOnly = false;
|
|
||||||
|
|
||||||
[DataField("errorSound")]
|
|
||||||
private SoundSpecifier _errorSound = new SoundPathSpecifier("/Audio/Effects/error.ogg");
|
|
||||||
|
|
||||||
private bool Powered => !_entMan.TryGetComponent(Owner, out ApcPowerReceiverComponent? receiver) || receiver.Powered;
|
|
||||||
private CargoSystem _cargoConsoleSystem = default!;
|
|
||||||
|
|
||||||
[ViewVariables] private BoundUserInterface? UserInterface => Owner.GetUIOrNull(CargoConsoleUiKey.Key);
|
|
||||||
|
|
||||||
[DataField("senderPort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))]
|
|
||||||
public string SenderPort = "OrderSender";
|
|
||||||
|
|
||||||
protected override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
Owner.EnsureComponentWarn(out CargoOrderDatabaseComponent _);
|
|
||||||
|
|
||||||
if (UserInterface != null)
|
|
||||||
{
|
|
||||||
UserInterface.OnReceiveMessage += UserInterfaceOnOnReceiveMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
_cargoConsoleSystem = EntitySystem.Get<CargoSystem>();
|
|
||||||
BankAccount = _cargoConsoleSystem.StationAccount;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnRemove()
|
|
||||||
{
|
|
||||||
if (UserInterface != null)
|
|
||||||
{
|
|
||||||
UserInterface.OnReceiveMessage -= UserInterfaceOnOnReceiveMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
base.OnRemove();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UserInterfaceOnOnReceiveMessage(ServerBoundUserInterfaceMessage serverMsg)
|
|
||||||
{
|
|
||||||
if (!_entMan.TryGetComponent(Owner, out CargoOrderDatabaseComponent? orders))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var message = serverMsg.Message;
|
|
||||||
if (orders.Database == null)
|
|
||||||
return;
|
|
||||||
if (!Powered)
|
|
||||||
return;
|
|
||||||
switch (message)
|
|
||||||
{
|
|
||||||
case CargoConsoleAddOrderMessage msg:
|
|
||||||
{
|
|
||||||
if (msg.Amount <= 0 || _bankAccount == null)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_cargoConsoleSystem.AddOrder(orders.Database.Id, msg.Requester, msg.Reason, msg.ProductId,
|
|
||||||
msg.Amount, _bankAccount.Id))
|
|
||||||
{
|
|
||||||
SoundSystem.Play(_errorSound.GetSound(), Filter.Pvs(Owner), Owner, AudioParams.Default);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CargoConsoleRemoveOrderMessage msg:
|
|
||||||
{
|
|
||||||
_cargoConsoleSystem.RemoveOrder(orders.Database.Id, msg.OrderNumber);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CargoConsoleApproveOrderMessage msg:
|
|
||||||
{
|
|
||||||
if (_requestOnly ||
|
|
||||||
!orders.Database.TryGetOrder(msg.OrderNumber, out var order) ||
|
|
||||||
_bankAccount == null)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msg.Session.AttachedEntity is not {Valid: true} player)
|
|
||||||
break;
|
|
||||||
|
|
||||||
PrototypeManager.TryIndex(order.ProductId, out CargoProductPrototype? product);
|
|
||||||
if (product == null!)
|
|
||||||
break;
|
|
||||||
var capacity = _cargoConsoleSystem.GetCapacity(orders.Database.Id);
|
|
||||||
if (
|
|
||||||
(capacity.CurrentCapacity == capacity.MaxCapacity
|
|
||||||
|| capacity.CurrentCapacity + order.Amount > capacity.MaxCapacity
|
|
||||||
|| !_cargoConsoleSystem.CheckBalance(_bankAccount.Id, (-product.PointCost) * order.Amount)
|
|
||||||
|| !_cargoConsoleSystem.ApproveOrder(Owner, player, orders.Database.Id, msg.OrderNumber)
|
|
||||||
|| !_cargoConsoleSystem.ChangeBalance(_bankAccount.Id, (-product.PointCost) * order.Amount))
|
|
||||||
)
|
|
||||||
{
|
|
||||||
SoundSystem.Play(_errorSound.GetSound(), Filter.Pvs(Owner), Owner, AudioParams.Default);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateUIState();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CargoConsoleShuttleMessage _:
|
|
||||||
{
|
|
||||||
// Jesus fucking christ Glass
|
|
||||||
//var approvedOrders = _cargoOrderDataManager.RemoveAndGetApprovedFrom(orders.Database);
|
|
||||||
//orders.Database.ClearOrderCapacity();
|
|
||||||
|
|
||||||
// TODO replace with shuttle code
|
|
||||||
EntityUid? cargoTelepad = null;
|
|
||||||
|
|
||||||
if (_entMan.TryGetComponent<SignalTransmitterComponent>(Owner, out var transmitter) &&
|
|
||||||
transmitter.Outputs.TryGetValue(SenderPort, out var telepad) &&
|
|
||||||
telepad.Count > 0)
|
|
||||||
{
|
|
||||||
// use most recent link
|
|
||||||
var pad = telepad[^1].Uid;
|
|
||||||
if (_entMan.HasComponent<CargoTelepadComponent>(pad) &&
|
|
||||||
_entMan.TryGetComponent<ApcPowerReceiverComponent?>(pad, out var powerReceiver) &&
|
|
||||||
powerReceiver.Powered)
|
|
||||||
cargoTelepad = pad;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cargoTelepad != null)
|
|
||||||
{
|
|
||||||
if (_entMan.TryGetComponent<CargoTelepadComponent?>(cargoTelepad.Value, out var telepadComponent))
|
|
||||||
{
|
|
||||||
var approvedOrders = _cargoConsoleSystem.RemoveAndGetApprovedOrders(orders.Database.Id);
|
|
||||||
orders.Database.ClearOrderCapacity();
|
|
||||||
foreach (var order in approvedOrders)
|
|
||||||
{
|
|
||||||
_cargoConsoleSystem.QueueTeleport(telepadComponent, order);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateUIState()
|
|
||||||
{
|
|
||||||
if (_bankAccount == null || !_entMan.EntityExists(Owner))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var id = _bankAccount.Id;
|
|
||||||
var name = _bankAccount.Name;
|
|
||||||
var balance = _bankAccount.Balance;
|
|
||||||
var capacity = _cargoConsoleSystem.GetCapacity(id);
|
|
||||||
UserInterface?.SetState(new CargoConsoleInterfaceState(_requestOnly, id, name, balance, capacity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using Content.Shared.Sound;
|
||||||
|
|
||||||
|
namespace Content.Server.Cargo.Components
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Handles sending order requests to cargo. Doesn't handle orders themselves via shuttle or telepads.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class CargoOrderConsoleComponent : Component
|
||||||
|
{
|
||||||
|
[DataField("soundError")] public SoundSpecifier ErrorSound =
|
||||||
|
new SoundPathSpecifier("/Audio/Effects/Cargo/buzz_sigh.ogg");
|
||||||
|
|
||||||
|
[DataField("soundConfirm")]
|
||||||
|
public SoundSpecifier ConfirmSound = new SoundPathSpecifier("/Audio/Effects/Cargo/ping.ogg");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
using Content.Server.Cargo.Systems;
|
|
||||||
using Content.Shared.Cargo.Components;
|
|
||||||
|
|
||||||
namespace Content.Server.Cargo.Components
|
|
||||||
{
|
|
||||||
[RegisterComponent]
|
|
||||||
public sealed class CargoOrderDatabaseComponent : SharedCargoOrderDatabaseComponent
|
|
||||||
{
|
|
||||||
public CargoOrderDatabase? Database { get; set; }
|
|
||||||
public bool ConnectedToDatabase => Database != null;
|
|
||||||
|
|
||||||
protected override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
Database = EntitySystem.Get<CargoSystem>().StationOrderDatabase;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override ComponentState GetComponentState()
|
|
||||||
{
|
|
||||||
if (!ConnectedToDatabase)
|
|
||||||
return new CargoOrderDatabaseState(null);
|
|
||||||
return new CargoOrderDatabaseState(Database?.GetOrders());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
7
Content.Server/Cargo/Components/CargoPalletComponent.cs
Normal file
7
Content.Server/Cargo/Components/CargoPalletComponent.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
namespace Content.Server.Cargo.Components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Any entities intersecting when a shuttle is recalled will be sold.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class CargoPalletComponent : Component {}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
using Content.Server.Shuttles.Components;
|
||||||
|
|
||||||
|
namespace Content.Server.Cargo.Components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Lets you remotely control the cargo shuttle.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class CargoPilotConsoleComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <see cref="ShuttleConsoleComponent"/> that we're proxied into.
|
||||||
|
/// </summary>
|
||||||
|
public EntityUid? Entity;
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
using Content.Shared.Sound;
|
||||||
|
|
||||||
|
namespace Content.Server.Cargo.Components;
|
||||||
|
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class CargoShuttleConsoleComponent : Component
|
||||||
|
{
|
||||||
|
[ViewVariables(VVAccess.ReadWrite), DataField("soundDeny")]
|
||||||
|
public SoundSpecifier DenySound = new SoundPathSpecifier("/Audio/Effects/Cargo/buzz_two.ogg");
|
||||||
|
}
|
||||||
@@ -15,7 +15,7 @@ namespace Content.Server.Cargo.Components
|
|||||||
public sealed class CargoTelepadComponent : SharedCargoTelepadComponent
|
public sealed class CargoTelepadComponent : SharedCargoTelepadComponent
|
||||||
{
|
{
|
||||||
[DataField("delay")]
|
[DataField("delay")]
|
||||||
public float Delay = 20f;
|
public float Delay = 45f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// How much time we've accumulated until next teleport.
|
/// How much time we've accumulated until next teleport.
|
||||||
@@ -24,9 +24,6 @@ namespace Content.Server.Cargo.Components
|
|||||||
[DataField("accumulator")]
|
[DataField("accumulator")]
|
||||||
public float Accumulator = 0f;
|
public float Accumulator = 0f;
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
public readonly Stack<CargoOrderData> TeleportQueue = new();
|
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public CargoTelepadState CurrentState = CargoTelepadState.Unpowered;
|
public CargoTelepadState CurrentState = CargoTelepadState.Unpowered;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using Content.Shared.Cargo;
|
||||||
|
|
||||||
|
namespace Content.Server.Cargo.Components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Added to the abstract representation of a station to track its money.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent, Access(typeof(SharedCargoSystem))]
|
||||||
|
public sealed class StationBankAccountComponent : Component
|
||||||
|
{
|
||||||
|
[ViewVariables(VVAccess.ReadWrite), DataField("balance")]
|
||||||
|
public int Balance = 2000;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How much the bank balance goes up per second, every Delay period. Rounded down when multiplied.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite), DataField("increasePerSecond")]
|
||||||
|
public int IncreasePerSecond = 10;
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
using Content.Shared.Cargo;
|
||||||
|
|
||||||
|
namespace Content.Server.Cargo.Components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stores all of cargo orders for a particular station.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class StationCargoOrderDatabaseComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Maximum amount of orders a station is allowed, approved or not.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite), DataField("capacity")]
|
||||||
|
public int Capacity = 20;
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite), DataField("orders")]
|
||||||
|
public Dictionary<int, CargoOrderData> Orders = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tracks the next order index available.
|
||||||
|
/// </summary>
|
||||||
|
public int Index;
|
||||||
|
|
||||||
|
[ViewVariables, DataField("cargoShuttleProto")]
|
||||||
|
public string? CargoShuttleProto = "CargoShuttle";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The cargo shuttle assigned to this station.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables, DataField("shuttle")]
|
||||||
|
public EntityUid? Shuttle;
|
||||||
|
}
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
namespace Content.Server.Cargo
|
|
||||||
{
|
|
||||||
public interface ICargoBankAccount
|
|
||||||
{
|
|
||||||
int Id { get; }
|
|
||||||
string Name { get; }
|
|
||||||
int Balance { get; }
|
|
||||||
public event Action OnBalanceChange;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,240 +0,0 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using Content.Server.Access.Systems;
|
|
||||||
using Content.Server.Cargo.Components;
|
|
||||||
using Content.Server.MachineLinking.System;
|
|
||||||
using Content.Shared.Access.Components;
|
|
||||||
using Content.Shared.Access.Systems;
|
|
||||||
using Content.Shared.Cargo;
|
|
||||||
using Content.Shared.GameTicking;
|
|
||||||
|
|
||||||
namespace Content.Server.Cargo.Systems
|
|
||||||
{
|
|
||||||
public sealed partial class CargoSystem
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// How much time to wait (in seconds) before increasing bank accounts balance.
|
|
||||||
/// </summary>
|
|
||||||
private const float Delay = 10f;
|
|
||||||
/// <summary>
|
|
||||||
/// How many points to give to every bank account every <see cref="Delay"/> seconds.
|
|
||||||
/// </summary>
|
|
||||||
private const int PointIncrease = 150;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Keeps track of how much time has elapsed since last balance increase.
|
|
||||||
/// </summary>
|
|
||||||
private float _timer;
|
|
||||||
/// <summary>
|
|
||||||
/// Stores all bank accounts.
|
|
||||||
/// </summary>
|
|
||||||
private readonly Dictionary<int, CargoBankAccount> _accountsDict = new();
|
|
||||||
|
|
||||||
private readonly Dictionary<int, CargoOrderDatabase> _databasesDict = new();
|
|
||||||
/// <summary>
|
|
||||||
/// Used to assign IDs to bank accounts. Incremental counter.
|
|
||||||
/// </summary>
|
|
||||||
private int _accountIndex;
|
|
||||||
/// <summary>
|
|
||||||
/// Enumeration of all bank accounts.
|
|
||||||
/// </summary>
|
|
||||||
public IEnumerable<CargoBankAccount> BankAccounts => _accountsDict.Values;
|
|
||||||
/// <summary>
|
|
||||||
/// The station's bank account.
|
|
||||||
/// </summary>
|
|
||||||
public CargoBankAccount StationAccount => GetBankAccount(0);
|
|
||||||
|
|
||||||
public CargoOrderDatabase StationOrderDatabase => GetOrderDatabase(0);
|
|
||||||
|
|
||||||
[Dependency] private readonly IdCardSystem _idCardSystem = default!;
|
|
||||||
[Dependency] private readonly AccessReaderSystem _accessReaderSystem = default!;
|
|
||||||
[Dependency] private readonly SignalLinkerSystem _linker = default!;
|
|
||||||
|
|
||||||
private void InitializeConsole()
|
|
||||||
{
|
|
||||||
SubscribeLocalEvent<CargoConsoleComponent, ComponentInit>(OnInit);
|
|
||||||
SubscribeLocalEvent<RoundRestartCleanupEvent>(Reset);
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
private void OnInit(EntityUid uid, CargoConsoleComponent console, ComponentInit args)
|
|
||||||
{
|
|
||||||
_linker.EnsureTransmitterPorts(uid, console.SenderPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Reset(RoundRestartCleanupEvent ev)
|
|
||||||
{
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Reset()
|
|
||||||
{
|
|
||||||
_accountsDict.Clear();
|
|
||||||
_databasesDict.Clear();
|
|
||||||
_timer = 0;
|
|
||||||
_accountIndex = 0;
|
|
||||||
|
|
||||||
CreateBankAccount("Space Station 14", 1000);
|
|
||||||
CreateOrderDatabase(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateConsole(float frameTime)
|
|
||||||
{
|
|
||||||
_timer += frameTime;
|
|
||||||
|
|
||||||
while (_timer > Delay)
|
|
||||||
{
|
|
||||||
_timer -= Delay;
|
|
||||||
|
|
||||||
foreach (var account in BankAccounts)
|
|
||||||
{
|
|
||||||
account.Balance += PointIncrease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new bank account.
|
|
||||||
/// </summary>
|
|
||||||
public void CreateBankAccount(string name, int balance)
|
|
||||||
{
|
|
||||||
var account = new CargoBankAccount(_accountIndex, name, balance);
|
|
||||||
_accountsDict.Add(_accountIndex, account);
|
|
||||||
_accountIndex += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CreateOrderDatabase(int id)
|
|
||||||
{
|
|
||||||
_databasesDict.Add(id, new CargoOrderDatabase(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the bank account associated with the given ID.
|
|
||||||
/// </summary>
|
|
||||||
public CargoBankAccount GetBankAccount(int id)
|
|
||||||
{
|
|
||||||
return _accountsDict[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
public CargoOrderDatabase GetOrderDatabase(int id)
|
|
||||||
{
|
|
||||||
return _databasesDict[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns whether the account exists, eventually passing the account in the out parameter.
|
|
||||||
/// </summary>
|
|
||||||
public bool TryGetBankAccount(int id, [NotNullWhen(true)] out CargoBankAccount? account)
|
|
||||||
{
|
|
||||||
return _accountsDict.TryGetValue(id, out account);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TryGetOrderDatabase(int id, [NotNullWhen(true)] out CargoOrderDatabase? database)
|
|
||||||
{
|
|
||||||
return _databasesDict.TryGetValue(id, out database);
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// Verifies if there is enough money in the account's balance to pay the amount.
|
|
||||||
/// Returns false if there's no account associated with the given ID
|
|
||||||
/// or if the balance would end up being negative.
|
|
||||||
/// </summary>
|
|
||||||
public bool CheckBalance(int id, int amount)
|
|
||||||
{
|
|
||||||
if (!TryGetBankAccount(id, out var account))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (account.Balance + amount < 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// Attempts to change the given account's balance.
|
|
||||||
/// Returns false if there's no account associated with the given ID
|
|
||||||
/// or if the balance would end up being negative.
|
|
||||||
/// </summary>
|
|
||||||
public bool ChangeBalance(int id, int amount)
|
|
||||||
{
|
|
||||||
if (!TryGetBankAccount(id, out var account))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
account.Balance += amount;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddOrder(int id, string requester, string reason, string productId, int amount, int payingAccountId)
|
|
||||||
{
|
|
||||||
if (amount < 1 || !TryGetOrderDatabase(id, out var database) || amount > database.MaxOrderSize)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
database.AddOrder(requester, reason, productId, amount, payingAccountId);
|
|
||||||
SyncComponentsWithId(id);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool RemoveOrder(int id, int orderNumber)
|
|
||||||
{
|
|
||||||
if (!TryGetOrderDatabase(id, out var database))
|
|
||||||
return false;
|
|
||||||
database.RemoveOrder(orderNumber);
|
|
||||||
SyncComponentsWithId(id);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ApproveOrder(EntityUid uid, EntityUid approver, int id, int orderNumber, AccessReaderComponent? reader = null)
|
|
||||||
{
|
|
||||||
// does the approver have permission to approve orders?
|
|
||||||
if (Resolve(uid, ref reader) && !_accessReaderSystem.IsAllowed(approver, reader))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// get the approver's name
|
|
||||||
_idCardSystem.TryFindIdCard(approver, out var idCard);
|
|
||||||
var approverName = idCard?.FullName ?? string.Empty;
|
|
||||||
|
|
||||||
if (!TryGetOrderDatabase(id, out var database))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!database.TryGetOrder(orderNumber, out var order))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!database.ApproveOrder(approverName, orderNumber))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
SyncComponentsWithId(id);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<CargoOrderData> RemoveAndGetApprovedOrders(int id)
|
|
||||||
{
|
|
||||||
if (!TryGetOrderDatabase(id, out var database))
|
|
||||||
return new List<CargoOrderData>();
|
|
||||||
var approvedOrders = database.SpliceApproved();
|
|
||||||
SyncComponentsWithId(id);
|
|
||||||
return approvedOrders;
|
|
||||||
}
|
|
||||||
|
|
||||||
public (int CurrentCapacity, int MaxCapacity) GetCapacity(int id)
|
|
||||||
{
|
|
||||||
if (!TryGetOrderDatabase(id, out var database))
|
|
||||||
return (0,0);
|
|
||||||
return (database.CurrentOrderSize, database.MaxOrderSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SyncComponentsWithId(int id)
|
|
||||||
{
|
|
||||||
foreach (var comp in EntityManager.EntityQuery<CargoOrderDatabaseComponent>(true))
|
|
||||||
{
|
|
||||||
if (comp.Database == null || comp.Database.Id != id)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Dirty(comp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
324
Content.Server/Cargo/Systems/CargoSystem.Orders.cs
Normal file
324
Content.Server/Cargo/Systems/CargoSystem.Orders.cs
Normal file
@@ -0,0 +1,324 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using Content.Server.Access.Systems;
|
||||||
|
using Content.Server.Cargo.Components;
|
||||||
|
using Content.Server.MachineLinking.System;
|
||||||
|
using Content.Server.Popups;
|
||||||
|
using Content.Server.Station.Systems;
|
||||||
|
using Content.Shared.Access.Systems;
|
||||||
|
using Content.Shared.Cargo;
|
||||||
|
using Content.Shared.Cargo.BUI;
|
||||||
|
using Content.Shared.Cargo.Events;
|
||||||
|
using Content.Shared.Cargo.Prototypes;
|
||||||
|
using Content.Shared.GameTicking;
|
||||||
|
using Robust.Server.GameObjects;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.Player;
|
||||||
|
using Robust.Shared.Players;
|
||||||
|
|
||||||
|
namespace Content.Server.Cargo.Systems
|
||||||
|
{
|
||||||
|
public sealed partial class CargoSystem
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// How much time to wait (in seconds) before increasing bank accounts balance.
|
||||||
|
/// </summary>
|
||||||
|
private const int Delay = 10;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Keeps track of how much time has elapsed since last balance increase.
|
||||||
|
/// </summary>
|
||||||
|
private float _timer;
|
||||||
|
|
||||||
|
[Dependency] private readonly IdCardSystem _idCardSystem = default!;
|
||||||
|
[Dependency] private readonly AccessReaderSystem _accessReaderSystem = default!;
|
||||||
|
[Dependency] private readonly SignalLinkerSystem _linker = default!;
|
||||||
|
[Dependency] private readonly PopupSystem _popup = default!;
|
||||||
|
[Dependency] private readonly StationSystem _station = default!;
|
||||||
|
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
|
||||||
|
|
||||||
|
private void InitializeConsole()
|
||||||
|
{
|
||||||
|
SubscribeLocalEvent<CargoOrderConsoleComponent, CargoConsoleAddOrderMessage>(OnAddOrderMessage);
|
||||||
|
SubscribeLocalEvent<CargoOrderConsoleComponent, CargoConsoleRemoveOrderMessage>(OnRemoveOrderMessage);
|
||||||
|
SubscribeLocalEvent<CargoOrderConsoleComponent, CargoConsoleApproveOrderMessage>(OnApproveOrderMessage);
|
||||||
|
SubscribeLocalEvent<CargoOrderConsoleComponent, BoundUIOpenedEvent>(OnOrderUIOpened);
|
||||||
|
SubscribeLocalEvent<CargoOrderConsoleComponent, ComponentInit>(OnInit);
|
||||||
|
SubscribeLocalEvent<RoundRestartCleanupEvent>(Reset);
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnInit(EntityUid uid, CargoOrderConsoleComponent orderConsole, ComponentInit args)
|
||||||
|
{
|
||||||
|
var station = _station.GetOwningStation(uid);
|
||||||
|
UpdateOrderState(orderConsole, station);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Reset(RoundRestartCleanupEvent ev)
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Reset()
|
||||||
|
{
|
||||||
|
_timer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateConsole(float frameTime)
|
||||||
|
{
|
||||||
|
_timer += frameTime;
|
||||||
|
|
||||||
|
while (_timer > Delay)
|
||||||
|
{
|
||||||
|
_timer -= Delay;
|
||||||
|
|
||||||
|
foreach (var account in EntityQuery<StationBankAccountComponent>())
|
||||||
|
{
|
||||||
|
account.Balance += account.IncreasePerSecond * Delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var comp in EntityQuery<CargoOrderConsoleComponent>())
|
||||||
|
{
|
||||||
|
if (!_uiSystem.IsUiOpen(comp.Owner, CargoConsoleUiKey.Orders)) continue;
|
||||||
|
|
||||||
|
var station = _station.GetOwningStation(comp.Owner);
|
||||||
|
UpdateOrderState(comp, station);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Interface
|
||||||
|
|
||||||
|
private void OnApproveOrderMessage(EntityUid uid, CargoOrderConsoleComponent component, CargoConsoleApproveOrderMessage args)
|
||||||
|
{
|
||||||
|
if (args.Session.AttachedEntity is not {Valid: true} player)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!_accessReaderSystem.IsAllowed(player, uid))
|
||||||
|
{
|
||||||
|
ConsolePopup(args.Session, Loc.GetString("cargo-console-order-not-allowed"));
|
||||||
|
PlayDenySound(uid, component);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var orderDatabase = GetOrderDatabase(component);
|
||||||
|
var bankAccount = GetBankAccount(component);
|
||||||
|
|
||||||
|
// No station to deduct from.
|
||||||
|
if (orderDatabase == null || bankAccount == null)
|
||||||
|
{
|
||||||
|
ConsolePopup(args.Session, Loc.GetString("cargo-console-station-not-found"));
|
||||||
|
PlayDenySound(uid, component);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No order to approve?
|
||||||
|
if (!orderDatabase.Orders.TryGetValue(args.OrderNumber, out var order) ||
|
||||||
|
order.Approved) return;
|
||||||
|
|
||||||
|
// Invalid order
|
||||||
|
if (!_protoMan.TryIndex<CargoProductPrototype>(order.ProductId, out var product))
|
||||||
|
{
|
||||||
|
ConsolePopup(args.Session, Loc.GetString("cargo-console-invalid-product"));
|
||||||
|
PlayDenySound(uid, component);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var amount = GetOrderCount(orderDatabase);
|
||||||
|
var capacity = orderDatabase.Capacity;
|
||||||
|
|
||||||
|
// Too many orders, avoid them getting spammed in the UI.
|
||||||
|
if (amount >= capacity)
|
||||||
|
{
|
||||||
|
ConsolePopup(args.Session, Loc.GetString("cargo-console-too-many"));
|
||||||
|
PlayDenySound(uid, component);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cap orders so someone can't spam thousands.
|
||||||
|
var orderAmount = Math.Min(capacity - amount, order.Amount);
|
||||||
|
|
||||||
|
if (orderAmount != order.Amount)
|
||||||
|
{
|
||||||
|
order.Amount = orderAmount;
|
||||||
|
ConsolePopup(args.Session, Loc.GetString("cargo-console-snip-snip"));
|
||||||
|
PlayDenySound(uid, component);
|
||||||
|
}
|
||||||
|
|
||||||
|
var cost = product.PointCost * order.Amount;
|
||||||
|
|
||||||
|
// Not enough balance
|
||||||
|
if (cost > bankAccount.Balance)
|
||||||
|
{
|
||||||
|
ConsolePopup(args.Session, Loc.GetString("cargo-console-insufficient-funds", ("cost", cost)));
|
||||||
|
PlayDenySound(uid, component);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
order.Approved = true;
|
||||||
|
_idCardSystem.TryFindIdCard(player, out var idCard);
|
||||||
|
order.Approver = idCard?.FullName ?? string.Empty;
|
||||||
|
|
||||||
|
|
||||||
|
SoundSystem.Play(component.ConfirmSound.GetSound(), Filter.Pvs(uid, entityManager: EntityManager), uid);
|
||||||
|
|
||||||
|
DeductFunds(bankAccount, cost);
|
||||||
|
UpdateOrders(orderDatabase);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnRemoveOrderMessage(EntityUid uid, CargoOrderConsoleComponent component, CargoConsoleRemoveOrderMessage args)
|
||||||
|
{
|
||||||
|
var orderDatabase = GetOrderDatabase(component);
|
||||||
|
if (orderDatabase == null) return;
|
||||||
|
RemoveOrder(orderDatabase, args.OrderNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnAddOrderMessage(EntityUid uid, CargoOrderConsoleComponent component, CargoConsoleAddOrderMessage args)
|
||||||
|
{
|
||||||
|
if (args.Amount <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var bank = GetBankAccount(component);
|
||||||
|
if (bank == null) return;
|
||||||
|
var orderDatabase = GetOrderDatabase(component);
|
||||||
|
if (orderDatabase == null) return;
|
||||||
|
|
||||||
|
var data = GetOrderData(args, GetNextIndex(orderDatabase));
|
||||||
|
|
||||||
|
if (!TryAddOrder(orderDatabase, data))
|
||||||
|
{
|
||||||
|
PlayDenySound(uid, component);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnOrderUIOpened(EntityUid uid, CargoOrderConsoleComponent component, BoundUIOpenedEvent args)
|
||||||
|
{
|
||||||
|
var station = _station.GetOwningStation(uid);
|
||||||
|
UpdateOrderState(component, station);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private void UpdateOrderState(CargoOrderConsoleComponent component, EntityUid? station)
|
||||||
|
{
|
||||||
|
if (station == null ||
|
||||||
|
!TryComp<StationCargoOrderDatabaseComponent>(station, out var orderDatabase) ||
|
||||||
|
!TryComp<StationBankAccountComponent>(station, out var bankAccount)) return;
|
||||||
|
|
||||||
|
var state = new CargoConsoleInterfaceState(
|
||||||
|
MetaData(station.Value).EntityName,
|
||||||
|
GetOrderCount(orderDatabase),
|
||||||
|
orderDatabase.Capacity,
|
||||||
|
bankAccount.Balance,
|
||||||
|
orderDatabase.Orders.Values.ToList());
|
||||||
|
|
||||||
|
_uiSystem.GetUiOrNull(component.Owner, CargoConsoleUiKey.Orders)?.SetState(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConsolePopup(ICommonSession session, string text)
|
||||||
|
{
|
||||||
|
_popup.PopupCursor(text, Filter.SinglePlayer(session));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PlayDenySound(EntityUid uid, CargoOrderConsoleComponent component)
|
||||||
|
{
|
||||||
|
SoundSystem.Play(component.ErrorSound.GetSound(), Filter.Pvs(uid, entityManager: EntityManager), uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CargoOrderData GetOrderData(CargoConsoleAddOrderMessage args, int index)
|
||||||
|
{
|
||||||
|
return new CargoOrderData(index, args.Requester, args.Reason, args.ProductId, args.Amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetOrderCount(StationCargoOrderDatabaseComponent component)
|
||||||
|
{
|
||||||
|
var amount = 0;
|
||||||
|
|
||||||
|
foreach (var (_, order) in component.Orders)
|
||||||
|
{
|
||||||
|
if (!order.Approved) continue;
|
||||||
|
amount += order.Amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates all of the cargo-related consoles for a particular station.
|
||||||
|
/// This should be called whenever orders change.
|
||||||
|
/// </summary>
|
||||||
|
private void UpdateOrders(StationCargoOrderDatabaseComponent component)
|
||||||
|
{
|
||||||
|
// Order added so all consoles need updating.
|
||||||
|
foreach (var comp in EntityQuery<CargoOrderConsoleComponent>(true))
|
||||||
|
{
|
||||||
|
var station = _station.GetOwningStation(component.Owner);
|
||||||
|
if (station != component.Owner) continue;
|
||||||
|
|
||||||
|
UpdateOrderState(comp, station);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var comp in EntityQuery<CargoShuttleConsoleComponent>(true))
|
||||||
|
{
|
||||||
|
var station = _station.GetOwningStation(component.Owner);
|
||||||
|
if (station != component.Owner) continue;
|
||||||
|
|
||||||
|
UpdateShuttleState(comp, station);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryAddOrder(StationCargoOrderDatabaseComponent component, CargoOrderData data)
|
||||||
|
{
|
||||||
|
component.Orders.Add(data.OrderNumber, data);
|
||||||
|
UpdateOrders(component);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetNextIndex(StationCargoOrderDatabaseComponent component)
|
||||||
|
{
|
||||||
|
var index = component.Index;
|
||||||
|
component.Index++;
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveOrder(StationCargoOrderDatabaseComponent component, int index)
|
||||||
|
{
|
||||||
|
if (!component.Orders.Remove(index)) return;
|
||||||
|
UpdateOrders(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearOrders(StationCargoOrderDatabaseComponent component)
|
||||||
|
{
|
||||||
|
if (component.Orders.Count == 0) return;
|
||||||
|
|
||||||
|
component.Orders.Clear();
|
||||||
|
Dirty(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeductFunds(StationBankAccountComponent component, int amount)
|
||||||
|
{
|
||||||
|
component.Balance = Math.Max(0, component.Balance - amount);
|
||||||
|
Dirty(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Station
|
||||||
|
|
||||||
|
private StationBankAccountComponent? GetBankAccount(CargoOrderConsoleComponent component)
|
||||||
|
{
|
||||||
|
var station = _station.GetOwningStation(component.Owner);
|
||||||
|
|
||||||
|
TryComp<StationBankAccountComponent>(station, out var bankComponent);
|
||||||
|
return bankComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private StationCargoOrderDatabaseComponent? GetOrderDatabase(CargoOrderConsoleComponent component)
|
||||||
|
{
|
||||||
|
var station = _station.GetOwningStation(component.Owner);
|
||||||
|
|
||||||
|
TryComp<StationCargoOrderDatabaseComponent>(station, out var orderComponent);
|
||||||
|
return orderComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
528
Content.Server/Cargo/Systems/CargoSystem.Shuttle.cs
Normal file
528
Content.Server/Cargo/Systems/CargoSystem.Shuttle.cs
Normal file
@@ -0,0 +1,528 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Linq;
|
||||||
|
using Content.Server.Cargo.Components;
|
||||||
|
using Content.Server.GameTicking.Events;
|
||||||
|
using Content.Server.Shuttles.Components;
|
||||||
|
using Content.Server.Shuttles.Events;
|
||||||
|
using Content.Server.UserInterface;
|
||||||
|
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 Content.Shared.Dataset;
|
||||||
|
using Content.Shared.GameTicking;
|
||||||
|
using Content.Shared.MobState.Components;
|
||||||
|
using Robust.Server.GameObjects;
|
||||||
|
using Robust.Server.Maps;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Shared.Player;
|
||||||
|
using Robust.Shared.Random;
|
||||||
|
using Robust.Shared.Timing;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
|
namespace Content.Server.Cargo.Systems;
|
||||||
|
|
||||||
|
public sealed partial class CargoSystem
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Handles cargo shuttle mechanics, including cargo shuttle consoles.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[Dependency] private readonly IGameTiming _timing = default!;
|
||||||
|
[Dependency] private readonly IMapLoader _loader = default!;
|
||||||
|
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||||
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
|
[Dependency] private readonly EntityLookupSystem _lookup = default!;
|
||||||
|
[Dependency] private readonly PricingSystem _pricing = default!;
|
||||||
|
|
||||||
|
public MapId? CargoMap { get; private set; }
|
||||||
|
|
||||||
|
private const float ShuttleRecallRange = 100f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Minimum mass a grid needs to be to block a shuttle recall.
|
||||||
|
/// </summary>
|
||||||
|
private const float ShuttleCallMassThreshold = 300f;
|
||||||
|
|
||||||
|
private const float CallOffset = 50f;
|
||||||
|
|
||||||
|
private int _index;
|
||||||
|
|
||||||
|
private void InitializeShuttle()
|
||||||
|
{
|
||||||
|
SubscribeLocalEvent<CargoShuttleComponent, MoveEvent>(OnCargoShuttleMove);
|
||||||
|
SubscribeLocalEvent<CargoShuttleConsoleComponent, ComponentStartup>(OnCargoShuttleConsoleStartup);
|
||||||
|
SubscribeLocalEvent<CargoShuttleConsoleComponent, CargoCallShuttleMessage>(OnCargoShuttleCall);
|
||||||
|
SubscribeLocalEvent<CargoShuttleConsoleComponent, CargoRecallShuttleMessage>(RecallCargoShuttle);
|
||||||
|
|
||||||
|
SubscribeLocalEvent<CargoPilotConsoleComponent, ConsoleShuttleEvent>(OnCargoGetConsole);
|
||||||
|
SubscribeLocalEvent<CargoPilotConsoleComponent, AfterActivatableUIOpenEvent>(OnCargoPilotConsoleOpen);
|
||||||
|
SubscribeLocalEvent<CargoPilotConsoleComponent, BoundUIClosedEvent>(OnCargoPilotConsoleClose);
|
||||||
|
|
||||||
|
SubscribeLocalEvent<StationCargoOrderDatabaseComponent, ComponentStartup>(OnCargoOrderStartup);
|
||||||
|
|
||||||
|
SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundRestart);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Cargo Pilot Console
|
||||||
|
|
||||||
|
private void OnCargoPilotConsoleOpen(EntityUid uid, CargoPilotConsoleComponent component, AfterActivatableUIOpenEvent args)
|
||||||
|
{
|
||||||
|
component.Entity = GetShuttleConsole(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCargoPilotConsoleClose(EntityUid uid, CargoPilotConsoleComponent component, BoundUIClosedEvent args)
|
||||||
|
{
|
||||||
|
component.Entity = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCargoGetConsole(EntityUid uid, CargoPilotConsoleComponent component, ref ConsoleShuttleEvent args)
|
||||||
|
{
|
||||||
|
args.Console = GetShuttleConsole(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
private EntityUid? GetShuttleConsole(CargoPilotConsoleComponent component)
|
||||||
|
{
|
||||||
|
var stationUid = _station.GetOwningStation(component.Owner);
|
||||||
|
|
||||||
|
if (!TryComp<StationCargoOrderDatabaseComponent>(stationUid, out var orderDatabase) ||
|
||||||
|
!TryComp<CargoShuttleComponent>(orderDatabase.Shuttle, out var shuttle)) return null;
|
||||||
|
|
||||||
|
return GetShuttleConsole(shuttle);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Console
|
||||||
|
|
||||||
|
private void UpdateShuttleCargoConsoles(CargoShuttleComponent component)
|
||||||
|
{
|
||||||
|
foreach (var console in EntityQuery<CargoShuttleConsoleComponent>(true))
|
||||||
|
{
|
||||||
|
var stationUid = _station.GetOwningStation(console.Owner);
|
||||||
|
if (stationUid != component.Station) continue;
|
||||||
|
UpdateShuttleState(console, stationUid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCargoShuttleConsoleStartup(EntityUid uid, CargoShuttleConsoleComponent component, ComponentStartup args)
|
||||||
|
{
|
||||||
|
var station = _station.GetOwningStation(uid);
|
||||||
|
UpdateShuttleState(component, station);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateShuttleState(CargoShuttleConsoleComponent component, EntityUid? station = null)
|
||||||
|
{
|
||||||
|
TryComp<StationCargoOrderDatabaseComponent>(station, out var orderDatabase);
|
||||||
|
TryComp<CargoShuttleComponent>(orderDatabase?.Shuttle, out var shuttle);
|
||||||
|
|
||||||
|
var orders = GetProjectedOrders(orderDatabase, shuttle);
|
||||||
|
var shuttleName = orderDatabase?.Shuttle != null ? MetaData(orderDatabase.Shuttle.Value).EntityName : string.Empty;
|
||||||
|
|
||||||
|
// TODO: Loc
|
||||||
|
_uiSystem.GetUiOrNull(component.Owner, CargoConsoleUiKey.Shuttle)?.SetState(
|
||||||
|
new CargoShuttleConsoleBoundUserInterfaceState(
|
||||||
|
station != null ? MetaData(station.Value).EntityName : Loc.GetString("cargo-shuttle-console-station-unknown"),
|
||||||
|
string.IsNullOrEmpty(shuttleName) ? Loc.GetString("cargo-shuttle-console-shuttle-not-found") : shuttleName,
|
||||||
|
CanRecallShuttle(shuttle?.Owner, out _),
|
||||||
|
shuttle?.NextCall,
|
||||||
|
orders));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Shuttle
|
||||||
|
|
||||||
|
public EntityUid? GetShuttleConsole(CargoShuttleComponent component)
|
||||||
|
{
|
||||||
|
foreach (var (comp, xform) in EntityQuery<ShuttleConsoleComponent, TransformComponent>(true))
|
||||||
|
{
|
||||||
|
if (xform.ParentUid != component.Owner) continue;
|
||||||
|
return comp.Owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCargoShuttleMove(EntityUid uid, CargoShuttleComponent component, ref MoveEvent args)
|
||||||
|
{
|
||||||
|
if (component.Station == null) return;
|
||||||
|
|
||||||
|
var oldCanRecall = component.CanRecall;
|
||||||
|
|
||||||
|
// Check if we can update the recall status.
|
||||||
|
var canRecall = CanRecallShuttle(uid, out _, args.Component);
|
||||||
|
if (oldCanRecall == canRecall) return;
|
||||||
|
|
||||||
|
component.CanRecall = canRecall;
|
||||||
|
_sawmill.Debug($"Updated CanRecall for {ToPrettyString(uid)}");
|
||||||
|
UpdateShuttleCargoConsoles(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the orders that can fit on the cargo shuttle.
|
||||||
|
/// </summary>
|
||||||
|
private List<CargoOrderData> GetProjectedOrders(
|
||||||
|
StationCargoOrderDatabaseComponent? component = null,
|
||||||
|
CargoShuttleComponent? shuttle = null)
|
||||||
|
{
|
||||||
|
var orders = new List<CargoOrderData>();
|
||||||
|
|
||||||
|
if (component == null || shuttle == null || component.Orders.Count == 0)
|
||||||
|
return orders;
|
||||||
|
|
||||||
|
var space = GetCargoSpace(shuttle);
|
||||||
|
|
||||||
|
if (space == 0) return orders;
|
||||||
|
|
||||||
|
var indices = component.Orders.Keys.ToList();
|
||||||
|
indices.Sort();
|
||||||
|
var amount = 0;
|
||||||
|
|
||||||
|
foreach (var index in indices)
|
||||||
|
{
|
||||||
|
var order = component.Orders[index];
|
||||||
|
if (!order.Approved) continue;
|
||||||
|
|
||||||
|
var cappedAmount = Math.Min(space - amount, order.Amount);
|
||||||
|
amount += cappedAmount;
|
||||||
|
DebugTools.Assert(amount <= space);
|
||||||
|
|
||||||
|
if (cappedAmount < order.Amount)
|
||||||
|
{
|
||||||
|
var reducedOrder = new CargoOrderData(order.OrderNumber, order.Requester, order.Reason, order.ProductId,
|
||||||
|
cappedAmount);
|
||||||
|
|
||||||
|
orders.Add(reducedOrder);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
orders.Add(order);
|
||||||
|
|
||||||
|
if (amount == space) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return orders;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the amount of space the cargo shuttle can fit for orders.
|
||||||
|
/// </summary>
|
||||||
|
private int GetCargoSpace(CargoShuttleComponent component)
|
||||||
|
{
|
||||||
|
var space = GetCargoPallets(component).Count;
|
||||||
|
return space;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<CargoPalletComponent> GetCargoPallets(CargoShuttleComponent component)
|
||||||
|
{
|
||||||
|
var pads = new List<CargoPalletComponent>();
|
||||||
|
|
||||||
|
foreach (var (comp, compXform) in EntityQuery<CargoPalletComponent, TransformComponent>(true))
|
||||||
|
{
|
||||||
|
if (compXform.ParentUid != component.Owner ||
|
||||||
|
!compXform.Anchored) continue;
|
||||||
|
|
||||||
|
pads.Add(comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pads;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Station
|
||||||
|
|
||||||
|
private void OnCargoOrderStartup(EntityUid uid, StationCargoOrderDatabaseComponent component, ComponentStartup args)
|
||||||
|
{
|
||||||
|
// Stations get created first but if any are added at runtime then do this.
|
||||||
|
AddShuttle(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddShuttle(StationCargoOrderDatabaseComponent component)
|
||||||
|
{
|
||||||
|
Setup();
|
||||||
|
|
||||||
|
if (CargoMap == null || component.Shuttle != null) return;
|
||||||
|
|
||||||
|
if (component.CargoShuttleProto != null)
|
||||||
|
{
|
||||||
|
var prototype = _protoMan.Index<CargoShuttlePrototype>(component.CargoShuttleProto);
|
||||||
|
var possibleNames = _protoMan.Index<DatasetPrototype>(prototype.NameDataset).Values;
|
||||||
|
var name = _random.Pick(possibleNames);
|
||||||
|
|
||||||
|
var (_, gridId) = _loader.LoadBlueprint(CargoMap.Value, prototype.Path.ToString());
|
||||||
|
var shuttleUid = _mapManager.GetGridEuid(gridId!.Value);
|
||||||
|
var xform = Transform(shuttleUid);
|
||||||
|
MetaData(shuttleUid).EntityName = name;
|
||||||
|
|
||||||
|
// TODO: Something better like a bounds check.
|
||||||
|
xform.LocalPosition += 100 * _index;
|
||||||
|
var comp = EnsureComp<CargoShuttleComponent>(shuttleUid);
|
||||||
|
comp.Station = component.Owner;
|
||||||
|
comp.Coordinates = xform.Coordinates;
|
||||||
|
|
||||||
|
component.Shuttle = shuttleUid;
|
||||||
|
comp.NextCall = _timing.CurTime + TimeSpan.FromSeconds(comp.Cooldown);
|
||||||
|
UpdateShuttleCargoConsoles(comp);
|
||||||
|
_index++;
|
||||||
|
_sawmill.Info($"Added cargo shuttle to {ToPrettyString(shuttleUid)}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SellPallets(CargoShuttleComponent component, StationBankAccountComponent bank)
|
||||||
|
{
|
||||||
|
double amount = 0;
|
||||||
|
var toSell = new HashSet<EntityUid>();
|
||||||
|
var xformQuery = GetEntityQuery<TransformComponent>();
|
||||||
|
|
||||||
|
foreach (var pallet in GetCargoPallets(component))
|
||||||
|
{
|
||||||
|
// Containers should already get the sell price of their children so can skip those.
|
||||||
|
foreach (var ent in _lookup.GetEntitiesIntersecting(pallet.Owner, LookupFlags.Anchored))
|
||||||
|
{
|
||||||
|
// Don't re-sell anything, sell anything anchored (e.g. light fixtures), or anything blacklisted
|
||||||
|
// (e.g. players).
|
||||||
|
if (toSell.Contains(ent) ||
|
||||||
|
(xformQuery.TryGetComponent(ent, out var xform) && xform.Anchored)) continue;
|
||||||
|
|
||||||
|
var price = _pricing.GetPrice(ent);
|
||||||
|
if (price == 0) continue;
|
||||||
|
toSell.Add(ent);
|
||||||
|
amount += price;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bank.Balance += (int) amount;
|
||||||
|
_sawmill.Debug($"Cargo sold {toSell.Count} entities for {amount}");
|
||||||
|
|
||||||
|
foreach (var ent in toSell)
|
||||||
|
{
|
||||||
|
Del(ent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SendToCargoMap(EntityUid uid, CargoShuttleComponent? component = null)
|
||||||
|
{
|
||||||
|
if (!Resolve(uid, ref component))
|
||||||
|
return;
|
||||||
|
|
||||||
|
component.NextCall = _timing.CurTime + TimeSpan.FromSeconds(component.Cooldown);
|
||||||
|
Transform(uid).Coordinates = component.Coordinates;
|
||||||
|
DebugTools.Assert(MetaData(uid).EntityPaused);
|
||||||
|
|
||||||
|
UpdateShuttleCargoConsoles(component);
|
||||||
|
_sawmill.Info($"Stashed cargo shuttle {ToPrettyString(uid)}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves a shuttle for delivery.
|
||||||
|
/// </summary>
|
||||||
|
public void CallShuttle(StationCargoOrderDatabaseComponent orderDatabase)
|
||||||
|
{
|
||||||
|
if (!TryComp<CargoShuttleComponent>(orderDatabase.Shuttle, out var shuttle) ||
|
||||||
|
!TryComp<TransformComponent>(orderDatabase.Owner, out var xform)) return;
|
||||||
|
|
||||||
|
// Already called / not available
|
||||||
|
if (shuttle.NextCall == null || _timing.CurTime < shuttle.NextCall)
|
||||||
|
return;
|
||||||
|
|
||||||
|
shuttle.NextCall = null;
|
||||||
|
|
||||||
|
// Find a valid free area nearby to spawn in on
|
||||||
|
var center = new Vector2();
|
||||||
|
var minRadius = 0f;
|
||||||
|
Box2? aabb = null;
|
||||||
|
|
||||||
|
foreach (var grid in _mapManager.GetAllMapGrids(xform.MapID))
|
||||||
|
{
|
||||||
|
aabb = aabb?.Union(grid.WorldAABB) ?? grid.WorldAABB;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aabb != null)
|
||||||
|
{
|
||||||
|
center = aabb.Value.Center;
|
||||||
|
minRadius = MathF.Max(aabb.Value.Width, aabb.Value.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
var offset = 0f;
|
||||||
|
if (TryComp<IMapGridComponent>(orderDatabase.Shuttle, out var shuttleGrid))
|
||||||
|
{
|
||||||
|
var bounds = shuttleGrid.Grid.LocalAABB;
|
||||||
|
offset = MathF.Max(bounds.Width, bounds.Height) / 2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Transform(shuttle.Owner).Coordinates = new EntityCoordinates(xform.ParentUid,
|
||||||
|
center + _random.NextVector2(minRadius + offset, minRadius + CallOffset + offset));
|
||||||
|
DebugTools.Assert(!MetaData(shuttle.Owner).EntityPaused);
|
||||||
|
|
||||||
|
AddCargoContents(shuttle, orderDatabase);
|
||||||
|
UpdateOrders(orderDatabase);
|
||||||
|
UpdateShuttleCargoConsoles(shuttle);
|
||||||
|
|
||||||
|
_sawmill.Info($"Retrieved cargo shuttle {ToPrettyString(shuttle.Owner)} from {ToPrettyString(orderDatabase.Owner)}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddCargoContents(CargoShuttleComponent component, StationCargoOrderDatabaseComponent orderDatabase)
|
||||||
|
{
|
||||||
|
var xformQuery = GetEntityQuery<TransformComponent>();
|
||||||
|
var orders = GetProjectedOrders(orderDatabase, component);
|
||||||
|
|
||||||
|
var pads = GetCargoPallets(component);
|
||||||
|
DebugTools.Assert(orders.Sum(o => o.Amount) <= pads.Count);
|
||||||
|
|
||||||
|
for (var i = 0; i < orders.Count; i++)
|
||||||
|
{
|
||||||
|
var order = orders[i];
|
||||||
|
|
||||||
|
Spawn(_protoMan.Index<CargoProductPrototype>(order.ProductId).Product,
|
||||||
|
new EntityCoordinates(component.Owner, xformQuery.GetComponent(_random.PickAndTake(pads).Owner).LocalPosition));
|
||||||
|
order.Amount--;
|
||||||
|
|
||||||
|
if (order.Amount == 0)
|
||||||
|
{
|
||||||
|
orders.RemoveSwap(i);
|
||||||
|
orderDatabase.Orders.Remove(order.OrderNumber);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
orderDatabase.Orders[order.OrderNumber] = order;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanRecallShuttle(EntityUid? uid, [NotNullWhen(false)] out string? reason, TransformComponent? xform = null)
|
||||||
|
{
|
||||||
|
reason = null;
|
||||||
|
|
||||||
|
if (!TryComp<IMapGridComponent>(uid, out var grid) ||
|
||||||
|
!Resolve(uid.Value, ref xform)) return true;
|
||||||
|
|
||||||
|
var bounds = grid.Grid.WorldAABB.Enlarged(ShuttleRecallRange);
|
||||||
|
var bodyQuery = GetEntityQuery<PhysicsComponent>();
|
||||||
|
|
||||||
|
foreach (var other in _mapManager.FindGridsIntersecting(xform.MapID, bounds))
|
||||||
|
{
|
||||||
|
if (grid.GridIndex == other.Index ||
|
||||||
|
!bodyQuery.TryGetComponent(other.GridEntityId, out var body) ||
|
||||||
|
body.Mass < ShuttleCallMassThreshold) continue;
|
||||||
|
|
||||||
|
reason = Loc.GetString("cargo-shuttle-console-proximity");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RecallCargoShuttle(EntityUid uid, CargoShuttleConsoleComponent component, CargoRecallShuttleMessage args)
|
||||||
|
{
|
||||||
|
var player = args.Session.AttachedEntity;
|
||||||
|
|
||||||
|
if (player == null) return;
|
||||||
|
|
||||||
|
var stationUid = _station.GetOwningStation(component.Owner);
|
||||||
|
|
||||||
|
if (!TryComp<StationCargoOrderDatabaseComponent>(stationUid, out var orderDatabase) ||
|
||||||
|
!TryComp<StationBankAccountComponent>(stationUid, out var bank)) return;
|
||||||
|
|
||||||
|
if (!TryComp<CargoShuttleComponent>(orderDatabase.Shuttle, out var shuttle))
|
||||||
|
{
|
||||||
|
_popup.PopupEntity($"No cargo shuttle found!", args.Entity, Filter.Entities(args.Entity));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CanRecallShuttle(shuttle.Owner, out var reason))
|
||||||
|
{
|
||||||
|
_popup.PopupEntity(reason, args.Entity, Filter.Entities(args.Entity));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsBlocked(shuttle))
|
||||||
|
{
|
||||||
|
_popup.PopupEntity(Loc.GetString("cargo-shuttle-console-organics"), player.Value, Filter.Entities(player.Value));
|
||||||
|
SoundSystem.Play(component.DenySound.GetSound(), Filter.Pvs(uid, entityManager: EntityManager), uid);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
SellPallets(shuttle, bank);
|
||||||
|
|
||||||
|
SendToCargoMap(orderDatabase.Shuttle.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="component"></param>
|
||||||
|
private bool IsBlocked(CargoShuttleComponent component)
|
||||||
|
{
|
||||||
|
// TODO: Would be good to rate-limit this on the console.
|
||||||
|
var mobQuery = GetEntityQuery<MobStateComponent>();
|
||||||
|
var xformQuery = GetEntityQuery<TransformComponent>();
|
||||||
|
|
||||||
|
return FoundOrganics(component.Owner, mobQuery, xformQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool FoundOrganics(EntityUid uid, EntityQuery<MobStateComponent> mobQuery, EntityQuery<TransformComponent> xformQuery)
|
||||||
|
{
|
||||||
|
var xform = xformQuery.GetComponent(uid);
|
||||||
|
var childEnumerator = xform.ChildEnumerator;
|
||||||
|
|
||||||
|
while (childEnumerator.MoveNext(out var child))
|
||||||
|
{
|
||||||
|
if (mobQuery.HasComponent(child.Value) ||
|
||||||
|
FoundOrganics(child.Value, mobQuery, xformQuery)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCargoShuttleCall(EntityUid uid, CargoShuttleConsoleComponent component, CargoCallShuttleMessage args)
|
||||||
|
{
|
||||||
|
var stationUid = _station.GetOwningStation(args.Entity);
|
||||||
|
if (!TryComp<StationCargoOrderDatabaseComponent>(stationUid, out var orderDatabase)) return;
|
||||||
|
CallShuttle(orderDatabase);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private void OnRoundRestart(RoundRestartCleanupEvent ev)
|
||||||
|
{
|
||||||
|
Cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Cleanup()
|
||||||
|
{
|
||||||
|
if (CargoMap == null || !_mapManager.MapExists(CargoMap.Value))
|
||||||
|
{
|
||||||
|
CargoMap = null;
|
||||||
|
DebugTools.Assert(!EntityQuery<CargoShuttleComponent>().Any());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_mapManager.DeleteMap(CargoMap.Value);
|
||||||
|
CargoMap = null;
|
||||||
|
|
||||||
|
// Shuttle may not have been in the cargo dimension (e.g. on the station map) so need to delete.
|
||||||
|
foreach (var comp in EntityQuery<CargoShuttleComponent>())
|
||||||
|
{
|
||||||
|
QueueDel(comp.Owner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Setup()
|
||||||
|
{
|
||||||
|
if (CargoMap != null && _mapManager.MapExists(CargoMap.Value)) return;
|
||||||
|
|
||||||
|
// It gets mapinit which is okay... buuutt we still want it paused to avoid power draining.
|
||||||
|
CargoMap = _mapManager.CreateMap();
|
||||||
|
_mapManager.SetMapPaused(CargoMap!.Value, true);
|
||||||
|
|
||||||
|
foreach (var comp in EntityQuery<StationCargoOrderDatabaseComponent>(true))
|
||||||
|
{
|
||||||
|
AddShuttle(comp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
|
using System.Linq;
|
||||||
using Content.Server.Cargo.Components;
|
using Content.Server.Cargo.Components;
|
||||||
using Content.Server.Labels.Components;
|
using Content.Server.Labels.Components;
|
||||||
using Content.Server.Paper;
|
using Content.Server.Paper;
|
||||||
using Content.Server.Power.Components;
|
using Content.Server.Power.Components;
|
||||||
using Content.Shared.Cargo;
|
using Content.Shared.Cargo;
|
||||||
|
using Content.Shared.Cargo.Prototypes;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.Collections;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
|
|
||||||
namespace Content.Server.Cargo.Systems;
|
namespace Content.Server.Cargo.Systems;
|
||||||
@@ -27,7 +30,7 @@ public sealed partial class CargoSystem
|
|||||||
// Don't EntityQuery for it as it's not required.
|
// Don't EntityQuery for it as it's not required.
|
||||||
TryComp<AppearanceComponent>(comp.Owner, out var appearance);
|
TryComp<AppearanceComponent>(comp.Owner, out var appearance);
|
||||||
|
|
||||||
if (comp.CurrentState == CargoTelepadState.Unpowered || comp.TeleportQueue.Count <= 0)
|
if (comp.CurrentState == CargoTelepadState.Unpowered)
|
||||||
{
|
{
|
||||||
comp.CurrentState = CargoTelepadState.Idle;
|
comp.CurrentState = CargoTelepadState.Idle;
|
||||||
appearance?.SetData(CargoTelepadVisuals.State, CargoTelepadState.Idle);
|
appearance?.SetData(CargoTelepadVisuals.State, CargoTelepadState.Idle);
|
||||||
@@ -45,14 +48,44 @@ public sealed partial class CargoSystem
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var product = comp.TeleportQueue.Pop();
|
var station = _station.GetOwningStation(comp.Owner);
|
||||||
|
|
||||||
|
if (!TryComp<StationCargoOrderDatabaseComponent>(station, out var orderDatabase) ||
|
||||||
|
orderDatabase.Orders.Count == 0)
|
||||||
|
{
|
||||||
|
comp.Accumulator += comp.Delay;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var orderIndices = new ValueList<int>();
|
||||||
|
|
||||||
|
foreach (var (oIndex, oOrder) in orderDatabase.Orders)
|
||||||
|
{
|
||||||
|
if (!oOrder.Approved) continue;
|
||||||
|
orderIndices.Add(oIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orderIndices.Count == 0)
|
||||||
|
{
|
||||||
|
comp.Accumulator += comp.Delay;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
orderIndices.Sort();
|
||||||
|
var index = orderIndices[0];
|
||||||
|
var order = orderDatabase.Orders[index];
|
||||||
|
order.Amount--;
|
||||||
|
|
||||||
|
if (order.Amount <= 0)
|
||||||
|
orderDatabase.Orders.Remove(index);
|
||||||
|
|
||||||
SoundSystem.Play(comp.TeleportSound.GetSound(), Filter.Pvs(comp.Owner), comp.Owner, AudioParams.Default.WithVolume(-8f));
|
SoundSystem.Play(comp.TeleportSound.GetSound(), Filter.Pvs(comp.Owner), comp.Owner, AudioParams.Default.WithVolume(-8f));
|
||||||
SpawnProduct(comp, product);
|
SpawnProduct(comp, order);
|
||||||
|
UpdateOrders(orderDatabase);
|
||||||
|
|
||||||
comp.CurrentState = CargoTelepadState.Teleporting;
|
comp.CurrentState = CargoTelepadState.Teleporting;
|
||||||
appearance?.SetData(CargoTelepadVisuals.State, CargoTelepadState.Teleporting);
|
appearance?.SetData(CargoTelepadVisuals.State, CargoTelepadState.Teleporting);
|
||||||
comp.Accumulator = comp.Delay;
|
comp.Accumulator += comp.Delay;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,14 +120,6 @@ public sealed partial class CargoSystem
|
|||||||
SetEnabled(component);
|
SetEnabled(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void QueueTeleport(CargoTelepadComponent component, CargoOrderData order)
|
|
||||||
{
|
|
||||||
for (var i = 0; i < order.Amount; i++)
|
|
||||||
{
|
|
||||||
component.TeleportQueue.Push(order);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Spawn the product and a piece of paper. Attempt to attach the paper to the product.
|
/// Spawn the product and a piece of paper. Attempt to attach the paper to the product.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
|
using Content.Server.Cargo.Components;
|
||||||
|
using Content.Server.Station.Systems;
|
||||||
using Content.Shared.Cargo;
|
using Content.Shared.Cargo;
|
||||||
|
using Content.Shared.Cargo.Components;
|
||||||
using Content.Shared.Containers.ItemSlots;
|
using Content.Shared.Containers.ItemSlots;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
@@ -9,11 +12,28 @@ public sealed partial class CargoSystem : SharedCargoSystem
|
|||||||
[Dependency] private readonly IPrototypeManager _protoMan = default!;
|
[Dependency] private readonly IPrototypeManager _protoMan = default!;
|
||||||
[Dependency] private readonly ItemSlotsSystem _slots = default!;
|
[Dependency] private readonly ItemSlotsSystem _slots = default!;
|
||||||
|
|
||||||
|
private ISawmill _sawmill = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
_sawmill = Logger.GetSawmill("cargo");
|
||||||
InitializeConsole();
|
InitializeConsole();
|
||||||
|
InitializeShuttle();
|
||||||
InitializeTelepad();
|
InitializeTelepad();
|
||||||
|
SubscribeLocalEvent<StationInitializedEvent>(OnStationInit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Shutdown()
|
||||||
|
{
|
||||||
|
base.Shutdown();
|
||||||
|
Cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnStationInit(StationInitializedEvent ev)
|
||||||
|
{
|
||||||
|
EnsureComp<StationBankAccountComponent>(ev.Station);
|
||||||
|
EnsureComp<StationCargoOrderDatabaseComponent>(ev.Station);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(float frameTime)
|
public override void Update(float frameTime)
|
||||||
|
|||||||
@@ -187,17 +187,26 @@ public sealed class NukeopsRuleSystem : GameRuleSystem
|
|||||||
// TODO: Make this a prototype
|
// TODO: Make this a prototype
|
||||||
var map = "/Maps/infiltrator.yml";
|
var map = "/Maps/infiltrator.yml";
|
||||||
|
|
||||||
var aabbs = _stationSystem.Stations.SelectMany(x =>
|
var center = new Vector2();
|
||||||
Comp<StationDataComponent>(x).Grids.Select(x => _mapManager.GetGridComp(x).Grid.WorldAABB)).ToArray();
|
var minRadius = 0f;
|
||||||
var aabb = aabbs[0];
|
Box2? aabb = null;
|
||||||
for (int i = 1; i < aabbs.Length; i++)
|
|
||||||
|
foreach (var uid in _stationSystem.Stations)
|
||||||
{
|
{
|
||||||
aabb.Union(aabbs[i]);
|
var grid = Comp<IMapGridComponent>(uid).Grid;
|
||||||
|
|
||||||
|
aabb = aabb?.Union(grid.WorldAABB) ?? grid.WorldAABB;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aabb != null)
|
||||||
|
{
|
||||||
|
center = aabb.Value.Center;
|
||||||
|
minRadius = MathF.Max(aabb.Value.Width, aabb.Value.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
var (_, gridId) = _mapLoader.LoadBlueprint(GameTicker.DefaultMap, map, new MapLoadOptions
|
var (_, gridId) = _mapLoader.LoadBlueprint(GameTicker.DefaultMap, map, new MapLoadOptions
|
||||||
{
|
{
|
||||||
Offset = aabb.Center + MathF.Max(aabb.Height / 2f, aabb.Width / 2f) * 2.5f
|
Offset = center + MathF.Max(minRadius, minRadius) + 1000f,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!gridId.HasValue)
|
if (!gridId.HasValue)
|
||||||
|
|||||||
@@ -42,6 +42,9 @@ namespace Content.Server.Gravity.EntitySystems
|
|||||||
|
|
||||||
if (_mapManager.TryGetGrid(xform.GridUid, out var grid))
|
if (_mapManager.TryGetGrid(xform.GridUid, out var grid))
|
||||||
{
|
{
|
||||||
|
var alerts = _alerts.GetOrNew(xform.GridUid.Value);
|
||||||
|
alerts.Add(status);
|
||||||
|
|
||||||
if (EntityManager.GetComponent<GravityComponent>(grid.GridEntityId).Enabled)
|
if (EntityManager.GetComponent<GravityComponent>(grid.GridEntityId).Enabled)
|
||||||
{
|
{
|
||||||
RemoveWeightless(status.Owner);
|
RemoveWeightless(status.Owner);
|
||||||
@@ -51,6 +54,10 @@ namespace Content.Server.Gravity.EntitySystems
|
|||||||
AddWeightless(status.Owner);
|
AddWeightless(status.Owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddWeightless(status.Owner);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveAlert(AlertsComponent status)
|
public void RemoveAlert(AlertsComponent status)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Content.Server.Cargo.Components;
|
||||||
using Content.Server.Shuttles.Components;
|
using Content.Server.Shuttles.Components;
|
||||||
using Content.Server.Shuttles.Systems;
|
using Content.Server.Shuttles.Systems;
|
||||||
using Content.Shared.Vehicle.Components;
|
using Content.Shared.Vehicle.Components;
|
||||||
@@ -61,9 +62,18 @@ namespace Content.Server.Physics.Controllers
|
|||||||
var newPilots = new Dictionary<ShuttleComponent, List<(PilotComponent, IMoverComponent)>>();
|
var newPilots = new Dictionary<ShuttleComponent, List<(PilotComponent, IMoverComponent)>>();
|
||||||
|
|
||||||
// We just mark off their movement and the shuttle itself does its own movement
|
// We just mark off their movement and the shuttle itself does its own movement
|
||||||
foreach (var (pilot, mover, xform) in EntityManager.EntityQuery<PilotComponent, SharedPlayerInputMoverComponent, TransformComponent>())
|
foreach (var (pilot, mover) in EntityManager.EntityQuery<PilotComponent, SharedPlayerInputMoverComponent>())
|
||||||
{
|
{
|
||||||
if (pilot.Console == null) continue;
|
var consoleEnt = pilot.Console?.Owner;
|
||||||
|
|
||||||
|
// TODO: This is terrible. Just make a new mover and also make it remote piloting + device networks
|
||||||
|
if (TryComp<CargoPilotConsoleComponent>(consoleEnt, out var cargoConsole))
|
||||||
|
{
|
||||||
|
consoleEnt = cargoConsole.Entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TryComp<TransformComponent>(consoleEnt, out var xform)) continue;
|
||||||
|
|
||||||
_excludedMobs.Add(mover.Owner);
|
_excludedMobs.Add(mover.Owner);
|
||||||
|
|
||||||
var gridId = xform.GridUid;
|
var gridId = xform.GridUid;
|
||||||
|
|||||||
12
Content.Server/Shuttles/Events/ConsoleShuttleEvent.cs
Normal file
12
Content.Server/Shuttles/Events/ConsoleShuttleEvent.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using Content.Server.Shuttles.Components;
|
||||||
|
|
||||||
|
namespace Content.Server.Shuttles.Events;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised on a <see cref="ShuttleConsoleComponent"/> when it's trying to get its shuttle console to pilot.
|
||||||
|
/// </summary>
|
||||||
|
[ByRefEvent]
|
||||||
|
public struct ConsoleShuttleEvent
|
||||||
|
{
|
||||||
|
public EntityUid? Console;
|
||||||
|
}
|
||||||
@@ -23,7 +23,16 @@ public sealed class RadarConsoleSystem : SharedRadarConsoleSystem
|
|||||||
|
|
||||||
protected override void UpdateState(RadarConsoleComponent component)
|
protected override void UpdateState(RadarConsoleComponent component)
|
||||||
{
|
{
|
||||||
var radarState = new RadarConsoleBoundInterfaceState(component.MaxRange, component.Owner, new List<DockingInterfaceState>());
|
var xform = Transform(component.Owner);
|
||||||
|
|
||||||
|
var onGrid = xform.ParentUid == xform.GridUid;
|
||||||
|
|
||||||
|
var radarState = new RadarConsoleBoundInterfaceState(
|
||||||
|
component.MaxRange,
|
||||||
|
onGrid ? xform.Coordinates : null,
|
||||||
|
onGrid ? xform.LocalRotation : null,
|
||||||
|
new List<DockingInterfaceState>());
|
||||||
|
|
||||||
_uiSystem.GetUiOrNull(component.Owner, RadarConsoleUiKey.Key)?.SetState(radarState);
|
_uiSystem.GetUiOrNull(component.Owner, RadarConsoleUiKey.Key)?.SetState(radarState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Content.Server.Cargo.Components;
|
||||||
using Content.Server.Power.Components;
|
using Content.Server.Power.Components;
|
||||||
using Content.Server.Power.EntitySystems;
|
using Content.Server.Power.EntitySystems;
|
||||||
using Content.Server.Shuttles.Components;
|
using Content.Server.Shuttles.Components;
|
||||||
@@ -5,6 +6,7 @@ using Content.Server.Shuttles.Events;
|
|||||||
using Content.Server.UserInterface;
|
using Content.Server.UserInterface;
|
||||||
using Content.Shared.ActionBlocker;
|
using Content.Shared.ActionBlocker;
|
||||||
using Content.Shared.Alert;
|
using Content.Shared.Alert;
|
||||||
|
using Content.Shared.Light;
|
||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
using Content.Shared.Shuttles.BUIStates;
|
using Content.Shared.Shuttles.BUIStates;
|
||||||
using Content.Shared.Shuttles.Components;
|
using Content.Shared.Shuttles.Components;
|
||||||
@@ -136,15 +138,29 @@ namespace Content.Server.Shuttles.Systems
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void OnModeRequest(EntityUid uid, ShuttleConsoleComponent component, ShuttleModeRequestMessage args)
|
private void OnModeRequest(EntityUid uid, ShuttleConsoleComponent component, ShuttleModeRequestMessage args)
|
||||||
{
|
{
|
||||||
|
var consoleUid = uid;
|
||||||
|
|
||||||
|
if (TryComp<CargoPilotConsoleComponent>(uid, out var cargoPilot) && cargoPilot.Entity != null)
|
||||||
|
{
|
||||||
|
consoleUid = cargoPilot.Entity.Value;
|
||||||
|
}
|
||||||
|
|
||||||
if (args.Session.AttachedEntity is not { } player ||
|
if (args.Session.AttachedEntity is not { } player ||
|
||||||
!TryComp<PilotComponent>(player, out var pilot) ||
|
!TryComp<PilotComponent>(player, out var pilot) ||
|
||||||
!TryComp<TransformComponent>(player, out var xform) ||
|
!TryComp<ShuttleConsoleComponent>(consoleUid, out var console) ||
|
||||||
pilot.Console is not ShuttleConsoleComponent console) return;
|
!TryComp<TransformComponent>(consoleUid, out var consoleXform)) return;
|
||||||
|
|
||||||
if (!console.SubscribedPilots.Contains(pilot) ||
|
// Can't check console pilots as it may be remotely piloted!
|
||||||
!TryComp<ShuttleComponent>(xform.GridUid, out var shuttle)) return;
|
if (!component.SubscribedPilots.Contains(pilot) ||
|
||||||
|
!TryComp<ShuttleComponent>(consoleXform.GridUid, out var shuttle)) return;
|
||||||
|
|
||||||
SetShuttleMode(args.Mode, console, shuttle);
|
SetShuttleMode(args.Mode, console, shuttle);
|
||||||
|
UpdateState(component);
|
||||||
|
|
||||||
|
if (uid != consoleUid)
|
||||||
|
{
|
||||||
|
UpdateState(console);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -159,7 +175,6 @@ namespace Content.Server.Shuttles.Systems
|
|||||||
!consoleXform.Anchored ||
|
!consoleXform.Anchored ||
|
||||||
consoleXform.GridID != Transform(shuttleComponent.Owner).GridID)
|
consoleXform.GridID != Transform(shuttleComponent.Owner).GridID)
|
||||||
{
|
{
|
||||||
UpdateState(consoleComponent);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,8 +189,6 @@ namespace Content.Server.Shuttles.Systems
|
|||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateState(consoleComponent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -205,10 +218,21 @@ namespace Content.Server.Shuttles.Systems
|
|||||||
|
|
||||||
private void UpdateState(ShuttleConsoleComponent component, List<DockingInterfaceState>? docks = null)
|
private void UpdateState(ShuttleConsoleComponent component, List<DockingInterfaceState>? docks = null)
|
||||||
{
|
{
|
||||||
TryComp<RadarConsoleComponent>(component.Owner, out var radar);
|
EntityUid? entity = component.Owner;
|
||||||
|
|
||||||
|
var getShuttleEv = new ConsoleShuttleEvent
|
||||||
|
{
|
||||||
|
Console = entity,
|
||||||
|
};
|
||||||
|
|
||||||
|
RaiseLocalEvent(entity.Value, ref getShuttleEv, false);
|
||||||
|
entity = getShuttleEv.Console;
|
||||||
|
|
||||||
|
TryComp<TransformComponent>(entity, out var consoleXform);
|
||||||
|
TryComp<RadarConsoleComponent>(entity, out var radar);
|
||||||
var range = radar?.MaxRange ?? 0f;
|
var range = radar?.MaxRange ?? 0f;
|
||||||
|
|
||||||
TryComp<ShuttleComponent>(Transform(component.Owner).GridUid, out var shuttle);
|
TryComp<ShuttleComponent>(consoleXform?.GridUid, out var shuttle);
|
||||||
var mode = shuttle?.Mode ?? ShuttleMode.Cruise;
|
var mode = shuttle?.Mode ?? ShuttleMode.Cruise;
|
||||||
|
|
||||||
docks ??= GetAllDocks();
|
docks ??= GetAllDocks();
|
||||||
@@ -217,7 +241,8 @@ namespace Content.Server.Shuttles.Systems
|
|||||||
?.SetState(new ShuttleConsoleBoundInterfaceState(
|
?.SetState(new ShuttleConsoleBoundInterfaceState(
|
||||||
mode,
|
mode,
|
||||||
range,
|
range,
|
||||||
component.Owner,
|
consoleXform?.Coordinates,
|
||||||
|
consoleXform?.LocalRotation,
|
||||||
docks));
|
docks));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
22
Content.Shared/Cargo/BUI/CargoConsoleInterfaceState.cs
Normal file
22
Content.Shared/Cargo/BUI/CargoConsoleInterfaceState.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Cargo.BUI;
|
||||||
|
|
||||||
|
[NetSerializable, Serializable]
|
||||||
|
public sealed class CargoConsoleInterfaceState : BoundUserInterfaceState
|
||||||
|
{
|
||||||
|
public string Name;
|
||||||
|
public int Count;
|
||||||
|
public int Capacity;
|
||||||
|
public int Balance;
|
||||||
|
public List<CargoOrderData> Orders;
|
||||||
|
|
||||||
|
public CargoConsoleInterfaceState(string name, int count, int capacity, int balance, List<CargoOrderData> orders)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
Count = count;
|
||||||
|
Capacity = capacity;
|
||||||
|
Balance = balance;
|
||||||
|
Orders = orders;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Cargo.BUI;
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class CargoShuttleConsoleBoundUserInterfaceState : BoundUserInterfaceState
|
||||||
|
{
|
||||||
|
public string AccountName;
|
||||||
|
public string ShuttleName;
|
||||||
|
|
||||||
|
// Unfortunately shuttles have essentially 3 states so can't just use a nullable var for it:
|
||||||
|
// 1. stowed
|
||||||
|
// 2. called but not recallable
|
||||||
|
// 3. called and recallable
|
||||||
|
// The reason we have 2 is so people don't spam the recall button in the UI.
|
||||||
|
public bool CanRecall;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When the shuttle is expected to be usable.
|
||||||
|
/// </summary>
|
||||||
|
public TimeSpan? ShuttleETA;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List of orders expected on the delivery.
|
||||||
|
/// </summary>
|
||||||
|
public List<CargoOrderData> Orders;
|
||||||
|
|
||||||
|
public CargoShuttleConsoleBoundUserInterfaceState(
|
||||||
|
string accountName,
|
||||||
|
string shuttleName,
|
||||||
|
bool canRecall,
|
||||||
|
TimeSpan? shuttleETA,
|
||||||
|
List<CargoOrderData> orders)
|
||||||
|
{
|
||||||
|
AccountName = accountName;
|
||||||
|
ShuttleName = shuttleName;
|
||||||
|
CanRecall = canRecall;
|
||||||
|
ShuttleETA = shuttleETA;
|
||||||
|
Orders = orders;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,18 +12,16 @@ namespace Content.Shared.Cargo
|
|||||||
public string Reason;
|
public string Reason;
|
||||||
public string ProductId;
|
public string ProductId;
|
||||||
public int Amount;
|
public int Amount;
|
||||||
public int PayingAccountId;
|
|
||||||
public bool Approved;
|
public bool Approved;
|
||||||
public string Approver = string.Empty;
|
public string Approver = string.Empty;
|
||||||
|
|
||||||
public CargoOrderData(int orderNumber, string requester, string reason, string productId, int amount, int payingAccountId)
|
public CargoOrderData(int orderNumber, string requester, string reason, string productId, int amount)
|
||||||
{
|
{
|
||||||
OrderNumber = orderNumber;
|
OrderNumber = orderNumber;
|
||||||
Requester = requester;
|
Requester = requester;
|
||||||
Reason = reason;
|
Reason = reason;
|
||||||
ProductId = productId;
|
ProductId = productId;
|
||||||
Amount = amount;
|
Amount = amount;
|
||||||
PayingAccountId = payingAccountId;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
31
Content.Shared/Cargo/Components/CargoShuttleComponent.cs
Normal file
31
Content.Shared/Cargo/Components/CargoShuttleComponent.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using Robust.Shared.Map;
|
||||||
|
|
||||||
|
namespace Content.Shared.Cargo.Components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Present on cargo shuttles to provide metadata such as preventing spam calling.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent, Access(typeof(SharedCargoSystem))]
|
||||||
|
public sealed class CargoShuttleComponent : Component
|
||||||
|
{
|
||||||
|
[ViewVariables(VVAccess.ReadWrite), DataField("nextCall")]
|
||||||
|
public TimeSpan? NextCall;
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite), DataField("cooldown")]
|
||||||
|
public float Cooldown = 45f;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
public bool CanRecall;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The shuttle's assigned coordinates on the cargo map.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables]
|
||||||
|
public EntityCoordinates Coordinates;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The assigned station for this cargo shuttle.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables, DataField("station")]
|
||||||
|
public EntityUid? Station;
|
||||||
|
}
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
using Robust.Shared.Prototypes;
|
|
||||||
using Robust.Shared.Serialization;
|
|
||||||
|
|
||||||
namespace Content.Shared.Cargo.Components
|
|
||||||
{
|
|
||||||
[Virtual]
|
|
||||||
public class SharedCargoConsoleComponent : Component
|
|
||||||
{
|
|
||||||
[Dependency] protected readonly IPrototypeManager PrototypeManager = default!;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sends away or requests shuttle
|
|
||||||
/// </summary>
|
|
||||||
[Serializable, NetSerializable]
|
|
||||||
public sealed class CargoConsoleShuttleMessage : BoundUserInterfaceMessage
|
|
||||||
{
|
|
||||||
public CargoConsoleShuttleMessage()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Add order to database.
|
|
||||||
/// </summary>
|
|
||||||
[Serializable, NetSerializable]
|
|
||||||
public sealed class CargoConsoleAddOrderMessage : BoundUserInterfaceMessage
|
|
||||||
{
|
|
||||||
public string Requester;
|
|
||||||
public string Reason;
|
|
||||||
public string ProductId;
|
|
||||||
public int Amount;
|
|
||||||
|
|
||||||
public CargoConsoleAddOrderMessage(string requester, string reason, string productId, int amount)
|
|
||||||
{
|
|
||||||
Requester = requester;
|
|
||||||
Reason = reason;
|
|
||||||
ProductId = productId;
|
|
||||||
Amount = amount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Remove order from database.
|
|
||||||
/// </summary>
|
|
||||||
[Serializable, NetSerializable]
|
|
||||||
public sealed class CargoConsoleRemoveOrderMessage : BoundUserInterfaceMessage
|
|
||||||
{
|
|
||||||
public int OrderNumber;
|
|
||||||
|
|
||||||
public CargoConsoleRemoveOrderMessage(int orderNumber)
|
|
||||||
{
|
|
||||||
OrderNumber = orderNumber;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set order in database as approved.
|
|
||||||
/// </summary>
|
|
||||||
[Serializable, NetSerializable]
|
|
||||||
public sealed class CargoConsoleApproveOrderMessage : BoundUserInterfaceMessage
|
|
||||||
{
|
|
||||||
public int OrderNumber;
|
|
||||||
|
|
||||||
public CargoConsoleApproveOrderMessage(int orderNumber)
|
|
||||||
{
|
|
||||||
OrderNumber = orderNumber;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[NetSerializable, Serializable]
|
|
||||||
public enum CargoConsoleUiKey
|
|
||||||
{
|
|
||||||
Key
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[NetSerializable, Serializable]
|
|
||||||
public sealed class CargoConsoleInterfaceState : BoundUserInterfaceState
|
|
||||||
{
|
|
||||||
public readonly bool RequestOnly;
|
|
||||||
public readonly int BankId;
|
|
||||||
public readonly string BankName;
|
|
||||||
public readonly int BankBalance;
|
|
||||||
public readonly (int CurrentCapacity, int MaxCapacity) ShuttleCapacity;
|
|
||||||
|
|
||||||
public CargoConsoleInterfaceState(bool requestOnly, int bankId, string bankName, int bankBalance, (int CurrentCapacity, int MaxCapacity) shuttleCapacity)
|
|
||||||
{
|
|
||||||
RequestOnly = requestOnly;
|
|
||||||
BankId = bankId;
|
|
||||||
BankName = bankName;
|
|
||||||
BankBalance = bankBalance;
|
|
||||||
ShuttleCapacity = shuttleCapacity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
using Robust.Shared.GameStates;
|
|
||||||
using Robust.Shared.Serialization;
|
|
||||||
|
|
||||||
namespace Content.Shared.Cargo.Components
|
|
||||||
{
|
|
||||||
[NetworkedComponent()]
|
|
||||||
public abstract class SharedCargoOrderDatabaseComponent : Component
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[NetSerializable, Serializable]
|
|
||||||
public sealed class CargoOrderDatabaseState : ComponentState
|
|
||||||
{
|
|
||||||
public readonly List<CargoOrderData>? Orders;
|
|
||||||
|
|
||||||
public CargoOrderDatabaseState(List<CargoOrderData>? orders)
|
|
||||||
{
|
|
||||||
Orders = orders;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
12
Content.Shared/Cargo/Events/CargoCallShuttleMessage.cs
Normal file
12
Content.Shared/Cargo/Events/CargoCallShuttleMessage.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Cargo.Events;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised on a cargo console requesting the cargo shuttle.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class CargoCallShuttleMessage : BoundUserInterfaceMessage
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
23
Content.Shared/Cargo/Events/CargoConsoleAddOrderMessage.cs
Normal file
23
Content.Shared/Cargo/Events/CargoConsoleAddOrderMessage.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Cargo.Events;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add order to database.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class CargoConsoleAddOrderMessage : BoundUserInterfaceMessage
|
||||||
|
{
|
||||||
|
public string Requester;
|
||||||
|
public string Reason;
|
||||||
|
public string ProductId;
|
||||||
|
public int Amount;
|
||||||
|
|
||||||
|
public CargoConsoleAddOrderMessage(string requester, string reason, string productId, int amount)
|
||||||
|
{
|
||||||
|
Requester = requester;
|
||||||
|
Reason = reason;
|
||||||
|
ProductId = productId;
|
||||||
|
Amount = amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Cargo.Events;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set order in database as approved.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class CargoConsoleApproveOrderMessage : BoundUserInterfaceMessage
|
||||||
|
{
|
||||||
|
public int OrderNumber;
|
||||||
|
|
||||||
|
public CargoConsoleApproveOrderMessage(int orderNumber)
|
||||||
|
{
|
||||||
|
OrderNumber = orderNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Cargo.Events;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove order from database.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class CargoConsoleRemoveOrderMessage : BoundUserInterfaceMessage
|
||||||
|
{
|
||||||
|
public int OrderNumber;
|
||||||
|
|
||||||
|
public CargoConsoleRemoveOrderMessage(int orderNumber)
|
||||||
|
{
|
||||||
|
OrderNumber = orderNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
12
Content.Shared/Cargo/Events/CargoRecallShuttleMessage.cs
Normal file
12
Content.Shared/Cargo/Events/CargoRecallShuttleMessage.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Cargo.Events;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised on a client request cargo shuttle recall
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class CargoRecallShuttleMessage : BoundUserInterfaceMessage
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ using Robust.Shared.Serialization;
|
|||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Shared.Cargo
|
namespace Content.Shared.Cargo.Prototypes
|
||||||
{
|
{
|
||||||
[NetSerializable, Serializable, Prototype("cargoProduct")]
|
[NetSerializable, Serializable, Prototype("cargoProduct")]
|
||||||
public sealed class CargoProductPrototype : IPrototype
|
public sealed class CargoProductPrototype : IPrototype
|
||||||
@@ -13,7 +13,7 @@ namespace Content.Shared.Cargo
|
|||||||
[DataField("description")] private string _description = string.Empty;
|
[DataField("description")] private string _description = string.Empty;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
[IdDataFieldAttribute]
|
[IdDataField]
|
||||||
public string ID { get; } = default!;
|
public string ID { get; } = default!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
20
Content.Shared/Cargo/Prototypes/CargoShuttlePrototype.cs
Normal file
20
Content.Shared/Cargo/Prototypes/CargoShuttlePrototype.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using Content.Shared.Dataset;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
|
namespace Content.Shared.Cargo.Prototypes;
|
||||||
|
|
||||||
|
[Prototype("cargoShuttle")]
|
||||||
|
public sealed class CargoShuttlePrototype : IPrototype
|
||||||
|
{
|
||||||
|
[ViewVariables]
|
||||||
|
[IdDataField]
|
||||||
|
public string ID { get; } = default!;
|
||||||
|
|
||||||
|
[ViewVariables, DataField("path")]
|
||||||
|
public ResourcePath Path = default!;
|
||||||
|
|
||||||
|
[ViewVariables, DataField("nameDataset", customTypeSerializer:typeof(PrototypeIdSerializer<DatasetPrototype>))]
|
||||||
|
public string NameDataset = "CargoShuttleNames";
|
||||||
|
}
|
||||||
@@ -2,6 +2,14 @@ using Robust.Shared.Serialization;
|
|||||||
|
|
||||||
namespace Content.Shared.Cargo;
|
namespace Content.Shared.Cargo;
|
||||||
|
|
||||||
|
[NetSerializable, Serializable]
|
||||||
|
public enum CargoConsoleUiKey : byte
|
||||||
|
{
|
||||||
|
Orders,
|
||||||
|
Shuttle,
|
||||||
|
Telepad
|
||||||
|
}
|
||||||
|
|
||||||
public abstract class SharedCargoSystem : EntitySystem {}
|
public abstract class SharedCargoSystem : EntitySystem {}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
|
|||||||
@@ -8,16 +8,28 @@ namespace Content.Shared.Shuttles.BUIStates;
|
|||||||
public class RadarConsoleBoundInterfaceState : BoundUserInterfaceState
|
public class RadarConsoleBoundInterfaceState : BoundUserInterfaceState
|
||||||
{
|
{
|
||||||
public readonly float MaxRange;
|
public readonly float MaxRange;
|
||||||
public readonly EntityUid? Entity;
|
|
||||||
|
/// <summary>
|
||||||
|
/// The relevant coordinates to base the radar around.
|
||||||
|
/// </summary>
|
||||||
|
public EntityCoordinates? Coordinates;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The relevant rotation to rotate the angle around.
|
||||||
|
/// </summary>
|
||||||
|
public Angle? Angle;
|
||||||
|
|
||||||
public readonly List<DockingInterfaceState> Docks;
|
public readonly List<DockingInterfaceState> Docks;
|
||||||
|
|
||||||
public RadarConsoleBoundInterfaceState(
|
public RadarConsoleBoundInterfaceState(
|
||||||
float maxRange,
|
float maxRange,
|
||||||
EntityUid? entity,
|
EntityCoordinates? coordinates,
|
||||||
|
Angle? angle,
|
||||||
List<DockingInterfaceState> docks)
|
List<DockingInterfaceState> docks)
|
||||||
{
|
{
|
||||||
MaxRange = maxRange;
|
MaxRange = maxRange;
|
||||||
Entity = entity;
|
Coordinates = coordinates;
|
||||||
|
Angle = angle;
|
||||||
Docks = docks;
|
Docks = docks;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,8 +12,9 @@ public sealed class ShuttleConsoleBoundInterfaceState : RadarConsoleBoundInterfa
|
|||||||
public ShuttleConsoleBoundInterfaceState(
|
public ShuttleConsoleBoundInterfaceState(
|
||||||
ShuttleMode mode,
|
ShuttleMode mode,
|
||||||
float maxRange,
|
float maxRange,
|
||||||
EntityUid? entity,
|
EntityCoordinates? coordinates,
|
||||||
List<DockingInterfaceState> docks) : base(maxRange, entity, docks)
|
Angle? angle,
|
||||||
|
List<DockingInterfaceState> docks) : base(maxRange, coordinates, angle, docks)
|
||||||
{
|
{
|
||||||
Mode = mode;
|
Mode = mode;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,5 +17,5 @@ public sealed class RadarConsoleComponent : Component
|
|||||||
}
|
}
|
||||||
|
|
||||||
[ViewVariables, DataField("maxRange")]
|
[ViewVariables, DataField("maxRange")]
|
||||||
public float MaxRange = 120f;
|
public float MaxRange = 256f;
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
Resources/Audio/Effects/Cargo/buzz_sigh.ogg
Normal file
BIN
Resources/Audio/Effects/Cargo/buzz_sigh.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Effects/Cargo/buzz_two.ogg
Normal file
BIN
Resources/Audio/Effects/Cargo/buzz_two.ogg
Normal file
Binary file not shown.
7
Resources/Audio/Effects/Cargo/licenses.txt
Normal file
7
Resources/Audio/Effects/Cargo/licenses.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
The following sounds are taken from TGstation github (licensed under CC by 3.0):
|
||||||
|
|
||||||
|
buzz_sigh.ogg from https://github.com/tgstation/tgstation/tree/d6f15fb717e7c047f8befefabb4b7735b3c39a84/sound
|
||||||
|
|
||||||
|
buzz_two.ogg from https://github.com/tgstation/tgstation/tree/d6f15fb717e7c047f8befefabb4b7735b3c39a84/sound
|
||||||
|
|
||||||
|
ping.ogg from https://github.com/tgstation/tgstation/tree/d6f15fb717e7c047f8befefabb4b7735b3c39a84/sound
|
||||||
BIN
Resources/Audio/Effects/Cargo/ping.ogg
Normal file
BIN
Resources/Audio/Effects/Cargo/ping.ogg
Normal file
Binary file not shown.
Binary file not shown.
43
Resources/Locale/en-US/cargo/cargo-console-component.ftl
Normal file
43
Resources/Locale/en-US/cargo/cargo-console-component.ftl
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
## UI
|
||||||
|
cargo-console-menu-title = Cargo request console
|
||||||
|
cargo-console-menu-account-name-label = Account name:{" "}
|
||||||
|
cargo-console-menu-account-name-none-text = None
|
||||||
|
cargo-console-menu-shuttle-name-label = Shuttle name:{" "}
|
||||||
|
cargo-console-menu-shuttle-name-none-text = None
|
||||||
|
cargo-console-menu-points-label = Points:{" "}
|
||||||
|
cargo-console-menu-shuttle-status-label = Shuttle status:{" "}
|
||||||
|
cargo-console-menu-shuttle-status-away-text = Away
|
||||||
|
cargo-console-menu-order-capacity-label = Order capacity:{" "}
|
||||||
|
cargo-console-menu-call-shuttle-button = Activate telepad
|
||||||
|
cargo-console-menu-permissions-button = Permissions
|
||||||
|
cargo-console-menu-categories-label = Categories:{" "}
|
||||||
|
cargo-console-menu-search-bar-placeholder = Search
|
||||||
|
cargo-console-menu-requests-label = Requests
|
||||||
|
cargo-console-menu-orders-label = Orders
|
||||||
|
cargo-console-menu-order-reason-description = Reasons: {$reason}
|
||||||
|
cargo-console-menu-populate-categories-all-text = All
|
||||||
|
cargo-console-menu-populate-orders-cargo-order-row-product-name-text = {$productName} (x{$orderAmount}) by {$orderRequester}
|
||||||
|
cargo-console-menu-cargo-order-row-approve-button = Approve
|
||||||
|
cargo-console-menu-cargo-order-row-cancel-button = Cancel
|
||||||
|
|
||||||
|
# Orders
|
||||||
|
cargo-console-order-not-allowed = Access not allowed
|
||||||
|
cargo-console-station-not-found = No available station
|
||||||
|
cargo-console-invalid-product = Invalid product ID
|
||||||
|
cargo-console-too-many = Too many approved orders
|
||||||
|
cargo-console-snip-snip = Order trimmed to capacity
|
||||||
|
cargo-console-insufficient-funds = Insufficient funds (require {$cost})
|
||||||
|
|
||||||
|
cargo-console-paper-print-name = Order #{$orderNumber}
|
||||||
|
cargo-console-paper-print-text =
|
||||||
|
Order #{$orderNumber}
|
||||||
|
Requested by: {$requester}
|
||||||
|
Reason: {$reason}
|
||||||
|
Approved by: {$approver}
|
||||||
|
|
||||||
|
# Cargo shuttle console
|
||||||
|
cargo-shuttle-console-menu-title = Cargo shuttle console
|
||||||
|
cargo-shuttle-console-station-unknown = Unknown
|
||||||
|
cargo-shuttle-console-shuttle-not-found = Not found
|
||||||
|
cargo-shuttle-console-proximity = Too close to nearby objects
|
||||||
|
cargo-shuttle-console-organics = Detected organic lifeforms on the shuttle
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
## UI
|
|
||||||
cargo-console-menu-request-only-title = Cargo Request Console
|
|
||||||
cargo-console-menu-title = Cargo Shuttle Console
|
|
||||||
cargo-console-menu-account-name-label = Account Name:{" "}
|
|
||||||
cargo-console-menu-account-name-none-text = None
|
|
||||||
cargo-console-menu-points-label = Points:{" "}
|
|
||||||
cargo-console-menu-shuttle-status-label = Shuttle Status:{" "}
|
|
||||||
cargo-console-menu-shuttle-status-away-text = Away
|
|
||||||
cargo-console-menu-order-capacity-label = Order Capacity:{" "}
|
|
||||||
cargo-console-menu-call-shuttle-button = Activate Telepad
|
|
||||||
cargo-console-menu-permissions-button = Permissions
|
|
||||||
cargo-console-menu-categories-label = Categories:{" "}
|
|
||||||
cargo-console-menu-search-bar-placeholder = Search
|
|
||||||
cargo-console-menu-requests-label = Requests
|
|
||||||
cargo-console-menu-orders-label = Orders
|
|
||||||
cargo-console-menu-order-reason-description = Reasons: {$reason}
|
|
||||||
cargo-console-menu-populate-categories-all-text = All
|
|
||||||
cargo-console-menu-populate-orders-cargo-order-row-product-name-text = {$productName} (x{$orderAmount}) by {$orderRequester}
|
|
||||||
cargo-console-menu-cargo-order-row-approve-button = Approve
|
|
||||||
cargo-console-menu-cargo-order-row-cancel-button = Cancel
|
|
||||||
|
|
||||||
cargo-console-paper-print-name = Order #{$orderNumber}
|
|
||||||
cargo-console-paper-print-text =
|
|
||||||
Order #{$orderNumber}
|
|
||||||
Requested by: {$requester}
|
|
||||||
Reason: {$reason}
|
|
||||||
Approved by: {$approver}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
galactic-bank-selection-menu-title = Galactic Bank Selection
|
|
||||||
@@ -2603,7 +2603,7 @@ entities:
|
|||||||
parent: 179
|
parent: 179
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 326
|
- uid: 326
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: 0.5,-5.5
|
- pos: 0.5,-5.5
|
||||||
parent: 179
|
parent: 179
|
||||||
@@ -2613,7 +2613,7 @@ entities:
|
|||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- uid: 327
|
- uid: 327
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: 0.5,0.5
|
- pos: 0.5,0.5
|
||||||
parent: 179
|
parent: 179
|
||||||
|
|||||||
@@ -16554,7 +16554,7 @@ entities:
|
|||||||
parent: 30
|
parent: 30
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 1172
|
- uid: 1172
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: -1.5707963267948966 rad
|
- rot: -1.5707963267948966 rad
|
||||||
pos: -21.5,15.5
|
pos: -21.5,15.5
|
||||||
@@ -16678,7 +16678,7 @@ entities:
|
|||||||
parent: 30
|
parent: 30
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 1184
|
- uid: 1184
|
||||||
type: cargoTelepad
|
type: CargoTelepad
|
||||||
components:
|
components:
|
||||||
- pos: -21.5,16.5
|
- pos: -21.5,16.5
|
||||||
parent: 30
|
parent: 30
|
||||||
@@ -43132,14 +43132,11 @@ entities:
|
|||||||
parent: 30
|
parent: 30
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 4712
|
- uid: 4712
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: -35.5,17.5
|
- pos: -35.5,17.5
|
||||||
parent: 30
|
parent: 30
|
||||||
type: Transform
|
type: Transform
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- containers:
|
- containers:
|
||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
@@ -49808,14 +49805,11 @@ entities:
|
|||||||
parent: 30
|
parent: 30
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 5603
|
- uid: 5603
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: -27.5,17.5
|
- pos: -27.5,17.5
|
||||||
parent: 30
|
parent: 30
|
||||||
type: Transform
|
type: Transform
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- containers:
|
- containers:
|
||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
@@ -51445,7 +51439,7 @@ entities:
|
|||||||
parent: 30
|
parent: 30
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 5833
|
- uid: 5833
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: -28.5,21.5
|
- pos: -28.5,21.5
|
||||||
parent: 30
|
parent: 30
|
||||||
|
|||||||
@@ -119308,14 +119308,11 @@ entities:
|
|||||||
parent: 60
|
parent: 60
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 13084
|
- uid: 13084
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: 43.5,10.5
|
- pos: 43.5,10.5
|
||||||
parent: 60
|
parent: 60
|
||||||
type: Transform
|
type: Transform
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- containers:
|
- containers:
|
||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
@@ -119382,7 +119379,7 @@ entities:
|
|||||||
parent: 60
|
parent: 60
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 13095
|
- uid: 13095
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: 1.5707963267948966 rad
|
- rot: 1.5707963267948966 rad
|
||||||
pos: 43.5,14.5
|
pos: 43.5,14.5
|
||||||
@@ -120078,15 +120075,12 @@ entities:
|
|||||||
uid: 13173
|
uid: 13173
|
||||||
type: SignalReceiver
|
type: SignalReceiver
|
||||||
- uid: 13172
|
- uid: 13172
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: -1.5707963267948966 rad
|
- rot: -1.5707963267948966 rad
|
||||||
pos: 56.5,13.5
|
pos: 56.5,13.5
|
||||||
parent: 60
|
parent: 60
|
||||||
type: Transform
|
type: Transform
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- containers:
|
- containers:
|
||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
@@ -153756,7 +153750,7 @@ entities:
|
|||||||
- color: '#0335FCFF'
|
- color: '#0335FCFF'
|
||||||
type: AtmosPipeColor
|
type: AtmosPipeColor
|
||||||
- uid: 17876
|
- uid: 17876
|
||||||
type: cargoTelepad
|
type: CargoTelepad
|
||||||
components:
|
components:
|
||||||
- pos: 50.5,11.5
|
- pos: 50.5,11.5
|
||||||
parent: 60
|
parent: 60
|
||||||
@@ -162231,7 +162225,7 @@ entities:
|
|||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- uid: 19004
|
- uid: 19004
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: 49.5,11.5
|
- pos: 49.5,11.5
|
||||||
parent: 60
|
parent: 60
|
||||||
@@ -162509,15 +162503,12 @@ entities:
|
|||||||
parent: 60
|
parent: 60
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 19043
|
- uid: 19043
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: -1.5707963267948966 rad
|
- rot: -1.5707963267948966 rad
|
||||||
pos: 41.5,3.5
|
pos: 41.5,3.5
|
||||||
parent: 60
|
parent: 60
|
||||||
type: Transform
|
type: Transform
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- containers:
|
- containers:
|
||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
|
|||||||
@@ -44158,7 +44158,7 @@ entities:
|
|||||||
uid: 9045
|
uid: 9045
|
||||||
type: SignalReceiver
|
type: SignalReceiver
|
||||||
- uid: 3558
|
- uid: 3558
|
||||||
type: cargoTelepad
|
type: CargoTelepad
|
||||||
components:
|
components:
|
||||||
- pos: -32.5,-13.5
|
- pos: -32.5,-13.5
|
||||||
parent: 106
|
parent: 106
|
||||||
@@ -44235,7 +44235,7 @@ entities:
|
|||||||
parent: 106
|
parent: 106
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 3564
|
- uid: 3564
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: 3.141592653589793 rad
|
- rot: 3.141592653589793 rad
|
||||||
pos: -31.5,-18.5
|
pos: -31.5,-18.5
|
||||||
@@ -44245,9 +44245,6 @@ entities:
|
|||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- uid: 3565
|
- uid: 3565
|
||||||
type: FirelockEdge
|
type: FirelockEdge
|
||||||
components:
|
components:
|
||||||
@@ -46747,7 +46744,7 @@ entities:
|
|||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- uid: 3905
|
- uid: 3905
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: 1.5707963267948966 rad
|
- rot: 1.5707963267948966 rad
|
||||||
pos: -31.5,-13.5
|
pos: -31.5,-13.5
|
||||||
@@ -46785,7 +46782,7 @@ entities:
|
|||||||
parent: 106
|
parent: 106
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 3910
|
- uid: 3910
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: 1.5707963267948966 rad
|
- rot: 1.5707963267948966 rad
|
||||||
pos: -38.5,-12.5
|
pos: -38.5,-12.5
|
||||||
@@ -46795,9 +46792,6 @@ entities:
|
|||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- uid: 3911
|
- uid: 3911
|
||||||
type: Table
|
type: Table
|
||||||
components:
|
components:
|
||||||
|
|||||||
2011
Resources/Maps/cargo_shuttle.yml
Normal file
2011
Resources/Maps/cargo_shuttle.yml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -37669,7 +37669,7 @@ entities:
|
|||||||
stash: !type:ContainerSlot {}
|
stash: !type:ContainerSlot {}
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- uid: 437
|
- uid: 437
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: 1.5707963267948966 rad
|
- rot: 1.5707963267948966 rad
|
||||||
pos: -13.5,0.5
|
pos: -13.5,0.5
|
||||||
@@ -37679,11 +37679,8 @@ entities:
|
|||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- uid: 438
|
- uid: 438
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: 1.5707963267948966 rad
|
- rot: 1.5707963267948966 rad
|
||||||
pos: -13.5,-0.5
|
pos: -13.5,-0.5
|
||||||
@@ -42175,7 +42172,7 @@ entities:
|
|||||||
ItemCabinet: !type:ContainerSlot {}
|
ItemCabinet: !type:ContainerSlot {}
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- uid: 1056
|
- uid: 1056
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: -8.5,16.5
|
- pos: -8.5,16.5
|
||||||
parent: 60
|
parent: 60
|
||||||
@@ -42188,7 +42185,7 @@ entities:
|
|||||||
OrderSender: []
|
OrderSender: []
|
||||||
type: SignalTransmitter
|
type: SignalTransmitter
|
||||||
- uid: 1057
|
- uid: 1057
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: -7.5,16.5
|
- pos: -7.5,16.5
|
||||||
parent: 60
|
parent: 60
|
||||||
@@ -42197,9 +42194,6 @@ entities:
|
|||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- uid: 1058
|
- uid: 1058
|
||||||
type: CableApcExtension
|
type: CableApcExtension
|
||||||
components:
|
components:
|
||||||
@@ -48619,7 +48613,7 @@ entities:
|
|||||||
parent: 60
|
parent: 60
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 1949
|
- uid: 1949
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: -18.5,-32.5
|
- pos: -18.5,-32.5
|
||||||
parent: 60
|
parent: 60
|
||||||
@@ -48628,9 +48622,6 @@ entities:
|
|||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- uid: 1950
|
- uid: 1950
|
||||||
type: PosterLegitNanotrasenLogo
|
type: PosterLegitNanotrasenLogo
|
||||||
components:
|
components:
|
||||||
@@ -107866,7 +107857,7 @@ entities:
|
|||||||
parent: 60
|
parent: 60
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 10252
|
- uid: 10252
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: -29.5,43.5
|
- pos: -29.5,43.5
|
||||||
parent: 60
|
parent: 60
|
||||||
@@ -107875,9 +107866,6 @@ entities:
|
|||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- uid: 10253
|
- uid: 10253
|
||||||
type: CableApcExtension
|
type: CableApcExtension
|
||||||
components:
|
components:
|
||||||
@@ -150182,7 +150170,7 @@ entities:
|
|||||||
stash: !type:ContainerSlot {}
|
stash: !type:ContainerSlot {}
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- uid: 16392
|
- uid: 16392
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: -1.5707963267948966 rad
|
- rot: -1.5707963267948966 rad
|
||||||
pos: 10.5,31.5
|
pos: 10.5,31.5
|
||||||
@@ -150192,9 +150180,6 @@ entities:
|
|||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- uid: 16393
|
- uid: 16393
|
||||||
type: TableReinforced
|
type: TableReinforced
|
||||||
components:
|
components:
|
||||||
@@ -150860,7 +150845,7 @@ entities:
|
|||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- uid: 16487
|
- uid: 16487
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: 1.5707963267948966 rad
|
- rot: 1.5707963267948966 rad
|
||||||
pos: 8.5,33.5
|
pos: 8.5,33.5
|
||||||
@@ -152007,7 +151992,7 @@ entities:
|
|||||||
parent: 60
|
parent: 60
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 16645
|
- uid: 16645
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: 18.5,39.5
|
- pos: 18.5,39.5
|
||||||
parent: 60
|
parent: 60
|
||||||
@@ -152022,7 +152007,7 @@ entities:
|
|||||||
uid: 16646
|
uid: 16646
|
||||||
type: SignalTransmitter
|
type: SignalTransmitter
|
||||||
- uid: 16646
|
- uid: 16646
|
||||||
type: cargoTelepad
|
type: CargoTelepad
|
||||||
components:
|
components:
|
||||||
- pos: 18.5,40.5
|
- pos: 18.5,40.5
|
||||||
parent: 60
|
parent: 60
|
||||||
@@ -152975,7 +152960,7 @@ entities:
|
|||||||
parent: 60
|
parent: 60
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 16775
|
- uid: 16775
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: -1.5,49.5
|
- pos: -1.5,49.5
|
||||||
parent: 60
|
parent: 60
|
||||||
@@ -152984,9 +152969,6 @@ entities:
|
|||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- uid: 16776
|
- uid: 16776
|
||||||
type: AirlockGlass
|
type: AirlockGlass
|
||||||
components:
|
components:
|
||||||
@@ -154312,7 +154294,7 @@ entities:
|
|||||||
uid: 30426
|
uid: 30426
|
||||||
type: SignalReceiver
|
type: SignalReceiver
|
||||||
- uid: 16949
|
- uid: 16949
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: -1.5707963267948966 rad
|
- rot: -1.5707963267948966 rad
|
||||||
pos: 25.5,48.5
|
pos: 25.5,48.5
|
||||||
@@ -155451,7 +155433,7 @@ entities:
|
|||||||
parent: 60
|
parent: 60
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 17120
|
- uid: 17120
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: -1.5707963267948966 rad
|
- rot: -1.5707963267948966 rad
|
||||||
pos: 29.5,37.5
|
pos: 29.5,37.5
|
||||||
@@ -219233,7 +219215,7 @@ entities:
|
|||||||
- color: '#0313FFFF'
|
- color: '#0313FFFF'
|
||||||
type: AtmosPipeColor
|
type: AtmosPipeColor
|
||||||
- uid: 25752
|
- uid: 25752
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: 3.141592653589793 rad
|
- rot: 3.141592653589793 rad
|
||||||
pos: 31.5,-26.5
|
pos: 31.5,-26.5
|
||||||
@@ -219243,9 +219225,6 @@ entities:
|
|||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- uid: 25753
|
- uid: 25753
|
||||||
type: GasPipeTJunction
|
type: GasPipeTJunction
|
||||||
components:
|
components:
|
||||||
@@ -281207,15 +281186,12 @@ entities:
|
|||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- uid: 33379
|
- uid: 33379
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: -1.5707963267948966 rad
|
- rot: -1.5707963267948966 rad
|
||||||
pos: 48.5,-2.5
|
pos: 48.5,-2.5
|
||||||
parent: 60
|
parent: 60
|
||||||
type: Transform
|
type: Transform
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- containers:
|
- containers:
|
||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
|
|||||||
@@ -84441,7 +84441,7 @@ entities:
|
|||||||
parent: 30
|
parent: 30
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 8497
|
- uid: 8497
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: 1.5707963267948966 rad
|
- rot: 1.5707963267948966 rad
|
||||||
pos: 15.5,0.5
|
pos: 15.5,0.5
|
||||||
@@ -84451,11 +84451,8 @@ entities:
|
|||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- uid: 8498
|
- uid: 8498
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: 1.5707963267948966 rad
|
- rot: 1.5707963267948966 rad
|
||||||
pos: 15.5,1.5
|
pos: 15.5,1.5
|
||||||
@@ -107377,7 +107374,7 @@ entities:
|
|||||||
parent: 30
|
parent: 30
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 11627
|
- uid: 11627
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: 24.5,2.5
|
- pos: 24.5,2.5
|
||||||
parent: 30
|
parent: 30
|
||||||
@@ -108154,7 +108151,7 @@ entities:
|
|||||||
uid: 8465
|
uid: 8465
|
||||||
type: SignalTransmitter
|
type: SignalTransmitter
|
||||||
- uid: 11718
|
- uid: 11718
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: 26.5,-3.5
|
- pos: 26.5,-3.5
|
||||||
parent: 30
|
parent: 30
|
||||||
@@ -108167,7 +108164,7 @@ entities:
|
|||||||
OrderSender: []
|
OrderSender: []
|
||||||
type: SignalTransmitter
|
type: SignalTransmitter
|
||||||
- uid: 11719
|
- uid: 11719
|
||||||
type: cargoTelepad
|
type: CargoTelepad
|
||||||
components:
|
components:
|
||||||
- pos: 26.5,-4.5
|
- pos: 26.5,-4.5
|
||||||
parent: 30
|
parent: 30
|
||||||
|
|||||||
@@ -28403,7 +28403,7 @@ entities:
|
|||||||
parent: 130
|
parent: 130
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 1171
|
- uid: 1171
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: -30.5,-7.5
|
- pos: -30.5,-7.5
|
||||||
parent: 130
|
parent: 130
|
||||||
@@ -28412,9 +28412,6 @@ entities:
|
|||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- uid: 1172
|
- uid: 1172
|
||||||
type: Grille
|
type: Grille
|
||||||
components:
|
components:
|
||||||
@@ -39959,7 +39956,7 @@ entities:
|
|||||||
parent: 130
|
parent: 130
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 2885
|
- uid: 2885
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: 3.141592653589793 rad
|
- rot: 3.141592653589793 rad
|
||||||
pos: -34.5,-16.5
|
pos: -34.5,-16.5
|
||||||
@@ -40285,7 +40282,7 @@ entities:
|
|||||||
parent: 130
|
parent: 130
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 2933
|
- uid: 2933
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: 3.141592653589793 rad
|
- rot: 3.141592653589793 rad
|
||||||
pos: -35.5,-12.5
|
pos: -35.5,-12.5
|
||||||
@@ -59257,7 +59254,7 @@ entities:
|
|||||||
- canCollide: False
|
- canCollide: False
|
||||||
type: Physics
|
type: Physics
|
||||||
- uid: 5637
|
- uid: 5637
|
||||||
type: cargoTelepad
|
type: CargoTelepad
|
||||||
components:
|
components:
|
||||||
- pos: -34.5,-17.5
|
- pos: -34.5,-17.5
|
||||||
parent: 130
|
parent: 130
|
||||||
|
|||||||
@@ -28883,7 +28883,7 @@ entities:
|
|||||||
charger-slot: !type:ContainerSlot {}
|
charger-slot: !type:ContainerSlot {}
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- uid: 2135
|
- uid: 2135
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: -1.5707963267948966 rad
|
- rot: -1.5707963267948966 rad
|
||||||
pos: 13.5,30.5
|
pos: 13.5,30.5
|
||||||
@@ -28897,7 +28897,7 @@ entities:
|
|||||||
OrderSender: []
|
OrderSender: []
|
||||||
type: SignalTransmitter
|
type: SignalTransmitter
|
||||||
- uid: 2136
|
- uid: 2136
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: 20.5,23.5
|
- pos: 20.5,23.5
|
||||||
parent: 2
|
parent: 2
|
||||||
@@ -28906,9 +28906,6 @@ entities:
|
|||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- uid: 2137
|
- uid: 2137
|
||||||
type: CableHV
|
type: CableHV
|
||||||
components:
|
components:
|
||||||
@@ -94282,7 +94279,7 @@ entities:
|
|||||||
parent: 2
|
parent: 2
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 11095
|
- uid: 11095
|
||||||
type: cargoTelepad
|
type: CargoTelepad
|
||||||
components:
|
components:
|
||||||
- pos: 11.5,24.5
|
- pos: 11.5,24.5
|
||||||
parent: 2
|
parent: 2
|
||||||
@@ -94293,7 +94290,7 @@ entities:
|
|||||||
OrderReceiver: []
|
OrderReceiver: []
|
||||||
type: SignalReceiver
|
type: SignalReceiver
|
||||||
- uid: 11096
|
- uid: 11096
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: 11.5,25.5
|
- pos: 11.5,25.5
|
||||||
parent: 2
|
parent: 2
|
||||||
|
|||||||
@@ -22581,7 +22581,7 @@ entities:
|
|||||||
charger-slot: !type:ContainerSlot {}
|
charger-slot: !type:ContainerSlot {}
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- uid: 2157
|
- uid: 2157
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: 13.5,30.5
|
- pos: 13.5,30.5
|
||||||
parent: 0
|
parent: 0
|
||||||
@@ -22594,7 +22594,7 @@ entities:
|
|||||||
OrderSender: []
|
OrderSender: []
|
||||||
type: SignalTransmitter
|
type: SignalTransmitter
|
||||||
- uid: 2158
|
- uid: 2158
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: 20.5,23.5
|
- pos: 20.5,23.5
|
||||||
parent: 0
|
parent: 0
|
||||||
@@ -87928,7 +87928,7 @@ entities:
|
|||||||
parent: 0
|
parent: 0
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 11133
|
- uid: 11133
|
||||||
type: cargoTelepad
|
type: CargoTelepad
|
||||||
components:
|
components:
|
||||||
- pos: 11.5,24.5
|
- pos: 11.5,24.5
|
||||||
parent: 0
|
parent: 0
|
||||||
@@ -87939,7 +87939,7 @@ entities:
|
|||||||
OrderReceiver: []
|
OrderReceiver: []
|
||||||
type: SignalReceiver
|
type: SignalReceiver
|
||||||
- uid: 11134
|
- uid: 11134
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: 11.5,25.5
|
- pos: 11.5,25.5
|
||||||
parent: 0
|
parent: 0
|
||||||
|
|||||||
@@ -23263,7 +23263,7 @@ entities:
|
|||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- uid: 1771
|
- uid: 1771
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: 27.5,10.5
|
- pos: 27.5,10.5
|
||||||
parent: 852
|
parent: 852
|
||||||
@@ -23272,9 +23272,6 @@ entities:
|
|||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- uid: 1772
|
- uid: 1772
|
||||||
type: LockerQuarterMasterFilled
|
type: LockerQuarterMasterFilled
|
||||||
components:
|
components:
|
||||||
@@ -32620,16 +32617,13 @@ entities:
|
|||||||
parent: 852
|
parent: 852
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 3115
|
- uid: 3115
|
||||||
type: cargoTelepad
|
type: CargoTelepad
|
||||||
components:
|
components:
|
||||||
- pos: 20.5,10.5
|
- pos: 20.5,10.5
|
||||||
parent: 852
|
parent: 852
|
||||||
type: Transform
|
type: Transform
|
||||||
- canCollide: False
|
- canCollide: False
|
||||||
type: Physics
|
type: Physics
|
||||||
- inputs:
|
|
||||||
OrderReceiver: []
|
|
||||||
type: SignalReceiver
|
|
||||||
- uid: 3116
|
- uid: 3116
|
||||||
type: GasVentPump
|
type: GasVentPump
|
||||||
components:
|
components:
|
||||||
@@ -41694,7 +41688,7 @@ entities:
|
|||||||
parent: 852
|
parent: 852
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 4309
|
- uid: 4309
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: -1.5707963267948966 rad
|
- rot: -1.5707963267948966 rad
|
||||||
pos: 16.5,9.5
|
pos: 16.5,9.5
|
||||||
@@ -41704,9 +41698,6 @@ entities:
|
|||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- uid: 4310
|
- uid: 4310
|
||||||
type: CableApcExtension
|
type: CableApcExtension
|
||||||
components:
|
components:
|
||||||
@@ -56953,7 +56944,7 @@ entities:
|
|||||||
parent: 852
|
parent: 852
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 6251
|
- uid: 6251
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: 1.5707963267948966 rad
|
- rot: 1.5707963267948966 rad
|
||||||
pos: 21.5,10.5
|
pos: 21.5,10.5
|
||||||
@@ -56963,9 +56954,6 @@ entities:
|
|||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- uid: 6252
|
- uid: 6252
|
||||||
type: TableReinforced
|
type: TableReinforced
|
||||||
components:
|
components:
|
||||||
|
|||||||
@@ -70993,7 +70993,7 @@ entities:
|
|||||||
parent: 69
|
parent: 69
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 6473
|
- uid: 6473
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: 3.141592653589793 rad
|
- rot: 3.141592653589793 rad
|
||||||
pos: 13.5,-70.5
|
pos: 13.5,-70.5
|
||||||
@@ -71003,9 +71003,6 @@ entities:
|
|||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- uid: 6474
|
- uid: 6474
|
||||||
type: AirlockGlass
|
type: AirlockGlass
|
||||||
components:
|
components:
|
||||||
@@ -186003,7 +186000,7 @@ entities:
|
|||||||
- canCollide: False
|
- canCollide: False
|
||||||
type: Physics
|
type: Physics
|
||||||
- uid: 21911
|
- uid: 21911
|
||||||
type: cargoTelepad
|
type: CargoTelepad
|
||||||
components:
|
components:
|
||||||
- pos: 21.5,-71.5
|
- pos: 21.5,-71.5
|
||||||
parent: 69
|
parent: 69
|
||||||
@@ -186116,7 +186113,7 @@ entities:
|
|||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- uid: 21928
|
- uid: 21928
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: 1.5707963267948966 rad
|
- rot: 1.5707963267948966 rad
|
||||||
pos: 22.5,-71.5
|
pos: 22.5,-71.5
|
||||||
|
|||||||
@@ -20161,7 +20161,7 @@ entities:
|
|||||||
parent: 4
|
parent: 4
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 1961
|
- uid: 1961
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: 6.5,8.5
|
- pos: 6.5,8.5
|
||||||
parent: 4
|
parent: 4
|
||||||
@@ -20177,7 +20177,7 @@ entities:
|
|||||||
parent: 4
|
parent: 4
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 1963
|
- uid: 1963
|
||||||
type: cargoTelepad
|
type: CargoTelepad
|
||||||
components:
|
components:
|
||||||
- pos: 6.5,9.5
|
- pos: 6.5,9.5
|
||||||
parent: 4
|
parent: 4
|
||||||
|
|||||||
@@ -18704,7 +18704,7 @@ entities:
|
|||||||
parent: 82
|
parent: 82
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 592
|
- uid: 592
|
||||||
type: cargoTelepad
|
type: CargoTelepad
|
||||||
components:
|
components:
|
||||||
- pos: 14.5,43.5
|
- pos: 14.5,43.5
|
||||||
parent: 82
|
parent: 82
|
||||||
@@ -33056,7 +33056,7 @@ entities:
|
|||||||
parent: 82
|
parent: 82
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 2222
|
- uid: 2222
|
||||||
type: ComputerSupplyRequest
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: 16.5,33.5
|
- pos: 16.5,33.5
|
||||||
parent: 82
|
parent: 82
|
||||||
@@ -33065,9 +33065,6 @@ entities:
|
|||||||
board: !type:Container
|
board: !type:Container
|
||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- outputs:
|
|
||||||
OrderSender: []
|
|
||||||
type: SignalTransmitter
|
|
||||||
- uid: 2223
|
- uid: 2223
|
||||||
type: WallSolid
|
type: WallSolid
|
||||||
components:
|
components:
|
||||||
@@ -33856,7 +33853,7 @@ entities:
|
|||||||
parent: 82
|
parent: 82
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 2312
|
- uid: 2312
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: 10.5,36.5
|
- pos: 10.5,36.5
|
||||||
parent: 82
|
parent: 82
|
||||||
@@ -33978,7 +33975,7 @@ entities:
|
|||||||
parent: 82
|
parent: 82
|
||||||
type: Transform
|
type: Transform
|
||||||
- uid: 2326
|
- uid: 2326
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- rot: -1.5707963267948966 rad
|
- rot: -1.5707963267948966 rad
|
||||||
pos: 17.5,36.5
|
pos: 17.5,36.5
|
||||||
@@ -68591,7 +68588,7 @@ entities:
|
|||||||
ents: []
|
ents: []
|
||||||
type: ContainerContainer
|
type: ContainerContainer
|
||||||
- uid: 6330
|
- uid: 6330
|
||||||
type: ComputerSupplyOrdering
|
type: ComputerCargoOrders
|
||||||
components:
|
components:
|
||||||
- pos: 28.5,-35.5
|
- pos: 28.5,-35.5
|
||||||
parent: 82
|
parent: 82
|
||||||
|
|||||||
@@ -78,7 +78,7 @@
|
|||||||
sprite: Objects/Materials/Sheets/other.rsi
|
sprite: Objects/Materials/Sheets/other.rsi
|
||||||
state: plasma_3
|
state: plasma_3
|
||||||
product: CrateMaterialPlasma
|
product: CrateMaterialPlasma
|
||||||
cost: 4500
|
cost: 5000
|
||||||
category: Materials
|
category: Materials
|
||||||
group: market
|
group: market
|
||||||
|
|
||||||
|
|||||||
11
Resources/Prototypes/Datasets/Names/cargo_shuttle.yml
Normal file
11
Resources/Prototypes/Datasets/Names/cargo_shuttle.yml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
- type: dataset
|
||||||
|
id: CargoShuttleNames
|
||||||
|
values:
|
||||||
|
- A Shuttle Will Not Occur
|
||||||
|
- Big Money Shuttle
|
||||||
|
- Engine Change
|
||||||
|
- Ships-the-Cargo
|
||||||
|
- Shootel
|
||||||
|
- Shuttle McShuttleface
|
||||||
|
- ShuttleShuttle
|
||||||
|
- Urist McShuttle
|
||||||
@@ -114,6 +114,8 @@
|
|||||||
- type: Bloodstream
|
- type: Bloodstream
|
||||||
bloodMaxVolume: 0.1
|
bloodMaxVolume: 0.1
|
||||||
- type: NoSlip
|
- type: NoSlip
|
||||||
|
- type: MobPrice
|
||||||
|
price: 50
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: bee
|
name: bee
|
||||||
@@ -331,6 +333,8 @@
|
|||||||
- type: Bloodstream
|
- type: Bloodstream
|
||||||
bloodMaxVolume: 0.1
|
bloodMaxVolume: 0.1
|
||||||
- type: NoSlip
|
- type: NoSlip
|
||||||
|
- type: MobPrice
|
||||||
|
price: 50
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: cow
|
name: cow
|
||||||
@@ -822,7 +826,8 @@
|
|||||||
bloodMaxVolume: 50
|
bloodMaxVolume: 50
|
||||||
- type: DiseaseCarrier #The other class lab animal and disease vector
|
- type: DiseaseCarrier #The other class lab animal and disease vector
|
||||||
- type: CanEscapeInventory
|
- type: CanEscapeInventory
|
||||||
|
- type: MobPrice
|
||||||
|
price: 50
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: MobMouse
|
parent: MobMouse
|
||||||
|
|||||||
@@ -50,6 +50,8 @@
|
|||||||
- type: SentienceTarget
|
- type: SentienceTarget
|
||||||
flavorKind: corgi
|
flavorKind: corgi
|
||||||
- type: Puller
|
- type: Puller
|
||||||
|
- type: MobPrice
|
||||||
|
price: 200
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: corrupted corgi
|
name: corrupted corgi
|
||||||
@@ -272,6 +274,8 @@
|
|||||||
- type: Grammar
|
- type: Grammar
|
||||||
attributes:
|
attributes:
|
||||||
gender: epicene
|
gender: epicene
|
||||||
|
- type: MobPrice
|
||||||
|
price: 200
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: Runtime
|
name: Runtime
|
||||||
|
|||||||
@@ -204,4 +204,6 @@
|
|||||||
Heat : 1 #per second, scales with temperature & other constants
|
Heat : 1 #per second, scales with temperature & other constants
|
||||||
- type: Bloodstream
|
- type: Bloodstream
|
||||||
bloodMaxVolume: 150
|
bloodMaxVolume: 150
|
||||||
|
- type: MobPrice
|
||||||
|
price: 150
|
||||||
|
|
||||||
|
|||||||
@@ -44,8 +44,8 @@
|
|||||||
type: CommunicationsConsoleBoundUserInterface
|
type: CommunicationsConsoleBoundUserInterface
|
||||||
- key: enum.RadarConsoleUiKey.Key
|
- key: enum.RadarConsoleUiKey.Key
|
||||||
type: RadarConsoleBoundUserInterface
|
type: RadarConsoleBoundUserInterface
|
||||||
- key: enum.CargoConsoleUiKey.Key
|
- key: enum.CargoConsoleUiKey.Orders
|
||||||
type: CargoConsoleBoundUserInterface
|
type: CargoOrderConsoleBoundUserInterface
|
||||||
- key: enum.CrewMonitoringUIKey.Key
|
- key: enum.CrewMonitoringUIKey.Key
|
||||||
type: CrewMonitoringBoundUserInterface
|
type: CrewMonitoringBoundUserInterface
|
||||||
- type: IntrinsicUI
|
- type: IntrinsicUI
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
keywords: [ "AI", "console", "interface" ]
|
keywords: [ "AI", "console", "interface" ]
|
||||||
priority: -10
|
priority: -10
|
||||||
event: !type:ToggleIntrinsicUIEvent
|
event: !type:ToggleIntrinsicUIEvent
|
||||||
- key: enum.CargoConsoleUiKey.Key
|
- key: enum.CargoConsoleUiKey.Orders
|
||||||
toggleAction:
|
toggleAction:
|
||||||
name: action-name-show-cargo-console
|
name: action-name-show-cargo-console
|
||||||
description: action-description-show-cargo-console
|
description: action-description-show-cargo-console
|
||||||
@@ -100,8 +100,7 @@
|
|||||||
title: communicationsconsole-announcement-title-centcom
|
title: communicationsconsole-announcement-title-centcom
|
||||||
color: "#228b22"
|
color: "#228b22"
|
||||||
- type: RadarConsole
|
- type: RadarConsole
|
||||||
- type: CargoConsole
|
- type: CargoOrderConsole
|
||||||
- type: CargoOrderDatabase
|
|
||||||
- type: CrewMonitoringConsole
|
- type: CrewMonitoringConsole
|
||||||
snap: false
|
snap: false
|
||||||
precision: 3
|
precision: 3
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
description: A computer printed circuit board for a supply ordering console
|
description: A computer printed circuit board for a supply ordering console
|
||||||
components:
|
components:
|
||||||
- type: ComputerBoard
|
- type: ComputerBoard
|
||||||
prototype: ComputerSupplyOrdering
|
prototype: ComputerCargoOrders
|
||||||
- type: StaticPrice
|
- type: StaticPrice
|
||||||
price: 750
|
price: 750
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@
|
|||||||
description: A computer printed circuit board for a supply request console
|
description: A computer printed circuit board for a supply request console
|
||||||
components:
|
components:
|
||||||
- type: ComputerBoard
|
- type: ComputerBoard
|
||||||
prototype: ComputerSupplyRequest
|
prototype: ComputerCargoOrders
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: BaseComputerCircuitboard
|
parent: BaseComputerCircuitboard
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
- type: entity
|
||||||
|
id: CargoPallet
|
||||||
|
name: cargo pallet
|
||||||
|
description: Designates valid items to sell to Centcomm when a shuttle is recalled.
|
||||||
|
parent: BaseStructure
|
||||||
|
components:
|
||||||
|
- type: CargoPallet
|
||||||
|
- type: Sprite
|
||||||
|
netsync: false
|
||||||
|
layers:
|
||||||
|
- texture: Structures/catwalk.rsi/catwalk_preview.png
|
||||||
|
- type: CollideOnAnchor
|
||||||
@@ -62,7 +62,26 @@
|
|||||||
key: syndie_key
|
key: syndie_key
|
||||||
screen: syndishuttle
|
screen: syndishuttle
|
||||||
- type: RadarConsole
|
- type: RadarConsole
|
||||||
maxRange: 512
|
maxRange: 1536
|
||||||
|
- type: PointLight
|
||||||
|
radius: 1.5
|
||||||
|
energy: 1.6
|
||||||
|
color: "#c94242"
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: ComputerShuttleBase
|
||||||
|
id: ComputerShuttleCargo
|
||||||
|
name: cargo shuttle console
|
||||||
|
description: Used to pilot the cargo shuttle.
|
||||||
|
components:
|
||||||
|
- type: Appearance
|
||||||
|
visuals:
|
||||||
|
- type: ComputerVisualizer
|
||||||
|
key: generic_key
|
||||||
|
screen: shuttle
|
||||||
|
- type: CargoPilotConsole
|
||||||
|
- type: RadarConsole
|
||||||
|
maxRange: 256
|
||||||
- type: PointLight
|
- type: PointLight
|
||||||
radius: 1.5
|
radius: 1.5
|
||||||
energy: 1.6
|
energy: 1.6
|
||||||
@@ -388,25 +407,24 @@
|
|||||||
color: "#e6e227"
|
color: "#e6e227"
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: ComputerSupplyOrdering
|
id: ComputerCargoShuttle
|
||||||
parent: ComputerBase
|
parent: ComputerBase
|
||||||
name: Cargo ordering computer
|
name: cargo shuttle computer
|
||||||
description: Used to order supplies, approve requests, and control the shuttle.
|
description: Used to order the shuttle.
|
||||||
components:
|
components:
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
visuals:
|
visuals:
|
||||||
- type: ComputerVisualizer
|
- type: ComputerVisualizer
|
||||||
key: tech_key
|
key: tech_key
|
||||||
screen: supply
|
screen: supply
|
||||||
- type: CargoConsole
|
- type: CargoShuttleConsole
|
||||||
- type: CargoOrderDatabase
|
|
||||||
- type: ActivatableUI
|
- type: ActivatableUI
|
||||||
key: enum.CargoConsoleUiKey.Key
|
key: enum.CargoConsoleUiKey.Shuttle
|
||||||
- type: ActivatableUIRequiresPower
|
- type: ActivatableUIRequiresPower
|
||||||
- type: UserInterface
|
- type: UserInterface
|
||||||
interfaces:
|
interfaces:
|
||||||
- key: enum.CargoConsoleUiKey.Key
|
- key: enum.CargoConsoleUiKey.Shuttle
|
||||||
type: CargoConsoleBoundUserInterface
|
type: CargoShuttleConsoleBoundUserInterface
|
||||||
- type: Computer
|
- type: Computer
|
||||||
board: SupplyComputerCircuitboard
|
board: SupplyComputerCircuitboard
|
||||||
- type: PointLight
|
- type: PointLight
|
||||||
@@ -417,24 +435,32 @@
|
|||||||
access: [["Cargo"]]
|
access: [["Cargo"]]
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: ComputerSupplyRequest
|
id: ComputerCargoOrders
|
||||||
parent: ComputerSupplyOrdering
|
parent: ComputerBase
|
||||||
name: cargo request computer
|
name: cargo request computer
|
||||||
description: Used to request supplies from cargo.
|
description: Used to order supplies and approve requests.
|
||||||
components:
|
components:
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
visuals:
|
visuals:
|
||||||
- type: ComputerVisualizer
|
- type: ComputerVisualizer
|
||||||
key: tech_key
|
key: tech_key
|
||||||
screen: request
|
screen: request
|
||||||
- type: CargoConsole
|
- type: CargoOrderConsole
|
||||||
requestOnly: true
|
- type: ActivatableUI
|
||||||
|
key: enum.CargoConsoleUiKey.Orders
|
||||||
|
- type: ActivatableUIRequiresPower
|
||||||
|
- type: UserInterface
|
||||||
|
interfaces:
|
||||||
|
- key: enum.CargoConsoleUiKey.Orders
|
||||||
|
type: CargoOrderConsoleBoundUserInterface
|
||||||
- type: Computer
|
- type: Computer
|
||||||
board: SupplyRequestComputerCircuitboard
|
board: SupplyComputerCircuitboard
|
||||||
- type: PointLight
|
- type: PointLight
|
||||||
radius: 1.5
|
radius: 1.5
|
||||||
energy: 1.6
|
energy: 1.6
|
||||||
color: "#b89f25"
|
color: "#b89f25"
|
||||||
|
- type: AccessReader
|
||||||
|
access: [["Cargo"]]
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ComputerBase
|
parent: ComputerBase
|
||||||
|
|||||||
@@ -118,3 +118,28 @@
|
|||||||
autoRot: true
|
autoRot: true
|
||||||
offset: "0, 0.1" # shine from the top, not bottom of the computer
|
offset: "0, 0.1" # shine from the top, not bottom of the computer
|
||||||
color: "#4246b3"
|
color: "#4246b3"
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: DebugGyroscope
|
||||||
|
parent: Gyroscope
|
||||||
|
name: gyroscope
|
||||||
|
suffix: DEBUG
|
||||||
|
description: Increases the shuttle's potential angular rotation.
|
||||||
|
components:
|
||||||
|
- type: Thruster
|
||||||
|
requireSpace: false
|
||||||
|
- type: ApcPowerReceiver
|
||||||
|
needsPower: false
|
||||||
|
powerLoad: 0
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Structures/Shuttles/thruster.rsi
|
||||||
|
layers:
|
||||||
|
- state: base
|
||||||
|
map: ["enum.ThrusterVisualLayers.Base"]
|
||||||
|
- state: thrust
|
||||||
|
map: ["enum.ThrusterVisualLayers.ThrustOn"]
|
||||||
|
shader: unshaded
|
||||||
|
- state: thrust_burn_unshaded
|
||||||
|
map: ["enum.ThrusterVisualLayers.ThrustingUnshaded"]
|
||||||
|
shader: unshaded
|
||||||
|
offset: 0, 1
|
||||||
|
|||||||
51
Resources/Prototypes/Entities/Structures/cargo_console.yml
Normal file
51
Resources/Prototypes/Entities/Structures/cargo_console.yml
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
- type: entity
|
||||||
|
id: CargoTelepad
|
||||||
|
parent: BaseStructureDynamic
|
||||||
|
name: cargo telepad
|
||||||
|
components:
|
||||||
|
- type: InteractionOutline
|
||||||
|
- type: Physics
|
||||||
|
bodyType: Static
|
||||||
|
- type: Transform
|
||||||
|
anchored: true
|
||||||
|
noRot: true
|
||||||
|
- type: Fixtures
|
||||||
|
fixtures:
|
||||||
|
- shape:
|
||||||
|
!type:PhysShapeAabb
|
||||||
|
bounds: "-0.45,-0.45,0.45,0.00"
|
||||||
|
mass: 25
|
||||||
|
mask:
|
||||||
|
- MachineMask
|
||||||
|
- type: Sprite
|
||||||
|
netsync: false
|
||||||
|
sprite: Structures/cargo_telepad.rsi
|
||||||
|
drawdepth: FloorObjects
|
||||||
|
layers:
|
||||||
|
- state: offline
|
||||||
|
map: [ "enum.CargoTelepadLayers.Base" ]
|
||||||
|
- state: idle
|
||||||
|
map: [ "enum.CargoTelepadLayers.Beam" ]
|
||||||
|
shader: unshaded
|
||||||
|
- type: Damageable
|
||||||
|
damageContainer: Inorganic
|
||||||
|
damageModifierSet: Metallic
|
||||||
|
- type: Destructible
|
||||||
|
thresholds:
|
||||||
|
- trigger:
|
||||||
|
!type:DamageTrigger
|
||||||
|
damage: 75
|
||||||
|
behaviors:
|
||||||
|
- !type:SpawnEntitiesBehavior
|
||||||
|
spawn:
|
||||||
|
SheetSteel1:
|
||||||
|
min: 1
|
||||||
|
max: 1
|
||||||
|
- !type:DoActsBehavior
|
||||||
|
acts: [ "Destruction" ]
|
||||||
|
- type: ApcPowerReceiver
|
||||||
|
powerLoad: 1000 # TODO if we keep this make it spike power draw when teleporting
|
||||||
|
- type: ExtensionCableReceiver
|
||||||
|
- type: CargoTelepad
|
||||||
|
- type: Appearance
|
||||||
|
- type: CollideOnAnchor
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
- type: entity
|
|
||||||
id: cargoTelepad
|
|
||||||
parent: BaseStructureDynamic
|
|
||||||
name: cargo telepad
|
|
||||||
description: 'Temporary cargo delivery for developing Nanotrasen stations! Warning: destroying this while goods are in transit will lose them forever!'
|
|
||||||
components:
|
|
||||||
- type: InteractionOutline
|
|
||||||
- type: Physics
|
|
||||||
bodyType: Static
|
|
||||||
- type: Transform
|
|
||||||
anchored: true
|
|
||||||
noRot: true
|
|
||||||
- type: Fixtures
|
|
||||||
fixtures:
|
|
||||||
- shape:
|
|
||||||
!type:PhysShapeAabb
|
|
||||||
bounds: "-0.45,-0.45,0.45,0.00"
|
|
||||||
mass: 25
|
|
||||||
mask:
|
|
||||||
- MachineMask
|
|
||||||
- type: Sprite
|
|
||||||
netsync: false
|
|
||||||
sprite: Structures/cargo_telepad.rsi
|
|
||||||
drawdepth: FloorObjects
|
|
||||||
layers:
|
|
||||||
- state: offline
|
|
||||||
map: ["enum.CargoTelepadLayers.Base"]
|
|
||||||
- state: idle
|
|
||||||
map: [ "enum.CargoTelepadLayers.Beam" ]
|
|
||||||
shader: unshaded
|
|
||||||
- type: Damageable
|
|
||||||
damageContainer: Inorganic
|
|
||||||
damageModifierSet: Metallic
|
|
||||||
- type: Destructible
|
|
||||||
thresholds:
|
|
||||||
- trigger:
|
|
||||||
!type:DamageTrigger
|
|
||||||
damage: 75
|
|
||||||
behaviors:
|
|
||||||
- !type:SpawnEntitiesBehavior
|
|
||||||
spawn:
|
|
||||||
SheetSteel1:
|
|
||||||
min: 1
|
|
||||||
max: 1
|
|
||||||
- !type:DoActsBehavior
|
|
||||||
acts: ["Destruction"]
|
|
||||||
- type: ApcPowerReceiver
|
|
||||||
powerLoad: 1000 # TODO if we keep this make it spike power draw when teleporting
|
|
||||||
- type: ExtensionCableReceiver
|
|
||||||
- type: CargoTelepad
|
|
||||||
- type: Appearance
|
|
||||||
- type: CollideOnAnchor
|
|
||||||
4
Resources/Prototypes/shuttles.yml
Normal file
4
Resources/Prototypes/shuttles.yml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Cargo
|
||||||
|
- type: cargoShuttle
|
||||||
|
id: CargoShuttle
|
||||||
|
path: /Maps/cargo_shuttle.yml
|
||||||
Reference in New Issue
Block a user