Esempio n. 1
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);
            }
        }
Esempio n. 2
0
        public void DebugVeinMaps(ICoreServerAPI api, IMapRegion mapRegion, int regionX, int regionZ)
        {
            TyronThreadPool.QueueTask(() =>
            {
                DirectoryInfo path = Directory.CreateDirectory(Path.Combine(GamePaths.DataPath, "VeinMaps", api.World.Seed.ToString()));
                Dictionary <string, IntDataMap2D> veinMaps = mapRegion.GetModdata <Dictionary <string, IntDataMap2D> >("veinmaps");

                foreach (var vein in veinMaps)
                {
                    IntDataMap2D veinMap = vein.Value;

                    Bitmap bmp = new Bitmap(veinMap.Size, veinMap.Size);
                    for (int x = 0; x < veinMap.Size; x++)
                    {
                        for (int y = 0; y < veinMap.Size; y++)
                        {
                            Argb8 test = new Argb8(veinMap.GetInt(x, y));
                            bmp.SetPixel(x, y, Color.FromArgb(test.Value));
                        }
                    }
                    Directory.CreateDirectory(Path.Combine(path.FullName, vein.Key.UcFirst()));

                    string pt = Path.Combine(path.FullName, vein.Key.UcFirst(), string.Format("{0}, {1}.png", regionX, regionZ));

                    bmp.Save(pt, ImageFormat.Png);
                }
            });
        }
Esempio n. 3
0
        public float GetOreMapFactor(int chunkx, int chunkz)
        {
            IMapRegion originMapRegion = api.WorldManager.GetMapRegion(chunkx * chunksize / regionSize, chunkz * chunksize / regionSize);

            if (originMapRegion == null)
            {
                return(0);
            }
            int lx = (chunkx * chunksize + chunksize / 2) % regionSize;
            int lz = (chunkz * chunksize + chunksize / 2) % regionSize;

            IntDataMap2D map = null;

            originMapRegion.OreMaps.TryGetValue(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[Code].GetUnpaddedColorLerped(posXInRegionOre, posZInRegionOre);

                return((oreDist & 0xff) / 255f);
            }

            return(0);
        }
Esempio n. 4
0
        private void OnChunkColumnGen(IServerChunk[] chunks, int chunkX, int chunkZ, ITreeAttribute chunkGenParams = null)
        {
            IntDataMap2D climateMap = chunks[0].MapChunk.MapRegion.ClimateMap;

            ushort[] heightMap = chunks[0].MapChunk.WorldGenTerrainHeightMap;

            int regionChunkSize = api.WorldManager.RegionSize / chunksize;
            int rlX             = chunkX % regionChunkSize;
            int rlZ             = chunkZ % regionChunkSize;

            float facC = (float)climateMap.InnerSize / regionChunkSize;

            climateUpLeft   = climateMap.GetUnpaddedInt((int)(rlX * facC), (int)(rlZ * facC));
            climateUpRight  = climateMap.GetUnpaddedInt((int)(rlX * facC + facC), (int)(rlZ * facC));
            climateBotLeft  = climateMap.GetUnpaddedInt((int)(rlX * facC), (int)(rlZ * facC + facC));
            climateBotRight = climateMap.GetUnpaddedInt((int)(rlX * facC + facC), (int)(rlZ * facC + facC));

            IntDataMap2D forestMap = chunks[0].MapChunk.MapRegion.ForestMap;
            float        facF      = (float)forestMap.InnerSize / regionChunkSize;

            forestUpLeft   = forestMap.GetUnpaddedInt((int)(rlX * facF), (int)(rlZ * facF));
            forestUpRight  = forestMap.GetUnpaddedInt((int)(rlX * facF + facF), (int)(rlZ * facF));
            forestBotLeft  = forestMap.GetUnpaddedInt((int)(rlX * facF), (int)(rlZ * facF + facF));
            forestBotRight = forestMap.GetUnpaddedInt((int)(rlX * facF + facF), (int)(rlZ * facF + facF));

            IntDataMap2D shrubMap = chunks[0].MapChunk.MapRegion.ShrubMap;
            float        facS     = (float)shrubMap.InnerSize / regionChunkSize;

            shrubsUpLeft   = shrubMap.GetUnpaddedInt((int)(rlX * facS), (int)(rlZ * facS));
            shrubsUpRight  = shrubMap.GetUnpaddedInt((int)(rlX * facS + facS), (int)(rlZ * facS));
            shrubsBotLeft  = shrubMap.GetUnpaddedInt((int)(rlX * facS), (int)(rlZ * facS + facS));
            shrubsBotRight = shrubMap.GetUnpaddedInt((int)(rlX * facS + facS), (int)(rlZ * facS + facS));


            Vec3d    posAsVec = new Vec3d();
            BlockPos pos      = new BlockPos();

            foreach (var val in entityTypeGroups)
            {
                EntityProperties entitytype = val.Key;
                float            tries      = entitytype.Server.SpawnConditions.Worldgen.TriesPerChunk.nextFloat(1, rnd);

                while (tries-- > rnd.NextDouble())
                {
                    int dx = rnd.Next(chunksize);
                    int dz = rnd.Next(chunksize);

                    pos.Set(chunkX * chunksize + dx, 0, chunkZ * chunksize + dz);

                    pos.Y =
                        entitytype.Server.SpawnConditions.Worldgen.TryOnlySurface ?
                        heightMap[dz * chunksize + dx] + 1:
                        rnd.Next(worldheight)
                    ;
                    posAsVec.Set(pos.X + 0.5, pos.Y + 0.005, pos.Z + 0.5);

                    TrySpawnGroupAt(pos, posAsVec, entitytype, val.Value);
                }
            }
        }
Esempio n. 5
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;
                    }
                }
            }
        }
        private void OnChunkColumnGen(IServerChunk[] chunks, int chunkX, int chunkZ, ITreeAttribute chunkGenParams = null)
        {
            IntDataMap2D climateMap = chunks[0].MapChunk.MapRegion.ClimateMap;

            ushort[] heightMap = chunks[0].MapChunk.RainHeightMap;

            int regionChunkSize = api.WorldManager.RegionSize / chunksize;
            int rlX             = chunkX % regionChunkSize;
            int rlZ             = chunkZ % regionChunkSize;

            float facC            = (float)climateMap.InnerSize / regionChunkSize;
            int   climateUpLeft   = climateMap.GetUnpaddedInt((int)(rlX * facC), (int)(rlZ * facC));
            int   climateUpRight  = climateMap.GetUnpaddedInt((int)(rlX * facC + facC), (int)(rlZ * facC));
            int   climateBotLeft  = climateMap.GetUnpaddedInt((int)(rlX * facC), (int)(rlZ * facC + facC));
            int   climateBotRight = climateMap.GetUnpaddedInt((int)(rlX * facC + facC), (int)(rlZ * facC + facC));

            for (int x = 0; x < chunksize; x++)
            {
                for (int z = 0; z < chunksize; z++)
                {
                    int posY = heightMap[z * chunksize + x];

                    int climate = GameMath.BiLerpRgbColor((float)x / chunksize, (float)z / chunksize, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight);

                    float temp = TerraGenConfig.GetScaledAdjustedTemperatureFloat((climate >> 16) & 0xff, posY - TerraGenConfig.seaLevel);

                    int prevY = posY;
                    if (PlaceSnowLayer(x, prevY, z, chunks, temp))
                    {
                        heightMap[z * chunksize + x]++;
                    }
                }
            }
        }
Esempio n. 7
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);
        }
