Update DamageableSystem to modern standards (#39417)

* Update DamageableSystem to modern standards

* DamageContainerId -> DamageContainerID with lint flag

* Replace strings with protoids

* Make CVar subscription declarations all consistently whitespaced

* ChangeDamage -> TryChangeDamage, cope with C# jank

* Revert event signature changes

* Restore a comment

* Re-add two queries

* Init the queries

* Use appearanceQuery in DamageChanged

* Use damageableQuery in TryChangeDamage

* Use damageableQuery in SetDamageModifierSetId

* Final cleanup, fix sandboxing

* Rectify ExplosionSystem:::ProcessEntity's call to TryChangeDamage

* Re-organize DamageableSystem

* first big fuck you breaking change.

* THATS A LOT OF DAMAGE!!!

* Fix test fails

* test fixes 2

* push it

---------

Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
This commit is contained in:
Hannah Giovanna Dawson
2025-10-27 19:53:04 +00:00
committed by GitHub
parent cf66dd7b35
commit cdbe92d37d
157 changed files with 1127 additions and 967 deletions

View File

@@ -12,6 +12,7 @@ using Content.Shared.Chat;
using Content.Shared.Construction;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Database;
using Content.Shared.Roles;
using Content.Shared.StationRecords;

View File

@@ -1,6 +1,5 @@
using Content.Server.Administration.Components;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Body.Components;
using Content.Server.Body.Systems;
using Content.Server.Electrocution;
using Content.Server.Explosion.EntitySystems;
@@ -24,7 +23,6 @@ using Content.Shared.Body.Part;
using Content.Shared.Clothing.Components;
using Content.Shared.Clumsy;
using Content.Shared.Cluwne;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Database;
using Content.Shared.Electrocution;
@@ -58,6 +56,7 @@ using Robust.Shared.Spawners;
using Robust.Shared.Utility;
using System.Numerics;
using System.Threading;
using Content.Shared.Damage.Components;
using Timer = Robust.Shared.Timing.Timer;
namespace Content.Server.Administration.Systems;

View File

@@ -251,7 +251,7 @@ public sealed partial class AtmosphereSystem
var maxPressureCapped = Math.Min(maxPressure, ent.Comp.MaxEffectivePressure);
var appliedDamage = ScaleDamage(ent, ent.Comp.BaseDamage, maxPressureCapped);
_damage.TryChangeDamage(ent, appliedDamage, ignoreResistances: true, interruptsDoAfters: false);
_damage.ChangeDamage(ent.Owner, appliedDamage, ignoreResistances: true, interruptsDoAfters: false);
SetIsTakingDamageState(ent, true);
}

View File

@@ -14,7 +14,7 @@ using Robust.Shared.Map;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Prototypes;
using System.Linq;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Robust.Shared.Threading;
namespace Content.Server.Atmos.EntitySystems;

View File

@@ -3,7 +3,8 @@ using Content.Server.Administration.Logs;
using Content.Server.Atmos.Components;
using Content.Shared.Alert;
using Content.Shared.Atmos;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Damage.Systems;
using Content.Shared.Database;
using Content.Shared.FixedPoint;
using Content.Shared.Inventory;

View File

@@ -7,7 +7,7 @@ using Content.Shared.ActionBlocker;
using Content.Shared.Alert;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Components;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Database;
using Content.Shared.IgnitionSource;
using Content.Shared.Interaction;

View File

@@ -2,7 +2,7 @@ using Content.Server.Atmos.EntitySystems;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Rotting;
using Content.Shared.Body.Events;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Temperature.Components;
using Robust.Server.Containers;
using Robust.Shared.Physics.Components;

View File

@@ -2,7 +2,7 @@ using Content.Shared.Bed;
using Content.Shared.Bed.Components;
using Content.Shared.Bed.Sleep;
using Content.Shared.Buckle.Components;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Mobs.Systems;
namespace Content.Server.Bed

View File

