public void CreateInitialEmbarkment(Generation.ChunkGeneratorSettings Settings)
        {
            // If no file exists, we have to create the balloon and balloon port.
            if (!string.IsNullOrEmpty(Settings.Overworld.InstanceSettings.ExistingFile))
            {
                return;                                                                          // Todo: Don't call in the first place??
            }
            var port = GenerateInitialBalloonPort(Renderer.Camera.Position.X, Renderer.Camera.Position.Z, 1, Settings);

            PlayerFaction.Economy.Funds = Settings.Overworld.InstanceSettings.InitalEmbarkment.Funds;
            Settings.Overworld.PlayerCorporationFunds -= Settings.Overworld.InstanceSettings.InitalEmbarkment.Funds;
            Settings.Overworld.PlayerCorporationFunds -= Settings.Overworld.InstanceSettings.CalculateLandValue();

            foreach (var res in Settings.Overworld.InstanceSettings.InitalEmbarkment.Resources.Enumerate())
            {
                AddResources(res);
                Settings.Overworld.PlayerCorporationResources.Remove(res);
            }

            var portBox = port.GetBoundingBox();

            ComponentManager.RootComponent.AddChild(Balloon.CreateBalloon(
                                                        portBox.Center() + new Vector3(0, 100, 0),
                                                        portBox.Center() + new Vector3(0, 10, 0), ComponentManager,
                                                        PlayerFaction));

            foreach (var applicant in Settings.Overworld.InstanceSettings.InitalEmbarkment.Employees)
            {
                Settings.Overworld.PlayerCorporationFunds -= applicant.SigningBonus;
                HireImmediately(applicant);
            }

            Renderer.Camera.Target   = portBox.Center();
            Renderer.Camera.Position = Renderer.Camera.Target + new Vector3(0, 15, -15);
        }
Пример #2
0
        public static void CastSunlightColumn(int X, int Z, ChunkGeneratorSettings Settings)
        {
            for (var y = (Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY) - 1; y >= 0; y--)
            {
                var v = Settings.World.ChunkManager.CreateVoxelHandle(new GlobalVoxelCoordinate(X, y, Z));
                if (!v.IsValid)
                {
                    break;
                }
                v.Sunlight = true;
                v.RawSetIsExplored();

                if (v.Type.ID != 0 && !v.Type.IsTransparent)
                {
                    break;
                }
                else
                {
                    foreach (var neighbor in VoxelHelpers.EnumerateManhattanNeighbors2D(v.Coordinate))
                    {
                        var nv = Settings.World.ChunkManager.CreateVoxelHandle(neighbor);
                        if (nv.IsValid)
                        {
                            nv.RawSetIsExplored();
                        }
                    }
                }
            }
        }
