mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-06-26 19:34:47 +00:00
341 lines
10 KiB
C#
341 lines
10 KiB
C#
using HPJ.Simulation.Enums;
|
|
using HPJ.Simulation.Map;
|
|
using HPJ.Simulation.Utilities;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
|
|
namespace HPJ.Simulation.Pathing
|
|
{
|
|
/// <summary>
|
|
/// The Base class for any pathfinding algorithms
|
|
/// </summary>
|
|
public abstract class PathingCalculation
|
|
{
|
|
/// <summary>
|
|
/// The Navigation Type this pathing is. Will need to add yours to the enum
|
|
/// </summary>
|
|
public NavigationTypes NavigationType { get; protected set; }
|
|
|
|
/// <summary>
|
|
/// The Dictionary of all the pathing algorithms
|
|
/// </summary>
|
|
public static Dictionary<NavigationTypes, PathingCalculation> PathingTypes = new Dictionary<NavigationTypes, PathingCalculation>();
|
|
|
|
public PathingCalculation()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the Algorithm, You will need to call this or add this for your algorithm
|
|
/// </summary>
|
|
public virtual void Initialize()
|
|
{
|
|
NavigationType = NavigationTypes.None;
|
|
if (!PathingTypes.ContainsKey(NavigationType))
|
|
{
|
|
PathingTypes.Add(NavigationType, this);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calculates the Path for a Navigation Job Request on a specific Map
|
|
/// </summary>
|
|
/// <param name="Path"></param>
|
|
/// <param name="OccuringMap"></param>
|
|
/// <param name="Status"></param>
|
|
/// <param name="Succeeded"></param>
|
|
public abstract void CalculatePath(NavigationPath Path, Map.Map OccuringMap, out string Status, out bool Succeeded);
|
|
}
|
|
|
|
/// <summary>
|
|
/// A Navigation Job Request
|
|
/// </summary>
|
|
[Serializable]
|
|
public class NavigationJob
|
|
{
|
|
#region Navigation Info
|
|
|
|
/// <summary>
|
|
/// Infomation on this Job
|
|
/// </summary>
|
|
public PathingInfo Info;
|
|
/// <summary>
|
|
/// Current Step on the Pathfinding Calculation
|
|
/// </summary>
|
|
public PathfindingCalculationStep CurrentStep;
|
|
/// <summary>
|
|
/// The Number of tiles away from the start to the end
|
|
/// </summary>
|
|
public int TilesAway;
|
|
/// <summary>
|
|
/// Point A of the Path
|
|
/// </summary>
|
|
public IntVector3 WorldPointA;
|
|
/// <summary>
|
|
/// Point B of the Path
|
|
/// </summary>
|
|
public IntVector3 WorldPointB;
|
|
/// <summary>
|
|
/// If this Job was compatable or not
|
|
/// </summary>
|
|
public bool Compatable;
|
|
/// <summary>
|
|
/// Next time this path is pathed, repath it
|
|
/// </summary>
|
|
public bool RepathSavedPath;
|
|
/// <summary>
|
|
/// List of Traversable Tiles
|
|
/// </summary>
|
|
public List<TileTypes> TraverableTileTypes;
|
|
/// <summary>
|
|
/// List of Prefferred Tiles
|
|
/// </summary>
|
|
public List<TileTypes> PrefferedTileTypes;
|
|
|
|
#endregion
|
|
|
|
#region Navigation Results
|
|
|
|
/// <summary>
|
|
/// The Resulting Path for this Job Request
|
|
/// </summary>
|
|
public NavigationPath CurrentPath { get; protected set; }
|
|
public ushort AgentID { get; set; }
|
|
|
|
/// <summary>
|
|
/// The Callback to the presentation side
|
|
/// </summary>
|
|
public Action OnCompleteCallback;
|
|
|
|
#endregion
|
|
|
|
public NavigationJob(Action onCompleteCallback)
|
|
{
|
|
Info = new PathingInfo();
|
|
CurrentPath = null;
|
|
CurrentStep = PathfindingCalculationStep.Incomplete;
|
|
OnCompleteCallback = onCompleteCallback;
|
|
AgentID = 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clears the Job and reverts it back to default
|
|
/// </summary>
|
|
public void Clear()
|
|
{
|
|
Info = new PathingInfo();
|
|
CurrentPath = null;
|
|
CurrentStep = PathfindingCalculationStep.Incomplete;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes the Job with the neccessary pathing information
|
|
/// </summary>
|
|
/// <param name="Start"></param>
|
|
/// <param name="End"></param>
|
|
/// <param name="TraverableKey"></param>
|
|
/// <param name="PrefferedTilesKey"></param>
|
|
/// <param name="Navigation"></param>
|
|
/// <param name="ForMap"></param>
|
|
/// <param name="RepathAnyway"></param>
|
|
public void SetDestinationInfo(IntVector3 Start, IntVector3 End, List<TileTypes> TraverableTiles, List<TileTypes> PrefferedTiles, NavigationTypes Navigation, MapSet ForMap, bool RepathAnyway = false)
|
|
{
|
|
if (Start.x < End.x)
|
|
{
|
|
WorldPointA = Start;
|
|
WorldPointB = End;
|
|
}
|
|
else if (Start.x > End.x)
|
|
{
|
|
WorldPointA = End;
|
|
WorldPointB = Start;
|
|
}
|
|
else
|
|
{
|
|
if (Start.z < End.z)
|
|
{
|
|
WorldPointA = Start;
|
|
WorldPointB = End;
|
|
}
|
|
else if (Start.z > End.z)
|
|
{
|
|
WorldPointA = End;
|
|
WorldPointB = Start;
|
|
}
|
|
else
|
|
{
|
|
WorldPointA = Start;
|
|
WorldPointB = End;
|
|
}
|
|
}
|
|
|
|
TraverableTileTypes = TraverableTiles;
|
|
PrefferedTileTypes = PrefferedTiles;
|
|
RepathSavedPath = RepathAnyway;
|
|
Info = new PathingInfo(ForMap.GetMapTileIndex(WorldPointA), ForMap.GetMapTileIndex(WorldPointB), Navigation, TraverableTiles.TilesToString(), PrefferedTiles.TilesToString());
|
|
TilesAway = JumpPointSearch.Instance.CalculateDistanceCost(Start.x, Start.z, End.x, End.z);
|
|
Compatable = ForMap.JobCompatible(this);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the resulting path to the request
|
|
/// </summary>
|
|
/// <param name="path"></param>
|
|
internal void SetNewCurrentPath(NavigationPath path)
|
|
{
|
|
CurrentPath = path;
|
|
}
|
|
|
|
/// <summary>
|
|
/// The callback from the simulation when the job request is finished
|
|
/// </summary>
|
|
internal void PathfindingComplete()
|
|
{
|
|
CurrentStep = PathfindingCalculationStep.Complete;
|
|
OnCompleteCallback?.Invoke();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The Calculated Path on a specific Map
|
|
/// </summary>
|
|
[System.Serializable]
|
|
public class NavigationPath
|
|
{
|
|
/// <summary>
|
|
/// The map the path was calculated on
|
|
/// </summary>
|
|
public Map.Map HostMap;
|
|
/// <summary>
|
|
/// The Information on this Path
|
|
/// </summary>
|
|
public PathingInfo Info;
|
|
|
|
/// <summary>
|
|
/// The Resulting Path
|
|
/// </summary>
|
|
public List<IntVector2> Path;
|
|
|
|
/// <summary>
|
|
/// If this Path resulting in a valid path
|
|
/// </summary>
|
|
public bool ValidPath;
|
|
|
|
/// <summary>
|
|
/// Previous status on the path
|
|
/// </summary>
|
|
public string PreviousStatus { get; set; }
|
|
|
|
/// <summary>
|
|
/// Asking For Path from specific agent
|
|
/// </summary>
|
|
public ushort AgentID;
|
|
|
|
public NavigationPath()
|
|
{
|
|
Info = new PathingInfo();
|
|
Path = new List<IntVector2>();
|
|
ValidPath = false;
|
|
PreviousStatus = "";
|
|
AgentID = 0;
|
|
}
|
|
|
|
public NavigationPath(PathingInfo PathInfo, Map.Map hostMap, ushort ID = 0)
|
|
{
|
|
Info = PathInfo;
|
|
Path = new List<IntVector2>();
|
|
ValidPath = false;
|
|
HostMap = hostMap;
|
|
PreviousStatus = "";
|
|
AgentID = 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks to see if your starting point is the first index of the path or the last
|
|
/// </summary>
|
|
/// <param name="startPoint"></param>
|
|
/// <returns></returns>
|
|
public bool NeedToReverse(IntVector3 startPoint)
|
|
{
|
|
if (!ValidPath)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (Path.Count <= 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return Path[0] != HostMap.GetTileIndexPosition(startPoint);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The information on a given path
|
|
/// </summary>
|
|
[System.Serializable]
|
|
public struct PathingInfo
|
|
{
|
|
/// <summary>
|
|
/// Point A of a Path
|
|
/// </summary>
|
|
public IntVector2 PointA;
|
|
/// <summary>
|
|
/// Point B of a Path
|
|
/// </summary>
|
|
public IntVector2 PointB;
|
|
/// <summary>
|
|
/// Navigation type used for this Path
|
|
/// </summary>
|
|
public NavigationTypes NavigationType;
|
|
/// <summary>
|
|
/// Traversable Tiles Key
|
|
/// </summary>
|
|
public string TraversableTilesKey;
|
|
/// <summary>
|
|
/// Preffered Tile Kep
|
|
/// </summary>
|
|
public string PrefferedTilesKey;
|
|
|
|
public PathingInfo(IntVector2 A, IntVector2 B, NavigationTypes Type, string Traverable, string Preffered)
|
|
{
|
|
// Sort tiles by bottom left so there is no repeats in the saved path Dictionary
|
|
if (A.x < B.x)
|
|
{
|
|
PointA = A;
|
|
PointB = B;
|
|
}
|
|
else if (A.x > B.x)
|
|
{
|
|
PointA = B;
|
|
PointB = A;
|
|
}
|
|
else
|
|
{
|
|
if (A.y < B.y)
|
|
{
|
|
PointA = A;
|
|
PointB = B;
|
|
}
|
|
else if (A.y > B.y)
|
|
{
|
|
PointA = B;
|
|
PointB = A;
|
|
}
|
|
else
|
|
{
|
|
PointA = A;
|
|
PointB = B;
|
|
}
|
|
}
|
|
|
|
NavigationType = Type;
|
|
TraversableTilesKey = Traverable;
|
|
PrefferedTilesKey = Preffered;
|
|
}
|
|
}
|
|
}
|