Esempio n. 8
0
        private void OnChunkColumnGen(IServerChunk[] chunks, int chunkX, int chunkZ, ITreeAttribute chunkGenParams = null)
        {
            rnd.InitPositionSeed(chunkX, chunkZ);

            IMapChunk mapChunk = chunks[0].MapChunk;

            IntDataMap2D forestMap  = mapChunk.MapRegion.ForestMap;
            IntDataMap2D shrubMap   = mapChunk.MapRegion.ShrubMap;
            IntDataMap2D climateMap = mapChunk.MapRegion.ClimateMap;
            int          rlX        = chunkX % regionChunkSize;
            int          rlZ        = chunkZ % regionChunkSize;

            float facS = (float)shrubMap.InnerSize / regionChunkSize;

            shrubUpLeft   = shrubMap.GetUnpaddedInt((int)(rlX * facS), (int)(rlZ * facS));
            shrubUpRight  = shrubMap.GetUnpaddedInt((int)(rlX * facS + facS), (int)(rlZ * facS));
            shrubBotLeft  = shrubMap.GetUnpaddedInt((int)(rlX * facS), (int)(rlZ * facS + facS));
            shrubBotRight = shrubMap.GetUnpaddedInt((int)(rlX * facS + facS), (int)(rlZ * facS + facS));

            // A region has 16 chunks
            // Size of the forest map is RegionSize / TerraGenConfig.forestMapScale  => 32*16 / 32  = 16 pixel
            // rlX, rlZ goes from 0..16 pixel
            // facF = 16/16 = 1
            // Get 4 pixels for chunkx, chunkz, chunkx+1 and chunkz+1 inside the map
            float facF = (float)forestMap.InnerSize / regionChunkSize;

            forestUpLeft   = forestMap.GetUnpaddedInt((int)(rlX * facF), (int)(rlZ * facF));
            forestUpRight  = forestMap.GetUnpaddedInt((int)(rlX * facF + facF), (int)(rlZ * facF));
            forestBotLeft  = forestMap.GetUnpaddedInt((int)(rlX * facF), (int)(rlZ * facF + facF));
            forestBotRight = forestMap.GetUnpaddedInt((int)(rlX * facF + facF), (int)(rlZ * facF + facF));

            float facC = (float)climateMap.InnerSize / regionChunkSize;

            climateUpLeft   = climateMap.GetUnpaddedInt((int)(rlX * facC), (int)(rlZ * facC));
            climateUpRight  = climateMap.GetUnpaddedInt((int)(rlX * facC + facC), (int)(rlZ * facC));
            climateBotLeft  = climateMap.GetUnpaddedInt((int)(rlX * facC), (int)(rlZ * facC + facC));
            climateBotRight = climateMap.GetUnpaddedInt((int)(rlX * facC + facC), (int)(rlZ * facC + facC));

            heightmap = chunks[0].MapChunk.RainHeightMap;


            structuresIntersectingChunk.Clear();
            api.World.BlockAccessor.WalkStructures(chunkBase.Set(chunkX * chunksize, 0, chunkZ * chunksize), chunkend.Set(chunkX * chunksize + chunksize, chunkMapSizeY * chunksize, chunkZ * chunksize + chunksize), (struc) =>
            {
                if (struc.Code.StartsWith("trader"))
                {
                    structuresIntersectingChunk.Add(struc);
                }
            });

            if (TerraGenConfig.GenerateVegetation)
            {
                genPatches(chunkX, chunkZ, false);
                genShrubs(chunkX, chunkZ);
                genTrees(chunkX, chunkZ);
                genPatches(chunkX, chunkZ, true);
            }
        }
        private void OnMapRegionGen(IMapRegion mapRegion, int regionX, int regionZ)
        {
            int noiseSize = sapi.WorldManager.RegionSize / TerraGenConfig.blockPatchesMapScale;

            foreach (var val in blockPatchMapGens)
            {
                var map = IntDataMap2D.CreateEmpty();

                map.Size = noiseSize + 1;
                map.BottomRightPadding = 1;

                map.Data = val.Value.GenLayer(regionX * noiseSize, regionZ * noiseSize, noiseSize + 1, noiseSize + 1);
                mapRegion.BlockPatchMaps[val.Key] = map;
            }
        }
Esempio n. 10
0
        LerpedWeightedIndex2DMap GetOrLoadLerpedLandformMap(IMapChunk mapchunk, int regionX, int regionZ)
        {
            LerpedWeightedIndex2DMap map;

            // 1. Load?
            LandformMapByRegion.TryGetValue(regionZ * regionMapSize + regionX, out map);
            if (map != null)
            {
                return(map);
            }

            IntDataMap2D lmap = mapchunk.MapRegion.LandformMap;

            // 2. Create
            map             = LandformMapByRegion[regionZ * regionMapSize + regionX]
                            = new LerpedWeightedIndex2DMap(lmap.Data, lmap.Size, TerraGenConfig.landFormSmoothingRadius, lmap.TopLeftPadding, lmap.BottomRightPadding);

            return(map);
        }
Esempio n. 11
0
        private void OnChunkColumnGen(IServerChunk[] chunks, int chunkX, int chunkZ)
        {
            rnd.InitPositionSeed(chunkX, chunkZ);
            IMapChunk mapChunk = chunks[0].MapChunk;

            IntDataMap2D climateMap = mapChunk.MapRegion.ClimateMap;
            int          rlX        = chunkX % regionChunkSize;
            int          rlZ        = chunkZ % regionChunkSize;

            float facC = (float)climateMap.InnerSize / regionChunkSize;

            climateUpLeft   = climateMap.GetUnpaddedInt((int)(rlX * facC), (int)(rlZ * facC));
            climateUpRight  = climateMap.GetUnpaddedInt((int)(rlX * facC + facC), (int)(rlZ * facC));
            climateBotLeft  = climateMap.GetUnpaddedInt((int)(rlX * facC), (int)(rlZ * facC + facC));
            climateBotRight = climateMap.GetUnpaddedInt((int)(rlX * facC + facC), (int)(rlZ * facC + facC));

            heightmap = chunks[0].MapChunk.RainHeightMap;

            genPatches(chunkX, chunkZ);
        }
Esempio n. 12
0
        public static Vec3i ToClimateVec(this IntDataMap2D climateMap, int chunkX, int chunkZ, int regionsize, int chunksize, float lx = 0.5f, float ly = 0.5f)
        {
            int   regionChunkSize = regionsize / chunksize;
            float fac             = (float)climateMap.InnerSize / regionChunkSize;
            int   rlX             = chunkX % regionChunkSize;
            int   rlZ             = chunkZ % regionChunkSize;

            int climateUpLeft   = climateMap.GetUnpaddedInt((int)(rlX * fac), (int)(rlZ * fac));
            int climateUpRight  = climateMap.GetUnpaddedInt((int)(rlX * fac + fac), (int)(rlZ * fac));
            int climateBotLeft  = climateMap.GetUnpaddedInt((int)(rlX * fac), (int)(rlZ * fac + fac));
            int climateBotRight = climateMap.GetUnpaddedInt((int)(rlX * fac + fac), (int)(rlZ * fac + fac));

            int climateMid = GameMath.BiLerpRgbColor(lx, ly, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight);

            int rain     = (climateMid >> 8) & 0xff;
            int humidity = climateMid & 0xff;
            int temp     = (climateMid >> 16) & 0xff;

            return(new Vec3i(rain, humidity, temp));
        }
