Esempio n. 1
0
        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();
        }
Esempio n. 4
0
        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);
            }
        }
Esempio n. 5
0
        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));
                }
            }
        }
Esempio n. 6
0
        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";
        }
Esempio n. 7
0
        public virtual void GenDeposit(IServerChunk[] chunks, int chunkX, int chunkZ, BlockPos depoCenterPos, DepositVariant variant)
        {
            int lx = GameMath.Mod(depoCenterPos.X, chunksize);
            int lz = GameMath.Mod(depoCenterPos.Z, chunksize);

            // Check if suited for this area, climate wise
            if (variant.Climate != null)
            {
                IMapChunk originMapchunk = api.WorldManager.GetMapChunk(depoCenterPos.X / chunksize, depoCenterPos.Z / chunksize);

                if (originMapchunk == null)
                {
                    return;                         // Definition: Climate dependent deposits are limited to size 32x32x32
                }
                depoCenterPos.Y = originMapchunk.RainHeightMap[lz * chunksize + lx];

                IntDataMap2D climateMap = blockAccessor.GetMapRegion(depoCenterPos.X / regionSize, depoCenterPos.Z / regionSize).ClimateMap;

                float posXInRegionClimate = ((float)lx / regionSize - (float)lx / regionSize) * noiseSizeClimate;
                float posZInRegionClimate = ((float)lz / regionSize - (float)lz / regionSize) * noiseSizeClimate;

                int   climate = climateMap.GetUnpaddedColorLerped(posXInRegionClimate, posZInRegionClimate);
                float temp    = TerraGenConfig.GetScaledAdjustedTemperatureFloat((climate >> 16) & 0xff, depoCenterPos.Y - TerraGenConfig.seaLevel);
                float rainRel = TerraGenConfig.GetRainFall((climate >> 8) & 0xff, depoCenterPos.Y) / 255f;

                if (rainRel < variant.Climate.MinRain || rainRel > variant.Climate.MaxRain || temp < variant.Climate.MinTemp || temp > variant.Climate.MaxTemp)
                {
                    return;
                }
            }

            variant.GeneratorInst?.GenDeposit(blockAccessor, chunks, chunkX, chunkZ, depoCenterPos, ref subDepositsToPlace);
        }
        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;
        }
Esempio n. 12
0
        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);
            }
        }
Esempio n. 13
0
        private void OnChunkColumnGen(IServerChunk[] chunks, int chunkX, int chunkZ, ITreeAttribute chunkGenParams = null)
        {
            rnd.InitPositionSeed(chunkX, chunkZ);

            IMapChunk mapChunk = chunks[0].MapChunk;

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

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

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

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

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

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

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

            heightmap = chunks[0].MapChunk.RainHeightMap;


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

            if (TerraGenConfig.GenerateVegetation)
            {
                genPatches(chunkX, chunkZ, false);
                genShrubs(chunkX, chunkZ);
                genTrees(chunkX, chunkZ);
                genPatches(chunkX, chunkZ, true);
            }
        }
Esempio n. 14
0
        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);
        }
Esempio n. 18
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);
        }
Esempio n. 20
0
        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();
        }
Esempio n. 21
0
        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();
        }
Esempio n. 22
0
        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);
        }
Esempio n. 23
0
        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");
            }
        }
Esempio n. 24
0
        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));
        }
Esempio n. 25
0
        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);
        }
Esempio n. 27
0
 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)
                     );
             }
         }
     }
 }
Esempio n. 28
0
        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);
                }
            }
        }
Esempio n. 29
0
        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);
        }
Esempio n. 30
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);
        }