mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-06-27 03:44:54 +00:00
1308 lines
45 KiB
C#
1308 lines
45 KiB
C#
|
using HPJ.Simulation.Enums;
|
||
|
using HPJ.Simulation.Pathing;
|
||
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Linq;
|
||
|
|
||
|
namespace HPJ.Simulation.Map
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// The set of maps (base and redundant) that represent a specific area
|
||
|
/// </summary>
|
||
|
[Serializable]
|
||
|
public class MapSet
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// The Settings for this Map Set
|
||
|
/// </summary>
|
||
|
public MapSetSettings SetSettings = new MapSetSettings();
|
||
|
|
||
|
/// <summary>
|
||
|
/// The Instance ID to distinguish each map set apart
|
||
|
/// </summary>
|
||
|
public int InstanceID;
|
||
|
|
||
|
/// <summary>
|
||
|
/// Shows if this Map Set is initialized or not
|
||
|
/// </summary>
|
||
|
public bool Initialized { get; protected set; }
|
||
|
|
||
|
/// <summary>
|
||
|
/// The Base map that comes with each Map Set
|
||
|
/// </summary>
|
||
|
public Map BaseMap { get; protected set; }
|
||
|
|
||
|
/// <summary>
|
||
|
/// The Redundant Maps that help are used to help reduce queue times for each Navigation Agent
|
||
|
/// </summary>
|
||
|
public Map[] RedundantMaps { get; protected set; }
|
||
|
|
||
|
/// <summary>
|
||
|
/// The List of Bridges that connect to this Map Set
|
||
|
/// </summary>
|
||
|
public List<MapBridge> MapBridges { get; set; }
|
||
|
|
||
|
/// <summary>
|
||
|
/// The List of Seams that connect to this Map Set
|
||
|
/// </summary>
|
||
|
public List<MapSeam> MapSeams { get; set; }
|
||
|
|
||
|
/// <summary>
|
||
|
/// The Callback to links back up to Unity. Cannot use Debug.Log() in the simulation side of the navigation
|
||
|
/// </summary>
|
||
|
public Action<string, SimulationDebugLog> DebugLogCallback;
|
||
|
|
||
|
/// <summary>
|
||
|
/// The List of Key points around the border of the Map Set
|
||
|
/// </summary>
|
||
|
public List<IntVector3> KeyBorderPositions { get; set; }
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bottom Left Corner of the Map
|
||
|
/// </summary>
|
||
|
public IntVector3 BottomLeftPosition { get; set; }
|
||
|
|
||
|
/// <summary>
|
||
|
/// Left Center Position of the Map
|
||
|
/// </summary>
|
||
|
public IntVector3 LeftPosition { get; set; }
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bottom Center Position of the Map
|
||
|
/// </summary>
|
||
|
public IntVector3 BottomPosition { get; set; }
|
||
|
|
||
|
/// <summary>
|
||
|
/// Bottom Right Corner of the Map
|
||
|
/// </summary>
|
||
|
public IntVector3 BottomRightPosition { get; set; }
|
||
|
|
||
|
/// <summary>
|
||
|
/// Top Right Corner of the Map
|
||
|
/// </summary>
|
||
|
public IntVector3 TopRightPosition { get; set; }
|
||
|
|
||
|
/// <summary>
|
||
|
/// Right Center Position of the Map
|
||
|
/// </summary>
|
||
|
public IntVector3 RightPosition { get; set; }
|
||
|
|
||
|
/// <summary>
|
||
|
/// Top Center Position of the Map
|
||
|
/// </summary>
|
||
|
public IntVector3 TopPosition { get; set; }
|
||
|
|
||
|
/// <summary>
|
||
|
/// Top Left Corner of the Map
|
||
|
/// </summary>
|
||
|
public IntVector3 TopLeftPosition { get; set; }
|
||
|
|
||
|
/// <summary>
|
||
|
/// Middle Position of the Map Position of the Map
|
||
|
/// </summary>
|
||
|
public IntVector3 MiddlePosition { get; set; }
|
||
|
|
||
|
public MapSet()
|
||
|
{
|
||
|
MapBridges = new List<MapBridge>();
|
||
|
MapSeams = new List<MapSeam>();
|
||
|
OutgoingClaims = new Dictionary<IntVector2, TileOwnershipClaim>();
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Initilizes the Map Set
|
||
|
/// </summary>
|
||
|
/// <param name="Parrelism"></param>
|
||
|
/// <param name="Redundancy"></param>
|
||
|
/// <param name="CreateAgentMap"></param>
|
||
|
/// <param name="debugLogCallback"></param>
|
||
|
public void Initialize(int Parrelism, int Redundancy, bool CreateAgentMap, Action<string, SimulationDebugLog> debugLogCallback)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
DebugLogCallback = debugLogCallback;
|
||
|
|
||
|
Redundancy++;
|
||
|
RedundantMaps = new Map[Redundancy];
|
||
|
for (int i = 0; i < Redundancy; i++)
|
||
|
{
|
||
|
Map NewMap = new Map(SetSettings.MapSettings, $"{SetSettings.Name} - Map ({i})", Parrelism, CreateAgentMap);
|
||
|
NewMap.Initialize(debugLogCallback);
|
||
|
RedundantMaps[i] = NewMap;
|
||
|
}
|
||
|
BaseMap = RedundantMaps[0];
|
||
|
|
||
|
// Initialize Pathfinding
|
||
|
if (AStar.Instance == null)
|
||
|
{
|
||
|
AStar.Instance = new AStar();
|
||
|
}
|
||
|
if (JumpPointSearch.Instance == null)
|
||
|
{
|
||
|
JumpPointSearch.Instance = new JumpPointSearch();
|
||
|
}
|
||
|
KeyBorderPositions = new List<IntVector3>();
|
||
|
|
||
|
IntVector3 WorldTileMax = new IntVector3();
|
||
|
WorldTileMax.x = SetSettings.MapSettings.TileSize * SetSettings.MapSettings.MapWidth;
|
||
|
WorldTileMax.y = 0;
|
||
|
WorldTileMax.z = SetSettings.MapSettings.TileSize * SetSettings.MapSettings.MapHeight;
|
||
|
|
||
|
BottomLeftPosition = SetSettings.MapSettings.Offset;
|
||
|
KeyBorderPositions.Add(BottomLeftPosition);
|
||
|
BottomPosition = SetSettings.MapSettings.Offset + WorldTileMax.xVector() / 2;
|
||
|
KeyBorderPositions.Add(BottomPosition);
|
||
|
BottomRightPosition = SetSettings.MapSettings.Offset + WorldTileMax.xVector();
|
||
|
KeyBorderPositions.Add(BottomRightPosition);
|
||
|
|
||
|
LeftPosition = SetSettings.MapSettings.Offset + WorldTileMax.zVector() / 2;
|
||
|
KeyBorderPositions.Add(LeftPosition);
|
||
|
MiddlePosition = SetSettings.MapSettings.Offset + WorldTileMax.xzVector() / 2;
|
||
|
KeyBorderPositions.Add(MiddlePosition);
|
||
|
RightPosition = SetSettings.MapSettings.Offset + WorldTileMax.xVector() + WorldTileMax.zVector() / 2;
|
||
|
KeyBorderPositions.Add(RightPosition);
|
||
|
|
||
|
TopLeftPosition = SetSettings.MapSettings.Offset + WorldTileMax.zVector();
|
||
|
KeyBorderPositions.Add(TopLeftPosition);
|
||
|
TopPosition = SetSettings.MapSettings.Offset + WorldTileMax.xVector() / 2 + WorldTileMax.zVector();
|
||
|
KeyBorderPositions.Add(TopPosition);
|
||
|
TopRightPosition = SetSettings.MapSettings.Offset + WorldTileMax.xzVector();
|
||
|
KeyBorderPositions.Add(TopRightPosition);
|
||
|
|
||
|
Initialized = true;
|
||
|
}
|
||
|
catch (Exception ex)
|
||
|
{
|
||
|
debugLogCallback?.Invoke($"{ex.Message}: {ex.StackTrace}", SimulationDebugLog.Error);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void OnDestroy()
|
||
|
{
|
||
|
for (int i = 0; i < RedundantMaps.Length; i++)
|
||
|
{
|
||
|
RedundantMaps[i].OnDestroy();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Logs the debugs occured in the simulation
|
||
|
/// </summary>
|
||
|
/// <param name="Log"></param>
|
||
|
public void Log(string Log)
|
||
|
{
|
||
|
DebugLogCallback?.Invoke(Log, SimulationDebugLog.Log);
|
||
|
}
|
||
|
|
||
|
|
||
|
/// <summary>
|
||
|
/// Logs the warning occured in the simulation
|
||
|
/// </summary>
|
||
|
/// <param name="Log"></param>
|
||
|
public void LogWarning(string Log)
|
||
|
{
|
||
|
DebugLogCallback?.Invoke(Log, SimulationDebugLog.Warning);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Logs the errors occured in the simulation
|
||
|
/// </summary>
|
||
|
/// <param name="Log"></param>
|
||
|
public void LogError(string Log)
|
||
|
{
|
||
|
DebugLogCallback?.Invoke(Log, SimulationDebugLog.Error);
|
||
|
}
|
||
|
|
||
|
#region Pathfinding
|
||
|
|
||
|
private int _redundantMapCounter = -1;
|
||
|
/// <summary>
|
||
|
/// The Call a navigation job sends to the map to be calculated
|
||
|
/// </summary>
|
||
|
/// <param name="Job"></param>
|
||
|
public void SetDestination(NavigationJob Job)
|
||
|
{
|
||
|
_redundantMapCounter++;
|
||
|
if (_redundantMapCounter >= RedundantMaps.Length)
|
||
|
{
|
||
|
_redundantMapCounter = 0;
|
||
|
}
|
||
|
|
||
|
if (RedundantMaps.Length == 0)
|
||
|
{
|
||
|
LogWarning("Warning, No Maps to cast 'Set Destination On'");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
RedundantMaps[_redundantMapCounter].AddNavigationJob(Job);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Checks to see if this job is compatible with this map set. For example a job that has its start in another map is not compatible with this map set
|
||
|
/// </summary>
|
||
|
/// <param name="job"></param>
|
||
|
/// <returns></returns>
|
||
|
public bool JobCompatible(NavigationJob job)
|
||
|
{
|
||
|
if (BaseMap == null)
|
||
|
{
|
||
|
LogError($"Map {SetSettings.Name} Close Range is Null");
|
||
|
return false;
|
||
|
}
|
||
|
return BaseMap.JobCompatible(job);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Whether this index is out of range of the map
|
||
|
/// </summary>
|
||
|
/// <param name="newTilePosition"></param>
|
||
|
/// <returns></returns>
|
||
|
/// <exception cref="NotImplementedException"></exception>
|
||
|
public bool OutOfRange(IntVector2 newTilePosition)
|
||
|
{
|
||
|
if (newTilePosition.x < 0 || newTilePosition.y < 0)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (newTilePosition.x >= SetSettings.MapSettings.MapWidth || newTilePosition.y >= SetSettings.MapSettings.MapHeight)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region Map Changes
|
||
|
|
||
|
/// <summary>
|
||
|
/// The Call that changes the tiles on each map in the Map Set
|
||
|
/// </summary>
|
||
|
/// <param name="MapJob"></param>
|
||
|
public void ChangeMap(ChangeMapJob MapJob)
|
||
|
{
|
||
|
foreach (Map map in RedundantMaps)
|
||
|
{
|
||
|
map.AddMapChange(MapJob);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// A dictionary to keep track of the outgoing claims
|
||
|
/// </summary>
|
||
|
public Dictionary<IntVector2, TileOwnershipClaim> OutgoingClaims { get; protected set; }
|
||
|
|
||
|
/// <summary>
|
||
|
/// Requests to claim a tile
|
||
|
/// </summary>
|
||
|
/// <param name="Tile"></param>
|
||
|
/// <param name="AgentID"></param>
|
||
|
/// <returns></returns>
|
||
|
public bool AttemptClaim(IntVector2 Tile, ushort AgentID)
|
||
|
{
|
||
|
if (BaseMap.AgentOwnershipMap.Tiles[Tile.x, Tile.y] != 0)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (OutgoingClaims.ContainsKey(Tile))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
TileOwnershipClaim NewClaim = new TileOwnershipClaim(AgentID, Tile);
|
||
|
OutgoingClaims.Add(Tile, NewClaim);
|
||
|
Claim(NewClaim);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Disowns a claim to a tile
|
||
|
/// </summary>
|
||
|
/// <param name="Tile"></param>
|
||
|
/// <param name="AgentID"></param>
|
||
|
/// <returns></returns>
|
||
|
public bool DisownClaim(IntVector2 Tile, ushort AgentID)
|
||
|
{
|
||
|
if (BaseMap.AgentOwnershipMap.Tiles[Tile.x, Tile.y] != AgentID)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
DisownTileOwnership NewClaim = new DisownTileOwnership(AgentID, Tile);
|
||
|
foreach (Map map in RedundantMaps)
|
||
|
{
|
||
|
map.AddDisownmentClaim(NewClaim);
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Clears the list of claims
|
||
|
/// </summary>
|
||
|
public void ClearClaims()
|
||
|
{
|
||
|
OutgoingClaims.Clear();
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Adds a agent tile request claim for this map set
|
||
|
/// </summary>
|
||
|
/// <param name="Claim"></param>
|
||
|
protected void Claim(TileOwnershipClaim Claim)
|
||
|
{
|
||
|
foreach (Map map in RedundantMaps)
|
||
|
{
|
||
|
map.AddClaim(Claim);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
#region Helpers
|
||
|
|
||
|
/// <summary>
|
||
|
/// This Changed the DATA the Default data and makes all the tiles to the default tile type (TileTypes.Standard)
|
||
|
/// </summary>
|
||
|
public void CleanMapTiles()
|
||
|
{
|
||
|
SetSettings.MapSettings.MapInfo.CleanMap();
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// The Closest point on the map to the reach point
|
||
|
/// </summary>
|
||
|
/// <param name="reachPoint"></param>
|
||
|
/// <returns></returns>
|
||
|
public IntVector3 GetClosestPoint(IntVector3 reachPoint)
|
||
|
{
|
||
|
IntVector3 ClosestPoint = new IntVector3();
|
||
|
IntVector2 TileIndex = GetMapTileIndex(reachPoint);
|
||
|
|
||
|
ClosestPoint.y = reachPoint.y;
|
||
|
|
||
|
if (TileIndex.x < SetSettings.MapSettings.Offset.x)
|
||
|
{
|
||
|
ClosestPoint.x = SetSettings.MapSettings.Offset.x;
|
||
|
}
|
||
|
else if (TileIndex.x >= SetSettings.MapSettings.Offset.x + SetSettings.MapSettings.MapWidth)
|
||
|
{
|
||
|
ClosestPoint.x = SetSettings.MapSettings.Offset.x + SetSettings.MapSettings.MapWidth * SetSettings.MapSettings.TileSize - 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ClosestPoint.x = reachPoint.x;
|
||
|
}
|
||
|
|
||
|
if (TileIndex.y < SetSettings.MapSettings.Offset.z)
|
||
|
{
|
||
|
ClosestPoint.z = SetSettings.MapSettings.Offset.z;
|
||
|
}
|
||
|
else if (TileIndex.y >= SetSettings.MapSettings.Offset.z + SetSettings.MapSettings.MapHeight)
|
||
|
{
|
||
|
ClosestPoint.z = SetSettings.MapSettings.Offset.z + SetSettings.MapSettings.MapHeight * SetSettings.MapSettings.TileSize - 1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ClosestPoint.z = reachPoint.z;
|
||
|
}
|
||
|
|
||
|
return ClosestPoint;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// The Closest valid point to the reach point
|
||
|
/// </summary>
|
||
|
/// <param name="ClosestPoint"></param>
|
||
|
/// <param name="ValidTypes"></param>
|
||
|
/// <returns></returns>
|
||
|
public IntVector3 GetClosestValidPoint(IntVector3 ClosestPoint, TileTypes[] ValidTypes)
|
||
|
{
|
||
|
IntVector2 TileIndex = GetMapTileIndex(ClosestPoint);
|
||
|
|
||
|
int Radius = 1;
|
||
|
while (Radius <= 50)
|
||
|
{
|
||
|
for(int x = -Radius; x <= Radius; x++)
|
||
|
{
|
||
|
IntVector2 NewTileIndex = TileIndex + new IntVector2(x, Radius);
|
||
|
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return GetWorldTileIndex(NewTileIndex);
|
||
|
}
|
||
|
|
||
|
NewTileIndex = TileIndex + new IntVector2(x, -Radius);
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return GetWorldTileIndex(NewTileIndex);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (int y = -Radius; y <= Radius; y++)
|
||
|
{
|
||
|
IntVector2 NewTileIndex = TileIndex + new IntVector2(Radius, y);
|
||
|
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return GetWorldTileIndex(NewTileIndex);
|
||
|
}
|
||
|
|
||
|
NewTileIndex = TileIndex + new IntVector2(Radius, y);
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return GetWorldTileIndex(NewTileIndex);
|
||
|
}
|
||
|
}
|
||
|
Radius++;
|
||
|
}
|
||
|
|
||
|
return ClosestPoint;
|
||
|
}
|
||
|
|
||
|
|
||
|
/// <summary>
|
||
|
/// The Closest valid point to the reach point
|
||
|
/// </summary>
|
||
|
/// <param name="ClosestPoint"></param>
|
||
|
/// <param name="ValidTypes"></param>
|
||
|
/// <returns></returns>
|
||
|
public IntVector3 GetClosestValidPoint(IntVector3 ClosestPoint, List<TileTypes> ValidTypes)
|
||
|
{
|
||
|
IntVector2 TileIndex = GetMapTileIndex(ClosestPoint);
|
||
|
|
||
|
int Radius = 1;
|
||
|
while (Radius <= 50)
|
||
|
{
|
||
|
for (int x = -Radius; x <= Radius; x++)
|
||
|
{
|
||
|
IntVector2 NewTileIndex = TileIndex + new IntVector2(x, Radius);
|
||
|
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return GetWorldTileIndex(NewTileIndex);
|
||
|
}
|
||
|
|
||
|
NewTileIndex = TileIndex + new IntVector2(x, -Radius);
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return GetWorldTileIndex(NewTileIndex);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (int y = -Radius; y <= Radius; y++)
|
||
|
{
|
||
|
IntVector2 NewTileIndex = TileIndex + new IntVector2(Radius, y);
|
||
|
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return GetWorldTileIndex(NewTileIndex);
|
||
|
}
|
||
|
|
||
|
NewTileIndex = TileIndex + new IntVector2(Radius, y);
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return GetWorldTileIndex(NewTileIndex);
|
||
|
}
|
||
|
}
|
||
|
Radius++;
|
||
|
}
|
||
|
|
||
|
return ClosestPoint;
|
||
|
}
|
||
|
|
||
|
|
||
|
/// <summary>
|
||
|
/// The Closest valid point to the current tile index
|
||
|
/// </summary>
|
||
|
/// <param name="ClosestPoint"></param>
|
||
|
/// <param name="ValidTypes"></param>
|
||
|
/// <returns></returns>
|
||
|
public IntVector3 GetClosestValidPoint(IntVector2 CurrentTileIndex, TileTypes[] ValidTypes)
|
||
|
{
|
||
|
int Radius = 1;
|
||
|
while (Radius <= 50)
|
||
|
{
|
||
|
for (int x = -Radius; x <= Radius; x++)
|
||
|
{
|
||
|
IntVector2 NewTileIndex = CurrentTileIndex + new IntVector2(x, Radius);
|
||
|
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return GetWorldTileIndex(NewTileIndex);
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(x, -Radius);
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return GetWorldTileIndex(NewTileIndex);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (int y = -Radius; y <= Radius; y++)
|
||
|
{
|
||
|
IntVector2 NewTileIndex = CurrentTileIndex + new IntVector2(Radius, y);
|
||
|
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return GetWorldTileIndex(NewTileIndex);
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(Radius, y);
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return GetWorldTileIndex(NewTileIndex);
|
||
|
}
|
||
|
}
|
||
|
Radius++;
|
||
|
}
|
||
|
|
||
|
return GetWorldTileIndex(CurrentTileIndex);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// The Closest valid point to the current tile index
|
||
|
/// </summary>
|
||
|
/// <param name="ClosestPoint"></param>
|
||
|
/// <param name="ValidTypes"></param>
|
||
|
/// <returns></returns>
|
||
|
public IntVector3 GetClosestValidPoint(IntVector2 CurrentTileIndex, List<TileTypes> ValidTypes)
|
||
|
{
|
||
|
int Radius = 1;
|
||
|
while (Radius <= 50)
|
||
|
{
|
||
|
for (int x = -Radius; x <= Radius; x++)
|
||
|
{
|
||
|
IntVector2 NewTileIndex = CurrentTileIndex + new IntVector2(x, Radius);
|
||
|
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return GetWorldTileIndex(NewTileIndex);
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(x, -Radius);
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return GetWorldTileIndex(NewTileIndex);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (int y = -Radius; y <= Radius; y++)
|
||
|
{
|
||
|
IntVector2 NewTileIndex = CurrentTileIndex + new IntVector2(Radius, y);
|
||
|
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return GetWorldTileIndex(NewTileIndex);
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(Radius, y);
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return GetWorldTileIndex(NewTileIndex);
|
||
|
}
|
||
|
}
|
||
|
Radius++;
|
||
|
}
|
||
|
|
||
|
return GetWorldTileIndex(CurrentTileIndex);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// The Closest valid tile index to the current tile index
|
||
|
/// </summary>
|
||
|
/// <param name="ClosestPoint"></param>
|
||
|
/// <param name="ValidTypes"></param>
|
||
|
/// <returns></returns>
|
||
|
public IntVector2 GetClosestValidIndex(IntVector2 CurrentTileIndex, TileTypes[] ValidTypes)
|
||
|
{
|
||
|
int Radius = 1;
|
||
|
while (Radius <= 50)
|
||
|
{
|
||
|
for (int x = -Radius; x <= Radius; x++)
|
||
|
{
|
||
|
IntVector2 NewTileIndex = CurrentTileIndex + new IntVector2(x, Radius);
|
||
|
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(x, -Radius);
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (int y = -Radius; y <= Radius; y++)
|
||
|
{
|
||
|
IntVector2 NewTileIndex = CurrentTileIndex + new IntVector2(Radius, y);
|
||
|
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(Radius, y);
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
}
|
||
|
Radius++;
|
||
|
}
|
||
|
|
||
|
return CurrentTileIndex;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// The Closest valid tile index to the current tile index
|
||
|
/// </summary>
|
||
|
/// <param name="CurrentTileIndex"></param>
|
||
|
/// <param name="ValidTypes"></param>
|
||
|
/// <returns></returns>
|
||
|
public IntVector2 GetClosestValidIndex(IntVector2 CurrentTileIndex, List<TileTypes> ValidTypes)
|
||
|
{
|
||
|
int Radius = 1;
|
||
|
while (Radius <= 50)
|
||
|
{
|
||
|
for (int x = 0; x <= Radius; x++)
|
||
|
{
|
||
|
IntVector2 NewTileIndex = CurrentTileIndex + new IntVector2(x, Radius);
|
||
|
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(x, -Radius);
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(-x, Radius);
|
||
|
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(-x, -Radius);
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (int y = 0; y <= Radius; y++)
|
||
|
{
|
||
|
IntVector2 NewTileIndex = CurrentTileIndex + new IntVector2(Radius, y);
|
||
|
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(-Radius, y);
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(Radius, -y);
|
||
|
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(-Radius, -y);
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
}
|
||
|
Radius++;
|
||
|
}
|
||
|
|
||
|
return CurrentTileIndex;
|
||
|
}
|
||
|
/// <summary>
|
||
|
/// The Closest valid tile index to the current tile index
|
||
|
/// </summary>
|
||
|
/// <param name="CurrentTileIndex"></param>
|
||
|
/// <param name="ValidTypes"></param>
|
||
|
/// <param name="SimAgentID"></param>
|
||
|
/// <returns></returns>
|
||
|
public IntVector2 GetClosestValidIndex(IntVector2 CurrentTileIndex, List<TileTypes> ValidTypes, ushort SimAgentID)
|
||
|
{
|
||
|
int Radius = 1;
|
||
|
if (BaseMap.AgentAvoidence)
|
||
|
{
|
||
|
while (Radius <= 50)
|
||
|
{
|
||
|
for (int x = 0; x <= Radius; x++)
|
||
|
{
|
||
|
IntVector2 NewTileIndex = CurrentTileIndex + new IntVector2(x, Radius);
|
||
|
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)) && BaseMap.AgentOwnershipMap.ValidTileForAgent(SimAgentID, NewTileIndex.x, NewTileIndex.y))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(x, -Radius);
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)) && BaseMap.AgentOwnershipMap.ValidTileForAgent(SimAgentID, NewTileIndex.x, NewTileIndex.y))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(-x, Radius);
|
||
|
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)) && BaseMap.AgentOwnershipMap.ValidTileForAgent(SimAgentID, NewTileIndex.x, NewTileIndex.y))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(-x, -Radius);
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)) && BaseMap.AgentOwnershipMap.ValidTileForAgent(SimAgentID, NewTileIndex.x, NewTileIndex.y))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (int y = 0; y <= Radius; y++)
|
||
|
{
|
||
|
IntVector2 NewTileIndex = CurrentTileIndex + new IntVector2(Radius, y);
|
||
|
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)) && BaseMap.AgentOwnershipMap.ValidTileForAgent(SimAgentID, NewTileIndex.x, NewTileIndex.y))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(-Radius, y);
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)) && BaseMap.AgentOwnershipMap.ValidTileForAgent(SimAgentID, NewTileIndex.x, NewTileIndex.y))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(Radius, -y);
|
||
|
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)) && BaseMap.AgentOwnershipMap.ValidTileForAgent(SimAgentID, NewTileIndex.x, NewTileIndex.y))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(-Radius, -y);
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)) && BaseMap.AgentOwnershipMap.ValidTileForAgent(SimAgentID, NewTileIndex.x, NewTileIndex.y))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
}
|
||
|
Radius++;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
while (Radius <= 50)
|
||
|
{
|
||
|
for (int x = 0; x <= Radius; x++)
|
||
|
{
|
||
|
IntVector2 NewTileIndex = CurrentTileIndex + new IntVector2(x, Radius);
|
||
|
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(x, -Radius);
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(-x, Radius);
|
||
|
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(-x, -Radius);
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (int y = 0; y <= Radius; y++)
|
||
|
{
|
||
|
IntVector2 NewTileIndex = CurrentTileIndex + new IntVector2(Radius, y);
|
||
|
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(-Radius, y);
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(Radius, -y);
|
||
|
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
|
||
|
NewTileIndex = CurrentTileIndex + new IntVector2(-Radius, -y);
|
||
|
if (ValidTypes.Contains(GetTileType(NewTileIndex)))
|
||
|
{
|
||
|
return NewTileIndex;
|
||
|
}
|
||
|
}
|
||
|
Radius++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return CurrentTileIndex;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Gets the world tile index relative to the tile index of the map set
|
||
|
/// </summary>
|
||
|
/// <param name="newTileIndex"></param>
|
||
|
/// <param name="GetTileCenter"></param>
|
||
|
/// <returns></returns>
|
||
|
public IntVector3 GetWorldTileIndex(IntVector2 newTileIndex, bool GetTileCenter = true)
|
||
|
{
|
||
|
IntVector3 WorldTilePosition = new IntVector3();
|
||
|
|
||
|
WorldTilePosition.x = SetSettings.MapSettings.Offset.x + newTileIndex.x * SetSettings.MapSettings.TileSize;
|
||
|
WorldTilePosition.y = SetSettings.MapSettings.Offset.y;
|
||
|
WorldTilePosition.z = SetSettings.MapSettings.Offset.z + newTileIndex.y * SetSettings.MapSettings.TileSize;
|
||
|
|
||
|
if (GetTileCenter)
|
||
|
{
|
||
|
WorldTilePosition.x += SetSettings.MapSettings.TileSize / 2;
|
||
|
WorldTilePosition.z += SetSettings.MapSettings.TileSize / 2;
|
||
|
}
|
||
|
|
||
|
return WorldTilePosition;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Gets the world tile index relative to the tile index of the map set
|
||
|
/// </summary>
|
||
|
/// <param name="x"></param>
|
||
|
/// <param name="y"></param>
|
||
|
/// <param name="GetTileCenter"></param>
|
||
|
/// <returns></returns>
|
||
|
public IntVector3 GetWorldTileIndex(int x, int y, bool GetTileCenter = true)
|
||
|
{
|
||
|
IntVector3 WorldTilePosition = new IntVector3();
|
||
|
|
||
|
WorldTilePosition.x = SetSettings.MapSettings.Offset.x + x * SetSettings.MapSettings.TileSize;
|
||
|
WorldTilePosition.y = SetSettings.MapSettings.Offset.y;
|
||
|
WorldTilePosition.z = SetSettings.MapSettings.Offset.z + y * SetSettings.MapSettings.TileSize;
|
||
|
|
||
|
if (GetTileCenter)
|
||
|
{
|
||
|
WorldTilePosition.x += SetSettings.MapSettings.TileSize / 2;
|
||
|
WorldTilePosition.z += SetSettings.MapSettings.TileSize / 2;
|
||
|
}
|
||
|
|
||
|
return WorldTilePosition;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// This gets you the Tile Index of the Default Map
|
||
|
/// </summary>
|
||
|
/// <param name="WorldPosition"></param>
|
||
|
/// <returns></returns>
|
||
|
public IntVector2 GetMapTileIndex(IntVector3 WorldTileIndexPosition)
|
||
|
{
|
||
|
// Offset the Position
|
||
|
IntVector2 TileIndex = new IntVector2();
|
||
|
TileIndex.x = (int)Math.Floor((WorldTileIndexPosition.x - SetSettings.MapSettings.Offset.x) / (float)SetSettings.MapSettings.TileSize);
|
||
|
TileIndex.y = (int)Math.Floor((WorldTileIndexPosition.z - SetSettings.MapSettings.Offset.z) / (float)SetSettings.MapSettings.TileSize);
|
||
|
|
||
|
return TileIndex;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Checks to see if this point is on the Map
|
||
|
/// </summary>
|
||
|
/// <param name="hitTileIndexPosition"></param>
|
||
|
/// <returns></returns>
|
||
|
public bool PointInMap(IntVector3 hitTileIndexPosition)
|
||
|
{
|
||
|
if (hitTileIndexPosition.x < SetSettings.MapSettings.Offset.x || hitTileIndexPosition.z < SetSettings.MapSettings.Offset.z)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (hitTileIndexPosition.x >= SetSettings.MapSettings.Offset.x + SetSettings.MapSettings.MapWidth * SetSettings.MapSettings.TileSize || hitTileIndexPosition.z >= SetSettings.MapSettings.Offset.z + SetSettings.MapSettings.MapHeight * SetSettings.MapSettings.TileSize)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Checks to see if this point is on the Map
|
||
|
/// </summary>
|
||
|
/// <param name="hitTileIndexPosition"></param>
|
||
|
/// <returns></returns>
|
||
|
public bool PointInMap(IntVector2 TileIndex)
|
||
|
{
|
||
|
if (TileIndex.x < 0 || TileIndex.y < 0)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (TileIndex.x >= SetSettings.MapSettings.MapWidth || TileIndex.y >= SetSettings.MapSettings.MapHeight)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// This Changed the DATA the Default data, the maps that are generated on awake are not effected by this
|
||
|
/// </summary>
|
||
|
/// <param name="WorldPosition"></param>
|
||
|
/// <param name="NewType"></param>
|
||
|
public void ChangeDefaultTileType(IntVector3 WorldTileIndexPosition, TileTypes NewType, int Radius, PainterTypes painterType)
|
||
|
{
|
||
|
IntVector2 TileIndex = GetMapTileIndex(WorldTileIndexPosition);
|
||
|
|
||
|
if (painterType == PainterTypes.Square)
|
||
|
{
|
||
|
for (int x = -Radius; x <= Radius; x++)
|
||
|
{
|
||
|
for (int y = -Radius; y <= Radius; y++)
|
||
|
{
|
||
|
if (GetDefaultTileType(TileIndex.x + x, TileIndex.y + y) == TileTypes.OutOfBounds)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
SetSettings.MapSettings.MapInfo.SavedTiles[TileIndex.x + x, TileIndex.y + y] = (byte)NewType;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for (int x = -Radius; x <= Radius; x++)
|
||
|
{
|
||
|
for (int y = -Radius; y <= Radius; y++)
|
||
|
{
|
||
|
if (GetDefaultTileType(TileIndex.x + x, TileIndex.y + y) == TileTypes.OutOfBounds)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (x * x + y * y > Radius * Radius)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
SetSettings.MapSettings.MapInfo.SavedTiles[TileIndex.x + x, TileIndex.y + y] = (byte)NewType;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// This Changed the DATA the Default data, the maps that are generated on awake are not effected by this
|
||
|
/// </summary>
|
||
|
/// <param name="WorldPosition"></param>
|
||
|
/// <param name="NewType"></param>
|
||
|
public void ChangeDefaultTileType(int x, int y, TileTypes NewType)
|
||
|
{
|
||
|
if (GetDefaultTileType(x, y) == TileTypes.OutOfBounds)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
SetSettings.MapSettings.MapInfo.SavedTiles[x, y] = (byte)NewType;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// This gets you the Tile Type at a Index from the Default Map
|
||
|
/// </summary>
|
||
|
/// <param name="TileIndex"></param>
|
||
|
/// <returns></returns>
|
||
|
public TileTypes GetDefaultTileType(IntVector2 TileIndex)
|
||
|
{
|
||
|
if (TileIndex.x < 0 || TileIndex.y < 0 || TileIndex.x >= SetSettings.MapSettings.MapWidth || TileIndex.y >= SetSettings.MapSettings.MapHeight)
|
||
|
{
|
||
|
return TileTypes.OutOfBounds;
|
||
|
}
|
||
|
|
||
|
return (TileTypes)SetSettings.MapSettings.MapInfo.SavedTiles[TileIndex.x, TileIndex.y];
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// This gets you the Tile Type at a Index from the Default Map
|
||
|
/// </summary>
|
||
|
/// <param name="TileIndex"></param>
|
||
|
/// <returns></returns>
|
||
|
public TileTypes GetDefaultTileType(int x, int y)
|
||
|
{
|
||
|
if (x < 0 || y < 0 || x >= SetSettings.MapSettings.MapWidth || y >= SetSettings.MapSettings.MapHeight)
|
||
|
{
|
||
|
return TileTypes.OutOfBounds;
|
||
|
}
|
||
|
|
||
|
return (TileTypes)SetSettings.MapSettings.MapInfo.SavedTiles[x, y];
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// This gets you the Tile Type at a Index from the Map
|
||
|
/// </summary>
|
||
|
/// <param name="TileIndex"></param>
|
||
|
/// <returns></returns>
|
||
|
public TileTypes GetTileType(IntVector2 TileIndex)
|
||
|
{
|
||
|
if (TileIndex.x < 0 || TileIndex.y < 0 || TileIndex.x >= SetSettings.MapSettings.MapWidth || TileIndex.y >= SetSettings.MapSettings.MapHeight)
|
||
|
{
|
||
|
return TileTypes.OutOfBounds;
|
||
|
}
|
||
|
|
||
|
if (BaseMap == null)
|
||
|
{
|
||
|
return TileTypes.OutOfBounds;
|
||
|
}
|
||
|
|
||
|
return BaseMap.GetTileType(TileIndex);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// This gets you the Tile Type at a World Position Index from the Map
|
||
|
/// </summary>
|
||
|
/// <param name="TileIndex"></param>
|
||
|
/// <returns></returns>
|
||
|
public TileTypes GetTileType(IntVector3 worldTileIndex)
|
||
|
{
|
||
|
IntVector2 MapIndex = GetMapTileIndex(worldTileIndex);
|
||
|
return GetTileType(MapIndex);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// This gets you the Tile Type at a Index from the Default Map
|
||
|
/// </summary>
|
||
|
/// <param name="TileIndex"></param>
|
||
|
/// <returns></returns>
|
||
|
public TileTypes GetTileType(int x, int y)
|
||
|
{
|
||
|
if (x < 0 || y < 0 || x >= SetSettings.MapSettings.MapWidth || y >= SetSettings.MapSettings.MapHeight)
|
||
|
{
|
||
|
return TileTypes.OutOfBounds;
|
||
|
}
|
||
|
|
||
|
return BaseMap.GetTileType(x, y);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Adds the bridge if this bridge is connected to this Map
|
||
|
/// </summary>
|
||
|
/// <param name="bridge"></param>
|
||
|
public void AddBridge(MapBridge bridge)
|
||
|
{
|
||
|
if (RedundantMaps != null)
|
||
|
{
|
||
|
foreach (Map map in RedundantMaps)
|
||
|
{
|
||
|
if (!map.Bridges.Contains(bridge))
|
||
|
{
|
||
|
map.Bridges.Add(bridge);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!MapBridges.Contains(bridge))
|
||
|
{
|
||
|
MapBridges.Add(bridge);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Adds the seam if this seam is connected to this Map
|
||
|
/// </summary>
|
||
|
/// <param name="bridge"></param>
|
||
|
public void AddSeam(MapSeam seam)
|
||
|
{
|
||
|
if (RedundantMaps != null)
|
||
|
{
|
||
|
foreach (Map map in RedundantMaps)
|
||
|
{
|
||
|
if (!map.Seams.Contains(seam))
|
||
|
{
|
||
|
map.Seams.Add(seam);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!MapSeams.Contains(seam))
|
||
|
{
|
||
|
MapSeams.Add(seam);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Clears the Maps and the Bridges connected to this Map
|
||
|
/// </summary>
|
||
|
public void ClearMaps()
|
||
|
{
|
||
|
if (RedundantMaps != null)
|
||
|
{
|
||
|
foreach(Map map in RedundantMaps)
|
||
|
{
|
||
|
map.Bridges.Clear();
|
||
|
map.Seams.Clear();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
MapBridges.Clear();
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Finds the closest bridge that connects the destination Map
|
||
|
/// </summary>
|
||
|
/// <param name="nextMap"></param>
|
||
|
/// <param name="start"></param>
|
||
|
/// <returns></returns>
|
||
|
public MapBridge GetClosestBridge(MapSet nextMap, IntVector3 start)
|
||
|
{
|
||
|
MapBridge ClosestBridge = null;
|
||
|
int ClosestScore = int.MaxValue;
|
||
|
// Check for direct bridges first
|
||
|
foreach (MapBridge Bridge in MapBridges)
|
||
|
{
|
||
|
if (!Bridge.ValidBridge)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (Bridge.CanWalkInDirection(this, nextMap))
|
||
|
{
|
||
|
IntVector3 BridgePoint = Bridge.GetPoint(this);
|
||
|
int Distance = IntVector3.DistanceSquared(BridgePoint, start);
|
||
|
if (Distance < ClosestScore)
|
||
|
{
|
||
|
ClosestBridge = Bridge;
|
||
|
ClosestScore = Distance;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return ClosestBridge;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Finds the closest seam that connects the destination Map
|
||
|
/// </summary>
|
||
|
/// <param name="nextMap"></param>
|
||
|
/// <param name="start"></param>
|
||
|
/// <returns></returns>
|
||
|
public MapSeam GetClosestSeam(MapSet nextMap, IntVector3 start)
|
||
|
{
|
||
|
MapSeam ClosestSeam = null;
|
||
|
int ClosestScore = int.MaxValue;
|
||
|
// Check for direct bridges first
|
||
|
foreach (MapSeam Seam in MapSeams)
|
||
|
{
|
||
|
if (!Seam.ValidSeam)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (Seam.DirectConnects(this, nextMap))
|
||
|
{
|
||
|
IntVector3 BridgePoint = Seam.GetPoint(this, start);
|
||
|
int Distance = IntVector3.DistanceSquared(BridgePoint, start);
|
||
|
if (Distance < ClosestScore)
|
||
|
{
|
||
|
ClosestSeam = Seam;
|
||
|
ClosestScore = Distance;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return ClosestSeam;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Gets the closest Map Tile Index based on a tile index relative to this Map
|
||
|
/// </summary>
|
||
|
/// <param name="tileIndex"></param>
|
||
|
/// <returns></returns>
|
||
|
public IntVector2 GetClosestMapTileIndex(IntVector2 tileIndex)
|
||
|
{
|
||
|
if (tileIndex.x < 0)
|
||
|
{
|
||
|
tileIndex.x = 0;
|
||
|
}
|
||
|
else if (tileIndex.x >= SetSettings.MapSettings.MapWidth)
|
||
|
{
|
||
|
tileIndex.x = SetSettings.MapSettings.MapWidth - 1;
|
||
|
}
|
||
|
|
||
|
if (tileIndex.y < 0)
|
||
|
{
|
||
|
tileIndex.y = 0;
|
||
|
}
|
||
|
else if (tileIndex.y >= SetSettings.MapSettings.MapHeight)
|
||
|
{
|
||
|
tileIndex.y = SetSettings.MapSettings.MapHeight - 1;
|
||
|
}
|
||
|
|
||
|
return tileIndex;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Gets the closest Map Tile Index based on a tile index relative to this Map
|
||
|
/// </summary>
|
||
|
/// <param name="worldIndex"></param>
|
||
|
/// <returns></returns>
|
||
|
public IntVector2 GetClosestMapTileIndex(IntVector3 worldIndex)
|
||
|
{
|
||
|
IntVector2 tileIndex = GetMapTileIndex(worldIndex);
|
||
|
|
||
|
return GetClosestMapTileIndex(tileIndex);
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// The settings of the Map Set
|
||
|
/// </summary>
|
||
|
[Serializable]
|
||
|
public class MapSetSettings
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// The Name of the Map
|
||
|
/// </summary>
|
||
|
public string Name;
|
||
|
/// <summary>
|
||
|
/// The Settings for each Map on the Map Set
|
||
|
/// </summary>
|
||
|
public MapSettings MapSettings = new MapSettings();
|
||
|
|
||
|
public MapSetSettings()
|
||
|
{
|
||
|
Name = "No Name";
|
||
|
}
|
||
|
}
|
||
|
}
|