Esempio n. 13
0
        private void OnMapRegionGen(IMapRegion mapRegion, int regionX, int regionZ)
        {
            int noiseSize = api.WorldManager.RegionSize / TerraGenConfig.rockStrataScale;
            int pad       = 2;

            mapRegion.RockStrata = new IntDataMap2D[strata.Variants.Length];
            for (int i = 0; i < strata.Variants.Length; i++)
            {
                IntDataMap2D intmap = new IntDataMap2D();
                mapRegion.RockStrata[i] = intmap;
                intmap.Data             = strataNoises[i].GenLayer(
                    regionX * noiseSize - pad,
                    regionZ * noiseSize - pad,
                    noiseSize + 2 * pad,
                    noiseSize + 2 * pad
                    );

                intmap.Size           = noiseSize + 2 * pad;
                intmap.TopLeftPadding = intmap.BottomRightPadding = pad;
            }
        }
Esempio n. 14
0
        private void OnChunkColumnGen(IServerChunk[] chunks, int chunkX, int chunkZ, ITreeAttribute chunkGenParams = null)
        {
            if (!TerraGenConfig.GenerateStructures)
            {
                return;
            }

            IMapRegion region = chunks[0].MapChunk.MapRegion;

            IntDataMap2D forestMap  = region.ForestMap;
            IntDataMap2D climateMap = region.ClimateMap;
            int          rlX        = chunkX % regionChunkSize;
            int          rlZ        = chunkZ % regionChunkSize;


            // A region has 16 chunks
            // Size of the forest map is RegionSize / TerraGenConfig.forestMapScale  => 32*16 / 32  = 16 pixel
            // rlX, rlZ goes from 0..16 pixel
            // facF = 16/16 = 1
            // Get 4 pixels for chunkx, chunkz, chunkx+1 and chunkz+1 inside the map
            float facF = (float)forestMap.InnerSize / regionChunkSize;

            forestUpLeft   = forestMap.GetUnpaddedInt((int)(rlX * facF), (int)(rlZ * facF));
            forestUpRight  = forestMap.GetUnpaddedInt((int)(rlX * facF + facF), (int)(rlZ * facF));
            forestBotLeft  = forestMap.GetUnpaddedInt((int)(rlX * facF), (int)(rlZ * facF + facF));
            forestBotRight = forestMap.GetUnpaddedInt((int)(rlX * facF + facF), (int)(rlZ * facF + facF));

            float facC = (float)climateMap.InnerSize / regionChunkSize;

            climateUpLeft   = climateMap.GetUnpaddedInt((int)(rlX * facC), (int)(rlZ * facC));
            climateUpRight  = climateMap.GetUnpaddedInt((int)(rlX * facC + facC), (int)(rlZ * facC));
            climateBotLeft  = climateMap.GetUnpaddedInt((int)(rlX * facC), (int)(rlZ * facC + facC));
            climateBotRight = climateMap.GetUnpaddedInt((int)(rlX * facC + facC), (int)(rlZ * facC + facC));

            heightmap = chunks[0].MapChunk.WorldGenTerrainHeightMap;


            DoGenStructures(region, chunkX, chunkZ, false, chunkGenParams);
            DoGenVillages(region, chunkX, chunkZ, false, chunkGenParams);
        }
Esempio n. 15
0
        private void OnChunkColumnGeneration(IServerChunk[] chunks, int chunkX, int chunkZ, ITreeAttribute chunkGenParams = null)
        {
            rnd.InitPositionSeed(chunkX, chunkZ);

            IntDataMap2D forestMap  = chunks[0].MapChunk.MapRegion.ForestMap;
            IntDataMap2D climateMap = chunks[0].MapChunk.MapRegion.ClimateMap;
            IntDataMap2D beachMap   = chunks[0].MapChunk.MapRegion.BeachMap;

            ushort[] heightMap = chunks[0].MapChunk.RainHeightMap;

            int regionChunkSize = api.WorldManager.RegionSize / chunksize;
            int rdx             = chunkX % regionChunkSize;
            int rdz             = chunkZ % regionChunkSize;

            // Amount of data points per chunk
            float climateStep = (float)climateMap.InnerSize / regionChunkSize;
            float forestStep  = (float)forestMap.InnerSize / regionChunkSize;
            float beachStep   = (float)beachMap.InnerSize / regionChunkSize;

            // Retrieves the map data on the chunk edges
            int forestUpLeft   = forestMap.GetUnpaddedInt((int)(rdx * forestStep), (int)(rdz * forestStep));
            int forestUpRight  = forestMap.GetUnpaddedInt((int)(rdx * forestStep + forestStep), (int)(rdz * forestStep));
            int forestBotLeft  = forestMap.GetUnpaddedInt((int)(rdx * forestStep), (int)(rdz * forestStep + forestStep));
            int forestBotRight = forestMap.GetUnpaddedInt((int)(rdx * forestStep + forestStep), (int)(rdz * forestStep + forestStep));

            int beachUpLeft   = beachMap.GetUnpaddedInt((int)(rdx * beachStep), (int)(rdz * beachStep));
            int beachUpRight  = beachMap.GetUnpaddedInt((int)(rdx * beachStep + beachStep), (int)(rdz * beachStep));
            int beachBotLeft  = beachMap.GetUnpaddedInt((int)(rdx * beachStep), (int)(rdz * beachStep + beachStep));
            int beachBotRight = beachMap.GetUnpaddedInt((int)(rdx * beachStep + beachStep), (int)(rdz * beachStep + beachStep));


            // increasing x -> left to right
            // increasing z -> top to bottom

            float transitionSize = blockLayerConfig.blockLayerTransitionSize;


            for (int x = 0; x < chunksize; x++)
            {
                for (int z = 0; z < chunksize; z++)
                {
                    // Some weird randomnes stuff to hide fundamental bugs in the climate transition system :D T_T   (maybe not bugs but just fundamental shortcomings of using lerp on a very low resolution map)
                    float distx = (float)distort2dx.Noise(chunkX * chunksize + x, chunkZ * chunksize + z);
                    float distz = (float)distort2dz.Noise(chunkX * chunksize + x, chunkZ * chunksize + z);

                    double posRand        = (double)GameMath.MurmurHash3(x + chunkX * chunksize, 1, z + chunkZ * chunksize) / int.MaxValue;
                    double transitionRand = (posRand + 1) * transitionSize;

                    int posY = heightMap[z * chunksize + x];

                    int climate = climateMap.GetUnpaddedColorLerped(
                        rdx * climateStep + climateStep * (float)(x + distx) / chunksize,
                        rdz * climateStep + climateStep * (float)(z + distz) / chunksize
                        );

                    int   tempUnscaled = (climate >> 16) & 0xff;
                    int   rnd          = (int)(distx / 5);
                    float temp         = TerraGenConfig.GetScaledAdjustedTemperatureFloat(tempUnscaled, posY - TerraGenConfig.seaLevel + rnd);
                    float tempRel      = TerraGenConfig.GetAdjustedTemperature(tempUnscaled, posY - TerraGenConfig.seaLevel + rnd) / 255f;
                    float rainRel      = TerraGenConfig.GetRainFall((climate >> 8) & 0xff, posY + rnd) / 255f;
                    float forestRel    = GameMath.BiLerp(forestUpLeft, forestUpRight, forestBotLeft, forestBotRight, (float)x / chunksize, (float)z / chunksize) / 255f;
                    float beachRel     = GameMath.BiLerp(beachUpLeft, beachUpRight, beachBotLeft, beachBotRight, (float)x / chunksize, (float)z / chunksize) / 255f;

                    int prevY = posY;

                    posY = PutLayers(transitionRand, x, posY, z, chunks, rainRel, temp, tempUnscaled, heightMap);
                    int blockID = chunks[0].MapChunk.TopRockIdMap[z * chunksize + x];

                    GenBeach(x, prevY, z, chunks, rainRel, temp, beachRel, blockID);
                    PlaceTallGrass(x, prevY, z, chunks, rainRel, tempRel, temp, forestRel);


                    // Try again to put layers if above sealevel and we found over 10 air blocks
                    int foundAir = 0;
                    while (posY >= TerraGenConfig.seaLevel - 1)
                    {
                        int chunkY  = posY / chunksize;
                        int lY      = posY % chunksize;
                        int index3d = (chunksize * lY + z) * chunksize + x;
                        int blockId = chunks[chunkY].Blocks[index3d];

                        if (blockId == 0)
                        {
                            foundAir++;
                        }
                        else
                        {
                            if (foundAir >= 8)
                            {
                                //temp = TerraGenConfig.GetScaledAdjustedTemperatureFloat(tempUnscaled, posY - TerraGenConfig.seaLevel);
                                //rainRel = TerraGenConfig.GetRainFall((climate >> 8) & 0xff, posY) / 255f;
                                //PutLayers(transitionRand, x, posY, z, chunks, rainRel, temp, tempUnscaled, null);
                                break;
                            }
                            else
                            {
                                foundAir = 0;
                            }
                        }

                        posY--;
                    }
                }
            }
        }
