mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-11-11 08:38:45 +00:00
no message
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c252000f45a359844bbc365b3584318c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
|
||||
namespace HPJ.Simulation.Map
|
||||
{
|
||||
public class AgentMap
|
||||
{
|
||||
/// <summary>
|
||||
/// Base map related to this map
|
||||
/// </summary>
|
||||
public Map Base { get; protected set; }
|
||||
/// <summary>
|
||||
/// Tile that descripe the agent ownership
|
||||
/// </summary>
|
||||
public ushort[,] Tiles { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the agent map based on the base map
|
||||
/// </summary>
|
||||
/// <param name="baseMap"></param>
|
||||
public AgentMap(Map baseMap)
|
||||
{
|
||||
Base = baseMap;
|
||||
|
||||
Tiles = new ushort[baseMap.Settings.MapWidth, baseMap.Settings.MapHeight];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disowns this tile so other agents can claim it or to know its availible
|
||||
/// </summary>
|
||||
/// <param name="ownedTile"></param>
|
||||
public void DisownTile(IntVector2 ownedTile, ushort ID)
|
||||
{
|
||||
if (ownedTile.x < 0 || ownedTile.y < 0 || ownedTile.x >= Base.Settings.MapWidth || ownedTile.y >= Base.Settings.MapHeight)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Tiles[ownedTile.x, ownedTile.y] == ID)
|
||||
{
|
||||
Tiles[ownedTile.x, ownedTile.y] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to claim a tile for a specified ID
|
||||
/// </summary>
|
||||
/// <param name="newTilePosition"></param>
|
||||
/// <param name="ID"></param>
|
||||
/// <returns></returns>
|
||||
public bool ClaimTile(IntVector2 newTilePosition, ushort ID)
|
||||
{
|
||||
if (newTilePosition.x < 0 || newTilePosition.y < 0 || newTilePosition.x >= Base.Settings.MapWidth || newTilePosition.y >= Base.Settings.MapHeight)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Tiles[newTilePosition.x, newTilePosition.y] == 0)
|
||||
{
|
||||
Tiles[newTilePosition.x, newTilePosition.y] = ID;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
internal bool IsBlocked(int x, int y, ushort CompareID)
|
||||
{
|
||||
return Tiles[x, y] != 0 && Tiles[x, y] != CompareID;
|
||||
}
|
||||
|
||||
public bool ValidTileForAgent(ushort simNavigationAgentID, int x, int y)
|
||||
{
|
||||
if (Tiles[x, y] == 0 || Tiles[x, y] == simNavigationAgentID)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d12e6518def9eb4698b61dd77af94a1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,129 @@
|
||||
using HPJ.Simulation.Enums;
|
||||
using HPJ.Simulation.Utilities;
|
||||
using System.Linq;
|
||||
|
||||
namespace HPJ.Simulation.Map
|
||||
{
|
||||
/// <summary>
|
||||
/// A Flattenned version of a map that changes every tile type into a 1 or 0. Is it traverable or is it not
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class BytePointMap
|
||||
{
|
||||
private byte[,] _tiles;
|
||||
/// <summary>
|
||||
/// The Tiles for the Byte Map
|
||||
/// </summary>
|
||||
public byte[,] Tiles { get { return _tiles; } }
|
||||
private int _width;
|
||||
/// <summary>
|
||||
/// The Width of the Byte Map
|
||||
/// </summary>
|
||||
public int Width { get { return _width; } }
|
||||
|
||||
private int _length;
|
||||
/// <summary>
|
||||
/// The Length of the Byte Map
|
||||
/// </summary>
|
||||
public int Length { get { return _length; } }
|
||||
|
||||
private bool _cornerCutting;
|
||||
/// <summary>
|
||||
/// Whether corner cuttins is enabled on this map
|
||||
/// </summary>
|
||||
public bool CornerCutting { get { return _cornerCutting; } set { _cornerCutting = value; } }
|
||||
|
||||
private string _traversableKey;
|
||||
/// <summary>
|
||||
/// The Key used to flatten the map
|
||||
/// </summary>
|
||||
public string TraversableKey { get { return _traversableKey; } }
|
||||
|
||||
private TileTypes[] _traversable;
|
||||
/// <summary>
|
||||
/// The Tiles that are traversable on this map
|
||||
/// </summary>
|
||||
public TileTypes[] Traversable { get { return _traversable; } }
|
||||
|
||||
public BytePointMap(byte[,] TileTypeMap, TileTypes[] TraversableTiles, int TileMapWidth, int TileMapLength, bool CornerCuttingEnabled)
|
||||
{
|
||||
_traversable = TraversableTiles;
|
||||
_traversableKey = TraversableTiles.TilesToString();
|
||||
_cornerCutting = CornerCuttingEnabled;
|
||||
_tiles = new byte[TileMapWidth, TileMapLength];
|
||||
_width = TileMapWidth;
|
||||
_length = TileMapLength;
|
||||
|
||||
for (int x = 0; x < TileMapWidth; x++)
|
||||
{
|
||||
for (int y = 0; y < TileMapLength; y++)
|
||||
{
|
||||
if (_traversable.Contains((TileTypes)TileTypeMap[x, y]))
|
||||
{
|
||||
_tiles[x, y] = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
_tiles[x, y] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the tile of the byte map
|
||||
/// </summary>
|
||||
/// <param name="x"></param>
|
||||
/// <param name="y"></param>
|
||||
/// <param name="newType"></param>
|
||||
public void ChangeTile(int x, int y, TileTypes newType)
|
||||
{
|
||||
if (_traversable.Contains(newType))
|
||||
{
|
||||
_tiles[x, y] = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
_tiles[x, y] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the tile of the byte map
|
||||
/// </summary>
|
||||
/// <param name="TileIndex"></param>
|
||||
/// <param name="newType"></param>
|
||||
public void ChangeTile(IntVector2 TileIndex, TileTypes newType)
|
||||
{
|
||||
if (_traversable.Contains(newType))
|
||||
{
|
||||
_tiles[TileIndex.x, TileIndex.y] = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
_tiles[TileIndex.x, TileIndex.y] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the speed of the tile
|
||||
/// </summary>
|
||||
/// <param name="x"></param>
|
||||
/// <param name="y"></param>
|
||||
/// <returns></returns>
|
||||
public byte GetTileSpeed(int x, int y)
|
||||
{
|
||||
if (x < 0 || x >= _width)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (y < 0 || y >= _length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _tiles[x, y];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a78ad3bb786105e4498376a108278248
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,27 @@
|
||||
using HPJ.Simulation.Enums;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace HPJ.Simulation.Map
|
||||
{
|
||||
[System.Serializable]
|
||||
public class ChangeMapJob
|
||||
{
|
||||
public List<(IntVector2, TileTypes)> TilesToBeChanged;
|
||||
|
||||
public ChangeMapJob(List<(IntVector2, TileTypes)> TilesChanged)
|
||||
{
|
||||
TilesToBeChanged = TilesChanged;
|
||||
}
|
||||
|
||||
public ChangeMapJob()
|
||||
{
|
||||
TilesToBeChanged = new List<(IntVector2, TileTypes)>();
|
||||
}
|
||||
|
||||
public void AddTileChange(IntVector2 TileIndex, TileTypes TypeChange)
|
||||
{
|
||||
TilesToBeChanged.Add((TileIndex, TypeChange));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4dee08e2c91f0874cb9ddeb7d3b8261f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1543
JNFrame/Assets/HPJ Pathfinding Pro/Scripts/2.Simulation/1.Map/Map.cs
Normal file
1543
JNFrame/Assets/HPJ Pathfinding Pro/Scripts/2.Simulation/1.Map/Map.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 76e9eb321b9adff43b8e51b251db8e1d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b9694e0d5a80a3c4eb0b89141c221aff
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,26 @@
|
||||
namespace HPJ.Simulation
|
||||
{
|
||||
public struct TileOwnershipClaim
|
||||
{
|
||||
public ushort OwnerID;
|
||||
public IntVector2 RequestTile;
|
||||
|
||||
public TileOwnershipClaim(ushort ID, IntVector2 Tile)
|
||||
{
|
||||
OwnerID = ID;
|
||||
RequestTile = Tile;
|
||||
}
|
||||
}
|
||||
|
||||
public struct DisownTileOwnership
|
||||
{
|
||||
public ushort OwnerID;
|
||||
public IntVector2 RequestTile;
|
||||
|
||||
public DisownTileOwnership(ushort ID, IntVector2 Tile)
|
||||
{
|
||||
OwnerID = ID;
|
||||
RequestTile = Tile;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6db62976e6c7e20499490631bbbc2382
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 48809749fb43d0b45800347fa4e2a389
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,294 @@
|
||||
using HPJ.Simulation.Enums;
|
||||
using HPJ.Simulation.Map;
|
||||
using HPJ.Simulation.Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace HPJ.Simulation.Pathing
|
||||
{
|
||||
public class AStar : PathingCalculation
|
||||
{
|
||||
public static AStar Instance = null;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
NavigationType = Enums.NavigationTypes.AStar;
|
||||
if (!PathingTypes.ContainsKey(NavigationType))
|
||||
{
|
||||
PathingTypes.Add(NavigationType, this);
|
||||
}
|
||||
}
|
||||
|
||||
public override void CalculatePath(NavigationPath Path, Map.Map OccuringMap, out string Status, out bool Succeeded)
|
||||
{
|
||||
try
|
||||
{
|
||||
List<IntVector2> OpenList = new List<IntVector2>();
|
||||
HashSet<IntVector2> ClosedList = new HashSet<IntVector2>();
|
||||
Dictionary<IntVector2, AStarTileData> SortedList = new Dictionary<IntVector2, AStarTileData>();
|
||||
|
||||
IntVector2 StartTile = Path.Info.PointA;
|
||||
IntVector2 EndTile = Path.Info.PointB;
|
||||
|
||||
OpenList.Add(StartTile);
|
||||
AStarTileData StartingTileData = new AStarTileData(new IntVector2(-1, -1), CalculateDistanceCost(StartTile.x, StartTile.y, EndTile.x, EndTile.y));
|
||||
StartingTileData.GCost = 0;
|
||||
StartingTileData.FCost = StartingTileData.GCost + StartingTileData.HCost;
|
||||
SortedList.Add(StartTile, StartingTileData);
|
||||
|
||||
int TentativeGCost = 0;
|
||||
IntVector2 CurrentTile = StartTile;
|
||||
int Iterations = 0;
|
||||
|
||||
bool MaxIterationsMade = false;
|
||||
int MaxIterations = 3000;
|
||||
|
||||
// Get BitMap
|
||||
BytePointMap BitMap = Path.HostMap.GetBytePointMap(Path);
|
||||
TileTypes[] PrefferedTiles = Path.Info.PrefferedTilesKey.StringToTilesArray();
|
||||
|
||||
while (OpenList.Count > 0)
|
||||
{
|
||||
// Give a safty range of 2 times the range in terms of iterations, if it cannot find a path by then, it's failed. can probably cannot be reached
|
||||
if (Iterations > MaxIterations)
|
||||
{
|
||||
MaxIterationsMade = true;
|
||||
break;
|
||||
}
|
||||
Iterations++;
|
||||
|
||||
int CurrentNodeIndex = GetLowestFCostTileIndex(OpenList, Path.HostMap, StartTile, EndTile, CurrentTile, PrefferedTiles);
|
||||
CurrentTile = OpenList[CurrentNodeIndex];
|
||||
if (EndTile == CurrentTile)
|
||||
{
|
||||
// Reached the end
|
||||
//Debug.Log("Found the End - Should be Path Complete");
|
||||
break;
|
||||
}
|
||||
|
||||
// Remove current
|
||||
OpenList.RemoveAt(CurrentNodeIndex);
|
||||
|
||||
ClosedList.Add(CurrentTile);
|
||||
|
||||
AStarTileData CurrentData = SortedList[CurrentTile];
|
||||
|
||||
for (int x = -1; x <= 1; x++)
|
||||
{
|
||||
for (int y = -1; y <= 1; y++)
|
||||
{
|
||||
if (x == 0 && y == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IntVector2 neighbourPosition = new IntVector2(CurrentTile.x + x, CurrentTile.y + y);
|
||||
if (BitMap.GetTileSpeed(neighbourPosition.x, neighbourPosition.y) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ClosedList.Contains(neighbourPosition))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Get Corner Types, if its a wall, continue (DO NOT WALK THROUGH WALLS)
|
||||
if (!BitMap.CornerCutting)
|
||||
{
|
||||
if (x != 0 && y != 0)
|
||||
{
|
||||
IntVector2 cornerAdjacentPosition = new IntVector2(CurrentTile.x + x, CurrentTile.y);
|
||||
|
||||
if (BitMap.Tiles[cornerAdjacentPosition.x, cornerAdjacentPosition.y] == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
cornerAdjacentPosition.x = CurrentTile.x;
|
||||
cornerAdjacentPosition.y = CurrentTile.y + y;
|
||||
|
||||
if (BitMap.Tiles[cornerAdjacentPosition.x, cornerAdjacentPosition.y] == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AStarTileData NeighbourData;
|
||||
if (!SortedList.TryGetValue(neighbourPosition, out NeighbourData))
|
||||
{
|
||||
NeighbourData = new AStarTileData(new IntVector2(-1, -1), CalculateDistanceCost(neighbourPosition.x, neighbourPosition.y, EndTile.x, EndTile.y));
|
||||
SortedList.Add(neighbourPosition, NeighbourData);
|
||||
}
|
||||
|
||||
TentativeGCost = CurrentData.GCost + CalculateDistanceCost(CurrentTile.x, CurrentTile.y, neighbourPosition.x, neighbourPosition.y);
|
||||
if (TentativeGCost < NeighbourData.GCost)
|
||||
{
|
||||
//Debug.Log("Lower G Cost");
|
||||
NeighbourData.RouteFromTileIndex = CurrentTile;
|
||||
NeighbourData.GCost = TentativeGCost;
|
||||
NeighbourData.FCost = NeighbourData.GCost + NeighbourData.HCost;
|
||||
SortedList[neighbourPosition] = NeighbourData;
|
||||
|
||||
if (!OpenList.Contains(neighbourPosition))
|
||||
{
|
||||
//Debug.Log("LEnter To OpenList");
|
||||
OpenList.Add(neighbourPosition);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AStarTileData EndTileData;
|
||||
if (MaxIterationsMade)
|
||||
{
|
||||
Succeeded = false;
|
||||
Status = $"Path is too far away, or cannot be reached --> Iteration Max Reached {MaxIterations}";
|
||||
}
|
||||
else if (!SortedList.TryGetValue(EndTile, out EndTileData) || EndTileData.RouteFromTileIndex.x == -1)
|
||||
{
|
||||
// No Valid Path Found
|
||||
Succeeded = false;
|
||||
Status = "Open list emptied - But did NOT reach the End, Likely Trapped";
|
||||
}
|
||||
else
|
||||
{
|
||||
Succeeded = true;
|
||||
// Path should be valid
|
||||
SortPath(Path, SortedList, EndTile);
|
||||
Status = $"Found a Valid Path 'Iterations ({Iterations} / {MaxIterations})' -> 'List Counts (Open:{OpenList.Count} / Closed:{ClosedList.Count})'";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Status = "Faled";
|
||||
OccuringMap.LogError($"{ex.Message}: {ex.Source}: {ex.StackTrace}");
|
||||
Succeeded = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected int GetLowestFCostTileIndex(List<IntVector2> OpenList, Map.Map OccuringMap, IntVector2 Start, IntVector2 End, IntVector2 CurrentTileIndex, TileTypes[] PrefferedTiles)
|
||||
{
|
||||
int LowestCostIndex = 0;
|
||||
if (PrefferedTiles.Contains(OccuringMap.GetTileType(CurrentTileIndex)))
|
||||
{
|
||||
// Try to stick to the group tile unless the tile is farther from the start AND closer to the end
|
||||
int CurrentStartScore = CalculateDistanceCost(CurrentTileIndex.x, CurrentTileIndex.y, Start.x, Start.y);
|
||||
int CurrentEndScore = CalculateDistanceCost(CurrentTileIndex.x, CurrentTileIndex.y, End.x, End.y);
|
||||
|
||||
int LowestSameCostIndex = -1;
|
||||
TileTypes ZeroTileType = OccuringMap.GetTileType(OpenList[0].x, OpenList[0].y);
|
||||
byte TileSpeed = OccuringMap.GetTileSpeedData(ZeroTileType);
|
||||
int ZeroStartScore = CalculateDistanceCost(OpenList[0].x, OpenList[0].y, Start.x, Start.y);
|
||||
int ZeroEndScore = CalculateDistanceCost(OpenList[0].x, OpenList[0].y, End.x, End.y);
|
||||
int CurrentLowestCost = ZeroEndScore / TileSpeed;
|
||||
|
||||
int CurrentSameLowestCost = int.MaxValue;
|
||||
if (PrefferedTiles.Contains(ZeroTileType) || (ZeroStartScore > CurrentStartScore && ZeroEndScore < CurrentEndScore))
|
||||
{
|
||||
LowestSameCostIndex = 0;
|
||||
CurrentSameLowestCost = CurrentLowestCost;
|
||||
}
|
||||
|
||||
for (int i = 1; i < OpenList.Count; i++)
|
||||
{
|
||||
TileTypes iTileType = OccuringMap.GetTileType(OpenList[i].x, OpenList[i].y);
|
||||
TileSpeed = OccuringMap.GetTileSpeedData(iTileType);
|
||||
int iStartScore = CalculateDistanceCost(OpenList[i].x, OpenList[i].y, Start.x, Start.y);
|
||||
int iEndScore = CalculateDistanceCost(OpenList[i].x, OpenList[i].y, End.x, End.y);
|
||||
int testCost = iEndScore / TileSpeed;
|
||||
if (testCost < CurrentLowestCost)
|
||||
{
|
||||
CurrentLowestCost = testCost;
|
||||
LowestCostIndex = i;
|
||||
}
|
||||
|
||||
if (PrefferedTiles.Contains(iTileType) || (iStartScore > CurrentStartScore && iEndScore < CurrentEndScore))
|
||||
{
|
||||
if (testCost < CurrentSameLowestCost)
|
||||
{
|
||||
LowestSameCostIndex = i;
|
||||
CurrentSameLowestCost = testCost;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (LowestSameCostIndex != -1)
|
||||
{
|
||||
return LowestSameCostIndex;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Typical AStar pathfinding
|
||||
int TileSpeed = OccuringMap.GetTileSpeedData(OccuringMap.GetTileType(OpenList[0].x, OpenList[0].y));
|
||||
int CurrentLowestCost = CalculateDistanceCost(OpenList[0].x, OpenList[0].y, End.x, End.y) / TileSpeed;
|
||||
for (int i = 1; i < OpenList.Count; i++)
|
||||
{
|
||||
TileSpeed = OccuringMap.GetTileSpeedData(OccuringMap.GetTileType(OpenList[i].x, OpenList[i].y));
|
||||
int testCost = CalculateDistanceCost(OpenList[i].x, OpenList[i].y, End.x, End.y) / TileSpeed;
|
||||
if (testCost < CurrentLowestCost)
|
||||
{
|
||||
CurrentLowestCost = testCost;
|
||||
LowestCostIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return LowestCostIndex;
|
||||
}
|
||||
|
||||
protected int CalculateDistanceCost(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
int X_Distance = x1 - x2;
|
||||
X_Distance = X_Distance < 0 ? -X_Distance : X_Distance;
|
||||
int Y_Distance = y1 - y2;
|
||||
Y_Distance = Y_Distance < 0 ? -Y_Distance : Y_Distance;
|
||||
int remaining = X_Distance - Y_Distance;
|
||||
remaining = remaining < 0 ? -remaining : remaining;
|
||||
if (Y_Distance < X_Distance)
|
||||
{
|
||||
return 14 * Y_Distance + 10 * remaining;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 14 * X_Distance + 10 * remaining;
|
||||
}
|
||||
}
|
||||
|
||||
protected void SortPath(NavigationPath Path, Dictionary<IntVector2, AStarTileData> SortedData, IntVector2 EndTileIndex)
|
||||
{
|
||||
AStarTileData CurrentTile = SortedData[EndTileIndex];
|
||||
int InsertIndex = Path.Path.Count;
|
||||
Path.Path.Insert(InsertIndex, EndTileIndex);
|
||||
|
||||
// The Route From Index of the starting tile should be the only one with a (-1, -1) index
|
||||
while (CurrentTile.RouteFromTileIndex.x != -1)
|
||||
{
|
||||
Path.Path.Insert(InsertIndex, CurrentTile.RouteFromTileIndex);
|
||||
CurrentTile = SortedData[CurrentTile.RouteFromTileIndex];
|
||||
}
|
||||
}
|
||||
|
||||
public struct AStarTileData
|
||||
{
|
||||
public IntVector2 RouteFromTileIndex;
|
||||
public int FCost;
|
||||
public int GCost;
|
||||
public int HCost;
|
||||
|
||||
public AStarTileData(IntVector2 RouteFromTile, int EndCost)
|
||||
{
|
||||
RouteFromTileIndex = RouteFromTile;
|
||||
FCost = int.MaxValue;
|
||||
GCost = int.MaxValue;
|
||||
HCost = EndCost;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 183160215d33bde4981db6e6901c2972
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 91124dce985e03b428dfcfd28071da97
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,340 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5785cb1e31a25e948b0f11f9b7ae1b5d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b47d43b65afd2aa41bc9924ebeebe679
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,140 @@
|
||||
namespace HPJ.Simulation.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// The Navigation Types a agent can use for pathfinding
|
||||
/// </summary>
|
||||
public enum NavigationTypes
|
||||
{
|
||||
None = 0, // No Navigation Possible
|
||||
Free = 1,
|
||||
JumpPointSearch = 2,
|
||||
AStar = 3,
|
||||
Unknown = 4,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Navigation Tile Types that are availble on a Map, add more as needed
|
||||
/// </summary>
|
||||
public enum TileTypes : byte
|
||||
{
|
||||
Standard = 0,
|
||||
Blocked = 1,
|
||||
Free = 2,
|
||||
Void = 3,
|
||||
Obstacle = 4,
|
||||
Water = 5,
|
||||
OutOfBounds = 6,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Bridge Direction Types
|
||||
/// </summary>
|
||||
public enum BridgeDirections : byte
|
||||
{
|
||||
Both = 0,
|
||||
A_To_B = 1,
|
||||
B_To_A = 2,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Who has right of way based on your moving direction
|
||||
/// </summary>
|
||||
public enum RightOfWay : byte
|
||||
{
|
||||
NorthWest = 0,
|
||||
SouthEast = 1,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// How agents try to avoid each other
|
||||
/// </summary>
|
||||
public enum AvoidenceType : byte
|
||||
{
|
||||
StopAndGo = 0,
|
||||
TryToPathAround = 1,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The seam connection side
|
||||
/// </summary>
|
||||
public enum SeamConnectionSide : byte
|
||||
{
|
||||
North = 0,
|
||||
West = 1,
|
||||
South = 2,
|
||||
East = 3,
|
||||
}
|
||||
|
||||
public enum DistanceCheck
|
||||
{
|
||||
Manhatten = 0,
|
||||
Distance = 1,
|
||||
SqrDistance,
|
||||
}
|
||||
|
||||
public enum MovementType
|
||||
{
|
||||
FourDirection = 0,
|
||||
EightDirection = 1,
|
||||
}
|
||||
|
||||
public enum PathfindingCalculationStep
|
||||
{
|
||||
Incomplete = 0,
|
||||
Pathfinding = 1,
|
||||
Complete = 2,
|
||||
Finalized = 3,
|
||||
}
|
||||
|
||||
public enum SimulationDebugLog
|
||||
{
|
||||
Log = 0,
|
||||
Warning = 1,
|
||||
Error = 2,
|
||||
}
|
||||
|
||||
public enum MapExpansionSide
|
||||
{
|
||||
Top = 0,
|
||||
Bottom = 1,
|
||||
Left = 2,
|
||||
Right = 3,
|
||||
}
|
||||
|
||||
public enum PainterTypes
|
||||
{
|
||||
Square = 0,
|
||||
Circle = 1,
|
||||
}
|
||||
|
||||
public enum ObstacleValidationStates : byte
|
||||
{
|
||||
Validated = 0,
|
||||
Invalidated = 1,
|
||||
Added = 2,
|
||||
}
|
||||
|
||||
public enum AgentStates : byte
|
||||
{
|
||||
Stopped = 0,
|
||||
Paused = 1,
|
||||
Pathfinding = 2,
|
||||
Moving = 3,
|
||||
FailedPathing = 4,
|
||||
SucceededPathing = 5,
|
||||
Idle = 6,
|
||||
}
|
||||
|
||||
public enum DestinationStates : byte
|
||||
{
|
||||
None = 0,
|
||||
SameMap = 1,
|
||||
Bridge = 2,
|
||||
NextMap_FromBridge = 3,
|
||||
ClosestPoint = 4,
|
||||
Null = 5,
|
||||
SamePosition = 6,
|
||||
Seam = 7,
|
||||
NextMap_FromSeam = 8,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e598b475ade85241be20aea419b3429
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2528b26349a8af24c93f6911e62a23fd
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,79 @@
|
||||
using HPJ.Simulation.Enums;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace HPJ.Simulation.Utilities
|
||||
{
|
||||
public static class Extensions
|
||||
{
|
||||
public static float Distance(this IntVector2 vector)
|
||||
{
|
||||
return (float)System.Math.Sqrt(vector.x * vector.x + vector.y * vector.y);
|
||||
}
|
||||
|
||||
public static int SqrDistance(this IntVector2 vector)
|
||||
{
|
||||
return vector.x * vector.x + vector.y * vector.y;
|
||||
}
|
||||
|
||||
public static string TilesToString(this TileTypes[] Tiles)
|
||||
{
|
||||
if (Tiles.Length == 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
string ReturnString = "";
|
||||
for(int i = 0; i < Tiles.Length - 1; i++)
|
||||
{
|
||||
ReturnString += $"{Tiles[i]}.";
|
||||
}
|
||||
ReturnString += $"{Tiles[Tiles.Length - 1]}.";
|
||||
|
||||
return ReturnString;
|
||||
}
|
||||
|
||||
public static string TilesToString(this List<TileTypes> Tiles)
|
||||
{
|
||||
if (Tiles.Count == 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
string ReturnString = "";
|
||||
for (int i = 0; i < Tiles.Count - 1; i++)
|
||||
{
|
||||
ReturnString += $"{Tiles[i]}.";
|
||||
}
|
||||
ReturnString += $"{Tiles[Tiles.Count - 1]}.";
|
||||
|
||||
return ReturnString;
|
||||
}
|
||||
|
||||
public static TileTypes[] StringToTilesArray(this string TilesStringArray)
|
||||
{
|
||||
string[] Split = TilesStringArray.Split('.');
|
||||
|
||||
if (Split.Length == 0)
|
||||
{
|
||||
return new TileTypes[1] { TileTypes.Free };
|
||||
}
|
||||
|
||||
TileTypes[] ReturnArr = new TileTypes[Split.Length];
|
||||
|
||||
string[] EnumNames = System.Enum.GetNames(typeof(TileTypes));
|
||||
for (int splitIndex = 0; splitIndex < Split.Length; splitIndex++)
|
||||
{
|
||||
for(int enumIndex = 0; enumIndex < EnumNames.Length; enumIndex++)
|
||||
{
|
||||
if (EnumNames[enumIndex] == Split[splitIndex])
|
||||
{
|
||||
ReturnArr[splitIndex] = (TileTypes)enumIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ReturnArr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf82f03bbe52cc14c8644aca8076615f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5b17713f3d6762747909224fe3c9184e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,59 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace HPJ.Simulation.Utilities
|
||||
{
|
||||
[System.Serializable]
|
||||
public class Pool<T>
|
||||
{
|
||||
public List<T> Active;
|
||||
public List<T> Inactive;
|
||||
|
||||
public Pool()
|
||||
{
|
||||
Active = new List<T>();
|
||||
Inactive = new List<T>();
|
||||
}
|
||||
|
||||
public T GetItem()
|
||||
{
|
||||
if (Inactive.Count > 0)
|
||||
{
|
||||
T Item = Inactive[0];
|
||||
Inactive.RemoveAt(0);
|
||||
return Item;
|
||||
}
|
||||
|
||||
return default(T);
|
||||
}
|
||||
|
||||
public void ReturnItem(T Item)
|
||||
{
|
||||
if (Active.Contains(Item))
|
||||
{
|
||||
Active.Remove(Item);
|
||||
Inactive.Add(Item);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddItem(T Item, bool AddToActiveList = true)
|
||||
{
|
||||
if (AddToActiveList)
|
||||
{
|
||||
Active.Add(Item);
|
||||
}
|
||||
else
|
||||
{
|
||||
Inactive.Add(Item);
|
||||
}
|
||||
}
|
||||
|
||||
public void ReturnAll()
|
||||
{
|
||||
for (int i = 0; i < Active.Count; i++)
|
||||
{
|
||||
Inactive.Add(Active[i]);
|
||||
}
|
||||
Active.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f8bf26b81289be840af5d4dfdb184443
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "HPJ_Simulation",
|
||||
"rootNamespace": "HPJ.Simulation",
|
||||
"references": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": true,
|
||||
"precompiledReferences": [
|
||||
"Newtonsoft.Json.dll"
|
||||
],
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": true
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2964754212fd90b4188341fc9783c7d6
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user