using System.Linq; using Content.Shared.Chemistry; using Content.Shared.Damage.Components; using Content.Shared.Explosion.EntitySystems; using Content.Shared.Mobs.Systems; using Robust.Shared.Configuration; using Robust.Shared.GameStates; using Robust.Shared.Network; using Robust.Shared.Prototypes; using Robust.Shared.Utility; namespace Content.Shared.Damage.Systems; public sealed partial class DamageableSystem : EntitySystem { [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly INetManager _netMan = default!; [Dependency] private readonly MobThresholdSystem _mobThreshold = default!; [Dependency] private readonly IConfigurationManager _config = default!; [Dependency] private readonly SharedChemistryGuideDataSystem _chemistryGuideData = default!; [Dependency] private readonly SharedExplosionSystem _explosion = default!; private EntityQuery _appearanceQuery; private EntityQuery _damageableQuery; public float UniversalAllDamageModifier { get; private set; } = 1f; public float UniversalAllHealModifier { get; private set; } = 1f; public float UniversalMeleeDamageModifier { get; private set; } = 1f; public float UniversalProjectileDamageModifier { get; private set; } = 1f; public float UniversalHitscanDamageModifier { get; private set; } = 1f; public float UniversalReagentDamageModifier { get; private set; } = 1f; public float UniversalReagentHealModifier { get; private set; } = 1f; public float UniversalExplosionDamageModifier { get; private set; } = 1f; public float UniversalThrownDamageModifier { get; private set; } = 1f; public float UniversalTopicalsHealModifier { get; private set; } = 1f; public float UniversalMobDamageModifier { get; private set; } = 1f; /// /// If the damage in a DamageableComponent was changed this function should be called. /// /// /// This updates cached damage information, flags the component as dirty, and raises a damage changed event. /// The damage changed event is used by other systems, such as damage thresholds. /// private void OnEntityDamageChanged( Entity ent, DamageSpecifier? damageDelta = null, bool interruptsDoAfters = true, EntityUid? origin = null, bool forceRefresh = false // Offbrand ) { ent.Comp.Damage.GetDamagePerGroup(_prototypeManager, ent.Comp.DamagePerGroup); ent.Comp.TotalDamage = ent.Comp.Damage.GetTotal(); Dirty(ent); if (damageDelta != null && _appearanceQuery.TryGetComponent(ent, out var appearance)) { _appearance.SetData( ent, DamageVisualizerKeys.DamageUpdateGroups, new DamageVisualizerGroupData(ent.Comp.DamagePerGroup.Keys.ToList()), appearance ); } // TODO DAMAGE // byref struct event. RaiseLocalEvent(ent, new DamageChangedEvent(ent.Comp, damageDelta, interruptsDoAfters, origin, forceRefresh)); // Offbrand } private void DamageableGetState(Entity ent, ref ComponentGetState args) { if (_netMan.IsServer) { args.State = new DamageableComponentState( ent.Comp.Damage.DamageDict, ent.Comp.DamageContainerID, ent.Comp.DamageModifierSetId, ent.Comp.HealthBarThreshold ); // TODO BODY SYSTEM pass damage onto body system // BOBBY WHEN? 😭 // BOBBY SOON 🫡 return; } // avoid mispredicting damage on newly spawned entities. args.State = new DamageableComponentState( ent.Comp.Damage.DamageDict.ShallowClone(), ent.Comp.DamageContainerID, ent.Comp.DamageModifierSetId, ent.Comp.HealthBarThreshold ); } }