From 8951b9f26a74be670aac9cf1a34895237f4a2252 Mon Sep 17 00:00:00 2001
From: ThunderBear2006 <100388962+ThunderBear2006@users.noreply.github.com>
Date: Wed, 3 May 2023 14:37:33 -0400
Subject: [PATCH] Ice anomaly (#15925)
Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com>
---
.../Components/ExplosionAnomalyComponent.cs | 32 ++++++
.../Components/GasProducerAnomalyComponent.cs | 40 ++++++++
.../Components/ProjectileAnomalyComponent.cs | 38 ++++++++
.../TempAffectingAnomalyComponent.cs | 34 +++++++
.../Anomaly/Effects/ExplosionAnomalySystem.cs | 30 ++++++
.../Effects/GasProducerAnomalySystem.cs | 75 +++++++++++++++
.../Effects/ProjectileAnomalySystem.cs | 91 ++++++++++++++++++
.../Effects/PyroclasticAnomalySystem.cs | 48 ---------
.../Effects/TempAffectingAnomalySystem.cs | 39 ++++++++
.../Components/PyroclasticAnomalyComponent.cs | 16 ---
.../Markers/Spawners/Random/anomaly.yml | 1 +
.../Weapons/Guns/Projectiles/magic.yml | 16 +++
.../Structures/Specific/anomalies.yml | 46 ++++++++-
Resources/Prototypes/explosion.yml | 1 +
.../Specific/Anomalies/ice_anom.rsi/anom.png | Bin 0 -> 431 bytes
.../Anomalies/ice_anom.rsi/bullet.png | Bin 0 -> 430 bytes
.../Specific/Anomalies/ice_anom.rsi/meta.json | 30 ++++++
.../Specific/Anomalies/ice_anom.rsi/pulse.png | Bin 0 -> 1571 bytes
18 files changed, 472 insertions(+), 65 deletions(-)
create mode 100644 Content.Server/Anomaly/Components/ExplosionAnomalyComponent.cs
create mode 100644 Content.Server/Anomaly/Components/GasProducerAnomalyComponent.cs
create mode 100644 Content.Server/Anomaly/Components/ProjectileAnomalyComponent.cs
create mode 100644 Content.Server/Anomaly/Components/TempAffectingAnomalyComponent.cs
create mode 100644 Content.Server/Anomaly/Effects/ExplosionAnomalySystem.cs
create mode 100644 Content.Server/Anomaly/Effects/GasProducerAnomalySystem.cs
create mode 100644 Content.Server/Anomaly/Effects/ProjectileAnomalySystem.cs
create mode 100644 Content.Server/Anomaly/Effects/TempAffectingAnomalySystem.cs
create mode 100644 Resources/Textures/Structures/Specific/Anomalies/ice_anom.rsi/anom.png
create mode 100644 Resources/Textures/Structures/Specific/Anomalies/ice_anom.rsi/bullet.png
create mode 100644 Resources/Textures/Structures/Specific/Anomalies/ice_anom.rsi/meta.json
create mode 100644 Resources/Textures/Structures/Specific/Anomalies/ice_anom.rsi/pulse.png
diff --git a/Content.Server/Anomaly/Components/ExplosionAnomalyComponent.cs b/Content.Server/Anomaly/Components/ExplosionAnomalyComponent.cs
new file mode 100644
index 0000000000..0c9f71bb2d
--- /dev/null
+++ b/Content.Server/Anomaly/Components/ExplosionAnomalyComponent.cs
@@ -0,0 +1,32 @@
+using Content.Shared.Explosion;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
+
+namespace Content.Server.Anomaly.Components;
+
+[RegisterComponent]
+public sealed class ExplosionAnomalyComponent : Component
+{
+ ///
+ /// The explosion prototype to spawn
+ ///
+ [DataField("supercriticalExplosion", required: true, customTypeSerializer: typeof(PrototypeIdSerializer))]
+ public string ExplosionPrototype = default!;
+
+ ///
+ /// The total amount of intensity an explosion can achieve
+ ///
+ [DataField("explosionTotalIntensity")]
+ public float TotalIntensity = 100f;
+
+ ///
+ /// How quickly does the explosion's power slope? Higher = smaller area and more concentrated damage, lower = larger area and more spread out damage
+ ///
+ [DataField("explosionDropoff")]
+ public float Dropoff = 10f;
+
+ ///
+ /// How much intensity can be applied per tile?
+ ///
+ [DataField("explosionMaxTileIntensity")]
+ public float MaxTileIntensity = 10f;
+}
diff --git a/Content.Server/Anomaly/Components/GasProducerAnomalyComponent.cs b/Content.Server/Anomaly/Components/GasProducerAnomalyComponent.cs
new file mode 100644
index 0000000000..078f816542
--- /dev/null
+++ b/Content.Server/Anomaly/Components/GasProducerAnomalyComponent.cs
@@ -0,0 +1,40 @@
+using Content.Shared.Atmos;
+
+namespace Content.Server.Anomaly.Components;
+
+///
+/// This component is used for handling gas producing anomalies
+///
+[RegisterComponent]
+public sealed class GasProducerAnomalyComponent : Component
+{
+ ///
+ /// Should this gas be released when an anomaly reaches max severity?
+ ///
+ [DataField("releaseOnMaxSeverity")]
+ public bool ReleaseOnMaxSeverity = false;
+
+ ///
+ /// Should this gas be released over time?
+ ///
+ [DataField("releasePassively")]
+ public bool ReleasePassively = false; // In case there are any future anomalies that release gas passively
+
+ ///
+ /// The gas to release
+ ///
+ [DataField("releasedGas", required: true)]
+ public Gas ReleasedGas = Gas.WaterVapor; // There is no entry for none, and Gas cannot be null
+
+ ///
+ /// The amount of gas released when the anomaly reaches max severity
+ ///
+ [DataField("criticalMoleAmount")]
+ public float SuperCriticalMoleAmount = 150f;
+
+ ///
+ /// The amount of gas released passively
+ ///
+ [DataField("passiveMoleAmount")]
+ public float PassiveMoleAmount = 1f;
+}
diff --git a/Content.Server/Anomaly/Components/ProjectileAnomalyComponent.cs b/Content.Server/Anomaly/Components/ProjectileAnomalyComponent.cs
new file mode 100644
index 0000000000..60354e6915
--- /dev/null
+++ b/Content.Server/Anomaly/Components/ProjectileAnomalyComponent.cs
@@ -0,0 +1,38 @@
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
+
+namespace Content.Server.Anomaly.Components;
+
+[RegisterComponent]
+public sealed class ProjectileAnomalyComponent : Component
+{
+ ///
+ /// The prototype of the projectile that will be shot when the anomaly pulses
+ ///
+ [DataField("projectilePrototype", required: true, customTypeSerializer: typeof(PrototypeIdSerializer))]
+ public string ProjectilePrototype = default!;
+
+ ///
+ /// The MAXIMUM speed can travel
+ ///
+ [DataField("maxProjectileSpeed")]
+ public float MaxProjectileSpeed = 30f;
+
+ ///
+ /// The MAXIMUM number of projectiles shot per pulse
+ ///
+ [DataField("maxProjectiles")]
+ public int MaxProjectiles = 5;
+
+ ///
+ /// The MAXIMUM range for targeting entities
+ ///
+ [DataField("projectileRange")]
+ public float ProjectileRange = 50f;
+
+ ///
+ /// Chance that a non sentient entity will be targeted, value must be between 0.0-1.0
+ ///
+ [DataField("targetNonSentientChance")]
+ public float TargetNonSentientChance = 0.5f;
+}
diff --git a/Content.Server/Anomaly/Components/TempAffectingAnomalyComponent.cs b/Content.Server/Anomaly/Components/TempAffectingAnomalyComponent.cs
new file mode 100644
index 0000000000..af97694857
--- /dev/null
+++ b/Content.Server/Anomaly/Components/TempAffectingAnomalyComponent.cs
@@ -0,0 +1,34 @@
+namespace Content.Server.Anomaly.Components;
+
+///
+/// This component is used for handling anomalies that affect the temperature
+///
+[RegisterComponent]
+public sealed class TempAffectingAnomalyComponent : Component
+{
+
+ ///
+ /// The the amount the tempurature should be modified by (negative for decreasing temp)
+ ///
+ [DataField("tempChangePerSecond")]
+ public float TempChangePerSecond = 0;
+
+ ///
+ /// The minimum amount of severity required
+ /// before the anomaly becomes a hotspot.
+ ///
+ [DataField("anomalyHotSpotThreshold")]
+ public float AnomalyHotSpotThreshold = 0.6f;
+
+ ///
+ /// The temperature of the hotspot where the anomaly is
+ ///
+ [DataField("hotspotExposeTemperature")]
+ public float HotspotExposeTemperature = 0;
+
+ ///
+ /// The volume of the hotspot where the anomaly is.
+ ///
+ [DataField("hotspotExposeVolume")]
+ public float HotspotExposeVolume = 50;
+}
diff --git a/Content.Server/Anomaly/Effects/ExplosionAnomalySystem.cs b/Content.Server/Anomaly/Effects/ExplosionAnomalySystem.cs
new file mode 100644
index 0000000000..3c881fed6a
--- /dev/null
+++ b/Content.Server/Anomaly/Effects/ExplosionAnomalySystem.cs
@@ -0,0 +1,30 @@
+using Content.Server.Explosion.EntitySystems;
+using Content.Server.Anomaly.Components;
+using Content.Shared.Anomaly.Components;
+
+namespace Content.Server.Anomaly.Effects;
+
+///
+/// This handles
+///
+public sealed class ExplosionAnomalySystem : EntitySystem
+{
+ [Dependency] private readonly ExplosionSystem _boom = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+ SubscribeLocalEvent(OnSupercritical);
+ }
+
+ private void OnSupercritical(EntityUid uid, ExplosionAnomalyComponent component, ref AnomalySupercriticalEvent args)
+ {
+ _boom.QueueExplosion(
+ uid,
+ component.ExplosionPrototype,
+ component.TotalIntensity,
+ component.Dropoff,
+ component.MaxTileIntensity
+ );
+ }
+}
diff --git a/Content.Server/Anomaly/Effects/GasProducerAnomalySystem.cs b/Content.Server/Anomaly/Effects/GasProducerAnomalySystem.cs
new file mode 100644
index 0000000000..85119d8676
--- /dev/null
+++ b/Content.Server/Anomaly/Effects/GasProducerAnomalySystem.cs
@@ -0,0 +1,75 @@
+using Content.Server.Atmos.EntitySystems;
+using Content.Server.Anomaly.Components;
+using Content.Shared.Anomaly.Components;
+using Content.Shared.Atmos;
+using Robust.Server.GameObjects;
+
+namespace Content.Server.Anomaly.Effects;
+
+///
+/// This handles and the events from
+///
+public sealed class GasProducerAnomalySystem : EntitySystem
+{
+ [Dependency] private readonly AtmosphereSystem _atmosphere = default!;
+ [Dependency] private readonly TransformSystem _xform = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+ SubscribeLocalEvent(OnSupercritical);
+ }
+
+ private void OnSupercritical(EntityUid uid, GasProducerAnomalyComponent component, ref AnomalySupercriticalEvent args)
+ {
+ if (!component.ReleaseOnMaxSeverity)
+ return;
+
+ ReleaseGas(uid, component.ReleasedGas, component.SuperCriticalMoleAmount);
+ }
+
+ public override void Update(float frameTime)
+ {
+ base.Update(frameTime);
+
+ var query = EntityQueryEnumerator();
+ while (query.MoveNext(out var ent, out var comp))
+ {
+ if (!comp.ReleasePassively)
+ continue;
+
+ // Yes this is unused code since there are no anomalies that
+ // release gas passively *yet*, but since I'm here I figured
+ // I'd save someone some time and just add it for the future
+ ReleaseGas(ent, comp.ReleasedGas, comp.PassiveMoleAmount * frameTime);
+ }
+ }
+
+ private void ReleaseGas(EntityUid uid, Gas gas, float amount)
+ {
+ var xform = Transform(uid);
+ var grid = xform.GridUid;
+ var map = xform.MapUid;
+
+ var indices = _xform.GetGridOrMapTilePosition(uid, xform);
+ var mixture = _atmosphere.GetTileMixture(grid, map, indices, true);
+
+ if (mixture == null)
+ return;
+
+ mixture.AdjustMoles(gas, amount);
+
+ if (grid is { })
+ {
+ foreach (var ind in _atmosphere.GetAdjacentTiles(grid.Value, indices))
+ {
+ var mix = _atmosphere.GetTileMixture(grid, map, ind, true);
+
+ if (mix is not { })
+ continue;
+
+ mix.AdjustMoles(gas, amount);
+ }
+ }
+ }
+}
diff --git a/Content.Server/Anomaly/Effects/ProjectileAnomalySystem.cs b/Content.Server/Anomaly/Effects/ProjectileAnomalySystem.cs
new file mode 100644
index 0000000000..06c2082045
--- /dev/null
+++ b/Content.Server/Anomaly/Effects/ProjectileAnomalySystem.cs
@@ -0,0 +1,91 @@
+using Content.Server.Anomaly.Components;
+using Content.Server.Mind.Components;
+using Content.Server.Weapons.Ranged.Systems;
+using Content.Shared.Anomaly.Components;
+using Content.Shared.Projectiles;
+using Robust.Server.GameObjects;
+using Robust.Shared.Map;
+using Robust.Shared.Random;
+
+namespace Content.Server.Anomaly.Effects;
+
+///
+/// This handles and the events from
+///
+public sealed class ProjectileAnomalySystem : EntitySystem
+{
+ [Dependency] private readonly TransformSystem _xform = default!;
+ [Dependency] private readonly EntityLookupSystem _lookup = default!;
+ [Dependency] private readonly IRobustRandom _random = default!;
+ [Dependency] private readonly IMapManager _mapManager = default!;
+ [Dependency] private readonly GunSystem _gunSystem = default!;
+
+ public override void Initialize()
+ {
+ SubscribeLocalEvent(OnPulse);
+ SubscribeLocalEvent(OnSupercritical);
+ }
+
+ private void OnPulse(EntityUid uid, ProjectileAnomalyComponent component, ref AnomalyPulseEvent args)
+ {
+ ShootProjectilesAtEntities(uid, component, args.Severity);
+ }
+
+ private void OnSupercritical(EntityUid uid, ProjectileAnomalyComponent component, ref AnomalySupercriticalEvent args)
+ {
+ ShootProjectilesAtEntities(uid, component, 1.0f);
+ }
+
+ private void ShootProjectilesAtEntities(EntityUid uid, ProjectileAnomalyComponent component, float severity)
+ {
+ var xform = Transform(uid);
+ var projectilesShot = 0;
+ var range = component.ProjectileRange * severity;
+ var mobQuery = GetEntityQuery();
+
+ foreach (var entity in _lookup.GetEntitiesInRange(uid, range, LookupFlags.Dynamic))
+ {
+ if (projectilesShot >= component.MaxProjectiles * severity)
+ return;
+
+ // Sentient entities are more likely to be shot at than non sentient
+ if (!mobQuery.HasComponent(entity) && !_random.Prob(component.TargetNonSentientChance))
+ continue;
+
+ var targetCoords = Transform(entity).Coordinates.Offset(_random.NextVector2(-1, 1));
+
+ ShootProjectile(
+ uid, component,
+ xform.Coordinates,
+ targetCoords,
+ severity
+ );
+ projectilesShot++;
+ }
+ }
+
+ private void ShootProjectile(
+ EntityUid uid,
+ ProjectileAnomalyComponent component,
+ EntityCoordinates coords,
+ EntityCoordinates targetCoords,
+ float severity
+ )
+ {
+ var mapPos = coords.ToMap(EntityManager, _xform);
+
+ var spawnCoords = _mapManager.TryFindGridAt(mapPos, out var grid)
+ ? coords.WithEntityId(grid.Owner, EntityManager)
+ : new(_mapManager.GetMapEntityId(mapPos.MapId), mapPos.Position);
+
+ var ent = Spawn(component.ProjectilePrototype, spawnCoords);
+ var direction = targetCoords.ToMapPos(EntityManager, _xform) - mapPos.Position;
+
+ if (!TryComp(ent, out var comp))
+ return;
+
+ comp.Damage *= severity;
+
+ _gunSystem.ShootProjectile(ent, direction, Vector2.Zero, uid, component.MaxProjectileSpeed * severity);
+ }
+}
diff --git a/Content.Server/Anomaly/Effects/PyroclasticAnomalySystem.cs b/Content.Server/Anomaly/Effects/PyroclasticAnomalySystem.cs
index 8144a5143c..7051dfb00f 100644
--- a/Content.Server/Anomaly/Effects/PyroclasticAnomalySystem.cs
+++ b/Content.Server/Anomaly/Effects/PyroclasticAnomalySystem.cs
@@ -3,7 +3,6 @@ using Content.Server.Atmos.EntitySystems;
using Content.Server.Interaction;
using Content.Shared.Anomaly.Components;
using Content.Shared.Anomaly.Effects.Components;
-using Robust.Server.GameObjects;
using Robust.Shared.Map;
namespace Content.Server.Anomaly.Effects;
@@ -13,11 +12,9 @@ namespace Content.Server.Anomaly.Effects;
///
public sealed class PyroclasticAnomalySystem : EntitySystem
{
- [Dependency] private readonly AtmosphereSystem _atmosphere = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!;
[Dependency] private readonly FlammableSystem _flammable = default!;
[Dependency] private readonly InteractionSystem _interaction = default!;
- [Dependency] private readonly TransformSystem _xform = default!;
///
public override void Initialize()
@@ -36,54 +33,9 @@ public sealed class PyroclasticAnomalySystem : EntitySystem
private void OnSupercritical(EntityUid uid, PyroclasticAnomalyComponent component, ref AnomalySupercriticalEvent args)
{
var xform = Transform(uid);
- var grid = xform.GridUid;
- var map = xform.MapUid;
-
- var indices = _xform.GetGridOrMapTilePosition(uid, xform);
- var mixture = _atmosphere.GetTileMixture(grid, map, indices, true);
-
- if (mixture == null)
- return;
- mixture.AdjustMoles(component.SupercriticalGas, component.SupercriticalMoleAmount);
- if (grid is { })
- {
- foreach (var ind in _atmosphere.GetAdjacentTiles(grid.Value, indices))
- {
- var mix = _atmosphere.GetTileMixture(grid, map, ind, true);
- if (mix is not { })
- continue;
-
- mix.AdjustMoles(component.SupercriticalGas, component.SupercriticalMoleAmount);
- mix.Temperature += component.HotspotExposeTemperature;
- _atmosphere.HotspotExpose(grid.Value, indices, component.HotspotExposeTemperature, mix.Volume, uid, true);
- }
- }
IgniteNearby(xform.Coordinates, 1, component.MaximumIgnitionRadius * 2);
}
- public override void Update(float frameTime)
- {
- base.Update(frameTime);
-
- var query = EntityQueryEnumerator();
- while (query.MoveNext(out var ent, out var pyro, out var anom, out var xform))
- {
- var grid = xform.GridUid;
- var map = xform.MapUid;
- var indices = _xform.GetGridOrMapTilePosition(ent, xform);
- var mixture = _atmosphere.GetTileMixture(grid, map, indices, true);
- if (mixture is { })
- {
- mixture.Temperature += pyro.HeatPerSecond * anom.Severity * frameTime;
- }
-
- if (grid != null && anom.Severity > pyro.AnomalyHotspotThreshold)
- {
- _atmosphere.HotspotExpose(grid.Value, indices, pyro.HotspotExposeTemperature, pyro.HotspotExposeVolume, ent, true);
- }
- }
- }
-
public void IgniteNearby(EntityCoordinates coordinates, float severity, float radius)
{
foreach (var flammable in _lookup.GetComponentsInRange(coordinates, radius))
diff --git a/Content.Server/Anomaly/Effects/TempAffectingAnomalySystem.cs b/Content.Server/Anomaly/Effects/TempAffectingAnomalySystem.cs
new file mode 100644
index 0000000000..f65612f98a
--- /dev/null
+++ b/Content.Server/Anomaly/Effects/TempAffectingAnomalySystem.cs
@@ -0,0 +1,39 @@
+using Content.Server.Atmos.EntitySystems;
+using Content.Server.Anomaly.Components;
+using Content.Shared.Anomaly.Components;
+using Robust.Server.GameObjects;
+
+namespace Content.Server.Anomaly.Effects;
+
+///
+/// This handles
+///
+public sealed class TempAffectingAnomalySystem : EntitySystem
+{
+ [Dependency] private readonly AtmosphereSystem _atmosphere = default!;
+ [Dependency] private readonly TransformSystem _xform = default!;
+
+ public override void Update(float frameTime)
+ {
+ base.Update(frameTime);
+
+ var query = EntityQueryEnumerator();
+ while (query.MoveNext(out var ent, out var comp, out var anom, out var xform))
+ {
+ var grid = xform.GridUid;
+ var map = xform.MapUid;
+ var indices = _xform.GetGridOrMapTilePosition(ent, xform);
+ var mixture = _atmosphere.GetTileMixture(grid, map, indices, true);
+
+ if (mixture is { })
+ {
+ mixture.Temperature += comp.TempChangePerSecond * anom.Severity * frameTime;
+ }
+
+ if (grid != null && anom.Severity > comp.AnomalyHotSpotThreshold)
+ {
+ _atmosphere.HotspotExpose(grid.Value, indices, comp.HotspotExposeTemperature, comp.HotspotExposeVolume, ent, true);
+ }
+ }
+ }
+}
diff --git a/Content.Shared/Anomaly/Effects/Components/PyroclasticAnomalyComponent.cs b/Content.Shared/Anomaly/Effects/Components/PyroclasticAnomalyComponent.cs
index 9cfa56bcc2..b474c8f090 100644
--- a/Content.Shared/Anomaly/Effects/Components/PyroclasticAnomalyComponent.cs
+++ b/Content.Shared/Anomaly/Effects/Components/PyroclasticAnomalyComponent.cs
@@ -5,15 +5,6 @@ namespace Content.Shared.Anomaly.Effects.Components;
[RegisterComponent]
public sealed class PyroclasticAnomalyComponent : Component
{
- ///
- /// The MAXIMUM amount of heat released per second.
- /// This is scaled linearly with the Severity of the anomaly.
- ///
- ///
- /// I have no clue if this is balanced.
- ///
- [DataField("heatPerSecond")]
- public float HeatPerSecond = 25;
///
/// The maximum distance from which you can be ignited by the anomaly.
@@ -21,13 +12,6 @@ public sealed class PyroclasticAnomalyComponent : Component
[DataField("maximumIgnitionRadius")]
public float MaximumIgnitionRadius = 8f;
- ///
- /// The minimum amount of severity required
- /// before the anomaly becomes a hotspot.
- ///
- [DataField("anomalyHotspotThreshold")]
- public float AnomalyHotspotThreshold = 0.6f;
-
///
/// The temperature of the hotspot where the anomaly is
///
diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Random/anomaly.yml b/Resources/Prototypes/Entities/Markers/Spawners/Random/anomaly.yml
index a21437fd77..a21ce2b13f 100644
--- a/Resources/Prototypes/Entities/Markers/Spawners/Random/anomaly.yml
+++ b/Resources/Prototypes/Entities/Markers/Spawners/Random/anomaly.yml
@@ -15,4 +15,5 @@
- AnomalyElectricity
- AnomalyFlesh
- AnomalyBluespace
+ - AnomalyIce
chance: 1
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/magic.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/magic.yml
index 94e928bdd1..829af331b6 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/magic.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/magic.yml
@@ -124,3 +124,19 @@
whitelist:
components:
- Body
+
+- type: entity
+ id: ProjectileIcicle
+ parent: BaseBulletHighVelocity
+ name: Icicle
+ description: Brrrrr.
+ components:
+ - type: Sprite
+ sprite: Structures/Specific/Anomalies/ice_anom.rsi
+ - type: Projectile
+ damage:
+ types:
+ Piercing: 20
+ Cold: 20
+ Structural: 40
+
diff --git a/Resources/Prototypes/Entities/Structures/Specific/anomalies.yml b/Resources/Prototypes/Entities/Structures/Specific/anomalies.yml
index f3d40d0d13..09bb2e6061 100644
--- a/Resources/Prototypes/Entities/Structures/Specific/anomalies.yml
+++ b/Resources/Prototypes/Entities/Structures/Specific/anomalies.yml
@@ -45,7 +45,7 @@
guides:
- AnomalousResearch
- type: EmitSoundOnSpawn
- sound:
+ sound:
path: /Audio/Effects/teleport_arrival.ogg
- type: entity
@@ -66,6 +66,12 @@
color: "#fca3c0"
castShadows: false
- type: PyroclasticAnomaly
+ - type: TempAffectingAnomaly
+ tempChangePerSecond: 25
+ hotspotExposeTemperature: 1000
+ - type: GasProducerAnomaly
+ releasedGas: 3
+ releaseOnMaxSeverity: true
- type: entity
id: AnomalyGravity
@@ -179,3 +185,41 @@
anomalyContactDamage:
types:
Radiation: 10
+
+
+- type: entity
+ id: AnomalyIce
+ parent: BaseAnomaly
+ suffix: Ice
+ components:
+ - type: Sprite
+ sprite: Structures/Specific/Anomalies/ice_anom.rsi
+ layers:
+ - state: anom
+ map: ["enum.AnomalyVisualLayers.Base"]
+ - state: pulse
+ map: ["enum.AnomalyVisualLayers.Animated"]
+ visible: false
+ - type: PointLight
+ radius: 2.0
+ energy: 2.5
+ color: "#befaff"
+ castShadows: false
+ - type: Anomaly
+ anomalyContactDamage:
+ types:
+ Cold: 10
+ - type: ExplosionAnomaly
+ supercriticalExplosion: Cryo
+ explosionTotalIntensity: 1000
+ explosionDropoff: 1
+ explosionMaxTileIntensity: 10
+ - type: ProjectileAnomaly
+ projectilePrototype: ProjectileIcicle
+ targetNonSentientChance: 0.1
+ - type: TempAffectingAnomaly
+ tempChangePerSecond: -25
+ hotspotExposeTemperature: -1000
+ - type: GasProducerAnomaly
+ releasedGas: 8 # Frezon. Please replace if there is a better way to specify this
+ releaseOnMaxSeverity: true
diff --git a/Resources/Prototypes/explosion.yml b/Resources/Prototypes/explosion.yml
index 12d3e7078a..7a196ae31e 100644
--- a/Resources/Prototypes/explosion.yml
+++ b/Resources/Prototypes/explosion.yml
@@ -64,6 +64,7 @@
types:
Cold: 5
Blunt: 2
+ Structural: 20
tileBreakChance: [0]
tileBreakIntensity: [0]
lightColor: Blue
diff --git a/Resources/Textures/Structures/Specific/Anomalies/ice_anom.rsi/anom.png b/Resources/Textures/Structures/Specific/Anomalies/ice_anom.rsi/anom.png
new file mode 100644
index 0000000000000000000000000000000000000000..d8b42b4c303935173ade5e49b078ba576aca41a4
GIT binary patch
literal 431
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^T<{+=$5ArY;~
z2@o#?5#BU)cSBSLE`OWh}xwr%l(}7rHJ*lUZ;=db&pL
z&KSQw`jaI!UG>XXio=^}|2S?`xK^xCR~of`a!yguA{7
zzh!9J*Ul*9+^E6+VC$cU{#`PTg(3l5999grS0D3Kl{lnmY!FDjad=Pd(Z<2YScr@^0?Bd&%`A1{hKIiWfUdP<=
z#r7hf1G|f5lZV3=<_XS>tP>=^t5`GK75ot3;MbuN~6@vd$@?2>@}cqo@D?
literal 0
HcmV?d00001
diff --git a/Resources/Textures/Structures/Specific/Anomalies/ice_anom.rsi/bullet.png b/Resources/Textures/Structures/Specific/Anomalies/ice_anom.rsi/bullet.png
new file mode 100644
index 0000000000000000000000000000000000000000..5dc920dd671c82a1bc1ca7a22130f244808e87fd
GIT binary patch
literal 430
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^TpHpqRs(!sS!X5sA8U-ox(+ap&18T^<+-C+(EaqL;tU@52_md_O?RokTf5_Qg2o}va*iU7lIt(#Em+B%
z@BnCygsS4sh75Lx&DR_wH0IQQmYw~ce^QjpWKkvq_XUxDVhTHrk`fXuI-F;v+@H)_
zX7l^v#>Y4NA75~LS?DFTtY?Y^)3If<&$p{GFa))1dg#Ocz#JINe5nzhX}-P;T0k}j
U5QD&_;K?A$)78&qol`;+0L2TfqyPW_
literal 0
HcmV?d00001
diff --git a/Resources/Textures/Structures/Specific/Anomalies/ice_anom.rsi/meta.json b/Resources/Textures/Structures/Specific/Anomalies/ice_anom.rsi/meta.json
new file mode 100644
index 0000000000..13d19a16d3
--- /dev/null
+++ b/Resources/Textures/Structures/Specific/Anomalies/ice_anom.rsi/meta.json
@@ -0,0 +1,30 @@
+{
+ "version": 1,
+ "license": "CC0-1.0",
+ "copyright": "Created by EmoGarbage404 (github) for ss14",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "anom"
+ },
+ {
+ "name": "pulse",
+ "delays": [
+ [
+ 0.15625,
+ 0.15625,
+ 0.15625,
+ 0.15625,
+ 0.15625,
+ 0.15625
+ ]
+ ]
+ },
+ {
+ "name": "bullet"
+ }
+ ]
+}
diff --git a/Resources/Textures/Structures/Specific/Anomalies/ice_anom.rsi/pulse.png b/Resources/Textures/Structures/Specific/Anomalies/ice_anom.rsi/pulse.png
new file mode 100644
index 0000000000000000000000000000000000000000..b0dc064fc0608d14a8f55f893d6ef7e634d53f08
GIT binary patch
literal 1571
zcmV+;2Hg3HP)Px)!%0LzRCt{2T)l1^IS`&44v6FGid2Sy06Ih67U|A!;O^RM^Z<6hSQjd;P+?*p
zAP?ZikD&S*7cK%sz!gR;z<}W@xH7h@y+Yz@c6LY($+cFp_yNH>YYx95XUOHxi~$l7
z5)!r-)5qtF#NQ)%roL5uDY4W1n*7gy{;RUHo3$(PR``GMAgnNXetBCAjt>_vKD~#0
zGApnWxO@y~J=4eM%Er%??@9;sw6>p?w?Slp>Em;CaemECruxpD^33S
z;|KWqx|Y=qk?`a4x(?sYr@F`R<0pmD0Jsy8@`{$5Uq5i-N-GgF
z9cf-9FXqR3hj>2LIi~#p_K{#!jC7vjtj{WN{{rPWQvguJOh?3MLHznv$Os^g6U=Yx
z1CdgA-laotesu@%>Ag{jlY_l;2?xVjVGqhLZy|tRQO_+$LofbvG_=;|qeD5)g4$n>
zGbgur6_ihAF!<~D`gil|ho+_JhX{RyVpc(Y@@pLcK;@HJ5x`%s1Wol@M*z3}*4yvF
z@!_gNxK+Rc%D3^Zvz*hTeJj7q^L<7FDqD|Y&-T|lVp9Ru0L)oRQI0cpdbAH;e>@q_
zKs3tHu(c0xDWYN80hi+pPLKBC%lDsF{`~S*^8=Qb?ubo0;BuV7{OS(=`0bsQzZ?zg
z(MS2YK4=+$+W~7MHnAGtZrNlGW_z%tTFdudFgb-$>|Q5U)@>xvG;|XNzn};kyCmK
zH1RK|K*h;(4#-YHCJ$U1LCvr3R$hQVM62DeQC`{sv=j6@Z3GKH*yLSC;Jg;ep96rk
z{Q#g&4))GDd1)UsIs-q^`-|-CW^o&&zAgSSw?Z+ep_{;Ol9lpHxJ9d=&?Q_KOHf?T
zI^}U4F%Hz##S~ZhMRs;$wf<{j*ZCVt^g^EaS4#9op7;|I5)u*;5)u*;dO_do;GO25
z?s9y7-~5_<+vD^5=HK}IfVa*s&JW-!wdDu+C?VnJj&;|OpP=i*PYFL)o`c8$mI@pm57Os_KMJEBC~ZJA^h}?T-tsr
zXX3Z!2hdL7%9+CTqzMW(e&!yx6=i4OZ)B*1-l*X^v;zqF6?I+{ztI5P<+Le8y8#ju
z8#*1~_@Fv0#e?5ehYvrl0}P|jz+ZqcNyK?4y!=ra8_xxzt~#NSDdG$4y&?QG!Xkv<
z+4*MvmJv8?Y<|F|KnJA-id*AC0k$JQ;7#+3(p2I81?I5$*tC{khVqtxRe!u;{*BEK
z*cE1o_JnY{clJcA6DMYKFn6s2v`Oqa~SMvC|Zh0&8P~6q{
z{J!}cO7udW_*Y8wMxOW+5)u*;wiy2d3m+pn_QB;10000EWmrjOO-%qQ0000800000
V0002eQ