Skip to content

Commit

Permalink
Station Bank Deposits (#361)
Browse files Browse the repository at this point in the history
* Bank

* Bank

* Missing FTL

* Fix
  • Loading branch information
dvir001 authored Oct 2, 2023
1 parent 8f41896 commit d777209
Show file tree
Hide file tree
Showing 12 changed files with 284 additions and 15 deletions.
10 changes: 10 additions & 0 deletions Content.Client/Bank/BUI/StationBankATMMenuBoundUserInterface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ protected override void Open()

_menu = new StationBankATMMenu();
_menu.WithdrawRequest += OnWithdraw;
_menu.DepositRequest += OnDeposit;
_menu.OnClose += Close;
_menu.PopulateReasons();
_menu.OpenCentered();
Expand All @@ -40,6 +41,14 @@ private void OnWithdraw()
SendMessage(new StationBankWithdrawMessage(amount, _menu.Reason, _menu.Description));
}

private void OnDeposit()
{
if (_menu?.Amount is not int amount)
return;

SendMessage(new StationBankDepositMessage(amount, _menu.Reason, _menu.Description));
}

protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
Expand All @@ -49,5 +58,6 @@ protected override void UpdateState(BoundUserInterfaceState state)

_menu?.SetEnabled(bankState.Enabled);
_menu?.SetBalance(bankState.Balance);
_menu?.SetDeposit(bankState.Deposit);
}
}
15 changes: 12 additions & 3 deletions Content.Client/Bank/UI/StationBankATMMenu.xaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<controls:FancyWindow xmlns="https://spacestation14.io"
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
SetSize="480 180"
MinSize="360 180">
SetSize="480 230"
MinSize="360 230">
<BoxContainer Margin="10 2 10 2" Orientation="Vertical">
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'bank-atm-menu-balance-label'}"
Expand All @@ -27,10 +27,19 @@
<Label Text="{Loc 'bank-atm-description-label'}"
StyleClasses="LabelKeyText"
MinSize="100 0" />
<LineEdit Name="WithdrawDescription" MinSize="120 0" HorizontalExpand="True"/>
<LineEdit Name="AmountDescription" MinSize="120 0" HorizontalExpand="True"/>
</BoxContainer>
<Button Name="WithdrawButton"
Text="{Loc 'bank-atm-menu-withdraw-button'}"/>
<TextureButton VerticalExpand="True" />
<BoxContainer Orientation="Horizontal">
<Label Text="{Loc 'bank-atm-menu-deposit-label'}"
StyleClasses="LabelKeyText" />
<Label Name="DepositLabel"
Text="{Loc 'bank-atm-menu-no-deposit'}" />
</BoxContainer>
<Button Name="DepositButton"
Text="{Loc 'bank-atm-menu-deposit-button'}"/>
<TextureButton VerticalExpand="True" />
</BoxContainer>
</controls:FancyWindow>
16 changes: 15 additions & 1 deletion Content.Client/Bank/UI/StationBankATMMenu.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace Content.Client.Bank.UI;
public sealed partial class StationBankATMMenu : FancyWindow
{
public Action? WithdrawRequest;
public Action? DepositRequest;
public int Amount;
private readonly List<string> _reasonStrings = new();
public string? Reason;
Expand All @@ -17,10 +18,11 @@ public StationBankATMMenu()
{
RobustXamlLoader.Load(this);
WithdrawButton.OnPressed += OnWithdrawPressed;
DepositButton.OnPressed += OnDepositPressed;
Title = Loc.GetString("station-bank-atm-menu-title");
WithdrawEdit.OnTextChanged += OnAmountChanged;
Reasons.OnItemSelected += OnReasonSelected;
WithdrawDescription.OnTextChanged += OnDescChanged;
AmountDescription.OnTextChanged += OnDescChanged;
}

private void SetReasonText(int id)
Expand All @@ -37,16 +39,28 @@ public void SetBalance(int amount)
BalanceLabel.Text = Loc.GetString("cargo-console-menu-points-amount", ("amount", amount.ToString()));
}

public void SetDeposit(int amount)
{
DepositButton.Disabled = amount <= 0;
DepositLabel.Text = Loc.GetString("cargo-console-menu-points-amount", ("amount", amount.ToString()));
}

