Skip to content

Commit

Permalink
Add a cash slot to vending machines
Browse files Browse the repository at this point in the history
  • Loading branch information
whatston3 committed Feb 6, 2025
1 parent 77a4744 commit d67574a
Show file tree
Hide file tree
Showing 11 changed files with 238 additions and 77 deletions.
26 changes: 18 additions & 8 deletions Content.Client/VendingMachines/UI/VendingMachineMenu.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,25 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
xmlns:co="clr-namespace:Content.Client.UserInterface.Controls"
SetSize="360 380"
MinSize="300 300"> <!-- Frontier: added SetSize, MinSize, remove MinHeight="210" -->
SetSize="360 400"
MinSize="300 320"> <!-- Frontier: added SetSize, MinSize, remove MinHeight="210" -->
<BoxContainer Name="MainContainer" Orientation="Vertical">
<BoxContainer Margin ="0 2 0 4" Orientation="Horizontal">
<Label Text="{Loc 'bank-atm-menu-balance-label'}"
StyleClasses="LabelKeyText" />
<Label Name="BalanceLabel"
Text="{Loc 'bank-atm-menu-no-bank'}" />
</BoxContainer>
<!-- Frontier: balance -->
<GridContainer Margin ="0 2 0 4" Columns="2" HorizontalExpand="True">
<BoxContainer Margin="4 0 2 0" Orientation="Horizontal" HorizontalExpand="True" HorizontalAlignment="Left">
<Label Text="{Loc 'bank-atm-menu-balance-label'}"
StyleClasses="LabelKeyText" />
<Label Name="BalanceLabel"
Text="{Loc 'bank-atm-menu-no-bank'}" />
</BoxContainer>
<BoxContainer Margin="2 0 4 0" Orientation="Horizontal" HorizontalExpand="True" HorizontalAlignment="Right" Name="CashSlotControls">
<Label Text="{Loc 'vending-machine-menu-cash-slot-label'}"
StyleClasses="LabelKeyText" />
<Label Name="CashSlotLabel"
Text="$0" />
</BoxContainer>
</GridContainer>
<!-- End Frontier: balance -->
<LineEdit Name="SearchBar" PlaceHolder="{Loc 'vending-machine-component-search-filter'}" HorizontalExpand="True" Margin ="4 4"/>
<co:SearchListContainer Name="VendingContents" VerticalExpand="True" Margin="4 4"/>
<!-- Footer -->
Expand Down
49 changes: 29 additions & 20 deletions Content.Client/VendingMachines/UI/VendingMachineMenu.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
using Content.Shared.Chemistry.Reagent;
using FancyWindow = Content.Client.UserInterface.Controls.FancyWindow;
using Robust.Client.UserInterface;
using Content.Client.UserInterface.Controls;
using Content.Shared.IdentityManagement;
using Robust.Client.Graphics;

Expand All @@ -23,6 +22,7 @@ public sealed partial class VendingMachineMenu : FancyWindow
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IComponentFactory _componentFactory = default!; // Frontier

private readonly Dictionary<EntProtoId, EntityUid> _dummies = [];

