From 05a7eb07c27a0304285a4c8ef5f1e5b6bdd566a9 Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Tue, 23 Jan 2024 15:40:37 +0300 Subject: [PATCH] Revert "Start rebalancing anomalies - Rock and Flesh anomaly reworked" (#24448) --- .../Anomaly/Effects/EntityAnomalySystem.cs | 108 +++--- .../Anomaly/Effects/TileAnomalySystem.cs | 91 +---- .../Anomaly/Components/AnomalyComponent.cs | 4 +- .../Components/EntitySpawnAnomalyComponent.cs | 53 +-- .../Effects/Components/TileSpawnAnomaly.cs | 26 ++ .../Components/TileSpawnAnomalyComponent.cs | 73 ---- .../Effects/SharedEntityAnomalySystem.cs | 6 - .../Effects/SharedTileAnomalySystem.cs | 6 - Content.Shared/Anomaly/SharedAnomalySystem.cs | 4 +- .../Prototypes/Entities/Effects/wallspawn.yml | 50 +-- .../Markers/Spawners/Random/anomaly.yml | 20 +- .../Markers/Spawners/Random/asteroidcrab.yml | 31 ++ .../Entities/Objects/Misc/ice_crust.yml | 3 +- .../Structures/Specific/Anomaly/anomalies.yml | 324 +++--------------- .../Entities/Structures/Walls/asteroid.yml | 88 +++-- .../Specific/anomaly.rsi/anom6-pulse.png | Bin 3741 -> 23507 bytes .../Structures/Specific/anomaly.rsi/anom6.png | Bin 3078 -> 18861 bytes 17 files changed, 216 insertions(+), 671 deletions(-) create mode 100644 Content.Shared/Anomaly/Effects/Components/TileSpawnAnomaly.cs delete mode 100644 Content.Shared/Anomaly/Effects/Components/TileSpawnAnomalyComponent.cs delete mode 100644 Content.Shared/Anomaly/Effects/SharedEntityAnomalySystem.cs delete mode 100644 Content.Shared/Anomaly/Effects/SharedTileAnomalySystem.cs create mode 100644 Resources/Prototypes/Entities/Markers/Spawners/Random/asteroidcrab.yml diff --git a/Content.Server/Anomaly/Effects/EntityAnomalySystem.cs b/Content.Server/Anomaly/Effects/EntityAnomalySystem.cs index 30b159b615..ee4e2ac115 100644 --- a/Content.Server/Anomaly/Effects/EntityAnomalySystem.cs +++ b/Content.Server/Anomaly/Effects/EntityAnomalySystem.cs @@ -1,18 +1,17 @@ using System.Linq; using System.Numerics; using Content.Shared.Anomaly.Components; -using Content.Shared.Anomaly.Effects; using Content.Shared.Anomaly.Effects.Components; using Content.Shared.Physics; using Robust.Shared.Map; -using Robust.Shared.Map.Components; using Robust.Shared.Physics; using Robust.Shared.Physics.Components; +using Robust.Shared.Prototypes; using Robust.Shared.Random; namespace Content.Server.Anomaly.Effects; -public sealed class EntityAnomalySystem : SharedEntityAnomalySystem +public sealed class EntityAnomalySystem : EntitySystem { [Dependency] private readonly IMapManager _map = default!; [Dependency] private readonly IRobustRandom _random = default!; @@ -23,70 +22,55 @@ public sealed class EntityAnomalySystem : SharedEntityAnomalySystem SubscribeLocalEvent(OnPulse); SubscribeLocalEvent(OnSupercritical); SubscribeLocalEvent(OnStabilityChanged); - SubscribeLocalEvent(OnSeverityChanged); } - private void OnPulse(Entity component, ref AnomalyPulseEvent args) + private void OnPulse(EntityUid uid, EntitySpawnAnomalyComponent component, ref AnomalyPulseEvent args) { - foreach (var entry in component.Comp.Entries) - { - if (!entry.SpawnOnPulse) - continue; - - SpawnEntitesOnOpenTiles(component, entry, args.Stability, args.Severity); - } - } - - private void OnSupercritical(Entity component, ref AnomalySupercriticalEvent args) - { - foreach (var entry in component.Comp.Entries) - { - if (!entry.SpawnOnSuperCritical) - continue; - - SpawnEntitesOnOpenTiles(component, entry, 1, 1); - } - } - - private void OnStabilityChanged(Entity component, ref AnomalyStabilityChangedEvent args) - { - foreach (var entry in component.Comp.Entries) - { - if (!entry.SpawnOnStabilityChanged) - continue; - - SpawnEntitesOnOpenTiles(component, entry, args.Stability, args.Severity); - } - } - - private void OnSeverityChanged(Entity component, ref AnomalySeverityChangedEvent args) - { - foreach (var entry in component.Comp.Entries) - { - if (!entry.SpawnOnSeverityChanged) - continue; - - SpawnEntitesOnOpenTiles(component, entry, args.Stability, args.Severity); - } - } - - //TheShuEd: - //I know it's a shitcode! I didn't write it! I just restructured the functions - // To Do: make it reusable with TileAnomalySystem - private void SpawnEntitesOnOpenTiles(Entity component, EntitySpawnSettingsEntry entry, float stability, float severity) - { - if (entry.Spawns.Count == 0) + if (!component.SpawnOnPulse) return; - var xform = Transform(component.Owner); - if (!TryComp(xform.GridUid, out var grid)) + var range = component.SpawnRange * args.Stability; + var amount = (int) (component.MaxSpawnAmount * args.Severity + 0.5f); + + var xform = Transform(uid); + SpawnEntitesOnOpenTiles(component, xform, amount, range, component.Spawns); + } + + private void OnSupercritical(EntityUid uid, EntitySpawnAnomalyComponent component, ref AnomalySupercriticalEvent args) + { + if (!component.SpawnOnSuperCritical) return; - var amount = (int) (MathHelper.Lerp(entry.MinAmount, entry.MaxAmount, severity * stability) + 0.5f); + var xform = Transform(uid); + // A cluster of entities + SpawnEntitesOnOpenTiles(component, xform, component.MaxSpawnAmount, component.SpawnRange, component.Spawns); + // And so much meat (for the meat anomaly at least) + SpawnEntitesOnOpenTiles(component, xform, component.MaxSpawnAmount, component.SpawnRange, component.SuperCriticalSpawns); + } + + private void OnStabilityChanged(EntityUid uid, EntitySpawnAnomalyComponent component, ref AnomalyStabilityChangedEvent args) + { + if (!component.SpawnOnStabilityChanged) + return; + + var range = component.SpawnRange * args.Stability; + var amount = (int) (component.MaxSpawnAmount * args.Stability + 0.5f); + + var xform = Transform(uid); + SpawnEntitesOnOpenTiles(component, xform, amount, range, component.Spawns); + } + + private void SpawnEntitesOnOpenTiles(EntitySpawnAnomalyComponent component, TransformComponent xform, int amount, float radius, List spawns) + { + if (!component.Spawns.Any()) + return; + + if (!_map.TryGetGrid(xform.GridUid, out var grid)) + return; var localpos = xform.Coordinates.Position; var tilerefs = grid.GetLocalTilesIntersecting( - new Box2(localpos + new Vector2(-entry.MaxRange, -entry.MaxRange), localpos + new Vector2(entry.MaxRange, entry.MaxRange))).ToArray(); + new Box2(localpos + new Vector2(-radius, -radius), localpos + new Vector2(radius, radius))).ToArray(); if (tilerefs.Length == 0) return; @@ -96,14 +80,6 @@ public sealed class EntityAnomalySystem : SharedEntityAnomalySystem var amountCounter = 0; foreach (var tileref in tilerefs) { - //cut outer circle - if (MathF.Sqrt(MathF.Pow(tileref.X - xform.LocalPosition.X, 2) + MathF.Pow(tileref.Y - xform.LocalPosition.Y, 2)) > entry.MaxRange) - continue; - - //cut inner circle - if (MathF.Sqrt(MathF.Pow(tileref.X - xform.LocalPosition.X, 2) + MathF.Pow(tileref.Y - xform.LocalPosition.Y, 2)) < entry.MinRange) - continue; - var valid = true; foreach (var ent in grid.GetAnchoredEntities(tileref.GridIndices)) { @@ -121,7 +97,7 @@ public sealed class EntityAnomalySystem : SharedEntityAnomalySystem if (!valid) continue; amountCounter++; - Spawn(_random.Pick(entry.Spawns), tileref.GridIndices.ToEntityCoordinates(xform.GridUid.Value, _map)); + Spawn(_random.Pick(spawns), tileref.GridIndices.ToEntityCoordinates(xform.GridUid.Value, _map)); if (amountCounter >= amount) return; } diff --git a/Content.Server/Anomaly/Effects/TileAnomalySystem.cs b/Content.Server/Anomaly/Effects/TileAnomalySystem.cs index 1cc81aecc0..08ec3a1c93 100644 --- a/Content.Server/Anomaly/Effects/TileAnomalySystem.cs +++ b/Content.Server/Anomaly/Effects/TileAnomalySystem.cs @@ -1,16 +1,13 @@ -using System.Linq; using System.Numerics; using Content.Shared.Anomaly.Components; -using Content.Shared.Anomaly.Effects; using Content.Shared.Anomaly.Effects.Components; using Content.Shared.Maps; using Robust.Shared.Map; -using Robust.Shared.Map.Components; using Robust.Shared.Random; namespace Content.Server.Anomaly.Effects; -public sealed class TileAnomalySystem : SharedTileAnomalySystem +public sealed class TileAnomalySystem : EntitySystem { [Dependency] private readonly IMapManager _map = default!; [Dependency] private readonly IRobustRandom _random = default!; @@ -20,93 +17,25 @@ public sealed class TileAnomalySystem : SharedTileAnomalySystem /// public override void Initialize() { - - SubscribeLocalEvent(OnPulse); - SubscribeLocalEvent(OnSupercritical); - SubscribeLocalEvent(OnStabilityChanged); - SubscribeLocalEvent(OnSeverityChanged); + SubscribeLocalEvent(OnSeverityChanged); } - private void OnPulse(Entity component, ref AnomalyPulseEvent args) + private void OnSeverityChanged(EntityUid uid, TileSpawnAnomalyComponent component, ref AnomalyStabilityChangedEvent args) { - foreach (var entry in component.Comp.Entries) - { - if (!entry.SpawnOnPulse) - continue; - - SpawnTiles(component, entry, args.Stability, args.Severity); - } - } - private void OnSupercritical(Entity component, ref AnomalySupercriticalEvent args) - { - foreach (var entry in component.Comp.Entries) - { - if (!entry.SpawnOnSuperCritical) - continue; - - SpawnTiles(component, entry, 1, 1); - } - } - - private void OnStabilityChanged(Entity component, ref AnomalyStabilityChangedEvent args) - { - foreach (var entry in component.Comp.Entries) - { - if (!entry.SpawnOnStabilityChanged) - continue; - - SpawnTiles(component, entry, args.Stability, args.Severity); - } - } - - private void OnSeverityChanged(Entity component, ref AnomalySeverityChangedEvent args) - { - foreach (var entry in component.Comp.Entries) - { - if (!entry.SpawnOnSeverityChanged) - continue; - - SpawnTiles(component, entry, args.Stability, args.Severity); - } - } - - //TheShuEd: - //I know it's a shitcode! I didn't write it! I just restructured the functions - // To Do: make it reusable with EntityAnomalySustem - private void SpawnTiles(Entity component, TileSpawnSettingsEntry entry, float stability, float severity) - { - var xform = Transform(component.Owner); - if (!TryComp(xform.GridUid, out var grid)) + var xform = Transform(uid); + if (!_map.TryGetGrid(xform.GridUid, out var grid)) return; - var amount = (int) (MathHelper.Lerp(entry.MinAmount, entry.MaxAmount, stability * severity) + 0.5f); - + var radius = component.SpawnRange * args.Stability; + var fleshTile = (ContentTileDefinition) _tiledef[component.FloorTileId]; var localpos = xform.Coordinates.Position; var tilerefs = grid.GetLocalTilesIntersecting( - new Box2(localpos + new Vector2(-entry.MaxRange, -entry.MaxRange), localpos + new Vector2(entry.MaxRange, entry.MaxRange))).ToArray(); - - if (tilerefs.Length == 0) - return; - - _random.Shuffle(tilerefs); - var amountCounter = 0; - + new Box2(localpos + new Vector2(-radius, -radius), localpos + new Vector2(radius, radius))); foreach (var tileref in tilerefs) { - //cut outer circle - if (MathF.Sqrt(MathF.Pow(tileref.X - xform.LocalPosition.X, 2) + MathF.Pow(tileref.Y - xform.LocalPosition.Y, 2)) > entry.MaxRange) + if (!_random.Prob(component.SpawnChance)) continue; - - //cut inner circle - if (MathF.Sqrt(MathF.Pow(tileref.X - xform.LocalPosition.X, 2) + MathF.Pow(tileref.Y - xform.LocalPosition.Y, 2)) < entry.MinRange) - continue; - - amountCounter++; - var tile = (ContentTileDefinition) _tiledef[entry.Floor]; - _tile.ReplaceTile(tileref, tile); - - if (amountCounter >= amount) - return; + _tile.ReplaceTile(tileref, fleshTile); } } } diff --git a/Content.Shared/Anomaly/Components/AnomalyComponent.cs b/Content.Shared/Anomaly/Components/AnomalyComponent.cs index 89afbb0122..0e83861863 100644 --- a/Content.Shared/Anomaly/Components/AnomalyComponent.cs +++ b/Content.Shared/Anomaly/Components/AnomalyComponent.cs @@ -268,13 +268,13 @@ public readonly record struct AnomalyShutdownEvent(EntityUid Anomaly, bool Super /// /// The anomaly being changed [ByRefEvent] -public readonly record struct AnomalySeverityChangedEvent(EntityUid Anomaly, float Stability, float Severity); +public readonly record struct AnomalySeverityChangedEvent(EntityUid Anomaly, float Severity); /// /// Event broadcast when an anomaly's stability is changed. /// [ByRefEvent] -public readonly record struct AnomalyStabilityChangedEvent(EntityUid Anomaly, float Stability, float Severity); +public readonly record struct AnomalyStabilityChangedEvent(EntityUid Anomaly, float Stability); /// /// Event broadcast when an anomaly's health is changed. diff --git a/Content.Shared/Anomaly/Effects/Components/EntitySpawnAnomalyComponent.cs b/Content.Shared/Anomaly/Effects/Components/EntitySpawnAnomalyComponent.cs index 6b4ea208c3..7a816e4312 100644 --- a/Content.Shared/Anomaly/Effects/Components/EntitySpawnAnomalyComponent.cs +++ b/Content.Shared/Anomaly/Effects/Components/EntitySpawnAnomalyComponent.cs @@ -2,71 +2,52 @@ using Robust.Shared.Prototypes; namespace Content.Shared.Anomaly.Effects.Components; -[RegisterComponent, Access(typeof(SharedEntityAnomalySystem))] +[RegisterComponent] public sealed partial class EntitySpawnAnomalyComponent : Component -{ - /// - /// All types of entity spawns with their settings - /// - [DataField] - public List Entries = new(); -} - -[DataDefinition, Serializable] -public partial record struct EntitySpawnSettingsEntry() { /// /// A list of entities that are random picked to be spawned on each pulse /// [DataField] - public List Spawns { get; set; } = new(); + public List Spawns = new(); /// - /// The minimum number of entities that spawn per pulse + /// A list of entities that are random picked to be spawned when supercritical; /// [DataField] - public int MinAmount { get; set; } = 0; + public List SuperCriticalSpawns = new(); /// /// The maximum number of entities that spawn per pulse /// scales with severity. /// - [DataField] - public int MaxAmount { get; set; } = 1; - - /// - /// The distance from the anomaly in which the entities will not appear - /// - [DataField] - public float MinRange { get; set; } = 0f; + [DataField("maxSpawnAmount"), ViewVariables(VVAccess.ReadWrite)] + public int MaxSpawnAmount = 7; /// /// The maximum radius the entities will spawn in. + /// Also governs the maximum reach of flesh tiles + /// scales with stability /// - [DataField] - public float MaxRange { get; set; } = 1f; + [DataField("spawnRange"), ViewVariables(VVAccess.ReadWrite)] + public float SpawnRange = 5f; /// /// Whether or not anomaly spawns entities on Pulse /// - [DataField] - public bool SpawnOnPulse { get; set; } = false; + [DataField, ViewVariables(VVAccess.ReadWrite)] + public bool SpawnOnPulse = true; /// /// Whether or not anomaly spawns entities on SuperCritical /// - [DataField] - public bool SpawnOnSuperCritical { get; set; } = false; + [DataField, ViewVariables(VVAccess.ReadWrite)] + public bool SpawnOnSuperCritical = true; /// /// Whether or not anomaly spawns entities on StabilityChanged + /// The idea was to spawn entities either on Pulse/Supercritical OR StabilityChanged /// - [DataField] - public bool SpawnOnStabilityChanged { get; set; } = false; - - /// - /// Whether or not anomaly spawns entities on SeverityChanged - /// - [DataField] - public bool SpawnOnSeverityChanged { get; set; } = false; + [DataField, ViewVariables(VVAccess.ReadWrite)] + public bool SpawnOnStabilityChanged = false; } diff --git a/Content.Shared/Anomaly/Effects/Components/TileSpawnAnomaly.cs b/Content.Shared/Anomaly/Effects/Components/TileSpawnAnomaly.cs new file mode 100644 index 0000000000..7e3125ba20 --- /dev/null +++ b/Content.Shared/Anomaly/Effects/Components/TileSpawnAnomaly.cs @@ -0,0 +1,26 @@ +using Content.Shared.Maps; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Anomaly.Effects.Components; + +[RegisterComponent] +public sealed partial class TileSpawnAnomalyComponent : Component +{ + /// + /// The maximum radius of tiles scales with stability + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public float SpawnRange = 5f; + + /// + /// The probability a tile will spawn. + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public float SpawnChance = 0.33f; + + /// + /// The tile that is spawned by the anomaly's effect + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public ProtoId FloorTileId = "FloorFlesh"; +} diff --git a/Content.Shared/Anomaly/Effects/Components/TileSpawnAnomalyComponent.cs b/Content.Shared/Anomaly/Effects/Components/TileSpawnAnomalyComponent.cs deleted file mode 100644 index 1e54803948..0000000000 --- a/Content.Shared/Anomaly/Effects/Components/TileSpawnAnomalyComponent.cs +++ /dev/null @@ -1,73 +0,0 @@ -using Content.Shared.Maps; -using Robust.Shared.Prototypes; - -namespace Content.Shared.Anomaly.Effects.Components; - -[RegisterComponent, Access(typeof(SharedTileAnomalySystem))] -public sealed partial class TileSpawnAnomalyComponent : Component -{ - /// - /// All types of floors spawns with their settings - /// - [DataField] - public List Entries = new(); -} - -[DataDefinition, Serializable] -public partial record struct TileSpawnSettingsEntry() -{ - /// - /// The tile that is spawned by the anomaly's effect - /// - [DataField(required: true)] - public ProtoId Floor { get; set; } = default!; - - /// - /// The minimum number of tiles that spawn per pulse - /// - [DataField] - public int MinAmount { get; set; } = 0; - - /// - /// The maximum number of tiles that spawn per pulse - /// scales with severity. - /// - [DataField] - public int MaxAmount { get; set; } = 1; - - /// - /// The distance from the anomaly in which the tiles will not appear - /// - [DataField] - public float MinRange { get; set; } = 0f; - - /// - /// The maximum radius the tiles will spawn in. - /// - [DataField] - public float MaxRange { get; set; } = 1f; - - /// - /// Whether or not anomaly spawns tiles on Pulse - /// - [DataField] - public bool SpawnOnPulse { get; set; } = false; - - /// - /// Whether or not anomaly spawns tiles on SuperCritical - /// - [DataField] - public bool SpawnOnSuperCritical { get; set; } = false; - - /// - /// Whether or not anomaly spawns tiles on StabilityChanged - /// - [DataField] - public bool SpawnOnStabilityChanged { get; set; } = false; - - /// - /// Whether or not anomaly spawns tiles on StabilityChanged - /// - [DataField] - public bool SpawnOnSeverityChanged { get; set; } = false; -} diff --git a/Content.Shared/Anomaly/Effects/SharedEntityAnomalySystem.cs b/Content.Shared/Anomaly/Effects/SharedEntityAnomalySystem.cs deleted file mode 100644 index 28732f4022..0000000000 --- a/Content.Shared/Anomaly/Effects/SharedEntityAnomalySystem.cs +++ /dev/null @@ -1,6 +0,0 @@ - -namespace Content.Shared.Anomaly.Effects; - -public abstract class SharedEntityAnomalySystem : EntitySystem -{ -} diff --git a/Content.Shared/Anomaly/Effects/SharedTileAnomalySystem.cs b/Content.Shared/Anomaly/Effects/SharedTileAnomalySystem.cs deleted file mode 100644 index 199c6b6f13..0000000000 --- a/Content.Shared/Anomaly/Effects/SharedTileAnomalySystem.cs +++ /dev/null @@ -1,6 +0,0 @@ - -namespace Content.Shared.Anomaly.Effects; - -public abstract class SharedTileAnomalySystem : EntitySystem -{ -} diff --git a/Content.Shared/Anomaly/SharedAnomalySystem.cs b/Content.Shared/Anomaly/SharedAnomalySystem.cs index 7390cbda0a..c014ff90e1 100644 --- a/Content.Shared/Anomaly/SharedAnomalySystem.cs +++ b/Content.Shared/Anomaly/SharedAnomalySystem.cs @@ -227,7 +227,7 @@ public abstract class SharedAnomalySystem : EntitySystem component.Stability = Math.Clamp(newVal, 0, 1); Dirty(component); - var ev = new AnomalyStabilityChangedEvent(uid, component.Stability, component.Severity); + var ev = new AnomalyStabilityChangedEvent(uid, component.Stability); RaiseLocalEvent(uid, ref ev, true); } @@ -250,7 +250,7 @@ public abstract class SharedAnomalySystem : EntitySystem component.Severity = Math.Clamp(newVal, 0, 1); Dirty(component); - var ev = new AnomalySeverityChangedEvent(uid, component.Stability, component.Severity); + var ev = new AnomalySeverityChangedEvent(uid, component.Severity); RaiseLocalEvent(uid, ref ev, true); } diff --git a/Resources/Prototypes/Entities/Effects/wallspawn.yml b/Resources/Prototypes/Entities/Effects/wallspawn.yml index f1bd236a8a..2010b8e73e 100644 --- a/Resources/Prototypes/Entities/Effects/wallspawn.yml +++ b/Resources/Prototypes/Entities/Effects/wallspawn.yml @@ -26,57 +26,15 @@ prototype: AsteroidRock - type: entity - id: WallSpawnAsteroidUraniumCrab + id: WallSpawnAsteroidCrab parent: WallSpawnAsteroid components: - type: SpawnOnDespawn - prototype: AsteroidRockUraniumCrab + prototype: AsteroidRockCrab - type: entity - id: WallSpawnAsteroidUranium + id: WallSpawnAsteroidCrab1 parent: WallSpawnAsteroid components: - type: SpawnOnDespawn - prototype: AsteroidRockUranium - -- type: entity - id: WallSpawnAsteroidQuartzCrab - parent: WallSpawnAsteroid - components: - - type: SpawnOnDespawn - prototype: AsteroidRockQuartzCrab - -- type: entity - id: WallSpawnAsteroidQuartz - parent: WallSpawnAsteroid - components: - - type: SpawnOnDespawn - prototype: AsteroidRockQuartz - -- type: entity - id: WallSpawnAsteroidSilverCrab - parent: WallSpawnAsteroid - components: - - type: SpawnOnDespawn - prototype: AsteroidRockSilverCrab - -- type: entity - id: WallSpawnAsteroidSilver - parent: WallSpawnAsteroid - components: - - type: SpawnOnDespawn - prototype: AsteroidRockSilver - -- type: entity - id: WallSpawnAsteroidIronCrab - parent: WallSpawnAsteroid - components: - - type: SpawnOnDespawn - prototype: AsteroidRockTinCrab - -- type: entity - id: WallSpawnAsteroidIron - parent: WallSpawnAsteroid - components: - - type: SpawnOnDespawn - prototype: AsteroidRockTin \ No newline at end of file + prototype: AsteroidRockCrab1 diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Random/anomaly.yml b/Resources/Prototypes/Entities/Markers/Spawners/Random/anomaly.yml index c81c840fb0..6d2149965f 100644 --- a/Resources/Prototypes/Entities/Markers/Spawners/Random/anomaly.yml +++ b/Resources/Prototypes/Entities/Markers/Spawners/Random/anomaly.yml @@ -16,26 +16,8 @@ - AnomalyFlesh - AnomalyBluespace - AnomalyIce - - RandomRockAnomalySpawner + - AnomalyRock - AnomalyLiquid - AnomalyFlora chance: 1 offset: 0.15 # not to put it higher. The anomaly sychnronizer looks for anomalies within this radius, and if the radius is higher, the anomaly can be attracted from a neighboring tile. - -- type: entity - id: RandomRockAnomalySpawner - parent: MarkerBase - components: - - type: Sprite - layers: - - state: red - - sprite: Structures/Specific/anomaly.rsi - state: anom6 - - type: RandomSpawner - prototypes: - - AnomalyRockIron - - AnomalyRockSilver - - AnomalyRockQuartz - - AnomalyRockUranium - chance: 1 - offset: 0.15 \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Random/asteroidcrab.yml b/Resources/Prototypes/Entities/Markers/Spawners/Random/asteroidcrab.yml new file mode 100644 index 0000000000..4c4b969335 --- /dev/null +++ b/Resources/Prototypes/Entities/Markers/Spawners/Random/asteroidcrab.yml @@ -0,0 +1,31 @@ +- type: entity + name: Asteroid Crab Spawner + id: AsteroidCrabSpawner + parent: MarkerBase + components: + - type: Sprite + layers: + - state: red + - sprite: Structures/Walls/rock.rsi + state: rock_asteroid_ore + - type: RandomSpawner + prototypes: + - AsteroidRockCrab + - AsteroidRockCrab1 + chance: 1 + +- type: entity + name: Rock Anom Crab Spawner + id: RockAnomCrabSpawner + parent: MarkerBase + components: + - type: Sprite + layers: + - state: red + - sprite: Structures/Walls/rock.rsi + state: rock_asteroid_ore + - type: RandomSpawner + prototypes: + - WallSpawnAsteroidCrab + - WallSpawnAsteroidCrab1 + chance: 1 \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Objects/Misc/ice_crust.yml b/Resources/Prototypes/Entities/Objects/Misc/ice_crust.yml index bc3488aaf4..ad1f876675 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/ice_crust.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/ice_crust.yml @@ -10,7 +10,8 @@ - type: MeleeSound soundGroups: Brute: - collection: GlassBreak + path: + "/Audio/Weapons/slash.ogg" - type: Sprite sprite: Objects/Misc/ice_crust.rsi layers: diff --git a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml index 2a4a934861..aecef8c637 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomalies.yml @@ -147,58 +147,16 @@ color: "#cb5b7e" castShadows: false - type: TileSpawnAnomaly - entries: - - spawnOnPulse: true - spawnOnStabilityChanged: true - minAmount: 3 - maxAmount: 7 - maxRange: 4 - floor: FloorFlesh - - spawnOnSuperCritical: true - minAmount: 10 - maxAmount: 30 - maxRange: 10 - floor: FloorFlesh + floorTileId: FloorFlesh - type: EntitySpawnAnomaly - entries: - - spawnOnPulse: true - minAmount: 1 - maxAmount: 4 - minRange: 1.5 - maxRange: 2.5 - spawns: - - FleshBlocker - - spawnOnPulse: true - maxAmount: 3 - minRange: 3 - maxRange: 4.5 - spawns: - - MobFleshJared - - MobFleshGolem - - MobFleshClamp - - MobFleshLover - - spawnOnSuperCritical: true - minAmount: 10 - maxAmount: 15 - minRange: 5 - maxRange: 15 - spawns: - - FleshBlocker - - spawnOnSuperCritical: true - minAmount: 5 - maxAmount: 10 - maxRange: 8 - spawns: - - MobFleshJared - - MobFleshGolem - - MobFleshClamp - - MobFleshLover - - spawnOnSuperCritical: true - minAmount: 5 - maxAmount: 8 - maxRange: 10 - spawns: - - FleshKudzu + superCriticalSpawns: + - FleshKudzu + spawns: + - MobFleshJared + - MobFleshGolem + - MobFleshClamp + - MobFleshLover + - FleshBlocker - type: entity id: AnomalyBluespace @@ -283,13 +241,12 @@ projectilePrototype: ProjectileIcicle targetNonSentientChance: 0.1 - type: EntitySpawnAnomaly - entries: - - spawnOnStabilityChanged: true - minAmount: 5 - maxAmount: 15 - maxRange: 4 - spawns: - - IceCrust + spawns: + - IceCrust + maxSpawnAmount: 17 + spawnOnPulse: false + spawnOnSuperCritical: false + spawnOnStabilityChanged: true - type: TempAffectingAnomaly tempChangePerSecond: -25 hotspotExposeTemperature: -1000 @@ -299,9 +256,8 @@ spawnRadius: 0 - type: entity - id: AnomalyRockBase + id: AnomalyRock parent: BaseAnomaly - abstract: true suffix: Rock components: - type: Anomaly @@ -320,201 +276,18 @@ color: "#5ca8cb" castShadows: false - type: TileSpawnAnomaly - entries: - - spawnOnPulse: true - minAmount: 15 - maxAmount: 20 - maxRange: 7.5 - floor: FloorAsteroidTile - - spawnOnSuperCritical: true - minAmount: 30 - maxAmount: 50 - maxRange: 12 - floor: FloorAsteroidTile - -- type: entity - id: AnomalyRockUranium - parent: AnomalyRockBase - suffix: Rock, Uranium - components: - - type: Sprite - color: "#52ff39" - - type: PointLight - radius: 2.0 - energy: 7.5 - color: "#52ff39" + floorTileId: FloorAsteroidTile + spawnChance: 0.8 - type: EntitySpawnAnomaly - entries: - - spawnOnPulse: true - minAmount: 8 - maxAmount: 15 - minRange: 4.5 - maxRange: 7.5 - spawns: - - WallSpawnAsteroid - - WallSpawnAsteroid - - WallSpawnAsteroidUranium - - WallSpawnAsteroidUraniumCrab - - spawnOnPulse: true - maxAmount: 3 - minRange: 2.5 - maxRange: 4.5 - spawns: - - CrystalGreen - - spawnOnSuperCritical: true - minAmount: 30 - maxAmount: 40 - minRange: 5 - maxRange: 15 - spawns: - - CrystalGreen - - WallSpawnAsteroid - - WallSpawnAsteroid - - WallSpawnAsteroidUraniumCrab - - spawnOnSuperCritical: true - minAmount: 6 - maxAmount: 10 - maxRange: 5 - spawns: - - MobSpawnCrabUranium - -- type: entity - id: AnomalyRockQuartz - parent: AnomalyRockBase - suffix: Rock, Quartz - components: - - type: Sprite - color: "#fb4747" - - type: PointLight - radius: 2.0 - energy: 7.5 - color: "#fb4747" - - type: EntitySpawnAnomaly - entries: - - spawnOnPulse: true - minAmount: 8 - maxAmount: 15 - minRange: 4.5 - maxRange: 7.5 - spawns: - - WallSpawnAsteroid - - WallSpawnAsteroid - - WallSpawnAsteroidQuartz - - WallSpawnAsteroidQuartzCrab - - spawnOnPulse: true - maxAmount: 3 - minRange: 2.5 - maxRange: 4.5 - spawns: - - CrystalGrey - - spawnOnSuperCritical: true - minAmount: 30 - maxAmount: 40 - minRange: 5 - maxRange: 15 - spawns: - - CrystalGrey - - WallSpawnAsteroid - - WallSpawnAsteroid - - WallSpawnAsteroidQuartzCrab - - spawnOnSuperCritical: true - minAmount: 6 - maxAmount: 10 - maxRange: 5 - spawns: - - MobSpawnCrabQuartz - -- type: entity - id: AnomalyRockSilver - parent: AnomalyRockBase - suffix: Rock, Silver - components: - - type: Sprite - color: "#47f8ff" - - type: PointLight - radius: 2.0 - energy: 7.5 - color: "#47f8ff" - - type: EntitySpawnAnomaly - entries: - - spawnOnPulse: true - minAmount: 8 - maxAmount: 15 - minRange: 4.5 - maxRange: 7.5 - spawns: - - WallSpawnAsteroid - - WallSpawnAsteroid - - WallSpawnAsteroidSilver - - WallSpawnAsteroidSilverCrab - - spawnOnPulse: true - maxAmount: 3 - minRange: 2.5 - maxRange: 4.5 - spawns: - - CrystalCyan - - spawnOnSuperCritical: true - minAmount: 30 - maxAmount: 40 - minRange: 5 - maxRange: 15 - spawns: - - CrystalCyan - - WallSpawnAsteroid - - WallSpawnAsteroid - - WallSpawnAsteroidSilverCrab - - spawnOnSuperCritical: true - minAmount: 6 - maxAmount: 10 - maxRange: 5 - spawns: - - MobSpawnCrabSilver - -- type: entity - id: AnomalyRockIron - parent: AnomalyRockBase - suffix: Rock, Iron - components: - - type: Sprite - color: "#ff8227" - - type: PointLight - radius: 2.0 - energy: 7.5 - color: "#ff8227" - - type: EntitySpawnAnomaly - entries: - - spawnOnPulse: true - minAmount: 8 - maxAmount: 15 - minRange: 4.5 - maxRange: 7.5 - spawns: - - WallSpawnAsteroid - - WallSpawnAsteroid - - WallSpawnAsteroidIron - - WallSpawnAsteroidIronCrab - - spawnOnPulse: true - maxAmount: 3 - minRange: 2.5 - maxRange: 4.5 - spawns: - - CrystalOrange - - spawnOnSuperCritical: true - minAmount: 30 - maxAmount: 40 - minRange: 5 - maxRange: 15 - spawns: - - CrystalOrange - - WallSpawnAsteroid - - WallSpawnAsteroid - - WallSpawnAsteroidIronCrab - - spawnOnSuperCritical: true - minAmount: 6 - maxAmount: 10 - maxRange: 5 - spawns: - - MobSpawnCrabIron + maxSpawnAmount: 50 + spawnRange: 10 + spawns: + - WallSpawnAsteroid + - RockAnomCrabSpawner + - CrystalSpawner + superCriticalSpawns: + - WallSpawnAsteroid + - SpawnMobOreCrab - type: entity id: AnomalyFlora @@ -543,31 +316,15 @@ types: Slash: 0 - type: TileSpawnAnomaly - entries: - - spawnOnPulse: true - minAmount: 3 - maxAmount: 7 - maxRange: 5 - floor: FloorAstroGrass - - spawnOnSuperCritical: true - minAmount: 10 - maxAmount: 30 - maxRange: 15 - floor: FloorAstroGrass + floorTileId: FloorAstroGrass + spawnRange: 6 - type: EntitySpawnAnomaly - entries: - - spawnOnPulse: true - minAmount: 2 - maxAmount: 5 - maxRange: 2 - spawns: - - KudzuFlowerFriendly - - spawnOnSuperCritical: true - minAmount: 5 - maxAmount: 10 - maxRange: 6 - spawns: - - KudzuFlowerAngry + maxSpawnAmount: 15 + spawnRange: 6 + superCriticalSpawns: + - KudzuFlowerAngry + spawns: + - KudzuFlowerFriendly - type: entity id: AnomalyFloraBulb @@ -643,13 +400,10 @@ types: Slash: 1 - type: EntitySpawnAnomaly - entries: - - spawnOnSuperCritical: true - minAmount: 3 - maxAmount: 8 - maxRange: 2 - spawns: - - ReagentSlimeSpawner + superCriticalSpawns: + - ReagentSlimeSpawner + spawns: + - PuddleSparkle - type: SolutionContainerManager solutions: anomaly: diff --git a/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml b/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml index aa5f1421c7..d5c542a0a1 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml @@ -148,28 +148,6 @@ state: rock_asteroid_west - state: rock_quartz -- type: entity - id: AsteroidRockQuartzCrab - parent: AsteroidRock - description: An ore vein rich with quartz. - suffix: Quartz Crab - components: - - type: OreVein - oreChance: 1.0 - currentOre: OreQuartzCrab - - type: Sprite - layers: - - state: rock_asteroid - - map: [ "enum.EdgeLayer.South" ] - state: rock_asteroid_south - - map: [ "enum.EdgeLayer.East" ] - state: rock_asteroid_east - - map: [ "enum.EdgeLayer.North" ] - state: rock_asteroid_north - - map: [ "enum.EdgeLayer.West" ] - state: rock_asteroid_west - - state: rock_quartz - - type: entity id: AsteroidRockSilver parent: AsteroidRock @@ -191,15 +169,6 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_asteroid_west - state: rock_silver - -- type: entity - id: AsteroidRockSilverCrab - parent: AsteroidRockSilver - suffix: Silver Crab - components: - - type: OreVein - oreChance: 1.0 - currentOre: OreSilverCrab # Yes I know it drops steel but we may get smelting at some point - type: entity @@ -223,15 +192,6 @@ - map: [ "enum.EdgeLayer.West" ] state: rock_asteroid_west - state: rock_tin - -- type: entity - id: AsteroidRockTinCrab - parent: AsteroidRockTin - suffix: Iron - components: - - type: OreVein - oreChance: 1.0 - currentOre: OreIronCrab - type: entity id: AsteroidRockUranium @@ -255,14 +215,6 @@ state: rock_asteroid_west - state: rock_uranium -- type: entity - id: AsteroidRockUraniumCrab - parent: AsteroidRockUranium - suffix: Uranium Crab - components: - - type: OreVein - oreChance: 1.0 - currentOre: OreUraniumCrab - type: entity id: AsteroidRockBananium @@ -319,6 +271,46 @@ oreChance: 0.33 oreRarityPrototypeId: RandomOreDistributionStandard +- type: entity + id: AsteroidRockCrab + parent: AsteroidRock + name: asteroid rock + suffix: orecrab + description: An asteroid. + components: + - type: Sprite + sprite: Structures/Walls/rock.rsi + layers: + - state: rock_asteroid_ore + - map: [ "enum.EdgeLayer.South" ] + state: rock_asteroid_south + - map: [ "enum.EdgeLayer.East" ] + state: rock_asteroid_east + - map: [ "enum.EdgeLayer.North" ] + state: rock_asteroid_north + - map: [ "enum.EdgeLayer.West" ] + state: rock_asteroid_west + - type: OreVein + oreChance: 0.33 + oreRarityPrototypeId: OreCrab + +- type: entity + id: AsteroidRockCrab1 + parent: AsteroidRockCrab + components: + - type: Sprite + sprite: Structures/Walls/rock.rsi + layers: + - state: rock_asteroid_ore1 + - map: [ "enum.EdgeLayer.South" ] + state: rock_asteroid_south + - map: [ "enum.EdgeLayer.East" ] + state: rock_asteroid_east + - map: [ "enum.EdgeLayer.North" ] + state: rock_asteroid_north + - map: [ "enum.EdgeLayer.West" ] + state: rock_asteroid_west + - type: entity id: IronRock parent: AsteroidRock diff --git a/Resources/Textures/Structures/Specific/anomaly.rsi/anom6-pulse.png b/Resources/Textures/Structures/Specific/anomaly.rsi/anom6-pulse.png index cfeabdaa8131470a8d54c12755fe3a83f06bdb93..f92a77a95ed07e8d75d6211cbf7841b4f44ce5e0 100644 GIT binary patch literal 23507 zcmeHvcT|&0v~Q>a(orc=LIgz*ffNW3AynzTNf9xmK%@kdP(-TIEudmS1Vj+zAVop3 zQ3M49MVcZi0v4)DFH+x!SkU9S_vD^;-(B~uWUY{onO$an`!{>`%pYHzrMUqQmlzia z1mZC=)UyVD!-20B2Rrb$D)(S0unLy{xi-16SPf4~8GzT+NG>+`8 zfW?#D2nvDTzJN3cq^=q0i^X{oXka&jJIO}_GJK~30w&=#AUl=KU}nC$1P_v75QSh9 zWNwQK^2Dj(A(|L2^*}UWz?(qBf&;z1e5mL^4agU}XyAFdSrG#MB0}@jfM_o}1Ur~n zf_2Fh0$5oA1;xQoDqs~g1-P<`ijs;v7y*MTE5eY9NEj4>L@UA2N(k`R4+O&nJgHOg zM6|V@{#SRve;N=E8qF82s2C6spb&smAXD5G;c9AXiZFyC0s#dipw#_7G;AQ$hq`IS z$TvHB1S*a~@}-f;KHz1$SU0jCO#=d1cJ%%8bza`S-yQi-zhVcVs2GU#RfH?R6o03L z$9>oF^`m%w85$m^Nbn+f6MSe?Ko9;~JzozpjZF0*|BcJ<-GA#Ch>4lmci+DquebMa zT~ld0`~e8QLi$@xs_lMXf}%BnO7^4R2s`|Nscib)?5Q+s!jI_u15<$bZw=8%#J{n# z-1D~}5CTbmqqf|$qV|PTE1^~gKttyo|56ku2c3{qY3cg?@m(j(*imY0UM4~{?u;y_&$A0SF!7QYVG{pZ$i z9bP2NO6tLraU?wYhf{(7%}jnsbx z#WK0f%+N+YR2mjQ%193bG$@dON#l_?C9InY0t!PCuuxTm5)7)UtfmT8RZ~_*VBrWP z!43X}GC!;TnDkfE-@F5+e?M^~Rz(f2rmPB8c7wYuPn-aCBd8Fecmhlbizg6J%4)=K zj#e4_iz5pP3D|A0UaMr5=Yj|3qJ~#i#S#HnVajeQP-VCh5sF2+;Q*+WP-;Xh5k*)I z+X@uFG4mH!hNNXm?f*H#Unpfm*!Oem4@!O67ksf4Dq%V6X+XZEz3&^z3QN9n5d1~`?|lS#5Pbe77p++NBJlV6R5Fnk zfTa+$-GNp5Pcr0+)t}XVHUIks@_#1=WFLP5g`Ow?vBm<03jxSIL<-p({5|D?X=E_g z*Vl`L!!Czc(ccIEwG8;4X}*Pem5u+0bERVa{~g;@V0d6zV^yG7V0}T6L}03LFcCyQu=@1zZV8`>I$36bXaFRMZd%912JHHosLF=GQ6yK;`EYp=t}18A_^X z#B#a92-?@o{;#vjf09U+bItd}^9}d^nXG~*P)PLTl~tp}eS-=7C6oT|ne)HSq*yng zz63UJs2bc20VOCa0o4&ql?YV-ZbUZ}5{W{peXk1`i*mUT`cj8^k^V)w^{<2W&uZuY z+V=O`liU9X>2#%Z`?-GpR+Im=-u`yDSV<}R%jMPb(FjNx|4DfbY}ml%0D9F@`F7y> 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 Hu0mjf`Bn}* diff --git a/Resources/Textures/Structures/Specific/anomaly.rsi/anom6.png b/Resources/Textures/Structures/Specific/anomaly.rsi/anom6.png index 14fc7d80c00005711861c259c827ecd110abd3ec..04c772bca1787588e9b44b43109fbc5d815fe3e6 100644 GIT binary patch literal 18861 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 delta 3051 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