SupaLidlGame/State/Thinker/CenturionAttackState.cs

99 lines
2.5 KiB
C#
Raw Normal View History

2023-08-16 21:02:37 -07:00
using Godot;
using SupaLidlGame.Extensions;
namespace SupaLidlGame.State.Thinker;
public partial class CenturionAttackState : BlockAttackState
{
[Export]
public bool FollowTeammate { get; set; } = false;
[Export]
public NavigationAgent2D NavigationAgent { get; set; }
[Export]
public float PathfindingDistance { get; set; } = 64;
protected Characters.Character _bestTeammate = null;
public Characters.Character FindBestTeammate()
{
float bestScore = float.MaxValue;
Characters.Character bestChar = null;
var world = this.GetWorld();
foreach (Node node in world.CurrentMap.Entities.GetChildren())
{
if (node != NPC && node is Characters.Character character)
{
if (!IsInstanceValid(character) || !character.IsAlive)
{
continue;
}
if (character.Faction == NPC.Faction)
{
float score = NPC.Position.DistanceTo(character.Position);
if (score < bestScore)
{
bestScore = score;
bestChar = character;
}
}
}
}
return _bestTeammate = bestChar;
}
public override ThinkerState Think()
{
base.Think();
2023-11-13 20:11:20 -08:00
if (_bestTarget?.StunTime > 0)
{
return null;
}
2023-08-16 21:02:37 -07:00
var teammate = FindBestTeammate();
if (teammate is not null)
{
UpdateWeights(teammate.GlobalPosition);
NavigationAgent.TargetPosition = teammate.GlobalPosition;
}
return null;
}
public override ThinkerState Process(double delta)
{
if (_bestTeammate is null)
{
return null;
}
float dist = NPC.DistanceTo(_bestTeammate);
if (NPC.DistanceTo(_bestTeammate) < PathfindingDistance)
{
// move to weighted position
return base.Process(delta);
}
return null;
}
public override ThinkerState PhysicsProcess(double delta)
{
if (_bestTeammate is not null)
{
float dist = NPC.DistanceTo(_bestTeammate);
if (dist >= PathfindingDistance)
{
var nextPos = NavigationAgent.GetNextPathPosition();
NPC.Direction = NPC.GlobalPosition.DirectionTo(nextPos);
}
}
return base.PhysicsProcess(delta);
}
}