]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Tech Anomaly (#31764)
authorEd <96445749+TheShuEd@users.noreply.github.com>
Fri, 6 Sep 2024 07:24:17 +0000 (10:24 +0300)
committerGitHub <noreply@github.com>
Fri, 6 Sep 2024 07:24:17 +0000 (10:24 +0300)
* A

* B

* C

* D

* Update TechAnomalySystem.cs

* idle anim

* Update meta.json

* new animation

18 files changed:
Content.Server/Anomaly/Components/TechAnomalyComponent.cs [new file with mode: 0644]
Content.Server/Anomaly/Effects/TechAnomalySystem.cs [new file with mode: 0644]
Resources/Prototypes/Entities/Markers/Spawners/Random/anomaly.yml
Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml
Resources/Prototypes/Entities/Structures/Specific/Anomaly/cores.yml
Resources/Textures/Effects/techanom_beam.rsi/beam.png [new file with mode: 0644]
Resources/Textures/Effects/techanom_beam.rsi/meta.json [new file with mode: 0644]
Resources/Textures/Structures/Specific/Anomalies/Cores/tech_core.rsi/core.png [new file with mode: 0644]
Resources/Textures/Structures/Specific/Anomalies/Cores/tech_core.rsi/meta.json [new file with mode: 0644]
Resources/Textures/Structures/Specific/Anomalies/Cores/tech_core.rsi/pulse.png [new file with mode: 0644]
Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/bg.png [new file with mode: 0644]
Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/bg_powered.png [new file with mode: 0644]
Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/meta.json [new file with mode: 0644]
Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/part1.png [new file with mode: 0644]
Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/part2.png [new file with mode: 0644]
Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/part3.png [new file with mode: 0644]
Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/part4.png [new file with mode: 0644]
Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/pulse.png [new file with mode: 0644]

diff --git a/Content.Server/Anomaly/Components/TechAnomalyComponent.cs b/Content.Server/Anomaly/Components/TechAnomalyComponent.cs
new file mode 100644 (file)
index 0000000..c15fa4f
--- /dev/null
@@ -0,0 +1,61 @@
+using Content.Server.Anomaly.Effects;
+using Content.Shared.Destructible.Thresholds;
+using Content.Shared.DeviceLinking;
+using Robust.Shared.Prototypes;
+
+namespace Content.Server.Anomaly.Components;
+
+[RegisterComponent, AutoGenerateComponentPause, Access(typeof(TechAnomalySystem))]
+public sealed partial class TechAnomalyComponent : Component
+{
+    /// <summary>
+    /// the distance at which random ports will bind to the anomaly. Scales with severity.
+    /// </summary>
+    [DataField]
+    public MinMax LinkRadius = new(5, 10);
+
+    /// <summary>
+    /// the maximum number of entities with which an anomaly is associated during pulsing. Scales with severity
+    /// </summary>
+    [DataField]
+    public MinMax LinkCountPerPulse = new(2, 8);
+
+    /// <summary>
+    /// Number of linkable pairs. when supercrit, the anomaly will link random devices in the radius to each other in pairs.
+    /// </summary>
+    [DataField]
+    public int LinkCountSupercritical = 30;
+
+    /// <summary>
+    /// port activated by pulsation of the anomaly
+    /// </summary>
+    [DataField]
+    public ProtoId<SourcePortPrototype> PulsePort = "Pulse";
+
+    /// <summary>
+    /// A port that activates every few seconds of an anomaly's lifetime
+    /// </summary>
+    [DataField]
+    public ProtoId<SourcePortPrototype> TimerPort = "Timer";
+
+    /// <summary>
+    /// Chance of emag the device, when supercrit
+    /// </summary>
+    [DataField]
+    public float EmagSupercritProbability = 0.4f;
+
+    /// <summary>
+    /// A prototype beam shot into devices when pulsed
+    /// </summary>
+    [DataField]
+    public EntProtoId LinkBeamProto = "AnomalyTechBeam";
+
+    /// <summary>
+    /// time until the next activation of the timer ports
+    /// </summary>
+    [DataField, AutoPausedField]
+    public TimeSpan NextTimer = TimeSpan.Zero;
+
+    [DataField]
+    public float TimerFrequency = 3f;
+}
diff --git a/Content.Server/Anomaly/Effects/TechAnomalySystem.cs b/Content.Server/Anomaly/Effects/TechAnomalySystem.cs
new file mode 100644 (file)
index 0000000..6317493
--- /dev/null
@@ -0,0 +1,125 @@
+using Content.Server.Anomaly.Components;
+using Content.Server.Beam;
+using Content.Server.DeviceLinking.Systems;
+using Content.Shared.Anomaly.Components;
+using Content.Shared.DeviceLinking;
+using Content.Shared.Emag.Systems;
+using Robust.Shared.Random;
+using Robust.Shared.Timing;
+
+namespace Content.Server.Anomaly.Effects;
+
+public sealed class TechAnomalySystem : EntitySystem
+{
+    [Dependency] private readonly DeviceLinkSystem _signal = default!;
+    [Dependency] private readonly EntityLookupSystem _lookup = default!;
+    [Dependency] private readonly IRobustRandom _random = default!;
+    [Dependency] private readonly BeamSystem _beam = default!;
+    [Dependency] private readonly IGameTiming _timing = default!;
+    [Dependency] private readonly EmagSystem _emag = default!;
+
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<TechAnomalyComponent, AnomalyPulseEvent>(OnPulse);
+        SubscribeLocalEvent<TechAnomalyComponent, AnomalySupercriticalEvent>(OnSupercritical);
+        SubscribeLocalEvent<TechAnomalyComponent, AnomalyStabilityChangedEvent>(OnStabilityChanged);
+    }
+
+    public override void Update(float frameTime)
+    {
+        base.Update(frameTime);
+
+        var query = EntityQueryEnumerator<TechAnomalyComponent, AnomalyComponent>();
+        while (query.MoveNext(out var uid, out var tech, out var anom))
+        {
+            if (_timing.CurTime < tech.NextTimer)
+                return;
+
+            tech.NextTimer = _timing.CurTime + TimeSpan.FromSeconds(tech.TimerFrequency * anom.Stability);
+
+            _signal.InvokePort(uid, tech.TimerPort);
+        }
+    }
+
+    private void OnStabilityChanged(Entity<TechAnomalyComponent> tech, ref AnomalyStabilityChangedEvent args)
+    {
+        var links = MathHelper.Lerp(tech.Comp.LinkCountPerPulse.Min, tech.Comp.LinkCountPerPulse.Max, args.Severity);
+        CreateNewRandomLink(tech, (int)links);
+    }
+
+    private void CreateNewRandomLink(Entity<TechAnomalyComponent> tech, int count)
+    {
+        if (!TryComp<AnomalyComponent>(tech, out var anomaly))
+            return;
+        if (!TryComp<DeviceLinkSourceComponent>(tech, out var sourceComp))
+            return;
+
+        var range = MathHelper.Lerp(tech.Comp.LinkRadius.Min, tech.Comp.LinkRadius.Max, anomaly.Severity);
+
+        var devices = _lookup.GetEntitiesInRange<DeviceLinkSinkComponent>(Transform(tech).Coordinates, range);
+        if (devices.Count < 1)
+            return;
+        
+        for (var i = 0; i < count; i++)
+        {
+            var device = _random.Pick(devices);
+            CreateNewLink(tech, (tech, sourceComp), device);
+        }
+    }
+
+    private void CreateNewLink(Entity<TechAnomalyComponent> tech, Entity<DeviceLinkSourceComponent> source, Entity<DeviceLinkSinkComponent> target)
+    {
+        var sourcePort = _random.Pick(source.Comp.Ports);
+        var sinkPort = _random.Pick(target.Comp.Ports);
+
+        _signal.SaveLinks(null, source, target,new()
+        {
+            (sourcePort, sinkPort),
+        });
+        _beam.TryCreateBeam(source, target, tech.Comp.LinkBeamProto);
+    }
+
+    private void OnSupercritical(Entity<TechAnomalyComponent> tech, ref AnomalySupercriticalEvent args)
+    {
+        // We remove the component so that the anomaly does not bind itself to other devices before self destroy.
+        RemComp<DeviceLinkSourceComponent>(tech);
+
+        var sources =
+            _lookup.GetEntitiesInRange<DeviceLinkSourceComponent>(Transform(tech).Coordinates,
+                tech.Comp.LinkRadius.Max);
+
+        var sinks =
+            _lookup.GetEntitiesInRange<DeviceLinkSinkComponent>(Transform(tech).Coordinates,
+                tech.Comp.LinkRadius.Max);
+
+        for (var i = 0; i < tech.Comp.LinkCountSupercritical; i++)
+        {
+            if (sources.Count < 1)
+                return;
+
+            if (sinks.Count < 1)
+                return;
+
+            var source = _random.Pick(sources);
+            sources.Remove(source);
+
+            var sink = _random.Pick(sinks);
+            sinks.Remove(sink);
+
+            if (_random.Prob(tech.Comp.EmagSupercritProbability))
+            {
+                _emag.DoEmagEffect(tech, source);
+                _emag.DoEmagEffect(tech, sink);
+            }
+
+            CreateNewLink(tech, source, sink);
+        }
+    }
+
+    private void OnPulse(Entity<TechAnomalyComponent> tech, ref AnomalyPulseEvent args)
+    {
+        _signal.InvokePort(tech, tech.Comp.PulsePort);
+    }
+}
index d4edbe9fc06d4682aa5b87f0558d8d6f39cfe4b0..5a9360e652d00573bed67e2651cffb2c497646f5 100644 (file)
@@ -20,6 +20,7 @@
     - AnomalyLiquid
     - AnomalyFlora
     - AnomalyShadow
