Ejemplo n.º 1
0
        public void GenerateWater(VoxelChunk chunk, float maxHeight)
        {
            int waterHeight = Math.Min((int)(VoxelConstants.ChunkSizeY * NormalizeHeight(SeaLevel + 1.0f / VoxelConstants.ChunkSizeY, maxHeight)), VoxelConstants.ChunkSizeY - 1);
            var iceID       = VoxelLibrary.GetVoxelType("Ice");

            for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x)
            {
                for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z)
                {
                    var biome    = Overworld.GetBiomeAt(new Vector3(x, 0, z) + chunk.Origin, chunk.Manager.World.WorldScale, chunk.Manager.World.WorldOrigin);
                    var topVoxel = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle(
                                                                        chunk, new LocalVoxelCoordinate(x, VoxelConstants.ChunkSizeY - 1, z)));

                    for (var y = 0; y <= waterHeight; ++y)
                    {
                        var vox = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y, z));
                        if (vox.IsEmpty && y > topVoxel.Coordinate.Y)
                        {
                            if (biome.WaterSurfaceIce && y == waterHeight)
                            {
                                vox.RawSetType(iceID);
                            }
                            else
                            {
                                vox.QuickSetLiquid(biome.WaterIsLava ? LiquidType.Lava : LiquidType.Water, WaterManager.maxWaterLevel);
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 2
0
        override public void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera)
        {
            base.Update(gameTime, chunks, camera);

            if (CachedBiome == null)
            {
                var biome = Overworld.GetBiomeAt(LocalPosition, chunks.World.WorldScale, chunks.World.WorldOrigin);
                CachedBiome = biome.Name;
            }

            var factor = 1.0f;

            if (GoodBiomes.Contains(CachedBiome))
            {
                factor = 1.5f;
            }
            if (BadBiomes.Contains(CachedBiome))
            {
                factor = 0.5f;
            }

            GrowthTime += gameTime.ElapsedGameTime.TotalMinutes * factor;

            var scale = (float)(MinSize + (MaxSize - MinSize) * (GrowthTime / GrowthHours));

            ReScale(scale);

            if (GrowthTime >= GrowthHours)
            {
                CreateAdult();
            }
        }
Ejemplo n.º 3
0
        public void GenerateWater(VoxelChunk chunk)
        {
            int waterHeight = (int)(SeaLevel * VoxelConstants.ChunkSizeY) + 1;
            var iceID       = VoxelLibrary.GetVoxelType("Ice");

            for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x)
            {
                for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z)
                {
                    var biome    = Overworld.GetBiomeAt(new Vector3(x, 0, z) + chunk.Origin, chunk.Manager.World.WorldScale, chunk.Manager.World.WorldOrigin);
                    var topVoxel = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle(
                                                                        chunk, new LocalVoxelCoordinate(x, VoxelConstants.ChunkSizeY - 1, z)));

                    for (var y = 0; y <= waterHeight; ++y)
                    {
                        var vox = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y, z));
                        if (vox.IsEmpty && y > topVoxel.Coordinate.Y)
                        {
                            if (biome.WaterSurfaceIce && y == waterHeight)
                            {
                                vox.RawSetType(iceID);
                            }
                            else
                            {
                                vox.QuickSetLiquid(LiquidType.Water, WaterManager.maxWaterLevel);
                            }
                        }
                    }

                    Vector2 vec = Overworld.WorldToOverworld(new Vector2(x + chunk.Origin.X, z + chunk.Origin.Z), chunk.Manager.World.WorldScale, chunk.Manager.World.WorldOrigin);


                    if (topVoxel.Coordinate.Y < VoxelConstants.ChunkSizeY - 1 &&
                        Overworld.GetWater(Overworld.Map, vec) == Overworld.WaterType.Volcano)
                    {
                        var localCoord = topVoxel.Coordinate.GetLocalVoxelCoordinate();
                        topVoxel = new VoxelHandle(topVoxel.Chunk, new LocalVoxelCoordinate(
                                                       localCoord.X, localCoord.Y + 1, localCoord.Z));

                        if (topVoxel.IsEmpty)
                        {
                            topVoxel.QuickSetLiquid(LiquidType.Lava, WaterManager.maxWaterLevel);
                        }
                    }
                }
            }
        }
