]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
More anomalies (#13766)
authorNemanja <98561806+EmoGarbage404@users.noreply.github.com>
Mon, 6 Feb 2023 05:03:53 +0000 (00:03 -0500)
committerGitHub <noreply@github.com>
Mon, 6 Feb 2023 05:03:53 +0000 (01:03 -0400)
41 files changed:
Content.Client/Anomaly/AnomalySystem.cs
Content.Server/Anomaly/AnomalySystem.Generator.cs
Content.Server/Anomaly/AnomalySystem.cs
Content.Server/Anomaly/Effects/ElectricityAnomalySystem.cs
Content.Server/Anomaly/Effects/FleshAnomalySystem.cs [new file with mode: 0644]
Content.Server/Anomaly/Effects/PyroclasticAnomalySystem.cs
Content.Server/Maps/TileSystem.cs
Content.Shared/Anomaly/Components/AnomalyComponent.cs
Content.Shared/Anomaly/Effects/BluespaceAnomalySystem.cs [new file with mode: 0644]
Content.Shared/Anomaly/Effects/Components/BluespaceAnomalyComponent.cs [new file with mode: 0644]
Content.Shared/Anomaly/Effects/Components/ElectricityAnomalyComponent.cs
Content.Shared/Anomaly/Effects/Components/FleshAnomalyComponent.cs [new file with mode: 0644]
Content.Shared/Anomaly/Effects/Components/GravityAnomalyComponent.cs
Content.Shared/Anomaly/Effects/Components/PyroclasticAnomalyComponent.cs
Content.Shared/Anomaly/Effects/SharedGravityAnomalySystem.cs
Content.Shared/Anomaly/SharedAnomalySystem.cs
Resources/Locale/en-US/tiles/tiles.ftl
Resources/Prototypes/Entities/Markers/Spawners/Random/anomaly.yml
Resources/Prototypes/Entities/Mobs/NPCs/flesh.yml [new file with mode: 0644]
Resources/Prototypes/Entities/Objects/Misc/kudzu.yml
Resources/Prototypes/Entities/Structures/Decoration/flesh_blockers.yml [new file with mode: 0644]
Resources/Prototypes/Entities/Structures/Specific/anomalies.yml
Resources/Prototypes/Tiles/floors.yml
Resources/Prototypes/tags.yml
Resources/Textures/Mobs/Aliens/flesh.rsi/clamp.png [new file with mode: 0644]
Resources/Textures/Mobs/Aliens/flesh.rsi/dead.png [new file with mode: 0644]
Resources/Textures/Mobs/Aliens/flesh.rsi/golem.png [new file with mode: 0644]
Resources/Textures/Mobs/Aliens/flesh.rsi/jared.png [new file with mode: 0644]
Resources/Textures/Mobs/Aliens/flesh.rsi/lover.png [new file with mode: 0644]
Resources/Textures/Mobs/Aliens/flesh.rsi/meta.json [new file with mode: 0644]
Resources/Textures/Objects/Misc/fleshkudzu.rsi/base.png [new file with mode: 0644]
Resources/Textures/Objects/Misc/fleshkudzu.rsi/meta.json [new file with mode: 0644]
Resources/Textures/Structures/Decoration/flesh_decoration.rsi/ajar.png [new file with mode: 0644]
Resources/Textures/Structures/Decoration/flesh_decoration.rsi/closed.png [new file with mode: 0644]
Resources/Textures/Structures/Decoration/flesh_decoration.rsi/meta.json [new file with mode: 0644]
Resources/Textures/Structures/Decoration/flesh_decoration.rsi/open.png [new file with mode: 0644]
Resources/Textures/Structures/Specific/anomaly.rsi/anom5-pulse.png [new file with mode: 0644]
Resources/Textures/Structures/Specific/anomaly.rsi/anom5.png [new file with mode: 0644]
Resources/Textures/Structures/Specific/anomaly.rsi/meta.json
Resources/Textures/Tiles/attributions.yml
Resources/Textures/Tiles/meat.png [new file with mode: 0644]

index 57f1f90f10871c4ac63a4d458155e249fc83aead..b8e3e743939e53bbb047f3daca790b24e92d1414 100644 (file)
@@ -1,4 +1,5 @@
-using Content.Shared.Anomaly;
+using Content.Client.Gravity;
+using Content.Shared.Anomaly;
 using Content.Shared.Anomaly.Components;
 using Robust.Client.GameObjects;
 using Robust.Shared.Timing;
@@ -8,6 +9,7 @@ namespace Content.Client.Anomaly;
 public sealed class AnomalySystem : SharedAnomalySystem
 {
     [Dependency] private readonly IGameTiming _timing = default!;
+    [Dependency] private readonly FloatingVisualizerSystem _floating = default!;
 
     /// <inheritdoc/>
     public override void Initialize()
@@ -15,6 +17,20 @@ public sealed class AnomalySystem : SharedAnomalySystem
         base.Initialize();
 
         SubscribeLocalEvent<AnomalyComponent, AppearanceChangeEvent>(OnAppearanceChanged);
+        SubscribeLocalEvent<AnomalyComponent, ComponentStartup>(OnStartup);
+        SubscribeLocalEvent<AnomalyComponent, AnimationCompletedEvent>(OnAnimationComplete);
+    }
+
+    private void OnStartup(EntityUid uid, AnomalyComponent component, ComponentStartup args)
+    {
+        _floating.FloatAnimation(uid, component.FloatingOffset, component.AnimationKey, component.AnimationTime);
+    }
+
+    private void OnAnimationComplete(EntityUid uid, AnomalyComponent component, AnimationCompletedEvent args)
+    {
+        if (args.Key != component.AnimationKey)
+            return;
+        _floating.FloatAnimation(uid, component.FloatingOffset, component.AnimationKey, component.AnimationTime);
     }
 
     private void OnAppearanceChanged(EntityUid uid, AnomalyComponent component, ref AppearanceChangeEvent args)
index 2baacf6b52c696f99863a8e4a095b1052483a35a..7a2deb86110baa74ed621a53f65f7620fad99a34 100644 (file)
@@ -4,7 +4,10 @@ using Content.Server.Power.EntitySystems;
 using Content.Shared.Anomaly;
 using Content.Shared.CCVar;
 using Content.Shared.Materials;
+using Content.Shared.Physics;
 using Robust.Shared.Map.Components;
+using Robust.Shared.Physics;
+using Robust.Shared.Physics.Components;
 
 namespace Content.Server.Anomaly;
 
@@ -91,12 +94,32 @@ public sealed partial class AnomalySystem
             var randomY = Random.Next((int) gridBounds.Bottom, (int)gridBounds.Top);
 
             var tile = new Vector2i(randomX, randomY);
-            if (_atmosphere.IsTileSpace(grid, xform.MapUid, tile,
-                    mapGridComp: gridComp) || _atmosphere.IsTileAirBlocked(grid, tile, mapGridComp: gridComp))
+
+            // no air-blocked areas.
+            if (_atmosphere.IsTileSpace(grid, xform.MapUid, tile, mapGridComp: gridComp) ||
+                _atmosphere.IsTileAirBlocked(grid, tile, mapGridComp: gridComp))
             {
                 continue;
             }
 
+            // don't spawn inside of solid objects
+            var physQuery = GetEntityQuery<PhysicsComponent>();
+            var valid = true;
+            foreach (var ent in gridComp.GetAnchoredEntities(tile))
+            {
+                if (!physQuery.TryGetComponent(ent, out var body))
+                    continue;
+                if (body.BodyType != BodyType.Static ||
+                    !body.Hard ||
+                    (body.CollisionLayer & (int) CollisionGroup.Impassable) == 0)
+                    continue;
+
+                valid = false;
+                break;
+            }
+            if (!valid)
+                continue;
+
             targetCoords = gridComp.GridTileToLocal(tile);
             break;
         }