Esempio n. 16
0
        public virtual int[] GenLayerDiffuse(int xCoord, int zCoord, int smallSize, int largeSize, int flags, int diffusionSize, int blurSize, int maxTries = 8, int padding = 2)
        {
            ServerGL.xCoord = xCoord;
            ServerGL.yCoord = zCoord;

            int step       = largeSize / smallSize / 2;
            int paddedSize = largeSize + (padding * 2 * step);

            int[] largeData = new int[largeSize * largeSize];

            int[] paddedData   = GenLayerSized(xCoord - (padding * step), zCoord - (padding * step), smallSize, paddedSize, flags);
            int[] diffusedData = (int[])paddedData.Clone();

            //diffusion
            if (diffusionSize > 0)
            {
                for (int z = 0; z < paddedSize; ++z)
                {
                    for (int x = 0; x < paddedSize; ++x)
                    {
                        int sample = 0;

                        for (int i = 0; sample == 0 && i < maxTries; i++)
                        {
                            int rz = GameMath.oaatHash(x, i + 0, z) % diffusionSize;
                            int rx = GameMath.oaatHash(x, i + 0, z) % diffusionSize;

                            rz -= diffusionSize / 2;
                            rx -= diffusionSize / 2;

                            rz += z;
                            rx += x;

                            rz     = GameMath.Clamp(rz, 0, paddedSize - 1);
                            rx     = GameMath.Clamp(rx, 0, paddedSize - 1);
                            sample = paddedData[rz * paddedSize + rx];
                        }

                        diffusedData[z * paddedSize + x] = sample;
                    }
                }
            }

            //blur
            if (blurSize > 0)
            {
                BoxBlur(diffusedData, blurSize, paddedSize, paddedSize);
            }

            //crop
            IntDataMap2D data = new IntDataMap2D()
            {
                BottomRightPadding = padding * 2 * step,
                TopLeftPadding     = padding * 2 * step,
                Data = diffusedData,
                Size = paddedSize
            };

            for (int z = 0; z < largeSize; ++z)
            {
                for (int x = 0; x < largeSize; ++x)
                {
                    largeData[z * largeSize + x] = data.GetUnpaddedInt(x, z);
                }
            }

            return(largeData);
        }
Esempio n. 17
0
        public void genBlockColumn(IServerChunk[] chunks, int chunkX, int chunkZ, int lx, int lz)
        {
            int surfaceY = heightMap[lz * chunksize + lx];
            int ylower   = 1;
            int yupper   = surfaceY;

            strataThickness = 0;

            WeightedIndex[] indices = map[
                chunkInRegionX + lx * lerpMapInv,
                chunkInRegionZ + lz * lerpMapInv
                                      ];
            rockGroupMaxThickness[0]     = rockGroupMaxThickness[1] = rockGroupMaxThickness[2] = rockGroupMaxThickness[3] = 0;
            rockGroupCurrentThickness[0] = rockGroupCurrentThickness[1] = rockGroupCurrentThickness[2] = rockGroupCurrentThickness[3] = 0;

            for (int i = 0; i < indices.Length; i++)
            {
                float w = indices[i].Weight;

                GeologicProvinceVariant var = provinces.Variants[indices[i].Index];

                rockGroupMaxThickness[0] += var.RockStrataIndexed[0].MaxThickness * w;
                rockGroupMaxThickness[1] += var.RockStrataIndexed[1].MaxThickness * w;
                rockGroupMaxThickness[2] += var.RockStrataIndexed[2].MaxThickness * w;
                rockGroupMaxThickness[3] += var.RockStrataIndexed[3].MaxThickness * w;
            }



            float distx = (float)distort2dx.Noise(chunkX * chunksize + lx, chunkZ * chunksize + lz);
            float distz = (float)distort2dz.Noise(chunkX * chunksize + lx, chunkZ * chunksize + lz);


            rockStrataId = -1;

            while (ylower <= yupper)
            {
                if (--strataThickness <= 0)
                {
                    rockStrataId++;
                    if (rockStrataId >= strata.Variants.Length)
                    {
                        break;
                    }
                    stratum = strata.Variants[rockStrataId];
                    rockMap = mapChunk.MapRegion.RockStrata[rockStrataId];
                    step    = (float)rockMap.InnerSize / regionChunkSize;

                    grp = (int)stratum.RockGroup;

                    float thicknessDistort = GameMath.Clamp((distx + distz) / 30, 0.9f, 1.1f);

                    float allowedThickness = rockGroupMaxThickness[grp] * thicknessDistort - rockGroupCurrentThickness[grp];

                    strataThickness = Math.Min(allowedThickness, rockMap.GetIntLerpedCorrectly(rdx * step + step * (float)(lx + distx) / chunksize, rdz * step + step * (float)(lz + distz) / chunksize));

                    strataThickness -= (stratum.RockGroup == EnumRockGroup.Sedimentary) ? Math.Max(0, yupper - TerraGenConfig.seaLevel) * 0.5f : 0;

                    if (strataThickness < 2)
                    {
                        strataThickness = -1;
                        continue;
                    }
                }

                rockGroupCurrentThickness[grp]++;

                if (stratum.GenDir == EnumStratumGenDir.BottomUp)
                {
                    int chunkY       = ylower / chunksize;
                    int lY           = ylower - chunkY * chunksize;
                    int localIndex3D = (chunksize * lY + lz) * chunksize + lx;

                    if (chunks[chunkY].Blocks[localIndex3D] == rockBlockId)
                    {
                        chunks[chunkY].Blocks[localIndex3D] = stratum.BlockId;
                    }

                    ylower++;
                }
                else
                {
                    int chunkY       = yupper / chunksize;
                    int lY           = yupper - chunkY * chunksize;
                    int localIndex3D = (chunksize * lY + lz) * chunksize + lx;

                    if (chunks[chunkY].Blocks[localIndex3D] == rockBlockId)
                    {
                        chunks[chunkY].Blocks[localIndex3D] = stratum.BlockId;
                    }

                    yupper--;
                }
            }
        }
