예제 #1
0
        public void initWorldGen(int seedDiff)
        {
            IAsset asset = api.Assets.Get("worldgen/rockstrata.json");

            strata = asset.ToObject <RockStrataConfig>();

            for (int i = 0; i < strata.Variants.Length; i++)
            {
                strata.Variants[i].Init(api.World);
            }

            LoadGlobalConfig(api);

            chunksize  = api.WorldManager.ChunkSize;
            regionSize = api.WorldManager.RegionSize;
            chunkRatio = (float)chunksize / regionSize;

            // Unpadded region noise size in chunks
            regionChunkSize = regionSize / chunksize;

            rand = new Random(api.WorldManager.Seed + seedDiff);

            // Unpadded region noise size in blocks
            int geoProvRegionNoiseSize = regionSize / TerraGenConfig.geoProvMapScale;

            // Amount of regions in all of the map
            regionMapSize = api.WorldManager.MapSizeX / (chunksize * geoProvRegionNoiseSize);

            rockBlockId = (ushort)api.WorldManager.GetBlockId(new AssetLocation("rock-granite"));
            worldHeight = api.WorldManager.MapSizeY;

            distort2dx = new SimplexNoise(new double[] { 14, 9, 6, 3 }, new double[] { 1 / 100.0, 1 / 50.0, 1 / 25.0, 1 / 12.5 }, api.World.SeaLevel + 9876 + seedDiff);
            distort2dz = new SimplexNoise(new double[] { 14, 9, 6, 3 }, new double[] { 1 / 100.0, 1 / 50.0, 1 / 25.0, 1 / 12.5 }, api.World.SeaLevel + 9877 + seedDiff);

            strataNoises = new MapLayerCustomPerlin[strata.Variants.Length];
            for (int i = 0; i < strataNoises.Length; i++)
            {
                RockStratum stratum = strata.Variants[i];

                double[] ampls = (double[])stratum.Amplitudes.Clone();
                double[] freq  = (double[])stratum.Frequencies.Clone();
                double[] th    = (double[])stratum.Thresholds.Clone();

                if (ampls.Length != freq.Length || ampls.Length != th.Length)
                {
                    throw new ArgumentException(string.Format("Bug in Rock stratum {0}: The list of amplitudes ({1} elements), frequencies ({2} elements) and thresholds ({3} elements) are not of the same length!", i, ampls.Length, freq.Length, th.Length));
                }

                for (int j = 0; j < freq.Length; j++)
                {
                    freq[j]  /= TerraGenConfig.rockStrataOctaveScale;
                    ampls[j] *= api.WorldManager.MapSizeY;
                    th[j]    *= api.WorldManager.MapSizeY;
                }

                strataNoises[i] = new MapLayerCustomPerlin(api.World.Seed + 23423 + i + seedDiff, ampls, freq, th);
            }
        }
예제 #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;
        }
예제 #3
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;
            }
            }
        }
예제 #4
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--;
                }
            }
        }