Exemple #1
0
        /// <summary>
        /// Run the reveal algorithm without invoking the invalidation mechanism.
        /// </summary>
        /// <param name="Data"></param>
        /// <param name="voxel"></param>
        public static void InitialReveal(
            ChunkManager Manager,
            ChunkData Data,
            VoxelHandle voxel)
        {
            // Fog of war must be on for the initial reveal to avoid artifacts.
            bool fogOfWar = GameSettings.Default.FogofWar;

            GameSettings.Default.FogofWar = true;

            var queue = new Queue <VoxelHandle>(128);

            queue.Enqueue(voxel);

            while (queue.Count > 0)
            {
                var v = queue.Dequeue();
                if (!v.IsValid)
                {
                    continue;
                }

                foreach (var neighborCoordinate in VoxelHelpers.EnumerateManhattanNeighbors(v.Coordinate))
                {
                    var neighbor = new VoxelHandle(Data, neighborCoordinate);
                    if (!neighbor.IsValid)
                    {
                        continue;
                    }
                    if (neighbor.IsExplored)
                    {
                        continue;
                    }

                    // We are skipping the invalidation mechanism but still need to trigger events.
                    Manager.NotifyChangedVoxel(new VoxelChangeEvent
                    {
                        Type  = VoxelChangeEventType.Explored,
                        Voxel = neighbor
                    });
                    neighbor.RawSetIsExplored();

                    if (neighbor.IsEmpty)
                    {
                        queue.Enqueue(neighbor);
                    }
                }

                v.RawSetIsExplored();
            }

            GameSettings.Default.FogofWar = fogOfWar;
        }
Exemple #2
0
        /// <summary>
        /// Run the reveal algorithm without invoking the invalidation mechanism.
        /// </summary>
        /// <param name="Data"></param>
        /// <param name="voxel"></param>
        public static void InitialReveal(
            ChunkData Data,
            VoxelHandle voxel)
        {
            // Fog of war must be on for the initial reveal to avoid artifacts.
            bool fogOfWar = GameSettings.Default.FogofWar;

            GameSettings.Default.FogofWar = true;

            var queue = new Queue <VoxelHandle>(128);

            queue.Enqueue(voxel);

            while (queue.Count > 0)
            {
                var v = queue.Dequeue();
                if (!v.IsValid)
                {
                    continue;
                }

                foreach (var neighborCoordinate in VoxelHelpers.EnumerateManhattanNeighbors(v.Coordinate))
                {
                    var neighbor = new VoxelHandle(Data, neighborCoordinate);
                    if (!neighbor.IsValid)
                    {
                        continue;
                    }
                    if (neighbor.IsExplored)
                    {
                        continue;
                    }

                    neighbor.Chunk.NotifyExplored(neighbor.Coordinate.GetLocalVoxelCoordinate());
                    neighbor.RawSetIsExplored(true);

                    if (neighbor.IsEmpty)
                    {
                        queue.Enqueue(neighbor);
                    }
                }

                v.RawSetIsExplored(true);
            }

            GameSettings.Default.FogofWar = fogOfWar;
        }
