using Content.Server.Administration.Logs; using Content.Server.Cargo.Systems; using Content.Server.Storage.Components; using Content.Shared.Cargo; using Content.Shared.Database; using Content.Shared.Hands.EntitySystems; using Content.Shared.Interaction.Events; using Robust.Shared.Audio.Systems; using Robust.Shared.Map; using Robust.Shared.Random; using static Content.Shared.Storage.EntitySpawnCollection; namespace Content.Server.Storage.EntitySystems { public sealed class SpawnItemsOnUseSystem : EntitySystem { [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly IAdminLogManager _adminLogger = default!; [Dependency] private readonly SharedHandsSystem _hands = default!; [Dependency] private readonly PricingSystem _pricing = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnUseInHand); SubscribeLocalEvent(CalculatePrice, before: new[] { typeof(PricingSystem) }); } private void CalculatePrice(EntityUid uid, SpawnItemsOnUseComponent component, ref PriceCalculationEvent args) { var ungrouped = CollectOrGroups(component.Items, out var orGroups); foreach (var entry in ungrouped) { var protUid = Spawn(entry.PrototypeId, MapCoordinates.Nullspace); // Calculate the average price of the possible spawned items args.Price += _pricing.GetPrice(protUid) * entry.SpawnProbability * entry.GetAmount(getAverage: true); EntityManager.DeleteEntity(protUid); } foreach (var group in orGroups) { foreach (var entry in group.Entries) { var protUid = Spawn(entry.PrototypeId, MapCoordinates.Nullspace); // Calculate the average price of the possible spawned items args.Price += _pricing.GetPrice(protUid) * (entry.SpawnProbability / group.CumulativeProbability) * entry.GetAmount(getAverage: true); EntityManager.DeleteEntity(protUid); } } args.Handled = true; } private void OnUseInHand(EntityUid uid, SpawnItemsOnUseComponent component, UseInHandEvent args) { if (args.Handled) return; // If starting with zero or less uses, this component is a no-op if (component.Uses <= 0) return; var coords = Transform(args.User).Coordinates; var spawnEntities = GetSpawns(component.Items, _random); EntityUid? entityToPlaceInHands = null; foreach (var proto in spawnEntities) { entityToPlaceInHands = SpawnAtPosition(proto, coords); // Frontier: Spawn