Skip to content

Commit

Permalink
Revert "Replace the teleportation logic on the SCRAM implant! (space-…
Browse files Browse the repository at this point in the history
…wizards#26429)"

This reverts commit 2ffd616.
  • Loading branch information
Ilya246 committed Sep 22, 2024
1 parent 4f5255b commit 5f23015
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 80 deletions.
6 changes: 6 additions & 0 deletions Content.Server/Implants/Components/ScramImplantComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ 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");
}
108 changes: 28 additions & 80 deletions Content.Server/Implants/SubdermalImplantSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Content.Shared.Preferences;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Random;
Expand All @@ -31,6 +32,7 @@ public sealed class SubdermalImplantSystem : SharedSubdermalImplantSystem
{
[Dependency] private readonly CuffableSystem _cuffable = default!;
[Dependency] private readonly HumanoidAppearanceSystem _humanoidAppearance = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly MetaDataSystem _metaData = default!;
[Dependency] private readonly StoreSystem _store = default!;
Expand All @@ -39,11 +41,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;
private HashSet<Entity<MapGridComponent>> _targetGrids = [];

public override void Initialize()
{
Expand Down Expand Up @@ -112,92 +111,41 @@ private void OnScramImplant(EntityUid uid, SubdermalImplantComponent component,
_pullingSystem.TryStopPull(ent, pull);

var xform = Transform(ent);
var targetCoords = SelectRandomTileInRange(xform, implant.TeleportRadius);
var entityCoords = xform.Coordinates.ToMap(EntityManager, _xform);

if (targetCoords != null)
// 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++)
{
_xform.SetCoordinates(ent, targetCoords.Value);
_audio.PlayPvs(implant.TeleportSound, ent);
args.Handled = true;
}
}

private EntityCoordinates? SelectRandomTileInRange(TransformComponent userXform, float radius)
{
var userCoords = userXform.Coordinates.ToMap(EntityManager, _xform);
_targetGrids.Clear();
_lookupSystem.GetEntitiesInRange(userCoords, radius, _targetGrids);
Entity<MapGridComponent>? targetGrid = null;

if (_targetGrids.Count == 0)
return null;

// Give preference to the grid the entity is currently on.
// This does not guarantee that if the probability fails that the owner's grid won't be picked.
// In reality the probability is higher and depends on the number of grids.
if (userXform.GridUid != null && TryComp<MapGridComponent>(userXform.GridUid, out var gridComp))
{
var userGrid = new Entity<MapGridComponent>(userXform.GridUid.Value, gridComp);
if (_random.Prob(0.5f))
{
_targetGrids.Remove(userGrid);
targetGrid = userGrid;
}
}

if (targetGrid == null)
targetGrid = _random.GetRandom().PickAndTake(_targetGrids);

EntityCoordinates? targetCoords = null;
var distance = implant.TeleportRadius * MathF.Sqrt(_random.NextFloat()); // to get an uniform distribution
targetCoords = entityCoords.Offset(_random.NextAngle().ToVec() * distance);

do
{
var valid = false;

var range = (float) Math.Sqrt(radius);
var box = Box2.CenteredAround(userCoords.Position, new Vector2(range, range));
var tilesInRange = _mapSystem.GetTilesEnumerator(targetGrid.Value.Owner, targetGrid.Value.Comp, box, false);
var tileList = new ValueList<Vector2i>();
// prefer teleporting to grids
if (!_mapManager.TryFindGridAt(targetCoords, out var gridUid, out var grid))
continue;

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

while (tileList.Count != 0)
{
var tile = tileList.RemoveSwap(_random.Next(tileList.Count));
valid = true;
foreach (var entity in _mapSystem.GetAnchoredEntities(targetGrid.Value.Owner, targetGrid.Value.Comp,
tile))
{
if (!_physicsQuery.TryGetComponent(entity, out var body))
continue;

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

valid = false;
break;
}

if (valid)
{
targetCoords = new EntityCoordinates(targetGrid.Value.Owner,
_mapSystem.TileCenterToVector(targetGrid.Value, tile));
break;
}
}
if (body.BodyType != BodyType.Static ||
!body.Hard ||
(body.CollisionLayer & (int) CollisionGroup.Impassable) == 0)
continue;

if (valid || _targetGrids.Count == 0) // if we don't do the check here then PickAndTake will blow up on an empty set.
valid = false;
break;
}
if (valid)
break;
}
_xform.SetWorldPosition(ent, targetCoords.Position);
_audio.PlayPvs(implant.TeleportSound, ent);

targetGrid = _random.GetRandom().PickAndTake(_targetGrids);
} while (true);

return targetCoords;
args.Handled = true;
}

private void OnDnaScramblerImplant(EntityUid uid, SubdermalImplantComponent component, UseDnaScramblerImplantEvent args)
Expand Down

0 comments on commit 5f23015

Please sign in to comment.