public static ArrayGrid <T> MapToSubGrid <T>(this ArrayGrid <T> grid, Vector2Int sourceAreaPos, Vector2Int sourceAreaSize, Vector2Int subGridSize, bool clampOutOfBounds = true) { if (!clampOutOfBounds) { if (!grid.IsValidPosition(sourceAreaPos)) { return(new ArrayGrid <T>()); } if (!grid.IsValidPosition(sourceAreaPos + sourceAreaSize - Vector2Int.one)) { return(new ArrayGrid <T>()); } } else { sourceAreaPos.Clamp(Vector2Int.zero, grid.MaxValidPosition); Vector2Int sourceAreaMax = sourceAreaPos + sourceAreaSize; sourceAreaMax.Clamp(Vector2Int.zero, grid.Size); sourceAreaSize = sourceAreaMax - sourceAreaPos; if (sourceAreaSize.x <= 0 || sourceAreaSize.y <= 0) { return(new ArrayGrid <T>()); } } ArrayGrid <T> subGrid = new ArrayGrid <T>(subGridSize); var subGridIter = subGrid.GetEnumerator2D(); Vector2 scale = new Vector2((float)sourceAreaSize.x / subGridSize.x, (float)sourceAreaSize.y / subGridSize.y); while (subGridIter.MoveNext()) { Vector2Int subCurrent = subGridIter.Current; Vector2 scaledSubCurrent = new Vector2(subCurrent.x * scale.x, subCurrent.y * scale.y); Vector2Int sourcePos = sourceAreaPos + Vector2Int.FloorToInt(scaledSubCurrent); subGrid[subCurrent] = grid[sourcePos]; } return(subGrid); }
protected bool AddCorridor(ArrayGrid <MapElement> map, ArrayGrid <int> valueMap, KeyValuePair <Vector2Int, Vector2Int> closestCells, bool straightConnections = false) { if (!map.IsValidPosition(closestCells.Key) || !map.IsValidPosition(closestCells.Value)) { return(false); } // we start from both sides Vector2Int p0 = closestCells.Key; Vector2Int p1 = closestCells.Value; Vector2Int dir = new Vector2Int(p0.x > p1.x ? -1 : 1, p0.y > p1.y ? -1 : 1); bool firstHorizontal = GameRNG.CoinToss(); bool secondHorizontal = GameRNG.CoinToss(); for (; ;) { if (!straightConnections) { firstHorizontal = GameRNG.CoinToss(); secondHorizontal = GameRNG.CoinToss(); } // connect rooms dir.x = p0.x > p1.x ? -1 : 1; dir.y = p0.y > p1.y ? -1 : 1; if (p0.x != p1.x && p0.y != p1.y) { if (firstHorizontal) { p0.x += dir.x; } else { p0.y += dir.y; } } if (p0.x != p1.x && p0.y != p1.y) { if (secondHorizontal) { p1.x -= dir.x; } else { p1.y -= dir.y; } } if (valueMap[p0] == valueWall) { valueMap[p0] = valueHall; } if (valueMap[p1] == valueWall) { valueMap[p1] = valueHall; } // connect corridors if on the same level if (p0.x == p1.x) { dir.y = p0.y > p1.y ? -1 : 1; while (p0.y != p1.y) { p0.y += dir.y; if (valueMap[p0] == valueWall) { valueMap[p0] = valueHall; } } if (valueMap[p0] == valueWall) { valueMap[p0] = valueHall; } return(true); } if (p0.y == p1.y) { dir.x = p0.x > p1.x ? -1 : 1; while (p0.x != p1.x) { p0.x += dir.x; if (valueMap[p0] == valueWall) { valueMap[p0] = valueHall; } } if (valueMap[p0] == valueWall) { valueMap[p0] = valueHall; } return(true); } } //return true; }
bool GenerateMap(ArrayGrid <MapElement> map, ArrayGrid <int> valueMap) { map[map.CenterPosition] = defaultCorridorElement; Vector2Int s0 = Vector2Int.zero; Vector2 s1 = Vector2Int.zero; Vector2Int p = Vector2Int.zero; Vector2 d = Vector2Int.zero; int iterCount = map.Count / 3; for (int i = 0; i < iterCount; i++) { s1 = GameRNG.RandomPointOnCircle(map.Size.DivideBy(2)) + map.CenterPosition; d.x = strideLimitX.RandomNormalizedValue(); d.y = strideLimitY.RandomNormalizedValue(); d.x -= .5f; d.y -= .5f; int counter = 0; for (; ;) { //try again if (counter > maxTunnelIterations) { --i; break; } s1 += d; p = Vector2Int.FloorToInt(s1); p = map.Wrap(p); if (map.IsValidPosition(p) && map.GetAdjacentPositionsOfType(p, false, defaultCorridorElement).Count > 0) { map[p] = defaultCorridorElement; break; } } } if (placeRooms) { var areaIter = Mathnv.GetAreaEnumerator(Vector2Int.one, map.MaxValidPosition - Vector2Int.one); while (areaIter.MoveNext()) { Vector2Int current = areaIter.Current; Range limitX = new Range(map.w / 2 - strideLimitX.Min, map.w / 2 + strideLimitX.Min); Range limitY = new Range(map.h / 2 - strideLimitY.Min, map.h / 2 + strideLimitY.Min); if ((limitX.Contains(current.x) && limitY.Contains(current.y)) || map[current] == defaultWallElement) { continue; } int n = map.GetAdjacentPositionsOfType(current, false, defaultCorridorElement).Count; if (n == 1) { Rect room = new Rect(Vector2.zero, new Vector2(roomSizeX.RandomValuei(), roomSizeY.RandomValuei())); var roomIter = Mathnv.GetAreaEnumerator(Vector2Int.FloorToInt(room.min), Vector2Int.FloorToInt(room.max)); while (roomIter.MoveNext()) { Vector2Int rCurrent = roomIter.Current; map[current + rCurrent] = defaultRoomElement; } } } } return(true); }