using Robust.Shared.Prototypes; using System.Linq; namespace Content.Shared.VendingMachines; public abstract class SharedVendingMachineSystem : EntitySystem { [Dependency] private readonly IPrototypeManager _prototypeManager = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnComponentInit); } protected virtual void OnComponentInit(EntityUid uid, VendingMachineComponent component, ComponentInit args) { RestockInventoryFromPrototype(uid, component); } public void RestockInventoryFromPrototype(EntityUid uid, VendingMachineComponent? component = null) { if (!Resolve(uid, ref component)) { return; } if (!_prototypeManager.TryIndex(component.PackPrototypeId, out VendingMachineInventoryPrototype? packPrototype)) return; AddInventoryFromPrototype(uid, packPrototype.StartingInventory, InventoryType.Regular, component); AddInventoryFromPrototype(uid, packPrototype.EmaggedInventory, InventoryType.Emagged, component); AddInventoryFromPrototype(uid, packPrototype.ContrabandInventory, InventoryType.Contraband, component); } /// /// Returns all of the vending machine's inventory. Only includes emagged and contraband inventories if /// and /// are true respectively. /// /// /// /// public List GetAllInventory(EntityUid uid, VendingMachineComponent? component = null) { if (!Resolve(uid, ref component)) return new(); var inventory = new List(component.Inventory.Values); if (component.Emagged) inventory.AddRange(component.EmaggedInventory.Values); if (component.Contraband) inventory.AddRange(component.ContrabandInventory.Values); return inventory; } public List GetAvailableInventory(EntityUid uid, VendingMachineComponent? component = null) { if (!Resolve(uid, ref component)) return new(); return GetAllInventory(uid, component).Where(_ => _.Amount > 0).ToList(); } private void AddInventoryFromPrototype(EntityUid uid, Dictionary? entries, InventoryType type, VendingMachineComponent? component = null) { if (!Resolve(uid, ref component) || entries == null) { return; } Dictionary inventory; switch (type) { case InventoryType.Regular: inventory = component.Inventory; break; case InventoryType.Emagged: inventory = component.EmaggedInventory; break; case InventoryType.Contraband: inventory = component.ContrabandInventory; break; default: return; } foreach (var (id, amount) in entries) { if (_prototypeManager.HasIndex(id)) { if (inventory.TryGetValue(id, out VendingMachineInventoryEntry? entry)) // Prevent a machine's stock from going over three times // the prototype's normal amount. This is an arbitrary // number and meant to be a convenience for someone // restocking a machine who doesn't want to force vend out // all the items just to restock one empty slot without // losing the rest of the restock. entry.Amount = Math.Min(entry.Amount + amount, 3 * amount); else inventory.Add(id, new VendingMachineInventoryEntry(type, id, amount)); } } } }