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