2023-01-03 17:46:55 +01:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
2023-01-04 21:29:42 +01:00
|
|
|
using System.Diagnostics;
|
2023-01-03 17:46:55 +01:00
|
|
|
using System.Linq;
|
|
|
|
using System.Numerics;
|
|
|
|
using Godot;
|
|
|
|
using Vector2 = Godot.Vector2;
|
|
|
|
using Vector3 = Godot.Vector3;
|
2023-01-04 21:29:42 +01:00
|
|
|
using GoDotLog;
|
2023-01-03 17:46:55 +01:00
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// </summary>
|
2023-01-04 21:29:42 +01:00
|
|
|
public class NavigationComponent : Node
|
2023-01-03 17:46:55 +01:00
|
|
|
{
|
2023-01-04 21:29:42 +01:00
|
|
|
public TileWorld TileWorld { set; get; }
|
2023-01-03 17:46:55 +01:00
|
|
|
|
2023-01-04 21:29:42 +01:00
|
|
|
public Vector3 CurrentGoalWorld => _currentGoalWorld;
|
2023-01-03 17:46:55 +01:00
|
|
|
|
2023-01-04 21:29:42 +01:00
|
|
|
private Vector3 _currentGoalWorld = Vector3.Zero;
|
|
|
|
private Vector2 _currentGoalPlane = Vector2.Zero;
|
|
|
|
private Vector2 _currentGoalOffset = Vector2.Zero;
|
|
|
|
private Vector3 _currentPositionWorld = Vector3.Zero;
|
|
|
|
|
|
|
|
private List<Vector2> _pathOffsetCoords;
|
|
|
|
private HexCell[] _path;
|
|
|
|
|
|
|
|
public override void _Ready()
|
|
|
|
{
|
|
|
|
base._Ready();
|
|
|
|
_pathOffsetCoords = new List<Vector2>();
|
|
|
|
}
|
|
|
|
|
|
|
|
public override void _Process(float delta)
|
|
|
|
{
|
|
|
|
Debug.Assert(TileWorld != null);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Plan(Vector3 fromPositionWorld, Vector3 toPositionWorld)
|
2023-01-03 17:46:55 +01:00
|
|
|
{
|
2023-01-04 21:29:42 +01:00
|
|
|
Vector2 fromPositionOffset = TileWorld.WorldToOffsetCoords(fromPositionWorld);
|
|
|
|
Vector2 toPositionOffset = TileWorld.WorldToOffsetCoords(toPositionWorld);
|
|
|
|
|
|
|
|
HexCell fromCell = new HexCell();
|
|
|
|
fromCell.OffsetCoords = fromPositionOffset;
|
|
|
|
|
|
|
|
HexCell toCell = new HexCell();
|
|
|
|
toCell.OffsetCoords = toPositionOffset;
|
|
|
|
|
|
|
|
_path = fromCell.LineTo(toCell);
|
|
|
|
Debug.Assert(_path.Length > 0);
|
|
|
|
|
|
|
|
_pathOffsetCoords = new List<Vector2>();
|
|
|
|
foreach (int index in Enumerable.Range(1, _path.Length - 1))
|
|
|
|
{
|
|
|
|
_pathOffsetCoords.Add(_path[index].OffsetCoords);
|
|
|
|
}
|
|
|
|
|
|
|
|
UpdateCurrentGoal();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void UpdateCurrentGoal()
|
|
|
|
{
|
|
|
|
if (_pathOffsetCoords.Count == 0)
|
2023-01-03 17:46:55 +01:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-01-04 21:29:42 +01:00
|
|
|
_currentGoalWorld = TileWorld.GetTileWorldCenterFromOffset(_pathOffsetCoords[0]);
|
2023-01-03 17:46:55 +01:00
|
|
|
|
2023-01-04 21:29:42 +01:00
|
|
|
GD.Print("Navigation: at " + _currentGoalWorld + " path length: " +
|
|
|
|
_pathOffsetCoords.Count);
|
|
|
|
}
|
2023-01-03 17:46:55 +01:00
|
|
|
|
|
|
|
|
2023-01-04 21:29:42 +01:00
|
|
|
public void UpdateCurrentGoal(Vector3 currentPositionWorld)
|
|
|
|
{
|
|
|
|
_currentPositionWorld = currentPositionWorld;
|
|
|
|
|
|
|
|
Vector2 currentPositionPlane = new Vector2(currentPositionWorld.x, currentPositionWorld.z);
|
|
|
|
Vector2 currentGoalPlane = new Vector2(_currentGoalWorld.x, _currentGoalWorld.z);
|
|
|
|
if (_pathOffsetCoords.Count > 0 &&
|
|
|
|
(currentPositionPlane - currentGoalPlane).LengthSquared() < Globals.EpsPositionSquared)
|
2023-01-03 17:46:55 +01:00
|
|
|
{
|
2023-01-04 21:29:42 +01:00
|
|
|
_pathOffsetCoords.RemoveAt(0);
|
|
|
|
UpdateCurrentGoal();
|
2023-01-03 17:46:55 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|