@@ -4,7 +4,7 @@ using Content.Server.Popups;
using Content.Shared.ActionBlocker;
using Content.Shared.Actions;
using Content.Shared.Bible;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Ghost.Roles.Components;
using Content.Shared.IdentityManagement;
using Content.Shared.Interaction;
@@ -14,7 +14,6 @@ using Content.Shared.Mobs.Systems;
using Content.Shared.Popups;
using Content.Shared.Timing;
using Content.Shared.Verbs;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Player;
using Robust.Shared.Random;
@@ -133,9 +132,7 @@ namespace Content.Server.Bible
}
}
var damage = _damageableSystem.TryChangeDamage(args.Target.Value, component.Damage, true, origin: uid);
if (damage == null || damage.Empty)
if (_damageableSystem.TryChangeDamage(args.Target.Value, component.Damage, true, origin: uid))
{
var othersMessage = Loc.GetString(component.LocPrefix + "-heal-success-none-others", ("user", Identity.Entity(args.User, EntityManager)), ("target", Identity.Entity(args.Target.Value, EntityManager)), ("bible", uid));
_popupSystem.PopupEntity(othersMessage, args.User, Filter.PvsExcept(args.User), true, PopupType.Medium);

View File

@@ -12,7 +12,7 @@ using Content.Shared.Chat;
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Database;
using Content.Shared.EntityConditions;
using Content.Shared.EntityConditions.Conditions.Body;
@@ -367,7 +367,7 @@ public sealed class RespiratorSystem : EntitySystem
if (ent.Comp.SuffocationCycles == 2)
_adminLogger.Add(LogType.Asphyxiation, $"{ToPrettyString(ent):entity} started suffocating");
_damageableSys.TryChangeDamage(ent, ent.Comp.Damage, interruptsDoAfters: false);
_damageableSys.ChangeDamage(ent.Owner, ent.Comp.Damage, interruptsDoAfters: false);
if (ent.Comp.SuffocationCycles < ent.Comp.SuffocationCycleThreshold)
return;
@@ -381,7 +381,7 @@ public sealed class RespiratorSystem : EntitySystem
if (ent.Comp.SuffocationCycles >= 2)
_adminLogger.Add(LogType.Asphyxiation, $"{ToPrettyString(ent):entity} stopped suffocating");
_damageableSys.TryChangeDamage(ent, ent.Comp.DamageRecovery);
_damageableSys.ChangeDamage(ent.Owner, ent.Comp.DamageRecovery);
var ev = new StopSuffocatingEvent();
RaiseLocalEvent(ent, ref ev);

View File

@@ -1,20 +1,16 @@
using Content.Server.Storage.Components;
using Content.Server.Storage.EntitySystems;
using Content.Shared.Access.Components;
using Content.Shared.CardboardBox;
using Content.Shared.CardboardBox.Components;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Interaction;
using Content.Shared.Movement.Components;
using Content.Shared.Movement.Systems;
using Content.Shared.Stealth;
using Content.Shared.Stealth.Components;
using Content.Shared.Storage.Components;
using Robust.Server.GameObjects;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Containers;
using Robust.Shared.Player;
using Robust.Shared.Timing;
namespace Content.Server.CardboardBox;
@@ -109,10 +105,10 @@ public sealed class CardboardBoxSystem : SharedCardboardBoxSystem
//Relay damage to the mover
private void OnDamage(EntityUid uid, CardboardBoxComponent component, DamageChangedEvent args)
{
if (args.DamageDelta != null && args.DamageIncreased)
{
_damageable.TryChangeDamage(component.Mover, args.DamageDelta, origin: args.Origin);
}
if (args.DamageDelta == null || !args.DamageIncreased || component.Mover is not { } mover)
return;
_damageable.ChangeDamage(mover, args.DamageDelta, origin: args.Origin);
}
private void OnEntInserted(EntityUid uid, CardboardBoxComponent component, EntInsertedIntoContainerMessage args)

View File

@@ -2,7 +2,7 @@ using Content.Server.Ghost;
using Content.Server.Hands.Systems;
using Content.Shared.Administration.Logs;
using Content.Shared.Chat;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Database;
using Content.Shared.IdentityManagement;
using Content.Shared.Interaction.Events;

View File

@@ -1,3 +1,5 @@
using Content.Shared.Damage.Systems;
namespace Content.Server.Chat.Systems;
using Content.Shared.Chat;

View File

@@ -12,7 +12,7 @@ using Content.Shared.CCVar;
using Content.Shared.Chemistry.Components;
using Content.Shared.Cloning;
using Content.Shared.Chat;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.DeviceLinking.Events;
using Content.Shared.Emag.Components;
using Content.Shared.Emag.Systems;

View File

@@ -8,7 +8,7 @@ using Content.Shared.Chat;
using Content.Shared.Chat.Prototypes;
using Content.Shared.Clumsy;
using Content.Shared.Cluwne;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Mobs;
using Content.Shared.NameModifier.EntitySystems;
using Content.Shared.Popups;

View File

@@ -1,13 +1,8 @@
using Content.Server.Destructible;
using Content.Shared.Construction;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Examine;
using Content.Shared.FixedPoint;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Content.Server.Construction.Conditions;

View File

@@ -4,7 +4,7 @@ using Content.Server.Administration;
using Content.Shared.Administration;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
using Content.Shared.FixedPoint;
using Content.Shared.Damage.Systems;
using Robust.Shared.Console;
using Robust.Shared.Prototypes;

View File

@@ -2,6 +2,7 @@ using Content.Shared.Bed.Sleep;
using Content.Shared.Damage;
using Content.Shared.Damage.Events;
using Content.Shared.Damage.ForceSay;
using Content.Shared.Damage.Systems;
using Content.Shared.FixedPoint;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Systems;

View File

@@ -1,8 +1,7 @@
using Content.Server.Damage.Components;
using Content.Shared.Damage;
using Robust.Shared.Player;
using Content.Shared.Weapons.Melee.Events;
using System.Linq;
using Content.Shared.Damage.Systems;
namespace Content.Server.Damage.Systems;

View File

@@ -9,7 +9,7 @@ namespace Content.Server.Damage.Systems
/// </summary>
public sealed class DamageOnLandSystem : EntitySystem
{
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
[Dependency] private readonly Shared.Damage.Systems.DamageableSystem _damageableSystem = default!;
public override void Initialize()
{

View File

@@ -11,7 +11,7 @@ namespace Content.Server.Damage.Systems
{
public sealed class DamageOnToolInteractSystem : EntitySystem
{
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
[Dependency] private readonly Shared.Damage.Systems.DamageableSystem _damageableSystem = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly SharedToolSystem _toolSystem = default!;
@@ -35,22 +35,22 @@ namespace Content.Server.Damage.Systems
&& itemToggle.Activated
&& !welder.TankSafe)
{
var dmg = _damageableSystem.TryChangeDamage(args.Target, weldingDamage, origin: args.User);
if (dmg != null)
if (_damageableSystem.TryChangeDamage(args.Target, weldingDamage, out var dmg, origin: args.User))
{
_adminLogger.Add(LogType.Damaged,
$"{ToPrettyString(args.User):user} used {ToPrettyString(args.Used):used} as a welder to deal {dmg.GetTotal():damage} damage to {ToPrettyString(args.Target):target}");
}
args.Handled = true;
}
else if (component.DefaultDamage is {} damage
&& _toolSystem.HasQuality(args.Used, component.Tools))
{
var dmg = _damageableSystem.TryChangeDamage(args.Target, damage, origin: args.User);
if (dmg != null)
if (_damageableSystem.TryChangeDamage(args.Target, damage, out var dmg, origin: args.User))
{
_adminLogger.Add(LogType.Damaged,
$"{ToPrettyString(args.User):user} used {ToPrettyString(args.Used):used} as a tool to deal {dmg.GetTotal():damage} damage to {ToPrettyString(args.Target):target}");
}
args.Handled = true;
}

View File

@@ -17,7 +17,7 @@ public sealed class DamageOtherOnHitSystem : SharedDamageOtherOnHitSystem
{
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly GunSystem _guns = default!;
[Dependency] private readonly DamageableSystem _damageable = default!;
[Dependency] private readonly Shared.Damage.Systems.DamageableSystem _damageable = default!;
[Dependency] private readonly SharedCameraRecoilSystem _sharedCameraRecoil = default!;
[Dependency] private readonly SharedColorFlashEffectSystem _color = default!;
@@ -33,13 +33,13 @@ public sealed class DamageOtherOnHitSystem : SharedDamageOtherOnHitSystem
if (TerminatingOrDeleted(args.Target))
return;
var dmg = _damageable.TryChangeDamage(args.Target, component.Damage * _damageable.UniversalThrownDamageModifier, component.IgnoreResistances, origin: args.Component.Thrower);
var dmg = _damageable.ChangeDamage(args.Target, component.Damage * _damageable.UniversalThrownDamageModifier, component.IgnoreResistances, origin: args.Component.Thrower);
// Log damage only for mobs. Useful for when people throw spears at each other, but also avoids log-spam when explosions send glass shards flying.
if (dmg != null && HasComp<MobStateComponent>(args.Target))
if (HasComp<MobStateComponent>(args.Target))
_adminLogger.Add(LogType.ThrowHit, $"{ToPrettyString(args.Target):target} received {dmg.GetTotal():damage} damage from collision");
if (dmg is { Empty: false })
if (!dmg.Empty)
{
_color.RaiseEffect(Color.Red, [args.Target], Filter.Pvs(args.Target, entityManager: EntityManager));
}

View File

@@ -1,6 +1,7 @@
using Content.Server.Damage.Components;
using Content.Server.Popups;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Robust.Shared.Player;
using Robust.Shared.Random;

View File

@@ -1,6 +1,6 @@
using Content.Server.Damage.Components;
using Content.Server.Destructible;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Examine;
using Content.Shared.Rounding;
using Robust.Shared.Prototypes;

View File

@@ -7,7 +7,7 @@ public sealed partial class DestructibleSystem
/// <summary>
/// Tests all triggers in a DestructibleComponent to see how expensive it is to query them.
/// </summary>
public void TestAllTriggers(List<Entity<DamageableComponent, DestructibleComponent>> destructibles)
public void TestAllTriggers(List<Entity<Shared.Damage.Components.DamageableComponent, DestructibleComponent>> destructibles)
{
foreach (var (uid, damageable, destructible) in destructibles)
{
@@ -22,7 +22,7 @@ public sealed partial class DestructibleSystem
/// <summary>
/// Tests all behaviours in a DestructibleComponent to see how expensive it is to query them.
/// </summary>
public void TestAllBehaviors(List<Entity<DamageableComponent, DestructibleComponent>> destructibles)
public void TestAllBehaviors(List<Entity<Shared.Damage.Components.DamageableComponent, DestructibleComponent>> destructibles)
{
foreach (var (uid, damageable, destructible) in destructibles)
{

View File

@@ -11,6 +11,7 @@ using Content.Server.Fluids.EntitySystems;
using Content.Server.Stack;
using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Database;
using Content.Shared.Destructible;
using Content.Shared.Destructible.Thresholds.Triggers;
@@ -111,7 +112,7 @@ namespace Content.Server.Destructible
/// <summary>
/// Check if the given threshold should trigger.
/// </summary>
public bool Triggered(DamageThreshold threshold, Entity<DamageableComponent> owner)
public bool Triggered(DamageThreshold threshold, Entity<Shared.Damage.Components.DamageableComponent> owner)
{
if (threshold.Trigger == null)
return false;
@@ -135,7 +136,7 @@ namespace Content.Server.Destructible
/// <summary>
/// Check if the conditions for the given threshold are currently true.
/// </summary>
public bool Reached(DamageThreshold threshold, Entity<DamageableComponent> owner)
public bool Reached(DamageThreshold threshold, Entity<Shared.Damage.Components.DamageableComponent> owner)
{
if (threshold.Trigger == null)
return false;

View File

@@ -1,7 +1,7 @@
using Content.Server.Atmos.EntitySystems;
using Content.Server.Disposal.Tube;
using Content.Shared.Body.Components;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Disposal.Components;
using Content.Shared.Item;
using Content.Shared.Throwing;

View File

@@ -2,16 +2,14 @@ using Content.Server.Chat.Systems;
using Content.Server.NPC;
using Content.Server.NPC.Systems;
using Content.Server.Pinpointer;
using Content.Shared.Damage;
using Content.Shared.Dragon;
using Content.Shared.Examine;
using Content.Shared.Sprite;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Player;
using Robust.Shared.Serialization.Manager;
using System.Numerics;
using Robust.Shared.Audio;
using Content.Shared.Damage.Components;
using Robust.Shared.Audio.Systems;
using Robust.Shared.GameStates;
using Robust.Shared.Utility;

View File

@@ -1,14 +1,12 @@
using Content.Server.Administration.Logs;
using Content.Server.NodeContainer;
using Content.Server.NodeContainer.EntitySystems;
using Content.Server.NodeContainer.NodeGroups;
using Content.Server.NodeContainer.Nodes;
using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems;
using Content.Server.Power.NodeGroups;
using Content.Server.Weapons.Melee;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
using Content.Shared.Damage.Systems;
using Content.Shared.Database;
using Content.Shared.Electrocution;
using Content.Shared.IdentityManagement;
@@ -27,7 +25,6 @@ using Content.Shared.Tag;
using Content.Shared.Weapons.Melee.Events;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Map;
using Robust.Shared.Physics.Events;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
@@ -402,19 +399,16 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem
? _stun.TryUpdateParalyzeDuration(uid, time * ParalyzeTimeMultiplier)
: _stun.TryAddParalyzeDuration(uid, time * ParalyzeTimeMultiplier);
}
// TODO: Sparks here.
if (shockDamage is { } dmg)
{
var actual = _damageable.TryChangeDamage(uid,
new DamageSpecifier(_prototypeManager.Index(DamageType), dmg), origin: sourceUid);
if (actual != null)
if (_damageable.TryChangeDamage(uid, new DamageSpecifier(_prototypeManager.Index(DamageType), dmg), out var damage, origin: sourceUid))
{
_adminLogger.Add(LogType.Electrocution,
$"{ToPrettyString(uid):entity} received {actual.GetTotal():damage} powered electrocution damage{(sourceUid != null ? " from " + ToPrettyString(sourceUid.Value) : ""):source}");
$"{ToPrettyString(uid):entity} received {damage:damage} powered electrocution damage{(sourceUid != null ? " from " + ToPrettyString(sourceUid.Value) : ""):source}");
}
}

View File

@@ -1,9 +1,7 @@
using Content.Server.Atmos.Components;
using Content.Server.Destructible;
using Content.Shared.Atmos;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Explosion;
using Content.Shared.Explosion.EntitySystems;
using Content.Shared.FixedPoint;
using Robust.Shared.Map.Components;

View File

@@ -1,13 +1,10 @@
using System.Linq;
using System.Numerics;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Explosion.Components;
using Content.Shared.CCVar;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Database;
using Content.Shared.Explosion;
using Content.Shared.Explosion.Components;
using Content.Shared.Explosion.EntitySystems;
using Content.Shared.Maps;
using Content.Shared.Physics;
using Content.Shared.Projectiles;
@@ -17,7 +14,6 @@ using Robust.Shared.Map.Components;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Dynamics;
using Robust.Shared.Player;
using Robust.Shared.Random;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
@@ -439,28 +435,25 @@ public sealed partial class ExplosionSystem
float? fireStacksOnIgnite,
EntityUid? cause)
{
if (originalDamage != null)
if (originalDamage is not null)
{
GetEntitiesToDamage(uid, originalDamage, id);
foreach (var (entity, damage) in _toDamage)
{
if (_actorQuery.HasComp(entity))
{
// Log damage to player entities only, cause this will create a massive amount of log spam otherwise.
if (cause != null)
{
_adminLogger.Add(LogType.ExplosionHit, LogImpact.Medium, $"Explosion of {ToPrettyString(cause):actor} dealt {damage.GetTotal()} damage to {ToPrettyString(entity):subject}");
}
else
{
_adminLogger.Add(LogType.ExplosionHit, LogImpact.Medium, $"Explosion at {epicenter:epicenter} dealt {damage.GetTotal()} damage to {ToPrettyString(entity):subject}");
}
}
if (!_damageableQuery.TryComp(entity, out var damageable))
continue;
// TODO EXPLOSIONS turn explosions into entities, and pass the the entity in as the damage origin.
_damageableSystem.TryChangeDamage(entity, damage, ignoreResistances: true, ignoreGlobalModifiers: true);
_damageableSystem.TryChangeDamage((entity, damageable), damage, ignoreResistances: true, ignoreGlobalModifiers: true);
if (_actorQuery.HasComp(entity))
{
// Log damage to player entities only; this will create a massive amount of log spam otherwise.
if (cause is not null)
_adminLogger.Add(LogType.ExplosionHit, LogImpact.Medium, $"Explosion of {ToPrettyString(cause):actor} dealt {damage.GetTotal()} damage to {ToPrettyString(entity):subject}");
else
_adminLogger.Add(LogType.ExplosionHit, LogImpact.Medium, $"Explosion at {epicenter:epicenter} dealt {damage.GetTotal()} damage to {ToPrettyString(entity):subject}");
}
}
}
@@ -666,7 +659,7 @@ sealed class Explosion
private readonly IEntityManager _entMan;
private readonly ExplosionSystem _system;
private readonly SharedMapSystem _mapSystem;
private readonly DamageableSystem _damageable;
private readonly Shared.Damage.Systems.DamageableSystem _damageable;
public readonly EntityUid VisualEnt;
@@ -690,7 +683,7 @@ sealed class Explosion
EntityUid visualEnt,
EntityUid? cause,
SharedMapSystem mapSystem,
DamageableSystem damageable)
Shared.Damage.Systems.DamageableSystem damageable)
{
VisualEnt = visualEnt;
Cause = cause;

View File

@@ -9,7 +9,8 @@ using Content.Server.NPC.Pathfinding;
using Content.Shared.Atmos.Components;
using Content.Shared.Camera;
using Content.Shared.CCVar;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Damage.Systems;
using Content.Shared.Database;
using Content.Shared.Explosion;
using Content.Shared.Explosion.Components;

View File

@@ -3,13 +3,14 @@ using System.Numerics;
using Content.Server.Administration.Logs;
using Content.Server.Chat.Managers;
using Content.Server.GameTicking;
using Content.Server.Ghost.Components;
using Content.Server.Mind;
using Content.Server.Roles.Jobs;
using Content.Shared.Actions;
using Content.Shared.CCVar;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Damage.Prototypes;
using Content.Shared.Damage.Systems;
using Content.Shared.Database;
using Content.Shared.Examine;
using Content.Shared.Eye;
@@ -586,7 +587,7 @@ namespace Content.Server.Ghost
DamageSpecifier damage = new(_prototypeManager.Index(AsphyxiationDamageType), dealtDamage);
_damageable.TryChangeDamage(playerEntity, damage, true);
_damageable.ChangeDamage(playerEntity.Value, damage, true);
}
}

View File

@@ -1,7 +1,7 @@
using Content.Server.Body.Systems;
using Content.Server.Popups;
using Content.Shared.Actions;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.DoAfter;
using Content.Shared.Examine;
using Content.Shared.Guardian;
@@ -285,8 +285,8 @@ namespace Content.Server.Guardian
if (args.DamageDelta == null || component.Host == null || component.DamageShare == 0)
return;
_damageSystem.TryChangeDamage(
component.Host,
_damageSystem.ChangeDamage(
component.Host.Value,
args.DamageDelta * component.DamageShare,
origin: args.Origin,
ignoreResistances: true,

View File

@@ -1,10 +1,9 @@
using Content.Server.Body.Systems;
using Content.Server.Destructible;
using Content.Server.Examine;
using Content.Server.Polymorph.Components;
using Content.Server.Popups;
using Content.Shared.Body.Components;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Examine;
using Content.Shared.Popups;
using Robust.Shared.Audio.Systems;

View File

@@ -1,5 +1,6 @@
using Content.Server.NPC.HTN;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.FixedPoint;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Systems;

View File

@@ -7,7 +7,6 @@ using Content.Server.Hands.Systems;
using Content.Server.Kitchen.Components;
using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems;
using Content.Server.Temperature.Components;
using Content.Server.Temperature.Systems;
using Content.Shared.Body.Components;
using Content.Shared.Body.Part;
@@ -40,9 +39,8 @@ using Robust.Shared.Timing;
using Content.Shared.Stacks;
using Content.Server.Construction.Components;
using Content.Shared.Chat;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Temperature.Components;
using Robust.Shared.Utility;
namespace Content.Server.Kitchen.EntitySystems
{

View File

@@ -2,6 +2,7 @@ using Content.Server.Explosion.EntitySystems;
using Content.Server.Lightning;
using Content.Server.Lightning.Components;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Robust.Server.GameObjects;
namespace Content.Server.Tesla.EntitySystems;
@@ -26,7 +27,7 @@ public sealed class LightningTargetSystem : EntitySystem
{
DamageSpecifier damage = new();
damage.DamageDict.Add("Structural", uid.Comp.DamageFromLightning);
_damageable.TryChangeDamage(uid, damage, true);
_damageable.ChangeDamage(uid.Owner, damage, true);
if (uid.Comp.LightningExplode)
{

View File

@@ -4,7 +4,7 @@ using Content.Server.Body.Systems;
using Content.Server.Mech.Components;
using Content.Server.Power.EntitySystems;
using Content.Shared.ActionBlocker;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.DoAfter;
using Content.Shared.FixedPoint;
using Content.Shared.Interaction;
@@ -265,7 +265,7 @@ public sealed partial class MechSystem : SharedMechSystem
component.PilotSlot.ContainedEntity != null)
{
var damage = args.DamageDelta * component.MechToPilotDamageMultiplier;
_damageable.TryChangeDamage(component.PilotSlot.ContainedEntity, damage);
_damageable.ChangeDamage(component.PilotSlot.ContainedEntity.Value, damage);
}
}

View File

@@ -8,7 +8,8 @@ using Content.Server.Popups;
using Content.Server.PowerCell;
using Content.Shared.Traits.Assorted;
using Content.Shared.Chat;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Damage.Systems;
using Content.Shared.DoAfter;
using Content.Shared.Interaction;
using Content.Shared.Item.ItemToggle;

View File

@@ -2,7 +2,7 @@ using Content.Server.Medical.Components;
using Content.Server.PowerCell;
using Content.Shared.Body.Components;
using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.DoAfter;
using Content.Shared.IdentityManagement;
using Content.Shared.Interaction;

View File

@@ -1,6 +1,7 @@
using Content.Server.Administration.Logs;
using Content.Server.Destructible;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Damage.Systems;
using Content.Shared.Database;
using Content.Shared.FixedPoint;
using Content.Shared.Mobs.Systems;

View File

@@ -3,7 +3,7 @@ using System.Threading.Tasks;
using Content.Shared.NPC.Components;
using Content.Server.NPC.Pathfinding;
using Content.Shared.Chemistry.Components.SolutionManager;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Interaction;
using Content.Shared.Mobs.Components;
using Content.Shared.Silicons.Bots;

View File

@@ -1,6 +1,7 @@
using Content.Server.NPC.Components;
using Content.Shared.CombatMode;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Mobs.Components;
using Content.Shared.NPC.Components;
using Content.Shared.NPC.Systems;

View File

@@ -6,7 +6,6 @@ using Content.Server.NPC.Queries.Curves;
using Content.Server.NPC.Queries.Queries;
using Content.Server.Nutrition.Components;
using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.Damage;
using Content.Shared.Examine;
using Content.Shared.Fluids.Components;
using Content.Shared.Inventory;
@@ -29,6 +28,7 @@ using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
using Content.Shared.Atmos.Components;
using System.Linq;
using Content.Shared.Damage.Components;
using Content.Shared.Temperature.Components;
namespace Content.Server.NPC.Systems;

View File

@@ -1,6 +1,6 @@
using Content.Server.Ninja.Events;
using Content.Server.Power.EntitySystems;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Interaction;
using Content.Shared.Ninja.Components;
using Content.Shared.Ninja.Systems;
@@ -9,8 +9,6 @@ using Content.Shared.Stunnable;
using Content.Shared.Timing;
using Content.Shared.Whitelist;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Timing;
using Robust.Shared.Prototypes;
namespace Content.Server.Ninja.Systems;
@@ -62,7 +60,7 @@ public sealed class StunProviderSystem : SharedStunProviderSystem
_audio.PlayPvs(comp.Sound, target);
_damageable.TryChangeDamage(target, comp.StunDamage, false, true, null, origin: uid);
_damageable.ChangeDamage(target, comp.StunDamage, origin: uid);
_stun.TryAddParalyzeDuration(target, comp.StunTime);
// short cooldown to prevent instant stunlocking

View File

@@ -4,7 +4,7 @@ using Content.Server.Nutrition.Components;
using Content.Server.Popups;
using Content.Shared.Body.Components;
using Content.Shared.Atmos;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.DoAfter;
using Content.Shared.Emag.Systems;
using Content.Shared.IdentityManagement;

View File

@@ -4,7 +4,8 @@ using Content.Server.Inventory;
using Content.Server.Polymorph.Components;
using Content.Shared.Buckle;
using Content.Shared.Coordinates;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Damage.Systems;
using Content.Shared.Destructible;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.IdentityManagement;
@@ -228,7 +229,7 @@ public sealed partial class PolymorphSystem : EntitySystem
_mobThreshold.GetScaledDamage(uid, child, out var damage) &&
damage != null)
{
_damageable.SetDamage(child, damageParent, damage);
_damageable.SetDamage((child, damageParent), damage);
}
if (configuration.Inventory == PolymorphInventoryChange.Transfer)
@@ -323,7 +324,7 @@ public sealed partial class PolymorphSystem : EntitySystem
_mobThreshold.GetScaledDamage(uid, parent, out var damage) &&
damage != null)
{
_damageable.SetDamage(parent, damageParent, damage);
_damageable.SetDamage((parent, damageParent), damage);
}
if (component.Configuration.Inventory == PolymorphInventoryChange.Transfer)

View File

@@ -3,7 +3,8 @@ using Content.Server.Destructible;
using Content.Server.Effects;
using Content.Server.Weapons.Ranged.Systems;
using Content.Shared.Camera;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Damage.Systems;
using Content.Shared.Database;
using Content.Shared.FixedPoint;
using Content.Shared.Projectiles;
@@ -54,64 +55,63 @@ public sealed class ProjectileSystem : SharedProjectileSystem
damageRequired -= damageableComponent.TotalDamage;
damageRequired = FixedPoint2.Max(damageRequired, FixedPoint2.Zero);
}
var modifiedDamage = _damageableSystem.TryChangeDamage(target, ev.Damage, component.IgnoreResistances, damageable: damageableComponent, origin: component.Shooter);
var deleted = Deleted(target);
if (modifiedDamage is not null && Exists(component.Shooter))
if (_damageableSystem.TryChangeDamage((target, damageableComponent), ev.Damage, out var damage, component.IgnoreResistances, origin: component.Shooter) && Exists(component.Shooter))
{
if (modifiedDamage.AnyPositive() && !deleted)
if (!deleted)
{
_color.RaiseEffect(Color.Red, new List<EntityUid> { target }, Filter.Pvs(target, entityManager: EntityManager));
}
_adminLogger.Add(LogType.BulletHit,
LogImpact.Medium,
$"Projectile {ToPrettyString(uid):projectile} shot by {ToPrettyString(component.Shooter!.Value):user} hit {otherName:target} and dealt {modifiedDamage.GetTotal():damage} damage");
}
$"Projectile {ToPrettyString(uid):projectile} shot by {ToPrettyString(component.Shooter!.Value):user} hit {otherName:target} and dealt {damage:damage} damage");
// If penetration is to be considered, we need to do some checks to see if the projectile should stop.
if (modifiedDamage is not null && component.PenetrationThreshold != 0)
{
// If a damage type is required, stop the bullet if the hit entity doesn't have that type.
if (component.PenetrationDamageTypeRequirement != null)
// If penetration is to be considered, we need to do some checks to see if the projectile should stop.
if (component.PenetrationThreshold != 0)
{
var stopPenetration = false;
foreach (var requiredDamageType in component.PenetrationDamageTypeRequirement)
// If a damage type is required, stop the bullet if the hit entity doesn't have that type.
if (component.PenetrationDamageTypeRequirement != null)
{
if (!modifiedDamage.DamageDict.Keys.Contains(requiredDamageType))
var stopPenetration = false;
foreach (var requiredDamageType in component.PenetrationDamageTypeRequirement)
{
stopPenetration = true;
break;
if (!damage.DamageDict.Keys.Contains(requiredDamageType))
{
stopPenetration = true;
break;
}
}
if (stopPenetration)
component.ProjectileSpent = true;
}
// If the object won't be destroyed, it "tanks" the penetration hit.
if (damage.GetTotal() < damageRequired)
{
component.ProjectileSpent = true;
}
if (!component.ProjectileSpent)
{
component.PenetrationAmount += damageRequired;
// The projectile has dealt enough damage to be spent.
if (component.PenetrationAmount >= component.PenetrationThreshold)
{
component.ProjectileSpent = true;
}
}
if (stopPenetration)
component.ProjectileSpent = true;
}
// If the object won't be destroyed, it "tanks" the penetration hit.
if (modifiedDamage.GetTotal() < damageRequired)
else
{
component.ProjectileSpent = true;
}
if (!component.ProjectileSpent)
{
component.PenetrationAmount += damageRequired;
// The projectile has dealt enough damage to be spent.
if (component.PenetrationAmount >= component.PenetrationThreshold)
{
component.ProjectileSpent = true;
}
}
}
else
{
component.ProjectileSpent = true;
}
if (!deleted)
{
_guns.PlayImpactSound(target, modifiedDamage, component.SoundHit, component.ForceSound);
_guns.PlayImpactSound(target, damage, component.SoundHit, component.ForceSound);
if (!args.OurBody.LinearVelocity.IsLengthZero())
_sharedCameraRecoil.KickCamera(target, args.OurBody.LinearVelocity.Normalized());

View File

@@ -213,7 +213,7 @@ public sealed partial class RevenantSystem
return;
DamageSpecifier dspec = new();
dspec.DamageDict.Add("Cold", damage.Value);
_damage.TryChangeDamage(args.Args.Target, dspec, true, origin: uid);
_damage.ChangeDamage(args.Args.Target.Value, dspec, true, origin: uid);
args.Handled = true;
}

View File

@@ -3,7 +3,7 @@ using Content.Server.Actions;
using Content.Server.GameTicking;
using Content.Server.Store.Systems;
using Content.Shared.Alert;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.DoAfter;
using Content.Shared.Examine;
using Content.Shared.Eye;

View File

@@ -20,6 +20,7 @@ using Robust.Shared.Physics.Events;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using System.Numerics;
using Content.Shared.Damage.Components;
namespace Content.Server.Shuttles.Systems;
@@ -372,7 +373,7 @@ public sealed partial class ShuttleSystem
damageSpec.DamageDict["Blunt"] = scaledDamage;
damageSpec.DamageDict["Structural"] = scaledDamage * _structuralDamage;
_damageSys.TryChangeDamage(localEnt, damageSpec, damageable: damageable);
_damageSys.ChangeDamage((localEnt, damageable), damageSpec);
}
// might've been destroyed
if (TerminatingOrDeleted(localEnt) || EntityManager.IsQueuedForDeletion(localEnt))

View File

@@ -8,7 +8,7 @@ using Content.Server.Shuttles.Events;
using Content.Server.Station.Systems;
using Content.Server.Stunnable;
using Content.Shared.Buckle.Components;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Light.Components;
using Content.Shared.Movement.Events;
using Content.Shared.Salvage;

View File

@@ -1,16 +1,14 @@
using System.Numerics;
using Content.Server.Audio;
using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems;
using Content.Server.Shuttles.Components;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Examine;
using Content.Shared.Interaction;
using Content.Shared.Maps;
using Content.Shared.Physics;
using Content.Shared.Shuttles.Components;
using Content.Shared.Temperature;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Physics.Collision.Shapes;
using Robust.Shared.Physics.Components;

View File

@@ -1,6 +1,6 @@
using Content.Shared.Containers.ItemSlots;
using Content.Shared.DeviceNetwork;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.FixedPoint;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Systems;

View File

@@ -12,7 +12,8 @@ using Content.Server.Station.Systems;
using Content.Shared.Alert;
using Content.Shared.Chat.Prototypes;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Damage.Systems;
using Content.Shared.Destructible;
using Content.Shared.DeviceNetwork.Components;
using Content.Shared.DoAfter;
@@ -127,10 +128,7 @@ public sealed class StationAiSystem : SharedStationAiSystem
_battery.SetCharge(ent, battery.MaxCharge);
}
if (TryComp<DamageableComponent>(ent, out var damageable))
{
_damageable.SetAllDamage(ent, damageable, 0);
}
_damageable.ClearAllDamage(ent.Owner);
}
protected override void OnAiInsert(Entity<StationAiCoreComponent> ent, ref EntInsertedIntoContainerMessage args)

View File

@@ -2,7 +2,7 @@
using Content.Server.Destructible;
using Content.Server.PowerCell;
using Content.Shared.Speech.Components;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.FixedPoint;
using Content.Shared.Speech;
using Robust.Shared.Random;

View File

@@ -1,4 +1,5 @@
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Damage.Systems;
using Content.Shared.Spreader;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;

View File

@@ -5,7 +5,8 @@ using Content.Server.Body.Components;
using Content.Server.Temperature.Components;
using Content.Shared.Alert;
using Content.Shared.Atmos;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Damage.Systems;
using Content.Shared.Database;
using Content.Shared.Inventory;
using Content.Shared.Rejuvenate;

View File

@@ -5,6 +5,7 @@ using Content.Server.Power.Components;
using Content.Server.Vocalization.Systems;
using Content.Shared.Cargo;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Destructible;
using Content.Shared.Emp;
using Content.Shared.Power;

View File

@@ -1,4 +1,4 @@
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Weapons.Ranged.Components;
using Robust.Shared.Map;

View File

@@ -14,10 +14,9 @@ using Content.Server.NPC.Systems;
using Content.Server.StationEvents.Components;
using Content.Server.Speech.Components;
using Content.Shared.Body.Components;
using Content.Shared.Chat;
using Content.Shared.CombatMode;
using Content.Shared.CombatMode.Pacification;
using Content.Shared.Damage;
using Content.Shared.Damage.Components;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Humanoid;
@@ -248,8 +247,7 @@ public sealed partial class ZombieSystem
tempComp.ColdDamage.ClampMax(0);
//Heals the zombie from all the damage it took while human
if (TryComp<DamageableComponent>(target, out var damageablecomp))
_damageable.SetAllDamage(target, damageablecomp, 0);
_damageable.ClearAllDamage(target);
_mobState.ChangeMobState(target, MobState.Alive);
_faction.ClearFactions(target, dirty: false);

View File

@@ -1,4 +1,3 @@
using System.Linq;
using Content.Shared.NPC.Prototypes;
using Content.Server.Actions;
using Content.Server.Body.Systems;
@@ -11,7 +10,7 @@ using Content.Shared.Armor;
using Content.Shared.Bed.Sleep;
using Content.Shared.Cloning.Events;
using Content.Shared.Chat;
using Content.Shared.Damage;
using Content.Shared.Damage.Systems;
using Content.Shared.Humanoid;
using Content.Shared.Inventory;
using Content.Shared.Mind;
@@ -118,7 +117,7 @@ namespace Content.Server.Zombies
var curTime = _timing.CurTime;
// Hurt the living infected
var query = EntityQueryEnumerator<PendingZombieComponent, DamageableComponent, MobStateComponent>();
var query = EntityQueryEnumerator<PendingZombieComponent, Shared.Damage.Components.DamageableComponent, MobStateComponent>();
while (query.MoveNext(out var uid, out var comp, out var damage, out var mobState))
{
// Process only once per second
@@ -138,11 +137,11 @@ namespace Content.Server.Zombies
? comp.CritDamageMultiplier
: 1f;
_damageable.TryChangeDamage(uid, comp.Damage * multiplier, true, false, damage);
_damageable.ChangeDamage((uid, damage), comp.Damage * multiplier, true, false);
}
// Heal the zombified
var zombQuery = EntityQueryEnumerator<ZombieComponent, DamageableComponent, MobStateComponent>();
var zombQuery = EntityQueryEnumerator<ZombieComponent, Shared.Damage.Components.DamageableComponent, MobStateComponent>();
while (zombQuery.MoveNext(out var uid, out var comp, out var damage, out var mobState))
{
// Process only once per second
@@ -159,7 +158,7 @@ namespace Content.Server.Zombies
: 1f;
// Gradual healing for living zombies.
_damageable.TryChangeDamage(uid, comp.PassiveHealing * multiplier, true, false, damage);
_damageable.ChangeDamage((uid, damage), comp.PassiveHealing * multiplier, true, false);
}
}