84 lines
2.1 KiB
C#
84 lines
2.1 KiB
C#
using Chickensoft.AutoInject;
|
|
using Chickensoft.Introspection;
|
|
using Godot;
|
|
using System;
|
|
using System.Threading.Tasks;
|
|
using Zennysoft.Game.Abstractions;
|
|
|
|
namespace Zennysoft.Game.Ma;
|
|
|
|
[Meta(typeof(IAutoNode))]
|
|
public partial class NavigationAgentClient : Node3D, INavigationAgentClient
|
|
{
|
|
public override void _Notification(int what) => this.Notify(what);
|
|
|
|
[Node] private NavigationAgent3D NavAgent { get; set; } = default!;
|
|
|
|
[Node] private Timer _patrolTimer { get; set; } = default!;
|
|
|
|
private Vector3 _currentTarget = Vector3.Zero;
|
|
private Timer _thinkTimer;
|
|
private bool _canMove = false;
|
|
|
|
public void Setup()
|
|
{
|
|
NavAgent.VelocityComputed += NavAgent_VelocityComputed;
|
|
NavAgent.TargetReached += NavAgent_TargetReached;
|
|
|
|
var rng = new RandomNumberGenerator();
|
|
rng.Randomize();
|
|
_patrolTimer.Timeout += OnPatrolTimeout;
|
|
_patrolTimer.WaitTime = rng.RandfRange(7.0f, 15.0f);
|
|
|
|
_thinkTimer = new Timer
|
|
{
|
|
WaitTime = 0.4f
|
|
};
|
|
AddChild(_thinkTimer);
|
|
_thinkTimer.Timeout += NavAgent_TargetReached;
|
|
_thinkTimer.Start();
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
_patrolTimer.Stop();
|
|
_thinkTimer.Stop();
|
|
}
|
|
|
|
private void NavAgent_VelocityComputed(Vector3 safeVelocity)
|
|
{
|
|
if (!_canMove)
|
|
return;
|
|
|
|
var enemy = GetOwner() as IEnemy;
|
|
enemy.Move(safeVelocity);
|
|
}
|
|
|
|
public void CalculateVelocity(Vector3 currentPosition, bool canMove)
|
|
{
|
|
_canMove = canMove;
|
|
var nextPathPosition = NavAgent.GetNextPathPosition();
|
|
|
|
var newVelocity = currentPosition.DirectionTo(nextPathPosition) * 2f;
|
|
NavAgent.Velocity = newVelocity;
|
|
}
|
|
public void SetTarget(Vector3 target) => Task.Delay(TimeSpan.FromSeconds(0.4)).ContinueWith(_ => _currentTarget = new Vector3(target.X, -1.75f, target.Z));
|
|
|
|
public bool IsAvoidanceEnabled => NavAgent.AvoidanceEnabled;
|
|
|
|
|
|
private void NavAgent_TargetReached()
|
|
{
|
|
NavAgent.TargetPosition = _currentTarget;
|
|
}
|
|
|
|
private void OnPatrolTimeout()
|
|
{
|
|
var rng = new RandomNumberGenerator();
|
|
rng.Randomize();
|
|
_patrolTimer.WaitTime = rng.RandfRange(5.0f, 10.0f);
|
|
var enemy = GetOwner() as ICanPatrol;
|
|
enemy.Patrol();
|
|
}
|
|
}
|