]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
RespawnRuleSystem tweaks. (#28528)
authorAJCM-git <60196617+AJCM-git@users.noreply.github.com>
Mon, 3 Jun 2024 03:28:38 +0000 (23:28 -0400)
committerGitHub <noreply@github.com>
Mon, 3 Jun 2024 03:28:38 +0000 (23:28 -0400)
Content.Server/GameTicking/Rules/Components/RespawnDeadRuleComponent.cs
Content.Server/GameTicking/Rules/Components/RespawnTrackerComponent.cs
Content.Server/GameTicking/Rules/DeathMatchRuleSystem.cs
Content.Server/GameTicking/Rules/RespawnRuleSystem.cs
Resources/Prototypes/GameRules/roundstart.yml

index fafe811dd9225098ba902576a0d222602de427ce..f6e4a3b1290afca8945f4c595210dae58b932b99 100644 (file)
@@ -6,4 +6,9 @@
 [RegisterComponent, Access(typeof(RespawnRuleSystem))]
 public sealed partial class RespawnDeadRuleComponent : Component
 {
+    /// <summary>
+    /// Whether or not we want to add everyone who dies to the respawn tracker
+    /// </summary>
+    [DataField]
+    public bool AlwaysRespawnDead;
 }
index 3d338c2d133698349b0cdbfea23e50a02df929fd..b9c8fe1096246e3439cb14636c93b10f6ecbf634 100644 (file)
@@ -13,18 +13,24 @@ public sealed partial class RespawnTrackerComponent : Component
     /// A list of the people that should be respawned.
     /// Used to make sure that we don't respawn aghosts or observers.
     /// </summary>
-    [DataField("players")]
+    [DataField]
     public HashSet<NetUserId> Players = new();
 
     /// <summary>
     /// The delay between dying and respawning.
     /// </summary>
-    [DataField("respawnDelay")]
+    [DataField]
     public TimeSpan RespawnDelay = TimeSpan.Zero;
 
     /// <summary>
     /// A dictionary of player netuserids and when they will respawn.
     /// </summary>
-    [DataField("respawnQueue")]
+    [DataField]
     public Dictionary<NetUserId, TimeSpan> RespawnQueue = new();
+
+    /// <summary>
+    /// Whether or not to delete the original body when respawning
+    /// </summary>
+    [DataField]
+    public bool DeleteBody = true;
 }
index ad7c63ff58df755775fcbd49e666e6e6df93a1ea..9e3203d170bc2115a06aaf6dbbf3dba1c322a424 100644 (file)
@@ -56,7 +56,7 @@ public sealed class DeathMatchRuleSystem : GameRuleSystem<DeathMatchRuleComponen
             _mind.TransferTo(newMind, mob);
             SetOutfitCommand.SetOutfit(mob, dm.Gear, EntityManager);
             EnsureComp<KillTrackerComponent>(mob);
-            _respawn.AddToTracker(ev.Player.UserId, uid, tracker);
+            _respawn.AddToTracker(ev.Player.UserId, (uid, tracker));
 
             _point.EnsurePlayer(ev.Player.UserId, uid, point);
 
@@ -73,7 +73,7 @@ public sealed class DeathMatchRuleSystem : GameRuleSystem<DeathMatchRuleComponen
         {
             if (!GameTicker.IsGameRuleActive(uid, rule))
                 continue;
-            _respawn.AddToTracker(ev.Mob, uid, tracker);
+            _respawn.AddToTracker((ev.Mob, null), (uid, tracker));
         }
     }
 
index 5215da96aa8df550ad7b679fa9ebb7083822141c..3f8d31f622ff391e3fd20e7e7c36d0e999398a92 100644 (file)
@@ -1,4 +1,5 @@
 using Content.Server.Chat.Managers;
+using Content.Server.Database.Migrations.Postgres;
 using Content.Server.GameTicking.Components;
 using Content.Server.GameTicking.Rules.Components;
 using Content.Server.Station.Systems;
