/// <summary> /// Equalises the gas by tile. /// </summary> /// <param name="tile">The tile to begin the check from.</param> /// <param name="leakFactor">How leaky should the equalization be.</param> public void EqualiseGasByTile(Tile tile, float leakFactor) { HashSet <Room> roomsDone = new HashSet <Room>(); foreach (Tile t in tile.GetNeighbours()) { // Skip tiles with a null room (i.e. outside). // TODO: Verify that gas still leaks to the outside // somehow. if (t.Room == null) { continue; } if (roomsDone.Contains(t.Room) == false) { foreach (Room r in roomsDone) { AtmosphereUtils.EqualizeRooms(t.Room, r, leakFactor); } roomsDone.Add(t.Room); } } }
protected Room ActualFloodFill(Tile sourceTile, Room oldRoom, int sizeOfOldRoom) { if (sourceTile == null) { // We are trying to flood fill off the map, so just return // without doing anything. return(null); } if (sourceTile.Room != oldRoom) { // This tile was already assigned to another "new" room, which means // that the direction picked isn't isolated. So we can just return // without creating a new room. return(null); } if (sourceTile.Furniture != null && sourceTile.Furniture.RoomEnclosure) { // This tile has a wall/door/whatever in it, so clearly // we can't do a room here. return(null); } // If we get to this point, then we know that we need to create a new room. HashSet <Room> listOfOldRooms = new HashSet <Room>(); Room newRoom = new Room(); Queue <Tile> tilesToCheck = new Queue <Tile>(); tilesToCheck.Enqueue(sourceTile); bool connectedToSpace = false; int processedTiles = 0; while (tilesToCheck.Count > 0) { Tile currentTile = tilesToCheck.Dequeue(); processedTiles++; if (currentTile.Room != newRoom) { if (currentTile.Room != null && listOfOldRooms.Contains(currentTile.Room) == false) { listOfOldRooms.Add(currentTile.Room); AtmosphereUtils.MovePercentageOfAtmosphere(currentTile.Room.Atmosphere, newRoom.Atmosphere, 1.0f); } newRoom.AssignTile(currentTile); Tile[] neighbors = currentTile.GetNeighbours(false, true); foreach (Tile neighborTile in neighbors) { if (neighborTile == null || neighborTile.HasClearLineToBottom()) { // We have hit open space (either by being the edge of the map or being an empty tile) // so this "room" we're building is actually part of the Outside. // Therefore, we can immediately end the flood fill (which otherwise would take ages) // and more importantly, we need to delete this "newRoom" and re-assign // all the tiles to Outside. connectedToSpace = true; } else { // We know t2 is not null nor is it an empty tile, so just make sure it // hasn't already been processed and isn't a "wall" type tile. if ( neighborTile.Room != newRoom && (neighborTile.Furniture == null || neighborTile.Furniture.RoomEnclosure == false)) { tilesToCheck.Enqueue(neighborTile); } } } } } if (connectedToSpace) { // All tiles that were found by this flood fill should // actually be "assigned" to outside. newRoom.ReturnTilesToOutsideRoom(); return(null); } // Copy data from the old room into the new room. if (oldRoom != null) { // In this case we are splitting one room into two or more, // so we can just copy the old gas ratios. // 1 is subtracted from size of old room to account for tile being filled by furniture, // this prevents gas from being lost float ratio = oldRoom.IsOutsideRoom() ? 0.0f : (float)newRoom.TileCount / (sizeOfOldRoom - 1); ////UnityDebugger.Debugger.Log("Splitting atmo between " + oldRoom.ID + " and " + newRoom.ID + ". " + newRoom.TileCount + " / " + (sizeOfOldRoom - 1) + " = " + ratio); AtmosphereUtils.MovePercentageOfAtmosphere(oldRoom.Atmosphere, newRoom.Atmosphere, ratio); } // Tell the world that a new room has been formed. Add(newRoom); return(newRoom); }