+    - AnomalyTech
     chance: 1
     offset: 0.15 # not to put it higher. The anomaly sychnronizer looks for anomalies within this radius, and if the radius is higher, the anomaly can be attracted from a neighboring tile.
 
index a16aaaabbbe3770b49c4373595216102842832fb..140f3c94429555c89c0fb298e63584860336ab4b 100644 (file)
     damage:
       types:
         Cold: 10
+
+- type: entity
+  id: AnomalyTech
+  parent: BaseAnomaly
+  suffix: Tech
+  components:
+  - type: Sprite
+    sprite: Structures/Specific/Anomalies/tech_anom.rsi
+    layers:
+    - state: bg
+      map: ["enum.AnomalyVisualLayers.Base"]
+    - state: bg_powered
+      map: ["enum.AnomalyVisualLayers.Animated"]
+      visible: false
+      shader: unshaded
+    - state: part1
+    - state: part2
+    - state: part3
+    - state: part4
+  - type: PointLight
+    radius: 6.5
+    energy: 3.5
+    color: "#56c1e8"
+  - type: Anomaly
+    corePrototype: AnomalyCoreTech
+    coreInertPrototype: AnomalyCoreTechInert
+    minPulseLength: 60
+    maxPulseLength: 120
+  - type: TechAnomaly
+  - type: DeviceLinkSource
+    ports:
+      - Pulse
+      - Timer
+
+- type: entity
+  id: AnomalyTechBeam
+  categories: [ HideSpawnMenu ]
+  components:
+  - type: Sprite
+    sprite: /Textures/Effects/techanom_beam.rsi
+    drawdepth: Effects
+    layers:
+    - state: beam
+      shader: unshaded
+      color: "#21c4ff"
+  - type: Physics
+    canCollide: false
+  - type: PointLight
+    enabled: true
+    color: "#4080FF"
+    radius: 3.5
+    softness: 1
+    autoRot: true
+    castShadows: false
+  - type: Beam
+  - type: TimedDespawn
+    lifetime: 2.3
+  - type: Tag
+    tags:
+      - HideContextMenu
\ No newline at end of file
index 97f4488fd4793135473391e65c1884daad6a25f6..71065a8e3d50de979f57dd2e9fd28a11492ab915 100644 (file)
     color: "#793a80"
     castShadows: false
 
