protected override void loadYPosAndThickness(IMapChunk heremapchunk, int lx, int lz, BlockPos targetPos, double distanceToEdge)
        {
            double curTh = depoitThickness * GameMath.Clamp(distanceToEdge * 2 - 0.2, 0, 1);

            hereThickness = (int)curTh + ((DepositRand.NextDouble() < (curTh - (int)curTh)) ? 1 : 0);

            targetPos.Y = heremapchunk.WorldGenTerrainHeightMap[lz * chunksize + lx] - posyi;
        }
        protected override void loadYPosAndThickness(IMapChunk heremapchunk, int lx, int lz, BlockPos pos, double distanceToEdge)
        {
            double curTh = depoitThickness * GameMath.Clamp(distanceToEdge * 2 - 0.2, 0, 1);

            hereThickness = (int)curTh + ((DepositRand.NextDouble() < (curTh - (int)curTh)) ? 1 : 0);

            int yOff = (int)getDepositYDistort(targetPos, lx, lz, step, heremapchunk);

            pos.Y = posyi + yOff;
        }
        protected override void loadYPosAndThickness(IMapChunk heremapchunk, int lx, int lz, BlockPos pos, double distanceToEdge)
        {
            hereThickness = depoitThickness;

            pos.Y  = (int)(depthf * heremapchunk.WorldGenTerrainHeightMap[lz * chunksize + lx]);
            pos.Y -= (int)getDepositYDistort(pos, lx, lz, step, heremapchunk);

            double curTh = depoitThickness * GameMath.Clamp(distanceToEdge * 2 - 0.2, 0, 1);

            hereThickness = (int)curTh + ((DepositRand.NextDouble() < (curTh - (int)curTh)) ? 1 : 0);
        }
Пример #4
0
        public override void GenDeposit(IBlockAccessor blockAccessor, IServerChunk[] chunks, int originChunkX, int originChunkZ, BlockPos pos, ref Dictionary <BlockPos, DepositVariant> subDepositsToPlace)
        {
            IMapChunk heremapchunk = chunks[0].MapChunk;

            int depositGradeIndex = PlaceBlock.AllowedVariants != null?DepositRand.NextInt(PlaceBlock.AllowedVariants.Length) : 0;

            int radius = Math.Min(64, (int)Radius.nextFloat(1, DepositRand));

            if (radius <= 0)
            {
                return;
            }
            radius++;

            bool  shouldGenSurfaceDeposit = DepositRand.NextFloat() > 0.35f && SurfaceBlock != null;
            float tries = RandomTries.nextFloat(1, DepositRand);

            for (int i = 0; i < tries; i++)
            {
                targetPos.Set(
                    pos.X + DepositRand.NextInt(2 * radius + 1) - radius,
                    pos.Y + DepositRand.NextInt(2 * radius + 1) - radius,
                    pos.Z + DepositRand.NextInt(2 * radius + 1) - radius
                    );

                int lx = targetPos.X % chunksize;
                int lz = targetPos.Z % chunksize;

                if (targetPos.Y <= 1 || targetPos.Y >= worldheight || lx < 0 || lz < 0 || lx >= chunksize || lz >= chunksize)
                {
                    continue;
                }

                int index3d = ((targetPos.Y % chunksize) * chunksize + lz) * chunksize + lx;
                int blockId = chunks[targetPos.Y / chunksize].Blocks[index3d];

                ResolvedDepositBlock resolvedPlaceBlock;

                if (placeBlockByInBlockId.TryGetValue(blockId, out resolvedPlaceBlock))
                {
                    Block placeblock = resolvedPlaceBlock.Blocks[depositGradeIndex];

                    if (variant.WithBlockCallback)
                    {
                        placeblock.TryPlaceBlockForWorldGen(blockAccessor, targetPos, BlockFacing.UP, DepositRand);
                    }
                    else
                    {
                        chunks[targetPos.Y / chunksize].Blocks[index3d] = placeblock.BlockId;
                    }

                    if (shouldGenSurfaceDeposit)
                    {
                        int   surfaceY = heremapchunk.RainHeightMap[lz * chunksize + lx];
                        int   depth    = surfaceY - targetPos.Y;
                        float chance   = SurfaceBlockChance * Math.Max(0, 1 - depth / 8f);
                        if (surfaceY < worldheight && DepositRand.NextFloat() < chance)
                        {
                            index3d = (((surfaceY + 1) % chunksize) * chunksize + lz) * chunksize + lx;

                            Block belowBlock = Api.World.Blocks[chunks[surfaceY / chunksize].Blocks[((surfaceY % chunksize) * chunksize + lz) * chunksize + lx]];

                            if (belowBlock.SideSolid[BlockFacing.UP.Index] && chunks[(surfaceY + 1) / chunksize].Blocks[index3d] == 0)
                            {
                                chunks[(surfaceY + 1) / chunksize].Blocks[index3d] = surfaceBlockByInBlockId[blockId].Blocks[0].BlockId;
                            }
                        }
                    }
                }
            }
        }
