scram implant (#23122)
* implement * fix charges * add listing * fixes * fix locale, probably all done * fix * fix of fix * move query init * cleanup * unbrokey rt
This commit is contained in:
26
Content.Server/Implants/Components/ScramImplantComponent.cs
Normal file
26
Content.Server/Implants/Components/ScramImplantComponent.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using Content.Server.Implants;
|
||||
using Robust.Shared.Audio;
|
||||
|
||||
namespace Content.Server.Implants.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Randomly teleports entity when triggered.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class ScramImplantComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Up to how far to teleport the user
|
||||
/// </summary>
|
||||
[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");
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using Content.Server.Cuffs;
|
||||
using Content.Server.Forensics;
|
||||
using Content.Server.Humanoid;
|
||||
using Content.Server.Implants.Components;
|
||||
using Content.Server.Store.Components;
|
||||
using Content.Server.Store.Systems;
|
||||
using Content.Shared.Cuffs.Components;
|
||||
@@ -8,8 +9,16 @@ using Content.Shared.Humanoid;
|
||||
using Content.Shared.Implants;
|
||||
using Content.Shared.Implants.Components;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Physics;
|
||||
using Content.Shared.Popups;
|
||||
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;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Content.Server.Implants;
|
||||
|
||||
@@ -17,18 +26,27 @@ 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!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _xform = default!;
|
||||
[Dependency] private readonly ForensicsSystem _forensicsSystem = default!;
|
||||
|
||||
private EntityQuery<PhysicsComponent> _physicsQuery;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
_physicsQuery = GetEntityQuery<PhysicsComponent>();
|
||||
|
||||
SubscribeLocalEvent<SubdermalImplantComponent, UseFreedomImplantEvent>(OnFreedomImplant);
|
||||
SubscribeLocalEvent<StoreComponent, ImplantRelayEvent<AfterInteractUsingEvent>>(OnStoreRelay);
|
||||
SubscribeLocalEvent<SubdermalImplantComponent, ActivateImplantEvent>(OnActivateImplantEvent);
|
||||
SubscribeLocalEvent<SubdermalImplantComponent, UseScramImplantEvent>(OnScramImplant);
|
||||
SubscribeLocalEvent<SubdermalImplantComponent, UseDnaScramblerImplantEvent>(OnDnaScramblerImplant);
|
||||
|
||||
}
|
||||
@@ -72,6 +90,52 @@ public sealed class SubdermalImplantSystem : SharedSubdermalImplantSystem
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnScramImplant(EntityUid uid, SubdermalImplantComponent component, UseScramImplantEvent args)
|
||||
{
|
||||
if (component.ImplantedEntity is not { } ent)
|
||||
return;
|
||||
|
||||
if (!TryComp<ScramImplantComponent>(uid, out var implant))
|
||||
return;
|
||||
|
||||
var xform = Transform(ent);
|
||||
var entityCoords = xform.Coordinates.ToMap(EntityManager);
|
||||
|
||||
// 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 distance = implant.TeleportRadius * MathF.Sqrt(_random.NextFloat()); // to get an uniform distribution
|
||||
targetCoords = entityCoords.Offset(_random.NextAngle().ToVec() * distance);
|
||||
|
||||
// prefer teleporting to grids
|
||||
if (!_mapManager.TryFindGridAt(targetCoords, out var gridUid, out var grid))
|
||||
continue;
|
||||
|
||||
// the implant user probably does not want to be in your walls
|
||||
var valid = true;
|
||||
foreach (var entity in grid.GetAnchoredEntities(targetCoords))
|
||||
{
|
||||
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)
|
||||
break;
|
||||
}
|
||||
_xform.SetWorldPosition(ent, targetCoords.Position);
|
||||
_audio.PlayPvs(implant.TeleportSound, ent);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnDnaScramblerImplant(EntityUid uid, SubdermalImplantComponent component, UseDnaScramblerImplantEvent args)
|
||||
{
|
||||
if (component.ImplantedEntity is not { } ent)
|
||||
|
||||
@@ -80,6 +80,11 @@ public sealed partial class OpenUplinkImplantEvent : InstantActionEvent
|
||||
|
||||
}
|
||||
|
||||
public sealed partial class UseScramImplantEvent : InstantActionEvent
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public sealed partial class UseDnaScramblerImplantEvent : InstantActionEvent
|
||||
{
|
||||
|
||||
|
||||
@@ -149,6 +149,9 @@ uplink-storage-implanter-desc = Hide goodies inside of yourself with new bluespa
|
||||
uplink-freedom-implanter-name = Freedom Implanter
|
||||
uplink-freedom-implanter-desc = Get away from those nasty sec officers with this three use implant!
|
||||
|
||||
uplink-scram-implanter-name = Scram Implanter
|
||||
uplink-scram-implanter-desc = A 3-use implant which teleports you within a large radius. Attempts to teleport you onto an unobstructed tile. May sometimes fail to do so. Life insurance not included.
|
||||
|
||||
uplink-dna-scrambler-implanter-name = DNA Scrambler Implanter
|
||||
uplink-dna-scrambler-implanter-desc = A single use implant that can be activated to modify your DNA and give you a completely new look.
|
||||
|
||||
|
||||
@@ -123,6 +123,22 @@
|
||||
state: icon
|
||||
event: !type:ActivateImplantEvent
|
||||
|
||||
- type: entity
|
||||
id: ActionActivateScramImplant
|
||||
name: SCRAM!
|
||||
description: Randomly teleports you within a large distance.
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: InstantAction
|
||||
charges: 2
|
||||
useDelay: 5
|
||||
itemIconStyle: BigAction
|
||||
priority: -20
|
||||
icon:
|
||||
sprite: Structures/Specific/anomaly.rsi
|
||||
state: anom4
|
||||
event: !type:UseScramImplantEvent
|
||||
|
||||
- type: entity
|
||||
id: ActionActivateDnaScramblerImplant
|
||||
name: Scramble DNA
|
||||
|
||||
@@ -555,6 +555,17 @@
|
||||
categories:
|
||||
- UplinkImplants
|
||||
|
||||
- type: listing
|
||||
id: UplinkScramImplanter
|
||||
name: uplink-scram-implanter-name
|
||||
description: uplink-scram-implanter-desc
|
||||
icon: { sprite: /Textures/Structures/Specific/anomaly.rsi, state: anom4 }
|
||||
productEntity: ScramImplanter
|
||||
cost:
|
||||
Telecrystal: 6 # it's a gamble that may kill you easily so 6 TC per 2 uses, second one more of a backup
|
||||
categories:
|
||||
- UplinkImplants
|
||||
|
||||
- type: listing
|
||||
id: UplinkDnaScramblerImplant
|
||||
name: uplink-dna-scrambler-implanter-name
|
||||
|
||||
@@ -188,6 +188,14 @@
|
||||
- type: Implanter
|
||||
implant: EmpImplant
|
||||
|
||||
- type: entity
|
||||
id: ScramImplanter
|
||||
name: scram implanter
|
||||
parent: BaseImplantOnlyImplanterSyndi
|
||||
components:
|
||||
- type: Implanter
|
||||
implant: ScramImplant
|
||||
|
||||
- type: entity
|
||||
id: DnaScramblerImplanter
|
||||
name: DNA scrambler implanter
|
||||
|
||||
@@ -177,6 +177,19 @@
|
||||
range: 1.75
|
||||
energyConsumption: 50000
|
||||
disableDuration: 10
|
||||
|
||||
- type: entity
|
||||
parent: BaseSubdermalImplant
|
||||
id: ScramImplant
|
||||
name: scram implant
|
||||
description: This implant randomly teleports the user within a large radius when activated.
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: SubdermalImplant
|
||||
implantAction: ActionActivateScramImplant
|
||||
- type: TriggerImplantAction
|
||||
- type: ScramImplant
|
||||
teleportAttempts: 10 # small amount of risk of being teleported into space and lets you teleport off shuttles
|
||||
|
||||
- type: entity
|
||||
parent: BaseSubdermalImplant
|
||||
|
||||
Reference in New Issue
Block a user