コード例 #1
0
        public DepositVariant Clone()
        {
            DepositVariant var = new DepositVariant()
            {
                fromFile          = fromFile,
                Code              = Code,
                TriesPerChunk     = TriesPerChunk,
                Generator         = Generator,
                WithOreMap        = WithOreMap,
                WithBlockCallback = WithBlockCallback,
                Attributes        = Attributes?.Clone(),
                Climate           = Climate?.Clone(),
                ChildDeposits     = ChildDeposits == null ? null : (DepositVariant[])ChildDeposits.Clone(),
                OreMapLayer       = OreMapLayer,
            };

            foreach (var val in ChildDeposits)
            {
                val.parentDeposit = var;
            }

            var.GeneratorInst = DepositGeneratorRegistry.CreateGenerator(Generator, Attributes, api, var, GeneratorInst.DepositRand, GeneratorInst.DistortNoiseGen);

            return(var);
        }
コード例 #2
0
ファイル: GenDeposits.cs プロジェクト: bitcynth/vssurvivalmod
        private void OnMapRegionGen(IMapRegion mapRegion, int regionX, int regionZ)
        {
            IntMap map;

            for (int i = 0; i < deposits.variants.Length; i++)
            {
                DepositVariant variant = deposits.variants[i];
                if (variant.OreMap != null)
                {
                    map      = new IntMap();
                    map.Size = noiseSizeOre + 1;
                    map.BottomRightPadding = 1;
                    map.Data = variant.OreMap.GenLayer(regionX * noiseSizeOre, regionZ * noiseSizeOre, noiseSizeOre + 1, noiseSizeOre + 1);
                    mapRegion.OreMaps[variant.Code] = map;
                }

                if (variant.ChildDeposits != null)
                {
                    for (int k = 0; k < variant.ChildDeposits.Length; k++)
                    {
                        DepositVariant childVariant = variant.ChildDeposits[k];
                        if (childVariant.OreMap != null)
                        {
                            map      = new IntMap();
                            map.Size = noiseSizeOre + 1;
                            map.BottomRightPadding = 1;
                            map.Data = childVariant.OreMap.GenLayer(regionX * noiseSizeOre, regionZ * noiseSizeOre, noiseSizeOre + 1, noiseSizeOre + 1);
                            mapRegion.OreMaps[childVariant.Code] = map;
                        }
                    }
                }
            }
        }
コード例 #3
0
        public void OnMapRegionGen(IMapRegion mapRegion, int regionX, int regionZ)
        {
            IntDataMap2D map;

            if (OreMapLayer != null && !mapRegion.OreMaps.ContainsKey(Code))
            {
                map      = new IntDataMap2D();
                map.Size = noiseSizeOre + 1;
                map.BottomRightPadding = 1;
                map.Data = OreMapLayer.GenLayer(regionX * noiseSizeOre, regionZ * noiseSizeOre, noiseSizeOre + 1, noiseSizeOre + 1);
                mapRegion.OreMaps[Code] = map;
            }

            if (ChildDeposits != null)
            {
                for (int k = 0; k < ChildDeposits.Length; k++)
                {
                    DepositVariant childVariant = ChildDeposits[k];
                    if (childVariant.OreMapLayer != null && !mapRegion.OreMaps.ContainsKey(childVariant.Code))
                    {
                        map      = new IntDataMap2D();
                        map.Size = noiseSizeOre + 1;
                        map.BottomRightPadding = 1;
                        map.Data = childVariant.OreMapLayer.GenLayer(regionX * noiseSizeOre, regionZ * noiseSizeOre, noiseSizeOre + 1, noiseSizeOre + 1);
                        mapRegion.OreMaps[childVariant.Code] = map;
                    }
                }
            }
        }