Esempio n. 18
0
        LerpedWeightedIndex2DMap CreateLerpedProvinceMap(IntDataMap2D geoMap, int regionX, int regionZ)
        {
            int index2d = regionZ * regionMapSize + regionX;

            return(ProvinceMapByRegion[index2d] = new LerpedWeightedIndex2DMap(geoMap.Data, geoMap.Size, TerraGenConfig.geoProvSmoothingRadius, geoMap.TopLeftPadding, geoMap.BottomRightPadding));
        }
Esempio n. 19
0
 public void SetInputMap(IntDataMap2D inputMap, IntDataMap2D outputMap)
 {
     this.inputMap  = inputMap;
     this.outputMap = outputMap;
 }
        protected virtual void PrintProbeResults(IWorldAccessor world, IServerPlayer byPlayer, ItemSlot itemslot, BlockPos pos)
        {
            DepositVariant[] deposits = api.ModLoader.GetModSystem <GenDeposits>()?.Deposits;
            if (deposits == null)
            {
                return;
            }

            IBlockAccessor blockAccess = world.BlockAccessor;
            int            chunksize   = blockAccess.ChunkSize;
            int            regsize     = blockAccess.RegionSize;

            IMapRegion reg = world.BlockAccessor.GetMapRegion(pos.X / regsize, pos.Z / regsize);
            int        lx  = pos.X % regsize;
            int        lz  = pos.Z % regsize;

            pos   = pos.Copy();
            pos.Y = world.BlockAccessor.GetTerrainMapheightAt(pos);

            int[] blockColumn = ppws.GetRockColumn(pos.X, pos.Z);

            List <KeyValuePair <double, string> > readouts = new List <KeyValuePair <double, string> >();

            List <string> traceamounts = new List <string>();

            foreach (var val in reg.OreMaps)
            {
                IntDataMap2D map       = val.Value;
                int          noiseSize = map.InnerSize;

                float posXInRegionOre = (float)lx / regsize * noiseSize;
                float posZInRegionOre = (float)lz / regsize * noiseSize;

                int oreDist = map.GetUnpaddedColorLerped(posXInRegionOre, posZInRegionOre);

                double ppt;
                double totalFactor;

                if (!ppws.depositsByCode.ContainsKey(val.Key))
                {
                    string text = Lang.Get("propick-reading-unknown", val.Key);
                    readouts.Add(new KeyValuePair <double, string>(1, text));
                    continue;
                }

                ppws.depositsByCode[val.Key].GetPropickReading(pos, oreDist, blockColumn, out ppt, out totalFactor);

                string[] names = new string[] { "propick-density-verypoor", "propick-density-poor", "propick-density-decent", "propick-density-high", "propick-density-veryhigh", "propick-density-ultrahigh" };

                if (totalFactor > 0.025)
                {
                    string pageCode = ppws.pageCodes[val.Key];
                    string text     = Lang.Get("propick-reading", Lang.Get(names[(int)GameMath.Clamp(totalFactor * 7.5f, 0, 5)]), pageCode, Lang.Get("ore-" + val.Key), ppt.ToString("0.#"));
                    readouts.Add(new KeyValuePair <double, string>(totalFactor, text));
                }
                else if (totalFactor > 0.002)
                {
                    traceamounts.Add(val.Key);
                }
            }

            StringBuilder sb = new StringBuilder();

            IServerPlayer splr = byPlayer as IServerPlayer;

            if (readouts.Count >= 0 || traceamounts.Count > 0)
            {
                var elems = readouts.OrderByDescending(val => val.Key);

                sb.AppendLine(Lang.Get("propick-reading-title", readouts.Count));
                foreach (var elem in elems)
                {
                    sb.AppendLine(elem.Value);
                }

                if (traceamounts.Count > 0)
                {
                    var sbTrace = new StringBuilder();
                    int i       = 0;
                    foreach (var val in traceamounts)
                    {
                        if (i > 0)
                        {
                            sbTrace.Append(", ");
                        }
                        string pageCode = ppws.pageCodes[val];
                        string text     = string.Format("<a href=\"handbook://{0}\">{1}</a>", pageCode, Lang.Get("ore-" + val));
                        sbTrace.Append(text);
                        i++;
                    }

                    sb.Append(Lang.Get("Miniscule amounts of {0}", sbTrace.ToString()));
                    sb.AppendLine();
                }
            }
            else
            {
                sb.Append(Lang.Get("propick-noreading"));
            }

            splr.SendMessage(GlobalConstants.InfoLogChatGroup, sb.ToString(), EnumChatType.Notification);
        }
Esempio n. 21
0
        private void OnChunkColumnGen(IServerChunk[] chunks, int chunkX, int chunkZ, ITreeAttribute chunkGenParams = null)
        {
            IntDataMap2D climateMap      = chunks[0].MapChunk.MapRegion.ClimateMap;
            int          regionChunkSize = api.WorldManager.RegionSize / chunksize;
            float        fac             = (float)climateMap.InnerSize / regionChunkSize;
            int          rlX             = chunkX % regionChunkSize;
            int          rlZ             = chunkZ % regionChunkSize;

            int climateUpLeft   = climateMap.GetUnpaddedInt((int)(rlX * fac), (int)(rlZ * fac));
            int climateUpRight  = climateMap.GetUnpaddedInt((int)(rlX * fac + fac), (int)(rlZ * fac));
            int climateBotLeft  = climateMap.GetUnpaddedInt((int)(rlX * fac), (int)(rlZ * fac + fac));
            int climateBotRight = climateMap.GetUnpaddedInt((int)(rlX * fac + fac), (int)(rlZ * fac + fac));

            int climateMid = GameMath.BiLerpRgbColor(0.5f, 0.5f, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight);

            // 16-23 bits = Red = temperature
            // 8-15 bits = Green = rain
            // 0-7 bits = Blue = humidity

            int rain     = (climateMid >> 8) & 0xff;
            int humidity = climateMid & 0xff;
            int temp     = (climateMid >> 16) & 0xff;


            int quantityRivulets = (int)(80 * (rain + humidity) / 255f) * (api.WorldManager.MapSizeY / chunksize) - Math.Max(0, 100 - temp);
            int fx, fy, fz;

            float sealeveltemp = TerraGenConfig.GetScaledAdjustedTemperatureFloat(temp, 0);

            if (sealeveltemp < -15)
            {
                return;
            }

            while (quantityRivulets-- > 0)
            {
                int dx = 1 + rnd.Next(chunksize - 2);
                int y  = 1 + rnd.Next(api.WorldManager.MapSizeY - 2);
                int dz = 1 + rnd.Next(chunksize - 2);

                int quantitySolid = 0;
                int quantityAir   = 0;
                for (int i = 0; i < BlockFacing.NumberOfFaces; i++)
                {
                    BlockFacing facing = BlockFacing.ALLFACES[i];
                    fx = dx + facing.Normali.X;
                    fy = y + facing.Normali.Y;
                    fz = dz + facing.Normali.Z;

                    Block block = api.World.Blocks[
                        chunks[fy / chunksize].Blocks[(chunksize * (fy % chunksize) + fz) * chunksize + fx]
                                  ];

                    bool solid = block.BlockMaterial == EnumBlockMaterial.Stone;
                    quantitySolid += solid ? 1 : 0;
                    quantityAir   += (block.BlockMaterial == EnumBlockMaterial.Air) ? 1 : 0;

                    if (!solid && facing == BlockFacing.UP)
                    {
                        quantitySolid = 0;
                    }
                }

                if (quantitySolid != 5 || quantityAir != 1)
                {
                    continue;
                }

                chunks[y / chunksize].Blocks[(chunksize * (y % chunksize) + dz) * chunksize + dx] = y < 24 ? GlobalConfig.lavaBlockId : GlobalConfig.waterBlockId;

                BlockPos pos = new BlockPos(chunkX * chunksize + dx, y, chunkZ * chunksize + dz);
                blockAccessor.ScheduleBlockUpdate(pos);
            }
        }
