|
|
|
|
@@ -5,15 +5,19 @@ using Content.Shared.CombatMode;
|
|
|
|
|
using Content.Shared.Damage.Components;
|
|
|
|
|
using Content.Shared.Damage.Events;
|
|
|
|
|
using Content.Shared.Database;
|
|
|
|
|
using Content.Shared.Effects;
|
|
|
|
|
using Content.Shared.IdentityManagement;
|
|
|
|
|
using Content.Shared.Popups;
|
|
|
|
|
using Content.Shared.Projectiles;
|
|
|
|
|
using Content.Shared.Rejuvenate;
|
|
|
|
|
using Content.Shared.Rounding;
|
|
|
|
|
using Content.Shared.Stunnable;
|
|
|
|
|
using Content.Shared.Throwing;
|
|
|
|
|
using Content.Shared.Weapons.Melee.Events;
|
|
|
|
|
using JetBrains.Annotations;
|
|
|
|
|
using Robust.Shared.Audio;
|
|
|
|
|
using Robust.Shared.GameStates;
|
|
|
|
|
using Robust.Shared.Network;
|
|
|
|
|
using Robust.Shared.Player;
|
|
|
|
|
using Robust.Shared.Random;
|
|
|
|
|
using Robust.Shared.Serialization;
|
|
|
|
|
@@ -30,6 +34,8 @@ public sealed partial class StaminaSystem : EntitySystem
|
|
|
|
|
[Dependency] private readonly MetaDataSystem _metadata = default!;
|
|
|
|
|
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
|
|
|
|
[Dependency] private readonly SharedStunSystem _stunSystem = default!;
|
|
|
|
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
|
|
|
|
[Dependency] private readonly INetManager _net = default!;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// How much of a buffer is there between the stun duration and when stuns can be re-applied.
|
|
|
|
|
@@ -50,8 +56,9 @@ public sealed partial class StaminaSystem : EntitySystem
|
|
|
|
|
SubscribeLocalEvent<StaminaComponent, DisarmedEvent>(OnDisarmed);
|
|
|
|
|
SubscribeLocalEvent<StaminaComponent, RejuvenateEvent>(OnRejuvenate);
|
|
|
|
|
|
|
|
|
|
SubscribeLocalEvent<StaminaDamageOnCollideComponent, ProjectileHitEvent>(OnCollide);
|
|
|
|
|
SubscribeLocalEvent<StaminaDamageOnHitComponent, MeleeHitEvent>(OnHit);
|
|
|
|
|
SubscribeLocalEvent<StaminaDamageOnCollideComponent, ProjectileHitEvent>(OnProjectileHit);
|
|
|
|
|
SubscribeLocalEvent<StaminaDamageOnCollideComponent, ThrowDoHitEvent>(OnThrowHit);
|
|
|
|
|
SubscribeLocalEvent<StaminaDamageOnHitComponent, MeleeHitEvent>(OnMeleeHit);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnStamUnpaused(EntityUid uid, StaminaComponent component, ref EntityUnpausedEvent args)
|
|
|
|
|
@@ -159,7 +166,7 @@ public sealed partial class StaminaSystem : EntitySystem
|
|
|
|
|
args.Handled = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnHit(EntityUid uid, StaminaDamageOnHitComponent component, MeleeHitEvent args)
|
|
|
|
|
private void OnMeleeHit(EntityUid uid, StaminaDamageOnHitComponent component, MeleeHitEvent args)
|
|
|
|
|
{
|
|
|
|
|
if (!args.IsHit ||
|
|
|
|
|
!args.HitEntities.Any() ||
|
|
|
|
|
@@ -170,11 +177,9 @@ public sealed partial class StaminaSystem : EntitySystem
|
|
|
|
|
|
|
|
|
|
var ev = new StaminaDamageOnHitAttemptEvent();
|
|
|
|
|
RaiseLocalEvent(uid, ref ev);
|
|
|
|
|
|
|
|
|
|
if (ev.Cancelled)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
args.HitSoundOverride = ev.HitSoundOverride;
|
|
|
|
|
var stamQuery = GetEntityQuery<StaminaComponent>();
|
|
|
|
|
var toHit = new List<(EntityUid Entity, StaminaComponent Component)>();
|
|
|
|
|
|
|
|
|
|
@@ -201,18 +206,28 @@ public sealed partial class StaminaSystem : EntitySystem
|
|
|
|
|
|
|
|
|
|
foreach (var (ent, comp) in toHit)
|
|
|
|
|
{
|
|
|
|
|
var oldDamage = comp.StaminaDamage;
|
|
|
|
|
TakeStaminaDamage(ent, damage / toHit.Count, comp, source: args.User, with: args.Weapon);
|
|
|
|
|
if (comp.StaminaDamage.Equals(oldDamage))
|
|
|
|
|
{
|
|
|
|
|
_popup.PopupClient(Loc.GetString("stamina-resist"), ent, args.User);
|
|
|
|
|
}
|
|
|
|
|
TakeStaminaDamage(ent, damage / toHit.Count, comp, source: args.User, with: args.Weapon, sound: component.Sound);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnCollide(EntityUid uid, StaminaDamageOnCollideComponent component, ref ProjectileHitEvent args)
|
|
|
|
|
private void OnProjectileHit(EntityUid uid, StaminaDamageOnCollideComponent component, ref ProjectileHitEvent args)
|
|
|
|
|
{
|
|
|
|
|
TakeStaminaDamage(args.Target, component.Damage, source: uid);
|
|
|
|
|
OnCollide(uid, component, args.Target);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnThrowHit(EntityUid uid, StaminaDamageOnCollideComponent component, ThrowDoHitEvent args)
|
|
|
|
|
{
|
|
|
|
|
OnCollide(uid, component, args.Target);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnCollide(EntityUid uid, StaminaDamageOnCollideComponent component, EntityUid target)
|
|
|
|
|
{
|
|
|
|
|
var ev = new StaminaDamageOnHitAttemptEvent();
|
|
|
|
|
RaiseLocalEvent(uid, ref ev);
|
|
|
|
|
if (ev.Cancelled)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
TakeStaminaDamage(target, component.Damage, source: uid, sound: component.Sound);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SetStaminaAlert(EntityUid uid, StaminaComponent? component = null)
|
|
|
|
|
@@ -240,11 +255,12 @@ public sealed partial class StaminaSystem : EntitySystem
|
|
|
|
|
if (oldStam + value > component.CritThreshold || component.Critical)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
TakeStaminaDamage(uid, value, component, source, with);
|
|
|
|
|
TakeStaminaDamage(uid, value, component, source, with, visual: false);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void TakeStaminaDamage(EntityUid uid, float value, StaminaComponent? component = null, EntityUid? source = null, EntityUid? with = null)
|
|
|
|
|
public void TakeStaminaDamage(EntityUid uid, float value, StaminaComponent? component = null,
|
|
|
|
|
EntityUid? source = null, EntityUid? with = null, bool visual = true, SoundSpecifier? sound = null)
|
|
|
|
|
{
|
|
|
|
|
if (!Resolve(uid, ref component, false))
|
|
|
|
|
return;
|
|
|
|
|
@@ -309,6 +325,16 @@ public sealed partial class StaminaSystem : EntitySystem
|
|
|
|
|
{
|
|
|
|
|
_adminLogger.Add(LogType.Stamina, $"{ToPrettyString(uid):target} took {value} stamina damage");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (visual)
|
|
|
|
|
{
|
|
|
|
|
RaiseNetworkEvent(new ColorFlashEffectEvent(Color.Aqua, new List<EntityUid>() { uid }));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_net.IsServer)
|
|
|
|
|
{
|
|
|
|
|
_audio.PlayPvs(sound, uid);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void Update(float frameTime)
|
|
|
|
|
|