Esempio n. 1
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);
            }

            // 2. Create
            map             = LandformMapByRegion[regionZ * regionMapSize + regionX]
                            = new LerpedWeightedIndex2DMap(mapchunk.MapRegion.LandformMap.Data, mapchunk.MapRegion.LandformMap.Size, TerraGenConfig.landFormSmothingRadius);

            return(map);
        }
Esempio n. 2
0
        public void preLoad(IServerChunk[] chunks, int chunkX, int chunkZ)
        {
            mapChunk  = chunks[0].MapChunk;
            heightMap = mapChunk.WorldGenTerrainHeightMap;
            rdx       = chunkX % regionChunkSize;
            rdz       = chunkZ % regionChunkSize;

            stratum         = null;
            step            = 0;
            strataThickness = 0;

            map            = GetOrLoadLerpedProvinceMap(chunks[0].MapChunk, chunkX, chunkZ);
            lerpMapInv     = 1f / TerraGenConfig.geoProvMapScale;
            chunkInRegionX = (chunkX % regionChunkSize) * lerpMapInv * chunksize;
            chunkInRegionZ = (chunkZ % regionChunkSize) * lerpMapInv * chunksize;

            provinces = NoiseGeoProvince.provinces;
            grp       = 0;
        }
Esempio n. 3
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. 4
0
        LerpedWeightedIndex2DMap CreateLerpedProvinceMap(IntMap geoMap, int regionX, int regionZ)
        {
            int index2d = regionZ * regionMapSize + regionX;

            return(ProvinceMapByRegion[index2d] = new LerpedWeightedIndex2DMap(geoMap.Data, geoMap.Size, TerraGenConfig.geoProvSmoothingRadius));
        }
Esempio n. 5
0
        internal void GenChunkColumn(IServerChunk[] chunks, int chunkX, int chunkZ)
        {
            ushort[] heightMap = chunks[0].MapChunk.RainHeightMap;

            float lerpMapInv = 1f / TerraGenConfig.geoProvMapScale;

            float chunkInRegionX = (chunkX % regionChunkSize) * lerpMapInv * chunksize;
            float chunkInRegionZ = (chunkZ % regionChunkSize) * lerpMapInv * chunksize;

            LerpedWeightedIndex2DMap map = GetOrLoadLerpedProvinceMap(chunks[0].MapChunk, chunkX, chunkZ);


            int localIndex3D;

            float chunkSizeFloat = chunksize;

            int absX, absZ;

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

                    absX = chunkX * chunksize + x;
                    absZ = chunkZ * chunksize + z;

                    // Todo: lerp these 3 noise gens for performance
                    double distortX   = (float)distort2dX.Noise(absX, absZ) * 160f;
                    double distortZ   = (float)distort2dZ.Noise(absX, absZ) * 160f;
                    double noiseValue = noiseGen.Noise(
                        absX + distortX,
                        absZ + distortZ
                        );

                    WeightedIndex[] indices = map[
                        TerraGenConfig.geoProvMapPadding + chunkInRegionX + x * lerpMapInv,
                        TerraGenConfig.geoProvMapPadding + chunkInRegionZ + z * lerpMapInv
                                              ];

                    LoadInterpolatedLayerBlockIds(noiseValue, indices, surfaceY);

                    int i = 0;

                    while (surfaceY >= 0)
                    {
                        int chunkY = surfaceY / chunksize;
                        int lY     = Math.Min(chunksize - 1, surfaceY - chunkY * chunksize);

                        localIndex3D = (chunksize * lY + z) * chunksize + x;

                        if (chunks[chunkY].Blocks[localIndex3D] == rockBlockId && finalBlockIds.Count > i)
                        {
                            chunks[chunkY].Blocks[localIndex3D] = finalBlockIds[i++];
                        }

                        surfaceY--;
                    }
                }
            }
        }
Esempio n. 6
0
        private void OnChunkColumnGen(IServerChunk[] chunks, int chunkX, int chunkZ)
        {
            landforms = NoiseLandforms.landforms;

            IntMap regionMap = chunks[0].MapChunk.MapRegion.LandformMap;
            // Amount of pixels for each chunk (probably 1, 2, or 4)
            float chunkPixelSize = regionMap.InnerSize / regionChunkSize;
            // Adjusted lerp for the noiseWidth
            float chunkPixelStep = chunkPixelSize / noiseWidth;
            // Start coordinates for the chunk in the region map
            float baseX = regionMap.TopLeftPadding + (chunkX % regionChunkSize) * chunkPixelSize;
            float baseZ = regionMap.TopLeftPadding + (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;

            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);

                                            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;
                        }
                    }
                }
            }

            int ymax = 0;

            for (int i = 0; i < rainheightmap.Length; i++)
            {
                ymax = Math.Max(ymax, rainheightmap[i]);
            }
            chunks[0].MapChunk.YMax = (ushort)ymax;
        }
