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:
Ilya246
2024-01-04 16:38:02 +04:00
committed by GitHub
parent abbb724849
commit ca529178e2
8 changed files with 146 additions and 0 deletions

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

View File

@@ -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)

View File

@@ -80,6 +80,11 @@ public sealed partial class OpenUplinkImplantEvent : InstantActionEvent
}
public sealed partial class UseScramImplantEvent : InstantActionEvent
{
}
public sealed partial class UseDnaScramblerImplantEvent : InstantActionEvent
{

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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