public void SetEnabled(bool enabled)
{
WithdrawButton.Disabled = !enabled;
DepositButton.Disabled = !enabled;
}

private void OnWithdrawPressed(BaseButton.ButtonEventArgs obj)
{
WithdrawRequest?.Invoke();
}

private void OnDepositPressed(BaseButton.ButtonEventArgs obj)
{
DepositRequest?.Invoke();
}

private void OnAmountChanged(LineEdit.LineEditEventArgs args)
{
if (int.TryParse(args.Text, out var amount))
Expand Down
2 changes: 1 addition & 1 deletion Content.Server/_NF/Bank/ATMSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,9 @@ private void OnDeposit(EntityUid uid, BankATMComponent component, BankDepositMes
new BankATMMenuInterfaceState(bank.Balance, true, 0));
return;
}

private void OnCashSlotChanged(EntityUid uid, BankATMComponent component, ContainerModifiedMessage args)
{

var bankUi = _uiSystem.GetUiOrNull(uid, BankATMMenuUiKey.ATM) ?? _uiSystem.GetUiOrNull(uid, BankATMMenuUiKey.BlackMarket);

var uiUser = bankUi!.SubscribedSessions.FirstOrDefault();
Expand Down
1 change: 1 addition & 0 deletions Content.Server/_NF/Bank/BankSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Content.Shared.Preferences;
using Robust.Shared.GameStates;
using Robust.Shared.Network;
using Content.Server.Cargo.Components;

namespace Content.Server.Bank;

Expand Down
191 changes: 183 additions & 8 deletions Content.Server/_NF/Bank/StationATMSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
using Content.Shared.Bank.BUI;
using Content.Shared.Access.Systems;
using Content.Shared.Database;
using Robust.Server.GameObjects;
using Robust.Shared.Containers;
using System.Linq;

namespace Content.Server.Bank;

Expand All @@ -22,7 +23,10 @@ public sealed partial class BankSystem
private void InitializeStationATM()
{
SubscribeLocalEvent<StationBankATMComponent, StationBankWithdrawMessage>(OnWithdraw);
SubscribeLocalEvent<StationBankATMComponent, StationBankDepositMessage>(OnDeposit);
SubscribeLocalEvent<StationBankATMComponent, BoundUIOpenedEvent>(OnATMUIOpen);
SubscribeLocalEvent<StationBankATMComponent, EntInsertedIntoContainerMessage>(OnCashSlotChanged);
SubscribeLocalEvent<StationBankATMComponent, EntRemovedFromContainerMessage>(OnCashSlotChanged);
}

private void OnWithdraw(EntityUid uid, StationBankATMComponent component, StationBankWithdrawMessage args)
Expand All @@ -36,14 +40,15 @@ private void OnWithdraw(EntityUid uid, StationBankATMComponent component, Statio
var station = _station.GetOwningStation(uid);
// check for a bank account

GetInsertedCashAmount(component, out var deposit);

if (!TryComp<StationBankAccountComponent>(station, out var stationBank))
{
_log.Info($"station {station} has no bank account");
ConsolePopup(args.Session, Loc.GetString("bank-atm-menu-no-bank"));
PlayDenySound(uid, component);
_uiSystem.SetUiState(bui,
new StationBankATMMenuInterfaceState(0, false));
new StationBankATMMenuInterfaceState(0, false, deposit));
return;
}

Expand All @@ -53,7 +58,7 @@ private void OnWithdraw(EntityUid uid, StationBankATMComponent component, Statio
ConsolePopup(args.Session, Loc.GetString("station-bank-unauthorized"));
PlayDenySound(uid, component);
_uiSystem.SetUiState(bui,
new StationBankATMMenuInterfaceState(stationBank.Balance, false));
new StationBankATMMenuInterfaceState(stationBank.Balance, false, deposit));
return;
}

Expand All @@ -62,7 +67,7 @@ private void OnWithdraw(EntityUid uid, StationBankATMComponent component, Statio
ConsolePopup(args.Session, Loc.GetString("station-bank-requires-reason"));
PlayDenySound(uid, component);
_uiSystem.SetUiState(bui,
new StationBankATMMenuInterfaceState(stationBank.Balance, _access.IsAllowed(player, uid)));
new StationBankATMMenuInterfaceState(stationBank.Balance, _access.IsAllowed(player, uid), deposit));
return;
}