Esempio n. 7
0
        void ReadPos(IServerPlayer player, CmdArgs arguments)
        {
            if (arguments.Length < 2)
            {
                player.SendMessage(groupId, "/wgen pos [gprov|landform|climate|height]", EnumChatType.CommandError);
                return;
            }


            int          chunkSize   = api.WorldManager.ChunkSize;
            BlockPos     pos         = player.Entity.Pos.AsBlockPos;
            IServerChunk serverchunk = api.WorldManager.GetChunk(pos);

            if (serverchunk == null)
            {
                player.SendMessage(groupId, "Can't check here, beyond chunk boundaries!", EnumChatType.CommandError);
                return;
            }

            IMapRegion mapRegion = serverchunk.MapChunk.MapRegion;
            IMapChunk  mapchunk  = serverchunk.MapChunk;

            int regionChunkSize = api.WorldManager.RegionSize / chunkSize;


            int lx      = pos.X % chunkSize;
            int lz      = pos.Z % chunkSize;
            int chunkX  = pos.X / chunkSize;
            int chunkZ  = pos.Z / chunkSize;
            int regionX = pos.X / regionSize;
            int regionZ = pos.Z / regionSize;

            switch (arguments[1])
            {
            case "coords":
                player.SendMessage(groupId, string.Format("Chunk X/Z: {0}/{1}, Region X/Z: {2},{3}", chunkX, chunkZ, regionX, regionZ), EnumChatType.CommandSuccess);
                break;

            case "structures":
                bool found = false;
                api.World.BlockAccessor.WalkStructures(pos, (struc) =>
                {
                    found = true;
                    player.SendMessage(groupId, "Structure with code " + struc.Code + " at this position", EnumChatType.CommandSuccess);
                });

                if (!found)
                {
                    player.SendMessage(groupId, "No structures at this position", EnumChatType.CommandSuccess);
                }

                return;


            case "height":
            {
                string str = string.Format("Rain y={0}, Worldgen terrain y={1}", serverchunk.MapChunk.RainHeightMap[lz * chunkSize + lx], serverchunk.MapChunk.WorldGenTerrainHeightMap[lz * chunkSize + lx]);
                player.SendMessage(groupId, str, EnumChatType.CommandSuccess);
            }
            break;


            case "cavedistort":
                Bitmap bmp = new Bitmap(chunkSize, chunkSize);

                for (int x = 0; x < chunkSize; x++)
                {
                    for (int z = 0; z < chunkSize; z++)
                    {
                        byte color = mapchunk.CaveHeightDistort[z * chunkSize + x];
                        bmp.SetPixel(x, z, Color.FromArgb((color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff));
                    }
                }

                bmp.Save("cavedistort" + chunkX + "-" + chunkZ + ".png");
                player.SendMessage(groupId, "saved bitmap cavedistort" + chunkX + "-" + chunkZ + ".png", EnumChatType.CommandSuccess);
                break;


            case "gprov":
            {
                int noiseSizeGeoProv = mapRegion.GeologicProvinceMap.InnerSize;

                float posXInRegion = ((float)pos.X / regionSize - regionX) * noiseSizeGeoProv;
                float posZInRegion = ((float)pos.Z / regionSize - regionZ) * noiseSizeGeoProv;
                GeologicProvinceVariant[] provincesByIndex = NoiseGeoProvince.provinces.Variants;
                IntMap intmap = mapRegion.GeologicProvinceMap;
                LerpedWeightedIndex2DMap map     = new LerpedWeightedIndex2DMap(intmap.Data, mapRegion.GeologicProvinceMap.Size, TerraGenConfig.geoProvSmoothingRadius, mapRegion.GeologicProvinceMap.TopLeftPadding, mapRegion.GeologicProvinceMap.BottomRightPadding);
                WeightedIndex[]          indices = map[posXInRegion, posZInRegion];

                string text = "";
                foreach (WeightedIndex windex in indices)
                {
                    if (text.Length > 0)
                    {
                        text += ", ";
                    }

                    text += (100 * windex.Weight).ToString("#.#") + "% " + provincesByIndex[windex.Index].Code;
                }

                player.SendMessage(groupId, text, EnumChatType.CommandSuccess);

                break;
            }


            case "rockstrata":
            {
                GenRockStrataNew rockstratagen = api.ModLoader.GetModSystem <GenRockStrataNew>();

                int   noiseSizeGeoProv = mapRegion.GeologicProvinceMap.InnerSize;
                float posXInRegion     = ((float)pos.X / regionSize - pos.X / regionSize) * noiseSizeGeoProv;
                float posZInRegion     = ((float)pos.Z / regionSize - pos.Z / regionSize) * noiseSizeGeoProv;
                GeologicProvinceVariant[] provincesByIndex = NoiseGeoProvince.provinces.Variants;
                IntMap intmap = mapRegion.GeologicProvinceMap;
                LerpedWeightedIndex2DMap map     = new LerpedWeightedIndex2DMap(intmap.Data, mapRegion.GeologicProvinceMap.Size, TerraGenConfig.geoProvSmoothingRadius, mapRegion.GeologicProvinceMap.TopLeftPadding, mapRegion.GeologicProvinceMap.BottomRightPadding);
                WeightedIndex[]          indices = map[posXInRegion, posZInRegion];

                float[] rockGroupMaxThickness = new float[4];

                rockGroupMaxThickness[0] = rockGroupMaxThickness[1] = rockGroupMaxThickness[2] = rockGroupMaxThickness[3] = 0;

                int    rdx = chunkX % regionChunkSize;
                int    rdz = chunkZ % regionChunkSize;
                IntMap rockMap;
                float  step  = 0;
                float  distx = (float)rockstratagen.distort2dx.Noise(pos.X, pos.Z);
                float  distz = (float)rockstratagen.distort2dz.Noise(pos.X, pos.Z);



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

                    GeologicProvinceVariant var = NoiseGeoProvince.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;
                }

                System.Text.StringBuilder sb = new System.Text.StringBuilder();

                sb.AppendLine("Sedimentary max thickness: " + rockGroupMaxThickness[(int)EnumRockGroup.Sedimentary]);
                sb.AppendLine("Metamorphic max thickness: " + rockGroupMaxThickness[(int)EnumRockGroup.Metamorphic]);
                sb.AppendLine("Igneous max thickness: " + rockGroupMaxThickness[(int)EnumRockGroup.Igneous]);
                sb.AppendLine("Volcanic max thickness: " + rockGroupMaxThickness[(int)EnumRockGroup.Volcanic]);
                sb.AppendLine("========");

                for (int id = 0; id < rockstratagen.strata.Variants.Length; id++)
                {
                    rockMap = mapchunk.MapRegion.RockStrata[id];
                    step    = (float)rockMap.InnerSize / regionChunkSize;

                    float dist = 1 + GameMath.Clamp((distx + distz) / 30, 0.9f, 1.1f);
                    sb.AppendLine(rockstratagen.strata.Variants[id].BlockCode.ToShortString() + " max thickness: " + rockMap.GetIntLerpedCorrectly(rdx * step + step * (float)(lx + distx) / chunkSize, rdz * step + step * (float)(lz + distz) / chunkSize));
                }

                sb.AppendLine("======");

                int         surfaceY        = api.World.BlockAccessor.GetTerrainMapheightAt(pos);
                int         ylower          = 1;
                int         yupper          = surfaceY;
                int         rockStrataId    = -1;
                float       strataThickness = 0;
                RockStratum stratum         = null;


                OrderedDictionary <int, int> stratathicknesses = new OrderedDictionary <int, int>();

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

                        int grp = (int)stratum.RockGroup;

                        float dist = 1 + GameMath.Clamp((distx + distz) / 30, 0.9f, 1.1f);
                        strataThickness = Math.Min(rockGroupMaxThickness[grp] * dist, 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;
                        }
                    }

                    if (!stratathicknesses.ContainsKey(stratum.BlockId))
                    {
                        stratathicknesses[stratum.BlockId] = 0;
                    }
                    stratathicknesses[stratum.BlockId]++;

                    if (stratum.GenDir == EnumStratumGenDir.BottomUp)
                    {
                        ylower++;
                    }
                    else
                    {
                        yupper--;
                    }
                }

                foreach (var val in stratathicknesses)
                {
                    sb.AppendLine(api.World.Blocks[val.Key].Code.ToShortString() + " : " + val.Value + " blocks");
                }


                player.SendMessage(groupId, sb.ToString(), EnumChatType.CommandSuccess);

                break;
            }


            case "landform":
            {
                int noiseSizeLandform = mapRegion.LandformMap.InnerSize;

                float posXInRegion = ((float)pos.X / regionSize - pos.X / regionSize) * noiseSizeLandform;
                float posZInRegion = ((float)pos.Z / regionSize - pos.Z / regionSize) * noiseSizeLandform;


                LandformVariant[] landforms = NoiseLandforms.landforms.LandFormsByIndex;

                IntMap intmap = mapRegion.LandformMap;

                LerpedWeightedIndex2DMap map = new LerpedWeightedIndex2DMap(intmap.Data, mapRegion.LandformMap.Size, TerraGenConfig.landFormSmoothingRadius, intmap.TopLeftPadding, intmap.BottomRightPadding);

                WeightedIndex[] indices = map[posXInRegion, posZInRegion];

                string text = "";
                foreach (WeightedIndex windex in indices)
                {
                    if (text.Length > 0)
                    {
                        text += ", ";
                    }

                    text += (100 * windex.Weight).ToString("#.#") + "% " + landforms[windex.Index].Code;
                }

                player.SendMessage(groupId, text, EnumChatType.CommandSuccess);

                break;
            }

            case "climate":
            {
                ClimateCondition climate = api.World.BlockAccessor.GetClimateAt(pos);

                string text = string.Format("Temperature: {0}°, Rainfall: {1}%, Fertility: {2}%, Forest: {3}%, Shrub: {4}%, Sealevel dist: {5}%", climate.Temperature.ToString("0.#"), (int)(climate.Rainfall * 100f), (int)(climate.Fertility * 100f), (int)(climate.ForestDensity * 100f), (int)(climate.ShrubDensity * 100f), (int)(100f * pos.Y / 255f));

                player.SendMessage(groupId, text, EnumChatType.CommandSuccess);


                break;
            }
            }
        }