Пример #5
0
        public override void GenDeposit(IBlockAccessor blockAccessor, IServerChunk[] chunks, int chunkX, int chunkZ, BlockPos depoCenterPos, ref Dictionary <BlockPos, DepositVariant> subDepositsToPlace)
        {
            int depositGradeIndex = PlaceBlock.MaxGrade == 0 ? 0 : DepositRand.NextInt(PlaceBlock.MaxGrade);

            int radius = Math.Min(64, (int)Radius.nextFloat(1, DepositRand));

            if (radius <= 0)
            {
                return;
            }


            // Let's deform that perfect circle a bit (+/- 25%)
            float deform = GameMath.Clamp(DepositRand.NextFloat() - 0.5f, -0.25f, 0.25f);

            radiusX = radius - (int)(radius * deform);
            radiusZ = radius + (int)(radius * deform);


            int baseX = chunkX * chunksize;
            int baseZ = chunkZ * chunksize;


            // No need to caluclate further if this deposit won't be part of this chunk
            if (depoCenterPos.X + radiusX < baseX - 6 || depoCenterPos.Z + radiusZ < baseZ - 6 || depoCenterPos.X - radiusX >= baseX + chunksize + 6 || depoCenterPos.Z - radiusZ >= baseZ + chunksize + 6)
            {
                return;
            }

            IMapChunk heremapchunk = chunks[0].MapChunk;


            beforeGenDeposit(heremapchunk, depoCenterPos);

            // Ok generate
            float th = Thickness.nextFloat(1, DepositRand);

            depoitThickness = (int)th + (DepositRand.NextFloat() < th - (int)th ? 1 : 0);

            float xRadSqInv = 1f / (radiusX * radiusX);
            float zRadSqInv = 1f / (radiusZ * radiusZ);

            bool parentBlockOk = false;
            ResolvedDepositBlock resolvedPlaceBlock = null;


            bool shouldGenSurfaceDeposit = DepositRand.NextFloat() <= GenSurfaceBlockChance && SurfaceBlock != null;

            int lx = GameMath.Mod(depoCenterPos.X, chunksize);
            int lz = GameMath.Mod(depoCenterPos.Z, chunksize);
            int distx, distz;

            // No need to go search far beyond chunk boundaries
            int minx = baseX - 6;
            int maxx = baseX + chunksize + 6;
            int minz = baseZ - 6;
            int maxz = baseZ + chunksize + 6;

            minx = GameMath.Clamp(depoCenterPos.X - radiusX, minx, maxx);
            maxx = GameMath.Clamp(depoCenterPos.X + radiusX, minx, maxx);
            minz = GameMath.Clamp(depoCenterPos.Z - radiusZ, minz, maxz);
            maxz = GameMath.Clamp(depoCenterPos.Z + radiusZ, minz, maxz);

            //int placed = 0;

            float  invChunkAreaSize = 1f / (chunksize * chunksize);
            double val = 1;

            for (int posx = minx; posx < maxx; posx++)
            {
                targetPos.X = posx;
                lx          = targetPos.X - baseX;
                distx       = posx - depoCenterPos.X;

                float xSq = distx * distx * xRadSqInv;

                for (int posz = minz; posz < maxz; posz++)
                {
                    targetPos.Y = depoCenterPos.Y;
                    targetPos.Z = posz;
                    lz          = targetPos.Z - baseZ;
                    distz       = posz - depoCenterPos.Z;


                    // Kinda weird mathematically speaking, but seems to work as a means to distort the perfect circleness of deposits ¯\_(ツ)_/¯
                    // Also not very efficient to use direct perlin noise in here :/
                    // But after ~10 hours of failing (=weird lines of missing deposit material) with a pre-generated 2d distortion map i give up >.>
                    val = 1 - (radius > 3 ? DistortNoiseGen.Noise(targetPos.X / 3.0, targetPos.Z / 3.0) * 0.2 : 0);
                    double distanceToEdge = val - (xSq + distz * distz * zRadSqInv);

                    if (distanceToEdge < 0 || lx < 0 || lz < 0 || lx >= chunksize || lz >= chunksize)
                    {
                        continue;
                    }


                    loadYPosAndThickness(heremapchunk, lx, lz, targetPos, distanceToEdge);


                    // Some deposits may not appear all over cliffs
                    if (Math.Abs(depoCenterPos.Y - targetPos.Y) > MaxYRoughness)
                    {
                        continue;
                    }


                    for (int y = 0; y < hereThickness; y++)
                    {
                        if (targetPos.Y <= 1 || targetPos.Y >= worldheight)
                        {
                            continue;
                        }

                        int index3d = ((targetPos.Y % chunksize) * chunksize + lz) * chunksize + lx;
                        int blockId = chunks[targetPos.Y / chunksize].Blocks[index3d];


                        if (!IgnoreParentTestPerBlock || !parentBlockOk)
                        {
                            parentBlockOk = placeBlockByInBlockId.TryGetValue(blockId, out resolvedPlaceBlock);
                        }

                        if (parentBlockOk && resolvedPlaceBlock.Blocks.Length > 0)
                        {
                            int gradeIndex = Math.Min(resolvedPlaceBlock.Blocks.Length - 1, depositGradeIndex);

                            Block placeblock = resolvedPlaceBlock.Blocks[gradeIndex];

                            if (variant.WithBlockCallback || (WithLastLayerBlockCallback && y == hereThickness - 1))
                            {
                                placeblock.TryPlaceBlockForWorldGen(blockAccessor, targetPos.Copy(), BlockFacing.UP, rand);
                            }
                            else
                            {
                                chunks[targetPos.Y / chunksize].Blocks[index3d] = placeblock.BlockId;
                                //placed++;
                            }

                            if (variant.ChildDeposits != null)
                            {
                                for (int i = 0; i < variant.ChildDeposits.Length; i++)
                                {
                                    float rndVal   = DepositRand.NextFloat();
                                    float quantity = variant.ChildDeposits[i].TriesPerChunk * invChunkAreaSize;

                                    if (quantity > rndVal)
                                    {
                                        if (ShouldPlaceAdjustedForOreMap(variant.ChildDeposits[i], targetPos.X, targetPos.Z, quantity, rndVal))
                                        {
                                            subDepositsToPlace[targetPos.Copy()] = variant.ChildDeposits[i];
                                        }
                                    }
                                }
                            }

                            if (shouldGenSurfaceDeposit)
                            {
                                int   surfaceY = heremapchunk.RainHeightMap[lz * chunksize + lx];
                                int   depth    = surfaceY - targetPos.Y;
                                float chance   = SurfaceBlockChance * Math.Max(0, 1.11f - depth / 9f);
                                if (surfaceY < worldheight && DepositRand.NextFloat() < chance)
                                {
                                    Block belowBlock = Api.World.Blocks[chunks[surfaceY / chunksize].Blocks[((surfaceY % chunksize) * chunksize + lz) * chunksize + lx]];

                                    index3d = (((surfaceY + 1) % chunksize) * chunksize + lz) * chunksize + lx;
                                    if (belowBlock.SideSolid[BlockFacing.UP.Index] && chunks[(surfaceY + 1) / chunksize].Blocks[index3d] == 0)
                                    {
                                        chunks[(surfaceY + 1) / chunksize].Blocks[index3d] = surfaceBlockByInBlockId[blockId].Blocks[0].BlockId;
                                    }
                                }
                            }
                        }

                        targetPos.Y--;
                    }
                }
            }

            //Console.WriteLine("placed {0} blocks", placed);
        }