Expand All @@ -72,7 +77,7 @@ private void OnWithdraw(EntityUid uid, StationBankATMComponent component, Statio
ConsolePopup(args.Session, Loc.GetString("bank-insufficient-funds"));
PlayDenySound(uid, component);
_uiSystem.SetUiState(bui,
new StationBankATMMenuInterfaceState(stationBank.Balance, _access.IsAllowed(player, uid)));
new StationBankATMMenuInterfaceState(stationBank.Balance, _access.IsAllowed(player, uid), deposit));
return;
}

Expand All @@ -87,27 +92,197 @@ private void OnWithdraw(EntityUid uid, StationBankATMComponent component, Statio
_stackSystem.Spawn(args.Amount, stackPrototype, uid.ToCoordinates());

_uiSystem.SetUiState(bui,
new StationBankATMMenuInterfaceState(stationBank.Balance, _access.IsAllowed(player, uid)));
new StationBankATMMenuInterfaceState(stationBank.Balance, _access.IsAllowed(player, uid), deposit));
}

private void OnDeposit(EntityUid uid, StationBankATMComponent component, StationBankDepositMessage args)
{
if (args.Session.AttachedEntity is not { Valid: true } player)
return;

// to keep the window stateful
var bui = _uiSystem.GetUi(component.Owner, BankATMMenuUiKey.ATM);
var station = _station.GetOwningStation(uid);
// check for a bank account

// gets the money inside a cashslot of an ATM.
// Dynamically knows what kind of cash to look for according to BankATMComponent
GetInsertedCashAmount(component, out var deposit);

if (!TryComp<StationBankAccountComponent>(station, out var stationBank))
{
_log.Info($"station {station} has no bank account");
ConsolePopup(args.Session, Loc.GetString("bank-atm-menu-no-bank"));
PlayDenySound(uid, component);
_uiSystem.SetUiState(bui,
new StationBankATMMenuInterfaceState(0, false, deposit));
return;
}

// validating the cash slot was setup correctly in the yaml
if (component.CashSlot.ContainerSlot is not BaseContainer cashSlot)
{
_log.Info($"ATM has no cash slot");
ConsolePopup(args.Session, Loc.GetString("bank-atm-menu-no-bank"));
PlayDenySound(uid, component);
_uiSystem.SetUiState(bui,
new StationBankATMMenuInterfaceState(0, false, deposit));
return;
}

if (!_access.IsAllowed(player, uid))
{
_log.Info($"{player} tried to access stationo bank account");
ConsolePopup(args.Session, Loc.GetString("station-bank-unauthorized"));
PlayDenySound(uid, component);
_uiSystem.SetUiState(bui,
new StationBankATMMenuInterfaceState(stationBank.Balance, false, deposit));
return;
}

if (args.Description == null || args.Reason == null)
{
ConsolePopup(args.Session, Loc.GetString("station-bank-requires-reason"));
PlayDenySound(uid, component);
_uiSystem.SetUiState(bui,
new StationBankATMMenuInterfaceState(stationBank.Balance, _access.IsAllowed(player, uid), deposit));
return;
}

// validate stack prototypes
if (!TryComp<StackComponent>(component.CashSlot.ContainerSlot.ContainedEntity, out var stackComponent) ||
stackComponent.StackTypeId == null)
{
_log.Info($"ATM cash slot contains bad stack prototype");
ConsolePopup(args.Session, Loc.GetString("bank-atm-menu-wrong-cash"));
PlayDenySound(uid, component);
_uiSystem.SetUiState(bui,
new StationBankATMMenuInterfaceState(0, false, deposit));
return;
}

// and then check them against the ATM's CashType
if (_prototypeManager.Index<StackPrototype>(component.CashType) != _prototypeManager.Index<StackPrototype>(stackComponent.StackTypeId))
{
_log.Info($"{stackComponent.StackTypeId} is not {component.CashType}");
ConsolePopup(args.Session, Loc.GetString("bank-atm-menu-wrong-cash"));
PlayDenySound(uid, component);
_uiSystem.SetUiState(bui,
new StationBankATMMenuInterfaceState(0, false, deposit));
return;
}

// try to deposit the inserted cash into a player's bank acount.
if (args.Amount <= 0)
{
_log.Info($"{args.Amount} is invalid");
ConsolePopup(args.Session, Loc.GetString("bank-atm-menu-transaction-denied"));
PlayDenySound(uid, component);
return;
}

if (deposit < args.Amount)
{
_log.Info($"{args.Amount} is more then {deposit}");
ConsolePopup(args.Session, Loc.GetString("bank-insufficient-funds"));
PlayDenySound(uid, component);
return;
}

_cargo.DeductFunds(stationBank, -args.Amount);
ConsolePopup(args.Session, Loc.GetString("bank-atm-menu-deposit-successful"));
PlayConfirmSound(uid, component);
_log.Info($"{args.Session.UserId} {args.Session.Name} deposited {args.Amount}, '{args.Reason}': {args.Description}");

_adminLogger.Add(LogType.ATMUsage, LogImpact.Low, $"{ToPrettyString(player):actor} deposited {args.Amount} to station bank account. '{args.Reason}': {args.Description}");

SetInsertedCashAmount(component, args.Amount, out int leftAmount, out bool empty);

// yeet and delete the stack in the cash slot after success if its worth 0
if (empty)
_containerSystem.CleanContainer(cashSlot);

_uiSystem.SetUiState(bui,
new StationBankATMMenuInterfaceState(stationBank.Balance, _access.IsAllowed(player, uid), leftAmount));
}

