Skip to content

Commit

Permalink
vent critters rework (#2495)
Browse files Browse the repository at this point in the history
* vent critters rework

* change pests timer to 15

* nullspace check and loggy

* OH

* 15 -> 30 seconds

---------

Co-authored-by: deltanedas <@deltanedas:kde.org>
  • Loading branch information
deltanedas authored Dec 23, 2024
1 parent ff62b2a commit 9beaf06
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Content.Server.StationEvents.Events;
using Content.Shared.Storage;
using Robust.Shared.Map; // DeltaV

namespace Content.Server.StationEvents.Components;

Expand All @@ -14,4 +15,28 @@ public sealed partial class VentCrittersRuleComponent : Component
/// </summary>
[DataField("specialEntries")]
public List<EntitySpawnEntry> SpecialEntries = new();

/// <summary>
/// DeltaV: The location of the vent that got picked.
/// </summary>
[ViewVariables]
public EntityCoordinates? Location;

/// <summary>
/// DeltaV: Base minimum number of critters to spawn.
/// </summary>
[DataField]
public int Min = 2;

/// <summary>
/// DeltaV: Base maximum number of critters to spawn.
/// </summary>
[DataField]
public int Max = 3;

/// <summary>
/// DeltaV: Min and max get multiplied by the player count then divided by this.
/// </summary>
[DataField]
public int PlayerRatio = 25;
}
86 changes: 63 additions & 23 deletions Content.Server/StationEvents/Events/VentCrittersRule.cs
Original file line number Diff line number Diff line change
@@ -1,59 +1,99 @@
using Content.Server.StationEvents.Components;
using Content.Server.Antag;
using Content.Server.GameTicking.Rules.Components;
using Content.Server.Pinpointer;
using Content.Server.StationEvents.Components;
using Content.Shared.GameTicking.Components;
using Content.Shared.Station.Components;
using Content.Shared.Storage;
using Robust.Shared.Map;
using Robust.Shared.Player;
using Robust.Shared.Random;

namespace Content.Server.StationEvents.Events;