Ejemplo n.º 4
0
        public void GenerateSurfaceLife(Dictionary <string, Dictionary <string, int> > creatureCounts, VoxelChunk Chunk, float maxHeight)
        {
            //int waterHeight = (int)(VoxelConstants.ChunkSizeY * NormalizeHeight(SeaLevel + 1.0f / VoxelConstants.ChunkSizeY, maxHeight));
            for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x)
            {
                for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z)
                {
                    var biomeData = Overworld.GetBiomeAt(new Vector3(x + Chunk.Origin.X, 0, z + Chunk.Origin.Z), Chunk.Manager.World.WorldScale, Chunk.Manager.World.WorldOrigin);
                    var topVoxel  = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle(
                                                                         Chunk, new LocalVoxelCoordinate(x, VoxelConstants.ChunkSizeY - 1, z)));

                    if (!topVoxel.IsValid ||
                        topVoxel.Coordinate.Y == 0 ||
                        topVoxel.Coordinate.Y >= 60)    // Lift to some kind of generator settings?
                    {
                        continue;
                    }
                    var above = VoxelHelpers.GetVoxelAbove(topVoxel);
                    if (above.IsValid && above.LiquidLevel != 0)
                    {
                        continue;
                    }
                    foreach (var animal in biomeData.Fauna)
                    {
                        if (MathFunctions.RandEvent(animal.SpawnProbability))
                        {
                            if (!creatureCounts.ContainsKey(biomeData.Name))
                            {
                                creatureCounts[biomeData.Name] = new Dictionary <string, int>();
                            }
                            var dict = creatureCounts[biomeData.Name];
                            if (!dict.ContainsKey(animal.Name))
                            {
                                dict[animal.Name] = 0;
                            }
                            if (dict[animal.Name] < animal.MaxPopulation)
                            {
                                EntityFactory.CreateEntity <Body>(animal.Name,
                                                                  topVoxel.WorldPosition + Vector3.Up * 1.5f);
                            }
                            break;
                        }
                    }

                    if (topVoxel.Type.Name != biomeData.SoilLayer.VoxelType)
                    {
                        continue;
                    }

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

                        if (MathFunctions.RandEvent(veg.SpawnProbability) &&
                            NoiseGenerator.Noise(topVoxel.Coordinate.X / veg.ClumpSize,
                                                 veg.NoiseOffset, topVoxel.Coordinate.Z / veg.ClumpSize) >= veg.ClumpThreshold)
                        {
                            topVoxel.RawSetType(VoxelLibrary.GetVoxelType(biomeData.SoilLayer.VoxelType));

                            var treeSize = MathFunctions.Rand() * veg.SizeVariance + veg.MeanSize;
                            var tree     = EntityFactory.CreateEntity <Plant>(veg.Name,
                                                                              topVoxel.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f),
                                                                              Blackboard.Create("Scale", treeSize));

                            break;
                        }
                    }
                }
            }
        }
Ejemplo n.º 5
0
        private static void UpdateChunk(VoxelChunk chunk)
        {
            var addGrassToThese = new List <Tuple <VoxelHandle, byte> >();

            for (var y = 0; y < VoxelConstants.ChunkSizeY; ++y)
            {
                // Skip empty slices.
                if (chunk.Data.VoxelsPresentInSlice[y] == 0)
                {
                    continue;
                }

                for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x)
                {
                    for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z)
                    {
                        var voxel = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y, z));

                        // Allow grass to decay
                        if (voxel.GrassType != 0)
                        {
                            var decal = GrassLibrary.GetGrassType(voxel.GrassType);

                            if (decal.NeedsSunlight && !voxel.Sunlight)
                            {
                                voxel.GrassType = 0;
                            }
                            else if (decal.Decay)
                            {
                                voxel.GrassDecay -= 1;
                                if (voxel.GrassDecay == 0)
                                {
                                    var newDecal = GrassLibrary.GetGrassType(decal.BecomeWhenDecays);
                                    if (newDecal != null)
                                    {
                                        voxel.GrassType = newDecal.ID;
                                    }
                                    else
                                    {
                                        voxel.GrassType = 0;
                                    }
                                }
                            }
                        }