Esempio n. 8
0
        private void ReadRegion(IServerPlayer player, CmdArgs arguments)
        {
            if (arguments.Length < 1)
            {
                player.SendMessage(groupId, "/wgen region [climate|ore|forest|wind|gprov|gprovi|landform|landformi]", EnumChatType.CommandError);
                return;
            }

            int          chunkSize   = api.WorldManager.ChunkSize;
            BlockPos     pos         = player.Entity.Pos.AsBlockPos;
            IServerChunk serverchunk = api.WorldManager.GetChunk(pos);

            if (serverchunk == null)
            {
                player.SendMessage(groupId, "Can't check here, beyond chunk boundaries!", EnumChatType.CommandError);
                return;
            }

            IMapRegion mapRegion = serverchunk.MapChunk.MapRegion;


            int regionX = pos.X / regionSize;
            int regionZ = pos.Z / regionSize;

            string arg = arguments.PopWord();

            string subarg = arguments.PopWord();
            bool   dolerp = subarg == "nolerp";

            NoiseBase.Debug = true;

            switch (arg)
            {
            case "climate":
                DrawMapRegion(0, player, mapRegion.ClimateMap, "climate", dolerp, regionX, regionZ, TerraGenConfig.climateMapScale);
                break;

            case "ore":
                string type = dolerp ? arguments.PopWord("limonite") : subarg;
                if (type == null)
                {
                    type = "limonite";
                }

                if (!mapRegion.OreMaps.ContainsKey(type))
                {
                    player.SendMessage(groupId, "Mapregion does not contain an ore map for ore " + type, EnumChatType.CommandError);
                    return;
                }

                DrawMapRegion(DebugDrawMode.RGB, player, mapRegion.OreMaps[type], "ore-" + type, dolerp, regionX, regionZ, TerraGenConfig.oreMapScale);
                break;

            case "forest":
                DrawMapRegion(DebugDrawMode.FirstByteGrayscale, player, mapRegion.ForestMap, "forest", dolerp, regionX, regionZ, TerraGenConfig.forestMapScale);
                break;


            case "oretopdistort":
                DrawMapRegion(DebugDrawMode.FirstByteGrayscale, player, mapRegion.OreMapVerticalDistortTop, "oretopdistort", dolerp, regionX, regionZ, TerraGenConfig.depositVerticalDistortScale);
                break;

            //case "depdist":
            //DrawMapRegion(0, player, mapRegion.DepositDistortionMap, "depositdistortion", dolerp, regionX, regionZ, TerraGenConfig.depositDistortionScale);
            //break;

            case "rockstrata":

                for (int i = 0; i < mapRegion.RockStrata.Length; i++)
                {
                    DrawMapRegion(DebugDrawMode.FirstByteGrayscale, player, mapRegion.RockStrata[i], "rockstrata" + i, dolerp, regionX, regionZ, TerraGenConfig.rockStrataScale);
                }
                break;

            case "wind":
            {
            }
            break;


            case "gprov":
                DrawMapRegion(DebugDrawMode.ProvinceRGB, player, mapRegion.GeologicProvinceMap, "province", dolerp, regionX, regionZ, TerraGenConfig.geoProvMapScale);
                break;


            case "gprovi":
            {
                int[] gprov            = mapRegion.GeologicProvinceMap.Data;
                int   noiseSizeGeoProv = mapRegion.GeologicProvinceMap.InnerSize;

                int outSize = (noiseSizeGeoProv + TerraGenConfig.geoProvMapPadding - 1) * TerraGenConfig.geoProvMapScale;

                GeologicProvinceVariant[] provincesByIndex = NoiseGeoProvince.provinces.Variants;

                LerpedWeightedIndex2DMap map = new LerpedWeightedIndex2DMap(gprov, noiseSizeGeoProv + 2 * TerraGenConfig.geoProvMapPadding, 2, mapRegion.GeologicProvinceMap.TopLeftPadding, mapRegion.GeologicProvinceMap.BottomRightPadding);

                int[] outColors = new int[outSize * outSize];
                for (int x = 0; x < outSize; x++)
                {
                    for (int z = 0; z < outSize; z++)
                    {
                        WeightedIndex[] indices = map[(float)x / TerraGenConfig.geoProvMapScale, (float)z / TerraGenConfig.geoProvMapScale];
                        for (int i = 0; i < indices.Length; i++)
                        {
                            indices[i].Index = provincesByIndex[indices[i].Index].ColorInt;
                        }
                        int[]   colors;
                        float[] weights;
                        map.Split(indices, out colors, out weights);
                        outColors[z * outSize + x] = ColorUtil.ColorAverage(colors, weights);
                    }
                }

                NoiseBase.DebugDrawBitmap(DebugDrawMode.ProvinceRGB, outColors, outSize, outSize, "geoprovince-lerped-" + regionX + "-" + regionZ);

                player.SendMessage(groupId, "done", EnumChatType.CommandSuccess);

                break;
            }



            case "landform":
                DrawMapRegion(DebugDrawMode.LandformRGB, player, mapRegion.LandformMap, "landform", dolerp, regionX, regionZ, TerraGenConfig.landformMapScale);
                break;



            case "landformi":
            {
                int[] data = mapRegion.LandformMap.Data;
                int   noiseSizeLandform = mapRegion.LandformMap.InnerSize;

                int outSize = (noiseSizeLandform + TerraGenConfig.landformMapPadding - 1) * TerraGenConfig.landformMapScale;

                LandformVariant[] landformsByIndex = NoiseLandforms.landforms.LandFormsByIndex;

                LerpedWeightedIndex2DMap map = new LerpedWeightedIndex2DMap(data, mapRegion.LandformMap.Size, 1, mapRegion.LandformMap.TopLeftPadding, mapRegion.LandformMap.BottomRightPadding);

                int[] outColors = new int[outSize * outSize];
                for (int x = 0; x < outSize; x++)
                {
                    for (int z = 0; z < outSize; z++)
                    {
                        WeightedIndex[] indices = map[(float)x / TerraGenConfig.landformMapScale, (float)z / TerraGenConfig.landformMapScale];
                        for (int i = 0; i < indices.Length; i++)
                        {
                            indices[i].Index = landformsByIndex[indices[i].Index].ColorInt;
                        }
                        int[]   colors;
                        float[] weights;
                        map.Split(indices, out colors, out weights);
                        outColors[z * outSize + x] = ColorUtil.ColorAverage(colors, weights);
                    }
                }

                NoiseBase.DebugDrawBitmap(DebugDrawMode.LandformRGB, outColors, outSize, outSize, "landform-lerped-" + regionX + "-" + regionZ);

                player.SendMessage(groupId, "Landform map done", EnumChatType.CommandSuccess);

                break;
            }


            default:
                player.SendMessage(groupId, "/wgen region [climate|ore|forest|wind|gprov|landform]", EnumChatType.CommandError);
                break;
            }

            NoiseBase.Debug = false;
        }