Esempio n. 22
0
        private void OnChunkColumnGen(IServerChunk[] chunks, int chunkX, int chunkZ, ITreeAttribute chunkGenParams = null)
        {
            landforms = NoiseLandforms.landforms;
            IMapChunk mapchunk = chunks[0].MapChunk;

            int climateUpLeft;
            int climateUpRight;
            int climateBotLeft;
            int climateBotRight;

            IntDataMap2D climateMap      = chunks[0].MapChunk.MapRegion.ClimateMap;
            int          regionChunkSize = api.WorldManager.RegionSize / chunksize;
            float        fac             = (float)climateMap.InnerSize / regionChunkSize;
            int          rlX             = chunkX % regionChunkSize;
            int          rlZ             = chunkZ % regionChunkSize;

            climateUpLeft   = climateMap.GetUnpaddedInt((int)(rlX * fac), (int)(rlZ * fac));
            climateUpRight  = climateMap.GetUnpaddedInt((int)(rlX * fac + fac), (int)(rlZ * fac));
            climateBotLeft  = climateMap.GetUnpaddedInt((int)(rlX * fac), (int)(rlZ * fac + fac));
            climateBotRight = climateMap.GetUnpaddedInt((int)(rlX * fac + fac), (int)(rlZ * fac + fac));

            int freezingTemp = -17;


            IntDataMap2D landformMap = mapchunk.MapRegion.LandformMap;
            // Amount of pixels for each chunk (probably 1, 2, or 4) in the land form map
            float chunkPixelSize = landformMap.InnerSize / regionChunkSize;
            // Adjusted lerp for the noiseWidth
            float chunkPixelStep = chunkPixelSize / noiseWidth;
            // Start coordinates for the chunk in the region map
            float baseX = (chunkX % regionChunkSize) * chunkPixelSize;
            float baseZ = (chunkZ % regionChunkSize) * chunkPixelSize;


            LerpedWeightedIndex2DMap landLerpMap = GetOrLoadLerpedLandformMap(chunks[0].MapChunk, chunkX / regionChunkSize, chunkZ / regionChunkSize);

            // Terrain octaves
            double[] octNoiseX0, octNoiseX1, octNoiseX2, octNoiseX3;
            double[] octThX0, octThX1, octThX2, octThX3;

            // So it seems we have some kind of off-by-one error here?
            // When the slope of a mountain goes up (in positive z or x direction), particularly at large word heights (512+)
            // then the last blocks (again in postive x/z dir) are below of where they should be?
            // I have no idea why, but this offset seems to greatly mitigate the issue
            float weirdOffset = 0.25f;

            chunkPixelSize += weirdOffset;

            GetInterpolatedOctaves(landLerpMap[baseX, baseZ], out octNoiseX0, out octThX0);
            GetInterpolatedOctaves(landLerpMap[baseX + chunkPixelSize, baseZ], out octNoiseX1, out octThX1);
            GetInterpolatedOctaves(landLerpMap[baseX, baseZ + chunkPixelSize], out octNoiseX2, out octThX2);
            GetInterpolatedOctaves(landLerpMap[baseX + chunkPixelSize, baseZ + chunkPixelSize], out octNoiseX3, out octThX3);


            double[] terrainNoise3d = GetTerrainNoise3D(octNoiseX0, octNoiseX1, octNoiseX2, octNoiseX3, octThX0, octThX1, octThX2, octThX3, chunkX * noiseWidth, 0, chunkZ * noiseWidth);

            // Store heightmap in the map chunk
            ushort[] rainheightmap    = chunks[0].MapChunk.RainHeightMap;
            ushort[] terrainheightmap = chunks[0].MapChunk.WorldGenTerrainHeightMap;


            // Terrain thresholds
            double tnoiseY0;
            double tnoiseY1;
            double tnoiseY2;
            double tnoiseY3;
            double tnoiseGainY0;
            double tnoiseGainY1;
            double tnoiseGainY2;
            double tnoiseGainY3;


            double thNoiseX0;
            double thNoiseX1;
            double thNoiseGainX0;
            double thNoiseGainX1;
            double thNoiseGainZ0;
            double thNoiseZ0;

            float[] terrainThresholdsX0 = new float[api.WorldManager.MapSizeY];
            float[] terrainThresholdsX1 = new float[api.WorldManager.MapSizeY];
            float[] terrainThresholdsX2 = new float[api.WorldManager.MapSizeY];
            float[] terrainThresholdsX3 = new float[api.WorldManager.MapSizeY];



            for (int xN = 0; xN < noiseWidth; xN++)
            {
                for (int zN = 0; zN < noiseWidth; zN++)
                {
                    // Landform thresholds
                    LoadInterpolatedThresholds(landLerpMap[baseX + xN * chunkPixelStep, baseZ + zN * chunkPixelStep], terrainThresholdsX0);
                    LoadInterpolatedThresholds(landLerpMap[baseX + (xN + 1) * chunkPixelStep, baseZ + zN * chunkPixelStep], terrainThresholdsX1);
                    LoadInterpolatedThresholds(landLerpMap[baseX + xN * chunkPixelStep, baseZ + (zN + 1) * chunkPixelStep], terrainThresholdsX2);
                    LoadInterpolatedThresholds(landLerpMap[baseX + (xN + 1) * chunkPixelStep, baseZ + (zN + 1) * chunkPixelStep], terrainThresholdsX3);

                    for (int yN = 0; yN < noiseHeight; yN++)
                    {
                        // Terrain noise
                        tnoiseY0 = terrainNoise3d[NoiseIndex3d(xN, yN, zN)];
                        tnoiseY1 = terrainNoise3d[NoiseIndex3d(xN, yN, zN + 1)];
                        tnoiseY2 = terrainNoise3d[NoiseIndex3d(xN + 1, yN, zN)];
                        tnoiseY3 = terrainNoise3d[NoiseIndex3d(xN + 1, yN, zN + 1)];

                        tnoiseGainY0 = (terrainNoise3d[NoiseIndex3d(xN, yN + 1, zN)] - tnoiseY0) * lerpDeltaVert;
                        tnoiseGainY1 = (terrainNoise3d[NoiseIndex3d(xN, yN + 1, zN + 1)] - tnoiseY1) * lerpDeltaVert;
                        tnoiseGainY2 = (terrainNoise3d[NoiseIndex3d(xN + 1, yN + 1, zN)] - tnoiseY2) * lerpDeltaVert;
                        tnoiseGainY3 = (terrainNoise3d[NoiseIndex3d(xN + 1, yN + 1, zN + 1)] - tnoiseY3) * lerpDeltaVert;


                        for (int y = 0; y < lerpVer; y++)
                        {
                            int posY   = yN * lerpVer + y;
                            int chunkY = posY / chunksize;
                            int localY = posY % chunksize;

                            // For Terrain noise
                            double tnoiseX0 = tnoiseY0;
                            double tnoiseX1 = tnoiseY1;

                            double tnoiseGainX0 = (tnoiseY2 - tnoiseY0) * lerpDeltaHor;
                            double tnoiseGainX1 = (tnoiseY3 - tnoiseY1) * lerpDeltaHor;

                            // Landform thresholds lerp
                            thNoiseX0 = terrainThresholdsX0[posY];
                            thNoiseX1 = terrainThresholdsX2[posY];

                            thNoiseGainX0 = (terrainThresholdsX1[posY] - thNoiseX0) * lerpDeltaHor;
                            thNoiseGainX1 = (terrainThresholdsX3[posY] - thNoiseX1) * lerpDeltaHor;

                            for (int x = 0; x < lerpHor; x++)
                            {
                                // For terrain noise
                                double tnoiseZ0     = tnoiseX0;
                                double tnoiseGainZ0 = (tnoiseX1 - tnoiseX0) * lerpDeltaHor;

                                // Landform
                                thNoiseZ0     = thNoiseX0;
                                thNoiseGainZ0 = (thNoiseX1 - thNoiseX0) * lerpDeltaHor;

                                for (int z = 0; z < lerpHor; z++)
                                {
                                    int lX = xN * lerpHor + x;
                                    int lZ = zN * lerpHor + z;

                                    int mapIndex   = ChunkIndex2d(lX, lZ);
                                    int chunkIndex = ChunkIndex3d(lX, localY, lZ);

                                    chunks[chunkY].Blocks[chunkIndex] = 0;

                                    if (posY == 0)
                                    {
                                        chunks[chunkY].Blocks[chunkIndex] = GlobalConfig.mantleBlockId;
                                        continue;
                                    }


                                    if (tnoiseZ0 > thNoiseZ0)
                                    {
                                        terrainheightmap[mapIndex] = rainheightmap[mapIndex] = (ushort)Math.Max(rainheightmap[mapIndex], posY);

                                        chunks[chunkY].Blocks[chunkIndex] = GlobalConfig.defaultRockId;
                                    }
                                    else
                                    {
                                        if (posY < TerraGenConfig.seaLevel)
                                        {
                                            terrainheightmap[mapIndex] = rainheightmap[mapIndex] = (ushort)Math.Max(rainheightmap[mapIndex], posY);

                                            if (posY == TerraGenConfig.seaLevel - 1)
                                            {
                                                int   temp    = (GameMath.BiLerpRgbColor(((float)lX) / chunksize, ((float)lZ) / chunksize, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight) >> 16) & 0xff;
                                                float distort = (float)distort2dx.Noise(chunkX * chunksize + lX, chunkZ * chunksize + lZ) / 20f;
                                                float tempf   = TerraGenConfig.GetScaledAdjustedTemperatureFloat(temp, 0) + distort;

                                                chunks[chunkY].Blocks[chunkIndex] = (tempf < freezingTemp) ? GlobalConfig.lakeIceBlockId : GlobalConfig.waterBlockId;
                                            }
                                            else
                                            {
                                                chunks[chunkY].Blocks[chunkIndex] = GlobalConfig.waterBlockId;
                                            }
                                        }
                                        else
                                        {
                                            chunks[chunkY].Blocks[chunkIndex] = 0;
                                        }
                                    }

                                    tnoiseZ0  += tnoiseGainZ0;
                                    thNoiseZ0 += thNoiseGainZ0;
                                }

                                tnoiseX0 += tnoiseGainX0;
                                tnoiseX1 += tnoiseGainX1;

                                thNoiseX0 += thNoiseGainX0;
                                thNoiseX1 += thNoiseGainX1;
                            }

                            tnoiseY0 += tnoiseGainY0;
                            tnoiseY1 += tnoiseGainY1;
                            tnoiseY2 += tnoiseGainY2;
                            tnoiseY3 += tnoiseGainY3;
                        }
                    }
                }
            }

            ushort ymax = 0;

            for (int i = 0; i < rainheightmap.Length; i++)
            {
                ymax = Math.Max(ymax, rainheightmap[i]);
            }
            chunks[0].MapChunk.YMax = ymax;
        }
