示例#1
0
文件: World.cs 项目: Arekva/winecrash
        public static void PlaceStructure(Structure structure, Vector3I position, bool eraseSolid = false)
        {
            Vector3I shift   = structure.Root;
            Vector3I origin  = position - shift;
            Vector3I extents = structure.Size;

            ConcurrentDictionary <Vector2I, Chunk> chunkCache = new ConcurrentDictionary <Vector2I, Chunk>();

            ushort[] blocks = structure.Blocks;

            ushort airID = ItemCache.GetIndex("winecrash:air");

            Parallel.For(0, blocks.Length, i =>
            {
                WMath.FlatTo3D(i, extents.X, extents.Y, out int localX, out int localY, out int localZ);

                Vector3I globalBpos = new Vector3I(localX, localY, localZ) + origin;

                GlobalToLocal(globalBpos, out Vector2I cpos, out Vector3I bpos);

                Chunk c;
                if (!chunkCache.TryGetValue(cpos, out c))
                {
                    c = GetChunk(cpos, "winecrash:overworld");
                    chunkCache.TryAdd(cpos, c);
                }

                if (c && (eraseSolid || c.GetBlockIndex(bpos.X, bpos.Y, bpos.Z) == airID))
                {
                    c.SetBlock(bpos.X, bpos.Y, bpos.Z, blocks[i]);
                }
            });
示例#2
0
文件: World.cs 项目: Arekva/winecrash
        private static ushort[] GenerateLandmass(Vector2I chunkCoords)
        {
            float globalScale = 1.0F;

            float baseLandmassScale = 0.005F; // lower => wider. yeah ik.
            float detailBias        = 0.0F;

            float oceanLevel         = 63;
            float landDeformity      = 40;
            float oceanDeformity     = 20;
            float landMaxHeight      = oceanLevel + landDeformity;
            float oceanMaxDepth      = oceanLevel - oceanDeformity;
            float mountainsDeformity = 10;
            float moutainsScale      = 0.01F;

            float maxLevel = 63 + 40;

            // this is meant to be used as a 2D base for continents     apparently unused \/
            IModule3D baseLandmass = new ImprovedPerlin(World.Seed.Value, NoiseQuality.Best);
            var       billow       = new Billow
            {
                Primitive3D = baseLandmass,
                OctaveCount = 5.0F,
                Frequency   = 0.9F,
            };
            IModule3D detailsLandmass = new ImprovedPerlin(World.Seed.Value * 123456, NoiseQuality.Best);

            detailsLandmass = new ScaleBias(detailsLandmass, .2F, detailBias);
            baseLandmass    = new Add(billow, detailsLandmass);
            //LibNoise.Modifier.Exponent baseLandExp = new Exponent(baseLandmass, 1.0F);

            //var combiner = new LibNoise.Combiner.Add(baseLandmass1, baseLandmass1);
            float oceanCoverage = 0.5F;

            ushort airID   = ItemCache.GetIndex("winecrash:air");
            ushort stoneID = ItemCache.GetIndex("winecrash:stone");

            ushort[] indices = new ushort[Chunk.Width * Chunk.Height * Chunk.Depth];

            Vector3F shift = Vector3F.Zero;

            Vector3F basePos = new Vector3F((chunkCoords.X * Chunk.Width) + shift.X, shift.Y, (chunkCoords.Y * Chunk.Depth) + shift.Z);

            for (int i = 0; i < Chunk.Width * Chunk.Height * Chunk.Depth; i++)
            {
                //Parallel.For(0, Chunk.Width * Chunk.Height * Chunk.Depth, i =>
                //{
                indices[i] = airID;

                // get, from index, the x,y,z coordinates of the block. Then move it from the basePos x scale.
                WMath.FlatTo3D(i, Chunk.Width, Chunk.Height, out int x, out int y, out int z);

                if (y > maxLevel)
                {
                    continue;
                }

                Vector3F finalPos = new Vector3F((basePos.X + x) * baseLandmassScale, basePos.Y + y,
                                                 (basePos.Z + z) * baseLandmassScale) * globalScale;

                float landMassPct = baseLandmass.GetValue(finalPos.X, 0, finalPos.Z);
                // retreive the 2D base land value (as seen from top). If under land cap, it's ocean.
                bool isLand = landMassPct > oceanCoverage;

                float landPct  = (float)Math.Pow(WMath.Remap(landMassPct, oceanCoverage, 1.0F, 0.0F, 1.0F), 2F);
                float waterPct = WMath.Remap(landMassPct, 0.0F, oceanCoverage, 0.0F, 1.0F);

                float landMassHeight      = oceanLevel + (landPct * landDeformity);
                int   finalLandMassHeight = (int)landMassHeight;

                float waterHeight      = oceanMaxDepth + (waterPct * oceanDeformity);
                int   finalWaterHeight = (int)waterHeight;

                if (isLand)
                {
                    if (y < finalLandMassHeight)
                    {
                        indices[i] = stoneID;
                    }
                }
                else if (y == oceanLevel - 1)
                {
                    //indices[i] = waterID;
                }
                else if (y < oceanLevel - 1)
                {
                    if (y > finalWaterHeight)
                    {
                        //indices[i] = waterID;
                    }
                    else
                    {
                        indices[i] = stoneID;
                    }
                }


                // debug: display this as grass / sand.


                //indices[i] = y == 63 ? (isLand ? grassID : sandID) : (y > 63 ? airID : debugID);//debug.GetValue(finalPos.X, finalPos.Y, finalPos.Z) < cap ? stoneID : airID;
                //});
            }

            return(indices);
        }