From 876beb936963889cc776a0d5be06a36339a49754 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Thu, 6 Jul 2023 14:42:17 +1000 Subject: [PATCH] Stop NPC smashing if it fails (#17847) --- .../Systems/NPCSteeringSystem.Obstacles.cs | 9 ++++-- .../Weapons/Melee/SharedMeleeWeaponSystem.cs | 30 ++++++++++--------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/Content.Server/NPC/Systems/NPCSteeringSystem.Obstacles.cs b/Content.Server/NPC/Systems/NPCSteeringSystem.Obstacles.cs index 318cc978ea..a8a396ba42 100644 --- a/Content.Server/NPC/Systems/NPCSteeringSystem.Obstacles.cs +++ b/Content.Server/NPC/Systems/NPCSteeringSystem.Obstacles.cs @@ -124,26 +124,31 @@ public sealed partial class NPCSteeringSystem // Try smashing obstacles. else if ((component.Flags & PathFlags.Smashing) != 0x0) { - if (_melee.TryGetWeapon(uid, out var meleeUid, out var meleeWeapon) && meleeWeapon.NextAttack <= _timing.CurTime && TryComp(uid, out var combatMode)) + if (_melee.TryGetWeapon(uid, out _, out var meleeWeapon) && meleeWeapon.NextAttack <= _timing.CurTime && TryComp(uid, out var combatMode)) { _combat.SetInCombatMode(uid, true, combatMode); var destructibleQuery = GetEntityQuery(); // TODO: This is a hack around grilles and windows. _random.Shuffle(obstacleEnts); + var attackResult = false; foreach (var ent in obstacleEnts) { // TODO: Validate we can damage it if (destructibleQuery.HasComponent(ent)) { - _melee.AttemptLightAttack(uid, uid, meleeWeapon, ent); + attackResult = _melee.AttemptLightAttack(uid, uid, meleeWeapon, ent); break; } } _combat.SetInCombatMode(uid, false, combatMode); + // Blocked or the likes? + if (!attackResult) + return SteeringObstacleStatus.Failed; + if (obstacleEnts.Count == 0) return SteeringObstacleStatus.Completed; diff --git a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs index ad61c39ad3..ed158cd788 100644 --- a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs +++ b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs @@ -425,48 +425,49 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem AttemptAttack(user, weaponUid, weapon, new LightAttackEvent(null, weaponUid, coordinates), null); } - public void AttemptLightAttack(EntityUid user, EntityUid weaponUid, MeleeWeaponComponent weapon, EntityUid target) + public bool AttemptLightAttack(EntityUid user, EntityUid weaponUid, MeleeWeaponComponent weapon, EntityUid target) { if (!TryComp(target, out var targetXform)) - return; + return false; - AttemptAttack(user, weaponUid, weapon, new LightAttackEvent(target, weaponUid, targetXform.Coordinates), null); + return AttemptAttack(user, weaponUid, weapon, new LightAttackEvent(target, weaponUid, targetXform.Coordinates), null); } - public void AttemptDisarmAttack(EntityUid user, EntityUid weaponUid, MeleeWeaponComponent weapon, EntityUid target) + public bool AttemptDisarmAttack(EntityUid user, EntityUid weaponUid, MeleeWeaponComponent weapon, EntityUid target) { if (!TryComp(target, out var targetXform)) - return; + return false; - AttemptAttack(user, weaponUid, weapon, new DisarmAttackEvent(target, targetXform.Coordinates), null); + return AttemptAttack(user, weaponUid, weapon, new DisarmAttackEvent(target, targetXform.Coordinates), null); } /// /// Called when a windup is finished and an attack is tried. /// - private void AttemptAttack(EntityUid user, EntityUid weaponUid, MeleeWeaponComponent weapon, AttackEvent attack, ICommonSession? session) + /// True if attack successful + private bool AttemptAttack(EntityUid user, EntityUid weaponUid, MeleeWeaponComponent weapon, AttackEvent attack, ICommonSession? session) { var curTime = Timing.CurTime; if (weapon.NextAttack > curTime) - return; + return false; if (!CombatMode.IsInCombatMode(user)) - return; + return false; switch (attack) { case LightAttackEvent light: if (!Blocker.CanAttack(user, light.Target)) - return; + return false; break; case DisarmAttackEvent disarm: if (!Blocker.CanAttack(user, disarm.Target)) - return; + return false; break; default: if (!Blocker.CanAttack(user)) - return; + return false; break; } @@ -497,7 +498,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem PopupSystem.PopupClient(ev.Message, weaponUid, user); } - return; + return false; } // Attack confirmed @@ -513,7 +514,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem break; case DisarmAttackEvent disarm: if (!DoDisarm(user, disarm, weaponUid, weapon, session)) - return; + return false; animation = weapon.ClickAnimation; break; @@ -529,6 +530,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem } weapon.Attacking = true; + return true; } ///