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);
}
}