Stop NPC smashing if it fails (#17847)

This commit is contained in:
metalgearsloth
2023-07-06 14:42:17 +10:00
committed by GitHub
parent 02db31fdc6
commit 876beb9369
2 changed files with 23 additions and 16 deletions

View File

@@ -124,26 +124,31 @@ public sealed partial class NPCSteeringSystem
// Try smashing obstacles. // Try smashing obstacles.
else if ((component.Flags & PathFlags.Smashing) != 0x0) else if ((component.Flags & PathFlags.Smashing) != 0x0)
{ {
if (_melee.TryGetWeapon(uid, out var meleeUid, out var meleeWeapon) && meleeWeapon.NextAttack <= _timing.CurTime && TryComp<CombatModeComponent>(uid, out var combatMode)) if (_melee.TryGetWeapon(uid, out _, out var meleeWeapon) && meleeWeapon.NextAttack <= _timing.CurTime && TryComp<CombatModeComponent>(uid, out var combatMode))
{ {
_combat.SetInCombatMode(uid, true, combatMode); _combat.SetInCombatMode(uid, true, combatMode);
var destructibleQuery = GetEntityQuery<DestructibleComponent>(); var destructibleQuery = GetEntityQuery<DestructibleComponent>();
// TODO: This is a hack around grilles and windows. // TODO: This is a hack around grilles and windows.
_random.Shuffle(obstacleEnts); _random.Shuffle(obstacleEnts);
var attackResult = false;
foreach (var ent in obstacleEnts) foreach (var ent in obstacleEnts)
{ {
// TODO: Validate we can damage it // TODO: Validate we can damage it
if (destructibleQuery.HasComponent(ent)) if (destructibleQuery.HasComponent(ent))
{ {
_melee.AttemptLightAttack(uid, uid, meleeWeapon, ent); attackResult = _melee.AttemptLightAttack(uid, uid, meleeWeapon, ent);
break; break;
} }
} }
_combat.SetInCombatMode(uid, false, combatMode); _combat.SetInCombatMode(uid, false, combatMode);
// Blocked or the likes?
if (!attackResult)
return SteeringObstacleStatus.Failed;
if (obstacleEnts.Count == 0) if (obstacleEnts.Count == 0)
return SteeringObstacleStatus.Completed; return SteeringObstacleStatus.Completed;

View File

@@ -425,48 +425,49 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
AttemptAttack(user, weaponUid, weapon, new LightAttackEvent(null, weaponUid, coordinates), null); 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<TransformComponent>(target, out var targetXform)) if (!TryComp<TransformComponent>(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<TransformComponent>(target, out var targetXform)) if (!TryComp<TransformComponent>(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);
} }
/// <summary> /// <summary>
/// Called when a windup is finished and an attack is tried. /// Called when a windup is finished and an attack is tried.
/// </summary> /// </summary>
private void AttemptAttack(EntityUid user, EntityUid weaponUid, MeleeWeaponComponent weapon, AttackEvent attack, ICommonSession? session) /// <returns>True if attack successful</returns>
private bool AttemptAttack(EntityUid user, EntityUid weaponUid, MeleeWeaponComponent weapon, AttackEvent attack, ICommonSession? session)
{ {
var curTime = Timing.CurTime; var curTime = Timing.CurTime;
if (weapon.NextAttack > curTime) if (weapon.NextAttack > curTime)
return; return false;
if (!CombatMode.IsInCombatMode(user)) if (!CombatMode.IsInCombatMode(user))
return; return false;
switch (attack) switch (attack)
{ {
case LightAttackEvent light: case LightAttackEvent light:
if (!Blocker.CanAttack(user, light.Target)) if (!Blocker.CanAttack(user, light.Target))
return; return false;
break; break;
case DisarmAttackEvent disarm: case DisarmAttackEvent disarm:
if (!Blocker.CanAttack(user, disarm.Target)) if (!Blocker.CanAttack(user, disarm.Target))
return; return false;
break; break;
default: default:
if (!Blocker.CanAttack(user)) if (!Blocker.CanAttack(user))
return; return false;
break; break;
} }
@@ -497,7 +498,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
PopupSystem.PopupClient(ev.Message, weaponUid, user); PopupSystem.PopupClient(ev.Message, weaponUid, user);
} }
return; return false;
} }
// Attack confirmed // Attack confirmed
@@ -513,7 +514,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
break; break;
case DisarmAttackEvent disarm: case DisarmAttackEvent disarm:
if (!DoDisarm(user, disarm, weaponUid, weapon, session)) if (!DoDisarm(user, disarm, weaponUid, weapon, session))
return; return false;
animation = weapon.ClickAnimation; animation = weapon.ClickAnimation;
break; break;
@@ -529,6 +530,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
} }
weapon.Attacking = true; weapon.Attacking = true;
return true;
} }
/// <summary> /// <summary>