From 5ecc849b1f35effe57a86bc241ea22f85bebde4b Mon Sep 17 00:00:00 2001 From: TheGrimbeeper Date: Fri, 28 Feb 2025 13:43:35 +1100 Subject: [PATCH] Radiation protective armor and medicine now effect message frequency Hooked into the existing damage modifier system to allow detection of applicable radiation modifiers. Also: - if you can't take damage, you won't see the messages - adds a 'virtualDamage' field to the damage modify event to allow seeing what modifiers exist without actually dealing damage to things like shields. --- .../Systems/RadiationNoticingSystem.cs | 42 +++++++++++++++++-- .../Blocking/BlockingSystem.User.cs | 5 ++- .../Damage/Systems/DamageableSystem.cs | 5 ++- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/Content.Server/_Impstation/Radiation/Systems/RadiationNoticingSystem.cs b/Content.Server/_Impstation/Radiation/Systems/RadiationNoticingSystem.cs index f60d959efe54..4f4e550c0828 100644 --- a/Content.Server/_Impstation/Radiation/Systems/RadiationNoticingSystem.cs +++ b/Content.Server/_Impstation/Radiation/Systems/RadiationNoticingSystem.cs @@ -2,7 +2,12 @@ using Content.Shared.Radiation.Events; using Robust.Shared.Player; using Robust.Shared.Random; +using Content.Shared.Damage; +using Content.Shared.Damage.Prototypes; using Content.Server.Radiation.Components; +using Content.Shared.FixedPoint; +using Robust.Shared.Prototypes; + using System.Linq; namespace Content.Server.Radiation.Systems; @@ -11,6 +16,7 @@ public sealed class RadiationNoticingSystem : EntitySystem { [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly SharedPopupSystem _popupSystem = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; public override void Initialize() { @@ -20,10 +26,40 @@ public override void Initialize() private void OnIrradiated(EntityUid uid, ActorComponent actorComponent, OnIrradiatedEvent args) { + // Convert recieved radiation from event into actual radiation after rad damage reductions + if (!TryComp(uid, out var damageable)) + return; // If you aren't taking damage from radiation then what the messages say make no sense + var trueTotalRads = args.TotalRads; + + DamageSpecifier damage = new(); + foreach (var typeId in damageable.RadiationDamageTypeIDs) + { + damage.DamageDict.Add(typeId, FixedPoint2.New(args.TotalRads)); + } + + // Calculate entity inherent resistances + if (damageable.DamageModifierSetId != null && + _prototypeManager.TryIndex(damageable.DamageModifierSetId, out var modifierSet)) + { + // Hook into damage modifier calculation system + damage = DamageSpecifier.ApplyModifierSet(damage, modifierSet); + } + + //Raise event to get all armor/shield/etc resistances + var ev = new DamageModifyEvent(damage, null, true); + RaiseLocalEvent(uid, ev); + damage = ev.Damage; + + if (damage.Empty) + { + return; + } + trueTotalRads = (float)damage.GetTotal(); + // Roll chance for popup messages - // This is per radiation update tick, - // is tuned so that when being irradiated with 1 rad/sec, see 1 message every 5-ish seconds on average - if (_random.NextFloat() <= args.RadsPerSecond / 20) + // Based on incoming rads so variable frame time does not alter message rate + // Tuned for approx 1 message every 5 seconds or so per 1 rad/second incoming + if (_random.NextFloat() <= trueTotalRads / 14) { SendRadiationPopup(uid); } diff --git a/Content.Shared/Blocking/BlockingSystem.User.cs b/Content.Shared/Blocking/BlockingSystem.User.cs index f69f91fb3e69..41934e10bc53 100644 --- a/Content.Shared/Blocking/BlockingSystem.User.cs +++ b/Content.Shared/Blocking/BlockingSystem.User.cs @@ -70,7 +70,8 @@ private void OnUserDamageModified(EntityUid uid, BlockingUserComponent component var blockFraction = blocking.IsBlocking ? blocking.ActiveBlockFraction : blocking.PassiveBlockFraction; blockFraction = Math.Clamp(blockFraction, 0, 1); - _damageable.TryChangeDamage(component.BlockingItem, blockFraction * args.OriginalDamage); + if (!args.IsVirtual) //#IMP Don't damage shield if we are just seeing what damage COULD be blocked + _damageable.TryChangeDamage(component.BlockingItem, blockFraction * args.OriginalDamage); var modify = new DamageModifierSet(); foreach (var key in dmgComp.Damage.DamageDict.Keys) @@ -80,7 +81,7 @@ private void OnUserDamageModified(EntityUid uid, BlockingUserComponent component args.Damage = DamageSpecifier.ApplyModifierSet(args.Damage, modify); - if (blocking.IsBlocking && !args.Damage.Equals(args.OriginalDamage)) + if (blocking.IsBlocking && !args.Damage.Equals(args.OriginalDamage) && !args.IsVirtual) //#IMP => IsVirtual { _audio.PlayPvs(blocking.BlockSound, uid); } diff --git a/Content.Shared/Damage/Systems/DamageableSystem.cs b/Content.Shared/Damage/Systems/DamageableSystem.cs index 3c3e1b736df3..bd1efd3381d9 100644 --- a/Content.Shared/Damage/Systems/DamageableSystem.cs +++ b/Content.Shared/Damage/Systems/DamageableSystem.cs @@ -304,11 +304,14 @@ public sealed class DamageModifyEvent : EntityEventArgs, IInventoryRelayEvent public DamageSpecifier Damage; public EntityUid? Origin; - public DamageModifyEvent(DamageSpecifier damage, EntityUid? origin = null) + public bool IsVirtual; //#IMP For when you want to see what damage could be dealt, without actually dealing it + + public DamageModifyEvent(DamageSpecifier damage, EntityUid? origin = null, bool isVirtual = false) { OriginalDamage = damage; Damage = damage; Origin = origin; + IsVirtual = isVirtual;// # IMP } }