index 8dce08c40601570b776cfedd3d456557ff48428f..e48fc328c48f68b4485c12c21b3adeb35502a5d0 100644 (file)
@@ -23,7 +23,6 @@ public sealed partial class AnomalySystem : SharedAnomalySystem
     [Dependency] private readonly DoAfterSystem _doAfter = default!;
     [Dependency] private readonly ExplosionSystem _explosion = default!;
     [Dependency] private readonly MaterialStorageSystem _material = default!;
-    [Dependency] private readonly TransformSystem _transform = default!;
     [Dependency] private readonly UserInterfaceSystem _ui = default!;
 
     public const float MinParticleVariation = 0.8f;
@@ -100,13 +99,13 @@ public sealed partial class AnomalySystem : SharedAnomalySystem
         var multiplier = 1f;
         if (component.Stability > component.GrowthThreshold)
             multiplier = component.GrowingPointMultiplier; //more points for unstable
-        else if (component.Stability < component.DecayThreshold)
-            multiplier = component.DecayingPointMultiplier; //less points if it's dying
 
         //penalty of up to 50% based on health
         multiplier *= MathF.Pow(1.5f, component.Health) - 0.5f;
 
-        return (int) ((component.MaxPointsPerSecond - component.MinPointsPerSecond) * component.Severity * multiplier);
+        var severityValue = 1 / (1 + MathF.Pow(MathF.E, -7 * (component.Severity - 0.5f)));
+
+        return (int) ((component.MaxPointsPerSecond - component.MinPointsPerSecond) * severityValue * multiplier) + component.MinPointsPerSecond;
     }
 
     /// <summary>
index 55c7b1bfa564b114de10d1c904d12557f6b90404..6c473d3570864efb2b5260fd5e0225f728bbfcdb 100644 (file)
@@ -6,11 +6,13 @@ using Content.Shared.Anomaly.Effects.Components;
 using Content.Shared.Mobs.Components;
 using Content.Shared.StatusEffect;
 using Robust.Shared.Random;
+using Robust.Shared.Timing;
 
 namespace Content.Server.Anomaly.Effects;
 
 public sealed class ElectricityAnomalySystem : EntitySystem
 {
+    [Dependency] private readonly IGameTiming _timing = default!;
     [Dependency] private readonly IRobustRandom _random = default!;
     [Dependency] private readonly LightningSystem _lightning = default!;
     [Dependency] private readonly ElectrocutionSystem _electrocution = default!;
@@ -25,16 +27,12 @@ public sealed class ElectricityAnomalySystem : EntitySystem
 
     private void OnPulse(EntityUid uid, ElectricityAnomalyComponent component, ref AnomalyPulseEvent args)
     {
-        var range = component.MaxElectrocuteRange * args.Stabiltiy;
-        var damage = (int) (component.MaxElectrocuteDamage * args.Severity);
-        var duration = component.MaxElectrocuteDuration * args.Severity;
-
+        var range = component.MaxElectrocuteRange * args.Stability;
         var xform = Transform(uid);
-        foreach (var comp in _lookup.GetComponentsInRange<StatusEffectsComponent>(xform.MapPosition, range))
+        foreach (var comp in _lookup.GetComponentsInRange<MobStateComponent>(xform.MapPosition, range))
         {
             var ent = comp.Owner;
-
-            _electrocution.TryDoElectrocution(ent, uid, damage, duration, true, statusEffects: comp, ignoreInsulation: true);
+            _lightning.ShootLightning(uid, ent);
         }
     }
 
@@ -48,7 +46,7 @@ public sealed class ElectricityAnomalySystem : EntitySystem
             if (mobQuery.HasComponent(ent))
                 validEnts.Add(ent);
 
-            if (_random.Prob(0.1f) && poweredQuery.HasComponent(ent))
+            if (_random.Prob(0.2f) && poweredQuery.HasComponent(ent))
                 validEnts.Add(ent);
         }
 
@@ -58,4 +56,32 @@ public sealed class ElectricityAnomalySystem : EntitySystem
             _lightning.ShootLightning(uid, ent);
         }
     }
+
+    public override void Update(float frameTime)
+    {
+        base.Update(frameTime);
+
+        foreach (var (elec, anom, xform) in EntityQuery<ElectricityAnomalyComponent, AnomalyComponent, TransformComponent>())
+        {
+            if (_timing.CurTime < elec.NextSecond)
+                continue;
+            elec.NextSecond = _timing.CurTime + TimeSpan.FromSeconds(1);
+
+            var owner = xform.Owner;
+
+            if (!_random.Prob(elec.PassiveElectrocutionChance * anom.Stability))
+                continue;
+
+            var range = elec.MaxElectrocuteRange * anom.Stability;
+            var damage = (int) (elec.MaxElectrocuteDamage * anom.Severity);
+            var duration = elec.MaxElectrocuteDuration * anom.Severity;
+
+            foreach (var comp in _lookup.GetComponentsInRange<StatusEffectsComponent>(xform.MapPosition, range))
+            {
+                var ent = comp.Owner;
+
+                _electrocution.TryDoElectrocution(ent, owner, damage, duration, true, statusEffects: comp, ignoreInsulation: true);
+            }
+        }
+    }
 }