Esempio n. 9
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. 10
0
        void ReadPos(IServerPlayer player, CmdArgs arguments)
        {
            if (arguments.Length < 2)
            {
                player.SendMessage(groupId, "/wgen pos [gprov|landform|climate|height]", EnumChatType.CommandError);
                return;
            }


            int          chunkSize   = api.WorldManager.ChunkSize;
            BlockPos     pos         = player.Entity.Pos.AsBlockPos;
            IServerChunk serverchunk = api.WorldManager.GetChunk(pos);

            if (serverchunk == null)
            {
                player.SendMessage(groupId, "Can check here, beyond chunk boundaries!", EnumChatType.CommandError);
                return;
            }

            IMapRegion mapRegion = serverchunk.MapChunk.MapRegion;


            int regionChunkSize = api.WorldManager.RegionSize / chunkSize;


            int lx      = pos.X % chunkSize;
            int lz      = pos.Z % chunkSize;
            int chunkX  = pos.X / chunkSize;
            int chunkZ  = pos.Z / chunkSize;
            int regionX = pos.X / regionSize;
            int regionZ = pos.Z / regionSize;

            switch (arguments[1])
            {
            case "height":
            {
                string str = string.Format("Rain y={0}, Worldgen terrain y={1}", serverchunk.MapChunk.RainHeightMap[lz * chunkSize + lx], serverchunk.MapChunk.WorldGenTerrainHeightMap[lz * chunkSize + lx]);
                player.SendMessage(groupId, str, EnumChatType.CommandSuccess);
            }
            break;

            case "gprov":
            {
                int noiseSizeGeoProv = mapRegion.GeologicProvinceMap.InnerSize;

                float posXInRegion = ((float)pos.X / regionSize - pos.X / regionSize) * noiseSizeGeoProv;
                float posZInRegion = ((float)pos.Z / regionSize - pos.Z / regionSize) * noiseSizeGeoProv;


                GeologicProvinceVariant[] provincesByIndex = NoiseGeoProvince.provinces.Variants;

                IntMap intmap = mapRegion.GeologicProvinceMap;

                LerpedWeightedIndex2DMap map = new LerpedWeightedIndex2DMap(intmap.Data, mapRegion.GeologicProvinceMap.Size, TerraGenConfig.geoProvSmoothingRadius);

                WeightedIndex[] indices = map[intmap.TopLeftPadding + posXInRegion, intmap.TopLeftPadding + posZInRegion];

                string text = "";
                foreach (WeightedIndex windex in indices)
                {
                    if (text.Length > 0)
                    {
                        text += ", ";
                    }

                    text += (100 * windex.weight).ToString("#.#") + "% " + provincesByIndex[windex.index].Code;
                }

                player.SendMessage(groupId, text, EnumChatType.CommandSuccess);

                break;
            }


            case "landform":
            {
                int noiseSizeLandform = mapRegion.LandformMap.InnerSize;

                float posXInRegion = ((float)pos.X / regionSize - pos.X / regionSize) * noiseSizeLandform;
                float posZInRegion = ((float)pos.Z / regionSize - pos.Z / regionSize) * noiseSizeLandform;


                LandformVariant[] landforms = NoiseLandforms.landforms.LandFormsByIndex;

                IntMap intmap = mapRegion.LandformMap;

                LerpedWeightedIndex2DMap map = new LerpedWeightedIndex2DMap(intmap.Data, mapRegion.LandformMap.Size, TerraGenConfig.landFormSmothingRadius);

                WeightedIndex[] indices = map[intmap.TopLeftPadding + posXInRegion, intmap.TopLeftPadding + posZInRegion];

                string text = "";
                foreach (WeightedIndex windex in indices)
                {
                    if (text.Length > 0)
                    {
                        text += ", ";
                    }

                    text += (100 * windex.weight).ToString("#.#") + "% " + landforms[windex.index].Code;
                }

                player.SendMessage(groupId, text, EnumChatType.CommandSuccess);

                break;
            }

            case "climate":
            {
                ClimateCondition climate = api.World.BlockAccessor.GetClimateAt(pos);

                string text = string.Format("Temperature: {0}°, Rainfall: {1}%, Fertility: {2}%, Forest: {3}%, Shrub: {4}%, Sealevel dist: {5}%", climate.Temperature.ToString("0.#"), (int)(climate.Rainfall * 100f), (int)(climate.Fertility * 100f), (int)(climate.ForestDensity * 100f), (int)(climate.ShrubDensity * 100f), (int)(100f * pos.Y / 255f));

                player.SendMessage(groupId, text, EnumChatType.CommandSuccess);


                break;
            }
            }
        }
Esempio n. 11
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));
        }