Esempio n. 23
0
        public void TryPlacePondAt(int dx, int pondYPos, int dz, int chunkX, int chunkZ, int depth = 0)
        {
            searchPositionsDeltas.Clear();
            pondPositions.Clear();

            // Clear Array
            for (int i = 0; i < didCheckPosition.Length; i++)
            {
                didCheckPosition[i] = false;
            }


            int   basePosX = chunkX * chunksize;
            int   basePosZ = chunkZ * chunksize;
            Vec2i tmp      = new Vec2i();


            searchPositionsDeltas.Enqueue(new Vec2i(dx, dz));
            pondPositions.Enqueue(new Vec2i(basePosX + dx, basePosZ + dz));
            didCheckPosition[(dz + mapOffset) * searchSize + dx + mapOffset] = true;


            while (searchPositionsDeltas.Count > 0)
            {
                Vec2i p = searchPositionsDeltas.Dequeue();

                foreach (BlockFacing facing in BlockFacing.HORIZONTALS)
                {
                    ndx = p.X + facing.Normali.X;
                    ndz = p.Y + facing.Normali.Z;

                    tmp.Set(chunkX * chunksize + ndx, chunkZ * chunksize + ndz);

                    Block belowBlock = blockAccessor.GetBlock(tmp.X, pondYPos - 1, tmp.Y);

                    bool inBoundary = ndx > minBoundary && ndz > minBoundary && ndx < maxBoundary && ndz < maxBoundary;

                    // Only continue when within our 3x3 chunk search area and having a more or less solid block below (or water)
                    if (inBoundary && (belowBlock.Replaceable < 6000 || belowBlock.BlockId == GlobalConfig.waterBlockId))
                    {
                        int arrayIndex = (ndz + mapOffset) * searchSize + ndx + mapOffset;

                        // Already checked or did we reach a pond border?
                        if (!didCheckPosition[arrayIndex] && blockAccessor.GetBlock(tmp.X, pondYPos, tmp.Y).Replaceable >= 6000)
                        {
                            searchPositionsDeltas.Enqueue(new Vec2i(ndx, ndz));
                            pondPositions.Enqueue(tmp.Copy());

                            didCheckPosition[arrayIndex] = true;
                        }
                    }
                    else
                    {
                        pondPositions.Clear();
                        searchPositionsDeltas.Clear();
                        return;
                    }
                }
            }

            if (pondPositions.Count == 0)
            {
                return;
            }


            int          curChunkX, curChunkZ;
            int          prevChunkX = -1, prevChunkZ = -1;
            int          regionChunkSize    = api.WorldManager.RegionSize / chunksize;
            IMapChunk    mapchunk           = null;
            IServerChunk chunk              = null;
            IServerChunk chunkOneBlockBelow = null;

            int ly = GameMath.Mod(pondYPos, chunksize);

            bool extraPondDepth = rand.NextDouble() > 0.5;
            bool withSeabed     = extraPondDepth || pondPositions.Count > 16;

            foreach (Vec2i p in pondPositions)
            {
                curChunkX = p.X / chunksize;
                curChunkZ = p.Y / chunksize;

                int lx = GameMath.Mod(p.X, chunksize);
                int lz = GameMath.Mod(p.Y, chunksize);

                // Get correct chunk and correct climate data if we don't have it already
                if (curChunkX != prevChunkX || curChunkZ != prevChunkZ)
                {
                    chunk = (IServerChunk)blockAccessor.GetChunk(curChunkX, pondYPos / chunksize, curChunkZ);
                    if (chunk == null)
                    {
                        chunk = api.WorldManager.GetChunk(curChunkX, pondYPos / chunksize, curChunkZ);
                    }
                    chunk.Unpack();

                    if (ly == 0)
                    {
                        chunkOneBlockBelow = ((IServerChunk)blockAccessor.GetChunk(curChunkX, (pondYPos - 1) / chunksize, curChunkZ));
                        if (chunkOneBlockBelow == null)
                        {
                            return;
                        }
                        chunkOneBlockBelow.Unpack();
                    }
                    else
                    {
                        chunkOneBlockBelow = chunk;
                    }

                    mapchunk = chunk.MapChunk;
                    IntDataMap2D climateMap = mapchunk.MapRegion.ClimateMap;

                    float fac = (float)climateMap.InnerSize / regionChunkSize;
                    int   rlX = curChunkX % regionChunkSize;
                    int   rlZ = curChunkZ % regionChunkSize;

                    climateUpLeft   = climateMap.GetUnpaddedInt((int)(rlX * fac), (int)(rlZ * fac));
                    climateUpRight  = climateMap.GetUnpaddedInt((int)(rlX * fac + fac), (int)(rlZ * fac));
                    climateBotLeft  = climateMap.GetUnpaddedInt((int)(rlX * fac), (int)(rlZ * fac + fac));
                    climateBotRight = climateMap.GetUnpaddedInt((int)(rlX * fac + fac), (int)(rlZ * fac + fac));

                    prevChunkX = curChunkX;
                    prevChunkZ = curChunkZ;

                    chunkOneBlockBelow.MarkModified();
                    chunk.MarkModified();
                }


                // Raise heightmap by 1
                mapchunk.RainHeightMap[lz * chunksize + lx] = Math.Max(mapchunk.RainHeightMap[lz * chunksize + lx], (ushort)pondYPos);

                // Identify correct climate at this position
                int   climate = GameMath.BiLerpRgbColor((float)lx / chunksize, (float)lz / chunksize, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight);
                float temp    = TerraGenConfig.GetScaledAdjustedTemperatureFloat((climate >> 16) & 0xff, pondYPos - TerraGenConfig.seaLevel);


                // 1. Place water or ice block
                chunk.Blocks[(ly * chunksize + lz) * chunksize + lx] = temp < -5 ? GlobalConfig.lakeIceBlockId : GlobalConfig.waterBlockId;


                // 2. Let's make a nice muddy gravely sea bed
                if (!withSeabed)
                {
                    continue;
                }

                // Need to check the block below first
                int index = ly == 0 ?
                            ((31 * chunksize + lz) * chunksize + lx) :
                            (((ly - 1) * chunksize + lz) * chunksize + lx)
                ;

                Block belowBlock = api.World.Blocks[chunkOneBlockBelow.Blocks[index]];

                // Water below? Seabed already placed
                if (belowBlock.IsLiquid())
                {
                    continue;
                }

                float rainRel     = TerraGenConfig.GetRainFall((climate >> 8) & 0xff, pondYPos) / 255f;
                int   rockBlockId = mapchunk.TopRockIdMap[lz * chunksize + lx];
                if (rockBlockId == 0)
                {
                    continue;
                }

                for (int i = 0; i < lakebedLayerConfig.BlockCodeByMin.Length; i++)
                {
                    if (lakebedLayerConfig.BlockCodeByMin[i].Suitable(temp, rainRel, (float)pondYPos / mapheight, rand))
                    {
                        chunkOneBlockBelow.Blocks[index] = lakebedLayerConfig.BlockCodeByMin[i].GetBlockForMotherRock(rockBlockId);
                        break;
                    }
                }
            }


            if (pondPositions.Count > 0 && extraPondDepth)
            {
                TryPlacePondAt(dx, pondYPos + 1, dz, chunkX, chunkZ, depth + 1);
            }
        }
