private MapChunkData _initChunkBuffers(IMapGrid grid, IMapChunk chunk) { var vao = (uint)GL.GenVertexArray(); GL.BindVertexArray(vao); var vboSize = _verticesPerChunk(chunk) * Vertex2D.SizeOf; var eboSize = _indicesPerChunk(chunk) * sizeof(ushort); var vbo = new GLBuffer(this, BufferTarget.ArrayBuffer, BufferUsageHint.DynamicDraw, vboSize, $"Grid {grid.Index} chunk {chunk.Indices} VBO"); var ebo = new GLBuffer(this, BufferTarget.ElementArrayBuffer, BufferUsageHint.DynamicDraw, eboSize, $"Grid {grid.Index} chunk {chunk.Indices} EBO"); ObjectLabelMaybe(ObjectLabelIdentifier.VertexArray, vao, $"Grid {grid.Index} chunk {chunk.Indices} VAO"); // Vertex Coords GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 0); GL.EnableVertexAttribArray(0); // Texture Coords. GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 2 * sizeof(float)); GL.EnableVertexAttribArray(1); // Assign VBO and EBO to VAO. // OpenGL 3.x is such a good API. vbo.Use(); ebo.Use(); var datum = new MapChunkData(vao, vbo, ebo) { Dirty = true }; _mapChunkData[grid.Index].Add(chunk.Indices, datum); return(datum); }
internal void processBlockUpdates(Vec2i coord, UpdateSnowLayerChunk updateChunk, IBulkBlockAccessor ba) { int chunkX = coord.X; int chunkZ = coord.Y; var setblocks = updateChunk.SetBlocks; double lastSnowAccumUpdateTotalHours = updateChunk.LastSnowAccumUpdateTotalHours; IMapChunk mc = sapi.WorldManager.GetMapChunk(chunkX, chunkZ); if (mc == null) { return; // No longer loaded, we can just ditch it and re-do the thing again next time it gets loaded again } Vec2i tmpVec = new Vec2i(); foreach (var sval in setblocks) { Block newblock = sval.Value.Block; float snowLevel = sval.Value.SnowLevel; Block hereblock = ba.GetBlock(sval.Key); tmpVec.Set(sval.Key.X, sval.Key.Z); if (snowLevel > 0 && !mc.SnowAccum.ContainsKey(tmpVec)) { continue; // Must have gotten removed since we last checked in our seperate thread } hereblock.PerformSnowLevelUpdate(ba, sval.Key, newblock, snowLevel); } mc.SetData("lastSnowAccumUpdateTotalHours", SerializerUtil.Serialize <double>(lastSnowAccumUpdateTotalHours)); mc.MarkDirty(); }
internal void processBlockUpdates(IMapChunk mc, UpdateSnowLayerChunk updateChunk, IBulkBlockAccessor ba) { var setblocks = updateChunk.SetBlocks; double lastSnowAccumUpdateTotalHours = updateChunk.LastSnowAccumUpdateTotalHours; Vec2i tmpVec = new Vec2i(); foreach (var sval in setblocks) { Block newblock = sval.Value.Block; float snowLevel = sval.Value.SnowLevel; Block hereblock = ba.GetBlock(sval.Key); tmpVec.Set(sval.Key.X, sval.Key.Z); if (snowLevel > 0 && !mc.SnowAccum.ContainsKey(tmpVec)) { continue; // Must have gotten removed since we last checked in our seperate thread } hereblock.PerformSnowLevelUpdate(ba, sval.Key, newblock, snowLevel); } mc.SetModdata("lastSnowAccumUpdateTotalHours", SerializerUtil.Serialize <double>(lastSnowAccumUpdateTotalHours)); mc.MarkDirty(); }
private void Event_DidPlaceBlock(IServerPlayer byPlayer, int oldblockId, BlockSelection blockSel, ItemStack withItemStack) { IMapChunk mapchunk = api.World.BlockAccessor.GetMapChunkAtBlockPos(blockSel.Position); if (mapchunk == null) { return; } int lx = blockSel.Position.X % chunksize; int lz = blockSel.Position.Z % chunksize; int y = mapchunk.RainHeightMap[lz * chunksize + lx]; int ly = y % chunksize; IWorldChunk chunk = api.World.BlockAccessor.GetChunkAtBlockPos(blockSel.Position.X, y, blockSel.Position.Z); if (chunk == null) { return; } chunk.Unpack(); int blockId = chunk.Blocks[(ly * chunksize + lz) * chunksize + lx]; if (blockId == 0) { int cx = blockSel.Position.X / chunksize; int cz = blockSel.Position.Z / chunksize; api.World.Logger.Notification("Huh. Found air block in rain map at chunk pos {0}/{1}. That seems invalid, will regenerate rain map", cx, cz); rebuildRainmap(cx, cz); } }
private void AttachChunksToCells() { foreach (var cell in Cells) { int chunkIndexX = Mathf.FloorToInt(cell.AbsolutePosition.x / RenderConfig.ChunkWidth); int chunkIndexZ = Mathf.FloorToInt(cell.AbsolutePosition.z / RenderConfig.ChunkHeight); var overlappingChunks = new List <IMapChunk>(); for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { int candidateX = Math.Max(0, Math.Min(chunkIndexX + i, ChunkCountX - 1)); int candidateZ = Math.Max(0, Math.Min(chunkIndexZ + j, ChunkCountZ - 1)); IMapChunk candidate = chunks[candidateX, candidateZ]; if (candidate.DoesCellOverlapChunk(cell)) { overlappingChunks.Add(candidate); } } } cell.AttachToChunks(overlappingChunks); foreach (var chunk in overlappingChunks) { chunk.AttachCell(cell, chunk.IsInTerrainBounds2D(cell.AbsolutePositionXZ)); } } }
private void GetNewTextures(IMapChunk chunk, out Texture2D newLand, out Texture2D newWater) { BakedElementFlags bakedElements = BakedElementsLogic.GetBakedElementsInCells(chunk.CenteredCells); bakedElements |= BakedElementsLogic.GetBakedElementsInCells(chunk.OverlappingCells); Vector2 textureSize = GetBakeTextureDimensionsForElements(bakedElements); int textureX = Mathf.RoundToInt(textureSize.x); int textureY = Mathf.RoundToInt(textureSize.y); newLand = new Texture2D(textureX, textureY, TextureFormat.ARGB32, false); newLand.filterMode = FilterMode.Point; newLand.wrapMode = TextureWrapMode.Clamp; newLand.anisoLevel = 0; newLand.name = "Land Bake Texture"; newWater = new Texture2D(textureX, textureY, TextureFormat.ARGB32, false); newWater.filterMode = FilterMode.Point; newWater.wrapMode = TextureWrapMode.Clamp; newWater.anisoLevel = 0; newWater.name = "Water Bake Texture"; }
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); }
public void PerformBakePass( IMapChunk chunk, Texture2D texture, CameraClearFlags clearFlags, LayerMask cullingMask, Shader replacementShader = null, string replacementTag = "" ) { IsReady = false; OriginalParent = transform.parent; transform.SetParent(chunk.transform, false); var renderTarget = GetRenderTarget(texture); BakingCamera.targetTexture = renderTarget; BakingCamera.clearFlags = clearFlags; BakingCamera.cullingMask = cullingMask; if (replacementShader != null) { BakingCamera.RenderWithShader(replacementShader, replacementTag); } else { BakingCamera.Render(); } }
protected override void beforeGenDeposit(IMapChunk mapChunk, BlockPos pos) { depthf = YPosRel.nextFloat(1, DepositRand); pos.Y = (int)depthf; step = (float)mapChunk.MapRegion.OreMapVerticalDistortTop.InnerSize / regionChunkSize; }
public ChunkOrientationData MakeOrientationRequestForChunk(IMapChunk chunk) { var newData = new ChunkOrientationData(chunk); UnrenderedOrientationData.Add(newData); return(newData); }
protected override void loadYPosAndThickness(IMapChunk heremapchunk, int lx, int lz, BlockPos targetPos, double distanceToEdge) { double curTh = depoitThickness * GameMath.Clamp(distanceToEdge * 2 - 0.2, 0, 1); hereThickness = (int)curTh + ((DepositRand.NextDouble() < (curTh - (int)curTh)) ? 1 : 0); targetPos.Y = heremapchunk.WorldGenTerrainHeightMap[lz * chunksize + lx] - posyi; }
private void _updateChunkMesh(IMapGrid grid, IMapChunk chunk) { var data = _mapChunkData[grid.Index]; if (!data.TryGetValue(chunk.Indices, out var datum)) { datum = _initChunkBuffers(grid, chunk); } var vertexPool = ArrayPool <Vertex2D> .Shared; var indexPool = ArrayPool <ushort> .Shared; var vertexBuffer = vertexPool.Rent(_verticesPerChunk(chunk)); var indexBuffer = indexPool.Rent(_indicesPerChunk(chunk)); try { var i = 0; foreach (var tile in chunk) { var regionMaybe = _tileDefinitionManager.TileAtlasRegion(tile.Tile); if (regionMaybe == null) { continue; } var region = regionMaybe.Value; var vIdx = i * 4; vertexBuffer[vIdx + 0] = new Vertex2D(tile.X + 1, tile.Y + 1, region.Right, region.Top); vertexBuffer[vIdx + 1] = new Vertex2D(tile.X, tile.Y + 1, region.Left, region.Top); vertexBuffer[vIdx + 2] = new Vertex2D(tile.X + 1, tile.Y, region.Right, region.Bottom); vertexBuffer[vIdx + 3] = new Vertex2D(tile.X, tile.Y, region.Left, region.Bottom); var nIdx = i * 5; var tIdx = (ushort)(i * 4); indexBuffer[nIdx + 0] = tIdx; indexBuffer[nIdx + 1] = (ushort)(tIdx + 1); indexBuffer[nIdx + 2] = (ushort)(tIdx + 2); indexBuffer[nIdx + 3] = (ushort)(tIdx + 3); indexBuffer[nIdx + 4] = ushort.MaxValue; i += 1; } GL.BindVertexArray(datum.VAO); CheckGlError(); datum.EBO.Use(); datum.VBO.Use(); datum.EBO.Reallocate(new Span <ushort>(indexBuffer, 0, i * 5)); datum.VBO.Reallocate(new Span <Vertex2D>(vertexBuffer, 0, i * 4)); datum.Dirty = false; datum.TileCount = i; } finally { vertexPool.Return(vertexBuffer); indexPool.Return(indexBuffer); } }
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); } }
public override void OnOffThreadTick() { int quantityToGen = chunksToGen.Count; while (quantityToGen > 0) { quantityToGen--; Vec2i cord; lock (chunksToGenLock) { if (chunksToGen.Count == 0) { break; } cord = chunksToGen.Dequeue(); } if (!api.World.BlockAccessor.IsValidPos(cord.X * chunksize, 1, cord.Y * chunksize)) { continue; } IMapChunk mc = api.World.BlockAccessor.GetMapChunk(cord); if (mc == null) { lock (chunksToGenLock) { chunksToGen.Enqueue(cord); } continue; } int[] pixels = (int[])GenerateChunkImage(cord, mc)?.Clone(); if (pixels == null) { lock (chunksToGenLock) { chunksToGen.Enqueue(cord); } continue; } api.Event.EnqueueMainThreadTask(() => { if (loadedMapData.ContainsKey(cord)) { UpdateMapData(loadedMapData[cord] as ChunkMapComponent, pixels); } else { mapSink.AddMapData(loadedMapData[cord] = LoadMapData(cord, pixels)); } }, "chunkmaplayerready"); } }
protected override void beforeGenDeposit(IMapChunk mapChunk, BlockPos targetPos) { ypos = YPosRel.nextFloat(1, DepositRand); posyi = (int)ypos; targetPos.Y = posyi; step = (float)mapChunk.MapRegion.OreMapVerticalDistortTop.InnerSize / regionChunkSize; }
protected override void loadYPosAndThickness(IMapChunk heremapchunk, int lx, int lz, BlockPos pos, double distanceToEdge) { double curTh = depoitThickness * GameMath.Clamp(distanceToEdge * 2 - 0.2, 0, 1); hereThickness = (int)curTh + ((DepositRand.NextDouble() < (curTh - (int)curTh)) ? 1 : 0); int yOff = (int)getDepositYDistort(targetPos, lx, lz, step, heremapchunk); pos.Y = posyi + yOff; }
protected override void loadYPosAndThickness(IMapChunk heremapchunk, int lx, int lz, BlockPos pos, double distanceToEdge) { hereThickness = depoitThickness; pos.Y = (int)(depthf * heremapchunk.WorldGenTerrainHeightMap[lz * chunksize + lx]); pos.Y -= (int)getDepositYDistort(pos, lx, lz, step, heremapchunk); double curTh = depoitThickness * GameMath.Clamp(distanceToEdge * 2 - 0.2, 0, 1); hereThickness = (int)curTh + ((DepositRand.NextDouble() < (curTh - (int)curTh)) ? 1 : 0); }
private void TryBakeChunks() { Profiler.BeginSample("TryBakeChunks()"); int dataCount = Math.Min(RenderConfig.MaxParallelTerrainRefreshes, FreeBakerPairs.Count); var chunksToProcess = UnbakedChunks.Where(chunk => !chunk.IsRefreshing).Take(dataCount).ToArray(); for (int i = 0; i < chunksToProcess.Length; i++) { IMapChunk activeChunk = chunksToProcess[i]; Texture2D newLand, newWater; GetNewTextures(activeChunk, out newLand, out newWater); UnbakedChunks.Remove(activeChunk); if (newLand.width > 0 && newLand.height > 0 && newWater.width > 0 && newWater.height > 0) { var servingBakerPair = FreeBakerPairs.Dequeue(); BakeLand(activeChunk, newLand, servingBakerPair.Item1); BakeWater(activeChunk, newWater, servingBakerPair.Item2); servingBakerPair.Item1.ReadPixels(newLand, texture => { if (activeChunk.LandBakeTexture != null) { Destroy(activeChunk.LandBakeTexture); } activeChunk.LandBakeTexture = texture; }); servingBakerPair.Item2.ReadPixels(newWater, texture => { if (activeChunk.WaterBakeTexture != null) { Destroy(activeChunk.WaterBakeTexture); } activeChunk.WaterBakeTexture = texture; }); PairsOfUnreadChunks[activeChunk] = servingBakerPair; } else { activeChunk.LandBakeTexture = newLand; activeChunk.WaterBakeTexture = newWater; } } Profiler.EndSample(); }
private void OnChunkBeganToRefresh(IMapChunk chunk) { if (ChunksRefreshing.Count == 0) { foreach (var gridChunk in Grid.Chunks) { gridChunk.IsRendering = true; } } ChunksRefreshing.Add(chunk); }
void rebuildRainmap(int cx, int cz) { ICoreServerAPI sapi = api as ICoreServerAPI; int ymax = sapi.WorldManager.MapSizeY / sapi.WorldManager.ChunkSize; IServerChunk[] column = new IServerChunk[ymax]; int chunksize = sapi.WorldManager.ChunkSize; IMapChunk mapchunk = null; for (int cy = 0; cy < ymax; cy++) { column[cy] = sapi.WorldManager.GetChunk(cx, cy, cz); column[cy]?.Unpack(); mapchunk = column[cy]?.MapChunk; } if (mapchunk == null) { return; } for (int dx = 0; dx < chunksize; dx++) { for (int dz = 0; dz < chunksize; dz++) { for (int dy = sapi.WorldManager.MapSizeY - 1; dy >= 0; dy--) { IServerChunk chunk = column[dy / chunksize]; if (chunk == null) { continue; } int index = ((dy % chunksize) * chunksize + dz) * chunksize + dx; Block block = sapi.World.Blocks[chunk.Blocks[index]]; if (!block.RainPermeable || dy == 0) { mapchunk.RainHeightMap[dz * chunksize + dx] = (ushort)dy; break; } } } } sapi.WorldManager.ResendMapChunk(cx, cz, true); mapchunk.MarkDirty(); }
public void PerformBakePass(IMapChunk chunk, CameraClearFlags clearFlags, LayerMask cullingMask) { IsReady = false; OriginalParent = transform.parent; Camera.transform.SetParent(chunk.transform, false); Camera.clearFlags = clearFlags; Camera.cullingMask = cullingMask; Camera.Render(); }
public void PerformBakePass(IMapChunk chunk, CameraClearFlags clearFlags, LayerMask cullingMask, Shader replacementShader, string replacementTag) { IsReady = false; OriginalParent = transform.parent; Camera.transform.SetParent(chunk.transform, false); Camera.clearFlags = clearFlags; Camera.cullingMask = cullingMask; Camera.RenderWithShader(replacementShader, replacementTag); }
public override void OnOffThreadTick() { int quantityToGen = chunksToGen.Count; while (quantityToGen > 0) { quantityToGen--; Vec2i cord; lock (chunksToGenLock) { if (chunksToGen.Count == 0) { break; } cord = chunksToGen.Dequeue(); } IMapChunk mc = api.World.BlockAccessor.GetMapChunk(cord); if (mc == null) { lock (chunksToGenLock) { chunksToGen.Enqueue(cord); } continue; } int[] pixels = (int[])GenerateChunkImage(cord, mc)?.Clone(); if (pixels == null) { lock (chunksToGenLock) { chunksToGen.Enqueue(cord); } continue; } api.Event.EnqueueMainThreadTask(() => { if (loadedMapData.ContainsKey(cord)) { loadedMapData[cord].Dispose(); mapSink.RemoveMapData(loadedMapData[cord]); } mapSink.AddMapData(loadedMapData[cord] = LoadMapData(cord, pixels)); }, "chunkmaplayerready"); } }
LerpedWeightedIndex2DMap GetOrLoadLerpedProvinceMap(IMapChunk mapchunk, int chunkX, int chunkZ) { int index2d = chunkZ / regionChunkSize * regionMapSize + chunkX / regionChunkSize; LerpedWeightedIndex2DMap map; ProvinceMapByRegion.TryGetValue(index2d, out map); if (map != null) { return(map); } return(CreateLerpedProvinceMap(mapchunk.MapRegion.GeologicProvinceMap, chunkX / regionChunkSize, chunkZ / regionChunkSize)); }
public float getDepositYDistort(BlockPos pos, int lx, int lz, float step, IMapChunk heremapchunk) { int rdx = (pos.X / chunksize) % regionChunkSize; int rdz = (pos.Z / chunksize) % regionChunkSize; IMapRegion reg = heremapchunk.MapRegion; float yOffTop = reg.OreMapVerticalDistortTop.GetIntLerpedCorrectly(rdx * step + step * ((float)lx / chunksize), rdz * step + step * ((float)lz / chunksize)) - 20; float yOffBot = reg.OreMapVerticalDistortBottom.GetIntLerpedCorrectly(rdx * step + step * ((float)lx / chunksize), rdz * step + step * ((float)lz / chunksize)) - 20; float yRel = (float)pos.Y / worldheight; return(yOffBot * (1 - yRel) + yOffTop * yRel); }
// Tyrons Brute force way of getting the correct reading for a rock strata column public virtual int[] GetRockColumn(int posX, int posZ) { int chunksize = sapi.World.BlockAccessor.ChunkSize; DummyChunk[] chunks = new DummyChunk[sapi.World.BlockAccessor.MapSizeY / chunksize]; int chunkX = posX / chunksize; int chunkZ = posZ / chunksize; int lx = posX % chunksize; int lz = posZ % chunksize; IMapChunk mapchunk = sapi.World.BlockAccessor.GetMapChunk(new Vec2i(chunkX, chunkZ)); for (int chunkY = 0; chunkY < chunks.Length; chunkY++) { chunks[chunkY] = new DummyChunk(chunksize); chunks[chunkY].MapChunk = mapchunk; chunks[chunkY].chunkY = chunkY; } int surfaceY = mapchunk.WorldGenTerrainHeightMap[lz * chunksize + lx]; for (int y = 0; y < surfaceY; y++) { int chunkY = y / chunksize; int lY = y - chunkY * chunksize; int localIndex3D = (chunksize * lY + lz) * chunksize + lx; chunks[chunkY].Blocks[localIndex3D] = rockStrataGen.rockBlockId; } rockStrataGen.preLoad(chunks, chunkX, chunkZ); rockStrataGen.genBlockColumn(chunks, chunkX, chunkZ, lx, lz); depositGen.GeneratePartial(chunks, chunkX, chunkZ, 0, 0); int[] rockColumn = new int[surfaceY]; for (int y = 0; y < surfaceY; y++) { int chunkY = y / chunksize; int lY = y - chunkY * chunksize; int localIndex3D = (chunksize * lY + lz) * chunksize + lx; rockColumn[y] = chunks[chunkY].Blocks[localIndex3D]; } return(rockColumn); }
private void OnChunkFinishedRefreshing(IMapChunk chunk) { foreach (var cell in chunk.CenteredCells) { foreach (var unit in UnitPositionCanon.GetPossessionsOfOwner(cell)) { if (!RepositioningCoroutineForUnit.ContainsKey(unit)) { RepositioningCoroutineForUnit[unit] = CoroutineInvoker.StartCoroutine( RefreshAfterChunksDone(unit, cell.OverlappingChunks) ); } } } }
private void OnMapChunkGen(IMapChunk mapChunk, int chunkX, int chunkZ) { mapChunk.CaveHeightDistort = new byte[chunksize * chunksize]; for (int dx = 0; dx < chunksize; dx++) { for (int dz = 0; dz < chunksize; dz++) { double val = heightvarNoise.Noise(chunksize * chunkX + dx, chunksize * chunkZ + dz) - 0.5; val = val > 0 ? Math.Max(0, val - 0.07) : Math.Min(0, val + 0.07); mapChunk.CaveHeightDistort[dz * chunksize + dx] = (byte)(128 * val + 127); } } }
private static YamlNode SerializeChunk(IMapChunk chunk) { var root = new YamlMappingNode(); var value = new YamlScalarNode($"{chunk.X},{chunk.Y}"); value.Style = ScalarStyle.DoubleQuoted; root.Add("ind", value); var gridNode = new YamlScalarNode(); root.Add("tiles", gridNode); gridNode.Value = SerializeTiles(chunk); return(root); }
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); }