//#if false
                        else if (voxel.Type.GrassSpreadsHere)
                        {
                            // Spread grass onto this tile - but only from the same biome.

                            // Don't spread if there's an entity here.
                            var entityPresent = chunk.Manager.World.EnumerateIntersectingObjects(
                                new BoundingBox(voxel.WorldPosition + new Vector3(0.1f, 1.1f, 0.1f), voxel.WorldPosition + new Vector3(0.9f, 1.9f, 0.9f)),
                                CollisionType.Static).Any();
                            if (entityPresent)
                            {
                                continue;
                            }

                            var biome = Overworld.GetBiomeAt(voxel.Coordinate.ToVector3(), chunk.Manager.World.WorldScale, chunk.Manager.World.WorldOrigin);

                            var grassyNeighbors = VoxelHelpers.EnumerateManhattanNeighbors2D(voxel.Coordinate)
                                                  .Select(c => new VoxelHandle(voxel.Chunk.Manager.ChunkData, c))
                                                  .Where(v => v.IsValid && v.GrassType != 0)
                                                  .Where(v => biome == Overworld.GetBiomeAt(v.Coordinate.ToVector3(), chunk.Manager.World.WorldScale, chunk.Manager.World.WorldOrigin))
                                                  .ToList();

                            if (grassyNeighbors.Count > 0)
                            {
                                if (MathFunctions.RandEvent(0.1f))
                                {
                                    addGrassToThese.Add(Tuple.Create(voxel, grassyNeighbors[MathFunctions.RandInt(0, grassyNeighbors.Count)].GrassType));
                                }
                            }
                        }
//#endif
                    }
                }
            }

            foreach (var v in addGrassToThese)
            {
                var l         = v.Item1;
                var grassType = GrassLibrary.GetGrassType(v.Item2);
                if (grassType.NeedsSunlight && !l.Sunlight)
                {
                    continue;
                }
                l.GrassType = v.Item2;
            }
        }
Ejemplo n.º 6
0
        public void RebuildMoteLayer(int Y)
        {
            var moteList = new List <NewInstanceData>();

            // Enumerate voxels.
            for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x)
            {
                for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z)
                {
                    // Don't generate motes if above is not empty
                    if (Y < VoxelConstants.ChunkSizeY - 1)
                    {
                        var voxelAbove = new VoxelHandle(this, new LocalVoxelCoordinate(x, Y + 1, z));
                        if (!voxelAbove.IsEmpty || voxelAbove.LiquidLevel != 0)
                        {
                            continue;
                        }
                    }

                    var v = new VoxelHandle(this, new LocalVoxelCoordinate(x, Y, z));

                    // Don't generate in empty voxels.
                    if (v.IsEmpty)
                    {
                        continue;
                    }

                    if (!v.IsExplored)
                    {
                        continue;
                    }

                    // Find biome type.
                    var biomeData = Overworld.GetBiomeAt(v.WorldPosition, Manager.World.WorldScale, Manager.World.WorldOrigin);

                    // Don't generate if not on grass type.
                    if (v.GrassType == 0 || GrassLibrary.GetGrassType(v.GrassType).Name != biomeData.GrassDecal)
                    {
                        continue;
                    }

                    // Biomes can contain multiple types of mote.
                    foreach (var moteDetail in biomeData.Motes)
                    {
                        // Lower mote if voxel is ramped.
                        float vOffset = 0.0f;
                        if (v.RampType != RampType.None)
                        {
                            vOffset = -0.5f;
                        }

                        var   vPos  = v.WorldPosition * moteDetail.RegionScale;
                        float value = MoteNoise.Noise(vPos.X, vPos.Y, vPos.Z);

                        if (!(Math.Abs(value) > moteDetail.SpawnThreshold))
                        {
                            continue;
                        }

                        float s = MoteScaleNoise.Noise(vPos.X, vPos.Y, vPos.Z) * moteDetail.MoteScale;

                        var smallNoise = ClampVector(VertexNoise.GetRandomNoiseVector(vPos * 20.0f) * 20.0f, 0.4f);
                        smallNoise.Y = 0.0f;

                        var mote = GenerateGrassMote(
                            Manager.World,
                            v.WorldPosition + new Vector3(0.5f, 1.0f + s * 0.5f + vOffset, 0.5f) + smallNoise,
                            new Color(v.Sunlight ? 255 : 0, 128, 0),
                            s,
                            moteDetail.Name);

                        moteList.Add(mote);
                    }
                }
            }

            MoteRecords[Y] = moteList;
        }
