Skip to content

Commit

Permalink
Anomalous infections (#31876)
Browse files Browse the repository at this point in the history
* inner anomaly

* anomaly pulse action

* test anom mine

* Update anomalies.yml

* fix action cooldown

* pyro_eyes

* clientsystem

* experiments

* blya

* some telegraphy

* shock eyes!

* shadow eyes

* separate files

* frosty eyes

* fix

* flora eyes

* bluespace eyes

* flesh eyes

* redoing injction

* auto add layers

* пипяу

* new injector component

* stupid me

* nice marker injectors

* anomaly spawn on shutdown

* gravity anom

* dead anomaly spawning

* add VOX states

* sprite specific layers support

* technology anom infection

* auto detach anomalies that have moved away

* Update anomaly_injections.yml

* anomalyspawner integration

* rock anomaly!

* Update anomaly_injections.yml

* fix crash bug

* tag filter

* fix anom dublication spawns

* Update anomaly.yml

* Update InnerBodyAnomalyComponent.cs

* Update anomaly_injections.yml

* dont spawn anomalies after decay

* fix morb sprite, add end message

* gravity resprite

* admin logging, double injection fix

* make flesh and living light mobs friendly to anomaly hosts

* popups

* severity feedback

* sloth review

* A

* keep organs after gib

* punpun host

* sloth synchronization

* Update arachnid.yml

* increase infections spawnrate
  • Loading branch information
TheShuEd authored Sep 17, 2024
1 parent 5eaac00 commit 92be69a
Show file tree
Hide file tree
Showing 49 changed files with 1,859 additions and 25 deletions.
50 changes: 50 additions & 0 deletions Content.Client/Anomaly/Effects/ClientInnerBodySystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using Content.Shared.Anomaly.Components;
using Content.Shared.Anomaly.Effects;
using Content.Shared.Body.Components;
using Robust.Client.GameObjects;

namespace Content.Client.Anomaly.Effects;

public sealed class ClientInnerBodyAnomalySystem : SharedInnerBodyAnomalySystem
{
public override void Initialize()
{
SubscribeLocalEvent<InnerBodyAnomalyComponent, AfterAutoHandleStateEvent>(OnAfterHandleState);
SubscribeLocalEvent<InnerBodyAnomalyComponent, ComponentShutdown>(OnCompShutdown);
}

private void OnAfterHandleState(Entity<InnerBodyAnomalyComponent> ent, ref AfterAutoHandleStateEvent args)
{
if (!TryComp<SpriteComponent>(ent, out var sprite))
return;

if (ent.Comp.FallbackSprite is null)
return;

if (!sprite.LayerMapTryGet(ent.Comp.LayerMap, out var index))
index = sprite.LayerMapReserveBlank(ent.Comp.LayerMap);

if (TryComp<BodyComponent>(ent, out var body) &&
body.Prototype is not null &&
ent.Comp.SpeciesSprites.TryGetValue(body.Prototype.Value, out var speciesSprite))
{
sprite.LayerSetSprite(index, speciesSprite);
}
else
{
sprite.LayerSetSprite(index, ent.Comp.FallbackSprite);
}

sprite.LayerSetVisible(index, true);
sprite.LayerSetShader(index, "unshaded");
}

private void OnCompShutdown(Entity<InnerBodyAnomalyComponent> ent, ref ComponentShutdown args)
{
if (!TryComp<SpriteComponent>(ent, out var sprite))
return;

var index = sprite.LayerMapGet(ent.Comp.LayerMap);
sprite.LayerSetVisible(index, false);
}
}
44 changes: 39 additions & 5 deletions Content.Server/Anomaly/AnomalySynchronizerSystem.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Linq;
using System.Numerics;
using Content.Server.Anomaly.Components;
using Content.Server.DeviceLinking.Systems;
using Content.Server.Power.Components;
Expand All @@ -10,6 +11,7 @@
using Content.Shared.Power;
using Robust.Shared.Audio.Systems;
using Content.Shared.Verbs;
using Robust.Shared.Timing;

namespace Content.Server.Anomaly;

Expand All @@ -25,6 +27,7 @@ public sealed partial class AnomalySynchronizerSystem : EntitySystem
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly PowerReceiverSystem _power = default!;
[Dependency] private readonly IGameTiming _timing = default!;

public override void Initialize()
{
Expand All @@ -40,6 +43,34 @@ public override void Initialize()
SubscribeLocalEvent<AnomalyStabilityChangedEvent>(OnAnomalyStabilityChanged);
}

public override void Update(float frameTime)
{
base.Update(frameTime);

var query = EntityQueryEnumerator<AnomalySynchronizerComponent, TransformComponent>();
while (query.MoveNext(out var uid, out var sync, out var xform))
{
if (sync.ConnectedAnomaly is null)
continue;

if (_timing.CurTime < sync.NextCheckTime)
continue;
sync.NextCheckTime += sync.CheckFrequency;

if (Transform(sync.ConnectedAnomaly.Value).MapUid != Transform(uid).MapUid)
{
DisconnectFromAnomaly((uid, sync), sync.ConnectedAnomaly.Value);
continue;
}

if (!xform.Coordinates.TryDistance(EntityManager, Transform(sync.ConnectedAnomaly.Value).Coordinates, out var distance))
continue;

if (distance > sync.AttachRange)
DisconnectFromAnomaly((uid, sync), sync.ConnectedAnomaly.Value);
}
}

/// <summary>
/// If powered, try to attach a nearby anomaly.
/// </summary>
Expand Down Expand Up @@ -73,10 +104,10 @@ private void OnPowerChanged(Entity<AnomalySynchronizerComponent> ent, ref PowerC
if (args.Powered)
return;

if (!TryComp<AnomalyComponent>(ent.Comp.ConnectedAnomaly, out var anomaly))
if (ent.Comp.ConnectedAnomaly is null)
return;

DisconnectFromAnomaly(ent, anomaly);
DisconnectFromAnomaly(ent, ent.Comp.ConnectedAnomaly.Value);
}

private void OnExamined(Entity<AnomalySynchronizerComponent> ent, ref ExaminedEvent args)
Expand Down Expand Up @@ -125,13 +156,16 @@ private void ConnectToAnomaly(Entity<AnomalySynchronizerComponent> ent, Entity<A

//TODO: disconnection from the anomaly should also be triggered if the anomaly is far away from the synchronizer.
//Currently only bluespace anomaly can do this, but for some reason it is the only one that cannot be connected to the synchronizer.
private void DisconnectFromAnomaly(Entity<AnomalySynchronizerComponent> ent, AnomalyComponent anomaly)
private void DisconnectFromAnomaly(Entity<AnomalySynchronizerComponent> ent, EntityUid other)
{
if (ent.Comp.ConnectedAnomaly == null)
return;

if (ent.Comp.PulseOnDisconnect)
_anomaly.DoAnomalyPulse(ent.Comp.ConnectedAnomaly.Value, anomaly);
if (TryComp<AnomalyComponent>(other, out var anomaly))
{
if (ent.Comp.PulseOnDisconnect)
_anomaly.DoAnomalyPulse(ent.Comp.ConnectedAnomaly.Value, anomaly);
}

_popup.PopupEntity(Loc.GetString("anomaly-sync-disconnected"), ent, PopupType.Large);
_audio.PlayPvs(ent.Comp.ConnectedSound, ent);
Expand Down
6 changes: 5 additions & 1 deletion Content.Server/Anomaly/AnomalySystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public override void Initialize()
SubscribeLocalEvent<AnomalyComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<AnomalyComponent, StartCollideEvent>(OnStartCollide);


InitializeGenerator();
InitializeScanner();
InitializeVessel();
Expand Down Expand Up @@ -86,7 +87,10 @@ public void ShuffleParticlesEffect(Entity<AnomalyComponent> anomaly)

private void OnShutdown(Entity<AnomalyComponent> anomaly, ref ComponentShutdown args)
{
EndAnomaly(anomaly);
if (anomaly.Comp.CurrentBehavior is not null)
RemoveBehavior(anomaly, anomaly.Comp.CurrentBehavior.Value);

EndAnomaly(anomaly, spawnCore: false);
}

private void OnStartCollide(Entity<AnomalyComponent> anomaly, ref StartCollideEvent args)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Content.Server.Anomaly.Components;
/// <summary>
/// a device that allows you to translate anomaly activity into multitool signals.
/// </summary>
[RegisterComponent, Access(typeof(AnomalySynchronizerSystem))]
[RegisterComponent, AutoGenerateComponentPause, Access(typeof(AnomalySynchronizerSystem))]
public sealed partial class AnomalySynchronizerComponent : Component
{
/// <summary>
Expand All @@ -34,6 +34,15 @@ public sealed partial class AnomalySynchronizerComponent : Component
[DataField]
public float AttachRange = 0.4f;

/// <summary>
/// Periodicheski checks to see if the anomaly has moved to disconnect it.
/// </summary>
[DataField]
public TimeSpan CheckFrequency = TimeSpan.FromSeconds(1f);

[DataField, AutoPausedField]
public TimeSpan NextCheckTime = TimeSpan.Zero;

[DataField]
public ProtoId<SourcePortPrototype> DecayingPort = "Decaying";

Expand Down
Loading

0 comments on commit 92be69a

Please sign in to comment.