Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Station Bank Deposits #361

Merged
merged 4 commits into from
Oct 2, 2023
Merged
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
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
Loading