Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Content.Client._NF.Shipyard.UI;
using Content.Shared.Containers.ItemSlots;
using Content.Shared._NF.Shipyard.BUI;
using Content.Shared._NF.Shipyard.Components;
using Content.Shared._NF.Shipyard.Events;
using static Robust.Client.UserInterface.Controls.BaseButton;

Expand Down Expand Up @@ -39,7 +40,7 @@ protected override void Open()
_menu.OnSellShip += SellShip;
_menu.OnUnassignDeed += UnassignDeed;
_menu.OnRenameShip += RenameShip;
_menu.TargetIdButton.OnPressed += _ => SendMessage(new ItemSlotButtonPressedEvent("ShipyardConsole-targetId"));
_menu.TargetIdButton.OnPressed += _ => SendMessage(new ItemSlotButtonPressedEvent(ShipyardConsoleComponent.TargetIdCardSlotId));
}

private void Populate(List<string> availablePrototypes, List<string> unavailablePrototypes, bool freeListings, bool validId)
Expand Down
9 changes: 7 additions & 2 deletions Content.Client/_NF/Shipyard/UI/ShipyardConsoleMenu.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@
<gfx:StyleBoxFlat BorderThickness="2" BorderColor="#333333" BackgroundColor="#141414"/>
</PanelContainer.PanelOverride>
<BoxContainer Orientation="Vertical" Margin="5 0 5 0">
<BoxContainer Orientation="Vertical">
<BoxContainer Orientation="Horizontal">
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
<Label Text="{Loc 'bank-atm-menu-balance-label'}"
StyleClasses="LabelKeyText" />
<Label Name="BalanceLabel"
Text="{Loc 'shipyard-console-no-bank'}" />
</BoxContainer>
<BoxContainer Orientation="Horizontal" HorizontalAlignment="Right">
<Label Text="{Loc 'vending-machine-menu-cash-slot-label'}"
StyleClasses="LabelKeyText" />
<Label Name="CashSlotLabel" />
</BoxContainer>
</BoxContainer>
<BoxContainer Orientation="Vertical">
<BoxContainer Orientation="Horizontal">
Expand Down
2 changes: 2 additions & 0 deletions Content.Client/_NF/Shipyard/UI/ShipyardConsoleMenu.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,8 @@ private void AddEnginesFromPrototypes(IEnumerable<string> prototypes)
public void UpdateState(ShipyardConsoleInterfaceState state)
{
BalanceLabel.Text = BankSystemExtensions.ToSpesoString(state.Balance);
CashSlotLabel.Text = BankSystemExtensions.ToSpesoString(state.CashSlotBalance);

var shipPrice = 0;
if (!state.FreeListings)
shipPrice = state.ShipSellValue;
Expand Down
83 changes: 77 additions & 6 deletions Content.Server/_NF/Shipyard/Systems/ShipyardSystem.Consoles.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Content.Server.Access.Systems;
using Content.Server.Stack;
using Content.Server.Popups;
using Content.Server.Radio.EntitySystems;
using Content.Server._NF.Bank;
Expand Down Expand Up @@ -50,7 +51,10 @@
using Robust.Server.Player;
using Content.Shared._Mono.Ships.Components;
using Content.Shared._Mono.Shipyard;
using Content.Shared._Mono.Traits.Physical;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.Tag;
using Content.Shared.Stacks;
using Robust.Shared.Timing;

namespace Content.Server._NF.Shipyard.Systems;
Expand Down Expand Up @@ -78,6 +82,8 @@ public sealed partial class ShipyardSystem : SharedShipyardSystem
[Dependency] private ShuttleConsoleLockSystem _shuttleConsoleLock = default!;
[Dependency] private IGameTiming _timing = default!;
[Dependency] private TagSystem _tagSystem = default!;
[Dependency] private StackSystem _stack = default!;
[Dependency] private ItemSlotsSystem _itemSlots = default!;

private static readonly ProtoId<TagPrototype> CrewedShuttleTag = "CrewedShuttle";
private static readonly Regex DeedRegex = new(@"\s*\([^()]*\)");
Expand Down Expand Up @@ -224,21 +230,25 @@ private void OnPurchaseMessage(EntityUid shipyardConsoleUid, ShipyardConsoleComp
}
else
{
if (bank.Balance <= vessel.Price)
var cashInSlot = GetCashInSlot(component);
if (vessel.Price > bank.Balance + cashInSlot)
{
Del(shuttleUid);
ConsolePopup(player, Loc.GetString("cargo-console-insufficient-funds", ("cost", vessel.Price)));
ConsolePopup(player, Loc.GetString("bank-insufficient-funds"));
PlayDenySound(player, shipyardConsoleUid, component);
return;
}

if (!_bank.TryBankWithdraw(player, vessel.Price))
var bankCharge = Math.Max(vessel.Price - cashInSlot, 0);
if (bankCharge > 0 && !_bank.TryBankWithdraw(player, bankCharge))
{
Del(shuttleUid);
ConsolePopup(player, Loc.GetString("cargo-console-insufficient-funds", ("cost", vessel.Price)));
ConsolePopup(player, Loc.GetString("bank-insufficient-funds"));
PlayDenySound(player, shipyardConsoleUid, component);
return;
}

TakeCashFromSlot(component, vessel.Price);
}

// Add company information to the shuttle from the ID card or voucher
Expand Down Expand Up @@ -554,7 +564,11 @@ public void OnSellMessage(EntityUid uid, ShipyardConsoleComponent component, Shi
}
bill = int.Max(0, bill);

_bank.TryBankDeposit(player, bill);
if (HasComp<IronmanComponent>(player))
AddCashToSlot(uid, component, bill);
else
_bank.TryBankDeposit(player, bill);

PlayConfirmSound(player, uid, component);
}

Expand Down Expand Up @@ -698,7 +712,8 @@ private void OnItemSlotChanged(EntityUid uid, ShipyardConsoleComponent component
if (!component.Initialized)
return;

if (args.Container.ID != component.TargetIdSlot.ID)
if (args.Container.ID != component.TargetIdSlot.ID
&& args.Container.ID != component.CashSlot.ID)
return;

// kind of cursed. We need to update the UI when an Id is entered, but the UI needs to know the player characters bank account.
Expand Down Expand Up @@ -919,8 +934,13 @@ private struct IDShipAccesses

private void RefreshState(EntityUid uid, int balance, bool access, string? shipDeed, int shipSellValue, EntityUid? targetId, ShipyardConsoleUiKey uiKey, bool freeListings)
{
var cashInSlot = 0;
if (TryComp<ShipyardConsoleComponent>(uid, out var shipyard))
cashInSlot = GetCashInSlot(shipyard);

var newState = new ShipyardConsoleInterfaceState(
balance,
cashInSlot,
access,
shipDeed,
shipSellValue,
Expand All @@ -934,6 +954,57 @@ private void RefreshState(EntityUid uid, int balance, bool access, string? shipD
_ui.SetUiState(uid, uiKey, newState);
}

private int GetCashInSlot(ShipyardConsoleComponent component)
{
var cashEntity = component.CashSlot.ContainerSlot?.ContainedEntity;
if (cashEntity == null)
return 0;

if (!TryComp<StackComponent>(cashEntity, out var cashStack) ||
cashStack.StackTypeId != component.CashType)
return 0;

return cashStack.Count;
}

private void TakeCashFromSlot(ShipyardConsoleComponent component, int amount)
{
if (amount <= 0)
return;

var cashEntity = component.CashSlot.ContainerSlot?.ContainedEntity;
if (cashEntity == null ||
!TryComp<StackComponent>(cashEntity, out var cashStack) ||
cashStack.StackTypeId != component.CashType)
return;

var spent = Math.Min(amount, cashStack.Count);
_stack.SetCount(cashEntity.Value, cashStack.Count - spent, cashStack);
}

private void AddCashToSlot(EntityUid uid, ShipyardConsoleComponent component, int amount)
{
if (amount <= 0)
return;

var cashEntity = component.CashSlot.ContainerSlot?.ContainedEntity;
if (cashEntity != null &&
TryComp<StackComponent>(cashEntity, out var cashStack) &&
cashStack.StackTypeId == component.CashType)
{
_stack.SetCount(cashEntity.Value, cashStack.Count + amount, cashStack);
return;
}

var coordinates = Transform(uid).Coordinates;
var stackPrototype = _prototypeManager.Index<StackPrototype>(component.CashType);
var payout = _stack.Spawn(amount, stackPrototype, coordinates);
if (_itemSlots.TryInsert(uid, component.CashSlot, payout, user: null, excludeUserAudio: true))
return;

_transform.SetCoordinates(payout, coordinates);
}

#region Deed Assignment
void AssignShuttleDeedProperties(ShuttleDeedComponent deed, EntityUid? shuttleUid, string? shuttleName, string? shuttleOwner, bool purchasedWithVoucher, string? purchaseVoucherUid = null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace Content.Shared._NF.Shipyard.BUI;
public sealed class ShipyardConsoleInterfaceState : BoundUserInterfaceState
{
public int Balance;
public int CashSlotBalance;
public readonly bool AccessGranted;
public readonly string? ShipDeedTitle;
public int ShipSellValue;
Expand All @@ -19,6 +20,7 @@ public sealed class ShipyardConsoleInterfaceState : BoundUserInterfaceState

public ShipyardConsoleInterfaceState(
int balance,
int cashSlotBalance,
bool accessGranted,
string? shipDeedTitle,
int shipSellValue,
Expand All @@ -30,6 +32,7 @@ public ShipyardConsoleInterfaceState(
float sellRate)
{
Balance = balance;
CashSlotBalance = cashSlotBalance;
AccessGranted = accessGranted;
ShipDeedTitle = shipDeedTitle;
ShipSellValue = shipSellValue;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,30 @@
using Robust.Shared.GameStates;
using Robust.Shared.Audio;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.Stacks;
using Robust.Shared.Prototypes;
using Content.Shared.Radio;
using Content.Shared.Access;
using Content.Shared._NF.Bank.Components;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;

namespace Content.Shared._NF.Shipyard.Components;

[RegisterComponent, NetworkedComponent, Access(typeof(SharedShipyardSystem))]
public sealed partial class ShipyardConsoleComponent : Component
{
public static string TargetIdCardSlotId = "ShipyardConsole-targetId";
public static string CashSlotId = "ShipyardConsole-cashSlot";

[DataField("targetIdSlot")]
public ItemSlot TargetIdSlot = new();

[ViewVariables(VVAccess.ReadWrite), DataField("cashType", customTypeSerializer: typeof(PrototypeIdSerializer<StackPrototype>))]
public string CashType = "Credit";

[DataField("cashSlot")]
public ItemSlot CashSlot = new();

[DataField("soundError")]
public SoundSpecifier ErrorSound =
new SoundPathSpecifier("/Audio/Effects/Cargo/buzz_sigh.ogg");
Expand Down
2 changes: 2 additions & 0 deletions Content.Shared/_NF/Shipyard/SharedShipyardSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,13 @@ private void OnGetState(EntityUid uid, ShipyardConsoleComponent component, ref C
private void OnComponentInit(EntityUid uid, ShipyardConsoleComponent component, ComponentInit args)
{
_itemSlotsSystem.AddItemSlot(uid, ShipyardConsoleComponent.TargetIdCardSlotId, component.TargetIdSlot);
_itemSlotsSystem.AddItemSlot(uid, ShipyardConsoleComponent.CashSlotId, component.CashSlot);
}

private void OnComponentRemove(EntityUid uid, ShipyardConsoleComponent component, ComponentRemove args)
{
_itemSlotsSystem.RemoveItemSlot(uid, component.TargetIdSlot);
_itemSlotsSystem.RemoveItemSlot(uid, component.CashSlot);
}

[Serializable, NetSerializable]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## UI
shipyard-console-invalid-vessel = Cannot purchase vessel:
shipyard-console-menu-title = Shipyard Menu
ShipyardConsole-cashSlot = Cash Slot
shipyard-console-menu-listing-free = Free
shipyard-console-menu-listing-voucher = Voucher
shipyard-console-docking = {$owner} shuttle {$vessel} en route.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@
components:
- IdCard
- ShipyardVoucher
cashSlot:
name: ShipyardConsole-cashSlot
insertSound: /Audio/Machines/scanning.ogg
ejectSound: /Audio/Machines/tray_eject.ogg
ejectOnBreak: true
swap: false
whitelist:
components:
- Cash
newAccessLevels: [Captain]
- type: ActivatableUI
singleUser: true
Expand All @@ -40,6 +49,7 @@
containers:
board: !type:Container
ShipyardConsole-targetId: !type:ContainerSlot
ShipyardConsole-cashSlot: !type:ContainerSlot
- type: Computer
board: Null

Expand Down
Loading