using System.Numerics; using Content.Server.Xenoarchaeology.Artifact.XAE.Components; using Content.Shared.Mind.Components; using Content.Shared.Mobs.Components; using Content.Shared.Teleportation.Systems; using Content.Shared.Xenoarchaeology.Artifact; using Content.Shared.Xenoarchaeology.Artifact.XAE; using Robust.Shared.Collections; using Robust.Shared.Containers; using Robust.Shared.Random; using Robust.Shared.Timing; using Content.Shared.Tiles; // Frontier namespace Content.Server.Xenoarchaeology.Artifact.XAE; /// /// System for xeno artifact effect that creates temporary portal between places on station. /// public sealed class XAEPortalSystem : BaseXAESystem { [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly LinkedEntitySystem _link = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly SharedContainerSystem _container = default!; [Dependency] private readonly IGameTiming _timing = default!; /// protected override void OnActivated(Entity ent, ref XenoArtifactNodeActivatedEvent args) { if (!_timing.IsFirstTimePredicted) return; var entXform = Transform(ent); // Frontier var map = entXform.MapID; // Frontier: Transform(ent)(); var mindQuery = EntityQueryEnumerator(); while (mindQuery.MoveNext(out var uid, out var mc, out _, out var xform, out var meta)) { // check if the MindContainer has a Mind and if the entity is not in a container (this also auto excludes AI) and if they are on the same map if (mc.HasMind && !_container.IsEntityOrParentInContainer(uid, meta: meta, xform: xform) && xform.MapID == map) { // Frontier: ensure range check (don't teleport people from across the map or off of protected grids) if (TryComp(xform.GridUid, out ProtectedGridComponent? grid) && grid.PreventArtifactTriggers) continue; if (Vector2.Distance(_transform.GetMapCoordinates(uid, xform).Position, entPosition) > ent.Comp.MaxRange) continue; // End Frontier: ensure range check (don't teleport people from across the map or off of protected grids) validMinds.Add(uid); } } // this would only be 0 if there were a station full of AIs and no one else, in that case just stop this function if (validMinds.Count == 0) return; if(!TrySpawnNextTo(ent.Comp.PortalProto, args.Artifact, out var firstPortal)) return; var target = _random.Pick(validMinds); if(!TrySpawnNextTo(ent.Comp.PortalProto, target, out var secondPortal)) return; // Manual position swapping, because the portal that opens doesn't trigger a collision, and doesn't teleport targets the first time. _transform.SwapPositions(target, args.Artifact.Owner); _link.TryLink(firstPortal.Value, secondPortal.Value, true); } }