Ejemplo n.º 7
0
        public void HandleAmbientSound()
        {
            AmbienceTimer.Update(DwarfTime.LastTime);
            if (!AmbienceTimer.HasTriggered && !firstAmbience)
            {
                return;
            }
            firstAmbience = false;

            // Before doing anything, determine if there is a rain or snow storm.
            if (Weather.IsRaining())
            {
                PlaySpecialAmbient("sfx_amb_rain_storm");
                return;
            }

            if (Weather.IsSnowing())
            {
                PlaySpecialAmbient("sfx_amb_snow_storm");
                return;
            }

            // First check voxels to see if we're underground or underwater.
            var vox = VoxelHelpers.FindFirstVisibleVoxelOnScreenRay(ChunkManager.ChunkData, GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height / 2, Camera, GraphicsDevice.Viewport, 100.0f, false, null);

            if (vox.IsValid)
            {
                float height = WaterRenderer.GetTotalWaterHeightCells(vox);
                if (height > 0)
                {
                    PlaySpecialAmbient("sfx_amb_ocean");
                    return;
                }
                else
                {
                    // Unexplored voxels assumed to be cave.
                    if (vox.IsValid && !vox.IsExplored)
                    {
                        PlaySpecialAmbient("sfx_amb_cave");
                        return;
                    }

                    var above = VoxelHelpers.GetVoxelAbove(vox);
                    // Underground, do the cave test.
                    if (above.IsValid && above.IsEmpty && above.Sunlight == false)
                    {
                        PlaySpecialAmbient("sfx_amb_cave");
                        return;
                    }
                }
            }
            else
            {
                return;
            }

            // Now check for biome ambience.
            var pos   = vox.WorldPosition;
            var biome = Overworld.GetBiomeAt(pos, WorldScale, WorldOrigin);

            if (biome != null && !string.IsNullOrEmpty(biome.DayAmbience))
            {
                if (prevAmbience[0] != biome.DayAmbience)
                {
                    if (!string.IsNullOrEmpty(prevAmbience[0]))
                    {
                        SoundManager.StopAmbience(prevAmbience[0]);
                        prevAmbience[0] = null;
                    }
                    if (!string.IsNullOrEmpty(prevAmbience[1]))
                    {
                        SoundManager.StopAmbience(prevAmbience[1]);
                        prevAmbience[1] = null;
                    }
                    SoundManager.PlayAmbience(biome.DayAmbience);
                }

                prevAmbience[0] = biome.DayAmbience;
            }

            if (!string.IsNullOrEmpty(biome.NightAmbience) && prevAmbience[1] != biome.NightAmbience)
            {
                prevAmbience[1] = biome.NightAmbience;

                SoundManager.PlayAmbience(biome.NightAmbience);
            }
        }
Ejemplo n.º 8
0
        public void CreateMigration()
        {
            int   tries   = 0;
            float padding = 2.0f;

            while (tries < 10)
            {
                int         side   = MathFunctions.Random.Next(4);
                BoundingBox bounds = World.ChunkManager.Bounds;
                Vector3     pos    = Vector3.Zero;
                switch (side)
                {
                case 0:
                    pos = new Vector3(bounds.Min.X + padding, bounds.Max.Y - padding, MathFunctions.Rand(bounds.Min.Z + padding, bounds.Max.Z - padding));
                    break;

                case 1:
                    pos = new Vector3(bounds.Max.X - padding, bounds.Max.Y - padding, MathFunctions.Rand(bounds.Min.Z + padding, bounds.Max.Z - padding));
                    break;

                case 2:
                    pos = new Vector3(MathFunctions.Rand(bounds.Min.X + padding, bounds.Max.X - padding), bounds.Max.Y - padding, bounds.Min.Z + padding);
                    break;

                case 3:
                    pos = new Vector3(MathFunctions.Rand(bounds.Min.X + padding, bounds.Max.X - padding), bounds.Max.Y - padding, bounds.Max.Z - padding);
                    break;
                }

                var biome = Overworld.GetBiomeAt(pos);
                if (biome.Fauna.Count == 0)
                {
                    tries++;
                    continue;
                }

                var randomFauna  = Datastructures.SelectRandom(biome.Fauna);
                var testCreature = EntityFactory.CreateEntity <GameComponent>(randomFauna.Name, Vector3.Zero);

                if (testCreature == null)
                {
                    tries++;
                    continue;
                }

                var testCreatureAI = testCreature.GetRoot().GetComponent <CreatureAI>();
                if (testCreatureAI == null || testCreatureAI.Movement.IsSessile)
                {
                    testCreature.GetRoot().Delete();
                    tries++;
                    continue;
                }


                var count = Creature.GetNumSpecies(testCreatureAI.Creature.Species);

                testCreature.GetRoot().Delete();

                if (count < 30)
                {
                    var randomNum = Math.Min(MathFunctions.RandInt(1, 3), 30 - count);
                    for (int i = 0; i < randomNum; i++)
                    {
                        var randompos = MathFunctions.Clamp(pos + MathFunctions.RandVector3Cube() * 2, World.ChunkManager.Bounds);
                        var vox       = VoxelHelpers.FindFirstVoxelBelow(new VoxelHandle(World.ChunkManager.ChunkData, GlobalVoxelCoordinate.FromVector3(pos)));
                        if (!vox.IsValid)
                        {
                            continue;
                        }
                        EntityFactory.CreateEntity <GameComponent>(randomFauna.Name, vox.GetBoundingBox().Center() + Vector3.Up * 1.5f);
                    }
                }
                break;
            }
        }
Ejemplo n.º 9
0
        private static void UpdateChunk(VoxelChunk chunk)
        {
            var addGrassToThese = new List <Tuple <VoxelHandle, byte> >();

            for (var y = 0; y < VoxelConstants.ChunkSizeY; ++y)
            {
                // Skip empty slices.
                if (chunk.Data.VoxelsPresentInSlice[y] == 0)
                {
                    continue;
                }

                for (var x = 0; x < VoxelConstants.ChunkSizeX; ++x)
                {
                    for (var z = 0; z < VoxelConstants.ChunkSizeZ; ++z)
                    {
                        var voxel = new VoxelHandle(chunk, new LocalVoxelCoordinate(x, y, z));

                        // Allow grass to decay
                        if (voxel.GrassType != 0)
                        {
                            var decal = GrassLibrary.GetGrassType(voxel.GrassType);

                            if (decal.NeedsSunlight && voxel.SunColor < 255)
                            {
                                voxel.GrassType = 0;
                            }
                            else if (decal.Decay)
                            {
                                voxel.GrassDecay -= 1;
                                if (voxel.GrassDecay == 0)
                                {
                                    var newDecal = GrassLibrary.GetGrassType(decal.BecomeWhenDecays);
                                    if (newDecal != null)
                                    {
                                        voxel.GrassType = newDecal.ID;
                                    }
                                    else
                                    {
                                        voxel.GrassType = 0;
                                    }
                                }
                            }
                        }
                        else if (voxel.Type.GrassSpreadsHere)
                        {
                            // Spread grass onto this tile - but only from the same biome.

                            var biome = Overworld.GetBiomeAt(voxel.Coordinate.ToVector3());

                            var grassyNeighbors = VoxelHelpers.EnumerateManhattanNeighbors2D(voxel.Coordinate)
                                                  .Select(c => new VoxelHandle(voxel.Chunk.Manager.ChunkData, c))
                                                  .Where(v => v.IsValid && v.GrassType != 0)
                                                  .Where(v => biome == Overworld.GetBiomeAt(v.Coordinate.ToVector3()))
                                                  .ToList();

                            if (grassyNeighbors.Count > 0)
                            {
                                if (MathFunctions.RandEvent(0.1f))
                                {
                                    addGrassToThese.Add(Tuple.Create(voxel, grassyNeighbors[MathFunctions.RandInt(0, grassyNeighbors.Count)].GrassType));
                                }
                            }
                        }
                    }
                }
            }

            foreach (var v in addGrassToThese)
            {
                var l         = v.Item1;
                var grassType = GrassLibrary.GetGrassType(v.Item2);
                if (grassType.NeedsSunlight && l.SunColor != 255)
                {
                    continue;
                }
                l.GrassType = v.Item2;
            }
        }