Refactors stunnable to be ECS. (#4819)

Also cleans up StandingStatesystem.
This commit is contained in:
Vera Aguilera Puerto
2021-10-10 12:47:26 +02:00
committed by GitHub
parent 19a588a70a
commit 6eee256b11
34 changed files with 776 additions and 633 deletions

View File

@@ -7,7 +7,7 @@ namespace Content.Server.Act
/// <summary>
/// Implements behavior when an entity is disarmed.
/// </summary>
[RequiresExplicitImplementation]
[RequiresExplicitImplementation, Obsolete("Use the directed event instead.")]
public interface IDisarmedAct
{
/// <summary>
@@ -15,7 +15,7 @@ namespace Content.Server.Act
/// Return true to prevent the default disarm behavior,
/// or rest of IDisarmedAct behaviors that come after this one from happening.
/// </summary>
bool Disarmed(DisarmedActEventArgs eventArgs);
bool Disarmed(DisarmedActEvent @event);
/// <summary>
/// Priority for this disarm act.
@@ -24,7 +24,7 @@ namespace Content.Server.Act
int Priority => 0;
}
public class DisarmedActEventArgs : EventArgs
public class DisarmedActEvent : HandledEntityEventArgs
{
/// <summary>
/// The entity being disarmed.

View File

@@ -91,11 +91,18 @@ namespace Content.Server.Actions.Actions
system.SendAnimation("disarm", angle, args.Performer, args.Performer, new[] { args.Target });
var eventArgs = new DisarmedActEventArgs() { Target = args.Target, Source = args.Performer, PushProbability = _pushProb };
var eventArgs = new DisarmedActEvent() { Target = args.Target, Source = args.Performer, PushProbability = _pushProb };
IoCManager.Resolve<IEntityManager>().EventBus.RaiseLocalEvent(args.Target.Uid, eventArgs);
// Check if the event has been handled, and if so, do nothing else!
if (eventArgs.Handled)
return;
// Sort by priority.
Array.Sort(disarmedActs, (a, b) => a.Priority.CompareTo(b.Priority));
// TODO: Remove this shit.
foreach (var disarmedAct in disarmedActs)
{
if (disarmedAct.Disarmed(eventArgs))

View File

@@ -2,12 +2,14 @@ using Content.Server.Atmos.Components;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Nutrition.Components;
using Content.Server.Nutrition.EntitySystems;
using Content.Server.Stunnable;
using Content.Server.Stunnable.Components;
using Content.Shared.Administration;
using Content.Shared.Damage;
using Content.Shared.Jittering;
using Content.Shared.MobState;
using Content.Shared.Nutrition.Components;
using Content.Shared.Stunnable;
using Robust.Server.Player;
using Robust.Shared.Console;
using Robust.Shared.GameObjects;
@@ -56,7 +58,11 @@ namespace Content.Server.Administration.Commands
target.GetComponentOrNull<IMobStateComponent>()?.UpdateState(0);
target.GetComponentOrNull<HungerComponent>()?.ResetFood();
target.GetComponentOrNull<ThirstComponent>()?.ResetThirst();
target.GetComponentOrNull<StunnableComponent>()?.ResetStuns();
if (target.TryGetComponent(out StunnableComponent? stunnable))
{
EntitySystem.Get<StunSystem>().Reset(target.Uid, stunnable);
}
if (target.TryGetComponent(out FlammableComponent? flammable))
{

View File

@@ -1,6 +1,7 @@
using System;
using Content.Server.Alert;
using Content.Server.Atmos.Components;
using Content.Server.Stunnable;
using Content.Server.Stunnable.Components;
using Content.Server.Temperature.Components;
using Content.Shared.ActionBlocker;
@@ -9,6 +10,7 @@ using Content.Shared.Atmos;
using Content.Shared.Damage;
using Content.Shared.Interaction;
using Content.Shared.Popups;
using Content.Shared.Stunnable;
using Content.Shared.Temperature;
using Robust.Server.GameObjects;
using Robust.Shared.GameObjects;
@@ -24,6 +26,7 @@ namespace Content.Server.Atmos.EntitySystems
[Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!;
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
[Dependency] private readonly StunSystem _stunSystem = default!;
private const float MinimumFireStacks = -10f;
private const float MaximumFireStacks = 20f;
@@ -148,7 +151,10 @@ namespace Content.Server.Atmos.EntitySystems
UpdateAppearance(uid, flammable);
}
public void Resist(EntityUid uid, FlammableComponent? flammable = null, StunnableComponent? stunnable = null)
public void Resist(EntityUid uid,
FlammableComponent? flammable = null,
StunnableComponent? stunnable = null,
ServerAlertsComponent? alerts = null)
{
if (!Resolve(uid, ref flammable, ref stunnable))
return;
@@ -159,8 +165,9 @@ namespace Content.Server.Atmos.EntitySystems
flammable.Resisting = true;
flammable.Owner.PopupMessage(Loc.GetString("flammable-component-resist-message"));
stunnable.Paralyze(2f);
_stunSystem.Paralyze(uid, TimeSpan.FromSeconds(2f), stunnable, alerts);
// TODO FLAMMABLE: Make this not use TimerComponent...
flammable.Owner.SpawnTimer(2000, () =>
{
flammable.Resisting = false;

View File

@@ -13,6 +13,7 @@ using Content.Shared.Popups;
using Content.Shared.Pulling;
using Content.Shared.Pulling.Components;
using Content.Shared.Standing;
using Content.Shared.Stunnable;
using Robust.Server.GameObjects;
using Robust.Shared.Audio;
using Robust.Shared.Containers;

View File

@@ -1,13 +1,16 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using Content.Server.Items;
using Content.Server.MachineLinking.Events;
using Content.Server.MachineLinking.Models;
using Content.Server.Power.Components;
using Content.Server.Stunnable;
using Content.Server.Stunnable.Components;
using Content.Shared.Conveyor;
using Content.Shared.MachineLinking;
using Content.Shared.Movement.Components;
using Content.Shared.Popups;
using Content.Shared.Stunnable;
using Robust.Server.GameObjects;
using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
@@ -20,6 +23,7 @@ namespace Content.Server.Conveyor
{
public class ConveyorSystem : EntitySystem
{
[Dependency] private StunSystem _stunSystem = default!;
[Dependency] private IEntityLookup _entityLookup = default!;
public override void Initialize()
@@ -60,7 +64,7 @@ namespace Content.Server.Conveyor
args.Cancel();
if (args.Attemptee.TryGetComponent<StunnableComponent>(out var stunnableComponent))
{
stunnableComponent.Paralyze(2);
_stunSystem.Paralyze(uid, TimeSpan.FromSeconds(2f), stunnableComponent);
component.Owner.PopupMessage(args.Attemptee, Loc.GetString("conveyor-component-failed-link"));
}
}

View File

@@ -9,6 +9,7 @@ using Content.Shared.Interaction;
using Content.Shared.Interaction.Helpers;
using Content.Shared.Popups;
using Content.Shared.Sound;
using Content.Shared.Stunnable;
using Robust.Shared.Audio;
using Robust.Shared.GameObjects;
using Robust.Shared.Localization;

View File

@@ -1,7 +1,10 @@
using System;
using Content.Server.Damage.Components;
using Content.Server.Stunnable;
using Content.Server.Stunnable.Components;
using Content.Shared.Audio;
using Content.Shared.Damage;
using Content.Shared.Stunnable;
using JetBrains.Annotations;
using Robust.Shared.Audio;
using Robust.Shared.GameObjects;
@@ -19,6 +22,7 @@ namespace Content.Server.Damage.Systems
[Dependency] private readonly IRobustRandom _robustRandom = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
[Dependency] private readonly StunSystem _stunSystem = default!;
public override void Initialize()
{
@@ -43,7 +47,7 @@ namespace Content.Server.Damage.Systems
component.LastHit = _gameTiming.CurTime;
if (EntityManager.TryGetComponent(uid, out StunnableComponent? stun) && _robustRandom.Prob(component.StunChance))
stun.Stun(component.StunSeconds);
_stunSystem.Stun(uid, TimeSpan.FromSeconds(component.StunSeconds), stun);
var damageScale = (speed / component.MinimumSpeed) * component.Factor;
_damageableSystem.TryChangeDamage(uid, component.Damage * damageScale);

View File

@@ -3,6 +3,7 @@ using System.Threading.Tasks;
using Content.Server.Hands.Components;
using Content.Server.Items;
using Content.Server.Stunnable.Components;
using Content.Shared.Stunnable;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;

View File

@@ -8,6 +8,7 @@ using Content.Server.Atmos.Components;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Construction.Components;
using Content.Server.Hands.Components;
using Content.Server.Stunnable;
using Content.Server.Stunnable.Components;
using Content.Server.Tools;
using Content.Server.Tools.Components;
@@ -15,6 +16,7 @@ using Content.Shared.Damage;
using Content.Shared.Doors;
using Content.Shared.Interaction;
using Content.Shared.Sound;
using Content.Shared.Stunnable;
using Content.Shared.Tools;
using Content.Shared.Tools.Components;
using Robust.Shared.Audio;
@@ -553,12 +555,6 @@ namespace Content.Server.Doors.Components
// Crush
foreach (var e in collidingentities)
{
if (!e.Owner.TryGetComponent(out StunnableComponent? stun)
|| !e.Owner.HasComponent<DamageableComponent>())
{
continue;
}
var percentage = e.GetWorldAABB().IntersectPercentage(doorAABB);
if (percentage < 0.1f)
@@ -567,9 +563,11 @@ namespace Content.Server.Doors.Components
hitsomebody = true;
CurrentlyCrushing.Add(e.Owner.Uid);
EntitySystem.Get<DamageableSystem>().TryChangeDamage(e.Owner.Uid, CrushDamage);
if (e.Owner.HasComponent<DamageableComponent>())
EntitySystem.Get<DamageableSystem>().TryChangeDamage(e.Owner.Uid, CrushDamage);
stun.Paralyze(DoorStunTime);
if(e.Owner.TryGetComponent(out StunnableComponent? stun))
EntitySystem.Get<StunSystem>().Paralyze(e.Owner.Uid, TimeSpan.FromSeconds(DoorStunTime), stun);
}
// If we hit someone, open up after stun (opens right when stun ends)

View File

@@ -1,6 +1,8 @@
using System;
using Content.Server.Flash.Components;
using Content.Server.Inventory.Components;
using Content.Server.Items;
using Content.Server.Stunnable;
using Content.Server.Stunnable.Components;
using Content.Server.Weapon.Melee;
using Content.Shared.Examine;
@@ -11,6 +13,7 @@ using Content.Shared.Inventory;
using Content.Shared.Physics;
using Content.Shared.Popups;
using Content.Shared.Sound;
using Content.Shared.Stunnable;
using Robust.Server.GameObjects;
using Robust.Shared.Audio;
using Robust.Shared.GameObjects;
@@ -25,6 +28,7 @@ namespace Content.Server.Flash
{
[Dependency] private readonly IEntityLookup _entityLookup = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly StunSystem _stunSystem = default!;
public override void Initialize()
{
@@ -127,9 +131,9 @@ namespace Content.Server.Flash
flashable.Dirty();
}
if (EntityManager.TryGetComponent<StunnableComponent>(target, out var stunnableComponent))
if (EntityManager.TryGetComponent<StunnableComponent>(target, out var stunnable))
{
stunnableComponent.Slowdown(flashDuration / 1000f, slowTo, slowTo);
_stunSystem.Slowdown(target, TimeSpan.FromSeconds(flashDuration/1000f), slowTo, slowTo, stunnable);
}
if (displayPopup && user != null && target != user)

View File

@@ -129,13 +129,13 @@ namespace Content.Server.Hands.Components
RemoveHand(args.Slot);
}
bool IDisarmedAct.Disarmed(DisarmedActEventArgs eventArgs)
bool IDisarmedAct.Disarmed(DisarmedActEvent @event)
{
if (BreakPulls())
return false;
var source = eventArgs.Source;
var target = eventArgs.Target;
var source = @event.Source;
var target = @event.Target;
if (source != null)
{

View File

@@ -1,5 +1,6 @@
using System;
using System.Linq;
using Content.Server.Stunnable;
using Content.Server.Stunnable.Components;
using Content.Server.UserInterface;
using Content.Shared.ActionBlocker;
@@ -8,6 +9,7 @@ using Content.Shared.Instruments;
using Content.Shared.Interaction;
using Content.Shared.Popups;
using Content.Shared.Standing;
using Content.Shared.Stunnable;
using Content.Shared.Throwing;
using Robust.Server.GameObjects;
using Robust.Server.Player;
@@ -364,7 +366,7 @@ namespace Content.Server.Instruments
if (mob.TryGetComponent(out StunnableComponent? stun))
{
stun.Stun(1);
EntitySystem.Get<StunSystem>().Stun(mob.Uid, TimeSpan.FromSeconds(1), stun);
Clean();
}

View File

@@ -1,5 +1,7 @@
using Content.Server.Stunnable.Components;
using Content.Server.Stunnable;
using Content.Server.Stunnable.Components;
using Content.Shared.MobState.State;
using Content.Shared.Stunnable;
using Robust.Shared.GameObjects;
namespace Content.Server.MobState.States
@@ -12,7 +14,7 @@ namespace Content.Server.MobState.States
if (entity.TryGetComponent(out StunnableComponent? stun))
{
stun.CancelAll();
EntitySystem.Get<StunSystem>().Reset(entity.Uid, stun);
}
}
}

View File

@@ -1,8 +1,10 @@
using Content.Server.Alert;
using Content.Server.Stunnable;
using Content.Server.Stunnable.Components;
using Content.Shared.Alert;
using Content.Shared.MobState;
using Content.Shared.MobState.State;
using Content.Shared.Stunnable;
using Robust.Server.GameObjects;
using Robust.Shared.GameObjects;
@@ -21,7 +23,8 @@ namespace Content.Server.MobState.States
if (entity.TryGetComponent(out StunnableComponent? stun))
{
stun.CancelAll();
// TODO: Use resolves to pass ServerAlertsComponent here.
EntitySystem.Get<StunSystem>().Reset(entity.Uid, stun);
}
}
}

View File

@@ -1,3 +1,4 @@
using Robust.Shared.Analyzers;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
@@ -6,18 +7,26 @@ namespace Content.Server.Stunnable.Components
/// <summary>
/// Adds stun when it collides with an entity
/// </summary>
[RegisterComponent]
internal sealed class StunOnCollideComponent : Component
[RegisterComponent, Friend(typeof(StunOnCollideSystem))]
public sealed class StunOnCollideComponent : Component
{
// TODO: Can probably predict this.
public override string Name => "StunOnCollide";
// See stunnable for what these do
[DataField("stunAmount")]
internal int StunAmount = default;
public int StunAmount;
[DataField("knockdownAmount")]
internal int KnockdownAmount = default;
public int KnockdownAmount;
[DataField("slowdownAmount")]
internal int SlowdownAmount = default;
public int SlowdownAmount;
[DataField("walkSpeedMultiplier")]
public float WalkSpeedMultiplier = 1f;
[DataField("runSpeedMultiplier")]
public float RunSpeedMultiplier = 1f;
}
}

View File

@@ -1,86 +0,0 @@
using Content.Server.Act;
using Content.Server.Popups;
using Content.Shared.Audio;
using Content.Shared.MobState;
using Content.Shared.Popups;
using Content.Shared.Sound;
using Content.Shared.Standing;
using Content.Shared.Stunnable;
using Robust.Shared.Audio;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Player;
using Robust.Shared.Random;
using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Server.Stunnable.Components
{
[RegisterComponent]
[ComponentReference(typeof(SharedStunnableComponent))]
public class StunnableComponent : SharedStunnableComponent, IDisarmedAct
{
[DataField("stunAttemptSound")] private SoundSpecifier _stunAttemptSound = new SoundPathSpecifier("/Audio/Effects/thudswoosh.ogg");
protected override void OnKnockdown()
{
EntitySystem.Get<StandingStateSystem>().Down(Owner);
}
protected override void OnKnockdownEnd()
{
if (Owner.TryGetComponent(out IMobStateComponent? mobState) && !mobState.IsIncapacitated())
EntitySystem.Get<StandingStateSystem>().Stand(Owner);
}
public void CancelAll()
{
KnockdownTimer = null;
StunnedTimer = null;
Dirty();
}
public void ResetStuns()
{
StunnedTimer = null;
SlowdownTimer = null;
if (KnockedDown &&
Owner.TryGetComponent(out IMobStateComponent? mobState) && !mobState.IsIncapacitated())
{
EntitySystem.Get<StandingStateSystem>().Stand(Owner);
}
KnockdownTimer = null;
Dirty();
}
protected override void OnInteractHand()
{
SoundSystem.Play(Filter.Pvs(Owner), _stunAttemptSound.GetSound(), Owner, AudioHelpers.WithVariation(0.05f));
}
bool IDisarmedAct.Disarmed(DisarmedActEventArgs eventArgs)
{
if (!IoCManager.Resolve<IRobustRandom>().Prob(eventArgs.PushProbability))
return false;
Paralyze(4f);
var source = eventArgs.Source;
var target = eventArgs.Target;
if (source != null)
{
SoundSystem.Play(Filter.Pvs(source), _stunAttemptSound.GetSound(), source, AudioHelpers.WithVariation(0.025f));
if (target != null)
{
source.PopupMessageOtherClients(Loc.GetString("stunnable-component-disarm-success-others", ("source", source.Name), ("target", target.Name)));
source.PopupMessageCursor(Loc.GetString("stunnable-component-disarm-success", ("target", target.Name)));
}
}
return true;
}
}
}

View File

@@ -1,6 +1,14 @@
using System;
using Content.Server.Alert;
using Content.Server.Stunnable.Components;
using Content.Shared.Alert;
using Content.Shared.Movement.Components;
using Content.Shared.Standing;
using Content.Shared.Stunnable;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Physics.Dynamics;
namespace Content.Server.Stunnable
@@ -8,6 +16,8 @@ namespace Content.Server.Stunnable
[UsedImplicitly]
internal sealed class StunOnCollideSystem : EntitySystem
{
[Dependency] private readonly StunSystem _stunSystem = default!;
public override void Initialize()
{
base.Initialize();
@@ -16,11 +26,25 @@ namespace Content.Server.Stunnable
private void HandleCollide(EntityUid uid, StunOnCollideComponent component, StartCollideEvent args)
{
if (args.OtherFixture.Body.Owner.TryGetComponent(out StunnableComponent? stunnableComponent))
var otherUid = args.OtherFixture.Body.Owner.Uid;
if (EntityManager.TryGetComponent(otherUid, out StunnableComponent? stunnableComponent))
{
stunnableComponent.Stun(component.StunAmount);
stunnableComponent.Knockdown(component.KnockdownAmount);
stunnableComponent.Slowdown(component.SlowdownAmount);
ServerAlertsComponent? alerts = null;
StandingStateComponent? standingState = null;
AppearanceComponent? appearance = null;
MovementSpeedModifierComponent? speedModifier = null;
// Let the actual methods log errors for these.
Resolve(otherUid, ref alerts, ref standingState, ref appearance, ref speedModifier, false);
_stunSystem.Stun(otherUid, TimeSpan.FromSeconds(component.StunAmount), stunnableComponent, alerts);
_stunSystem.Knockdown(otherUid, TimeSpan.FromSeconds(component.KnockdownAmount), stunnableComponent,
alerts, standingState, appearance);
_stunSystem.Slowdown(otherUid, TimeSpan.FromSeconds(component.SlowdownAmount),
component.WalkSpeedMultiplier, component.RunSpeedMultiplier, stunnableComponent, speedModifier, alerts);
}
}
}

View File

@@ -0,0 +1,52 @@
using System;
using Content.Server.Act;
using Content.Server.Popups;
using Content.Shared.Audio;
using Content.Shared.Popups;
using Content.Shared.Stunnable;
using Robust.Shared.Audio;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Player;
using Robust.Shared.Random;
namespace Content.Server.Stunnable
{
public sealed class StunSystem : SharedStunSystem
{
[Dependency] private readonly IRobustRandom _random = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<StunnableComponent, DisarmedActEvent>(OnDisarmed);
}
private void OnDisarmed(EntityUid uid, StunnableComponent stunnable, DisarmedActEvent args)
{
if (args.Handled || !_random.Prob(args.PushProbability))
return;
Paralyze(uid, TimeSpan.FromSeconds(4f), stunnable);
var source = args.Source;
var target = args.Target;
if (source != null)
{
SoundSystem.Play(Filter.Pvs(source), stunnable.StunAttemptSound.GetSound(), source, AudioHelpers.WithVariation(0.025f));
if (target != null)
{
// TODO: Use PopupSystem
source.PopupMessageOtherClients(Loc.GetString("stunnable-component-disarm-success-others", ("source", source.Name), ("target", target.Name)));
source.PopupMessageCursor(Loc.GetString("stunnable-component-disarm-success", ("target", target.Name)));
}
}
args.Handled = true;
}
}
}

View File

@@ -10,6 +10,7 @@ using Content.Shared.Audio;
using Content.Shared.Examine;
using Content.Shared.Interaction;
using Content.Shared.Popups;
using Content.Shared.Stunnable;
using Content.Shared.Throwing;
using Robust.Server.GameObjects;
using Robust.Shared.Audio;
@@ -23,6 +24,7 @@ namespace Content.Server.Stunnable
{
public class StunbatonSystem : EntitySystem
{
[Dependency] private readonly StunSystem _stunSystem = default!;
[Dependency] private readonly IRobustRandom _robustRandom = default!;
public override void Initialize()
@@ -119,20 +121,22 @@ namespace Content.Server.Stunnable
{
if (!entity.TryGetComponent(out StunnableComponent? stunnable) || !comp.Activated) return;
// TODO: Make slowdown inflicted customizable.
SoundSystem.Play(Filter.Pvs(comp.Owner), comp.StunSound.GetSound(), comp.Owner, AudioHelpers.WithVariation(0.25f));
if (!stunnable.SlowedDown)
{
if (_robustRandom.Prob(comp.ParalyzeChanceNoSlowdown))
stunnable.Paralyze(comp.ParalyzeTime);
_stunSystem.Paralyze(entity.Uid, TimeSpan.FromSeconds(comp.ParalyzeTime), stunnable);
else
stunnable.Slowdown(comp.SlowdownTime);
_stunSystem.Slowdown(entity.Uid, TimeSpan.FromSeconds(comp.SlowdownTime), 0.5f, 0.5f, stunnable);
}
else
{
if (_robustRandom.Prob(comp.ParalyzeChanceWithSlowdown))
stunnable.Paralyze(comp.ParalyzeTime);
_stunSystem.Paralyze(entity.Uid, TimeSpan.FromSeconds(comp.ParalyzeTime), stunnable);
else
stunnable.Slowdown(comp.SlowdownTime);
_stunSystem.Slowdown(entity.Uid, TimeSpan.FromSeconds(comp.SlowdownTime), 0.5f, 0.5f, stunnable);
}

View File

@@ -3,6 +3,7 @@ using Content.Server.Atmos.EntitySystems;
using Content.Server.CombatMode;
using Content.Server.Hands.Components;
using Content.Server.Interaction.Components;
using Content.Server.Stunnable;
using Content.Server.Stunnable.Components;
using Content.Server.Weapon.Ranged.Barrels.Components;
using Content.Shared.ActionBlocker;
@@ -10,6 +11,7 @@ using Content.Shared.Damage;
using Content.Shared.Hands;
using Content.Shared.Popups;
using Content.Shared.Sound;
using Content.Shared.Stunnable;
using Content.Shared.Weapons.Ranged.Components;
using Robust.Shared.Audio;
using Robust.Shared.GameObjects;
@@ -175,7 +177,7 @@ namespace Content.Server.Weapon.Ranged
// Knock them down
if (user.TryGetComponent(out StunnableComponent? stun))
{
stun.Paralyze(3f);
EntitySystem.Get<StunSystem>().Paralyze(user.Uid, TimeSpan.FromSeconds(3f), stun);
}
// Apply salt to the wound ("Honk!")