+- type: entity
+  parent: BaseAnomalyCore
+  id: AnomalyCoreTech
+  suffix: Tech
+  components:
+  - type: Sprite
+    sprite: Structures/Specific/Anomalies/Cores/tech_core.rsi
+  - type: PointLight
+    radius: 1.5
+    energy: 2.0
+    color: "#56c1e8"
+    castShadows: false
+
 # Inert cores
 
 - type: entity
     energy: 2.0
     color: "#793a80"
     castShadows: false
+
+- type: entity
+  parent: BaseAnomalyInertCore
+  id: AnomalyCoreTechInert
+  suffix: Tech, Inert
+  components:
+  - type: Sprite
+    sprite: Structures/Specific/Anomalies/Cores/tech_core.rsi
+  - type: PointLight
+    radius: 1.5
+    energy: 2.0
+    color: "#56c1e8"
+    castShadows: false
diff --git a/Resources/Textures/Effects/techanom_beam.rsi/beam.png b/Resources/Textures/Effects/techanom_beam.rsi/beam.png
new file mode 100644 (file)
index 0000000..9240fd5
Binary files /dev/null and b/Resources/Textures/Effects/techanom_beam.rsi/beam.png differ
diff --git a/Resources/Textures/Effects/techanom_beam.rsi/meta.json b/Resources/Textures/Effects/techanom_beam.rsi/meta.json
new file mode 100644 (file)
index 0000000..15ca5cd
--- /dev/null
@@ -0,0 +1,22 @@
+{
+  "version": 1,
+  "license": "CC0-1.0",
+  "copyright": "Created by TheShuEd (Github)",
+  "size": {
+    "x": 32,
+    "y": 32
+  },
+  "states": [
+    {
+      "name": "beam",
+      "delays": [
+        [
+          0.2,
+          0.2,
+          0.2,
+          0.2
+        ]
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/Resources/Textures/Structures/Specific/Anomalies/Cores/tech_core.rsi/core.png b/Resources/Textures/Structures/Specific/Anomalies/Cores/tech_core.rsi/core.png
new file mode 100644 (file)
index 0000000..9832fa1
Binary files /dev/null and b/Resources/Textures/Structures/Specific/Anomalies/Cores/tech_core.rsi/core.png differ
diff --git a/Resources/Textures/Structures/Specific/Anomalies/Cores/tech_core.rsi/meta.json b/Resources/Textures/Structures/Specific/Anomalies/Cores/tech_core.rsi/meta.json
new file mode 100644 (file)
index 0000000..cf761f4
--- /dev/null
@@ -0,0 +1,25 @@
+{
+  "version": 1,
+  "license": "CC0-1.0",
+  "copyright": "Created by Jaraten (github) for ss14",
+  "size": {
+    "x": 32,
+    "y": 32
+  },
+  "states": [
+    {
+      "name": "core"
+    },
+    {
+      "name": "pulse",
+      "delays": [
+        [
+          0.2,
+          0.2,
+          0.2,
+          0.2
+        ]
+      ]
+    }
+  ]
+}
diff --git a/Resources/Textures/Structures/Specific/Anomalies/Cores/tech_core.rsi/pulse.png b/Resources/Textures/Structures/Specific/Anomalies/Cores/tech_core.rsi/pulse.png
new file mode 100644 (file)
index 0000000..86fe22d
Binary files /dev/null and b/Resources/Textures/Structures/Specific/Anomalies/Cores/tech_core.rsi/pulse.png differ
diff --git a/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/bg.png b/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/bg.png
new file mode 100644 (file)
index 0000000..598abdf
Binary files /dev/null and b/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/bg.png differ
diff --git a/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/bg_powered.png b/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/bg_powered.png
new file mode 100644 (file)
index 0000000..85e04a7
Binary files /dev/null and b/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/bg_powered.png differ
diff --git a/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/meta.json b/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/meta.json
new file mode 100644 (file)
index 0000000..2636048
--- /dev/null
@@ -0,0 +1,90 @@
+{
+  "version": 1,
+  "license": "CC0-1.0",
+  "copyright": "Created by Jaraten (github) for ss14",
+  "size": {
+    "x": 48,
+    "y": 48
+  },
+  "states": [
+    {
+      "name": "bg"
+    },
+    {
+      "name": "bg_powered",
+      "delays": [
+        [
+          0.2,
+          0.2,
+          0.2,
+          0.2,
+          0.2,
+          0.2
+        ]
+      ]
+    },
+    {
+      "name": "part1",
+      "delays": [
+        [
+          1.8,
+          0.2,
+          0.8,
+          0.4,
+          0.2,
+          0.3
+        ]
+      ]
+    },
+    {
+      "name": "part2",
+      "delays": [
+        [
+          1.1,
+          0.1,
+          0.8,
+          0.5,
+          0.2,
+          0.1
+        ]
+      ]
+    },
+    {
+      "name": "part3",
+      "delays": [
+        [
+          1.5,
+          0.5,
+          0.5,
+          0.1,
+          0.5,
+          0.1
+        ]
+      ]
+    },
+    {
+      "name": "part4",
+      "delays": [
+        [
+          1.8,
+          0.1,
+          0.9,
+          0.4,
+          1.0,
+          0.4
+        ]
+      ]
+    },
+    {
+      "name": "pulse",
+      "delays": [
+        [
+          0.2,
+          0.2,
+          0.2,
+          0.2
+        ]
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/part1.png b/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/part1.png
new file mode 100644 (file)
index 0000000..48a3e66
Binary files /dev/null and b/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/part1.png differ
diff --git a/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/part2.png b/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/part2.png
new file mode 100644 (file)
index 0000000..be72368
Binary files /dev/null and b/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/part2.png differ
diff --git a/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/part3.png b/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/part3.png
new file mode 100644 (file)
index 0000000..184d0ea
Binary files /dev/null and b/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/part3.png differ
diff --git a/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/part4.png b/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/part4.png
new file mode 100644 (file)
index 0000000..028d788
Binary files /dev/null and b/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/part4.png differ
diff --git a/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/pulse.png b/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/pulse.png
new file mode 100644 (file)
index 0000000..9524b7e
Binary files /dev/null and b/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/pulse.png differ