diff --git a/Content.Server/Abilities/Psionics/Abilities/HealOtherPowerSystem.cs b/Content.Server/Abilities/Psionics/Abilities/HealOtherPowerSystem.cs index 85bae78dc6b..35b5e6a2381 100644 --- a/Content.Server/Abilities/Psionics/Abilities/HealOtherPowerSystem.cs +++ b/Content.Server/Abilities/Psionics/Abilities/HealOtherPowerSystem.cs @@ -53,14 +53,14 @@ private void OnPowerUsed(EntityUid uid, PsionicComponent component, PsionicHealO else ActivatePower(uid, component, args); if (args.PopupText is not null - && _glimmer.Glimmer > args.GlimmerObviousPopupThreshold * component.CurrentDampening) + && _glimmer.Glimmer > args.GlimmerPopupThreshold * component.CurrentDampening) _popupSystem.PopupEntity(Loc.GetString(args.PopupText, ("entity", uid)), uid, Filter.Pvs(uid).RemoveWhereAttachedEntity(entity => !_examine.InRangeUnOccluded(uid, entity, ExamineRange, null)), true, args.PopupType); if (args.PlaySound - && _glimmer.Glimmer > args.GlimmerObviousSoundThreshold * component.CurrentDampening) + && _glimmer.Glimmer > args.GlimmerSoundThreshold * component.CurrentDampening) _audioSystem.PlayPvs(args.SoundUse, uid, args.AudioParams); // Sanitize the Glimmer inputs because otherwise the game will crash if someone makes MaxGlimmer lower than MinGlimmer. @@ -76,13 +76,16 @@ private void OnPowerUsed(EntityUid uid, PsionicComponent component, PsionicHealO private void AttemptDoAfter(EntityUid uid, PsionicComponent component, PsionicHealOtherPowerActionEvent args) { var ev = new PsionicHealOtherDoAfterEvent(_gameTiming.CurTime); - ev.HealingAmount = args.HealingAmount; - ev.RotReduction = args.RotReduction; + if (args.HealingAmount is not null) + ev.HealingAmount = args.HealingAmount; + if (args.RotReduction is not null) + ev.RotReduction = args.RotReduction.Value; ev.DoRevive = args.DoRevive; var doAfterArgs = new DoAfterArgs(EntityManager, uid, args.UseDelay, ev, uid, target: args.Target) { BreakOnUserMove = args.BreakOnUserMove, BreakOnTargetMove = args.BreakOnTargetMove, + Hidden = _glimmer.Glimmer > args.GlimmerDoAfterVisibilityThreshold * component.CurrentDampening, }; if (!_doAfterSystem.TryStartDoAfter(doAfterArgs, out var doAfterId)) @@ -104,7 +107,8 @@ private void OnDispelled(EntityUid uid, PsionicComponent component, DispelledEve private void OnDoAfter(EntityUid uid, PsionicComponent component, PsionicHealOtherDoAfterEvent args) { // It's entirely possible for the caster to stop being Psionic(due to mindbreaking) mid cast - if (component is null) + if (component is null + || args.Cancelled) return; component.DoAfter = null; @@ -112,15 +116,19 @@ private void OnDoAfter(EntityUid uid, PsionicComponent component, PsionicHealOth if (args.Target is null) return; - _rotting.ReduceAccumulator(args.Target.Value, TimeSpan.FromSeconds(args.RotReduction * component.CurrentAmplification)); + if (args.RotReduction is not null) + _rotting.ReduceAccumulator(args.Target.Value, TimeSpan.FromSeconds(args.RotReduction.Value * component.CurrentAmplification)); if (!TryComp(args.Target.Value, out var damageableComponent)) return; - _damageable.TryChangeDamage(args.Target.Value, args.HealingAmount * component.CurrentAmplification, true, false, damageableComponent, uid); + if (args.HealingAmount is not null) + _damageable.TryChangeDamage(args.Target.Value, args.HealingAmount * component.CurrentAmplification, true, false, damageableComponent, uid); if (!args.DoRevive - || !TryComp(args.Target, out var mob) + || _rotting.IsRotten(args.Target.Value) + || !TryComp(args.Target.Value, out var mob) + || !_mobState.IsDead(args.Target.Value, mob) || !_mobThreshold.TryGetThresholdForState(args.Target.Value, MobState.Dead, out var threshold) || damageableComponent.TotalDamage > threshold) return; @@ -134,15 +142,19 @@ private void ActivatePower(EntityUid uid, PsionicComponent component, PsionicHea if (component is null) return; - _rotting.ReduceAccumulator(args.Target, TimeSpan.FromSeconds(args.RotReduction * component.CurrentAmplification)); + if (args.RotReduction is not null) + _rotting.ReduceAccumulator(args.Target, TimeSpan.FromSeconds(args.RotReduction.Value * component.CurrentAmplification)); if (!TryComp(args.Target, out var damageableComponent)) return; - _damageable.TryChangeDamage(args.Target, args.HealingAmount * component.CurrentAmplification, true, false, damageableComponent, uid); + if (args.HealingAmount is not null) + _damageable.TryChangeDamage(args.Target, args.HealingAmount * component.CurrentAmplification, true, false, damageableComponent, uid); if (!args.DoRevive + || _rotting.IsRotten(args.Target) || !TryComp(args.Target, out var mob) + || !_mobState.IsDead(args.Target, mob) || !_mobThreshold.TryGetThresholdForState(args.Target, MobState.Dead, out var threshold) || damageableComponent.TotalDamage > threshold) return; diff --git a/Content.Shared/Actions/Events/PsionicHealOtherPowerActionEvent.cs b/Content.Shared/Actions/Events/PsionicHealOtherPowerActionEvent.cs index 8cf11b9e66d..0001c7842d7 100644 --- a/Content.Shared/Actions/Events/PsionicHealOtherPowerActionEvent.cs +++ b/Content.Shared/Actions/Events/PsionicHealOtherPowerActionEvent.cs @@ -6,7 +6,7 @@ namespace Content.Shared.Actions.Events; public sealed partial class PsionicHealOtherPowerActionEvent : EntityTargetActionEvent { [DataField] - public DamageSpecifier HealingAmount = default!; + public DamageSpecifier? HealingAmount = default!; [DataField] public string PowerName; @@ -19,7 +19,7 @@ public sealed partial class PsionicHealOtherPowerActionEvent : EntityTargetActio public string? PopupText; [DataField] - public float RotReduction; + public float? RotReduction; [DataField] public bool DoRevive; @@ -40,10 +40,13 @@ public sealed partial class PsionicHealOtherPowerActionEvent : EntityTargetActio public int MaxGlimmer = 12; [DataField] - public int GlimmerObviousSoundThreshold; + public int GlimmerSoundThreshold; [DataField] - public int GlimmerObviousPopupThreshold; + public int GlimmerPopupThreshold; + + [DataField] + public int GlimmerDoAfterVisibilityThreshold; [DataField] public PopupType PopupType = PopupType.Medium; diff --git a/Content.Shared/Psionics/Events.cs b/Content.Shared/Psionics/Events.cs index f110c9c405f..744dd3b6ea2 100644 --- a/Content.Shared/Psionics/Events.cs +++ b/Content.Shared/Psionics/Events.cs @@ -42,10 +42,10 @@ public sealed partial class PsionicHealOtherDoAfterEvent : DoAfterEvent public TimeSpan StartedAt; [DataField] - public DamageSpecifier HealingAmount = default!; + public DamageSpecifier? HealingAmount = default!; [DataField] - public float RotReduction; + public float? RotReduction; [DataField] public bool DoRevive; diff --git a/Resources/Prototypes/Actions/psionics.yml b/Resources/Prototypes/Actions/psionics.yml index d38608a469b..82e356a11f5 100644 --- a/Resources/Prototypes/Actions/psionics.yml +++ b/Resources/Prototypes/Actions/psionics.yml @@ -179,8 +179,9 @@ playSound: true minGlimmer: 2 maxGlimmer: 4 - glimmerObviousSoundThreshold: 100 - glimmerObviousPopupThreshold: 200 + glimmerSoundThreshold: 100 + glimmerPopupThreshold: 200 + glimmerDoAfterVisibilityThreshold: 70 - type: entity id: ActionRevivify @@ -217,5 +218,6 @@ playSound: true minGlimmer: 10 # These also get multiplied by caster stats. So, maxGlimmer: 15 # keeping in mind the ~3.5x multiplier, this spikes glimmer by as much as 60 points. - glimmerObviousSoundThreshold: 50 - glimmerObviousPopupThreshold: 100 + glimmerSoundThreshold: 50 + glimmerPopupThreshold: 100 + glimmerDoAfterVisibilityThreshold: 35