コード例 #4
0
        public void OnMapRegionGen(IMapRegion mapRegion, int regionX, int regionZ)
        {
            int pad = 2;

            TerraGenConfig.depositVerticalDistortScale = 2;
            int noiseSize = api.WorldManager.RegionSize / TerraGenConfig.depositVerticalDistortScale;

            IntDataMap2D map = mapRegion.OreMapVerticalDistortBottom;

            map.Size = noiseSize + 2 * pad;
            map.BottomRightPadding = map.TopLeftPadding = pad;
            map.Data = verticalDistortBottom.GenLayer(regionX * noiseSize - pad, regionZ * noiseSize - pad, noiseSize + 2 * pad, noiseSize + 2 * pad);

            map      = mapRegion.OreMapVerticalDistortTop;
            map.Size = noiseSize + 2 * pad;
            map.BottomRightPadding = map.TopLeftPadding = pad;
            map.Data = verticalDistortTop.GenLayer(regionX * noiseSize - pad, regionZ * noiseSize - pad, noiseSize + 2 * pad, noiseSize + 2 * pad);


            for (int i = 0; i < Deposits.Length; i++)
            {
                DepositVariant variant = Deposits[i];
                variant.OnMapRegionGen(mapRegion, regionX, regionZ);
            }
        }
コード例 #5
0
ファイル: GenDeposits.cs プロジェクト: bitcynth/vssurvivalmod
        private bool ShouldPlaceAdjustedForOreMap(DepositVariant variant, int posX, int posZ, float quantity, float rndVal)
        {
            if (!variant.WithOreMap)
            {
                return(true);
            }

            float      quantityFactor  = 1;
            IMapRegion originMapRegion = api.WorldManager.GetMapRegion((posX) / regionSize, (posZ) / regionSize);

            if (originMapRegion == null)
            {
                return(false);
            }
            int lx = posX % regionSize;
            int lz = posZ % regionSize;

            IntMap map = null;

            originMapRegion.OreMaps.TryGetValue(variant.Code, out map);
            if (map != null)
            {
                float posXInRegionOre = (float)lx / regionSize * noiseSizeOre;
                float posZInRegionOre = (float)lz / regionSize * noiseSizeOre;

                int oreDist = originMapRegion.OreMaps[variant.Code].GetUnpaddedColorLerped(posXInRegionOre, posZInRegionOre);

                quantityFactor = (oreDist & 0xff) / 255f;
            }

            return(quantity * quantityFactor > rndVal);
        }
コード例 #6
0
ファイル: GenDeposits.cs プロジェクト: bitcynth/vssurvivalmod
        internal override void GeneratePartial(IServerChunk[] chunks, int intoChunkX, int intoChunkZ, int fromChunkdX, int fromChunkdZ)
        {
            for (int i = 0; i < deposits.variants.Length; i++)
            {
                DepositVariant variant = deposits.variants[i];

                float quantityFactor = 1;
                int   originChunkX   = intoChunkX + fromChunkdX;
                int   originChunkZ   = intoChunkZ + fromChunkdZ;

                if (variant.WithOreMap)
                {
                    IMapRegion originMapRegion = api.WorldManager.GetMapRegion((originChunkX * chunksize) / regionSize, (originChunkZ * chunksize) / regionSize);
                    if (originMapRegion == null)
                    {
                        continue;
                    }
                    int lx = (originChunkX * chunksize + chunksize / 2) % regionSize;
                    int lz = (originChunkZ * chunksize + chunksize / 2) % regionSize;

                    IntMap map = null;
                    originMapRegion.OreMaps.TryGetValue(variant.Code, out map);
                    if (map != null)
                    {
                        float posXInRegionOre = GameMath.Clamp((float)lx / regionSize * noiseSizeOre, 0, noiseSizeOre - 1);
                        float posZInRegionOre = GameMath.Clamp((float)lz / regionSize * noiseSizeOre, 0, noiseSizeOre - 1);

                        int oreDist = originMapRegion.OreMaps[variant.Code].GetUnpaddedColorLerped(posXInRegionOre, posZInRegionOre);

                        quantityFactor = (oreDist & 0xff) / 255f;
                    }
                }

                float qModified = variant.Quantity * quantityFactor;
                int   quantity  = (int)qModified;
                quantity += chunkRand.NextInt(100) < 100 * (qModified - quantity) ? 1 : 0;


                while (quantity-- > 0)
                {
                    int offsetX = chunksize * fromChunkdX + chunkRand.NextInt(chunksize);
                    int offsetZ = chunksize * fromChunkdZ + chunkRand.NextInt(chunksize);

                    depositRand.SetWorldSeed(chunkRand.NextInt(10000000));
                    depositRand.InitPositionSeed(intoChunkX + fromChunkdX, intoChunkZ + fromChunkdZ);

                    Dictionary <Vec3i, DepositVariant> SubDepositsToPlace = GenDeposit(chunks, intoChunkX, intoChunkZ, offsetX, offsetZ, variant);


                    foreach (var val in SubDepositsToPlace)
                    {
                        depositRand.SetWorldSeed(chunkRand.NextInt(10000000));
                        depositRand.InitPositionSeed(intoChunkX + fromChunkdX, intoChunkZ + fromChunkdZ);

                        GenDeposit(chunks, intoChunkX, intoChunkZ, val.Key.X, val.Key.Z, val.Value, val.Key.Y);
                    }
                }
            }
        }
コード例 #7
0
        public DepositGeneratorBase(ICoreServerAPI api, DepositVariant variant, LCGRandom depositRand, NormalizedSimplexNoise noiseGen)
        {
            this.variant         = variant;
            this.Api             = api;
            this.DepositRand     = depositRand;
            this.DistortNoiseGen = noiseGen;

            rand = new Random(api.World.Seed);
        }
コード例 #8
0
        protected DiscDepositGenerator(ICoreServerAPI api, DepositVariant variant, LCGRandom depositRand, NormalizedSimplexNoise noiseGen) : base(api, variant, depositRand, noiseGen)
        {
            chunksize   = api.World.BlockAccessor.ChunkSize;
            worldheight = api.World.BlockAccessor.MapSizeY;



            regionSize       = api.WorldManager.RegionSize;
            regionChunkSize  = api.WorldManager.RegionSize / chunksize;
            noiseSizeClimate = regionSize / TerraGenConfig.climateMapScale;
            noiseSizeOre     = regionSize / TerraGenConfig.oreMapScale;
        }
コード例 #9
0
        public override void GeneratePartial(IServerChunk[] chunks, int chunkX, int chunkZ, int chunkdX, int chunkdZ)
        {
            int fromChunkx = chunkX + chunkdX;
            int fromChunkz = chunkZ + chunkdZ;

            int fromBaseX = fromChunkx * chunksize;
            int fromBaseZ = fromChunkz * chunksize;

            subDepositsToPlace.Clear();

            float qfac = 1f;// chunks.Length / 8f;

            for (int i = 0; i < Deposits.Length; i++)
            {
                DepositVariant variant = Deposits[i];

                /*if (variant.Code != "sphalerite" || chunkdX != 0 || chunkdZ != 0)
                 * {
                 *  continue;
                 * }*/

                float quantityFactor = variant.WithOreMap ? variant.GetOreMapFactor(fromChunkx, fromChunkz) : 1;

                float qModified = qfac * variant.TriesPerChunk * quantityFactor * chanceMultiplier;
                int   quantity  = (int)qModified;
                quantity += chunkRand.NextInt(100) < 100 * (qModified - quantity) ? 1 : 0;

                while (quantity-- > 0)
                {
                    tmpPos.Set(fromBaseX + chunkRand.NextInt(chunksize), -99, fromBaseZ + chunkRand.NextInt(chunksize));
                    long crseed = chunkRand.NextInt(10000000);
                    depositRand.SetWorldSeed(crseed);
                    depositRand.InitPositionSeed(fromChunkx, fromChunkz);

                    GenDeposit(chunks, chunkX, chunkZ, tmpPos, variant);
                }
            }

            foreach (var val in subDepositsToPlace)
            {
                depositRand.SetWorldSeed(chunkRand.NextInt(10000000));
                depositRand.InitPositionSeed(fromChunkx, fromChunkz);

                val.Value.GeneratorInst.GenDeposit(blockAccessor, chunks, chunkX, chunkZ, val.Key, ref subDepositsToPlace);
            }
        }
コード例 #10
0
ファイル: GenDeposits.cs プロジェクト: bitcynth/vssurvivalmod
        internal override void OnGameWorldLoaded()
        {
            base.OnGameWorldLoaded();

            regionSize       = api.WorldManager.RegionSize;
            regionChunkSize  = api.WorldManager.RegionSize / chunksize;
            noiseSizeClimate = regionSize / TerraGenConfig.climateMapScale;
            noiseSizeOre     = regionSize / TerraGenConfig.oreMapScale;

            int seed = api.WorldManager.Seed;

            for (int i = 0; i < deposits.variants.Length; i++)
            {
                DepositVariant variant = deposits.variants[i];
                variant.Init(api);

                if (variant.WithOreMap)
                {
                    NoiseOre noiseOre = new NoiseOre(seed++);
                    variant.OreMap = GenMaps.GetOreMap(seed++, noiseOre);
                }

                if (variant.ChildDeposits != null)
                {
                    for (int k = 0; k < variant.ChildDeposits.Length; k++)
                    {
                        DepositVariant childVariant = variant.ChildDeposits[k];
                        if (childVariant.WithOreMap)
                        {
                            NoiseOre noiseOre = new NoiseOre(seed++);
                            childVariant.OreMap = GenMaps.GetOreMap(seed++, noiseOre);
                        }
                    }
                }
            }

            depositRand = new FastPositionalRandom(api.WorldManager.Seed + 34613);

            blockTypes = api.World.Blocks;
        }
コード例 #11
0
 public ChildDepositGenerator(ICoreServerAPI api, DepositVariant variant, LCGRandom depositRand, NormalizedSimplexNoise noiseGen) : base(api, variant, depositRand, noiseGen)
 {
 }
コード例 #12
0
        public virtual void GenDeposit(IServerChunk[] chunks, int chunkX, int chunkZ, BlockPos depoCenterPos, DepositVariant variant)
        {
            int lx = GameMath.Mod(depoCenterPos.X, chunksize);
            int lz = GameMath.Mod(depoCenterPos.Z, chunksize);

            // Check if suited for this area, climate wise
            if (variant.Climate != null)
            {
                IMapChunk originMapchunk = api.WorldManager.GetMapChunk(depoCenterPos.X / chunksize, depoCenterPos.Z / chunksize);

                if (originMapchunk == null)
                {
                    return;                         // Definition: Climate dependent deposits are limited to size 32x32x32
                }
                depoCenterPos.Y = originMapchunk.RainHeightMap[lz * chunksize + lx];

                IntDataMap2D climateMap = blockAccessor.GetMapRegion(depoCenterPos.X / regionSize, depoCenterPos.Z / regionSize).ClimateMap;

                float posXInRegionClimate = ((float)lx / regionSize - (float)lx / regionSize) * noiseSizeClimate;
                float posZInRegionClimate = ((float)lz / regionSize - (float)lz / regionSize) * noiseSizeClimate;

                int   climate = climateMap.GetUnpaddedColorLerped(posXInRegionClimate, posZInRegionClimate);
                float temp    = TerraGenConfig.GetScaledAdjustedTemperatureFloat((climate >> 16) & 0xff, depoCenterPos.Y - TerraGenConfig.seaLevel);
                float rainRel = TerraGenConfig.GetRainFall((climate >> 8) & 0xff, depoCenterPos.Y) / 255f;

                if (rainRel < variant.Climate.MinRain || rainRel > variant.Climate.MaxRain || temp < variant.Climate.MinTemp || temp > variant.Climate.MaxTemp)
                {
                    return;
                }
            }

            variant.GeneratorInst?.GenDeposit(blockAccessor, chunks, chunkX, chunkZ, depoCenterPos, ref subDepositsToPlace);
        }
コード例 #13
0
        public void initWorldGen(bool blockCallbacks)
        {
            base.initWorldGen();

            chanceMultiplier = api.Assets.Get("worldgen/deposits.json").ToObject <Deposits>().ChanceMultiplier;

            Dictionary <AssetLocation, DepositVariant[]> depositFiles = api.Assets.GetMany <DepositVariant[]>(api.World.Logger, "worldgen/deposits/");
            List <DepositVariant> variants = new List <DepositVariant>();


            foreach (var val in depositFiles)
            {
                foreach (var depo in val.Value)
                {
                    depo.fromFile           = val.Key.ToString();
                    depo.WithBlockCallback &= blockCallbacks;

                    variants.Add(depo);

                    if (depo.ChildDeposits != null)
                    {
                        foreach (var childdepo in depo.ChildDeposits)
                        {
                            childdepo.fromFile           = val.Key.ToString();
                            childdepo.parentDeposit      = depo;
                            childdepo.WithBlockCallback &= blockCallbacks;
                        }
                    }
                }
            }

            Deposits = variants.ToArray();


            depositShapeDistortNoise = NormalizedSimplexNoise.FromDefaultOctaves(3, 1 / 10f, 0.9f, 1);

            regionSize       = api.WorldManager.RegionSize;
            noiseSizeClimate = regionSize / TerraGenConfig.climateMapScale;


            int seed = api.WorldManager.Seed;

            depositRand = new LCGRandom(api.WorldManager.Seed + 34613);

            Dictionary <string, MapLayerBase> maplayersByCode = new Dictionary <string, MapLayerBase>();

            for (int i = 0; i < Deposits.Length; i++)
            {
                DepositVariant variant = Deposits[i];
                variant.Init(api, depositRand, depositShapeDistortNoise);

                if (variant.WithOreMap)
                {
                    variant.OreMapLayer = getOrCreateMapLayer(seed, variant.Code, maplayersByCode, variant.OreMapScale, variant.OreMapContrast, variant.OreMapSub);
                }

                if (variant.ChildDeposits != null)
                {
                    for (int k = 0; k < variant.ChildDeposits.Length; k++)
                    {
                        DepositVariant childVariant = variant.ChildDeposits[k];
                        if (childVariant.WithOreMap)
                        {
                            childVariant.OreMapLayer = getOrCreateMapLayer(seed, childVariant.Code, maplayersByCode, variant.OreMapScale, variant.OreMapContrast, variant.OreMapSub);
                        }
                    }
                }
            }

            verticalDistortBottom = GenMaps.GetDepositVerticalDistort(seed + 12);
            verticalDistortTop    = GenMaps.GetDepositVerticalDistort(seed + 28);
        }
コード例 #14
0
 public AlluvialDepositGenerator(ICoreServerAPI api, DepositVariant variant, LCGRandom depositRand, NormalizedSimplexNoise noiseGen) : base(api, variant, depositRand, noiseGen)
 {
     chunksize   = api.World.BlockAccessor.ChunkSize;
     worldheight = api.World.BlockAccessor.MapSizeY;
 }
コード例 #15
0
 private bool ShouldPlaceAdjustedForOreMap(DepositVariant variant, int posX, int posZ, float quantity, float rndVal)
 {
     return(!variant.WithOreMap || (variant.GetOreMapFactor(posX / chunksize, posZ / chunksize) * quantity > rndVal));
 }
コード例 #16
0
 public virtual DepositVariant[] Resolve(DepositVariant sourceVariant)
 {
     return(new DepositVariant[] { sourceVariant });
 }
コード例 #17
0
 public FollowSealevelDiscGenerator(ICoreServerAPI api, DepositVariant variant, LCGRandom depositRand, NormalizedSimplexNoise noiseGen) : base(api, variant, depositRand, noiseGen)
 {
 }
