private void InitializeSubMap(int islandId) { if (islandId > 0 && islandId <= numberOfIslands) { if (SubMaps.ContainsKey(islandId) == false) { Console.WriteLine($"Creating submap with island id: {islandId}"); SubMaps[islandId] = new SubMap(processedFullSizeMapDataForPathFinding, processedFullSizeMapDataForExploration, islandProcessedMapDataForPathFinding, islandId); } } }
public SubMap GetSubMap(Vector2 gridPosition, bool initializeIfNotPresent = false) { int islandId = TryGetIslandId((int)gridPosition.X, (int)gridPosition.Y); if (islandId == 0 || islandId == -1) { Console.WriteLine($"Unable to find any valid island id near pos: {gridPosition}."); return(null); } if (initializeIfNotPresent == true) { //InitializeSubMap(islandId); } SubMap subMap; bool gotSubMap = SubMaps.TryGetValue(islandId, out subMap); if (gotSubMap) { return(subMap); } return(null); }
private void IdIslands(byte[] rawMapData, int bytesPerRow, long cols, long rows) { var startTime = DateTime.Now; const int OutsideIslandsUnwalkable = -1; var baseMapArray = new byte[cols * Terrain.MapCellSizeI, rows *Terrain.MapCellSizeI]; Terrain.PopulatePathfindingGrid(rawMapData, bytesPerRow, cols, rows, baseMapArray); islandProcessedMapDataForPathFinding = new int[cols * Terrain.MapCellSizeI, rows *Terrain.MapCellSizeI]; var markArray = new int[cols * Terrain.MapCellSizeI, rows *Terrain.MapCellSizeI]; var floodSpiller = new FloodSpiller(); Predicate <int, int> positionQualifier = (x, y) => baseMapArray[x, y] == 0; var floodParameters = new FloodParameters(startX: 0, startY: 0) { ProcessStartAsFirstNeighbour = true, NeighbourhoodType = NeighbourhoodType.Eight, Qualifier = positionQualifier, NeighbourProcessor = (x, y, mark) => { islandProcessedMapDataForPathFinding[x, y] = OutsideIslandsUnwalkable; } }; floodSpiller.SpillFlood(floodParameters, markArray); int currentIslandId = 1; int currentStartX = 0; int currentStartY = 0; int sumOfCellsInCurrentIsland = 0; while (true) { var ret = GetPositionOfFirstMatchingValue(islandProcessedMapDataForPathFinding, 0); if (ret.Item1 == -1) { // done. No more islands break; } // add new submap SubMaps[currentIslandId] = new SubMap(currentIslandId, (int)cols * Terrain.MapCellSizeI, (int)rows * Terrain.MapCellSizeI); currentStartX = ret.Item1; currentStartY = ret.Item2; Predicate <int, int> positionQualifierIslands = (x, y) => islandProcessedMapDataForPathFinding[x, y] == 0; floodParameters = new FloodParameters(startX: currentStartX, startY: currentStartY) { ProcessStartAsFirstNeighbour = true, NeighbourhoodType = NeighbourhoodType.Eight, Qualifier = positionQualifierIslands, NeighbourProcessor = (x, y, mark) => { islandProcessedMapDataForPathFinding[x, y] = currentIslandId; if (processedFullSizeMapDataForPathFinding[x, y] == 1) { SubMaps[currentIslandId].SetExplorationGridValue(x, y, 1); SubMaps[currentIslandId].AddNodeWithPosition(x, y); } sumOfCellsInCurrentIsland += 1; } }; floodSpiller.SpillFlood(floodParameters, markArray); Console.WriteLine("Sum of current cells: {0}", sumOfCellsInCurrentIsland); if (sumOfCellsInCurrentIsland < 50) { SubMaps.Remove(currentIslandId); // erase the area. F.ex sarn ramparts has a few rogue walkable pixels in the middle of nowhere Predicate <int, int> eraseQualifier = (x, y) => islandProcessedMapDataForPathFinding[x, y] == currentIslandId; floodParameters = new FloodParameters(startX: currentStartX, startY: currentStartY) { ProcessStartAsFirstNeighbour = true, NeighbourhoodType = NeighbourhoodType.Eight, Qualifier = eraseQualifier, NeighbourProcessor = (x, y, mark) => { islandProcessedMapDataForPathFinding[x, y] = OutsideIslandsUnwalkable; } }; } else { SubMaps[currentIslandId].InitializeExploration(); currentIslandId += 1; } sumOfCellsInCurrentIsland = 0; } numberOfIslands = currentIslandId - 1; //SaveArrayAsImage(islandProcessedMapDataForPathFinding); Console.WriteLine($"Id islands took: {DateTime.Now.Subtract(startTime).TotalMilliseconds} milliseconds"); }