diff --git a/docs/config.rst b/docs/config.rst index f64a52d01..2d4107986 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -1141,6 +1141,15 @@ Hide blocks A list of block ids, or (blockid, data) tuples to hide. +Show + Show blocks based on blockid. Blocks hidden in this way will be + trated exactly the same as air. + + **Options** + + blocks + A list of block ids, or (blockid, data) tuples to show. + DepthTinting Tint blocks a color according to their depth (height) from bedrock. Useful mainly for cave renders. diff --git a/overviewer_core/rendermodes.py b/overviewer_core/rendermodes.py index 7ae67fe3f..cc2f477a5 100644 --- a/overviewer_core/rendermodes.py +++ b/overviewer_core/rendermodes.py @@ -237,6 +237,12 @@ class Hide(RenderPrimitive): 'blocks' : ('a list of blockids or (blockid, data) tuples of blocks to hide', []), } +class Show(RenderPrimitive): + name = "show" + options = { + 'blocks': ('a list of blockids or (blockid, data) tuples of blocks to show', []), + } + # Built-in rendermodes for your convenience! normal = [Base(), EdgeLines()] lighting = [Base(), EdgeLines(), Lighting()] diff --git a/overviewer_core/src/primitives/show.c b/overviewer_core/src/primitives/show.c new file mode 100644 index 000000000..140586c43 --- /dev/null +++ b/overviewer_core/src/primitives/show.c @@ -0,0 +1,118 @@ +/* + * This file is part of the Minecraft Overviewer. + * + * Minecraft Overviewer is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as published + * by the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Minecraft Overviewer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with the Overviewer. If not, see . + */ + +#include "../mc_id.h" +#include "../overviewer.h" + +struct ShowRule { + mc_block_t blockid; + bool has_data; + uint8_t data; +}; + +typedef struct { + struct ShowRule* rules; +} RenderPrimitiveShow; + +static bool +show_start(void* data, RenderState* state, PyObject* support) { + PyObject* opt; + RenderPrimitiveShow* self = (RenderPrimitiveShow*)data; + self->rules = NULL; + + if (!render_mode_parse_option(support, "blocks", "O", &(opt))) + return true; + if (opt && opt != Py_None) { + Py_ssize_t blocks_size = 0, i; + + if (!PyList_Check(opt)) { + PyErr_SetString(PyExc_TypeError, "'blocks' must be a list"); + return true; + } + + blocks_size = PyList_GET_SIZE(opt); + self->rules = calloc(blocks_size + 1, sizeof(struct ShowRule)); + if (self->rules == NULL) { + return true; + } + + for (i = 0; i < blocks_size; i++) { + PyObject* block = PyList_GET_ITEM(opt, i); + + if (PyLong_Check(block)) { + /* format 1: just a block id */ + self->rules[i].blockid = PyLong_AsLong(block); + self->rules[i].has_data = false; + } else if (PyArg_ParseTuple(block, "Hb", &(self->rules[i].blockid), &(self->rules[i].data))) { + /* format 2: (blockid, data) */ + self->rules[i].has_data = true; + } else { + /* format not recognized */ + free(self->rules); + self->rules = NULL; + return true; + } + } + } + + return false; +} + +static void +show_finish(void* data, RenderState* state) { + RenderPrimitiveShow* self = (RenderPrimitiveShow*)data; + + if (self->rules) { + free(self->rules); + } +} + +static bool +show_hidden(void* data, RenderState* state, int32_t x, int32_t y, int32_t z) { + RenderPrimitiveShow* self = (RenderPrimitiveShow*)data; + uint32_t i; + mc_block_t block; + + if (self->rules == NULL) + return true; + + block = get_data(state, BLOCKS, x, y, z); + for (i = 0; self->rules[i].blockid != block_air; i++) { + if (block == self->rules[i].blockid) { + uint8_t data; + + if (!(self->rules[i].has_data)) + return false; + + data = get_data(state, DATA, x, y, z); + if (data == self->rules[i].data) + return false; + } + } + + return true; +} + +RenderPrimitiveInterface primitive_show = { + "show", + sizeof(RenderPrimitiveShow), + show_start, + show_finish, + NULL, + show_hidden, + NULL, +};