]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Add evac shuttle test. (#27152)
authorLeon Friedrich <60421075+ElectroJr@users.noreply.github.com>
Sat, 20 Apr 2024 05:57:55 +0000 (17:57 +1200)
committerGitHub <noreply@github.com>
Sat, 20 Apr 2024 05:57:55 +0000 (15:57 +1000)
* Add evac shuttle test.

* Fix typo in comment

Content.IntegrationTests/Tests/Station/EvacShuttleTest.cs [new file with mode: 0644]
Content.Server/RoundEnd/RoundEndSystem.cs
Content.Server/Shuttles/Components/FTLComponent.cs
Content.Server/Shuttles/Systems/EmergencyShuttleSystem.Console.cs
Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs
Content.Server/Station/Systems/StationSystem.cs
Content.Shared/CCVar/CCVars.cs

diff --git a/Content.IntegrationTests/Tests/Station/EvacShuttleTest.cs b/Content.IntegrationTests/Tests/Station/EvacShuttleTest.cs
new file mode 100644 (file)
index 0000000..a01aac3
--- /dev/null
@@ -0,0 +1,111 @@
+using System.Linq;
+using Content.Server.GameTicking;
+using Content.Server.Shuttles.Components;
+using Content.Server.Shuttles.Systems;
+using Content.Server.Station.Components;
+using Content.Shared.CCVar;
+using Content.Shared.Shuttles.Components;
+using Robust.Shared.GameObjects;
+using Robust.Shared.Map.Components;
+
+namespace Content.IntegrationTests.Tests.Station;
+
+[TestFixture]
+[TestOf(typeof(EmergencyShuttleSystem))]
+public sealed class EvacShuttleTest
+{
+    /// <summary>
+    /// Ensure that the emergency shuttle can be called, and that it will travel to centcomm
+    /// </summary>
+    [Test]
+    public async Task EmergencyEvacTest()
+    {
+        await using var pair = await PoolManager.GetServerClient(new PoolSettings { DummyTicker = true, Dirty = true });
+        var server = pair.Server;
+        var entMan = server.EntMan;
+        var ticker = server.System<GameTicker>();
+
+        var shuttleEnabled = pair.Server.CfgMan.GetCVar(CCVars.EmergencyShuttleEnabled);
+        pair.Server.CfgMan.SetCVar(CCVars.GameMap, "Saltern");
+        pair.Server.CfgMan.SetCVar(CCVars.GameDummyTicker, false);
+        pair.Server.CfgMan.SetCVar(CCVars.EmergencyShuttleEnabled, true);
+
+        await server.WaitPost(() => ticker.RestartRound());
+        await pair.RunTicksSync(25);
+        Assert.That(ticker.RunLevel, Is.EqualTo(GameRunLevel.InRound));
+
+        // Find the station, centcomm, and shuttle, and ftl map.
+
+        Assert.That(entMan.Count<StationCentcommComponent>(), Is.EqualTo(1));
+        Assert.That(entMan.Count<StationEmergencyShuttleComponent>(), Is.EqualTo(1));
+        Assert.That(entMan.Count<StationDataComponent>(), Is.EqualTo(1));
+        Assert.That(entMan.Count<EmergencyShuttleComponent>(), Is.EqualTo(1));
+        Assert.That(entMan.Count<FTLMapComponent>(), Is.EqualTo(0));
+
+        var station = (Entity<StationCentcommComponent>) entMan.AllComponentsList<StationCentcommComponent>().Single();
+        var data = entMan.GetComponent<StationDataComponent>(station);
+        var shuttleData = entMan.GetComponent<StationEmergencyShuttleComponent>(station);
+
+        var saltern = data.Grids.Single();
+        Assert.That(entMan.HasComponent<MapGridComponent>(saltern));
+
+        var shuttle = shuttleData.EmergencyShuttle!.Value;
+        Assert.That(entMan.HasComponent<EmergencyShuttleComponent>(shuttle));
+        Assert.That(entMan.HasComponent<MapGridComponent>(shuttle));
+
+        var centcomm = station.Comp.Entity!.Value;
+        Assert.That(entMan.HasComponent<MapGridComponent>(centcomm));
+
+        var centcommMap = station.Comp.MapEntity!.Value;
+        Assert.That(entMan.HasComponent<MapComponent>(centcommMap));
+        Assert.That(server.Transform(centcomm).MapUid, Is.EqualTo(centcommMap));
+
+        var salternXform = server.Transform(saltern);
+        Assert.That(salternXform.MapUid, Is.Not.Null);
+        Assert.That(salternXform.MapUid, Is.Not.EqualTo(centcommMap));
+
+        var shuttleXform = server.Transform(shuttle);
+        Assert.That(shuttleXform.MapUid, Is.Not.Null);
+        Assert.That(shuttleXform.MapUid, Is.EqualTo(centcommMap));
+
+        // Set up shuttle timing
+        var evacSys = server.System<EmergencyShuttleSystem>();
+        evacSys.TransitTime = ShuttleSystem.DefaultTravelTime; // Absolute minimum transit time, so the test has to run for at least this long
+        // TODO SHUTTLE fix spaghetti
+
+        var dockTime = server.CfgMan.GetCVar(CCVars.EmergencyShuttleDockTime);
+        server.CfgMan.SetCVar(CCVars.EmergencyShuttleDockTime, 2);
+        async Task RunSeconds(float seconds)
+        {
+            await pair.RunTicksSync((int) Math.Ceiling(seconds / server.Timing.TickPeriod.TotalSeconds));
+        }
+
+        // Call evac shuttle.
+        await pair.WaitCommand("callshuttle 0:02");
+        await RunSeconds(3);
+
+        // Shuttle should have arrived on the station
+        Assert.That(shuttleXform.MapUid, Is.EqualTo(salternXform.MapUid));
+
+        await RunSeconds(2);
+
+        // Shuttle should be FTLing back to centcomm
+        Assert.That(entMan.Count<FTLMapComponent>(), Is.EqualTo(1));
+        var ftl = (Entity<FTLMapComponent>) entMan.AllComponentsList<FTLMapComponent>().Single();
+        Assert.That(entMan.HasComponent<MapComponent>(ftl));
+        Assert.That(ftl.Owner, Is.Not.EqualTo(centcommMap));
+        Assert.That(ftl.Owner, Is.Not.EqualTo(salternXform.MapUid));
+        Assert.That(shuttleXform.MapUid, Is.EqualTo(ftl.Owner));
+
+        // Shuttle should have arrived at centcomm
+        await RunSeconds(ShuttleSystem.DefaultTravelTime);
+        Assert.That(shuttleXform.MapUid, Is.EqualTo(centcommMap));
+
+        // Round should be ending now
+        Assert.That(ticker.RunLevel, Is.EqualTo(GameRunLevel.PostRound));
+
+        server.CfgMan.SetCVar(CCVars.EmergencyShuttleDockTime, dockTime);
+        pair.Server.CfgMan.SetCVar(CCVars.EmergencyShuttleEnabled, shuttleEnabled);
+        await pair.CleanReturnAsync();
+    }
+}
index 758e2e314640a1ea0e07d8aecea5817d3c9f2f16..42783f163bfe244fbbe784ad1a7507e9725e4d6a 100644 (file)
@@ -192,6 +192,8 @@ namespace Content.Server.RoundEnd
 
             LastCountdownStart = _gameTiming.CurTime;
             ExpectedCountdownEnd = _gameTiming.CurTime + countdownTime;
+
+            // TODO full game saves
             Timer.Spawn(countdownTime, _shuttle.CallEmergencyShuttle, _countdownTokenSource.Token);
 
             ActivateCooldown();
@@ -337,6 +339,8 @@ namespace Content.Server.RoundEnd
         {
             _cooldownTokenSource?.Cancel();
             _cooldownTokenSource = new();
+
+            // TODO full game saves
             Timer.Spawn(DefaultCooldownDuration, () =>
             {
                 _cooldownTokenSource.Cancel();
index a3da4855f753bece5dc538e55d7e268c4a932b05..edcf25981ba7a8276b80736a95ffafe11e8b422a 100644 (file)
@@ -14,6 +14,8 @@ namespace Content.Server.Shuttles.Components;
 [RegisterComponent]
 public sealed partial class FTLComponent : Component
 {
+    // TODO Full game save / add datafields
+
     [ViewVariables]
     public FTLState State = FTLState.Available;
 
@@ -23,6 +25,7 @@ public sealed partial class FTLComponent : Component
     [ViewVariables(VVAccess.ReadWrite)]
     public float StartupTime = 0f;
 
+    // Because of sphagetti, actual travel time is Math.Max(TravelTime, DefaultArrivalTime)
     [ViewVariables(VVAccess.ReadWrite)]
     public float TravelTime = 0f;
 
index aeb2ebdbba13cc4c24655a78a6ae159df9855eef..803aa963f390c39053948bf47abf42aa5beddb44 100644 (file)
@@ -19,6 +19,8 @@ using Timer = Robust.Shared.Timing.Timer;
 
 namespace Content.Server.Shuttles.Systems;
 
+// TODO full game saves
+// Move state data into the emergency shuttle component
 public sealed partial class EmergencyShuttleSystem
 {
     /*
@@ -55,7 +57,7 @@ public sealed partial class EmergencyShuttleSystem
     /// <summary>
     /// How long it will take for the emergency shuttle to arrive at CentComm.
     /// </summary>
-    public float TransitTime { get; private set; }
+    public float TransitTime;
 
     /// <summary>
     /// <see cref="CCVars.EmergencyShuttleAuthorizeTime"/>
@@ -132,6 +134,14 @@ public sealed partial class EmergencyShuttleSystem
         var minTime = -(TransitTime - (ShuttleSystem.DefaultStartupTime + ShuttleSystem.DefaultTravelTime + 1f));
 
         // TODO: I know this is shit but I already just cleaned up a billion things.
+
+        // This is very cursed spaghetti code. I don't even know what the fuck this is doing or why it exists.
+        // But I think it needs to be less than or equal to zero or the shuttle might never leave???
+        // TODO Shuttle AAAAAAAAAAAAAAAAAAAAAAAAA
+        // Clean this up, just have a single timer with some state system.
+        // I.e., dont infer state from the current interval that the accumulator is in???
+        minTime = Math.Min(0, minTime); // ????
+
         if (_consoleAccumulator < minTime)
         {
             return;
index 512886910395367508b94454504684a3136a06bf..b2b647369338c8eac1b4a664f0e80b3e7be15715 100644 (file)
@@ -40,6 +40,10 @@ public sealed partial class ShuttleSystem
     public const float FTLMassLimit = 300f;
 
     // I'm too lazy to make CVars.
+    // >:(
+    // Confusingly, some of them already are cvars?
+    // I.e., shuttle transit time???
+    // TODO Shuttle: fix spaghetti
 
     private readonly SoundSpecifier _startupSound = new SoundPathSpecifier("/Audio/Effects/Shuttle/hyperspace_begin.ogg")
     {
index 2ab33b62a50c98751c50da1838c7f70419f88bda..2fa2671b196493865269313ccd2fa13942c52301 100644 (file)
@@ -112,26 +112,12 @@ public sealed class StationSystem : EntitySystem
     {
         var dict = new Dictionary<string, List<EntityUid>>();
 
-        void AddGrid(string station, EntityUid grid)
-        {
-            if (dict.ContainsKey(station))
-            {
-                dict[station].Add(grid);
-            }
-            else
-            {
-                dict[station] = new List<EntityUid> {grid};
-            }
-        }
-
         // Iterate over all BecomesStation
         foreach (var grid in ev.Grids)
         {
             // We still setup the grid
-            if (!TryComp<BecomesStationComponent>(grid, out var becomesStation))
-                continue;
-
-            AddGrid(becomesStation.Id, grid);
+            if (TryComp<BecomesStationComponent>(grid, out var becomesStation))
+                dict.GetOrNew(becomesStation.Id).Add(grid);
         }
 
         if (!dict.Any())
index 94f9e218b88805ab7510ea2de2a83f9218944d60..3e1d3c2b10966dbd8a16610786610c0050aea386 100644 (file)
@@ -707,7 +707,7 @@ namespace Content.Shared.CCVar
 
         public static readonly CVarDef<bool> CombatModeIndicatorsPointShow =
             CVarDef.Create("hud.combat_mode_indicators_point_show", true, CVar.ARCHIVE | CVar.CLIENTONLY);
-        
+
         public static readonly CVarDef<bool> LoocAboveHeadShow =
             CVarDef.Create("hud.show_looc_above_head", true, CVar.ARCHIVE | CVar.CLIENTONLY);
 
@@ -1213,7 +1213,7 @@ namespace Content.Shared.CCVar
         /// </summary>
         public static readonly CVarDef<bool> OocEnableDuringRound =
             CVarDef.Create("ooc.enable_during_round", false, CVar.NOTIFY | CVar.REPLICATED | CVar.SERVER);
-        
+
         public static readonly CVarDef<bool> ShowOocPatronColor =
             CVarDef.Create("ooc.show_ooc_patron_color", true, CVar.ARCHIVE | CVar.REPLICATED | CVar.CLIENT);
 
@@ -1446,6 +1446,7 @@ namespace Content.Shared.CCVar
 
         /// <summary>
         /// The minimum time for the emergency shuttle to arrive at centcomm.
+        /// Actual minimum travel time cannot be less than <see cref="ShuttleSystem.DefaultArrivalTime"/>
         /// </summary>
         public static readonly CVarDef<float> EmergencyShuttleMinTransitTime =
             CVarDef.Create("shuttle.emergency_transit_time_min", 60f, CVar.SERVERONLY);