Пример #3
0
        public static void GenerateWater(VoxelChunk chunk, ChunkGeneratorSettings Settings)
        {
            var iceID = Library.GetVoxelType("Ice");

            for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x)
            {
                for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z)
                {
                    if (Settings.Overworld.Map.GetBiomeAt(new Vector3(x, 0, z) + chunk.Origin.ToVector3(), Settings.Overworld.InstanceSettings.Origin).HasValue(out var biome))
                    {
                        for (var y = 0; y < VoxelConstants.ChunkSizeY; ++y)
                        {
                            var globalY = y + chunk.Origin.Y;
                            if (globalY > Settings.NormalizedSeaLevel)
                            {
                                break;
                            }

                            var voxel = VoxelHandle.UnsafeCreateLocalHandle(chunk, new LocalVoxelCoordinate(x, y, z));
                            if (voxel.IsEmpty && voxel.Sunlight)
                            {
                                if (globalY == Settings.NormalizedSeaLevel && biome.WaterSurfaceIce)
                                {
                                    voxel.RawSetType(iceID);
                                }
                                else
                                {
                                    voxel.QuickSetLiquid(biome.WaterIsLava ? LiquidType.Lava : LiquidType.Water, WaterManager.maxWaterLevel);
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #4
0
        public static float GetAverageHeight(int X, int Z, int Width, int Height, ChunkGeneratorSettings Settings)
        {
            var avgHeight = 0;
            var numHeight = 0;

            for (var dx = 0; dx < Width; dx++)
            {
                for (var dz = 0; dz < Height; dz++)
                {
                    var worldPos  = new Vector3(X + dx, (Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY) - 1, Z + dz);
                    var baseVoxel = VoxelHelpers.FindFirstVoxelBelowIncludingWater(Settings.World.ChunkManager.CreateVoxelHandle(GlobalVoxelCoordinate.FromVector3(worldPos)));

                    if (!baseVoxel.IsValid)
                    {
                        continue;
                    }

                    avgHeight += baseVoxel.Coordinate.Y + 1;
                    numHeight += 1;
                }
            }

            if (numHeight == 0)
            {
                return(0);
            }
            return(avgHeight / numHeight);
        }
Пример #5
0
        public static void GenerateCaveFauna(VoxelHandle CaveFloor, BiomeData Biome, ChunkGeneratorSettings Settings)
        {
            var spawnLikelihood = (Settings.Overworld.Difficulty.CombatModifier + 0.1f);

            foreach (var animalType in Biome.Fauna)
            {
                if (!(MathFunctions.Random.NextDouble() < animalType.SpawnProbability * spawnLikelihood))
                {
                    continue;
                }

                var lambdaAnimalType = animalType;

                if (!GameSettings.Current.FogofWar)
                {
                    EntityFactory.CreateEntity <GameComponent>(lambdaAnimalType.Name, CaveFloor.WorldPosition + new Vector3(0.5f, 1.5f, 0.5f));
                }
                else
                {
                    Settings.World.ComponentManager.RootComponent.AddChild(new SpawnOnExploredTrigger(Settings.World.ComponentManager, CaveFloor)
                    {
                        EntityToSpawn = lambdaAnimalType.Name,
                        SpawnLocation = CaveFloor.WorldPosition + new Vector3(0.5f, 1.5f, 0.5f)
                    });
                }

                break; // Prevent spawning multiple animals in same spot.
            }
        }
Пример #6
0
        public void CreateInitialEmbarkment(Generation.ChunkGeneratorSettings Settings)
        {
            PlayerFaction.Economy.Funds = Settings.Overworld.InstanceSettings.InitalEmbarkment.Funds;
            Settings.Overworld.PlayerCorporationFunds -= Settings.Overworld.InstanceSettings.InitalEmbarkment.Funds;
            Settings.Overworld.PlayerCorporationFunds -= Settings.Overworld.InstanceSettings.CalculateLandValue();

            foreach (var res in Settings.Overworld.InstanceSettings.InitalEmbarkment.Resources.Enumerate())
            {
                AddResources(res);
                Settings.Overworld.PlayerCorporationResources.Remove(res);
            }

            if (GenerateInitialBalloonPort(Renderer.Camera.Position.X, Renderer.Camera.Position.Z, 1, Settings).HasValue(out var port))
            {
                var portBox = port.GetBoundingBox();

                ComponentManager.RootComponent.AddChild(Balloon.CreateBalloon( // Bypassing the entity factory because we need to set the target.
                                                            portBox.Center() + new Vector3(0, 10, 0),
                                                            portBox.Center() + new Vector3(0, 10, 0), ComponentManager,
                                                            PlayerFaction));

                Renderer.Camera.Target   = portBox.Center();
                Renderer.Camera.Position = Renderer.Camera.Target + new Vector3(0, 15, -15);
            }

            foreach (var applicant in Settings.Overworld.InstanceSettings.InitalEmbarkment.Employees)
            {
                Settings.Overworld.PlayerCorporationFunds -= applicant.SigningBonus;
                HireImmediately(applicant);
            }
        }
Пример #7
0
        public static void GenerateOres(VoxelChunk Chunk, ChunkGeneratorSettings Settings)
        {
            for (int x = 0; x < VoxelConstants.ChunkSizeX; x++)
            {
                for (int z = 0; z < VoxelConstants.ChunkSizeZ; z++)
                {
                    var overworldPosition = OverworldMap.WorldToOverworld(new Vector2(x + Chunk.Origin.X, z + Chunk.Origin.Z), Settings.Overworld.InstanceSettings.Origin);

                    var normalizedHeight = NormalizeHeight(Settings.Overworld.Map.LinearInterpolate(overworldPosition, OverworldField.Height));
                    var height           = MathFunctions.Clamp(normalizedHeight * Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY, 0.0f, Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY - 2);

                    for (int y = 0; y < VoxelConstants.ChunkSizeY; y++)
                    {
                        if (Chunk.Origin.Y + y >= height)
                        {
                            break;
                        }
                        if (Chunk.Origin.Y + y == 0)
                        {
                            continue;
                        }

                        var v = Chunk.Manager.CreateVoxelHandle(new GlobalVoxelCoordinate(Chunk.Origin.X + x, Chunk.Origin.Y + y, Chunk.Origin.Z + z));
                        if (v.Sunlight)
                        {
                            continue;
                        }

                        foreach (var voxelType in Library.EnumerateVoxelTypes())
                        {
                            if (voxelType.SpawnClusters)
                            {
                                if (Chunk.Origin.Y + y < voxelType.MinSpawnHeight)
                                {
                                    continue;
                                }
                                if (Chunk.Origin.Y + y > voxelType.MaxSpawnHeight)
                                {
                                    continue;
                                }

                                var vRand       = new Random(voxelType.ID);
                                var noiseVector = new Vector3(Chunk.Origin.X + x, Chunk.Origin.Y + y, Chunk.Origin.Z + z) * Settings.CaveNoiseScale * 2.0f;
                                noiseVector += new Vector3(vRand.Next(0, 64), vRand.Next(0, 64), vRand.Next(0, 64));

                                var fade = 1.0f - ((Chunk.Origin.Y + y - voxelType.MinSpawnHeight) / voxelType.MaxSpawnHeight);

                                var oreNoise = Settings.CaveNoise.GetValue(noiseVector.X, noiseVector.Y, noiseVector.Z);

                                if (Math.Abs(oreNoise) < voxelType.Rarity * fade)
                                {
                                    v.RawSetType(voxelType);
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #8
0
 public static void CastSunlight(VoxelChunk TopChunk, ChunkGeneratorSettings Settings)
 {
     for (var x = TopChunk.Origin.X; x < TopChunk.Origin.X + VoxelConstants.ChunkSizeX; x++)
     {
         for (var z = TopChunk.Origin.Z; z < TopChunk.Origin.Z + VoxelConstants.ChunkSizeZ; z++)
         {
             CastSunlightColumn(x, z, Settings);
         }
     }
 }
Пример #9
0
        private static void FillRuinColumn(ChunkGeneratorSettings Settings, MaybeNull <VoxelType> WallType, int gap, int wallHeight, VoxelHandle baseVoxel, float decay)
        {
            for (int dy = gap; dy < wallHeight * (1.0f - decay) && dy < (Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY) - 2; dy++)
            {
                var currVoxel = Settings.World.ChunkManager.CreateVoxelHandle(baseVoxel.Coordinate + new GlobalVoxelOffset(0, dy, 0));

                if (currVoxel.IsValid)
                {
                    currVoxel.RawSetType(WallType);
                }
            }
        }
Пример #10
0
        private static void FillBelowRuins(ChunkGeneratorSettings Settings, MaybeNull <VoxelType> ruinWallType, VoxelHandle baseVoxel, VoxelHandle underVoxel)
        {
            for (int dy = 1; dy < (baseVoxel.Coordinate.Y - underVoxel.Coordinate.Y); dy++)
            {
                var currVoxel = Settings.World.ChunkManager.CreateVoxelHandle(underVoxel.Coordinate + new GlobalVoxelOffset(0, dy, 0));

                if (!currVoxel.IsValid)
                {
                    continue;
                }

                currVoxel.RawSetType(ruinWallType);
            }

            underVoxel.RawSetGrass(0);
        }
Пример #11
0
        public static Zone GenerateInitialBalloonPort(float x, float z, int size, Generation.ChunkGeneratorSettings Settings)
        {
            var roomVoxels = Generation.Generator.GenerateBalloonPort(Settings.World.ChunkManager, x, z, size, Settings);

            // Actually create the BuildRoom.
            var toBuild = Library.CreateZone("Balloon Port", Settings.World);

            Settings.World.AddZone(toBuild);
            toBuild.CompleteRoomImmediately(roomVoxels.StockpileVoxels);

            var box  = toBuild.GetBoundingBox();
            var at   = new Vector3((box.Min.X + box.Max.X - 1) / 2, box.Max.Y, (box.Min.Z + box.Max.Z - 1) / 2);
            var flag = EntityFactory.CreateEntity <Flag>("Flag", at + new Vector3(0.5f, 0.5f, 0.5f));

            Settings.World.PlayerFaction.OwnedObjects.Add(flag);

            return(toBuild);
        }
Пример #12
0
        public static void GenerateLava(VoxelChunk chunk, ChunkGeneratorSettings Settings)
        {
            if (chunk.Origin.Y >= Settings.LavaLevel)
            {
                return;
            }

            for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x)
            {
                for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z)
                {
                    for (var y = 0; y < Settings.LavaLevel - chunk.Origin.Y; ++y)
                    {
                        var voxel = VoxelHandle.UnsafeCreateLocalHandle(chunk, new LocalVoxelCoordinate(x, y, z));
                        if (voxel.IsEmpty && voxel.LiquidLevel == 0)
                        {
                            voxel.QuickSetLiquid(LiquidType.Lava, WaterManager.maxWaterLevel);
                        }
                    }
                }
            }
        }
        private void CreateNewWorld()
        {
            SetLoadingMessage("Creating Sky...");

            Renderer.Sky = new SkyRenderer();


            #region Initialize static data

            bool actionComplete = false;

            Game.DoLazyAction(new Action(() =>
            {
                Renderer.InstanceRenderer = new InstanceRenderer();

                Renderer.bloom = new BloomComponent(Game)
                {
                    Settings = BloomSettings.PresetSettings[5]
                };
                Renderer.bloom.Initialize();

                SoundManager.Content = Content;
                if (PlanService != null)
                {
                    PlanService.Restart();
                }

                MonsterSpawner = new MonsterSpawner(this);
                EntityFactory.Initialize(this);
            }), () => { actionComplete = true; return(true); });

            while (!actionComplete)
            {
                Thread.Sleep(10);
            }

            #endregion


            SetLoadingMessage("Creating Planner ...");
            PlanService = new PlanService();


            SetLoadingMessage("Creating Liquids ...");

            #region liquids

            Renderer.WaterRenderer = new WaterRenderer(GraphicsDevice);

            #endregion

            #region Load Components

            // Create updateable systems.
            foreach (var updateSystemFactory in AssetManager.EnumerateModHooks(typeof(UpdateSystemFactoryAttribute), typeof(EngineModule), new Type[] { typeof(WorldManager) }))
            {
                UpdateSystems.Add(updateSystemFactory.Invoke(null, new Object[] { this }) as EngineModule);
            }

            Time = new WorldTime();

            Renderer.Camera = new OrbitCamera(this, // Todo: Is setting the camera position and target redundant here?
                                              new Vector3(VoxelConstants.ChunkSizeX,
                                                          WorldSizeInVoxels.Y - 1.0f,
                                                          VoxelConstants.ChunkSizeZ),
                                              new Vector3(VoxelConstants.ChunkSizeX, WorldSizeInVoxels.Y - 1.0f,
                                                          VoxelConstants.ChunkSizeZ) +
                                              Vector3.Up * 10.0f + Vector3.Backward * 10,
                                              MathHelper.PiOver4, GraphicsDevice.Viewport.AspectRatio, 0.1f,
                                              GameSettings.Default.VertexCullDistance);

            PersistentData = new PersistentWorldData();
            ChunkManager   = new ChunkManager(Content, this);
            Splasher       = new Splasher(ChunkManager);

            Renderer.ChunkRenderer = new ChunkRenderer(ChunkManager);

            Renderer.Camera.Position = new Vector3(0, 10, 0) + new Vector3(WorldSizeInChunks.X * VoxelConstants.ChunkSizeX, 0, WorldSizeInChunks.Z * VoxelConstants.ChunkSizeZ) * 0.5f;
            Renderer.Camera.Target   = new Vector3(0, 10, 1) + new Vector3(WorldSizeInChunks.X * VoxelConstants.ChunkSizeX, 0, WorldSizeInChunks.Z * VoxelConstants.ChunkSizeZ) * 0.5f;

            ComponentManager = new ComponentManager(this);
            ComponentManager.SetRootComponent(new GameComponent(ComponentManager, "root", Matrix.Identity, Vector3.Zero, Vector3.Zero));

            #region Prepare Factions

            Factions = new FactionSet();
            //Factions.Initialize(this, Settings.Company);
            foreach (var faction in Overworld.Natives)
            {
                Factions.AddFaction(new Faction(this, faction));
            }

            Point playerOrigin = new Point((int)(Overworld.InstanceSettings.Origin.X), (int)(Overworld.InstanceSettings.Origin.Y));

            PlayerFaction         = Factions.Factions["Player"];
            PlayerFaction.Economy = new Company(PlayerFaction, 300.0m, Overworld.Company);

            #endregion

            EventScheduler = new Events.Scheduler();

            TutorialManager = new Tutorial.TutorialManager();
            TutorialManager.TutorialEnabled = !GameSettings.Default.TutorialDisabledGlobally;
            Tutorial("new game start");

            foreach (var item in Library.EnumerateCraftables())
            {
                if (!String.IsNullOrEmpty(item.Tutorial))
                {
                    TutorialManager.AddTutorial(item.Name, item.Tutorial, item.Icon);
                }
            }

            Renderer.Camera.World = this;
            //Drawer3D.Camera = Camera;


            #endregion

            SetLoadingMessage("Creating Particles ...");
            Game.DoLazyAction(new Action(() => ParticleManager = new ParticleManager(ComponentManager)));

            SetLoadingMessage("Creating GameMaster ...");

            TaskManager       = new TaskManager();
            TaskManager.World = this;
            Time.NewDay      += (time) => PayEmployees();


            var generatorSettings = new Generation.ChunkGeneratorSettings(MathFunctions.Random.Next(), 0.02f, Overworld)
            {
                WorldSizeInChunks = WorldSizeInChunks,
                SetLoadingMessage = SetLoadingMessage,
                World             = this
            };

            SetLoadingMessage("Generating Chunks...");
            Generation.Generator.Generate(Overworld.InstanceSettings.Cell.Bounds, ChunkManager, this, generatorSettings, SetLoadingMessage);
            CreateInitialEmbarkment(generatorSettings);
            ChunkManager.NeedsMinimapUpdate = true;
            ChunkManager.RecalculateBounds();

            if (PlayerFaction.Economy.Information == null)
            {
                throw new InvalidProgramException();
            }

            if (MathFunctions.RandEvent(0.01f))
            {
                SetLoadingMessage("Reticulating Splines...");
            }

            ChunkManager.StartThreads();
            SetLoadingMessage("Presimulating ...");
            ShowingWorld = false;
            OnLoadedEvent();
            Thread.Sleep(1000);

            ShowingWorld = true;

            SetLoadingMessage("Complete.");

            LoadStatus = LoadingStatus.Success;
        }
Пример #14
0
        public static void GenerateSurfaceLife(VoxelChunk TopChunk, ChunkGeneratorSettings Settings)
        {
            var creatureCounts = new Dictionary <string, Dictionary <string, int> >();
            var worldDepth     = Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY;

            for (var x = TopChunk.Origin.X; x < TopChunk.Origin.X + VoxelConstants.ChunkSizeX; x++)
            {
                for (var z = TopChunk.Origin.Z; z < TopChunk.Origin.Z + VoxelConstants.ChunkSizeZ; z++)
                {
                    var overworldPosition = OverworldMap.WorldToOverworld(new Vector2(x, z), Settings.Overworld.InstanceSettings.Origin);

                    if (Settings.Overworld.Map.GetBiomeAt(new Vector3(x, 0, z), Settings.Overworld.InstanceSettings.Origin).HasValue(out var biome))
                    {
                        var normalizedHeight = NormalizeHeight(Settings.Overworld.Map.LinearInterpolate(overworldPosition, OverworldField.Height));
                        var height           = (int)MathFunctions.Clamp(normalizedHeight * worldDepth, 0.0f, worldDepth - 2);

                        var voxel = Settings.World.ChunkManager.CreateVoxelHandle(new GlobalVoxelCoordinate(x, height, z));

                        if (!voxel.IsValid ||
                            voxel.Coordinate.Y == 0 ||
                            voxel.Coordinate.Y >= worldDepth - Settings.TreeLine)
                        {
                            continue;
                        }

                        if (voxel.LiquidLevel != 0)
                        {
                            continue;
                        }

                        var above = VoxelHelpers.GetVoxelAbove(voxel);
                        if (above.IsValid && (above.LiquidLevel != 0 || !above.IsEmpty))
                        {
                            continue;
                        }

                        foreach (var animal in biome.Fauna)
                        {
                            if (MathFunctions.RandEvent(animal.SpawnProbability))
                            {
                                if (!creatureCounts.ContainsKey(biome.Name))
                                {
                                    creatureCounts[biome.Name] = new Dictionary <string, int>();
                                }
                                var dict = creatureCounts[biome.Name];
                                if (!dict.ContainsKey(animal.Name))
                                {
                                    dict[animal.Name] = 0;
                                }
                                if (dict[animal.Name] < animal.MaxPopulation)
                                {
                                    EntityFactory.CreateEntity <GameComponent>(animal.Name,
                                                                               voxel.WorldPosition + Vector3.Up * 1.5f);
                                }
                                break;
                            }
                        }

                        if (voxel.Type.Name != biome.SoilLayer.VoxelType)
                        {
                            continue;
                        }

                        foreach (VegetationData veg in biome.Vegetation)
                        {
                            if (voxel.GrassType == 0)
                            {
                                continue;
                            }

                            if (MathFunctions.RandEvent(veg.SpawnProbability) &&
                                Settings.NoiseGenerator.Noise(voxel.Coordinate.X / veg.ClumpSize,
                                                              veg.NoiseOffset, voxel.Coordinate.Z / veg.ClumpSize) >= veg.ClumpThreshold)
                            {
                                var treeSize = MathFunctions.Rand() * veg.SizeVariance + veg.MeanSize;

                                EntityFactory.CreateEntity <Plant>(veg.Name,
                                                                   voxel.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f),
                                                                   Blackboard.Create("Scale", treeSize));

                                break;
                            }
                        }
                    }
                }
            }
        }
Пример #15
0
        private static CaveGenerationData GetCaveGenerationData(GlobalVoxelCoordinate At, int LayerIndex, ChunkGeneratorSettings Settings)
        {
            var frequency = LayerIndex < Settings.CaveFrequencies.Count ? Settings.CaveFrequencies[LayerIndex] : Settings.CaveFrequencies[Settings.CaveFrequencies.Count - 1];

            var noiseVector = At.ToVector3() * Settings.CaveNoiseScale * new Vector3(frequency, 3.0f, frequency);
            var noise       = Settings.CaveNoise.GetValue(noiseVector.X, noiseVector.Y, noiseVector.Z);

            var heightVector = At.ToVector3() * Settings.NoiseScale * new Vector3(frequency, 3.0f, frequency);
            var height       = Settings.NoiseGenerator.Noise(heightVector);

            return(new CaveGenerationData
            {
                CaveHere = noise > Settings.CaveSize,
                Noise = noise,
                Height = Math.Min(Math.Max((int)(height * Settings.CaveHeightScaleFactor), 1), Settings.MaxCaveHeight)
            });
        }
Пример #16
0
        public static void GenerateCaves(VoxelChunk Chunk, ChunkGeneratorSettings Settings)
        {
            if (Library.GetBiome("Cave").HasValue(out BiomeData caveBiome) && Library.GetBiome("Hell").HasValue(out BiomeData hellBiome))
            {
                for (int x = 0; x < VoxelConstants.ChunkSizeX; x++)
                {
                    for (int z = 0; z < VoxelConstants.ChunkSizeZ; z++)
                    {
                        for (int i = 0; i < Settings.CaveLevels.Count; i++)
                        {
                            // Does layer intersect this voxel?
                            int y = Settings.CaveLevels[i];
                            if (y + Settings.MaxCaveHeight < Chunk.Origin.Y)
                            {
                                continue;
                            }
                            if (y >= Chunk.Origin.Y + VoxelConstants.ChunkSizeY)
                            {
                                continue;
                            }

                            var coordinate = new GlobalVoxelCoordinate(Chunk.Origin.X + x, y, Chunk.Origin.Z + z);

                            var data = GetCaveGenerationData(coordinate, i, Settings);

                            var biome = (y <= Settings.HellLevel) ? hellBiome : caveBiome;

                            if (!data.CaveHere)
                            {
                                continue;
                            }

                            for (int dy = 0; dy < data.Height; dy++)
                            {
                                var globalY = y + dy;

                                // Prevent caves punching holes in bedrock.
                                if (globalY <= 0)
                                {
                                    continue;
                                }

                                // Check if voxel is inside chunk.
                                if (globalY <= 0 || globalY < Chunk.Origin.Y || globalY >= Chunk.Origin.Y + VoxelConstants.ChunkSizeY)
                                {
                                    continue;
                                }

                                var voxel = VoxelHandle.UnsafeCreateLocalHandle(Chunk, new LocalVoxelCoordinate(x, globalY - Chunk.Origin.Y, z));

                                // Prevent caves from breaking surface.
                                bool caveBreaksSurface = false;

                                foreach (var neighborCoordinate in VoxelHelpers.EnumerateAllNeighbors(voxel.Coordinate))
                                {
                                    var v = Chunk.Manager.CreateVoxelHandle(neighborCoordinate);
                                    if (!v.IsValid || (v.Sunlight))
                                    {
                                        caveBreaksSurface = true;
                                        break;
                                    }
                                }

                                if (caveBreaksSurface)
                                {
                                    break;
                                }

                                voxel.RawSetType(Library.EmptyVoxelType);

                                if (dy == 0)
                                {
                                    // Place soil voxel and grass below cave.
                                    var below = VoxelHelpers.GetVoxelBelow(voxel);
                                    if (below.IsValid)
                                    {
                                        below.RawSetType(Library.GetVoxelType(biome.SoilLayer.VoxelType));
                                        var grassType = Library.GetGrassType(biome.GrassDecal);
                                        if (grassType != null)
                                        {
                                            below.RawSetGrass(grassType.ID);
                                        }
                                    }

                                    // Spawn flora and fauna.
                                    if (data.Noise > Settings.CaveSize * 1.8f && globalY > Settings.LavaLevel)
                                    {
                                        GenerateCaveFlora(below, biome, Settings);
                                        GenerateCaveFauna(below, biome, Settings);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #17
0
        private static void GenerateCaveFlora(VoxelHandle CaveFloor, BiomeData Biome, ChunkGeneratorSettings Settings)
        {
            foreach (var floraType in Biome.Vegetation)
            {
                if (!MathFunctions.RandEvent(floraType.SpawnProbability))
                {
                    continue;
                }

                if (Settings.NoiseGenerator.Noise(CaveFloor.Coordinate.X / floraType.ClumpSize, floraType.NoiseOffset, CaveFloor.Coordinate.Z / floraType.ClumpSize) < floraType.ClumpThreshold)
                {
                    continue;
                }

                var plantSize       = MathFunctions.Rand() * floraType.SizeVariance + floraType.MeanSize;
                var lambdaFloraType = floraType;

                if (!GameSettings.Current.FogofWar)
                {
                    EntityFactory.CreateEntity <GameComponent>(
                        lambdaFloraType.Name,
                        CaveFloor.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f),
                        Blackboard.Create("Scale", plantSize));
                }
                else
                {
                    Settings.World.ComponentManager.RootComponent.AddChild(new SpawnOnExploredTrigger(Settings.World.ComponentManager, CaveFloor)
                    {
                        EntityToSpawn  = lambdaFloraType.Name,
                        SpawnLocation  = CaveFloor.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f),
                        BlackboardData = Blackboard.Create("Scale", plantSize)
                    });
                }

                break; // Don't risk spawning multiple plants in the same spot.
            }
        }
Пример #18
0
        public static MaybeNull <Zone> GenerateInitialBalloonPort(float x, float z, int size, Generation.ChunkGeneratorSettings Settings)
        {
            var roomVoxels = Generation.Generator.GenerateBalloonPort(Settings.World.ChunkManager, x, z, size, Settings);

            if (Library.CreateZone("Balloon Port", Settings.World).HasValue(out var zone))
            {
                Settings.World.AddZone(zone);
                zone.CompleteRoomImmediately(roomVoxels.StockpileVoxels);

                var box  = zone.GetBoundingBox();
                var at   = new Vector3((box.Min.X + box.Max.X - 1) / 2, box.Max.Y, (box.Min.Z + box.Max.Z - 1) / 2);
                var flag = EntityFactory.CreateEntity <Flag>("Flag", at + new Vector3(0.5f, 0.5f, 0.5f));
                Settings.World.PlayerFaction.OwnedObjects.Add(flag);

                return(zone);
            }
            else
            {
                return(null);
            }
        }
Пример #19
0
        public static VoxelChunk GenerateChunk(GlobalChunkCoordinate ID, ChunkGeneratorSettings Settings)
        {
            var origin      = new GlobalVoxelCoordinate(ID, new LocalVoxelCoordinate(0, 0, 0));
            var worldDepth  = Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY;
            var waterHeight = NormalizeHeight(Settings.Overworld.GenerationSettings.SeaLevel + 1.0f / worldDepth);

            var c = new VoxelChunk(Settings.World.ChunkManager, ID);

            if (GameSettings.Current.NoStone)
            {
                return(c);
            }

            for (int x = 0; x < VoxelConstants.ChunkSizeX; x++)
            {
                for (int z = 0; z < VoxelConstants.ChunkSizeZ; z++)
                {
                    var overworldPosition = OverworldMap.WorldToOverworld(new Vector2(x + origin.X, z + origin.Z), Settings.Overworld.InstanceSettings.Origin);

                    if (Settings.Overworld.Map.GetBiomeAt(new Vector3(x + origin.X, 0, z + origin.Z), Settings.Overworld.InstanceSettings.Origin).HasValue(out var biomeData))
                    {
                        var normalizedHeight = NormalizeHeight(Settings.Overworld.Map.LinearInterpolate(overworldPosition, OverworldField.Height));
                        var height           = MathFunctions.Clamp(normalizedHeight * worldDepth, 0.0f, worldDepth - 2);
                        var stoneHeight      = (int)MathFunctions.Clamp((int)(height - (biomeData.SoilLayer.Depth + (Math.Sin(overworldPosition.X) + Math.Cos(overworldPosition.Y)))), 1, height);

                        for (int y = 0; y < VoxelConstants.ChunkSizeY; y++)
                        {
                            var globalY = origin.Y + y;
                            var voxel   = VoxelHandle.UnsafeCreateLocalHandle(c, new LocalVoxelCoordinate(x, y, z));

                            if (globalY == 0)
                            {
                                voxel.RawSetType(Library.GetVoxelType("Bedrock"));
                                continue;
                            }

                            // Below the stone line, use subsurface layers.
                            if (globalY <= stoneHeight && stoneHeight > 1)
                            {
                                var depth           = stoneHeight - globalY - biomeData.SubsurfaceLayers[0].Depth + 1;
                                var subsurfaceLayer = 0;
                                while (depth > 0 && subsurfaceLayer < biomeData.SubsurfaceLayers.Count - 1)
                                {
                                    depth           -= biomeData.SubsurfaceLayers[subsurfaceLayer].Depth;
                                    subsurfaceLayer += 1;
                                }

                                voxel.RawSetType(Library.GetVoxelType(biomeData.SubsurfaceLayers[subsurfaceLayer].VoxelType));
                            }
                            // Otherwise, on the surface.
                            else if ((globalY == (int)height || globalY == stoneHeight) && normalizedHeight > waterHeight)
                            {
                                voxel.RawSetType(Library.GetVoxelType(biomeData.SoilLayer.VoxelType));

                                if (!String.IsNullOrEmpty(biomeData.GrassDecal))
                                {
                                    if (!biomeData.ClumpGrass || (biomeData.ClumpGrass &&
                                                                  Settings.NoiseGenerator.Noise(overworldPosition.X / biomeData.ClumpSize, 0, overworldPosition.Y / biomeData.ClumpSize) > biomeData.ClumpTreshold))
                                    {
                                        voxel.RawSetGrass(Library.GetGrassType(biomeData.GrassDecal).ID);
                                    }
                                }
                            }
                            else if (globalY > height && globalY > 0)
                            {
                                voxel.RawSetType(Library.EmptyVoxelType);
                            }
                            else if (normalizedHeight <= waterHeight)
                            {
                                voxel.RawSetType(Library.GetVoxelType(biomeData.ShoreVoxel));
                            }
                            else
                            {
                                voxel.RawSetType(Library.GetVoxelType(biomeData.SoilLayer.VoxelType));
                            }
                        }
                    }
                }
            }

            return(c);
        }
Пример #20
0
 public static IEnumerable <VoxelChunk> EnumerateTopChunks(ChunkGeneratorSettings Settings)
 {
     return(Settings.World.ChunkManager.GetChunkEnumerator().Where(c => c.ID.Y == Settings.WorldSizeInChunks.Y - 1));
 }
Пример #21
0
        public static void GenerateRuin(VoxelChunk Chunk, ChunkGeneratorSettings Settings)
        {
            var noiseVector = Chunk.Origin.ToVector3() * Settings.CaveNoiseScale;
            var ruinsNoise  = Settings.CaveNoise.GetValue(noiseVector.X, noiseVector.Y, noiseVector.Z);

            if (Math.Abs(ruinsNoise) > GameSettings.Default.GenerationRuinsRate)
            {
                return;
            }

            int structureWidth = MathFunctions.RandInt(4, 16);
            int structureDepth = MathFunctions.RandInt(4, 16);
            int xOffset        = MathFunctions.RandInt(0, VoxelConstants.ChunkSizeX - structureWidth);
            int zOffset        = MathFunctions.RandInt(0, VoxelConstants.ChunkSizeZ - structureDepth);
            int wallHeight     = MathFunctions.RandInt(2, 6);
            int heightOffset   = MathFunctions.RandInt(-4, 2);

            if (Settings.Overworld.Map.GetBiomeAt(Chunk.Origin.ToVector3(), Settings.Overworld.InstanceSettings.Origin).HasValue(out var biome))
            {
                var avgHeight = GetAverageHeight(Chunk.Origin.X, Chunk.Origin.Z, structureWidth, structureDepth, Settings);

                bool[] doors = new bool[4];

                for (int k = 0; k < 4; k++)
                {
                    doors[k] = MathFunctions.RandEvent(0.5f);
                }

                for (int dx = 0; dx < structureWidth; dx++)
                {
                    for (int dz = 0; dz < structureDepth; dz++)
                    {
                        var worldPos = new Vector3(Chunk.Origin.X + dx + xOffset, avgHeight + heightOffset, Chunk.Origin.Z + dz + zOffset);

                        var baseVoxel  = Settings.World.ChunkManager.CreateVoxelHandle(GlobalVoxelCoordinate.FromVector3(worldPos));
                        var underVoxel = VoxelHelpers.FindFirstVoxelBelow(Settings.World.ChunkManager.CreateVoxelHandle(GlobalVoxelCoordinate.FromVector3(worldPos)));
                        var decay      = Settings.NoiseGenerator.Generate(worldPos.X * 0.05f, worldPos.Y * 0.05f, worldPos.Z * 0.05f);

                        if (decay > 0.7f)
                        {
                            continue;
                        }
                        if (!baseVoxel.IsValid)
                        {
                            continue;
                        }
                        if (baseVoxel.Coordinate.Y == (Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY) - 1)
                        {
                            continue;
                        }
                        if (!underVoxel.IsValid)
                        {
                            continue;
                        }

                        var edge = (dx == 0 || dx == structureWidth - 1) || (dz == 0 || dz == structureDepth - 1);
                        if (!edge && !baseVoxel.IsEmpty)
                        {
                            continue;
                        }

                        if (edge)
                        {
                            baseVoxel.RawSetType(Library.GetVoxelType(biome.RuinWallType));
                        }
                        else
                        {
                            baseVoxel.RawSetType(Library.GetVoxelType(biome.RuinFloorType));
                        }

                        bool[] wallState = new bool[4];
                        wallState[0] = dx == 0;
                        wallState[1] = dx == structureWidth - 1;
                        wallState[2] = dz == 0;
                        wallState[3] = dz == structureDepth - 1;

                        bool[] doorState = new bool[4];
                        doorState[0] = Math.Abs(dz - structureDepth / 2) < 1;
                        doorState[1] = doorState[0];
                        doorState[2] = Math.Abs(dx - structureWidth / 2) < 1;
                        doorState[3] = doorState[2];

                        for (int dy = 1; dy < (baseVoxel.Coordinate.Y - underVoxel.Coordinate.Y); dy++)
                        {
                            var currVoxel = Settings.World.ChunkManager.CreateVoxelHandle(underVoxel.Coordinate + new GlobalVoxelOffset(0, dy, 0));

                            if (!currVoxel.IsValid)
                            {
                                continue;
                            }

                            currVoxel.RawSetType(underVoxel.Type);
                        }

                        underVoxel.RawSetGrass(0);

                        if (edge)
                        {
                            for (int dy = 1; dy < wallHeight * (1.0f - decay) && dy < (Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY) - 2; dy++)
                            {
                                var currVoxel = Settings.World.ChunkManager.CreateVoxelHandle(baseVoxel.Coordinate + new GlobalVoxelOffset(0, dy, 0));

                                if (!currVoxel.IsValid)
                                {
                                    continue;
                                }

                                if (currVoxel.Coordinate.Y == VoxelConstants.ChunkSizeY - 1)
                                {
                                    continue;
                                }

                                bool door = false;
                                for (int k = 0; k < 4; k++)
                                {
                                    if (wallState[k] && doors[k] && doorState[k])
                                    {
                                        door = true;
                                        break;
                                    }
                                }

                                if (door && dy < 3)
                                {
                                    continue;
                                }

                                currVoxel.RawSetType(Library.GetVoxelType(biome.RuinWallType));
                            }
                        }
                    }
                }
            }
        }
Пример #22
0
        public static BalloonPortVoxelSets GenerateBalloonPort(ChunkManager chunkManager, float x, float z, int size, ChunkGeneratorSettings Settings)
        {
            var centerCoordinate = GlobalVoxelCoordinate.FromVector3(new Vector3(x, (Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY) - 1, z));

            var averageHeight = (int)GetAverageHeight(centerCoordinate.X - size, centerCoordinate.Y - size, size * 2 + 1, size * 2 + 1, Settings);

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

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

                    var baseVoxel = VoxelHelpers.FindFirstVoxelBelow(chunkManager.CreateVoxelHandle(GlobalVoxelCoordinate.FromVector3(worldPos)));

                    if (!baseVoxel.IsValid)
                    {
                        continue;
                    }

                    var h = baseVoxel.Coordinate.Y + 1;

                    for (int y = averageHeight; y < h && y < chunkManager.World.WorldSizeInVoxels.Y; y++)
                    {
                        var v = chunkManager.CreateVoxelHandle(new GlobalVoxelCoordinate(baseVoxel.Coordinate.X, y, baseVoxel.Coordinate.Z));
                        v.RawSetType(Library.EmptyVoxelType);
                        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;
                        }
                    }

                    // Fill from the top height down to the bottom.

                    for (int y = Math.Max(0, h - 1); y < averageHeight && y < chunkManager.World.WorldSizeInVoxels.Y; y++)
                    {
                        var v = chunkManager.CreateVoxelHandle(new GlobalVoxelCoordinate(baseVoxel.Coordinate.X, y, baseVoxel.Coordinate.Z));
                        if (!v.IsValid)
                        {
                            throw new InvalidProgramException("Voxel was invalid while creating a new game's initial zones. This should not happen.");
                        }

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

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

                            balloonPortDesignations.Add(v);
                        }

                        if (isSide)
                        {
                            var ladderPos = new Vector3(worldPos.X, y, worldPos.Z) + offset + Vector3.One * 0.5f;
                            var ladderVox = chunkManager.CreateVoxelHandle(GlobalVoxelCoordinate.FromVector3(ladderPos));
                            if (ladderVox.IsValid && ladderVox.IsEmpty)
                            {
                                var ladder = EntityFactory.CreateEntity <Ladder>("Ladder", ladderPos);
                                Settings.World.PlayerFaction.OwnedObjects.Add(ladder);
                                ladder.Tags.Add("Moveable");
                                ladder.Tags.Add("Deconstructable");
                            }
                        }
                    }

                    CastSunlightColumn(baseVoxel.Coordinate.X, baseVoxel.Coordinate.Z, Settings);
                }
            }

            return(new BalloonPortVoxelSets
            {
                StockpileVoxels = balloonPortDesignations,
            });
        }
Пример #23
0
        public static void Generate(Rectangle spawnRect, ChunkManager ChunkData, WorldManager World, ChunkGeneratorSettings Settings, Action <String> SetLoadingMessage)
        {
            SetLoadingMessage(String.Format("{0} chunks to generate!", Settings.WorldSizeInChunks.X * Settings.WorldSizeInChunks.Y * Settings.WorldSizeInChunks.Z));
            SetLoadingMessage("");

            for (int dx = 0; dx < Settings.WorldSizeInChunks.X; dx++)
            {
                for (int dy = 0; dy < Settings.WorldSizeInChunks.Y; dy++)
                {
                    for (int dz = 0; dz < Settings.WorldSizeInChunks.Z; dz++)
                    {
                        SetLoadingMessage(String.Format("#Generating chunk {0} {1} {2}...", dx, dy, dz));
                        ChunkData.AddChunk(GenerateChunk(new GlobalChunkCoordinate(dx, dy, dz), Settings));
                    }
                }
            }

            var worldDepth = Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY;

            Settings.NormalizedSeaLevel = Math.Min((int)(worldDepth * NormalizeHeight(Settings.Overworld.GenerationSettings.SeaLevel + 1.0f / worldDepth)), worldDepth - 1);

            SetLoadingMessage("");
            foreach (var chunk in EnumerateTopChunks(Settings))
            {
                SetLoadingMessage(String.Format("#Casting light in chunk {0} {1} {2}...", chunk.ID.X, chunk.ID.Y, chunk.ID.Z));
                CastSunlight(chunk, Settings);
                GenerateRuin(chunk, Settings);
            }

            // Todo: Can these be sped up by doing multiple in one iteration of the outer x,z?
            if (!GameSettings.Default.FastGen)
            {
                SetLoadingMessage("");
                foreach (var chunk in ChunkData.ChunkMap)
                {
                    SetLoadingMessage(String.Format("#Generating caves, ore, water in chunk {0} {1} {2}...", chunk.ID.X, chunk.ID.Y, chunk.ID.Z));
                    GenerateOres(chunk, Settings);
                    GenerateCaves(chunk, Settings);
                    GenerateWater(chunk, Settings);
                    GenerateLava(chunk, Settings);
                }
            }

            SetLoadingMessage("");
            foreach (var chunk in EnumerateTopChunks(Settings))
            {
                SetLoadingMessage(String.Format("#Spawning life in chunk {0} {1} {2}...", chunk.ID.X, chunk.ID.Y, chunk.ID.Z));
                GenerateSurfaceLife(chunk, Settings);
                ChunkData.EnqueueInvalidColumn(chunk.ID.X, chunk.ID.Z);
            }
        }
Пример #24
0
        public static void GenerateRuin(VoxelChunk Chunk, ChunkGeneratorSettings Settings)
        {
            // Todo: Support ruins deep underground - empty out their interiors.

            LoadRuinTemplates();

            var noiseVector = Chunk.Origin.ToVector3() * Settings.CaveNoiseScale;
            var ruinsNoise  = Settings.CaveNoise.GetValue(noiseVector.X, noiseVector.Y, noiseVector.Z);

            if (Math.Abs(ruinsNoise) > GameSettings.Current.GenerationRuinsRate)
            {
                return;
            }


            var avgHeight = GetAverageHeight(Chunk.Origin.X, Chunk.Origin.Z, 16, 16, Settings);

            var ruinWallType  = Library.GetVoxelType("Cobble"); // Todo: Should make this data so this doesn't break if tile names change?
            var ruinFloorType = Library.GetVoxelType("Blue Tile");

            if (Settings.Overworld.Map.GetBiomeAt(Chunk.Origin.ToVector3(), Settings.Overworld.InstanceSettings.Origin).HasValue(out var biome))
            {
                ruinWallType  = Library.GetVoxelType(biome.RuinWallType);
                ruinFloorType = Library.GetVoxelType(biome.RuinFloorType);
            }

            if (!ruinWallType.HasValue() || !ruinFloorType.HasValue())
            {
                return;
            }

            int wallHeight = MathFunctions.RandInt(2, 6);
            var template   = RuinTemplates[MathFunctions.RandInt(0, RuinTemplates.Count)];

            var rotations = MathFunctions.RandInt(0, 3);

            for (var i = 0; i < rotations; ++i)
            {
                template = TextureTool.RotatedCopy(template);
            }

            for (int dx = 0; dx < 16; dx++)
            {
                for (int dz = 0; dz < 16; dz++)
                {
                    var worldPos = new Vector3(Chunk.Origin.X + dx, avgHeight, Chunk.Origin.Z + dz);

                    var baseVoxel  = Settings.World.ChunkManager.CreateVoxelHandle(GlobalVoxelCoordinate.FromVector3(worldPos));
                    var underVoxel = VoxelHelpers.FindFirstVoxelBelow(Settings.World.ChunkManager.CreateVoxelHandle(GlobalVoxelCoordinate.FromVector3(worldPos)));
                    var decay      = Settings.NoiseGenerator.Generate(worldPos.X * 0.05f, worldPos.Y * 0.05f, worldPos.Z * 0.05f);

                    if (decay > 0.7f)
                    {
                        continue;
                    }
                    if (!baseVoxel.IsValid)
                    {
                        continue;
                    }
                    if (baseVoxel.Coordinate.Y == (Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY) - 1)
                    {
                        continue;
                    }
                    if (!underVoxel.IsValid)
                    {
                        continue;
                    }


                    var templateColor = template.Data[template.Index(dx, dz)];

                    if (templateColor == new Color(0, 0, 255, 255)) // Border
                    {
                        continue;
                    }
                    else if (templateColor == new Color(0, 0, 0, 255)) // Space
                    {
                        continue;
                    }
                    else if (templateColor == new Color(255, 0, 0, 255)) // Wall
                    {
                        baseVoxel.RawSetType(ruinWallType);
                        FillBelowRuins(Settings, ruinWallType, baseVoxel, underVoxel);
                        FillRuinColumn(Settings, ruinWallType, 1, wallHeight, baseVoxel, decay);
                    }
                    else if (templateColor == new Color(128, 128, 0, 255)) // Door
                    {
                        baseVoxel.RawSetType(ruinWallType);
                        FillBelowRuins(Settings, ruinWallType, baseVoxel, underVoxel);
                        FillRuinColumn(Settings, ruinWallType, 3, wallHeight, baseVoxel, decay);
                    }
                    else if (templateColor == new Color(128, 0, 0, 255)) // Floor
                    {
                        FillBelowRuins(Settings, ruinWallType, baseVoxel, underVoxel);
                        baseVoxel.RawSetType(ruinFloorType);
                    }
                }
            }
        }
Пример #25
0
        public static MaybeNull <Zone> GenerateInitialBalloonPort(float x, float z, int size, Generation.ChunkGeneratorSettings Settings)
        {
            var roomVoxels = Generation.Generator.GenerateBalloonPort(Settings.World.ChunkManager, x, z, size, Settings);

            if (Library.CreateZone("Balloon Port", Settings.World).HasValue(out var zone))
            {
                Settings.World.AddZone(zone);
                zone.CompleteRoomImmediately(roomVoxels.StockpileVoxels);

                var box  = zone.GetBoundingBox();
                var at   = new Vector3((box.Min.X + box.Max.X) / 2, box.Max.Y + 0.5f, (box.Min.Z + box.Max.Z) / 2);
                var flag = new Flag(Settings.World.ComponentManager, at, Settings.World.PlayerFaction.Economy.Information, new Resource("Flag"));
                Settings.World.PlayerFaction.OwnedObjects.Add(flag);
                flag.Tags.Add("Deconstructable");

                return(zone);
            }
            else
            {
                return(null);
            }
        }