From 38f6e6e8496512e993a363012fa32736179558ae Mon Sep 17 00:00:00 2001
From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com>
Date: Sat, 10 May 2025 08:51:28 -0400
Subject: [PATCH] Add EvenHealthChange effect (#37129)
* Add EvenHealthChange effect
* cleanup
---------
Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
---
.../EntityEffects/Effects/EvenHealthChange.cs | 141 ++++++++++++++++++
.../en-US/guidebook/chemistry/effects.ftl | 15 ++
Resources/Prototypes/Reagents/medicine.yml | 13 +-
3 files changed, 162 insertions(+), 7 deletions(-)
create mode 100644 Content.Server/EntityEffects/Effects/EvenHealthChange.cs
diff --git a/Content.Server/EntityEffects/Effects/EvenHealthChange.cs b/Content.Server/EntityEffects/Effects/EvenHealthChange.cs
new file mode 100644
index 0000000000..acf2bfafab
--- /dev/null
+++ b/Content.Server/EntityEffects/Effects/EvenHealthChange.cs
@@ -0,0 +1,141 @@
+using Content.Shared.Damage;
+using Content.Shared.Damage.Prototypes;
+using Content.Shared.EntityEffects;
+using Content.Shared.FixedPoint;
+using Content.Shared.Localizations;
+using JetBrains.Annotations;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Utility;
+
+namespace Content.Server.EntityEffects.Effects;
+
+///
+/// Version of that distributes the healing to groups
+///
+[UsedImplicitly]
+public sealed partial class EvenHealthChange : EntityEffect
+{
+ ///
+ /// Damage to heal, collected into entire damage groups.
+ ///
+ [DataField(required: true)]
+ public Dictionary, FixedPoint2> Damage = new();
+
+ ///
+ /// Should this effect scale the damage by the amount of chemical in the solution?
+ /// Useful for touch reactions, like styptic powder or acid.
+ /// Only usable if the EntityEffectBaseArgs is an EntityEffectReagentArgs.
+ ///
+ [DataField]
+ public bool ScaleByQuantity;
+
+ ///
+ /// Should this effect ignore damage modifiers?
+ ///
+ [DataField]
+ public bool IgnoreResistances = true;
+
+ protected override string ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
+ {
+ var damages = new List();
+ var heals = false;
+ var deals = false;
+
+ var damagableSystem = entSys.GetEntitySystem();
+ var universalReagentDamageModifier = damagableSystem.UniversalReagentDamageModifier;
+ var universalReagentHealModifier = damagableSystem.UniversalReagentHealModifier;
+
+ foreach (var (group, amount) in Damage)
+ {
+ var groupProto = prototype.Index(group);
+
+ var sign = FixedPoint2.Sign(amount);
+ var mod = 1f;
+
+ if (sign < 0)
+ {
+ heals = true;
+ mod = universalReagentHealModifier;
+ }
+ else if (sign > 0)
+ {
+ deals = true;
+ mod = universalReagentDamageModifier;
+ }
+
+ damages.Add(
+ Loc.GetString("health-change-display",
+ ("kind", groupProto.LocalizedName),
+ ("amount", MathF.Abs(amount.Float() * mod)),
+ ("deltasign", sign)
+ ));
+ }
+
+ var healsordeals = heals ? (deals ? "both" : "heals") : (deals ? "deals" : "none");
+ return Loc.GetString("reagent-effect-guidebook-even-health-change",
+ ("chance", Probability),
+ ("changes", ContentLocalizationManager.FormatList(damages)),
+ ("healsordeals", healsordeals));
+ }
+
+ public override void Effect(EntityEffectBaseArgs args)
+ {
+ if (!args.EntityManager.TryGetComponent(args.TargetEntity, out var damageable))
+ return;
+
+ var protoMan = IoCManager.Resolve();
+
+ var scale = FixedPoint2.New(1);
+
+ if (args is EntityEffectReagentArgs reagentArgs)
+ {
+ scale = ScaleByQuantity ? reagentArgs.Quantity * reagentArgs.Scale : reagentArgs.Scale;
+ }
+
+ var damagableSystem = args.EntityManager.System();
+ var universalReagentDamageModifier = damagableSystem.UniversalReagentDamageModifier;
+ var universalReagentHealModifier = damagableSystem.UniversalReagentHealModifier;
+
+ var dspec = new DamageSpecifier();
+
+ foreach (var (group, amount) in Damage)
+ {
+ var groupProto = protoMan.Index(group);
+ var groupDamage = new Dictionary();
+ foreach (var damageId in groupProto.DamageTypes)
+ {
+ var damageAmount = damageable.Damage.DamageDict.GetValueOrDefault(damageId);
+ if (damageAmount != FixedPoint2.Zero)
+ groupDamage.Add(damageId, damageAmount);
+ }
+
+ var sum = groupDamage.Values.Sum();
+ foreach (var (damageId, damageAmount) in groupDamage)
+ {
+ var existing = dspec.DamageDict.GetOrNew(damageId);
+ dspec.DamageDict[damageId] = existing + damageAmount / sum * amount;
+ }
+ }
+
+ if (universalReagentDamageModifier != 1 || universalReagentHealModifier != 1)
+ {
+ foreach (var (type, val) in dspec.DamageDict)
+ {
+ if (val < 0f)
+ {
+ dspec.DamageDict[type] = val * universalReagentHealModifier;
+ }
+ if (val > 0f)
+ {
+ dspec.DamageDict[type] = val * universalReagentDamageModifier;
+ }
+ }
+ }
+
+ damagableSystem.TryChangeDamage(
+ args.TargetEntity,
+ dspec * scale,
+ IgnoreResistances,
+ interruptsDoAfters: false);
+ }
+}
diff --git a/Resources/Locale/en-US/guidebook/chemistry/effects.ftl b/Resources/Locale/en-US/guidebook/chemistry/effects.ftl
index 2a40d00f72..ba6ae96c82 100644
--- a/Resources/Locale/en-US/guidebook/chemistry/effects.ftl
+++ b/Resources/Locale/en-US/guidebook/chemistry/effects.ftl
@@ -87,6 +87,21 @@ reagent-effect-guidebook-health-change =
}
} { $changes }
+reagent-effect-guidebook-even-health-change =
+ { $chance ->
+ [1] { $healsordeals ->
+ [heals] Evenly heals
+ [deals] Evenly deals
+ *[both] Evenly modifies health by
+ }
+ *[other] { $healsordeals ->
+ [heals] evenly heal
+ [deals] evenly deal
+ *[both] evenly modify health by
+ }
+ } { $changes }
+
+
reagent-effect-guidebook-status-effect =
{ $type ->
[add] { $chance ->
diff --git a/Resources/Prototypes/Reagents/medicine.yml b/Resources/Prototypes/Reagents/medicine.yml
index 4cb134059e..f1dcbc1a22 100644
--- a/Resources/Prototypes/Reagents/medicine.yml
+++ b/Resources/Prototypes/Reagents/medicine.yml
@@ -822,13 +822,12 @@
metabolisms:
Medicine:
effects:
- - !type:HealthChange
+ - !type:EvenHealthChange
damage:
- groups:
- Burn: -2
- Toxin: -2
- Airloss: -2
- Brute: -2
+ Burn: -2
+ Toxin: -2
+ Airloss: -2
+ Brute: -2
- type: reagent
id: Ultravasculine
@@ -1205,7 +1204,7 @@
conditions:
- !type:ReagentThreshold
min: 12
-
+
- type: reagent
id: Opporozidone #Name based of an altered version of the startreck chem "Opporozine"
name: reagent-name-opporozidone
--
2.51.2