From: ThunderBear2006 <100388962+ThunderBear2006@users.noreply.github.com>
Date: Wed, 3 May 2023 18:37:33 +0000 (-0400)
Subject: Ice anomaly (#15925)
X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=8951b9f26a74be670aac9cf1a34895237f4a2252;p=space-station-14.git
Ice anomaly (#15925)
Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com>
---
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 0000000000..d8b42b4c30
Binary files /dev/null and b/Resources/Textures/Structures/Specific/Anomalies/ice_anom.rsi/anom.png differ
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 0000000000..5dc920dd67
Binary files /dev/null and b/Resources/Textures/Structures/Specific/Anomalies/ice_anom.rsi/bullet.png differ
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 0000000000..b0dc064fc0
Binary files /dev/null and b/Resources/Textures/Structures/Specific/Anomalies/ice_anom.rsi/pulse.png differ