diff --git a/Content.Server/Anomaly/Effects/FleshAnomalySystem.cs b/Content.Server/Anomaly/Effects/FleshAnomalySystem.cs
new file mode 100644 (file)
index 0000000..227721f
--- /dev/null
@@ -0,0 +1,97 @@
+using System.Linq;
+using Content.Server.Maps;
+using Content.Shared.Anomaly.Components;
+using Content.Shared.Anomaly.Effects.Components;
+using Content.Shared.Maps;
+using Content.Shared.Physics;
+using Robust.Shared.Map;
+using Robust.Shared.Physics;
+using Robust.Shared.Physics.Components;
+using Robust.Shared.Random;
+
+namespace Content.Server.Anomaly.Effects;
+
+public sealed class FleshAnomalySystem : EntitySystem
+{
+    [Dependency] private readonly IMapManager _map = default!;
+    [Dependency] private readonly IRobustRandom _random = default!;
+    [Dependency] private readonly ITileDefinitionManager _tiledef = default!;
+    [Dependency] private readonly TileSystem _tile = default!;
+
+    /// <inheritdoc/>
+    public override void Initialize()
+    {
+        SubscribeLocalEvent<FleshAnomalyComponent, AnomalyPulseEvent>(OnPulse);
+        SubscribeLocalEvent<FleshAnomalyComponent, AnomalySupercriticalEvent>(OnSupercritical);
+        SubscribeLocalEvent<FleshAnomalyComponent, AnomalyStabilityChangedEvent>(OnSeverityChanged);
+    }
+
+    private void OnPulse(EntityUid uid, FleshAnomalyComponent component, ref AnomalyPulseEvent args)
+    {
+        var range = component.SpawnRange * args.Stability;
+        var amount = (int) (component.MaxSpawnAmount * args.Severity + 0.5f);
+
+        var xform = Transform(uid);
+        SpawnMonstersOnOpenTiles(component, xform, amount, range);
+    }
+
+    private void OnSupercritical(EntityUid uid, FleshAnomalyComponent component, ref AnomalySupercriticalEvent args)
+    {
+        var xform = Transform(uid);
+        SpawnMonstersOnOpenTiles(component, xform, component.MaxSpawnAmount, component.SpawnRange);
+        Spawn(component.SupercriticalSpawn, xform.Coordinates);
+    }
+
+    private void OnSeverityChanged(EntityUid uid, FleshAnomalyComponent component, ref AnomalyStabilityChangedEvent args)
+    {
+        var xform = Transform(uid);
+        if (!_map.TryGetGrid(xform.GridUid, out var grid))
+            return;
+
+        var radius = component.SpawnRange * args.Stability;
+        var fleshTile = (ContentTileDefinition) _tiledef[component.FleshTileId];
+        var localpos = xform.Coordinates.Position;
+        var tilerefs = grid.GetLocalTilesIntersecting(
+            new Box2(localpos + (-radius, -radius), localpos + (radius, radius)));
+        foreach (var tileref in tilerefs)
+        {
+            if (!_random.Prob(0.33f))
+                continue;
+            _tile.ReplaceTile(tileref, fleshTile);
+        }
+    }
+
+    private void SpawnMonstersOnOpenTiles(FleshAnomalyComponent component, TransformComponent xform, int amount, float radius)
+    {
+        if (!_map.TryGetGrid(xform.GridUid, out var grid))
+            return;
+
+        var localpos = xform.Coordinates.Position;
+        var tilerefs = grid.GetLocalTilesIntersecting(
+            new Box2(localpos + (-radius, -radius), localpos + (radius, radius))).ToArray();
+        _random.Shuffle(tilerefs);
+        var physQuery = GetEntityQuery<PhysicsComponent>();
+        var amountCounter = 0;
+        foreach (var tileref in tilerefs)
+        {
+            var valid = true;
+            foreach (var ent in grid.GetAnchoredEntities(tileref.GridIndices))
+            {
+                if (!physQuery.TryGetComponent(ent, out var body))
+                    continue;
+                if (body.BodyType != BodyType.Static ||
+                    !body.Hard ||
+                    (body.CollisionLayer & (int) CollisionGroup.Impassable) == 0)
+                    continue;
+                valid = false;
+                break;
+            }
+            if (!valid)
+                continue;
+            amountCounter++;
+            Spawn(_random.Pick(component.Spawns), tileref.GridIndices.ToEntityCoordinates(xform.GridUid.Value, _map));
+            if (amountCounter >= amount)
+                return;
+        }
+    }
+}
index 12f0b3134365c52cf02004d5620f396764a7ef68..8e656a58c8ff2bbffc1f3c5d2df548b900d4fafa 100644 (file)
@@ -29,7 +29,7 @@ public sealed class PyroclasticAnomalySystem : EntitySystem
     private void OnPulse(EntityUid uid, PyroclasticAnomalyComponent component, ref AnomalyPulseEvent args)
     {
         var xform = Transform(uid);
-        var ignitionRadius = component.MaximumIgnitionRadius * args.Stabiltiy;
+        var ignitionRadius = component.MaximumIgnitionRadius * args.Stability;
         IgniteNearby(xform.Coordinates, args.Severity, ignitionRadius);
     }
 
index 0b888cf2254b64b034d05fb47f4158ffee609411..ddf5efc7f1c437a259ec62ccbd88d8fefd73e510 100644 (file)
@@ -3,6 +3,7 @@ using Content.Server.Decals;
 using Content.Shared.Decals;
 using Content.Shared.Maps;
 using Robust.Shared.Map;
+using Robust.Shared.Map.Components;
 using Robust.Shared.Random;
 
 namespace Content.Server.Maps;
@@ -54,6 +55,28 @@ public sealed class TileSystem : EntitySystem
         return DeconstructTile(tileRef);
     }
 
+    public bool ReplaceTile(TileRef tileref, ContentTileDefinition replacementTile)
+    {
+        if (!TryComp<MapGridComponent>(tileref.GridUid, out var grid))
+            return false;
+        return ReplaceTile(tileref, replacementTile, tileref.GridUid, grid);
+    }
+
+    public bool ReplaceTile(TileRef tileref, ContentTileDefinition replacementTile, EntityUid grid, MapGridComponent? component = null)
+    {
+        if (!Resolve(grid, ref component))
+            return false;
+
+        var variant = _robustRandom.Pick(replacementTile.PlacementVariants);
+        var decals = _decal.GetDecalsInRange(tileref.GridUid, tileref.GridPosition().SnapToGrid(EntityManager, _mapManager).Position, 0.5f);
+        foreach (var (id, _) in decals)
+        {
+            _decal.RemoveDecal(tileref.GridUid, id);
+        }
+        component.SetTile(tileref.GridIndices, new Tile(replacementTile.TileId, 0, variant));
+        return true;
+    }
+
     private bool DeconstructTile(TileRef tileRef)
     {
         var indices = tileRef.GridIndices;
index cdee844b1f6613a945dc7d847362bd986ae5f8e9..50f128d145efd0d75dfc420ca8fa0f1919a7495b 100644 (file)
@@ -62,7 +62,7 @@ public sealed class AnomalyComponent : Component
     /// The amount of health lost when the stability is below the <see cref="DecayThreshold"/>
     /// </summary>
     [DataField("healthChangePerSecond"), ViewVariables(VVAccess.ReadWrite)]
-    public float HealthChangePerSecond = -0.05f;
+    public float HealthChangePerSecond = -0.01f;
     #endregion
 
     #region Growth
@@ -208,21 +208,14 @@ public sealed class AnomalyComponent : Component
     /// This doesn't include the point bonus for being unstable.
     /// </summary>
     [DataField("maxPointsPerSecond")]
-    public int MaxPointsPerSecond = 65;
+    public int MaxPointsPerSecond = 100;
 
     /// <summary>
     /// The multiplier applied to the point value for the
     /// anomaly being above the <see cref="GrowthThreshold"/>
     /// </summary>
     [DataField("growingPointMultiplier")]
-    public float GrowingPointMultiplier = 1.2f;
-
-    /// <summary>
-    /// The multiplier applied to the point value for the
-    /// anomaly being below the <see cref="DecayThreshold"/>
-    /// </summary>
-    [DataField("decayingPointMultiplier")]
-    public float DecayingPointMultiplier = 0.75f;
+    public float GrowingPointMultiplier = 1.5f;
     #endregion
 
     /// <summary>
@@ -238,6 +231,24 @@ public sealed class AnomalyComponent : Component
     /// </summary>
     [DataField("anomalyContactDamageSound")]
     public SoundSpecifier AnomalyContactDamageSound = new SoundPathSpecifier("/Audio/Effects/lightburn.ogg");
+
+    #region Floating Animation
+    /// <summary>
+    /// How long it takes to go from the bottom of the animation to the top.
+    /// </summary>
+    [ViewVariables(VVAccess.ReadWrite)]
+    [DataField("animationTime")]
+    public readonly float AnimationTime = 2f;
+
+    /// <summary>
+    /// How far it goes in any direction.
+    /// </summary>
+    [ViewVariables(VVAccess.ReadWrite)]
+    [DataField("offset")]
+    public readonly Vector2 FloatingOffset = (0, 0.15f);
+
+    public readonly string AnimationKey = "anomalyfloat";
+    #endregion
 }
 
 [Serializable, NetSerializable]
