using System.Linq; using Content.Shared._DV.Psionics.Components; using Content.Shared._DV.Psionics.Events; using Content.Shared._DV.Psionics.Systems.PsionicPowers; using Content.Shared.Damage.Events; using Content.Shared.Inventory; using Content.Shared.Inventory.Events; using Content.Shared.StatusEffectNew; using Content.Shared.Weapons.Melee.Events; using Robust.Shared.Audio.Systems; using Robust.Shared.Random; using Robust.Shared.Timing; namespace Content.Shared._DV.Psionics.Systems; public abstract partial class SharedPsionicSystem { [Dependency] private readonly IGameTiming _timing = default!; [Dependency] protected readonly SharedAudioSystem Audio = default!; [Dependency] private readonly SharedMindSwapPowerSystem _mindSwapPowerSystem = default!; [Dependency] private readonly StatusEffectsSystem _statusEffects = default!; private void InitializeItems() { SubscribeLocalEvent(OnInsulativeGearEquipped); SubscribeLocalEvent(OnInsulativeGearUnequipped); SubscribeLocalEvent>(OnPowerUseAttempt); SubscribeLocalEvent>(OnTargetedByPsionicPower); SubscribeLocalEvent(OnAntiPsionicMeleeHit); SubscribeLocalEvent(OnAntiPsionicStamHit); } private void OnInsulativeGearEquipped(Entity gear, ref GotEquippedEvent args) { if (_timing.ApplyingState) return; if (!gear.Comp.AllowsPsionicUsage) { var ev = new PsionicSuppressedEvent(args.Equipee); RaiseLocalEvent(args.Equipee, ref ev); } if (gear.Comp.ShieldsFromPsionics) { var ev = new PsionicShieldedEvent(args.Equipee); RaiseLocalEvent(args.Equipee, ref ev); } } private void OnInsulativeGearUnequipped(Entity gear, ref GotUnequippedEvent args) { if (_timing.ApplyingState) return; if (!gear.Comp.AllowsPsionicUsage && CanUsePsionicAbility(args.Equipee)) { var ev = new PsionicStoppedSuppressedEvent(args.Equipee); RaiseLocalEvent(args.Equipee, ref ev); } if (gear.Comp.ShieldsFromPsionics && CanBeTargeted(args.Equipee, showPopup: false)) { var ev = new PsionicStoppedShieldedEvent(args.Equipee); RaiseLocalEvent(args.Equipee, ref ev); } } #region EventHandling private void OnPowerUseAttempt(Entity gear, ref InventoryRelayedEvent args) { // If one gear blocks psionic usage, psionics cannot be used. args.Args.CanUsePower &= gear.Comp.AllowsPsionicUsage; } private void OnTargetedByPsionicPower(Entity gear, ref InventoryRelayedEvent args) { // If one gear shields from psionics, they're shielded. args.Args.IsShielded |= gear.Comp.ShieldsFromPsionics; } #endregion #region AntiPsionicWeaponry private void OnAntiPsionicMeleeHit(Entity weapon, ref MeleeHitEvent args) { foreach (var target in args.HitEntities) { if (HasComp(target)) { Audio.PlayPredicted(weapon.Comp.HitSound, target, args.User); args.ModifiersList.Add(weapon.Comp.Modifiers); if (Random.Prob(weapon.Comp.DisableChance)) _statusEffects.TryUpdateStatusEffectDuration(target, PsionicsDisabledProtoId, TimeSpan.FromSeconds(10)); } if (TryComp(target, out var swapped)) { _mindSwapPowerSystem.SwapMinds(target, swapped.OriginalEntity, false); return; } if (!weapon.Comp.Punish || !HasComp(target) || HasComp(target) || !Random.Prob(weapon.Comp.PunishChance)) continue; _stuttering.DoStutter(args.User, TimeSpan.FromMinutes(5), false); _stun.TryKnockdown(args.User, TimeSpan.FromSeconds(5), false, drop: false); _jittering.DoJitter(args.User, TimeSpan.FromSeconds(5), false); } } private void OnAntiPsionicStamHit(Entity weapon, ref StaminaMeleeHitEvent args) { if (args.HitList.Any(targetStamina => HasComp(targetStamina.Entity))) { args.Multiplier *= weapon.Comp.StaminaDamageMultiplier; } } #endregion }