Fire MeleeHitEvent on misses. (#12867)
* Fire MeleeHitEvent when there are no targets. * Prevent certain weapons from activating if they had no hit entities on hit. * Prevent miss events from firing when target is yourself or was deleted. * Use .Value as Target is already known not to be null. * uid changes --------- Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
@@ -220,9 +220,9 @@ public sealed partial class MeleeWeaponSystem : SharedMeleeWeaponSystem
|
||||
RaiseLocalEvent(new DamageEffectEvent(Color.Red, targets));
|
||||
}
|
||||
|
||||
protected override bool DoDisarm(EntityUid user, DisarmAttackEvent ev, MeleeWeaponComponent component, ICommonSession? session)
|
||||
protected override bool DoDisarm(EntityUid user, DisarmAttackEvent ev, EntityUid meleeUid, MeleeWeaponComponent component, ICommonSession? session)
|
||||
{
|
||||
if (!base.DoDisarm(user, ev, component, session))
|
||||
if (!base.DoDisarm(user, ev, meleeUid, component, session))
|
||||
return false;
|
||||
|
||||
if (!TryComp<CombatModeComponent>(user, out var combatMode) ||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Linq;
|
||||
using Content.Server.Flash.Components;
|
||||
using Content.Server.Light.EntitySystems;
|
||||
using Content.Server.Stunnable;
|
||||
@@ -43,11 +44,12 @@ namespace Content.Server.Flash
|
||||
|
||||
private void OnFlashMeleeHit(EntityUid uid, FlashComponent comp, MeleeHitEvent args)
|
||||
{
|
||||
if (!args.IsHit)
|
||||
return;
|
||||
|
||||
if (!UseFlash(comp, args.User))
|
||||
if (!args.IsHit ||
|
||||
!args.HitEntities.Any() ||
|
||||
!UseFlash(comp, args.User))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
args.Handled = true;
|
||||
foreach (var e in args.HitEntities)
|
||||
|
||||
@@ -95,17 +95,19 @@ public sealed partial class NPCCombatSystem
|
||||
|
||||
foreach (var (comp, _) in EntityQuery<NPCMeleeCombatComponent, ActiveNPCComponent>())
|
||||
{
|
||||
if (!combatQuery.TryGetComponent(comp.Owner, out var combat) || !combat.IsInCombatMode)
|
||||
var uid = comp.Owner;
|
||||
|
||||
if (!combatQuery.TryGetComponent(uid, out var combat) || !combat.IsInCombatMode)
|
||||
{
|
||||
RemComp<NPCMeleeCombatComponent>(comp.Owner);
|
||||
RemComp<NPCMeleeCombatComponent>(uid);
|
||||
continue;
|
||||
}
|
||||
|
||||
Attack(comp, curTime, physicsQuery, xformQuery);
|
||||
Attack(uid, comp, curTime, physicsQuery, xformQuery);
|
||||
}
|
||||
}
|
||||
|
||||
private void Attack(NPCMeleeCombatComponent component, TimeSpan curTime, EntityQuery<PhysicsComponent> physicsQuery, EntityQuery<TransformComponent> xformQuery)
|
||||
private void Attack(EntityUid uid, NPCMeleeCombatComponent component, TimeSpan curTime, EntityQuery<PhysicsComponent> physicsQuery, EntityQuery<TransformComponent> xformQuery)
|
||||
{
|
||||
component.Status = CombatStatus.Normal;
|
||||
|
||||
@@ -115,7 +117,7 @@ public sealed partial class NPCCombatSystem
|
||||
return;
|
||||
}
|
||||
|
||||
if (!xformQuery.TryGetComponent(component.Owner, out var xform) ||
|
||||
if (!xformQuery.TryGetComponent(uid, out var xform) ||
|
||||
!xformQuery.TryGetComponent(component.Target, out var targetXform))
|
||||
{
|
||||
component.Status = CombatStatus.TargetUnreachable;
|
||||
@@ -134,7 +136,7 @@ public sealed partial class NPCCombatSystem
|
||||
return;
|
||||
}
|
||||
|
||||
if (TryComp<NPCSteeringComponent>(component.Owner, out var steering) &&
|
||||
if (TryComp<NPCSteeringComponent>(uid, out var steering) &&
|
||||
steering.Status == SteeringStatus.NoPath)
|
||||
{
|
||||
component.Status = CombatStatus.TargetUnreachable;
|
||||
@@ -147,11 +149,11 @@ public sealed partial class NPCCombatSystem
|
||||
return;
|
||||
}
|
||||
|
||||
steering = EnsureComp<NPCSteeringComponent>(component.Owner);
|
||||
steering = EnsureComp<NPCSteeringComponent>(uid);
|
||||
steering.Range = MathF.Max(0.2f, weapon.Range - 0.4f);
|
||||
|
||||
// Gets unregistered on component shutdown.
|
||||
_steering.TryRegister(component.Owner, new EntityCoordinates(component.Target, Vector2.Zero), steering);
|
||||
_steering.TryRegister(uid, new EntityCoordinates(component.Target, Vector2.Zero), steering);
|
||||
|
||||
if (weapon.NextAttack > curTime || !Enabled)
|
||||
return;
|
||||
@@ -160,11 +162,11 @@ public sealed partial class NPCCombatSystem
|
||||
physicsQuery.TryGetComponent(component.Target, out var targetPhysics) &&
|
||||
targetPhysics.LinearVelocity.LengthSquared != 0f)
|
||||
{
|
||||
_melee.AttemptLightAttackMiss(component.Owner, weapon, targetXform.Coordinates.Offset(_random.NextVector2(0.5f)));
|
||||
_melee.AttemptLightAttackMiss(uid, component.Weapon, weapon, targetXform.Coordinates.Offset(_random.NextVector2(0.5f)));
|
||||
}
|
||||
else
|
||||
{
|
||||
_melee.AttemptLightAttack(component.Owner, weapon, component.Target);
|
||||
_melee.AttemptLightAttack(uid, component.Weapon, weapon, component.Target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ public sealed partial class NPCSteeringSystem
|
||||
// TODO: Validate we can damage it
|
||||
if (destructibleQuery.HasComponent(ent))
|
||||
{
|
||||
_melee.AttemptLightAttack(component.Owner, meleeWeapon, ent);
|
||||
_melee.AttemptLightAttack(component.Owner, component.Owner, meleeWeapon, ent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,9 +96,9 @@ public sealed class MeleeWeaponSystem : SharedMeleeWeaponSystem
|
||||
PopupSystem.PopupEntity(message, uid.Value, Filter.PvsExcept(user.Value, entityManager: EntityManager), true);
|
||||
}
|
||||
|
||||
protected override bool DoDisarm(EntityUid user, DisarmAttackEvent ev, MeleeWeaponComponent component, ICommonSession? session)
|
||||
protected override bool DoDisarm(EntityUid user, DisarmAttackEvent ev, EntityUid meleeUid, MeleeWeaponComponent component, ICommonSession? session)
|
||||
{
|
||||
if (!base.DoDisarm(user, ev, component, session))
|
||||
if (!base.DoDisarm(user, ev, meleeUid, component, session))
|
||||
return false;
|
||||
|
||||
if (!TryComp<CombatModeComponent>(user, out var combatMode) ||
|
||||
@@ -228,11 +228,12 @@ public sealed class MeleeWeaponSystem : SharedMeleeWeaponSystem
|
||||
|
||||
private void OnChemicalInjectorHit(EntityUid owner, MeleeChemicalInjectorComponent comp, MeleeHitEvent args)
|
||||
{
|
||||
if (!args.IsHit)
|
||||
return;
|
||||
|
||||
if (!_solutions.TryGetSolution(owner, comp.Solution, out var solutionContainer))
|
||||
if (!args.IsHit ||
|
||||
!args.HitEntities.Any() ||
|
||||
!_solutions.TryGetSolution(owner, comp.Solution, out var solutionContainer))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var hitBloodstreams = new List<BloodstreamComponent>();
|
||||
var bloodQuery = GetEntityQuery<BloodstreamComponent>();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Linq;
|
||||
using Content.Shared.Administration.Logs;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.CombatMode;
|
||||
@@ -139,10 +140,12 @@ public sealed class StaminaSystem : EntitySystem
|
||||
|
||||
private void OnHit(EntityUid uid, StaminaDamageOnHitComponent component, MeleeHitEvent args)
|
||||
{
|
||||
if (!args.IsHit)
|
||||
if (!args.IsHit ||
|
||||
!args.HitEntities.Any() ||
|
||||
component.Damage <= 0f)
|
||||
{
|
||||
return;
|
||||
|
||||
if (component.Damage <= 0f) return;
|
||||
}
|
||||
|
||||
var ev = new StaminaDamageOnHitAttemptEvent();
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
|
||||
@@ -12,7 +12,7 @@ public sealed class MeleeHitEvent : HandledEntityEventArgs
|
||||
/// <summary>
|
||||
/// The base amount of damage dealt by the melee hit.
|
||||
/// </summary>
|
||||
public readonly DamageSpecifier BaseDamage = new();
|
||||
public readonly DamageSpecifier BaseDamage;
|
||||
|
||||
/// <summary>
|
||||
/// Modifier sets to apply to the hit event when it's all said and done.
|
||||
@@ -31,18 +31,18 @@ public sealed class MeleeHitEvent : HandledEntityEventArgs
|
||||
/// <summary>
|
||||
/// A list containing every hit entity. Can be zero.
|
||||
/// </summary>
|
||||
public IEnumerable<EntityUid> HitEntities { get; }
|
||||
public IReadOnlyList<EntityUid> HitEntities;
|
||||
|
||||
/// <summary>
|
||||
/// Used to define a new hit sound in case you want to override the default GenericHit.
|
||||
/// Also gets a pitch modifier added to it.
|
||||
/// </summary>
|
||||
public SoundSpecifier? HitSoundOverride {get; set;}
|
||||
public SoundSpecifier? HitSoundOverride;
|
||||
|
||||
/// <summary>
|
||||
/// The user who attacked with the melee weapon.
|
||||
/// </summary>
|
||||
public EntityUid User { get; }
|
||||
public readonly EntityUid User;
|
||||
|
||||
/// <summary>
|
||||
/// Check if this is true before attempting to do something during a melee attack other than changing/adding bonus damage. <br/>
|
||||
|
||||
@@ -40,6 +40,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
[Dependency] protected readonly SharedInteractionSystem Interaction = default!;
|
||||
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
||||
[Dependency] protected readonly SharedPopupSystem PopupSystem = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||
[Dependency] private readonly StaminaSystem _stamina = default!;
|
||||
|
||||
protected ISawmill Sawmill = default!;
|
||||
@@ -148,7 +149,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
if (weapon?.Owner != msg.Weapon)
|
||||
return;
|
||||
|
||||
AttemptAttack(args.SenderSession.AttachedEntity!.Value, weapon, msg, args.SenderSession);
|
||||
AttemptAttack(args.SenderSession.AttachedEntity!.Value, msg.Weapon, weapon, msg, args.SenderSession);
|
||||
}
|
||||
|
||||
private void OnStopHeavyAttack(StopHeavyAttackEvent msg, EntitySessionEventArgs args)
|
||||
@@ -186,7 +187,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
if (userWeapon != weapon)
|
||||
return;
|
||||
|
||||
AttemptAttack(args.SenderSession.AttachedEntity.Value, weapon, msg, args.SenderSession);
|
||||
AttemptAttack(args.SenderSession.AttachedEntity.Value, msg.Weapon, weapon, msg, args.SenderSession);
|
||||
}
|
||||
|
||||
private void OnDisarmAttack(DisarmAttackEvent msg, EntitySessionEventArgs args)
|
||||
@@ -201,7 +202,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
if (userWeapon == null)
|
||||
return;
|
||||
|
||||
AttemptAttack(args.SenderSession.AttachedEntity.Value, userWeapon, msg, args.SenderSession);
|
||||
AttemptAttack(args.SenderSession.AttachedEntity.Value, userWeapon.Owner, userWeapon, msg, args.SenderSession);
|
||||
}
|
||||
|
||||
private void OnGetState(EntityUid uid, MeleeWeaponComponent component, ref ComponentGetState args)
|
||||
@@ -264,31 +265,31 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
return null;
|
||||
}
|
||||
|
||||
public void AttemptLightAttackMiss(EntityUid user, MeleeWeaponComponent weapon, EntityCoordinates coordinates)
|
||||
public void AttemptLightAttackMiss(EntityUid user, EntityUid weaponUid, MeleeWeaponComponent weapon, EntityCoordinates coordinates)
|
||||
{
|
||||
AttemptAttack(user, weapon, new LightAttackEvent(null, weapon.Owner, coordinates), null);
|
||||
AttemptAttack(user, weaponUid, weapon, new LightAttackEvent(null, weaponUid, coordinates), null);
|
||||
}
|
||||
|
||||
public void AttemptLightAttack(EntityUid user, MeleeWeaponComponent weapon, EntityUid target)
|
||||
public void AttemptLightAttack(EntityUid user, EntityUid weaponUid, MeleeWeaponComponent weapon, EntityUid target)
|
||||
{
|
||||
if (!TryComp<TransformComponent>(target, out var targetXform))
|
||||
return;
|
||||
|
||||
AttemptAttack(user, weapon, new LightAttackEvent(target, weapon.Owner, targetXform.Coordinates), null);
|
||||
AttemptAttack(user, weaponUid, weapon, new LightAttackEvent(target, weaponUid, targetXform.Coordinates), null);
|
||||
}
|
||||
|
||||
public void AttemptDisarmAttack(EntityUid user, MeleeWeaponComponent weapon, EntityUid target)
|
||||
public void AttemptDisarmAttack(EntityUid user, EntityUid weaponUid, MeleeWeaponComponent weapon, EntityUid target)
|
||||
{
|
||||
if (!TryComp<TransformComponent>(target, out var targetXform))
|
||||
return;
|
||||
|
||||
AttemptAttack(user, weapon, new DisarmAttackEvent(target, targetXform.Coordinates), null);
|
||||
AttemptAttack(user, weaponUid, weapon, new DisarmAttackEvent(target, targetXform.Coordinates), null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when a windup is finished and an attack is tried.
|
||||
/// </summary>
|
||||
private void AttemptAttack(EntityUid user, MeleeWeaponComponent weapon, AttackEvent attack, ICommonSession? session)
|
||||
private void AttemptAttack(EntityUid user, EntityUid weaponUid, MeleeWeaponComponent weapon, AttackEvent attack, ICommonSession? session)
|
||||
{
|
||||
var curTime = Timing.CurTime;
|
||||
|
||||
@@ -327,17 +328,17 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
switch (attack)
|
||||
{
|
||||
case LightAttackEvent light:
|
||||
DoLightAttack(user, light, weapon, session);
|
||||
DoLightAttack(user, light, weaponUid, weapon, session);
|
||||
animation = weapon.ClickAnimation;
|
||||
break;
|
||||
case DisarmAttackEvent disarm:
|
||||
if (!DoDisarm(user, disarm, weapon, session))
|
||||
if (!DoDisarm(user, disarm, weaponUid, weapon, session))
|
||||
return;
|
||||
|
||||
animation = weapon.ClickAnimation;
|
||||
break;
|
||||
case HeavyAttackEvent heavy:
|
||||
DoHeavyAttack(user, heavy, weapon, session);
|
||||
DoHeavyAttack(user, heavy, weaponUid, weapon, session);
|
||||
animation = weapon.WideAnimation;
|
||||
break;
|
||||
default:
|
||||
@@ -385,34 +386,34 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
|
||||
protected abstract bool InRange(EntityUid user, EntityUid target, float range, ICommonSession? session);
|
||||
|
||||
protected virtual void DoLightAttack(EntityUid user, LightAttackEvent ev, MeleeWeaponComponent component, ICommonSession? session)
|
||||
protected virtual void DoLightAttack(EntityUid user, LightAttackEvent ev, EntityUid meleeUid, MeleeWeaponComponent component, ICommonSession? session)
|
||||
{
|
||||
// Can't attack yourself
|
||||
// Not in LOS.
|
||||
if (user == ev.Target ||
|
||||
ev.Target == null ||
|
||||
Deleted(ev.Target) ||
|
||||
// For consistency with wide attacks stuff needs damageable.
|
||||
!HasComp<DamageableComponent>(ev.Target) ||
|
||||
!TryComp<TransformComponent>(ev.Target, out var targetXform))
|
||||
{
|
||||
Audio.PlayPredicted(component.SwingSound, component.Owner, user);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!InRange(user, ev.Target.Value, component.Range, session))
|
||||
{
|
||||
Audio.PlayPredicted(component.SwingSound, component.Owner, user);
|
||||
return;
|
||||
}
|
||||
|
||||
var damage = component.Damage * GetModifier(component, true);
|
||||
|
||||
// Can't attack yourself
|
||||
// For consistency with wide attacks stuff needs damageable.
|
||||
if (user == ev.Target ||
|
||||
Deleted(ev.Target) ||
|
||||
!HasComp<DamageableComponent>(ev.Target) ||
|
||||
!TryComp<TransformComponent>(ev.Target, out var targetXform) ||
|
||||
// Not in LOS.
|
||||
!InRange(user, ev.Target.Value, component.Range, session))
|
||||
{
|
||||
// Leave IsHit set to true, because the only time it's set to false
|
||||
// is when a melee weapon is examined. Misses are inferred from an
|
||||
// empty HitEntities.
|
||||
// TODO: This needs fixing
|
||||
var missEvent = new MeleeHitEvent(new List<EntityUid>(), user, damage);
|
||||
RaiseLocalEvent(meleeUid, missEvent);
|
||||
Audio.PlayPredicted(component.SwingSound, meleeUid, user);
|
||||
return;
|
||||
}
|
||||
|
||||
// Sawmill.Debug($"Melee damage is {damage.Total} out of {component.Damage.Total}");
|
||||
|
||||
// Raise event before doing damage so we can cancel damage if the event is handled
|
||||
var hitEvent = new MeleeHitEvent(new List<EntityUid> { ev.Target.Value }, user, damage);
|
||||
RaiseLocalEvent(component.Owner, hitEvent);
|
||||
RaiseLocalEvent(meleeUid, hitEvent);
|
||||
|
||||
if (hitEvent.Handled)
|
||||
return;
|
||||
@@ -430,7 +431,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
Interaction.DoContactInteraction(user, ev.Target);
|
||||
|
||||
// For stuff that cares about it being attacked.
|
||||
RaiseLocalEvent(ev.Target.Value, new AttackedEvent(component.Owner, user, targetXform.Coordinates));
|
||||
RaiseLocalEvent(ev.Target.Value, new AttackedEvent(meleeUid, user, targetXform.Coordinates));
|
||||
|
||||
var modifiedDamage = DamageSpecifier.ApplyModifierSets(damage + hitEvent.BonusDamage, hitEvent.ModifiersList);
|
||||
var damageResult = Damageable.TryChangeDamage(ev.Target, modifiedDamage, origin:user);
|
||||
@@ -443,7 +444,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
_stamina.TakeStaminaDamage(ev.Target.Value, (bluntDamage * component.BluntStaminaDamageFactor).Float(), source:user, with:(component.Owner == user ? null : component.Owner));
|
||||
}
|
||||
|
||||
if (component.Owner == user)
|
||||
if (meleeUid == user)
|
||||
{
|
||||
AdminLogger.Add(LogType.MeleeHit,
|
||||
$"{ToPrettyString(user):user} melee attacked {ToPrettyString(ev.Target.Value):target} using their hands and dealt {damageResult.Total:damage} damage");
|
||||
@@ -460,11 +461,11 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
{
|
||||
if (hitEvent.HitSoundOverride != null)
|
||||
{
|
||||
Audio.PlayPredicted(hitEvent.HitSoundOverride, component.Owner, user);
|
||||
Audio.PlayPredicted(hitEvent.HitSoundOverride, meleeUid, user);
|
||||
}
|
||||
else
|
||||
{
|
||||
Audio.PlayPredicted(component.NoDamageSound, component.Owner, user);
|
||||
Audio.PlayPredicted(component.NoDamageSound, meleeUid, user);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -476,7 +477,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
|
||||
protected abstract void DoDamageEffect(List<EntityUid> targets, EntityUid? user, TransformComponent targetXform);
|
||||
|
||||
protected virtual void DoHeavyAttack(EntityUid user, HeavyAttackEvent ev, MeleeWeaponComponent component, ICommonSession? session)
|
||||
protected virtual void DoHeavyAttack(EntityUid user, HeavyAttackEvent ev, EntityUid meleeUid, MeleeWeaponComponent component, ICommonSession? session)
|
||||
{
|
||||
// TODO: This is copy-paste as fuck with DoPreciseAttack
|
||||
if (!TryComp<TransformComponent>(user, out var userXform))
|
||||
@@ -491,16 +492,21 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
return;
|
||||
}
|
||||
|
||||
var userPos = userXform.WorldPosition;
|
||||
var userPos = _transform.GetWorldPosition(userXform);
|
||||
var direction = targetMap.Position - userPos;
|
||||
var distance = Math.Min(component.Range, direction.Length);
|
||||
|
||||
var damage = component.Damage * GetModifier(component, false);
|
||||
|
||||
// This should really be improved. GetEntitiesInArc uses pos instead of bounding boxes.
|
||||
var entities = ArcRayCast(userPos, direction.ToWorldAngle(), component.Angle, distance, userXform.MapID, user);
|
||||
|
||||
if (entities.Count == 0)
|
||||
{
|
||||
Audio.PlayPredicted(component.SwingSound, component.Owner, user);
|
||||
var missEvent = new MeleeHitEvent(new List<EntityUid>(), user, damage);
|
||||
RaiseLocalEvent(meleeUid, missEvent);
|
||||
|
||||
Audio.PlayPredicted(component.SwingSound, meleeUid, user);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -516,12 +522,11 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
targets.Add(entity);
|
||||
}
|
||||
|
||||
var damage = component.Damage * GetModifier(component, false);
|
||||
// Sawmill.Debug($"Melee damage is {damage.Total} out of {component.Damage.Total}");
|
||||
|
||||
// Raise event before doing damage so we can cancel damage if the event is handled
|
||||
var hitEvent = new MeleeHitEvent(targets, user, damage);
|
||||
RaiseLocalEvent(component.Owner, hitEvent);
|
||||
RaiseLocalEvent(meleeUid, hitEvent);
|
||||
|
||||
if (hitEvent.Handled)
|
||||
return;
|
||||
@@ -537,7 +542,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
// somewhat messy scuffle. See also, light attacks.
|
||||
Interaction.DoContactInteraction(user, target);
|
||||
|
||||
RaiseLocalEvent(target, new AttackedEvent(component.Owner, user, Transform(target).Coordinates));
|
||||
RaiseLocalEvent(target, new AttackedEvent(meleeUid, user, Transform(target).Coordinates));
|
||||
}
|
||||
|
||||
var modifiedDamage = DamageSpecifier.ApplyModifierSets(damage + hitEvent.BonusDamage, hitEvent.ModifiersList);
|
||||
@@ -545,7 +550,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
|
||||
foreach (var entity in targets)
|
||||
{
|
||||
RaiseLocalEvent(entity, new AttackedEvent(component.Owner, user, ev.Coordinates));
|
||||
RaiseLocalEvent(entity, new AttackedEvent(meleeUid, user, ev.Coordinates));
|
||||
|
||||
var damageResult = Damageable.TryChangeDamage(entity, modifiedDamage, origin:user);
|
||||
|
||||
@@ -553,7 +558,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
{
|
||||
appliedDamage += damageResult;
|
||||
|
||||
if (component.Owner == user)
|
||||
if (meleeUid == user)
|
||||
{
|
||||
AdminLogger.Add(LogType.MeleeHit,
|
||||
$"{ToPrettyString(user):user} melee attacked {ToPrettyString(entity):target} using their hands and dealt {damageResult.Total:damage} damage");
|
||||
@@ -577,11 +582,11 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
{
|
||||
if (hitEvent.HitSoundOverride != null)
|
||||
{
|
||||
Audio.PlayPredicted(hitEvent.HitSoundOverride, component.Owner, user);
|
||||
Audio.PlayPredicted(hitEvent.HitSoundOverride, meleeUid, user);
|
||||
}
|
||||
else
|
||||
{
|
||||
Audio.PlayPredicted(component.NoDamageSound, component.Owner, user);
|
||||
Audio.PlayPredicted(component.NoDamageSound, meleeUid, user);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -703,14 +708,14 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
return highestDamageType;
|
||||
}
|
||||
|
||||
protected virtual bool DoDisarm(EntityUid user, DisarmAttackEvent ev, MeleeWeaponComponent component, ICommonSession? session)
|
||||
protected virtual bool DoDisarm(EntityUid user, DisarmAttackEvent ev, EntityUid meleeUid, MeleeWeaponComponent component, ICommonSession? session)
|
||||
{
|
||||
if (Deleted(ev.Target) ||
|
||||
user == ev.Target)
|
||||
return false;
|
||||
|
||||
// Play a sound to give instant feedback; same with playing the animations
|
||||
Audio.PlayPredicted(component.SwingSound, component.Owner, user);
|
||||
Audio.PlayPredicted(component.SwingSound, meleeUid, user);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user