Rework enemy behavior (still in progress but shouldn't crash)
This commit is contained in:
87
Zennysoft.Game.Ma/src/enemy/behaviors/PatrolBehavior.cs
Normal file
87
Zennysoft.Game.Ma/src/enemy/behaviors/PatrolBehavior.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
using Zennysoft.Game.Abstractions.Entity;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
[Meta(typeof(IAutoNode))]
|
||||
public partial class PatrolBehavior : Node3D, IBehavior
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
[Export] private double _patrolSpeed { get; set; } = 100f;
|
||||
|
||||
[Export] private double _thinkTime { get; set; } = 0.8f;
|
||||
|
||||
[Export] private float _patrolRange { get; set; } = 5f;
|
||||
|
||||
[Export] private float _patrolTime { get; set; } = 10f;
|
||||
|
||||
private Timer _patrolTimer { get; set; } = default!;
|
||||
private NavigationAgent3D _navigationAgent;
|
||||
|
||||
private int _recursiveCounter = 0;
|
||||
|
||||
public Vector3 HomePosition { get; set; }
|
||||
|
||||
[Signal] public delegate void OnVelocityComputedEventHandler(Vector3 safeVelocity);
|
||||
|
||||
public void OnReady()
|
||||
{
|
||||
_patrolTimer = new Timer() { WaitTime = _patrolTime };
|
||||
_patrolTimer.Timeout += PatrolTimer_Timeout;
|
||||
AddChild(_patrolTimer);
|
||||
SetPhysicsProcess(false);
|
||||
}
|
||||
|
||||
public void Init(NavigationAgent3D navigationAgent)
|
||||
{
|
||||
_navigationAgent = navigationAgent;
|
||||
_navigationAgent.WaypointReached += NavigationAgent_WaypointReached;
|
||||
_navigationAgent.TargetPosition = HomePosition;
|
||||
}
|
||||
|
||||
private async void NavigationAgent_WaypointReached(Dictionary details) => await ToSignal(GetTree().CreateTimer(_thinkTime), "timeout");
|
||||
|
||||
public void StartPatrol()
|
||||
{
|
||||
SetPhysicsProcess(true);
|
||||
_patrolTimer?.Start();
|
||||
}
|
||||
|
||||
public void StopPatrol()
|
||||
{
|
||||
SetPhysicsProcess(false);
|
||||
_patrolTimer?.Stop();
|
||||
}
|
||||
|
||||
public void OnPhysicsProcess(double delta)
|
||||
{
|
||||
var nextVelocity = _navigationAgent.GetNextPathPosition();
|
||||
var parent = GetParent() as Node3D;
|
||||
var velocity = parent.GlobalPosition.DirectionTo(nextVelocity) * (float)_patrolSpeed * (float)delta;
|
||||
EmitSignal(SignalName.OnVelocityComputed, velocity);
|
||||
}
|
||||
|
||||
public void SetPatrolTarget()
|
||||
{
|
||||
var rng = new RandomNumberGenerator();
|
||||
rng.Randomize();
|
||||
var randomPointX = rng.RandfRange(-_patrolRange, _patrolRange);
|
||||
var randomPointZ = rng.RandfRange(-_patrolRange, _patrolRange);
|
||||
_navigationAgent.TargetPosition = HomePosition + new Vector3(randomPointX, 0, randomPointZ);
|
||||
if (!_navigationAgent.IsTargetReachable())
|
||||
{
|
||||
_recursiveCounter++;
|
||||
if (_recursiveCounter <= 100)
|
||||
SetPatrolTarget();
|
||||
else
|
||||
_navigationAgent.TargetPosition = HomePosition;
|
||||
}
|
||||
_recursiveCounter = 0;
|
||||
}
|
||||
|
||||
private void PatrolTimer_Timeout() => SetPatrolTarget();
|
||||
}
|
||||
Reference in New Issue
Block a user