/// <summary>
/// DeltaV: Reworked vent critters to spawn a number of mobs at a single telegraphed location.
/// This gives players time to run away and let sec do their job.
/// </summary>
/// <remarks>
/// This entire file is rewritten, ignore upstream changes.
/// </remarks>
public sealed class VentCrittersRule : StationEventSystem<VentCrittersRuleComponent>
{
/*
* DO NOT COPY PASTE THIS TO MAKE YOUR MOB EVENT.
* USE THE PROTOTYPE.
*/

protected override void Started(EntityUid uid, VentCrittersRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args)
{
base.Started(uid, component, gameRule, args);
[Dependency] private readonly AntagSelectionSystem _antag = default!;
[Dependency] private readonly ISharedPlayerManager _player = default!;
[Dependency] private readonly NavMapSystem _navMap = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;

if (!TryGetRandomStation(out var station))
private List<EntityCoordinates> _locations = new();

protected override void Added(EntityUid uid, VentCrittersRuleComponent comp, GameRuleComponent gameRule, GameRuleAddedEvent args)
{
PickLocation(comp);
if (comp.Location is not {} coords)
{
ForceEndSelf(uid, gameRule);
return;
}

var locations = EntityQueryEnumerator<VentCritterSpawnLocationComponent, TransformComponent>();
var validLocations = new List<EntityCoordinates>();
while (locations.MoveNext(out _, out _, out var transform))
var mapCoords = _transform.ToMapCoordinates(coords);
if (!_navMap.TryGetNearestBeacon(mapCoords, out var beacon, out _))
return;

var nearest = beacon?.Comp?.Text!;
Comp<StationEventComponent>(uid).StartAnnouncement = Loc.GetString("station-event-vent-creatures-start-announcement-deltav", ("location", nearest));

base.Added(uid, comp, gameRule, args);
}

protected override void Ended(EntityUid uid, VentCrittersRuleComponent comp, GameRuleComponent gameRule, GameRuleEndedEvent args)
{
base.Ended(uid, comp, gameRule, args);

if (comp.Location is not {} coords)
return;

var players = _antag.GetTotalPlayerCount(_player.Sessions);
var min = comp.Min * players / comp.PlayerRatio;
var max = comp.Max * players / comp.PlayerRatio;
var count = Math.Max(RobustRandom.Next(min, max), 1);
for (int i = 0; i < count; i++)
{
if (CompOrNull<StationMemberComponent>(transform.GridUid)?.Station == station)
foreach (var spawn in EntitySpawnCollection.GetSpawns(comp.Entries, RobustRandom))
{
validLocations.Add(transform.Coordinates);
foreach (var spawn in EntitySpawnCollection.GetSpawns(component.Entries, RobustRandom))
{
Spawn(spawn, transform.Coordinates);
}
Spawn(spawn, coords);
}
}

if (component.SpecialEntries.Count == 0 || validLocations.Count == 0)
{
if (comp.SpecialEntries.Count == 0)
return;
}

// guaranteed spawn
var specialEntry = RobustRandom.Pick(component.SpecialEntries);
var specialSpawn = RobustRandom.Pick(validLocations);
Spawn(specialEntry.PrototypeId, specialSpawn);
var specialEntry = RobustRandom.Pick(comp.SpecialEntries);
Spawn(specialEntry.PrototypeId, coords);
}

foreach (var location in validLocations)
private void PickLocation(VentCrittersRuleComponent comp)
{
if (!TryGetRandomStation(out var station))
return;

var locations = EntityQueryEnumerator<VentCritterSpawnLocationComponent, TransformComponent>();
_locations.Clear();
while (locations.MoveNext(out var uid, out _, out var transform))
{
foreach (var spawn in EntitySpawnCollection.GetSpawns(component.SpecialEntries, RobustRandom))
if (CompOrNull<StationMemberComponent>(transform.GridUid)?.Station == station)
{
Spawn(spawn, location);
_locations.Add(transform.Coordinates);
}
}

if (_locations.Count > 0)
comp.Location = RobustRandom.Pick(_locations);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
station-event-vent-creatures-start-announcement-deltav = Attention. A large influx of unknown life forms has been detected in ventilation systems near {$location}. All personnel must vacate the area immediately.
4 changes: 2 additions & 2 deletions Resources/Prototypes/DeltaV/GameRules/events.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
earliestStart: 45
minimumPlayers: 20
weight: 1
duration: 60
duration: 30
- type: PrecognitionResult
message: psionic-power-precognition-xeno-vents-result-message
- type: VentCrittersRule
Expand Down Expand Up @@ -75,7 +75,7 @@
earliestStart: 15
minimumPlayers: 15
weight: 4
duration: 60
duration: 30
- type: PrecognitionResult
message: psionic-power-precognition-mothroach-spawn-result-message
- type: VentCrittersRule
Expand Down
9 changes: 5 additions & 4 deletions Resources/Prototypes/GameRules/events.yml
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@
earliestStart: 20
minimumPlayers: 15
weight: 5
duration: 60
duration: 30 # DeltaV: was 60, used as a delay now
- type: PrecognitionResult # DeltaV - Precogniton
message: psionic-power-precognition-slimes-spawn-result-message
- type: VentCrittersRule
Expand All @@ -412,7 +412,7 @@
earliestStart: 20
minimumPlayers: 15
weight: 5
duration: 60
duration: 30 # DeltaV: was 60, used as a delay now
- type: PrecognitionResult # DeltaV - Precogniton
message: psionic-power-precognition-snake-spawn-result-message
- type: VentCrittersRule
Expand All @@ -435,7 +435,7 @@
earliestStart: 20
minimumPlayers: 15
weight: 5
duration: 60
duration: 30 # DeltaV: was 60, used as a delay now
- type: PrecognitionResult # DeltaV - Precogniton
message: psionic-power-precognition-spider-spawn-result-message
- type: VentCrittersRule
Expand All @@ -454,10 +454,11 @@
earliestStart: 45 # DeltaV - was 20
minimumPlayers: 30 # DeltaV - was 20
weight: 1 # DeltaV - was 1.5
duration: 60
duration: 30 # DeltaV: was 60, used as a delay now
- type: PrecognitionResult # DeltaV - Precogniton
message: psionic-power-precognition-spider-clown-spawn-result-message
- type: VentCrittersRule
playerRatio: 35 # DeltaV: Clown spiders are very robust
entries:
- id: MobClownSpider
prob: 0.03 # DeltaV - was 0.05
Expand Down
10 changes: 5 additions & 5 deletions Resources/Prototypes/GameRules/pests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
path: /Audio/Announcements/attention.ogg
earliestStart: 15
weight: 6
duration: 50
duration: 30 # DeltaV: was 50, used as a delay now
- type: PrecognitionResult # DeltaV - Precogniton
message: psionic-power-precognition-mouse-migration-result-message
- type: VentCrittersRule
Expand All @@ -52,7 +52,7 @@
path: /Audio/Announcements/attention.ogg
earliestStart: 15
weight: 6
duration: 50
duration: 30 # DeltaV: was 50, used as a delay now
minimumPlayers: 30 # Hopefully this is enough for the Rat King's potential Army (it was not, raised from 15 -> 30)
- type: PrecognitionResult # DeltaV - Precogniton
message: psionic-power-precognition-king-rat-migration-result-message
Expand All @@ -79,7 +79,7 @@
startAudio:
path: /Audio/Announcements/attention.ogg
weight: 6
duration: 50
duration: 30 # DeltaV: was 50, used as a delay now
- type: PrecognitionResult # DeltaV - Precogniton
message: psionic-power-precognition-cockroach-migration-result-message
- type: VentCrittersRule
Expand All @@ -98,7 +98,7 @@
startAudio:
path: /Audio/Announcements/attention.ogg
weight: 6
duration: 50
duration: 30 # DeltaV: was 50, used as a delay now
- type: PrecognitionResult # DeltaV - Precogniton
message: psionic-power-precognition-snail-migration-result-message
- type: VentCrittersRule
Expand All @@ -120,7 +120,7 @@
path: /Audio/Announcements/attention.ogg
earliestStart: 15
weight: 6
duration: 50
duration: 30 # DeltaV: was 50, used as a delay now
minimumPlayers: 30
- type: PrecognitionResult # DeltaV - Precogniton
message: psionic-power-precognition-snail-migration-result-message
Expand Down

0 comments on commit 9beaf06

Please sign in to comment.