Пример #6
0
        public override void GenDeposit(IBlockAccessor blockAccessor, IServerChunk[] chunks, int chunkX, int chunkZ, BlockPos depoCenterPos, ref Dictionary <BlockPos, DepositVariant> subDepositsToPlace)
        {
            int radius = Math.Min(64, (int)Radius.nextFloat(1, DepositRand));

            if (radius <= 0)
            {
                return;
            }

            // Let's deform that perfect circle a bit (+/- 25%)
            float deform = GameMath.Clamp(DepositRand.NextFloat() - 0.5f, -0.25f, 0.25f);

            radiusX = radius - (int)(radius * deform);
            radiusZ = radius + (int)(radius * deform);


            int baseX = chunkX * chunksize;
            int baseZ = chunkZ * chunksize;


            // No need to caluclate further if this deposit won't be part of this chunk
            if (depoCenterPos.X + radiusX < baseX - 6 || depoCenterPos.Z + radiusZ < baseZ - 6 || depoCenterPos.X - radiusX >= baseX + chunksize + 6 || depoCenterPos.Z - radiusZ >= baseZ + chunksize + 6)
            {
                return;
            }

            IMapChunk heremapchunk = chunks[0].MapChunk;


            // Ok generate
            float th = Thickness.nextFloat(1, DepositRand);
            float depoitThickness = (int)th + (DepositRand.NextFloat() < th - (int)th ? 1 : 0);

            float xRadSqInv = 1f / (radiusX * radiusX);
            float zRadSqInv = 1f / (radiusZ * radiusZ);

            int lx = GameMath.Mod(depoCenterPos.X, chunksize);
            int lz = GameMath.Mod(depoCenterPos.Z, chunksize);
            int distx, distz;

            // No need to go search far beyond chunk boundaries
            int minx = baseX - 6;
            int maxx = baseX + chunksize + 6;
            int minz = baseZ - 6;
            int maxz = baseZ + chunksize + 6;

            minx = GameMath.Clamp(depoCenterPos.X - radiusX, minx, maxx);
            maxx = GameMath.Clamp(depoCenterPos.X + radiusX, minx, maxx);
            minz = GameMath.Clamp(depoCenterPos.Z - radiusZ, minz, maxz);
            maxz = GameMath.Clamp(depoCenterPos.Z + radiusZ, minz, maxz);

            float  invChunkAreaSize = 1f / (chunksize * chunksize);
            double val = 1;

            IList <Block> blocktypes = Api.World.Blocks;

            bool doGravel = DepositRand.NextFloat() > 0.33;

            for (int posx = minx; posx < maxx; posx++)
            {
                targetPos.X = posx;
                lx          = targetPos.X - baseX;
                distx       = posx - depoCenterPos.X;

                float xSq = distx * distx * xRadSqInv;

                for (int posz = minz; posz < maxz; posz++)
                {
                    targetPos.Z = posz;
                    lz          = targetPos.Z - baseZ;
                    distz       = posz - depoCenterPos.Z;

                    // Kinda weird mathematically speaking, but seems to work as a means to distort the perfect circleness of deposits ¯\_(ツ)_/¯
                    // Also not very efficient to use direct perlin noise in here :/
                    // But after ~10 hours of failing (=weird lines of missing deposit material) with a pre-generated 2d distortion map i give up >.>
                    val = 1 - DistortNoiseGen.Noise(targetPos.X / 3.0, targetPos.Z / 3.0) * 1.5 + 0.15;
                    double distanceToEdge = val - (xSq + distz * distz * zRadSqInv);

                    if (distanceToEdge < 0 || lx < 0 || lz < 0 || lx >= chunksize || lz >= chunksize)
                    {
                        continue;
                    }

                    targetPos.Y = heremapchunk.WorldGenTerrainHeightMap[lz * chunksize + lx];

                    // Some deposits may not appear all over cliffs
                    if (Math.Abs(depoCenterPos.Y - targetPos.Y) > MaxYRoughness)
                    {
                        continue;
                    }

                    int rockblockid = heremapchunk.TopRockIdMap[lz * chunksize + lx];

                    Block rockblock = blocktypes[rockblockid];
                    if (!rockblock.Variant.ContainsKey("rock"))
                    {
                        continue;
                    }

                    Block alluvialblock;

                    if (doGravel)
                    {
                        alluvialblock = Api.World.GetBlock(new AssetLocation("gravel-" + rockblock.Variant["rock"]));
                    }
                    else
                    {
                        alluvialblock = Api.World.GetBlock(new AssetLocation("sand-" + rockblock.Variant["rock"]));
                    }


                    for (int y = 0; y < depoitThickness; y++)
                    {
                        if (targetPos.Y <= 1 || targetPos.Y >= worldheight)
                        {
                            continue;
                        }

                        int index3d = ((targetPos.Y % chunksize) * chunksize + lz) * chunksize + lx;
                        int blockId = chunks[targetPos.Y / chunksize].Blocks[index3d];

                        Block block = blocktypes[blockId];

                        if (block.BlockMaterial != EnumBlockMaterial.Soil)
                        {
                            continue;
                        }

                        if (alluvialblock != null)
                        {
                            chunks[targetPos.Y / chunksize].Blocks[index3d] = alluvialblock.BlockId;
                        }

                        targetPos.Y--;
                    }
                }
            }
        }