private void OnCashSlotChanged(EntityUid uid, StationBankATMComponent component, ContainerModifiedMessage args)
{
GetInsertedCashAmount(component, out var deposit);
var bui = _uiSystem.GetUi(component.Owner, BankATMMenuUiKey.ATM);
var station = _station.GetOwningStation(uid);

if (!TryComp<StationBankAccountComponent>(station, out var bank))
{
return;
}

if (component.CashSlot.ContainerSlot?.ContainedEntity is not { Valid: true } cash)
{
_uiSystem.SetUiState(bui,
new StationBankATMMenuInterfaceState(bank.Balance, true, 0));
}

_uiSystem.SetUiState(bui,
new StationBankATMMenuInterfaceState(bank.Balance, true, deposit));
}

private void OnATMUIOpen(EntityUid uid, StationBankATMComponent component, BoundUIOpenedEvent args)
{
if (args.Session.AttachedEntity is not { Valid : true } player)
return;

GetInsertedCashAmount(component, out var deposit);
var bui = _uiSystem.GetUi(component.Owner, BankATMMenuUiKey.ATM);
var station = _station.GetOwningStation(uid);

if (!TryComp<StationBankAccountComponent>(station, out var stationBank))
{
_log.Info($"{station} has no bank account");
_uiSystem.SetUiState(bui,
new StationBankATMMenuInterfaceState(0, false));
new StationBankATMMenuInterfaceState(0, false, deposit));
return;
}

_uiSystem.SetUiState(bui,
new StationBankATMMenuInterfaceState(stationBank.Balance, _access.IsAllowed(player, uid)));
new StationBankATMMenuInterfaceState(stationBank.Balance, _access.IsAllowed(player, uid), deposit));
}

private void GetInsertedCashAmount(StationBankATMComponent component, out int amount)
{
amount = 0;
var cashEntity = component.CashSlot.ContainerSlot?.ContainedEntity;

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

amount = cashStack.Count;
return;
}

private void SetInsertedCashAmount(StationBankATMComponent component, int amount, out int leftAmount, out bool empty)
{
leftAmount = 0;
empty = false;
var cashEntity = component.CashSlot.ContainerSlot?.ContainedEntity;

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

int newAmount = cashStack.Count;
cashStack.Count = newAmount - amount;
leftAmount = cashStack.Count;

if (cashStack.Count <= 0)
empty = true;

return;
}

private void PlayDenySound(EntityUid uid, StationBankATMComponent component)
Expand Down
Loading

0 comments on commit d777209

Please sign in to comment.