@@ -260,14 +271,10 @@ public sealed class AnomalyComponentState : ComponentState
 /// <summary>
 /// Event raised at regular intervals on an anomaly to do whatever its effect is.
 /// </summary>
-/// <param name="Stabiltiy"></param>
+/// <param name="Stability"></param>
 /// <param name="Severity"></param>
 [ByRefEvent]
-public readonly record struct AnomalyPulseEvent(float Stabiltiy, float Severity)
-{
-    public readonly float Stabiltiy = Stabiltiy;
-    public readonly float Severity = Severity;
-}
+public readonly record struct AnomalyPulseEvent(float Stability, float Severity);
 
 /// <summary>
 /// Event raised on an anomaly when it reaches a supercritical point.
diff --git a/Content.Shared/Anomaly/Effects/BluespaceAnomalySystem.cs b/Content.Shared/Anomaly/Effects/BluespaceAnomalySystem.cs
new file mode 100644 (file)
index 0000000..920cc26
--- /dev/null
@@ -0,0 +1,73 @@
+using System.Linq;
+using Content.Shared.Anomaly.Components;
+using Content.Shared.Anomaly.Effects.Components;
+using Content.Shared.Mobs.Components;
+using Content.Shared.Teleportation.Components;
+using Robust.Shared.Map;
+using Robust.Shared.Random;
+
+namespace Content.Shared.Anomaly.Effects;
+
+public sealed class BluespaceAnomalySystem : EntitySystem
+{
+    [Dependency] private readonly IRobustRandom _random = default!;
+    [Dependency] private readonly SharedAudioSystem _audio = default!;
+    [Dependency] private readonly EntityLookupSystem _lookup = default!;
+    [Dependency] private readonly SharedTransformSystem _xform = default!;
+
+    /// <inheritdoc/>
+    public override void Initialize()
+    {
+        SubscribeLocalEvent<BluespaceAnomalyComponent, AnomalyPulseEvent>(OnPulse);
+        SubscribeLocalEvent<BluespaceAnomalyComponent, AnomalySupercriticalEvent>(OnSupercritical);
+        SubscribeLocalEvent<BluespaceAnomalyComponent, AnomalySeverityChangedEvent>(OnSeverityChanged);
+    }
+
+    private void OnPulse(EntityUid uid, BluespaceAnomalyComponent component, ref AnomalyPulseEvent args)
+    {
+        var xform = Transform(uid);
+        var range = component.MaxShuffleRadius * args.Severity;
+        var allEnts = _lookup.GetComponentsInRange<MobStateComponent>(xform.Coordinates, range)
+            .Select(x => x.Owner).ToList();
+        allEnts.Add(uid);
+
+        var xformQuery = GetEntityQuery<TransformComponent>();
+        var coords = new List<EntityCoordinates>();
+        foreach (var ent in allEnts)
+        {
+            if (xformQuery.TryGetComponent(ent, out var xf))
+                coords.Add(xf.Coordinates);
+        }
+
+        _random.Shuffle(coords);
+        for (var i = 0; i < allEnts.Count; i++)
+        {
+            _xform.SetCoordinates(allEnts[i], coords[i]);
+        }
+    }
+
+    private void OnSupercritical(EntityUid uid, BluespaceAnomalyComponent component, ref AnomalySupercriticalEvent args)
+    {
+        var xform = Transform(uid);
+        var mapPos = _xform.GetWorldPosition(xform);
+        var radius = component.SupercriticalTeleportRadius;
+        var gridBounds = new Box2(mapPos - (radius, radius), mapPos + (radius, radius));
+        foreach (var comp in _lookup.GetComponentsInRange<MobStateComponent>(xform.Coordinates, component.MaxShuffleRadius))
+        {
+            var ent = comp.Owner;
+            var randomX = _random.NextFloat(gridBounds.Left, gridBounds.Right);
+            var randomY = _random.NextFloat(gridBounds.Bottom, gridBounds.Top);
+
+            var pos = new Vector2(randomX, randomY);
+            _xform.SetWorldPosition(ent, pos);
+            _audio.PlayPvs(component.TeleportSound, ent);
+        }
+    }
+
+    private void OnSeverityChanged(EntityUid uid, BluespaceAnomalyComponent component, ref AnomalySeverityChangedEvent args)
+    {
+        if (!TryComp<PortalComponent>(uid, out var portal))
+            return;
+        portal.MaxRandomRadius = (component.MaxPortalRadius - component.MinPortalRadius) * args.Severity + component.MinPortalRadius;
+    }
+}
diff --git a/Content.Shared/Anomaly/Effects/Components/BluespaceAnomalyComponent.cs b/Content.Shared/Anomaly/Effects/Components/BluespaceAnomalyComponent.cs
new file mode 100644 (file)
index 0000000..4461941
--- /dev/null
@@ -0,0 +1,40 @@
+using Robust.Shared.Audio;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Anomaly.Effects.Components;
+
+[RegisterComponent, NetworkedComponent]
+[Access(typeof(BluespaceAnomalySystem))]
+public sealed class BluespaceAnomalyComponent : Component
+{
+    /// <summary>
+    /// The maximum radius that the shuffle effect will extend for
+    /// scales with stability
+    /// </summary>
+    [DataField("maxShuffleRadius"), ViewVariables(VVAccess.ReadWrite)]
+    public float MaxShuffleRadius = 10;
+
+    /// <summary>
+    /// The maximum MAX distance the portal this anomaly is tied to can teleport you.
+    /// </summary>
+    [DataField("maxPortalRadius"), ViewVariables(VVAccess.ReadWrite)]
+    public float MaxPortalRadius = 25;
+
+    /// <summary>
+    /// The minimum MAX distance the portal this anomaly is tied to can teleport you.
+    /// </summary>
+    [DataField("minPortalRadius"), ViewVariables(VVAccess.ReadWrite)]
+    public float MinPortalRadius = 10;
+
+    /// <summary>
+    /// How far the supercritical event can teleport you
+    /// </summary>
+    [DataField("superCriticalTeleportRadius"), ViewVariables(VVAccess.ReadWrite)]
+    public float SupercriticalTeleportRadius = 50f;
+
+    /// <summary>
+    /// The sound played after players are shuffled/teleported around
+    /// </summary>
+    [DataField("teleportSound"), ViewVariables(VVAccess.ReadWrite)]
+    public SoundSpecifier TeleportSound = new SoundPathSpecifier("/Audio/Effects/teleport_arrival.ogg");
+}
index fc430127ef4af76c52dccd16aa440f913203c55e..9afdd0aaa2f49ce747e49543b111f9e44129f94a 100644 (file)
@@ -1,14 +1,41 @@
-namespace Content.Shared.Anomaly.Effects.Components;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
+
+namespace Content.Shared.Anomaly.Effects.Components;
 
 [RegisterComponent]
 public sealed class ElectricityAnomalyComponent : Component
 {
+    /// <summary>
+    /// The maximum radius of the passive electrocution effect
+    /// scales with stability
+    /// </summary>
     [DataField("maxElectrocutionRange"), ViewVariables(VVAccess.ReadWrite)]
-    public float MaxElectrocuteRange = 6f;
+    public float MaxElectrocuteRange = 7f;
 
+    /// <summary>
+    /// The maximum amount of damage the electrocution can do
+    /// scales with severity
+    /// </summary>
     [DataField("maxElectrocuteDamage"), ViewVariables(VVAccess.ReadWrite)]
     public float MaxElectrocuteDamage = 20f;
 
+    /// <summary>
+    /// The maximum amount of time the electrocution lasts
+    /// scales with severity
+    /// </summary>
     [DataField("maxElectrocuteDuration"), ViewVariables(VVAccess.ReadWrite)]
     public TimeSpan MaxElectrocuteDuration = TimeSpan.FromSeconds(8);
+
+    /// <summary>
+    /// The maximum chance that each second, when in range of the anomaly, you will be electrocuted.
+    /// scales with stability
+    /// </summary>
+    [DataField("passiveElectrocutionChance"), ViewVariables(VVAccess.ReadWrite)]
+    public float PassiveElectrocutionChance = 0.05f;
+
+    /// <summary>
+    /// Used for tracking seconds, so that we can shock people in a non-tick-dependent way.
+    /// </summary>
+    [DataField("nextSecond", customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)]
+    public TimeSpan NextSecond = TimeSpan.Zero;
 }
