Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vent critters rework #2495

Merged
merged 5 commits into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading