diff --git a/docs/config.rst b/docs/config.rst index 1884573..e7e4c99 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -560,6 +560,15 @@ Cave only_lit Only render lit caves. Default: False +Hide + Hide blocks based on blockid. Blocks hidden in this way will be + treated exactly the same as air. + + **Options** + + minerals + A list of block ids, or (blockid, data) tuples to hide. + 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 e1adc9c..8ea0b52 100644 --- a/overviewer_core/rendermodes.py +++ b/overviewer_core/rendermodes.py @@ -188,6 +188,12 @@ class MineralOverlay(Overlay): 'minerals' : ('a list of (blockid, (r, g, b)) tuples for coloring minerals', None), } +class Hide(RenderPrimitive): + name = "hide" + options = { + 'blocks' : ('a list of blockids or (blockid, data) tuples of blocks to hide', []), + } + # Built-in rendermodes for your convenience! normal = [Base(), EdgeLines()] lighting = [Base(), EdgeLines(), Lighting()] diff --git a/overviewer_core/src/primitives/hide.c b/overviewer_core/src/primitives/hide.c new file mode 100644 index 0000000..5444e82 --- /dev/null +++ b/overviewer_core/src/primitives/hide.c @@ -0,0 +1,111 @@ +/* + * 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 "../overviewer.h" + +struct HideRule { + unsigned short blockid; + unsigned char has_data; + unsigned char data; +}; + +typedef struct { + struct HideRule* rules; +} RenderPrimitiveHide; + +static int +hide_start(void *data, RenderState *state, PyObject *support) { + PyObject *opt; + RenderPrimitiveHide* self = (RenderPrimitiveHide *)data; + self->rules = NULL; + + if (!render_mode_parse_option(support, "blocks", "O", &(opt))) + return 1; + 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 1; + } + + blocks_size = PyList_GET_SIZE(opt); + self->rules = calloc(blocks_size + 1, sizeof(struct HideRule)); + if (self->rules == NULL) { + return 1; + } + + for (i = 0; i < blocks_size; i++) { + PyObject *block = PyList_GET_ITEM(opt, i); + + if (PyInt_Check(block)) { + /* format 1: just a block id */ + self->rules[i].blockid = PyInt_AsLong(block); + self->rules[i].has_data = 0; + } else if (PyArg_ParseTuple(block, "Hb", &(self->rules[i].blockid), &(self->rules[i].data))) { + /* format 2: (blockid, data) */ + self->rules[i].has_data = 1; + } else { + /* format not recognized */ + free(self->rules); + self->rules = NULL; + return 1; + } + } + } + + return 0; +} + +static void +hide_finish(void *data, RenderState *state) { + RenderPrimitiveHide *self = (RenderPrimitiveHide *)data; + + if (self->rules) { + free(self->rules); + } +} + +static int +hide_hidden(void *data, RenderState *state, int x, int y, int z) { + RenderPrimitiveHide *self = (RenderPrimitiveHide *)data; + unsigned int i; + + if (self->rules == NULL) + return 0; + + for (i = 0; self->rules[i].blockid != 0; i++) { + if (state->block == self->rules[i].blockid) { + if (!(self->rules[i].has_data)) + return 1; + if (state->block_data == self->rules[i].data) + return 1; + } + } + + return 0; +} + +RenderPrimitiveInterface primitive_hide = { + "hide", + sizeof(RenderPrimitiveHide), + hide_start, + hide_finish, + NULL, + hide_hidden, + NULL, +};