diff --git a/Content.Shared/Anomaly/Effects/Components/FleshAnomalyComponent.cs b/Content.Shared/Anomaly/Effects/Components/FleshAnomalyComponent.cs
new file mode 100644 (file)
index 0000000..abd0b01
--- /dev/null
@@ -0,0 +1,43 @@
+using Content.Shared.Maps;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
+
+namespace Content.Shared.Anomaly.Effects.Components;
+
+[RegisterComponent]
+public sealed class FleshAnomalyComponent : Component
+{
+    /// <summary>
+    /// A list of entities that are random picked to be spawned on each pulse
+    /// </summary>
+    [DataField("spawns", required: true, customTypeSerializer: typeof(PrototypeIdListSerializer<EntityPrototype>)), ViewVariables(VVAccess.ReadWrite)]
+    public List<string> Spawns = new();
+
+    /// <summary>
+    /// The maximum number of entities that spawn per pulse
+    /// scales with severity.
+    /// </summary>
+    [DataField("maxSpawnAmount"), ViewVariables(VVAccess.ReadWrite)]
+    public int MaxSpawnAmount = 8;
+
+    /// <summary>
+    /// The maximum radius the entities will spawn in.
+    /// Also governs the maximum reach of flesh tiles
+    /// scales with stability
+    /// </summary>
+    [DataField("spawnRange"), ViewVariables(VVAccess.ReadWrite)]
+    public float SpawnRange = 4f;
+
+    /// <summary>
+    /// The tile that is spawned by the anomaly's effect
+    /// </summary>
+    [DataField("fleshTileId", customTypeSerializer: typeof(PrototypeIdSerializer<ContentTileDefinition>)), ViewVariables(VVAccess.ReadWrite)]
+    public string FleshTileId = "FloorFlesh";
+
+    /// <summary>
+    /// The entity spawned when the anomaly goes supercritical
+    /// </summary>
+    [DataField("superCriticalSpawn", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>)), ViewVariables(VVAccess.ReadWrite)]
+    public string SupercriticalSpawn = "FleshKudzu";
+}
index a6f80aeda0f2af2f6d1280f22c14be626d2976a0..761bc9daecf4c4de271cbcaa545e5080d0b9562e 100644 (file)
@@ -1,6 +1,8 @@
-namespace Content.Shared.Anomaly.Effects.Components;
+using Robust.Shared.GameStates;
 
-[RegisterComponent]
+namespace Content.Shared.Anomaly.Effects.Components;
+
+[RegisterComponent, NetworkedComponent]
 public sealed class GravityAnomalyComponent : Component
 {
     /// <summary>
index 5f3c1c25950843d6719ef589e436c3d3cac7b5da..9cfa56bcc22ed9d16ee710d9162baa02e07cd3e8 100644 (file)
@@ -13,7 +13,7 @@ public sealed class PyroclasticAnomalyComponent : Component
     /// I have no clue if this is balanced.
     /// </remarks>
     [DataField("heatPerSecond")]
-    public float HeatPerSecond = 50;
+    public float HeatPerSecond = 25;
 
     /// <summary>
     /// The maximum distance from which you can be ignited by the anomaly.
@@ -50,5 +50,5 @@ public sealed class PyroclasticAnomalyComponent : Component
     /// The amount of gas released when the anomaly goes supercritical
     /// </summary>
     [DataField("supercriticalMoleAmount")]
-    public float SupercriticalMoleAmount = 50f;
+    public float SupercriticalMoleAmount = 75f;
 }
index d7cf92c17df910d3b27c16096346510f22b0da0f..09f8ec35eebba22e697f9d465ab9ae7cf950259c 100644 (file)
@@ -29,9 +29,8 @@ public abstract class SharedGravityAnomalySystem : EntitySystem
         foreach (var ent in lookup)
         {
             var tempXform = Transform(ent);
-
             var foo = tempXform.MapPosition.Position - xform.MapPosition.Position;
-            _throwing.TryThrow(ent, foo.Normalized * 10, strength, uid, 0);
+            _throwing.TryThrow(ent, foo * 10, strength, uid, 0);
         }
     }
 
@@ -54,7 +53,6 @@ public abstract class SharedGravityAnomalySystem : EntitySystem
             var tempXform = Transform(ent);
 
             var foo = tempXform.MapPosition.Position - xform.MapPosition.Position;
-            Logger.Debug($"{ToPrettyString(ent)}: {foo}: {foo.Normalized}: {foo.Normalized * 10}");
             _throwing.TryThrow(ent, foo * 5, strength, uid, 0);
         }
     }
index 6106112a1d0727a9941a555ec89da2ca98ef57db..874e28ebcd9f0ac7ebf68f6fe004be9db9d81baf 100644 (file)
@@ -119,6 +119,9 @@ public abstract class SharedAnomalySystem : EntitySystem
         if (!Resolve(uid, ref component))
             return;
 
