Add simple miss chances for NPCs (#12978)

Doesn't consider juking potential but okay for now.
This commit is contained in:
metalgearsloth
2022-12-12 00:37:09 +11:00
committed by GitHub
parent da31f9e5ee
commit 83fede79eb
6 changed files with 39 additions and 9 deletions

View File

@@ -4,6 +4,8 @@ using Content.Shared.MobState;
using Content.Shared.MobState.Components;
using Content.Shared.Weapons.Melee;
using Robust.Shared.Map;
using Robust.Shared.Physics.Components;
using Robust.Shared.Random;
namespace Content.Server.NPC.Systems;
@@ -42,6 +44,8 @@ public sealed partial class NPCCombatSystem
{
var combatQuery = GetEntityQuery<CombatModeComponent>();
var xformQuery = GetEntityQuery<TransformComponent>();
var physicsQuery = GetEntityQuery<PhysicsComponent>();
var curTime = _timing.CurTime;
foreach (var (comp, _) in EntityQuery<NPCMeleeCombatComponent, ActiveNPCComponent>())
{
@@ -51,17 +55,14 @@ public sealed partial class NPCCombatSystem
continue;
}
Attack(comp, xformQuery);
Attack(comp, curTime, physicsQuery, xformQuery);
}
}
private void Attack(NPCMeleeCombatComponent component, EntityQuery<TransformComponent> xformQuery)
private void Attack(NPCMeleeCombatComponent component, TimeSpan curTime, EntityQuery<PhysicsComponent> physicsQuery, EntityQuery<TransformComponent> xformQuery)
{
component.Status = CombatStatus.Normal;
// TODO:
// Also need some blackboard data for stuff like juke frequency, assigning target slots (to surround targets), etc.
// miss %
if (!TryComp<MeleeWeaponComponent>(component.Weapon, out var weapon))
{
component.Status = CombatStatus.NoWeapon;
@@ -105,6 +106,19 @@ public sealed partial class NPCCombatSystem
// Gets unregistered on component shutdown.
_steering.TryRegister(component.Owner, new EntityCoordinates(component.Target, Vector2.Zero), steering);
_melee.AttemptLightAttack(component.Owner, weapon, component.Target);
if (weapon.NextAttack > curTime)
return;
if (_random.Prob(component.MissChance) &&
physicsQuery.TryGetComponent(component.Target, out var targetPhysics) &&
targetPhysics.LinearVelocity.LengthSquared != 0f)
{
_melee.AttemptLightAttackMiss(component.Owner, weapon, targetXform.Coordinates.Offset(_random.NextVector2(0.5f)));
}
else
{
_melee.AttemptLightAttack(component.Owner, weapon, component.Target);
}
}
}