Files
GameJamDungeon/Zennysoft.Game.Ma/src/enemy/NavigationAgentClient.cs

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();
}
}