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.Cuffs;
|
||||||
using Content.Server.Forensics;
|
using Content.Server.Forensics;
|
||||||
using Content.Server.Humanoid;
|
using Content.Server.Humanoid;
|
||||||
|
using Content.Server.Implants.Components;
|
||||||
using Content.Server.Store.Components;
|
using Content.Server.Store.Components;
|
||||||
using Content.Server.Store.Systems;
|
using Content.Server.Store.Systems;
|
||||||
using Content.Shared.Cuffs.Components;
|
using Content.Shared.Cuffs.Components;
|
||||||
@@ -8,8 +9,16 @@ using Content.Shared.Humanoid;
|
|||||||
using Content.Shared.Implants;
|
using Content.Shared.Implants;
|
||||||
using Content.Shared.Implants.Components;
|
using Content.Shared.Implants.Components;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
|
using Content.Shared.Physics;
|
||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
using Content.Shared.Preferences;
|
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;
|
namespace Content.Server.Implants;
|
||||||
|
|
||||||
@@ -17,18 +26,27 @@ public sealed class SubdermalImplantSystem : SharedSubdermalImplantSystem
|
|||||||
{
|
{
|
||||||
[Dependency] private readonly CuffableSystem _cuffable = default!;
|
[Dependency] private readonly CuffableSystem _cuffable = default!;
|
||||||
[Dependency] private readonly HumanoidAppearanceSystem _humanoidAppearance = 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 MetaDataSystem _metaData = default!;
|
||||||
[Dependency] private readonly StoreSystem _store = default!;
|
[Dependency] private readonly StoreSystem _store = default!;
|
||||||
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||||
|
[Dependency] private readonly SharedTransformSystem _xform = default!;
|
||||||
[Dependency] private readonly ForensicsSystem _forensicsSystem = default!;
|
[Dependency] private readonly ForensicsSystem _forensicsSystem = default!;
|
||||||
|
|
||||||
|
private EntityQuery<PhysicsComponent> _physicsQuery;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
|
_physicsQuery = GetEntityQuery<PhysicsComponent>();
|
||||||
|
|
||||||
SubscribeLocalEvent<SubdermalImplantComponent, UseFreedomImplantEvent>(OnFreedomImplant);
|
SubscribeLocalEvent<SubdermalImplantComponent, UseFreedomImplantEvent>(OnFreedomImplant);
|
||||||
SubscribeLocalEvent<StoreComponent, ImplantRelayEvent<AfterInteractUsingEvent>>(OnStoreRelay);
|
SubscribeLocalEvent<StoreComponent, ImplantRelayEvent<AfterInteractUsingEvent>>(OnStoreRelay);
|
||||||
SubscribeLocalEvent<SubdermalImplantComponent, ActivateImplantEvent>(OnActivateImplantEvent);
|
SubscribeLocalEvent<SubdermalImplantComponent, ActivateImplantEvent>(OnActivateImplantEvent);
|
||||||
|
SubscribeLocalEvent<SubdermalImplantComponent, UseScramImplantEvent>(OnScramImplant);
|
||||||
SubscribeLocalEvent<SubdermalImplantComponent, UseDnaScramblerImplantEvent>(OnDnaScramblerImplant);
|
SubscribeLocalEvent<SubdermalImplantComponent, UseDnaScramblerImplantEvent>(OnDnaScramblerImplant);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -72,6 +90,52 @@ public sealed class SubdermalImplantSystem : SharedSubdermalImplantSystem
|
|||||||
args.Handled = true;
|
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)
|
private void OnDnaScramblerImplant(EntityUid uid, SubdermalImplantComponent component, UseDnaScramblerImplantEvent args)
|
||||||
{
|
{
|
||||||
if (component.ImplantedEntity is not { } ent)
|
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
|
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-name = Freedom Implanter
|
||||||
uplink-freedom-implanter-desc = Get away from those nasty sec officers with this three use implant!
|
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-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.
|
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
|
state: icon
|
||||||
event: !type:ActivateImplantEvent
|
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
|
- type: entity
|
||||||
id: ActionActivateDnaScramblerImplant
|
id: ActionActivateDnaScramblerImplant
|
||||||
name: Scramble DNA
|
name: Scramble DNA
|
||||||
|
|||||||
@@ -555,6 +555,17 @@
|
|||||||
categories:
|
categories:
|
||||||
- UplinkImplants
|
- 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
|
- type: listing
|
||||||
id: UplinkDnaScramblerImplant
|
id: UplinkDnaScramblerImplant
|
||||||
name: uplink-dna-scrambler-implanter-name
|
name: uplink-dna-scrambler-implanter-name
|
||||||
|
|||||||
@@ -188,6 +188,14 @@
|
|||||||
- type: Implanter
|
- type: Implanter
|
||||||
implant: EmpImplant
|
implant: EmpImplant
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: ScramImplanter
|
||||||
|
name: scram implanter
|
||||||
|
parent: BaseImplantOnlyImplanterSyndi
|
||||||
|
components:
|
||||||
|
- type: Implanter
|
||||||
|
implant: ScramImplant
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: DnaScramblerImplanter
|
id: DnaScramblerImplanter
|
||||||
name: DNA scrambler implanter
|
name: DNA scrambler implanter
|
||||||
|
|||||||
@@ -177,6 +177,19 @@
|
|||||||
range: 1.75
|
range: 1.75
|
||||||
energyConsumption: 50000
|
energyConsumption: 50000
|
||||||
disableDuration: 10
|
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
|
- type: entity
|
||||||
parent: BaseSubdermalImplant
|
parent: BaseSubdermalImplant
|
||||||
|
|||||||
Reference in New Issue
Block a user