From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Fri, 6 Sep 2024 07:24:17 +0000 (+0300) Subject: Tech Anomaly (#31764) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=1a4d58816fc2fadc74110d74ea510b4b2576cba2;p=space-station-14.git Tech Anomaly (#31764) * A * B * C * D * Update TechAnomalySystem.cs * idle anim * Update meta.json * new animation --- diff --git a/Content.Server/Anomaly/Components/TechAnomalyComponent.cs b/Content.Server/Anomaly/Components/TechAnomalyComponent.cs new file mode 100644 index 0000000000..c15fa4fcf4 --- /dev/null +++ b/Content.Server/Anomaly/Components/TechAnomalyComponent.cs @@ -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 +{ + /// + /// the distance at which random ports will bind to the anomaly. Scales with severity. + /// + [DataField] + public MinMax LinkRadius = new(5, 10); + + /// + /// the maximum number of entities with which an anomaly is associated during pulsing. Scales with severity + /// + [DataField] + public MinMax LinkCountPerPulse = new(2, 8); + + /// + /// Number of linkable pairs. when supercrit, the anomaly will link random devices in the radius to each other in pairs. + /// + [DataField] + public int LinkCountSupercritical = 30; + + /// + /// port activated by pulsation of the anomaly + /// + [DataField] + public ProtoId PulsePort = "Pulse"; + + /// + /// A port that activates every few seconds of an anomaly's lifetime + /// + [DataField] + public ProtoId TimerPort = "Timer"; + + /// + /// Chance of emag the device, when supercrit + /// + [DataField] + public float EmagSupercritProbability = 0.4f; + + /// + /// A prototype beam shot into devices when pulsed + /// + [DataField] + public EntProtoId LinkBeamProto = "AnomalyTechBeam"; + + /// + /// time until the next activation of the timer ports + /// + [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 index 0000000000..63174930df --- /dev/null +++ b/Content.Server/Anomaly/Effects/TechAnomalySystem.cs @@ -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(OnPulse); + SubscribeLocalEvent(OnSupercritical); + SubscribeLocalEvent(OnStabilityChanged); + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = EntityQueryEnumerator(); + 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 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 tech, int count) + { + if (!TryComp(tech, out var anomaly)) + return; + if (!TryComp(tech, out var sourceComp)) + return; + + var range = MathHelper.Lerp(tech.Comp.LinkRadius.Min, tech.Comp.LinkRadius.Max, anomaly.Severity); + + var devices = _lookup.GetEntitiesInRange(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 tech, Entity source, Entity 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 tech, ref AnomalySupercriticalEvent args) + { + // We remove the component so that the anomaly does not bind itself to other devices before self destroy. + RemComp(tech); + + var sources = + _lookup.GetEntitiesInRange(Transform(tech).Coordinates, + tech.Comp.LinkRadius.Max); + + var sinks = + _lookup.GetEntitiesInRange(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 tech, ref AnomalyPulseEvent args) + { + _signal.InvokePort(tech, tech.Comp.PulsePort); + } +} diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Random/anomaly.yml b/Resources/Prototypes/Entities/Markers/Spawners/Random/anomaly.yml index d4edbe9fc0..5a9360e652 100644 --- a/Resources/Prototypes/Entities/Markers/Spawners/Random/anomaly.yml +++ b/Resources/Prototypes/Entities/Markers/Spawners/Random/anomaly.yml @@ -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. diff --git a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml index a16aaaabbb..140f3c9442 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml @@ -875,3 +875,63 @@ 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 diff --git a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/cores.yml b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/cores.yml index 97f4488fd4..71065a8e3d 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/cores.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/cores.yml @@ -168,6 +168,19 @@ 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 @@ -314,3 +327,16 @@ 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 index 0000000000..9240fd5d6d 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 index 0000000000..15ca5cd3a4 --- /dev/null +++ b/Resources/Textures/Effects/techanom_beam.rsi/meta.json @@ -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 index 0000000000..9832fa1ffd 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 index 0000000000..cf761f4471 --- /dev/null +++ b/Resources/Textures/Structures/Specific/Anomalies/Cores/tech_core.rsi/meta.json @@ -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 index 0000000000..86fe22d763 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 index 0000000000..598abdf3c8 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 index 0000000000..85e04a74f5 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 index 0000000000..26360487fd --- /dev/null +++ b/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/meta.json @@ -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 index 0000000000..48a3e66b62 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 index 0000000000..be72368587 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 index 0000000000..184d0ea8d4 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 index 0000000000..028d78890f 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 index 0000000000..9524b7e344 Binary files /dev/null and b/Resources/Textures/Structures/Specific/Anomalies/tech_anom.rsi/pulse.png differ