Skip to content

Commit

Permalink
Replace the teleportation logic on the SCRAM implant!
Browse files Browse the repository at this point in the history
Now instead of just trying to pick a random tile in range 20 times, the
scram teleportation logic now:

- Gets a list of grids in range
- Until a suitable tile is picked it picks a random grid
- From that grid it picks a random tile.
- If the tile is suitable, then it is set as the target and the user
  will be teleported there.
- Grids and tiles are randomly picked as outlined above until a valid
  tile is found, or all valid grids and tiles are exhausted.
- Should no suitable tile be found then they get teleported to the same
  position they are at. Effectively not teleporting them.
  • Loading branch information
nikthechampiongr committed Mar 25, 2024
1 parent 54dd273 commit d722f83
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 26 deletions.
6 changes: 0 additions & 6 deletions Content.Server/Implants/Components/ScramImplantComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,6 @@ public sealed partial class ScramImplantComponent : Component
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float TeleportRadius = 100f;

/// <summary>
/// How many times to check for a valid tile to teleport to
/// </summary>
[DataField, ViewVariables(VVAccess.ReadOnly)]
public int TeleportAttempts = 20;

[DataField, ViewVariables(VVAccess.ReadWrite)]
public SoundSpecifier TeleportSound = new SoundPathSpecifier("/Audio/Effects/teleport_arrival.ogg");
}
63 changes: 43 additions & 20 deletions Content.Server/Implants/SubdermalImplantSystem.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Content.Server.Cuffs;
using System.Linq;
using Content.Server.Cuffs;
using Content.Server.Forensics;
using Content.Server.Humanoid;
using Content.Server.Implants.Components;
Expand All @@ -21,6 +22,7 @@
using System.Numerics;
using Content.Shared.Movement.Pulling.Components;
using Content.Shared.Movement.Pulling.Systems;
using Robust.Shared.Map.Components;

namespace Content.Server.Implants;

Expand All @@ -37,6 +39,8 @@ public sealed class SubdermalImplantSystem : SharedSubdermalImplantSystem
[Dependency] private readonly SharedTransformSystem _xform = default!;
[Dependency] private readonly ForensicsSystem _forensicsSystem = default!;
[Dependency] private readonly PullingSystem _pullingSystem = default!;
[Dependency] private readonly EntityLookupSystem _lookupSystem = default!;
[Dependency] private readonly SharedMapSystem _mapSystem = default!;

private EntityQuery<PhysicsComponent> _physicsQuery;

Expand Down Expand Up @@ -109,35 +113,54 @@ private void OnScramImplant(EntityUid uid, SubdermalImplantComponent component,
var xform = Transform(ent);
var entityCoords = xform.Coordinates.ToMap(EntityManager, _xform);

// try to find a valid position to teleport to, teleport to whatever works if we can't
var targetCoords = new MapCoordinates();
for (var i = 0; i < implant.TeleportAttempts; i++)
var grids = _lookupSystem.GetEntitiesInRange<MapGridComponent>(entityCoords, implant.TeleportRadius).ToList();
_random.Shuffle(grids);
var targetCoords = entityCoords; // If we somehow fail to find a suitable tile then we essentially we just don't teleport.

foreach (var grid in grids)
{
var distance = implant.TeleportRadius * MathF.Sqrt(_random.NextFloat()); // to get an uniform distribution
targetCoords = entityCoords.Offset(_random.NextAngle().ToVec() * distance);
var valid = false;

// prefer teleporting to grids
if (!_mapManager.TryFindGridAt(targetCoords, out var gridUid, out var grid))
continue;
var range = (float) Math.Sqrt(implant.TeleportRadius);
var box = Box2.CenteredAround(entityCoords.Position, new Vector2(range, range));
var tilesInRange = _mapSystem.GetTilesEnumerator(grid.Owner, grid.Comp, box, false);
var tileList = new List<TileRef>();

// the implant user probably does not want to be in your walls
var valid = true;
foreach (var entity in grid.GetAnchoredEntities(targetCoords))
while (tilesInRange.MoveNext(out var tile))
{
if (!_physicsQuery.TryGetComponent(entity, out var body))
continue;
tileList.Add(tile);
}

if (body.BodyType != BodyType.Static ||
!body.Hard ||
(body.CollisionLayer & (int) CollisionGroup.Impassable) == 0)
continue;
_random.Shuffle(tileList);

valid = false;
break;
foreach (var tile in tileList)
{
valid = true;
foreach(var entity in _mapSystem.GetAnchoredEntities(grid.Owner, grid.Comp, tile.GridIndices))
{
if (!_physicsQuery.TryGetComponent(entity, out var body))
continue;

if (body.BodyType != BodyType.Static ||
!body.Hard ||
(body.CollisionLayer & (int) CollisionGroup.Impassable) == 0)
continue;

valid = false;
break;
}

if (valid)
{
targetCoords = _mapSystem.GridTileToWorld(grid.Owner, grid.Comp, tile.GridIndices);
break;
}
}

if (valid)
break;
}

_xform.SetWorldPosition(ent, targetCoords.Position);
_xform.AttachToGridOrMap(ent, xform);
_audio.PlayPvs(implant.TeleportSound, ent);
Expand Down

0 comments on commit d722f83

Please sign in to comment.