From d691ddae64ff178d346255c1e0acfdc693f70e9a Mon Sep 17 00:00:00 2001
From: LankLTE <135308300+LankLTE@users.noreply.github.com>
Date: Sat, 7 Oct 2023 12:34:32 -0700
Subject: [PATCH] Give player species slight passive regen (#20638)
* Implementation
* Reviews
---
.../Components/PassiveDamageComponent.cs | 40 ++++++++++++++
.../Damage/Systems/PassiveDamageSystem.cs | 55 +++++++++++++++++++
.../Prototypes/Entities/Mobs/Species/base.yml | 9 +++
3 files changed, 104 insertions(+)
create mode 100644 Content.Shared/Damage/Components/PassiveDamageComponent.cs
create mode 100644 Content.Shared/Damage/Systems/PassiveDamageSystem.cs
diff --git a/Content.Shared/Damage/Components/PassiveDamageComponent.cs b/Content.Shared/Damage/Components/PassiveDamageComponent.cs
new file mode 100644
index 0000000000..269960adac
--- /dev/null
+++ b/Content.Shared/Damage/Components/PassiveDamageComponent.cs
@@ -0,0 +1,40 @@
+using Content.Shared.Mobs;
+using Content.Shared.FixedPoint;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Damage.Components;
+
+///
+/// Passively damages the entity on a specified interval.
+///
+[RegisterComponent, NetworkedComponent]
+public sealed partial class PassiveDamageComponent : Component
+{
+ ///
+ /// The entitys' states that passive damage will apply in
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public List AllowedStates = new();
+
+ ///
+ /// Damage / Healing per interval dealt to the entity every interval
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public DamageSpecifier Damage = new();
+
+ ///
+ /// Delay between damage events in seconds
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float Interval = 1f;
+
+ ///
+ /// The maximum HP the damage will be given to. If 0, disabled.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public FixedPoint2 DamageCap = 0;
+
+ [DataField("nextDamage", customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)]
+ public TimeSpan NextDamage = TimeSpan.Zero;
+}
diff --git a/Content.Shared/Damage/Systems/PassiveDamageSystem.cs b/Content.Shared/Damage/Systems/PassiveDamageSystem.cs
new file mode 100644
index 0000000000..5a37d6a6e6
--- /dev/null
+++ b/Content.Shared/Damage/Systems/PassiveDamageSystem.cs
@@ -0,0 +1,55 @@
+using Content.Shared.Damage.Components;
+using Content.Shared.Mobs.Systems;
+using Content.Shared.Mobs.Components;
+using Content.Shared.FixedPoint;
+using Robust.Shared.Timing;
+
+namespace Content.Shared.Damage;
+
+public sealed class PassiveDamageSystem : EntitySystem
+{
+ [Dependency] private readonly DamageableSystem _damageable = default!;
+ [Dependency] private readonly IGameTiming _timing = default!;
+ [Dependency] private readonly MobStateSystem _mobState = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnPendingMapInit);
+ }
+
+ private void OnPendingMapInit(EntityUid uid, PassiveDamageComponent component, MapInitEvent args)
+ {
+ component.NextDamage = _timing.CurTime + TimeSpan.FromSeconds(1f);
+ }
+
+ // Every tick, attempt to damage entities
+ public override void Update(float frameTime)
+ {
+ base.Update(frameTime);
+ var curTime = _timing.CurTime;
+
+ // Go through every entity with the component
+ var query = EntityQueryEnumerator();
+ while (query.MoveNext(out var uid, out var comp, out var damage, out var mobState))
+ {
+ // Make sure they're up for a damage tick
+ if (comp.NextDamage > curTime)
+ continue;
+
+ if (comp.DamageCap != 0 && damage.TotalDamage >= comp.DamageCap)
+ continue;
+
+ // Set the next time they can take damage
+ comp.NextDamage = curTime + TimeSpan.FromSeconds(1f);
+
+ // Damage them
+ foreach (var allowedState in comp.AllowedStates)
+ {
+ if(allowedState == mobState.CurrentState)
+ _damageable.TryChangeDamage(uid, comp.Damage, true, false, damage);
+ }
+ }
+ }
+}
diff --git a/Resources/Prototypes/Entities/Mobs/Species/base.yml b/Resources/Prototypes/Entities/Mobs/Species/base.yml
index 422e1aa4e1..74c676eb68 100644
--- a/Resources/Prototypes/Entities/Mobs/Species/base.yml
+++ b/Resources/Prototypes/Entities/Mobs/Species/base.yml
@@ -237,6 +237,15 @@
damage:
types:
Blunt: 0.55 #per second, scales with pressure and other constants.
+ - type: PassiveDamage # Slight passive regen. Assuming one damage type, comes out to about 4 damage a minute.
+ allowedStates:
+ - Alive
+ damageCap: 20
+ damage:
+ types:
+ Heat: -0.07
+ groups:
+ Brute: -0.07
# Organs
- type: StatusEffects
allowed: