diff --git a/Content.Shared/VendingMachines/SharedVendingMachineSystem.cs b/Content.Shared/VendingMachines/SharedVendingMachineSystem.cs index 50803e8ee2..59f8489ac6 100644 --- a/Content.Shared/VendingMachines/SharedVendingMachineSystem.cs +++ b/Content.Shared/VendingMachines/SharedVendingMachineSystem.cs @@ -7,6 +7,7 @@ using Content.Shared.Popups; using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; using Robust.Shared.Network; +using Robust.Shared.Random; namespace Content.Shared.VendingMachines; @@ -17,6 +18,7 @@ public abstract partial class SharedVendingMachineSystem : EntitySystem [Dependency] protected readonly SharedAudioSystem Audio = default!; [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; [Dependency] protected readonly SharedPopupSystem Popup = default!; + [Dependency] protected readonly IRobustRandom Randomizer = default!; public override void Initialize() { @@ -27,11 +29,11 @@ public abstract partial class SharedVendingMachineSystem : EntitySystem protected virtual void OnComponentInit(EntityUid uid, VendingMachineComponent component, ComponentInit args) { - RestockInventoryFromPrototype(uid, component); + RestockInventoryFromPrototype(uid, component, component.InitialStockQuality); } public void RestockInventoryFromPrototype(EntityUid uid, - VendingMachineComponent? component = null) + VendingMachineComponent? component = null, float restockQuality = 1f) { if (!Resolve(uid, ref component)) { @@ -41,9 +43,9 @@ public abstract partial class SharedVendingMachineSystem : EntitySystem 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); + AddInventoryFromPrototype(uid, packPrototype.StartingInventory, InventoryType.Regular, component, restockQuality); + AddInventoryFromPrototype(uid, packPrototype.EmaggedInventory, InventoryType.Emagged, component, restockQuality); + AddInventoryFromPrototype(uid, packPrototype.ContrabandInventory, InventoryType.Contraband, component, restockQuality); } /// @@ -80,7 +82,7 @@ public abstract partial class SharedVendingMachineSystem : EntitySystem private void AddInventoryFromPrototype(EntityUid uid, Dictionary? entries, InventoryType type, - VendingMachineComponent? component = null) + VendingMachineComponent? component = null, float restockQuality = 1.0f) { if (!Resolve(uid, ref component) || entries == null) { @@ -107,6 +109,15 @@ public abstract partial class SharedVendingMachineSystem : EntitySystem { if (PrototypeManager.HasIndex(id)) { + var restock = amount; + var chanceOfMissingStock = 1 - restockQuality; + + var result = Randomizer.NextFloat(0, 1); + if (result < chanceOfMissingStock) + { + restock = (uint) Math.Floor(amount * result / chanceOfMissingStock); + } + if (inventory.TryGetValue(id, out var entry)) // Prevent a machine's stock from going over three times // the prototype's normal amount. This is an arbitrary @@ -114,9 +125,9 @@ public abstract partial class SharedVendingMachineSystem : EntitySystem // 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); + entry.Amount = Math.Min(entry.Amount + amount, 3 * restock); else - inventory.Add(id, new VendingMachineInventoryEntry(type, id, amount)); + inventory.Add(id, new VendingMachineInventoryEntry(type, id, restock)); } } } diff --git a/Content.Shared/VendingMachines/VendingMachineComponent.cs b/Content.Shared/VendingMachines/VendingMachineComponent.cs index a7c8ae299a..725dc60e3b 100644 --- a/Content.Shared/VendingMachines/VendingMachineComponent.cs +++ b/Content.Shared/VendingMachines/VendingMachineComponent.cs @@ -123,6 +123,14 @@ namespace Content.Shared.VendingMachines public float DenyAccumulator = 0f; public float DispenseOnHitAccumulator = 0f; + /// + /// The quality of the stock in the vending machine on spawn. + /// Represents the percentage chance (0.0f = 0%, 1.0f = 100%) each set of items in the machine is fully-stocked. + /// If not fully stocked, the stock will have a random value between 0 (inclusive) and max stock (exclusive). + /// + [DataField] + public float InitialStockQuality = 1.0f; + /// /// While disabled by EMP it randomly ejects items /// diff --git a/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml b/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml index 4c2217e6ff..64b6b068c7 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml @@ -359,6 +359,7 @@ screenState: screen ejectDelay: 5 soundVend: /Audio/Machines/machine_vend_hot_drink.ogg + initialStockQuality: 0.33 - type: Advertise pack: HotDrinksMachineAds - type: Speech @@ -396,6 +397,7 @@ ejectState: eject-unshaded denyState: deny-unshaded ejectDelay: 1.9 + initialStockQuality: 0.33 - type: Advertise pack: RobustSoftdrinksAds - type: Speech @@ -539,6 +541,7 @@ ejectState: eject-unshaded denyState: deny-unshaded ejectDelay: 1.9 + initialStockQuality: 0.33 - type: Advertise pack: RobustSoftdrinksAds - type: Speech @@ -573,6 +576,7 @@ ejectState: eject-unshaded denyState: deny-unshaded ejectDelay: 1.9 + initialStockQuality: 0.33 - type: Advertise pack: RobustSoftdrinksAds - type: Speech @@ -607,6 +611,7 @@ ejectState: eject-unshaded denyState: deny-unshaded ejectDelay: 1.9 + initialStockQuality: 0.33 - type: Advertise pack: RobustSoftdrinksAds - type: Speech @@ -697,6 +702,7 @@ offState: off brokenState: broken normalState: normal-unshaded + initialStockQuality: 0.33 - type: Advertise pack: DiscountDansAds - type: Speech @@ -902,6 +908,7 @@ normalState: normal-unshaded ejectState: eject-unshaded denyState: deny-unshaded + initialStockQuality: 0.33 - type: Advertise pack: GetmoreChocolateCorpAds - type: Speech @@ -1045,6 +1052,7 @@ normalState: normal-unshaded ejectState: eject-unshaded denyState: deny-unshaded + initialStockQuality: 0.33 - type: Advertise pack: BodaAds - type: Speech @@ -1236,6 +1244,7 @@ offState: off brokenState: broken normalState: normal-unshaded + initialStockQuality: 0.33 - type: Advertise pack: ChangAds - type: Speech @@ -1258,7 +1267,7 @@ parent: VendingMachine id: VendingMachineSalvage name: Salvage Vendor - description: A dwarves best friend! + description: A dwarf's best friend! components: - type: VendingMachine pack: SalvageEquipmentInventory @@ -1299,6 +1308,7 @@ offState: off brokenState: broken normalState: normal-unshaded + initialStockQuality: 0.33 - type: Advertise pack: DonutAds - type: Speech @@ -1911,6 +1921,7 @@ denyState: deny-unshaded ejectDelay: 1.9 soundVend: /Audio/Items/bikehorn.ogg + initialStockQuality: 1.0 # Nobody knows how Honk does it, but their vending machines always seem well-stocked... - type: Sprite sprite: Structures/Machines/VendingMachines/happyhonk.rsi layers: