using HPJ.Simulation.Enums; using HPJ.Simulation.Pathing; using System; using System.Collections.Generic; using System.Linq; namespace HPJ.Simulation.Map { /// /// The set of maps (base and redundant) that represent a specific area /// [Serializable] public class MapSet { /// /// The Settings for this Map Set /// public MapSetSettings SetSettings = new MapSetSettings(); /// /// The Instance ID to distinguish each map set apart /// public int InstanceID; /// /// Shows if this Map Set is initialized or not /// public bool Initialized { get; protected set; } /// /// The Base map that comes with each Map Set /// public Map BaseMap { get; protected set; } /// /// The Redundant Maps that help are used to help reduce queue times for each Navigation Agent /// public Map[] RedundantMaps { get; protected set; } /// /// The List of Bridges that connect to this Map Set /// public List MapBridges { get; set; } /// /// The List of Seams that connect to this Map Set /// public List MapSeams { get; set; } /// /// The Callback to links back up to Unity. Cannot use Debug.Log() in the simulation side of the navigation /// public Action DebugLogCallback; /// /// The List of Key points around the border of the Map Set /// public List KeyBorderPositions { get; set; } /// /// Bottom Left Corner of the Map /// public IntVector3 BottomLeftPosition { get; set; } /// /// Left Center Position of the Map /// public IntVector3 LeftPosition { get; set; } /// /// Bottom Center Position of the Map /// public IntVector3 BottomPosition { get; set; } /// /// Bottom Right Corner of the Map /// public IntVector3 BottomRightPosition { get; set; } /// /// Top Right Corner of the Map /// public IntVector3 TopRightPosition { get; set; } /// /// Right Center Position of the Map /// public IntVector3 RightPosition { get; set; } /// /// Top Center Position of the Map /// public IntVector3 TopPosition { get; set; } /// /// Top Left Corner of the Map /// public IntVector3 TopLeftPosition { get; set; } /// /// Middle Position of the Map Position of the Map /// public IntVector3 MiddlePosition { get; set; } public MapSet() { MapBridges = new List(); MapSeams = new List(); OutgoingClaims = new Dictionary(); } /// /// Initilizes the Map Set /// /// /// /// /// public void Initialize(int Parrelism, int Redundancy, bool CreateAgentMap, Action 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 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(); } } /// /// Logs the debugs occured in the simulation /// /// public void Log(string Log) { DebugLogCallback?.Invoke(Log, SimulationDebugLog.Log); } /// /// Logs the warning occured in the simulation /// /// public void LogWarning(string Log) { DebugLogCallback?.Invoke(Log, SimulationDebugLog.Warning); } /// /// Logs the errors occured in the simulation /// /// public void LogError(string Log) { DebugLogCallback?.Invoke(Log, SimulationDebugLog.Error); } #region Pathfinding private int _redundantMapCounter = -1; /// /// The Call a navigation job sends to the map to be calculated /// /// 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); } /// /// 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 /// /// /// public bool JobCompatible(NavigationJob job) { if (BaseMap == null) { LogError($"Map {SetSettings.Name} Close Range is Null"); return false; } return BaseMap.JobCompatible(job); } /// /// Whether this index is out of range of the map /// /// /// /// 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 /// /// The Call that changes the tiles on each map in the Map Set /// /// public void ChangeMap(ChangeMapJob MapJob) { foreach (Map map in RedundantMaps) { map.AddMapChange(MapJob); } } /// /// A dictionary to keep track of the outgoing claims /// public Dictionary OutgoingClaims { get; protected set; } /// /// Requests to claim a tile /// /// /// /// 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; } /// /// Disowns a claim to a tile /// /// /// /// 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; } /// /// Clears the list of claims /// public void ClearClaims() { OutgoingClaims.Clear(); } /// /// Adds a agent tile request claim for this map set /// /// protected void Claim(TileOwnershipClaim Claim) { foreach (Map map in RedundantMaps) { map.AddClaim(Claim); } } #endregion #region Helpers /// /// This Changed the DATA the Default data and makes all the tiles to the default tile type (TileTypes.Standard) /// public void CleanMapTiles() { SetSettings.MapSettings.MapInfo.CleanMap(); } /// /// The Closest point on the map to the reach point /// /// /// 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; } /// /// The Closest valid point to the reach point /// /// /// /// 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; } /// /// The Closest valid point to the reach point /// /// /// /// public IntVector3 GetClosestValidPoint(IntVector3 ClosestPoint, List 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; } /// /// The Closest valid point to the current tile index /// /// /// /// 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); } /// /// The Closest valid point to the current tile index /// /// /// /// public IntVector3 GetClosestValidPoint(IntVector2 CurrentTileIndex, List 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); } /// /// The Closest valid tile index to the current tile index /// /// /// /// 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; } /// /// The Closest valid tile index to the current tile index /// /// /// /// public IntVector2 GetClosestValidIndex(IntVector2 CurrentTileIndex, List 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; } /// /// The Closest valid tile index to the current tile index /// /// /// /// /// public IntVector2 GetClosestValidIndex(IntVector2 CurrentTileIndex, List 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; } /// /// Gets the world tile index relative to the tile index of the map set /// /// /// /// 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; } /// /// Gets the world tile index relative to the tile index of the map set /// /// /// /// /// 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; } /// /// This gets you the Tile Index of the Default Map /// /// /// 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; } /// /// Checks to see if this point is on the Map /// /// /// 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; } /// /// Checks to see if this point is on the Map /// /// /// 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; } /// /// This Changed the DATA the Default data, the maps that are generated on awake are not effected by this /// /// /// 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; } } } } /// /// This Changed the DATA the Default data, the maps that are generated on awake are not effected by this /// /// /// public void ChangeDefaultTileType(int x, int y, TileTypes NewType) { if (GetDefaultTileType(x, y) == TileTypes.OutOfBounds) { return; } SetSettings.MapSettings.MapInfo.SavedTiles[x, y] = (byte)NewType; } /// /// This gets you the Tile Type at a Index from the Default Map /// /// /// 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]; } /// /// This gets you the Tile Type at a Index from the Default Map /// /// /// 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]; } /// /// This gets you the Tile Type at a Index from the Map /// /// /// 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); } /// /// This gets you the Tile Type at a World Position Index from the Map /// /// /// public TileTypes GetTileType(IntVector3 worldTileIndex) { IntVector2 MapIndex = GetMapTileIndex(worldTileIndex); return GetTileType(MapIndex); } /// /// This gets you the Tile Type at a Index from the Default Map /// /// /// 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); } /// /// Adds the bridge if this bridge is connected to this Map /// /// 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); } } /// /// Adds the seam if this seam is connected to this Map /// /// 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); } } /// /// Clears the Maps and the Bridges connected to this Map /// public void ClearMaps() { if (RedundantMaps != null) { foreach(Map map in RedundantMaps) { map.Bridges.Clear(); map.Seams.Clear(); } } MapBridges.Clear(); } /// /// Finds the closest bridge that connects the destination Map /// /// /// /// 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; } /// /// Finds the closest seam that connects the destination Map /// /// /// /// 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; } /// /// Gets the closest Map Tile Index based on a tile index relative to this Map /// /// /// 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; } /// /// Gets the closest Map Tile Index based on a tile index relative to this Map /// /// /// public IntVector2 GetClosestMapTileIndex(IntVector3 worldIndex) { IntVector2 tileIndex = GetMapTileIndex(worldIndex); return GetClosestMapTileIndex(tileIndex); } #endregion } /// /// The settings of the Map Set /// [Serializable] public class MapSetSettings { /// /// The Name of the Map /// public string Name; /// /// The Settings for each Map on the Map Set /// public MapSettings MapSettings = new MapSettings(); public MapSetSettings() { Name = "No Name"; } } }