Exemple #3
0
        /// <summary>
        /// Creates a flat, wooden balloon port for the balloon to land on, and Dwarves to sit on.
        /// </summary>
        /// <param name="roomDes">The player's BuildRoom designator (so that we can create a balloon port)</param>
        /// <param name="chunkManager">The terrain handler</param>
        /// <param name="x">The position of the center of the balloon port</param>
        /// <param name="z">The position of the center of the balloon port</param>
        /// <param name="size">The size of the (square) balloon port in voxels on a side</param>
        public Room GenerateInitialBalloonPort(RoomBuilder roomDes, ChunkManager chunkManager, float x, float z,
                                               int size)
        {
            var centerCoordinate = GlobalVoxelCoordinate.FromVector3(new Vector3(x, VoxelConstants.ChunkSizeY - 1, z));

            var accumulator = 0;
            var count       = 0;

            for (var offsetX = -size; offsetX <= size; ++offsetX)
            {
                for (var offsetY = -size; offsetY <= size; ++offsetY)
                {
                    var topVoxel = VoxelHelpers.FindFirstVoxelBelowIncludeWater(
                        new VoxelHandle(chunkManager.ChunkData,
                                        centerCoordinate + new GlobalVoxelOffset(offsetX, 0, offsetY)));

                    if (topVoxel.Coordinate.Y > 0)
                    {
                        accumulator += topVoxel.Coordinate.Y + 1;
                        count       += 1;
                    }
                }
            }

            var averageHeight = (int)Math.Round(((float)accumulator / (float)count));

            if (StartUnderground)
            {
                accumulator = 0;
                count       = 0;
                List <string> illegalTypes = new List <string>()
                {
                    "Sand", "Dirt", "DarkDirt", "Ice"
                };
                for (var offsetX = -size; offsetX <= size; ++offsetX)
                {
                    for (var offsetY = -size; offsetY <= size; ++offsetY)
                    {
                        var topVoxel = VoxelHelpers.FindFirstVoxelBelow(
                            new VoxelHandle(chunkManager.ChunkData,
                                            centerCoordinate + new GlobalVoxelOffset(offsetX, 0, offsetY)));

                        if (topVoxel.Coordinate.Y > 0)
                        {
                            var vox = topVoxel;
                            for (int dy = topVoxel.Coordinate.Y; dy > 0; dy--)
                            {
                                vox = new VoxelHandle(chunkManager.ChunkData, new GlobalVoxelCoordinate(topVoxel.Coordinate.X, dy, topVoxel.Coordinate.Z));
                                if (vox.IsValid && !vox.IsEmpty && !illegalTypes.Contains(vox.Type.Name))
                                {
                                    break;
                                }
                            }
                            accumulator += vox.Coordinate.Y + 1;
                            count       += 1;
                        }
                    }
                }
                averageHeight = Math.Max((int)Math.Round(((float)accumulator / (float)count)) - 5, 0);
            }

            // Next, create the balloon port by deciding which voxels to fill.
            var balloonPortDesignations = new List <VoxelHandle>();
            var treasuryDesignations    = new List <VoxelHandle>();

            for (int dx = -size; dx <= size; dx++)
            {
                for (int dz = -size; dz <= size; dz++)
                {
                    Vector3 worldPos = new Vector3(centerCoordinate.X + dx, centerCoordinate.Y, centerCoordinate.Z + dz);

                    var baseVoxel = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle(
                                                                         chunkManager.ChunkData, GlobalVoxelCoordinate.FromVector3(worldPos)));

                    if (!baseVoxel.IsValid)
                    {
                        continue;
                    }

                    var h          = baseVoxel.Coordinate.Y + 1;
                    var localCoord = baseVoxel.Coordinate.GetLocalVoxelCoordinate();

                    for (int y = averageHeight; y < (StartUnderground ? averageHeight + 2 : h); y++)
                    {
                        var v = new VoxelHandle(baseVoxel.Chunk,
                                                new LocalVoxelCoordinate((int)localCoord.X, y, (int)localCoord.Z));
                        v.RawSetType(VoxelLibrary.GetVoxelType(0));
                        v.RawSetIsExplored();
                        v.QuickSetLiquid(LiquidType.None, 0);
                    }

                    if (averageHeight < h)
                    {
                        h = averageHeight;
                    }

                    bool isPosX = (dx == size && dz == 0);
                    bool isPosZ = (dz == size & dx == 0);
                    bool isNegX = (dx == -size && dz == 0);
                    bool isNegZ = (dz == -size && dz == 0);
                    bool isSide = (isPosX || isNegX || isPosZ || isNegZ);

                    Vector3 offset = Vector3.Zero;

                    if (isSide)
                    {
                        if (isPosX)
                        {
                            offset = Vector3.UnitX;
                        }
                        else if (isPosZ)
                        {
                            offset = Vector3.UnitZ;
                        }
                        else if (isNegX)
                        {
                            offset = -Vector3.UnitX;
                        }
                        else if (isNegZ)
                        {
                            offset = -Vector3.UnitZ;
                        }
                    }

                    bool encounteredFilled = false;
                    // Fill from the top height down to the bottom.
                    for (int y = Math.Min(0, h - 1); y < averageHeight && y < VoxelConstants.ChunkSizeY; y++)
                    {
                        var v = new VoxelHandle(baseVoxel.Chunk,
                                                new LocalVoxelCoordinate((int)localCoord.X, y, (int)localCoord.Z));
                        if (!v.IsValid)
                        {
                            throw new InvalidProgramException("Voxel was invalid while creating a new game's initial zones. This should not happen.");
                        }

                        v.RawSetType(VoxelLibrary.GetVoxelType("Scaffold"));
                        v.IsPlayerBuilt = true;
                        v.QuickSetLiquid(LiquidType.None, 0);

                        if (y == averageHeight - 1)
                        {
                            v.RawSetIsExplored();

                            if (dz >= 0)
                            {
                                balloonPortDesignations.Add(v);
                            }
                            else
                            {
                                treasuryDesignations.Add(v);
                            }
                        }

                        if (isSide && !encounteredFilled)
                        {
                            var ladderPos = new Vector3(worldPos.X, y, worldPos.Z) + offset +
                                            Vector3.One * 0.5f;
                            var ladderVox = new VoxelHandle(chunkManager.ChunkData,
                                                            GlobalVoxelCoordinate.FromVector3(ladderPos));
                            if (ladderVox.IsValid && ladderVox.IsEmpty)
                            {
                                var ladder = EntityFactory.CreateEntity <Ladder>("Ladder", ladderPos);
                                Master.Faction.OwnedObjects.Add(ladder);
                                ladder.Tags.Add("Moveable");
                                ladder.Tags.Add("Deconstructable");
                            }
                            else
                            {
                                encounteredFilled = true;
                            }
                        }
                    }
                }
            }

            // Actually create the BuildRoom.
            var toBuild = RoomLibrary.CreateRoom(PlayerFaction, "Balloon Port", this);

            roomDes.DesignatedRooms.Add(toBuild);
            RoomLibrary.CompleteRoomImmediately(toBuild, balloonPortDesignations);

            // Also add a treasury
            var treasury = RoomLibrary.CreateRoom(PlayerFaction, "Treasury", this);

            roomDes.DesignatedRooms.Add(treasury);
            RoomLibrary.CompleteRoomImmediately(treasury, treasuryDesignations);

            return(toBuild);
        }