private void _connectTraversableTiles(Godot.Collections.Array tiles) { foreach (Vector2 tile in tiles) { // Add all neighbors for (int indexX = -1; indexX < 2; indexX++) { for (int indexY = -1; indexY < 2; indexY++) { Vector2 targetTile = new Vector2(tile.x + indexX, tile.y + indexY); int toId = getPointID((int)targetTile.x, (int)targetTile.y); int fromId = getPointID((int)tile.x, (int)tile.y); if (tile == targetTile || !_aStar.HasPoint(toId)) { // No need to add tile as it is the same continue; } // Caculate if diagonal point can be used // (this is to avoid to given a diagonal path to agent, but agent cannot pass as vertical/horizontal has obstacles) // Upper left/right diagonal (-1,1), (1,1) // which need (-1,0) (horizontal), (0,1) (veritcal), (1,0) (horizontal) // Bottom left/right diagonal (-1,-1), (1,-1) // which need (-1,0) (horizontal), (0,-1) (veritcal), (1,0) (horizontal) // this is to avoid stuck on corner if (indexX != 0 && indexY != 0) { int horizaontalId = getPointID((int)tile.x + indexX, (int)tile.y); int verticalId = getPointID((int)tile.x, (int)tile.y + indexY); // Upper diaonal connection depend on if there is obstacle for vertical/horizontal neighbors // If there are obstacles (i.e. point not exist, then not connect it) if (!_aStar.HasPoint(horizaontalId) || !_aStar.HasPoint(verticalId)) { continue; } } if (!_aStar.ArePointsConnected(fromId, toId)) { // Debug code if (debug) { Line2D line2d = new Line2D(); Vector2[] points = { (Vector2)_tilestoWorld[fromId], (Vector2)_tilestoWorld[toId] }; line2d.Points = points; _tileMap.AddChild(line2d); } _aStar.ConnectPoints(fromId, toId, true); } } } } }
// Called every time stabilizes (mode changes to RigidBody2D.MODE_STATIC). // // Once all rooms have stabilized it calculates a playable dungeon `_path` using the MST // algorithm. Based on the calculated `_path`, it populates `_data` with room and corridor tile // positions. // // It emits the "rooms_placed" signal when it finishes so we can begin the tileset placement. private void _on_Room_sleeping_state_changed() { GD.Print("_on_Room_sleeping_state_changed"); _sleepingRooms++; if (_sleepingRooms < MaxRooms) { return; } var mainRooms = new List <Room>(); var mainRoomsPositions = new List <Vector2>(); foreach (Room room in Rooms.GetChildren()) { if (IsMainRoom(room)) { mainRooms.Add(room); mainRoomsPositions.Add(room.Position); } } _path = Utils.MST(mainRoomsPositions); foreach (int point1Id in _path.GetPoints()) { foreach (int point2Id in _path.GetPoints()) { if (point1Id != point2Id && !_path.ArePointsConnected(point1Id, point2Id) && _rng.Randf() < ReconnectionFactor) { _path.ConnectPoints(point1Id, point2Id); } } } foreach (Room room in mainRooms) { AddRoom(room); } AddCorridors(); SetProcess(false); EmitSignal(nameof(RoomsPlaced)); }