Minecraft-Overviewer/overviewer_core/src/primitives/hide.c

119 lines
3.2 KiB
C

/*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "../mc_id.h"
#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 (PyLong_Check(block)) {
/* format 1: just a block id */
self->rules[i].blockid = PyLong_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;
unsigned short block;
if (self->rules == NULL)
return 0;
block = get_data(state, BLOCKS, x, y, z);
for (i = 0; self->rules[i].blockid != block_air; i++) {
if (block == self->rules[i].blockid) {
unsigned char data;
if (!(self->rules[i].has_data))
return 1;
data = get_data(state, DATA, x, y, z);
if (data == self->rules[i].data)
return 1;
}
}
return 0;
}
RenderPrimitiveInterface primitive_hide = {
"hide",
sizeof(RenderPrimitiveHide),
hide_start,
hide_finish,
NULL,
hide_hidden,
NULL,
};