Esempio n. 24
0
        private void OnChunkColumnGen(IServerChunk[] chunks, int chunkX, int chunkZ, ITreeAttribute chunkGenParams = null)
        {
            rand.InitPositionSeed(chunkX, chunkZ);

            ushort[] heightmap = chunks[0].MapChunk.RainHeightMap;

            IntDataMap2D climateMap      = chunks[0].MapChunk.MapRegion.ClimateMap;
            int          regionChunkSize = api.WorldManager.RegionSize / chunksize;
            float        fac             = (float)climateMap.InnerSize / regionChunkSize;
            int          rlX             = chunkX % regionChunkSize;
            int          rlZ             = chunkZ % regionChunkSize;

            climateUpLeft   = climateMap.GetUnpaddedInt((int)(rlX * fac), (int)(rlZ * fac));
            climateUpRight  = climateMap.GetUnpaddedInt((int)(rlX * fac + fac), (int)(rlZ * fac));
            climateBotLeft  = climateMap.GetUnpaddedInt((int)(rlX * fac), (int)(rlZ * fac + fac));
            climateBotRight = climateMap.GetUnpaddedInt((int)(rlX * fac + fac), (int)(rlZ * fac + fac));

            int climateMid = GameMath.BiLerpRgbColor(0.5f, 0.5f, climateUpLeft, climateUpRight, climateBotLeft, climateBotRight);

            // 16-23 bits = Red = temperature
            // 8-15 bits = Green = rain
            // 0-7 bits = Blue = humidity

            int rain     = (climateMid >> 8) & 0xff;
            int humidity = climateMid & 0xff;
            int temp     = (climateMid >> 16) & 0xff;

            // Lake density at chunk center
            float pondDensity = 4 * (rain + humidity) / 255f;

            float sealeveltemp = TerraGenConfig.GetScaledAdjustedTemperatureFloat(temp, 0);

            // Less lakes where its below -5 degrees
            pondDensity -= Math.Max(0, 5 - sealeveltemp);

            float maxTries = pondDensity * 10;

            int dx, dz;

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


            while (maxTries-- > 0)
            {
                if (maxTries < 1 && rand.NextDouble() > maxTries)
                {
                    break;
                }

                dx = rand.NextInt(chunksize);
                dz = rand.NextInt(chunksize);

                pondYPos = heightmap[dz * chunksize + dx] + 1;
                if (pondYPos <= 0 || pondYPos >= mapheight - 1)
                {
                    return;
                }

                TryPlacePondAt(dx, pondYPos, dz, chunkX, chunkZ);
            }

            maxTries = 600;
            while (maxTries-- > 0)
            {
                if (maxTries < 1 && rand.NextDouble() > maxTries)
                {
                    break;
                }

                dx = rand.NextInt(chunksize);
                dz = rand.NextInt(chunksize);

                pondYPos = (int)(rand.NextDouble() * heightmap[dz * chunksize + dx]);
                if (pondYPos <= 0 || pondYPos >= mapheight - 1)
                {
                    return;
                }

                int chunkY  = pondYPos / chunksize;
                int dy      = pondYPos % chunksize;
                int blockID = chunks[chunkY].Blocks[(dy * chunksize + dz) * chunksize + dx];

                while (blockID == 0 && pondYPos > 20)
                {
                    pondYPos--;

                    chunkY  = pondYPos / chunksize;
                    dy      = pondYPos % chunksize;
                    blockID = chunks[chunkY].Blocks[(dy * chunksize + dz) * chunksize + dx];

                    if (blockID != 0)
                    {
                        //blockAccessor.SetBlock(63, new BlockPos(dx + baseX, pondYPos, dz + baseZ));
                        TryPlacePondAt(dx, pondYPos, dz, chunkX, chunkZ);
                    }
                }
            }
        }