diff --git a/Content.Server/Communications/CommsHackerSystem.cs b/Content.Server/Communications/CommsHackerSystem.cs index 1cfe0e26cfd..c70d2bedab6 100644 --- a/Content.Server/Communications/CommsHackerSystem.cs +++ b/Content.Server/Communications/CommsHackerSystem.cs @@ -12,7 +12,7 @@ using Content.Server.Chat.Systems; using Content.Server.GameTicking; using Content.Server.Ninja.Systems; -using Content.Server.Power.EntitySystems; // goobstation - check power +using Content.Server.Power.EntitySystems; // goobstation - check power using Content.Shared.Communications; using Content.Shared.DoAfter; using Content.Shared.Interaction; @@ -46,7 +46,7 @@ public override void Initialize() /// private void OnBeforeInteractHand(EntityUid uid, CommsHackerComponent comp, BeforeInteractHandEvent args) { - if (args.Handled || !HasComp(args.Target)) + if (args.Handled || !TryComp(args.Target, out var console) || !console.CanShuttle) // Omu, change hascomp to trycomp, and check if the comms console can call shuttle return; if (!_powerReceiverSystem.IsPowered(args.Target)) // Goobstation - is powererd return; diff --git a/Content.Shared/Ninja/Components/SpaceNinjaComponent.cs b/Content.Shared/Ninja/Components/SpaceNinjaComponent.cs index 22f3cbd4122..90ff9524379 100644 --- a/Content.Shared/Ninja/Components/SpaceNinjaComponent.cs +++ b/Content.Shared/Ninja/Components/SpaceNinjaComponent.cs @@ -10,6 +10,7 @@ using Content.Shared.Ninja.Systems; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; +using Content.Goobstation.Maths.FixedPoint; namespace Content.Shared.Ninja.Components; @@ -62,4 +63,11 @@ public sealed partial class SpaceNinjaComponent : Component /// [DataField] public ProtoId SuitPowerAlert = "SuitPower"; -} \ No newline at end of file + + /// + /// DeltaV - The minimum damage to reveal the ninja on damage. Should be positive, since negative values are considered healing. + /// Note that the ninja suit has 20% brute resist and punches deal 5 damage, so 4 should be enough to reveal. + /// + [DataField] + public FixedPoint2 MinimumRevealDamage = 4; +} diff --git a/Content.Shared/Ninja/Systems/SharedSpaceNinjaSystem.cs b/Content.Shared/Ninja/Systems/SharedSpaceNinjaSystem.cs index a6cbd1f108c..88ec766d8af 100644 --- a/Content.Shared/Ninja/Systems/SharedSpaceNinjaSystem.cs +++ b/Content.Shared/Ninja/Systems/SharedSpaceNinjaSystem.cs @@ -12,6 +12,10 @@ using Content.Shared.Weapons.Ranged.Events; using Content.Shared.Popups; using System.Diagnostics.CodeAnalysis; +using Content.Shared.Damage; // DeltaV +using Content.Shared.Damage.Systems; // DeltaV +using Content.Shared.Stealth.Components; // DeltaV +using Robust.Shared.Prototypes; // DeltaV namespace Content.Shared.Ninja.Systems; @@ -22,6 +26,7 @@ public abstract class SharedSpaceNinjaSystem : EntitySystem { [Dependency] protected readonly SharedNinjaSuitSystem Suit = default!; [Dependency] protected readonly SharedPopupSystem Popup = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; // DeltaV public EntityQuery NinjaQuery; @@ -31,9 +36,10 @@ public override void Initialize() NinjaQuery = GetEntityQuery(); - SubscribeLocalEvent(OnNinjaAttacked); + // SubscribeLocalEvent(OnNinjaAttacked); // DeltaV - Handled by the DamageChangedEvent SubscribeLocalEvent(OnNinjaAttack); SubscribeLocalEvent(OnShotAttempted); + SubscribeLocalEvent(OnNinjaAttacked); // DeltaV - Reveal the ninja on damage } public bool IsNinja([NotNullWhen(true)] EntityUid? uid) @@ -87,11 +93,49 @@ public virtual bool TryUseCharge(EntityUid user, float charge) return false; } + // DeltaV - Handled by the DamageChangedEvent /// /// Handle revealing ninja if cloaked when attacked. /// - private void OnNinjaAttacked(Entity ent, ref AttackedEvent args) + //private void OnNinjaAttacked(Entity ent, ref AttackedEvent args) + //{ + // TryRevealNinja(ent, disable: true); + //} + // END DeltaV + + /// + /// DeltaV - Handle revealing ninja if cloaked when attacked by a hitscan attack. + /// + private void OnNinjaAttacked(Entity ent, ref DamageChangedEvent args) { + // If there's no damage delta, just return + if (args.DamageDelta is not { } damage) + return; + + // Don't reveal on (most) healing + if (!args.DamageIncreased) + return; + + // If the damage doesn't have a source, we need to check the type, in case it + // was a grenade or explosion. We want to ignore airloss and toxin damage types. + if (!args.Origin.HasValue) + { + // If there are any negative values, its probably natual or chem healing, so don't reveal. It might be an OD from medicine. + if (!damage.AnyPositive()) + return; + + // Check the damage types for damage types that should reveal (brute, burns) + // Basically, we want to ignore most indirect forms of damage (airloss, toxins) + var damageGroups = damage.GetDamagePerGroup(_prototypeManager); + if (!damageGroups.ContainsKey("Brute") && !damageGroups.ContainsKey("Burn")) // This feels a bit dirty, oh well. + return; + } + + // Only reveal on damage at least the minumum. This prevents tiny ticks of damage (e.g. from malign rifts pulses) + if (damage.GetTotal() < ent.Comp.MinimumRevealDamage) + return; + + // Yea, now reveal that son of a bitch >:3 TryRevealNinja(ent, disable: true); }