Expand Down Expand Up @@ -84,9 +84,10 @@ private void GenerateButton(ListData data, ListContainerButton button)
/// Populates the list of available items on the vending machine interface
/// and sets icons based on their prototypes
/// </summary>
public void Populate(List<VendingMachineInventoryEntry> inventory, float priceModifier, int balance) // Frontier: add balance
public void Populate(List<VendingMachineInventoryEntry> inventory, float priceModifier, int balance, int? cashSlotBalance) // Frontier: add balance, cashSlotBalance
{
BalanceLabel.Text = BankSystemExtensions.ToSpesoString(balance); // Frontier
UpdateBalance(balance); // Frontier
UpdateCashSlotBalance(cashSlotBalance); // Frontier

if (inventory.Count == 0 && VendingContents.Visible)
{
Expand Down Expand Up @@ -137,28 +138,29 @@ public void Populate(List<VendingMachineInventoryEntry> inventory, float priceMo
// determined dynamically by their contents/inventory), it then falls back to the default mystery
// hardcoded value of 20xMarketModifier.
var cost = 20;
if (prototype != null && prototype.TryGetComponent<StaticPriceComponent>(out var priceComponent))
if (prototype != null && prototype.TryGetComponent<StaticPriceComponent>(out var priceComponent, _componentFactory))
{
if (priceComponent.Price != 0)
{
var price = (float)priceComponent.Price;
cost = (int) (price * priceModifier);
cost = (int)(price * priceModifier);
}
else
{
if (prototype.TryGetComponent<StackPriceComponent>(out var stackPrice) && prototype.TryGetComponent<StackComponent>(out var stack))
if (prototype.TryGetComponent<StackPriceComponent>(out var stackPrice, _componentFactory)
&& prototype.TryGetComponent<StackComponent>(out var stack, _componentFactory))
{
var price = stackPrice.Price * stack.Count;
cost = (int) (price * priceModifier);
cost = (int)(price * priceModifier);
}
else
cost = (int) (cost * priceModifier);
cost = (int)(cost * priceModifier);
}
}
else
cost = (int) (cost * priceModifier);
cost = (int)(cost * priceModifier);

if (prototype != null && prototype.TryGetComponent<SolutionContainerManagerComponent>(out var priceSolutions))
if (prototype != null && prototype.TryGetComponent<SolutionContainerManagerComponent>(out var priceSolutions, _componentFactory))
{
if (priceSolutions.Solutions != null)
{
Expand All @@ -171,45 +173,45 @@ public void Populate(List<VendingMachineInventoryEntry> inventory, float priceMo
continue;

// TODO check ReagentData for price information?
var costReagent = (float) quantity * reagentProto.PricePerUnit;
cost += (int) (costReagent * priceModifier);
var costReagent = quantity.Float() * reagentProto.PricePerUnit;
cost += (int)(costReagent * priceModifier);
}
}
}
}
// End Frontier: item pricing

// Frontier: calculate vending price (this duplicates Content.Server.PricingSystem.GetVendPrice - this should be moved to Content.Shared if possible)
if (prototype != null)
{
var price = 0.0;

if (prototype.TryGetComponent<StaticPriceComponent>(out var staticComp) && staticComp.VendPrice > 0.0)
if (prototype.TryGetComponent<StaticPriceComponent>(out var staticComp, _componentFactory) && staticComp.VendPrice > 0.0)
{
price += staticComp.VendPrice;
}
else if (prototype.TryGetComponent<StackPriceComponent>(out var stackComp) && stackComp.VendPrice > 0.0)
else if (prototype.TryGetComponent<StackPriceComponent>(out var stackComp, _componentFactory) && stackComp.VendPrice > 0.0)
{
price += stackComp.VendPrice;
}

// If there is anything that explicitly sets vending price - higher OR lower, override the base.
if (price > 0.0) {
cost = (int) price;
if (price > 0.0)
{
cost = (int)price;
}
}
// End Frontier

var itemName = Identity.Name(dummy, _entityManager);
string itemText;

// New Frontiers - Unlimited vending - support items with unlimited vending stock.
// This code is licensed under AGPLv3. See AGPLv3.txt
// Frontier: unlimited vending
if (entry.Amount != uint.MaxValue)
itemText = $"[{BankSystemExtensions.ToSpesoString(cost)}] {itemName} [{entry.Amount}]";
else
itemText = $"[{BankSystemExtensions.ToSpesoString(cost)}] {itemName}";
// End of modified code
// End Frontier: item pricing
// End Frontier: unlimited vending


if (itemText.Length > longestEntry.Length)
Expand All @@ -228,6 +230,13 @@ public void UpdateBalance(int balance)
{
BalanceLabel.Text = BankSystemExtensions.ToSpesoString(balance);
}

public void UpdateCashSlotBalance(int? balance)
{
CashSlotControls.Visible = balance != null;
if (balance != null)
CashSlotLabel.Text = BankSystemExtensions.ToSpesoString(balance.Value);
}
// End Frontier

private void SetSizeAfterUpdate(int longestEntryLength, int contentCount)
Expand Down
31 changes: 22 additions & 9 deletions Content.Client/VendingMachines/VendingMachineBoundUserInterface.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using Content.Client.UserInterface.Controls;
using Content.Client.VendingMachines.UI;
using Content.Shared.VendingMachines;
using Content.Shared._NF.Bank.Components; // Frontier
using Robust.Client.UserInterface;
using Robust.Shared.Input;
using System.Linq;
using Robust.Client.GameObjects;
using Content.Shared._NF.Bank.Components; // Frontier
using Content.Shared.Containers.ItemSlots; // Frontier
using Content.Shared.Stacks; // Frontier

namespace Content.Client.VendingMachines
{
Expand All @@ -19,12 +21,14 @@ public sealed class VendingMachineBoundUserInterface : BoundUserInterface

// Frontier: market price modifier & balance
private UserInterfaceSystem _uiSystem = default!;
private IEntityManager _entMan = default!;
private ItemSlotsSystem _itemSlots = default!;

[ViewVariables]
private float _mod = 1f;
[ViewVariables]
private int _balance = 0;
[ViewVariables]
private int _cashSlotBalance = 0;
// End Frontier

public VendingMachineBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
Expand All @@ -35,13 +39,11 @@ protected override void Open()
{
base.Open();

var entMan = IoCManager.Resolve<IEntityManager>();

// Frontier: state, market modifier, balance status
_entMan = entMan;
_uiSystem = entMan.System<UserInterfaceSystem>();
_uiSystem = EntMan.System<UserInterfaceSystem>();
_itemSlots = EntMan.System<ItemSlotsSystem>();

if (entMan.TryGetComponent<MarketModifierComponent>(Owner, out var market))
if (EntMan.TryGetComponent<MarketModifierComponent>(Owner, out var market))
_mod = market.Mod;
// End Frontier

Expand All @@ -61,12 +63,23 @@ public void Refresh()
var uiUsers = _uiSystem.GetActors(Owner, UiKey);
foreach (var uiUser in uiUsers)
{
if (_entMan.TryGetComponent<BankAccountComponent>(uiUser, out var bank))
if (EntMan.TryGetComponent<BankAccountComponent>(uiUser, out var bank))
_balance = bank.Balance;
}
int? cashSlotValue = null;
if (EntMan.TryGetComponent<VendingMachineComponent>(Owner, out var vendingMachine))
{
_cashSlotBalance = vendingMachine.CashSlotBalance;
if (vendingMachine.CashSlotName != null)
cashSlotValue = _cashSlotBalance;
}
else
{
_cashSlotBalance = 0;
}
// End Frontier

_menu?.Populate(_cachedInventory, _mod, _balance); // Frontier: add _balance
_menu?.Populate(_cachedInventory, _mod, _balance, cashSlotValue); // Frontier: add _balance
}

private void OnItemSelected(GUIBoundKeyEventArgs args, ListData data)
Expand Down
21 changes: 21 additions & 0 deletions Content.Client/VendingMachines/VendingMachineSystem.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Content.Shared.VendingMachines;
using Robust.Client.Animations;
using Robust.Client.GameObjects;
using Robust.Shared.Containers;

namespace Content.Client.VendingMachines;

Expand All @@ -17,6 +18,8 @@ public override void Initialize()
SubscribeLocalEvent<VendingMachineComponent, AppearanceChangeEvent>(OnAppearanceChange);
SubscribeLocalEvent<VendingMachineComponent, AnimationCompletedEvent>(OnAnimationCompleted);
SubscribeLocalEvent<VendingMachineComponent, AfterAutoHandleStateEvent>(OnVendingAfterState);
SubscribeLocalEvent<VendingMachineComponent, EntInsertedIntoContainerMessage>(OnEntityInserted); // Frontier
SubscribeLocalEvent<VendingMachineComponent, EntRemovedFromContainerMessage>(OnEntityRemoved); // Frontier
}

private void OnVendingAfterState(EntityUid uid, VendingMachineComponent component, ref AfterAutoHandleStateEvent args)
Expand All @@ -27,6 +30,24 @@ private void OnVendingAfterState(EntityUid uid, VendingMachineComponent componen
}
}

// Frontier
private void OnEntityInserted(Entity<VendingMachineComponent> ent, ref EntInsertedIntoContainerMessage args)
{
if (_uiSystem.TryGetOpenUi<VendingMachineBoundUserInterface>(ent.Owner, VendingMachineUiKey.Key, out var bui))
{
bui.Refresh();
}
}

private void OnEntityRemoved(Entity<VendingMachineComponent> ent, ref EntRemovedFromContainerMessage args)
{
if (_uiSystem.TryGetOpenUi<VendingMachineBoundUserInterface>(ent.Owner, VendingMachineUiKey.Key, out var bui))
{
bui.Refresh();
}
}
// End Frontier

private void OnAnimationCompleted(EntityUid uid, VendingMachineComponent component, AnimationCompletedEvent args)
{
if (!TryComp<SpriteComponent>(uid, out var sprite))
Expand Down
Loading

0 comments on commit d67574a

Please sign in to comment.