@@ -34,38 +35,6 @@ public sealed class RespawnRuleSystem : GameRuleSystem<RespawnDeadRuleComponent>
         SubscribeLocalEvent<MobStateChangedEvent>(OnMobStateChanged);
     }
 
-    private void OnSuicide(SuicideEvent ev)
-    {
-        if (!TryComp<ActorComponent>(ev.Victim, out var actor))
-           return;
-
-        var query = EntityQueryEnumerator<RespawnTrackerComponent>();
-        while (query.MoveNext(out _, out var respawn))
-        {
-            if (respawn.Players.Remove(actor.PlayerSession.UserId))
-                QueueDel(ev.Victim);
-        }
-    }
-
-    private void OnMobStateChanged(MobStateChangedEvent args)
-    {
-        if (args.NewMobState == MobState.Alive)
-            return;
-
-        if (!TryComp<ActorComponent>(args.Target, out var actor))
-            return;
-
-        var query = EntityQueryEnumerator<RespawnDeadRuleComponent, GameRuleComponent>();
-        while (query.MoveNext(out var uid, out _, out var rule))
-        {
-            if (!GameTicker.IsGameRuleActive(uid, rule))
-                continue;
-
-            if (RespawnPlayer(args.Target, uid, actor: actor))
-                break;
-        }
-    }
-
     public override void Update(float frameTime)
     {
         base.Update(frameTime);
@@ -75,8 +44,7 @@ public sealed class RespawnRuleSystem : GameRuleSystem<RespawnDeadRuleComponent>
 
         foreach (var tracker in EntityQuery<RespawnTrackerComponent>())
         {
-            var queue = new Dictionary<NetUserId, TimeSpan>(tracker.RespawnQueue);
-            foreach (var (player, time) in queue)
+            foreach (var (player, time) in tracker.RespawnQueue)
             {
                 if (_timing.CurTime < time)
                     continue;
@@ -92,53 +60,84 @@ public sealed class RespawnRuleSystem : GameRuleSystem<RespawnDeadRuleComponent>
         }
     }
 
-    /// <summary>
-    /// Adds a given player to the respawn tracker, ensuring that they are respawned if they die.
-    /// </summary>
-    public void AddToTracker(EntityUid player, EntityUid tracker, RespawnTrackerComponent? component = null, ActorComponent? actor = null)
+    private void OnSuicide(SuicideEvent ev)
     {
-        if (!Resolve(tracker, ref component) || !Resolve(player, ref actor, false))
-            return;
+        if (!TryComp<ActorComponent>(ev.Victim, out var actor))
+           return;
 
-        AddToTracker(actor.PlayerSession.UserId, tracker, component);
+        var query = EntityQueryEnumerator<RespawnTrackerComponent>();
+        while (query.MoveNext(out _, out var respawn))
+        {
+            if (respawn.Players.Remove(actor.PlayerSession.UserId))
+                QueueDel(ev.Victim);
+        }
     }
 
-    /// <summary>
-    /// Adds a given player to the respawn tracker, ensuring that they are respawned if they die.
-    /// </summary>
-    public void AddToTracker(NetUserId id, EntityUid tracker, RespawnTrackerComponent? component = null)
+    private void OnMobStateChanged(MobStateChangedEvent args)
     {
-        if (!Resolve(tracker, ref component))
+        if (args.NewMobState != MobState.Dead)
             return;
 
-        component.Players.Add(id);
+        if (!TryComp<ActorComponent>(args.Target, out var actor))
+            return;
+
+        var query = EntityQueryEnumerator<RespawnDeadRuleComponent, RespawnTrackerComponent, GameRuleComponent>();
+        while (query.MoveNext(out var uid, out var respawnRule, out  var tracker, out var rule))
+        {
+            if (!GameTicker.IsGameRuleActive(uid, rule))
+                continue;
+
+            if (respawnRule.AlwaysRespawnDead)
+                AddToTracker(actor.PlayerSession.UserId, (uid, tracker));
+            if (RespawnPlayer((args.Target, actor), (uid, tracker)))
+                break;
+        }
     }
 
     /// <summary>
     /// Attempts to directly respawn a player, skipping the lobby screen.
     /// </summary>
-    public bool RespawnPlayer(EntityUid player, EntityUid respawnTracker, RespawnTrackerComponent? component = null, ActorComponent? actor = null)
+    public bool RespawnPlayer(Entity<ActorComponent> player, Entity<RespawnTrackerComponent> respawnTracker)
     {
-        if (!Resolve(respawnTracker, ref component) || !Resolve(player, ref actor, false))
+        if (!respawnTracker.Comp.Players.Contains(player.Comp.PlayerSession.UserId) || respawnTracker.Comp.RespawnQueue.ContainsKey(player.Comp.PlayerSession.UserId))
             return false;
 
-        if (!component.Players.Contains(actor.PlayerSession.UserId) || component.RespawnQueue.ContainsKey(actor.PlayerSession.UserId))
-            return false;
-
-        if (component.RespawnDelay == TimeSpan.Zero)
+        if (respawnTracker.Comp.RespawnDelay == TimeSpan.Zero)
         {
             if (_station.GetStations().FirstOrNull() is not { } station)
                 return false;
 
-            QueueDel(player);
-            GameTicker.MakeJoinGame(actor.PlayerSession, station, silent: true);
+            if (respawnTracker.Comp.DeleteBody)
+                QueueDel(player);
+            GameTicker.MakeJoinGame(player.Comp.PlayerSession, station, silent: true);
             return false;
         }
 
-        var msg = Loc.GetString("rule-respawn-in-seconds", ("second", component.RespawnDelay.TotalSeconds));
+        var msg = Loc.GetString("rule-respawn-in-seconds", ("second", respawnTracker.Comp.RespawnDelay.TotalSeconds));
         var wrappedMsg = Loc.GetString("chat-manager-server-wrap-message", ("message", msg));
-        _chatManager.ChatMessageToOne(ChatChannel.Server, msg, wrappedMsg, respawnTracker, false, actor.PlayerSession.Channel, Color.LimeGreen);
-        component.RespawnQueue[actor.PlayerSession.UserId] = _timing.CurTime + component.RespawnDelay;
+        _chatManager.ChatMessageToOne(ChatChannel.Server, msg, wrappedMsg, respawnTracker, false, player.Comp.PlayerSession.Channel, Color.LimeGreen);
+
+        respawnTracker.Comp.RespawnQueue[player.Comp.PlayerSession.UserId] = _timing.CurTime + respawnTracker.Comp.RespawnDelay;
+
         return true;
     }
+
+    /// <summary>
+    /// Adds a given player to the respawn tracker, ensuring that they are respawned if they die.
+    /// </summary>
+    public void AddToTracker(Entity<ActorComponent?> player, Entity<RespawnTrackerComponent?> respawnTracker)
+    {
+        if (!Resolve(respawnTracker, ref respawnTracker.Comp) || !Resolve(player, ref player.Comp, false))
+            return;
+
+        AddToTracker(player.Comp.PlayerSession.UserId, (respawnTracker, respawnTracker.Comp));
+    }
+
+    /// <summary>
+    /// Adds a given player to the respawn tracker, ensuring that they are respawned if they die.
+    /// </summary>
+    public void AddToTracker(NetUserId id, Entity<RespawnTrackerComponent> tracker)
+    {
+        tracker.Comp.Players.Add(id);
+    }
 }
index 93350163f68f98b1413b5160613bda2fd10186c8..cf2c5b2f475a9c7208c38db37463f9a2653c2590 100644 (file)
@@ -5,6 +5,17 @@
   components:
   - type: GameRule
 
+- type: entity
+  noSpawn: true
+  parent: BaseGameRule
+  id: RespawnDeadRule
+  components:
+  - type: RespawnDeadRule
+    alwaysRespawnDead: true
+  - type: RespawnTracker
+    respawnDelay: 10
+    deleteBody: false
+
 - type: entity
   noSpawn: true
   parent: BaseGameRule