From 64ab042551cea509754cc9d785e581d21a5246cc Mon Sep 17 00:00:00 2001 From: Valtos Date: Thu, 24 Oct 2024 17:15:00 +0300 Subject: [PATCH] fix retarded code (#744) --- .../Implants/SubdermalImplantSystem.cs | 6 +- Content.Server/Stack/StackSystem.cs | 63 ++++++++++++++++--- .../Store/Systems/StoreSystem.Ui.cs | 6 +- Content.Server/Store/Systems/StoreSystem.cs | 42 ++++++++----- 4 files changed, 88 insertions(+), 29 deletions(-) diff --git a/Content.Server/Implants/SubdermalImplantSystem.cs b/Content.Server/Implants/SubdermalImplantSystem.cs index 05550e2f4b..c25cf86c34 100644 --- a/Content.Server/Implants/SubdermalImplantSystem.cs +++ b/Content.Server/Implants/SubdermalImplantSystem.cs @@ -74,14 +74,12 @@ public sealed class SubdermalImplantSystem : SharedSubdermalImplantSystem return; // same as store code, but message is only shown to yourself - args.Handled = _store.TryAddCurrency(_store.GetCurrencyValue(args.Used, currency), uid, store); - - if (!args.Handled) + if (!_store.TryAddCurrency((args.Used, currency), (uid, store))) return; + args.Handled = true; var msg = Loc.GetString("store-currency-inserted-implant", ("used", args.Used)); _popup.PopupEntity(msg, args.User, args.User); - QueueDel(args.Used); } private void OnFreedomImplant(EntityUid uid, SubdermalImplantComponent component, UseFreedomImplantEvent args) diff --git a/Content.Server/Stack/StackSystem.cs b/Content.Server/Stack/StackSystem.cs index e34592b45f..10d46eb9e2 100644 --- a/Content.Server/Stack/StackSystem.cs +++ b/Content.Server/Stack/StackSystem.cs @@ -91,19 +91,68 @@ namespace Content.Server.Stack /// public List SpawnMultiple(string entityPrototype, int amount, EntityCoordinates spawnPosition) { - var proto = _prototypeManager.Index(entityPrototype); - proto.TryGetComponent(out var stack); - var maxCountPerStack = GetMaxCount(stack); + if (amount <= 0) + { + Log.Error( + $"Attempted to spawn an invalid stack: {entityPrototype}, {amount}. Trace: {Environment.StackTrace}"); + return new(); + } + + var spawns = CalculateSpawns(entityPrototype, amount); + var spawnedEnts = new List(); + foreach (var count in spawns) + { + var entity = SpawnAtPosition(entityPrototype, spawnPosition); + spawnedEnts.Add(entity); + SetCount(entity, count); + } + + return spawnedEnts; + } + + /// + public List SpawnMultiple(string entityPrototype, int amount, EntityUid target) + { + if (amount <= 0) + { + Log.Error( + $"Attempted to spawn an invalid stack: {entityPrototype}, {amount}. Trace: {Environment.StackTrace}"); + return new(); + } + var spawns = CalculateSpawns(entityPrototype, amount); + + var spawnedEnts = new List(); + foreach (var count in spawns) + { + var entity = SpawnNextToOrDrop(entityPrototype, target); + spawnedEnts.Add(entity); + SetCount(entity, count); + } + + return spawnedEnts; + } + + /// + /// Calculates how many stacks to spawn that total up to . + /// + /// The stack to spawn. + /// The amount of pieces across all stacks. + /// The list of stack counts per entity. + private List CalculateSpawns(string entityPrototype, int amount) + { + var proto = _prototypeManager.Index(entityPrototype); + proto.TryGetComponent(out var stack, EntityManager.ComponentFactory); + var maxCountPerStack = GetMaxCount(stack); + var amounts = new List(); while (amount > 0) { - var entity = Spawn(entityPrototype, spawnPosition); - spawnedEnts.Add(entity); var countAmount = Math.Min(maxCountPerStack, amount); - SetCount(entity, countAmount); amount -= countAmount; + amounts.Add(countAmount); } - return spawnedEnts; + + return amounts; } private void OnStackAlternativeInteract(EntityUid uid, StackComponent stack, GetVerbsEvent args) diff --git a/Content.Server/Store/Systems/StoreSystem.Ui.cs b/Content.Server/Store/Systems/StoreSystem.Ui.cs index 6df2f02d40..e8f4ae3630 100644 --- a/Content.Server/Store/Systems/StoreSystem.Ui.cs +++ b/Content.Server/Store/Systems/StoreSystem.Ui.cs @@ -297,6 +297,9 @@ public sealed partial class StoreSystem /// private void OnRequestWithdraw(EntityUid uid, StoreComponent component, StoreRequestWithdrawMessage msg) { + if (msg.Amount <= 0) + return; + //make sure we have enough cash in the bank and we actually support this currency if (!component.Balance.TryGetValue(msg.Currency, out var currentAmount) || currentAmount < msg.Amount) return; @@ -320,7 +323,8 @@ public sealed partial class StoreSystem var cashId = proto.Cash[value]; var amountToSpawn = (int) MathF.Floor((float) (amountRemaining / value)); var ents = _stack.SpawnMultiple(cashId, amountToSpawn, coordinates); - _hands.PickupOrDrop(buyer, ents.First()); + if (ents.FirstOrDefault() is {} ent) + _hands.PickupOrDrop(buyer, ent); amountRemaining -= value * amountToSpawn; } diff --git a/Content.Server/Store/Systems/StoreSystem.cs b/Content.Server/Store/Systems/StoreSystem.cs index 397ff26922..0c4bccd0f1 100644 --- a/Content.Server/Store/Systems/StoreSystem.cs +++ b/Content.Server/Store/Systems/StoreSystem.cs @@ -94,14 +94,12 @@ public sealed partial class StoreSystem : EntitySystem if (ev.Cancelled) return; - args.Handled = TryAddCurrency(GetCurrencyValue(uid, component), args.Target.Value, store); + if (!TryAddCurrency((uid, component), (args.Target.Value, store))) + return; - if (args.Handled) - { - var msg = Loc.GetString("store-currency-inserted", ("used", args.Used), ("target", args.Target)); - _popup.PopupEntity(msg, args.Target.Value, args.User); - QueueDel(args.Used); - } + args.Handled = true; + var msg = Loc.GetString("store-currency-inserted", ("used", args.Used), ("target", args.Target)); + _popup.PopupEntity(msg, args.Target.Value, args.User); } private void OnImplantActivate(EntityUid uid, StoreComponent component, OpenUplinkImplantEvent args) @@ -123,19 +121,29 @@ public sealed partial class StoreSystem : EntitySystem } /// - /// Tries to add a currency to a store's balance. + /// Tries to add a currency to a store's balance. Note that if successful, this will consume the currency in the process. /// - /// - /// - /// The currency to add - /// The store to add it to - /// Whether or not the currency was succesfully added - [PublicAPI] - public bool TryAddCurrency(EntityUid currencyEnt, EntityUid storeEnt, StoreComponent? store = null, CurrencyComponent? currency = null) + public bool TryAddCurrency(Entity currency, Entity store) { - if (!Resolve(currencyEnt, ref currency) || !Resolve(storeEnt, ref store)) + if (!Resolve(currency.Owner, ref currency.Comp)) return false; - return TryAddCurrency(GetCurrencyValue(currencyEnt, currency), storeEnt, store); + if (!Resolve(store.Owner, ref store.Comp)) + return false; + var value = currency.Comp.Price; + if (TryComp(currency.Owner, out StackComponent? stack) && stack.Count != 1) + { + value = currency.Comp.Price + .ToDictionary(v => v.Key, p => p.Value * stack.Count); + } + if (!TryAddCurrency(value, store, store.Comp)) + return false; + // Avoid having the currency accidentally be re-used. E.g., if multiple clients try to use the currency in the + // same tick + currency.Comp.Price.Clear(); + if (stack != null) + _stack.SetCount(currency.Owner, 0, stack); + QueueDel(currency); + return true; } ///