Ejemplo n.º 1
0
        public void RenderChunk(TImage dest, Chunk c, int xOffset, int zOffset)
        {
            var xzColumns         = c.Blocks.GroupBy(x => x.Value.XZ);
            var blocksOrderedByXZ = xzColumns.OrderBy(x => x.Key.GetLeByte(0)).ThenBy(x => x.Key.GetLeByte(1));
            var brightnessOffset  = Math.Min(renderSettings.BrillouinOffset, renderSettings.YMax);

            if (brightnessOffset < 0)
            {
                brightnessOffset = renderSettings.BrillouinOffset;
            }


            foreach (var blocks in blocksOrderedByXZ)
            {
                var blocksToRender = new Stack <BlockCoord>();

                List <KeyValuePair <uint, BlockCoord> > blocksFromSkyToBedrock = blocks.Where(x => x.Value.Block.Id != "minecraft:air").OrderByDescending(x => x.Value.Y).ToList();
                if (renderSettings.YMax > 0)
                {
                    blocksFromSkyToBedrock = blocksFromSkyToBedrock.Where(x => x.Value.Y <= renderSettings.YMax).ToList();
                }

                if (renderSettings.TrimCeiling)
                {
                    int start = -1;
                    for (int i = 1; i < blocksFromSkyToBedrock.Count(); i++)
                    {
                        if (Math.Abs(blocksFromSkyToBedrock[i].Value.Y - blocksFromSkyToBedrock[i - 1].Value.Y) > 4)
                        {
                            start = i;
                            break;
                        }
                    }

                    if (start != -1)
                    {
                        blocksFromSkyToBedrock.RemoveRange(0, start);
                    }
                }

                switch (renderSettings.Profile)
                {
                case "underground":
                {
                    var lastYValue  = 300;
                    var isRendering = false;
                    var state       = "goingthroughtoplevelsky";

                    foreach (var blockColumn in blocksFromSkyToBedrock)
                    {
                        var block = blockColumn.Value;

                        if (!isRendering)
                        {
                            var skyBlocksSkipped = lastYValue - block.Y - 1;

                            switch (state)
                            {
                            case "goingthroughtoplevelsky":
                                if (textureFinder.TransparentBlocks.ContainsKey(block.Block.Id) || block.Block.Id.Contains("water") || block.Block.Id.Contains("kelp"))
                                {
                                    continue;
                                }

                                lastYValue = block.Y;

                                if (skyBlocksSkipped > 0)
                                {
                                    state = "goingthroughground";
                                }
                                break;

                            case "goingthroughground":
                                lastYValue = block.Y;

                                if (textureFinder.TransparentBlocks.ContainsKey(block.Block.Id) || block.Block.Id.Contains("water") || block.Block.Id.Contains("kelp"))
                                {
                                    isRendering = true;
                                }

                                if (skyBlocksSkipped > 0)
                                {
                                    isRendering = true;
                                }
                                break;
                            }
                        }

                        if (isRendering)
                        {
                            blocksToRender.Push(block);
                            if (!textureFinder.TransparentBlocks.ContainsKey(block.Block.Id))
                            {
                                break;
                            }
                        }
                    }
                }
                break;

                case "aquatic":
                {
                    bool isWater = false;

                    foreach (var blockColumn in blocksFromSkyToBedrock)
                    {
                        var block = blockColumn.Value;

                        if (block.Block.Id.Contains("water"))
                        {
                            isWater = true;
                            continue;
                        }

                        if (!isWater)
                        {
                            // stop if we hit a solid block first
                            if (!textureFinder.TransparentBlocks.ContainsKey(block.Block.Id))
                            {
                                break;
                            }

                            continue;
                        }

                        blocksToRender.Push(block);
                        if (!textureFinder.TransparentBlocks.ContainsKey(block.Block.Id))
                        {
                            break;
                        }
                    }
                }
                break;

                case "ore":
                {
                    SearchForOres(blocksToRender, blocksFromSkyToBedrock);
                }
                break;

                case "stronghold":
                {
                    var lastYValue  = 300;
                    var isRendering = false;
                    var state       = "goingthroughtoplevelsky";

                    foreach (var blockColumn in blocksFromSkyToBedrock)
                    {
                        var block = blockColumn.Value;

                        if (!isRendering)
                        {
                            var skyBlocksSkipped = lastYValue - block.Y - 1;

                            switch (state)
                            {
                            case "goingthroughtoplevelsky":
                                if (textureFinder.TransparentBlocks.ContainsKey(block.Block.Id) || block.Block.Id.Contains("water") || block.Block.Id.Contains("kelp"))
                                {
                                    continue;
                                }

                                lastYValue = block.Y;

                                if (skyBlocksSkipped > 0)
                                {
                                    state = "goingthroughground";
                                }
                                break;

                            case "goingthroughground":
                                lastYValue = block.Y;

                                if (textureFinder.TransparentBlocks.ContainsKey(block.Block.Id) || block.Block.Id.Contains("water") || block.Block.Id.Contains("kelp"))
                                {
                                    isRendering = true;
                                }

                                if (skyBlocksSkipped > 0)
                                {
                                    isRendering = true;
                                }
                                break;
                            }
                        }

                        if (isRendering)
                        {
                            if (block.Block.Id.Contains("cobblestone") ||
                                block.Block.Id.Contains("brick") ||
                                block.Block.Id.Contains("end") ||
                                block.Block.Id.Contains("iron_bars") ||
                                block.Block.Id.Contains("spawn") ||
                                block.Block.Id.Contains("egg") ||
                                block.Block.Id.Contains("bookshelf") ||
                                block.Block.Id.Contains("cobweb") ||
                                block.Block.Id.Contains("oak_planks") ||
                                block.Block.Id.Contains("chest") ||
                                block.Block.Id.Contains("door"))
                            {
                                blocksToRender.Push(block);
                                if (!textureFinder.TransparentBlocks.ContainsKey(block.Block.Id))
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
                break;

                default:
                {
                    foreach (var blockColumn in blocksFromSkyToBedrock)         // Look for transparent blocks in single y column
                    {
                        var block = blockColumn.Value;

                        blocksToRender.Push(block);
                        if (!textureFinder.TransparentBlocks.ContainsKey(block.Block.Id))
                        {
                            break;
                        }
                    }
                }
                break;
                }

                foreach (var block in blocksToRender)
                {
                    var textures =
                        textureFinder.FindTexturePath(block.Block.Id, block.Block.Data, block.X, block.Z, block.Y);
                    if (textures == null)
                    {
                        Console.WriteLine($"\nMissing Texture(2): {block.ToString().PadRight(30)}");
                        MissingTextures.Add($"ID: {block.Block.Id}");
                        continue;
                    }

                    foreach (var texture in textures.Infos)
                    {
                        var bitmapTile = textureFinder.GetTextureImage(texture);
                        if (bitmapTile != null)
                        {
                            var x = xOffset + block.X * 16;
                            var z = zOffset + block.Z * 16;

                            if (renderSettings.RenderMode == RenderMode.Heightmap)
                            {
                                graphics.DrawImageWithBrightness(dest, bitmapTile, x, z, b.GetBrightness(block.Y - brightnessOffset));
                            }
                            else
                            {
                                graphics.DrawImageWithBrightness(dest, bitmapTile, x, z, 1);
                            }
                        }
                        else
                        {
                            Console.WriteLine($"\nMissing Texture(1): {block.ToString().PadRight(30)} -- {texture.Filename}");
                            MissingTextures.Add($"ID: {block.Block.Id}, {texture.Filename}");
                        }
                    }
                }
            }

            if (renderSettings.RenderCoordinateStrings)
            {
                graphics.DrawString(dest, $"{c.X * 1}, {c.Z * 1}", new Font(FontFamily.GenericSansSerif, 10), Brushes.Black, xOffset, zOffset);
            }
        }