using Content.Server.Engineering.Components; using Content.Server.Stack; using Content.Shared.Coordinates.Helpers; using Content.Shared.DoAfter; using Content.Shared.Interaction; using Content.Shared.Maps; using Content.Shared.Physics; using Content.Shared.Stacks; using JetBrains.Annotations; using Robust.Shared.Map.Components; using Content.Shared.Tag; namespace Content.Server.Engineering.EntitySystems { [UsedImplicitly] public sealed class SpawnAfterInteractSystem : EntitySystem { [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; [Dependency] private readonly StackSystem _stackSystem = default!; [Dependency] private readonly TurfSystem _turfSystem = default!; [Dependency] private readonly TagSystem _tagSystem = default!; [Dependency] private readonly EntityLookupSystem _lookup = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(HandleAfterInteract); } private async void HandleAfterInteract(EntityUid uid, SpawnAfterInteractComponent component, AfterInteractEvent args) { if (!args.CanReach && !component.IgnoreDistance) return; if (string.IsNullOrEmpty(component.Prototype)) return; if (!TryComp(args.ClickLocation.GetGridUid(EntityManager), out var grid)) return; if (!grid.TryGetTileRef(args.ClickLocation, out var tileRef)) return; bool IsTileClear() { return tileRef.Tile.IsEmpty == false && !_turfSystem.IsTileBlocked(tileRef, CollisionGroup.MobMask); } if (!IsTileClear()) return; if (component.DoAfterTime > 0) { var doAfterArgs = new DoAfterArgs(EntityManager, args.User, component.DoAfterTime, new AwaitedDoAfterEvent(), null) { BreakOnMove = true, }; var result = await _doAfterSystem.WaitDoAfter(doAfterArgs); if (result != DoAfterStatus.Finished) return; } if (component.Deleted || !IsTileClear()) return; if (EntityManager.TryGetComponent(uid, out StackComponent? stackComp) && component.RemoveOnInteract && !_stackSystem.Use(uid, 1, stackComp)) { return; } EntityManager.SpawnEntity(component.Prototype, args.ClickLocation.SnapToGrid(grid)); if (_tagSystem.HasTag(uid, "Bridging")) { var loc_entities = _lookup.GetEntitiesInRange(uid, 1); foreach (var ent in loc_entities) { if (_tagSystem.HasTag(ent, "Water") && _tagSystem.HasTag(ent, "Bridgeable")) { var coordinates = Transform(ent).Coordinates; QueueDel(ent); EntityManager.SpawnEntity("FloorWaterEntity", coordinates); } } } if (component.RemoveOnInteract && stackComp == null) TryQueueDel(uid); } } }