+        if (!Timing.IsFirstTimePredicted)
+            return;
+
         DebugTools.Assert(component.MinPulseLength > TimeSpan.FromSeconds(3)); // this is just to prevent lagspikes mispredicting pulses
         var variation = Random.NextFloat(-component.PulseVariation, component.PulseVariation) + 1;
         component.NextPulseTime = Timing.CurTime + GetPulseLength(component) * variation;
@@ -173,6 +176,10 @@ public abstract class SharedAnomalySystem : EntitySystem
     {
         if (!Resolve(uid, ref component))
             return;
+
+        if (!Timing.IsFirstTimePredicted)
+            return;
+
         Audio.PlayPvs(component.SupercriticalSound, uid);
 
         var ev = new AnomalySupercriticalEvent();
index a53fa1988f1113aa95504919cd12b370b4a21c48..974db2ab6eeb7f33b066226d0b2f7dfed2696267 100644 (file)
@@ -82,6 +82,7 @@ tiles-asteroid-ironsand-pebbles = asteroid ironsand pebbles
 tiles-asteroid-ironsand-rock = asteroid ironsand rock
 tiles-cave = cave
 tiles-cave-drought = cave drought
+tiles-flesh-floor = flesh floor
 tiles-techmaint3-floor = grated maintenance floor
 tiles-techmaint2-floor = steel maintenance floor
 tiles-wood2 = wood pattern floor
index a082fae7d62255283d4954b5c6eb1cb02a294f45..a21437fd77ecc610868589329511c04a42007037 100644 (file)
@@ -13,4 +13,6 @@
     - AnomalyPyroclastic
     - AnomalyGravity
     - AnomalyElectricity
+    - AnomalyFlesh
+    - AnomalyBluespace
     chance: 1
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/flesh.yml b/Resources/Prototypes/Entities/Mobs/NPCs/flesh.yml
new file mode 100644 (file)
index 0000000..68dde1d
--- /dev/null
@@ -0,0 +1,160 @@
+- type: entity
+  parent: SimpleMobBase
+  id: BaseMobFlesh
+  name: aberrant flesh
+  description: A shambling mass of flesh, animated through anomalous energy.
+  abstract: true
+  components:
+  - type: HTN
+    rootTask: SimpleHostileCompound
+  - type: Faction
+    factions:
+    - SimpleHostile
+  - type: Tag
+    tags:
+    - DoorBumpOpener
+    - Flesh
+  - type: Sprite
+    drawdepth: Mobs
+    sprite: Mobs/Aliens/flesh.rsi
+  - type: MovementAlwaysTouching
+  - type: MovementSpeedModifier
+    baseWalkSpeed: 1
+    baseSprintSpeed: 1.5
+  - type: MobState
+    allowedStates:
+    - Alive
+    - Dead
+  - type: MobThresholds
+    thresholds:
+      0: Alive
+      75: Dead
+  - type: Stamina
+    excess: 50
+  - type: Appearance
+  - type: Butcherable
+    spawned:
+    - id: FoodMeat
+      amount: 1
+  - type: Bloodstream
+    bloodMaxVolume: 500
+  - type: CombatMode
+    disarmAction:
+      enabled: false
+      autoPopulate: false
+      name: action-name-disarm
+  - type: MeleeWeapon
+    hidden: true
+    soundHit:
+        path: /Audio/Weapons/Xeno/alien_claw_flesh3.ogg
+    angle: 0
+    animation: WeaponArcClaw
+    damage:
+      types:
+        Slash: 3
+  - type: ReplacementAccent
+    accent: genericAggressive
+
+- type: entity
+  parent: BaseMobFlesh
+  id: MobFleshJared
+  components:
+  - type: Sprite
+    layers:
+    - map: [ "enum.DamageStateVisualLayers.Base" ]
+      state: jared
+  - type: DamageStateVisuals
+    states:
+      Alive:
+        Base: jared
+      Critical:
+        Base: dead
+      Dead:
+        Base: dead
+  - type: MeleeWeapon
+    hidden: true
+    soundHit:
+        path: /Audio/Weapons/Xeno/alien_claw_flesh3.ogg
+    angle: 0
+    animation: WeaponArcClaw
+    damage:
+      types:
+        Slash: 5
+
+- type: entity
+  parent: BaseMobFlesh
+  id: MobFleshGolem
+  components:
+  - type: Sprite
+    layers:
+    - map: [ "enum.DamageStateVisualLayers.Base" ]
+      state: golem
+  - type: DamageStateVisuals
+    states:
+      Alive:
+        Base: golem
+      Critical:
+        Base: dead
+      Dead:
+        Base: dead
+  - type: MobThresholds
+    thresholds:
+      0: Alive
+      50: Dead
+  - type: MeleeWeapon
+    hidden: true
+    soundHit:
+        path: /Audio/Weapons/Xeno/alien_claw_flesh3.ogg
+    angle: 0
+    animation: WeaponArcClaw
+    damage:
+      types:
+        Slash: 5
+
+- type: entity
+  parent: BaseMobFlesh
+  id: MobFleshClamp
+  components:
+  - type: Sprite
+    layers:
+    - map: [ "enum.DamageStateVisualLayers.Base" ]
+      state: clamp
+  - type: DamageStateVisuals
+    states:
+      Alive:
+        Base: clamp
+      Critical:
+        Base: dead
+      Dead:
+        Base: dead
+  - type: MobThresholds
+    thresholds:
+      0: Alive
+      30: Dead
+  - type: MovementSpeedModifier
+    baseWalkSpeed: 2
+    baseSprintSpeed: 2.5
+
+- type: entity
+  parent: BaseMobFlesh
+  id: MobFleshLover
+  components:
+  - type: Sprite
+    layers:
+    - map: [ "enum.DamageStateVisualLayers.Base" ]
+      state: lover
+  - type: DamageStateVisuals
+    states:
+      Alive:
+        Base: lover
+      Critical:
+        Base: dead
+      Dead:
+        Base: dead
+  - type: MobThresholds
+    thresholds:
+      0: Alive
+      30: Dead
+  - type: MovementSpeedModifier
+    baseWalkSpeed: 2
+    baseSprintSpeed: 2.5
index d2942f45cc1f0fad59f8492f0bb6cc0acd547c04..280ce2c7e3c87e726b70548859ef092dbc1d7de2 100644 (file)
@@ -14,6 +14,7 @@
             "/Audio/Weapons/slash.ogg"
     - type: Sprite
       sprite: Objects/Misc/kudzu.rsi
+      color: "#ff0000"
       state: kudzu_11
       drawdepth: Overdoors
       netsync: false
     - type: SlowContacts
       walkSpeedModifier: 0.2
       sprintSpeedModifier: 0.2
+
+- type: entity
+  id: FleshKudzu
+  name: tendons
+  description: A rapidly growing cluster of meaty tendons. WHY ARE YOU STOPPING TO LOOK AT IT?!
+  placement:
+    mode: SnapgridCenter
+    snap:
+      - Wall
+  components:
+    - type: MeleeSound
+      soundGroups:
+        Brute:
+          path:
+            "/Audio/Weapons/slash.ogg"
+    - type: Sprite
+      sprite: Objects/Misc/fleshkudzu.rsi
+      state: base
+      drawdepth: Overdoors
+      netsync: false
+    - type: Appearance
+    - type: Clickable
+    - type: Transform
+      anchored: true
+    - type: Physics
+    - type: Fixtures
+      fixtures:
+      - hard: false
+        density: 7
+        shape:
+          !type:PhysShapeAabb
+          bounds: "-0.5,-0.5,0.5,0.5"
+        layer:
+        - MidImpassable
+    - type: Damageable
+    - type: Destructible
+      thresholds:
+      - trigger:
+          !type:DamageTrigger
+          damage: 10
+        behaviors:
+        - !type:DoActsBehavior
+          acts: [ "Destruction" ]
+    - type: Spreader
+      growthResult: FleshKudzu
+      chance: 1
+    - type: SlowContacts
+      walkSpeedModifier: 0.2
+      sprintSpeedModifier: 0.2
+      ignoreWhitelist:
+        tags:
+        - Flesh
diff --git a/Resources/Prototypes/Entities/Structures/Decoration/flesh_blockers.yml b/Resources/Prototypes/Entities/Structures/Decoration/flesh_blockers.yml
new file mode 100644 (file)
index 0000000..e883177
--- /dev/null
@@ -0,0 +1,40 @@
+- type: entity
+  id: FleshBlocker
+  parent: BaseStructure
+  name: flesh clump
+  description: An annoying clump of flesh.
+  components:
+  - type: InteractionOutline
+  - type: Sprite
+    noRot: true
+    sprite: Structures/Decoration/flesh_decoration.rsi
+    layers:
+    - state: closed
+      map: [ "enum.DamageStateVisualLayers.Base" ]
+  - type: Fixtures
+    fixtures:
+    - shape:
+        !type:PhysShapeCircle
+        radius: 0.3
+      density: 190
+      mask:
+      - MachineMask
+      layer:
+      - Impassable
+  - type: RandomSprite
+    available:
+      - enum.DamageStateVisualLayers.Base:
+          closed: ""
+      - enum.DamageStateVisualLayers.Base:
+          ajar: ""
+      - enum.DamageStateVisualLayers.Base:
+          open: ""
+  - type: Damageable
+  - type: Destructible
+    thresholds:
+    - trigger:
+        !type:DamageTrigger
+        damage: 25
+      behaviors:
+        - !type:DoActsBehavior
+          acts: [ "Destruction" ]
index 5d57d343a7434ecafbb50a1109cc8c02823474c8..1dfeefff36ae721bd2e806789d3c4e165d17555d 100644 (file)
@@ -20,7 +20,7 @@
   - type: Transform
     anchored: true
   - type: Physics
-    bodyType: Static  
+    bodyType: Static
   - type: Fixtures
     fixtures:
     - shape:
       - MobLayer
   - type: Sprite
     netsync: false
-    drawdepth: Items
+    noRot: true
+    drawdepth: Effects #it needs to draw over stuff.
     sprite: Structures/Specific/anomaly.rsi
   - type: InteractionOutline
   - type: Clickable
   - type: Damageable
   - type: Appearance
+  - type: AnimationPlayer
   - type: GuideHelp
     guides:
     - AnomalousResearch
@@ -71,7 +73,6 @@
   suffix: Gravity
   components:
   - type: Sprite
-    drawdepth: Effects #it needs to draw over stuff.
     layers:
     - state: anom2
       map: ["enum.AnomalyVisualLayers.Base"]
     color: "#ffffaa"
     castShadows: false
   - type: ElectricityAnomaly
-  - type: Electrified
\ No newline at end of file
+  - type: Electrified
+
+- type: entity
+  id: AnomalyFlesh
+  parent: BaseAnomaly
+  suffix: Flesh
+  components:
+  - type: Sprite
+    layers:
+    - state: anom5
+      map: ["enum.AnomalyVisualLayers.Base"]
+    - state: anom5-pulse
+      map: ["enum.AnomalyVisualLayers.Animated"]
+      visible: false
+  - type: PointLight
+    radius: 2.0
+    energy: 7.5
+    color: "#cb5b7e"
+    castShadows: false
+  - type: FleshAnomaly
+    spawns:
+    - MobFleshJared
+    - MobFleshGolem
+    - MobFleshClamp
+    - MobFleshLover
+    - FleshBlocker
+
+- type: entity
+  id: AnomalyBluespace
+  parent: BaseAnomaly
+  suffix: Bluespace
+  components:
+  - type: Sprite
+    layers:
+    - state: anom4
+      map: ["enum.AnomalyVisualLayers.Base"]
+    - state: anom4-pulse
+      map: ["enum.AnomalyVisualLayers.Animated"]
+      visible: false
+  - type: PointLight
+    radius: 2.0
+    energy: 7.5
+    color: "#00ccff"
+    castShadows: false
+  - type: BluespaceAnomaly
+  - type: Portal
+  - type: Fixtures
+    fixtures:
+    - shape:
+        !type:PhysShapeCircle
+        radius: 0.35
+      density: 50
+      mask:
+      - MobMask
+      layer:
+      - MobLayer
+    - id: portalFixture
+      shape:
+        !type:PhysShapeAabb
+        bounds: "-0.25,-0.48,0.25,0.48"
+      mask:
+      - FullTileMask
+      layer:
+      - WallLayer
+      hard: false
+  - type: Anomaly
+    pulseSound:
+      collection: RadiationPulse
+      params:
+        volume: 5
+    anomalyContactDamage:
+      types:
+        Radiation: 10
index 9043d57afa75926558ca88c6937c0be73c4c2d30..a23e9493a4ff2965d22b97d06627c1f94bc7db21 100644 (file)
   thermalConductivity: 0.04
   heatCapacity: 10000
 
+- type: tile
+  id: FloorFlesh
+  name: tiles-flesh-floor
+  sprite: /Textures/Tiles/meat.png
+  variants: 4
+  placementVariants: [0, 1, 2, 3]
+  baseTurfs:
+  - Plating
+  isSubfloor: false
+  canCrowbar: true
+  footstepSounds:
+    collection: BarestepCarpet
+  friction: 0.20 #slippy
+  thermalConductivity: 0.04
+  heatCapacity: 10000
+
 - type: tile
   id: FloorTechMaint2
   name: tiles-techmaint2-floor
index 859eff49db9c74d2df9625f939bbdfba4abb9944..dbb2562846b2de93ad93a3639ad8c567a81e18ff 100644 (file)
 - type: Tag
   id: FireAxe
 
+- type: Tag
+  id: Flesh
+
 - type: Tag
   id: WhitelistChameleon
 
diff --git a/Resources/Textures/Mobs/Aliens/flesh.rsi/clamp.png b/Resources/Textures/Mobs/Aliens/flesh.rsi/clamp.png
new file mode 100644 (file)
index 0000000..d9085d7
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/flesh.rsi/clamp.png differ
diff --git a/Resources/Textures/Mobs/Aliens/flesh.rsi/dead.png b/Resources/Textures/Mobs/Aliens/flesh.rsi/dead.png
new file mode 100644 (file)
index 0000000..826d4e0
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/flesh.rsi/dead.png differ
diff --git a/Resources/Textures/Mobs/Aliens/flesh.rsi/golem.png b/Resources/Textures/Mobs/Aliens/flesh.rsi/golem.png
new file mode 100644 (file)
index 0000000..e7744ad
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/flesh.rsi/golem.png differ
diff --git a/Resources/Textures/Mobs/Aliens/flesh.rsi/jared.png b/Resources/Textures/Mobs/Aliens/flesh.rsi/jared.png
new file mode 100644 (file)
index 0000000..da20b43
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/flesh.rsi/jared.png differ
diff --git a/Resources/Textures/Mobs/Aliens/flesh.rsi/lover.png b/Resources/Textures/Mobs/Aliens/flesh.rsi/lover.png
new file mode 100644 (file)
index 0000000..0b5229c
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/flesh.rsi/lover.png differ
diff --git a/Resources/Textures/Mobs/Aliens/flesh.rsi/meta.json b/Resources/Textures/Mobs/Aliens/flesh.rsi/meta.json
new file mode 100644 (file)
index 0000000..6c81c52
--- /dev/null
@@ -0,0 +1,27 @@
+{
+  "version": 1,
+  "size": {
+    "x": 32,
+    "y": 32
+  },
+  "license": "CC-BY-SA-3.0",
+  "copyright": "Created by EmoGarbage404 (github) for space-station-14, credit to Aleksh#7552 (discord) for original concepts and designs",
+  "states": [
+    {
+      "name": "clamp"
+    },
+    {
+      "name": "dead"
+    },
+    {
+      "name": "golem",
+      "directions": 4
+    },
+    {
+      "name": "jared"
+    },
+    {
+      "name": "lover"
+    }
+  ]
+}
diff --git a/Resources/Textures/Objects/Misc/fleshkudzu.rsi/base.png b/Resources/Textures/Objects/Misc/fleshkudzu.rsi/base.png
new file mode 100644 (file)
index 0000000..659b2ea
Binary files /dev/null and b/Resources/Textures/Objects/Misc/fleshkudzu.rsi/base.png differ
diff --git a/Resources/Textures/Objects/Misc/fleshkudzu.rsi/meta.json b/Resources/Textures/Objects/Misc/fleshkudzu.rsi/meta.json
new file mode 100644 (file)
index 0000000..fc8bf10
--- /dev/null
@@ -0,0 +1,14 @@
+{
+  "version": 1,
+  "license": "CC0-1.0",
+  "copyright": "Created by EmoGarbage404 (github) for space-station-14",
+  "size": {
+    "x": 32,
+    "y": 32
+  },
+  "states": [
+    {
+      "name": "base"
+    }
+  ]
+}
diff --git a/Resources/Textures/Structures/Decoration/flesh_decoration.rsi/ajar.png b/Resources/Textures/Structures/Decoration/flesh_decoration.rsi/ajar.png
new file mode 100644 (file)
index 0000000..c4e0b26
Binary files /dev/null and b/Resources/Textures/Structures/Decoration/flesh_decoration.rsi/ajar.png differ
diff --git a/Resources/Textures/Structures/Decoration/flesh_decoration.rsi/closed.png b/Resources/Textures/Structures/Decoration/flesh_decoration.rsi/closed.png
new file mode 100644 (file)
index 0000000..dec70d0
Binary files /dev/null and b/Resources/Textures/Structures/Decoration/flesh_decoration.rsi/closed.png differ
diff --git a/Resources/Textures/Structures/Decoration/flesh_decoration.rsi/meta.json b/Resources/Textures/Structures/Decoration/flesh_decoration.rsi/meta.json
new file mode 100644 (file)
index 0000000..8b58bd6
--- /dev/null
@@ -0,0 +1,20 @@
+{
+  "version": 1,
+  "size": {
+    "x": 32,
+    "y": 32
+  },
+  "license": "CC-BY-SA-3.0",
+  "copyright": "Created by Aleksh#7552 (discord) for space-station-14",
+  "states": [
+    {
+      "name": "ajar"
+    },
+    {
+      "name": "closed"
+    },
+    {
+      "name": "open"
+    }
+  ]
+}
diff --git a/Resources/Textures/Structures/Decoration/flesh_decoration.rsi/open.png b/Resources/Textures/Structures/Decoration/flesh_decoration.rsi/open.png
new file mode 100644 (file)
index 0000000..5f7bfd3
Binary files /dev/null and b/Resources/Textures/Structures/Decoration/flesh_decoration.rsi/open.png differ
diff --git a/Resources/Textures/Structures/Specific/anomaly.rsi/anom5-pulse.png b/Resources/Textures/Structures/Specific/anomaly.rsi/anom5-pulse.png
new file mode 100644 (file)
index 0000000..c0e547f
Binary files /dev/null and b/Resources/Textures/Structures/Specific/anomaly.rsi/anom5-pulse.png differ
diff --git a/Resources/Textures/Structures/Specific/anomaly.rsi/anom5.png b/Resources/Textures/Structures/Specific/anomaly.rsi/anom5.png
new file mode 100644 (file)
index 0000000..6117776
Binary files /dev/null and b/Resources/Textures/Structures/Specific/anomaly.rsi/anom5.png differ
index f9d4be792f3bb97176213bd9f46da1166e8b8da0..c318e8116bdbe440559f79006b1731d565a2b62a 100644 (file)
@@ -1,7 +1,7 @@
 {
   "version": 1,
   "license": "CC0-1.0",
-  "copyright": "Created by EmoGarbage; anom3, anom3-pulse, anom4, anom4-pulse are CC-BY-SA-3.0 at https://github.com/ParadiseSS13/Paradise/blob/master/icons/effects/effects.dmi",
+  "copyright": "Created by EmoGarbage; anom3, anom3-pulse, anom4, anom4-pulse are CC-BY-SA-3.0 at https://github.com/ParadiseSS13/Paradise/blob/master/icons/effects/effects.dmi; anom5, anom5-pulse are CC-BY-SA-3.0 by Aleksh#7552 (discord) for space-station-14",
   "size": {
     "x": 32,
     "y": 32
           0.15
         ]
       ]
+    },
+    {
+      "name": "anom5"
+    },
+    {
+      "name": "anom5-pulse",
+      "delays": [
+        [
+          0.25,
+          0.25,
+          0.25,
+          0.25
+        ]
+      ]
     }
   ]
-}
\ No newline at end of file
+}
index 9fec6d6c0e1158dcdb16eec66cf8ae8ccfad1f9c..9ce6c90cd07804e948db32fd9953148d53f33da2 100644 (file)
@@ -56,3 +56,7 @@
   copyright: "by brainfood for space-station-14, ."
   source: "https://github.com/space-wizards/space-station-14/pull/12193"
 
+- files: ["meat.png"]
+  license: "CC0-1.0"
+  copyright: "Created by EmoGarbage404 (github) for space-station-14."
+  source: "https://github.com/space-wizards/space-station-14/pull/13766"
diff --git a/Resources/Textures/Tiles/meat.png b/Resources/Textures/Tiles/meat.png
new file mode 100644 (file)
index 0000000..d593c1b
Binary files /dev/null and b/Resources/Textures/Tiles/meat.png differ