コード例 #18
0
ファイル: GenDeposits.cs プロジェクト: bitcynth/vssurvivalmod
        /// <summary>
        /// forceInitialPosY is for subdeposits
        /// </summary>
        /// <param name="chunks"></param>
        /// <param name="chunkX"></param>
        /// <param name="chunkZ"></param>
        /// <param name="offsetX"></param>
        /// <param name="offsetZ"></param>
        /// <param name="variant"></param>
        /// <param name="forceInitialPosY"></param>
        /// <returns></returns>
        Dictionary <Vec3i, DepositVariant> GenDeposit(IServerChunk[] chunks, int chunkX, int chunkZ, int offsetX, int offsetZ, DepositVariant variant, int?forceInitialPosY = null)
        {
            Dictionary <Vec3i, DepositVariant> SubDepositsToPlace = new Dictionary <Vec3i, DepositVariant>();

            IMapChunk mapchunk = chunks[0].MapChunk;

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

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

            // Let's deform that perfect circle a bit (+/- 25%)
            float deform  = GameMath.Clamp(depositRand.NextFloat() - 0.5f, -0.25f, 0.25f);
            int   radiusX = radius - (int)(radius * deform);
            int   radiusZ = radius + (int)(radius * deform);
            int   posY;

            // No need to caluclate further if this deposit won't be part of this chunk
            if (radiusX + offsetX < 0 || radiusZ + offsetZ < 0 || offsetX - radiusX >= chunksize || offsetZ - radiusZ >= chunksize)
            {
                return(SubDepositsToPlace);
            }


            IMapChunk originMapchunk = null;
            int       origPosY       = 0;

            int lx = GameMath.Mod(offsetX, chunksize);
            int lz = GameMath.Mod(offsetZ, chunksize);

            if (variant.MaxY < 1 || variant.CheckClimate)
            {
                originMapchunk = api.WorldManager.GetMapChunk((chunkX * chunksize + offsetX) / chunksize, (chunkZ * chunksize + offsetZ) / chunksize);
                if (originMapchunk == null)
                {
                    return(SubDepositsToPlace);                        // argh >.<
                }
                origPosY = originMapchunk.RainHeightMap[lz * chunksize + lx];
                if ((float)origPosY / api.World.BlockAccessor.MapSizeY > variant.MaxY)
                {
                    return(SubDepositsToPlace);
                }
            }



            // Check if suited for this area, climate wise
            if (variant.CheckClimate)
            {
                IntMap climateMap = api.World.BlockAccessor.GetMapRegion((chunkX * chunksize + offsetX) / regionSize, (chunkZ * chunksize + offsetZ) / regionSize).ClimateMap;

                float posXInRegionClimate = ((float)lx / regionSize - lx / regionSize) * noiseSizeClimate;
                float posZInRegionClimate = ((float)lz / regionSize - lz / regionSize) * noiseSizeClimate;

                int   climate = climateMap.GetUnpaddedColorLerped(posXInRegionClimate, posZInRegionClimate);
                float temp    = TerraGenConfig.GetScaledAdjustedTemperatureFloat((climate >> 16) & 0xff, origPosY - TerraGenConfig.seaLevel);
                float rainRel = TerraGenConfig.GetRainFall((climate >> 8) & 0xff, origPosY) / 255f;

                if (rainRel < variant.MinRain || rainRel > variant.MaxRain || temp < variant.MinTemp || temp > variant.MaxTemp)
                {
                    return(SubDepositsToPlace);
                }
            }


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

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

            int  blockIndex    = 0;
            bool parentBlockOk = false;

            float depthf;

            bool shouldGenSurfaceDeposit = depositRand.NextFloat() > 0.35f && variant.SurfaceBlockCode != null;

            if (forceInitialPosY != null)
            {
                depthf = (float)forceInitialPosY / mapchunk.WorldGenTerrainHeightMap[offsetX * chunksize + offsetZ];
            }
            else
            {
                depthf = variant.Depth.nextFloat(1, depositRand);
            }

            int depthi = (int)depthf;

            int topLeft  = 2 * depositRand.NextInt(radiusX + 1) - radiusX;
            int topRight = 2 * depositRand.NextInt(radiusZ + 1) - radiusZ;
            int botLeft  = 2 * depositRand.NextInt(radiusX + 1) - radiusX;
            int botRight = 2 * depositRand.NextInt(radiusZ + 1) - radiusZ;
            int yOff     = 0;

            // Only generate inside this current chunk column
            int minx = GameMath.Clamp(offsetX - radiusX, 0, chunksize);
            int maxx = GameMath.Clamp(offsetX + radiusX, 0, chunksize);
            int minz = GameMath.Clamp(offsetZ - radiusZ, 0, chunksize);
            int maxz = GameMath.Clamp(offsetZ + radiusZ, 0, chunksize);

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

            for (int x = minx; x < maxx; x++)
            {
                float xSq = (x - offsetX) * (x - offsetX) * xRadSqInv;
                for (int z = minz; z < maxz; z++)
                {
                    if (xSq + (z - offsetZ) * (z - offsetZ) * zRadSqInv > 1)
                    {
                        continue;
                    }

                    if (variant.Placement == EnumDepositPlacement.FollowSurfaceBelow)
                    {
                        posY = mapchunk.WorldGenTerrainHeightMap[z * chunksize + x] - depthi;
                    }
                    else if (variant.Placement == EnumDepositPlacement.FollowSurface)
                    {
                        yOff = (int)GameMath.BiLerp(topLeft, topRight, botLeft, botRight, (x - offsetX + radiusX) / (2f * radiusX), (z - offsetZ + radiusZ) / (2f * radiusZ));

                        posY = (int)(depthf * mapchunk.WorldGenTerrainHeightMap[z * chunksize + x]) + yOff / 2;
                    }
                    else if (variant.Placement == EnumDepositPlacement.Straight)
                    {
                        posY = (int)(depthf * mapchunk.WorldGenTerrainHeightMap[z * chunksize + x]);
                    }
                    else
                    {
                        yOff = (int)GameMath.BiLerp(topLeft, topRight, botLeft, botRight, (x - offsetX + radiusX) / (2f * radiusX), (z - offsetZ + radiusZ) / (2f * radiusZ));

                        posY = depthi + yOff;
                    }

                    // Some deposits may not appear all over cliffs
                    if (variant.CheckClimate && Math.Abs(origPosY - posY) > variant.MaxYRoughness)
                    {
                        continue;
                    }

                    for (int y = 0; y < thickness; y++)
                    {
                        if (posY <= 1 || posY >= worldheight)
                        {
                            continue;
                        }

                        long   index3d = ((posY % chunksize) * chunksize + z) * chunksize + x;
                        ushort blockId = chunks[posY / chunksize].Blocks[index3d];

                        // Check if we are in mother material, but only if it has changed since last iteration (should reduce amount of these checks by 50-100%)
                        parentBlockOk = false;
                        for (int i = 0; i < variant.ParentBlockIds.Length; i++)
                        {
                            if (variant.ParentBlockIds[i] == blockId)
                            {
                                parentBlockOk = true;
                                blockIndex    = i;
                                break;
                            }
                        }

                        if (parentBlockOk)
                        {
                            if (variant.WithBlockCallback)
                            {
                                tmpPos.Set(chunkX * chunksize + x, posY, chunkZ * chunksize + z);
                                blockTypes[variant.BlockIds[blockIndex]].TryPlaceBlockForWorldGen(blockAccessor, tmpPos, BlockFacing.UP);
                            }
                            else
                            {
                                chunks[posY / chunksize].Blocks[index3d] = variant.BlockIds[blockIndex];
                            }


                            for (int i = 0; i < variant.ChildDeposits.Length; i++)
                            {
                                float rndVal   = depositRand.NextFloat();
                                float quantity = variant.ChildDeposits[i].Quantity * invChunkAreaSize;

                                if (quantity > rndVal)
                                {
                                    Vec3i pos = new Vec3i(x, posY, z);

                                    if (ShouldPlaceAdjustedForOreMap(variant.ChildDeposits[i], chunkX * chunksize + x, chunkZ * chunksize + z, quantity, rndVal))
                                    {
                                        SubDepositsToPlace[pos] = variant.ChildDeposits[i];
                                    }
                                }
                            }

                            if (shouldGenSurfaceDeposit)
                            {
                                int   surfaceY = mapchunk.RainHeightMap[z * chunksize + x];
                                int   depth    = surfaceY - posY;
                                float chance   = variant.SurfaceBlockChance * Math.Max(0, 1 - depth / 8f);
                                if (depositRand.NextFloat() < chance)
                                {
                                    index3d = (((surfaceY + 1) % chunksize) * chunksize + z) * chunksize + x;

                                    Block belowBlock = api.World.Blocks[chunks[surfaceY / chunksize].Blocks[((surfaceY % chunksize) * chunksize + z) * chunksize + x]];

                                    if (belowBlock.SideSolid[BlockFacing.UP.Index] && chunks[(surfaceY + 1) / chunksize].Blocks[index3d] == 0)
                                    {
                                        chunks[(surfaceY + 1) / chunksize].Blocks[index3d] = variant.SurfaceBlockIds[blockIndex];
                                    }
                                }
                            }
                        }

                        posY--;
                    }
                }
            }

            return(SubDepositsToPlace);
        }