Esempio n. 1
0
        /// <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);
                }
            }
        }
Esempio n. 2
0
        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);
        }