0

Completely change biome code again

Turns out my previous grasp of how Minecraft does this was wrong.

This seems to be the correct way. One side effect is that biome data
now has less resolution. One only really notices this when looking at
water, for which Minecraft does not even use the water colours for
in-game, otherwise I can't really tell a big difference.

Fixes #1698.
This commit is contained in:
Nicolas F
2019-12-23 23:50:20 +01:00
parent 2b699d0355
commit 0b74d26c49
4 changed files with 46 additions and 48 deletions

View File

@@ -109,12 +109,10 @@ static inline void load_chunk_section(ChunkData* dest, int32_t i, PyObject* sect
dest->sections[i].data = (PyArrayObject*)PyDict_GetItemString(section, "Data");
dest->sections[i].skylight = (PyArrayObject*)PyDict_GetItemString(section, "SkyLight");
dest->sections[i].blocklight = (PyArrayObject*)PyDict_GetItemString(section, "BlockLight");
dest->sections[i].biomes = (PyArrayObject*)PyDict_GetItemString(section, "Biomes");
Py_INCREF(dest->sections[i].blocks);
Py_INCREF(dest->sections[i].data);
Py_INCREF(dest->sections[i].skylight);
Py_INCREF(dest->sections[i].blocklight);
Py_INCREF(dest->sections[i].biomes);
}
/* loads the given chunk into the chunks[] array in the state
@@ -132,12 +130,13 @@ bool load_chunk(RenderState* state, int32_t x, int32_t z, uint8_t required) {
if (dest->loaded)
return false;
/* set reasonable defaults */
dest->biomes = NULL;
for (i = 0; i < SECTIONS_PER_CHUNK; i++) {
dest->sections[i].blocks = NULL;
dest->sections[i].data = NULL;
dest->sections[i].skylight = NULL;
dest->sections[i].blocklight = NULL;
dest->sections[i].biomes = NULL;
}
dest->loaded = 1;
@@ -167,6 +166,9 @@ bool load_chunk(RenderState* state, int32_t x, int32_t z, uint8_t required) {
return true;
}
dest->biomes = (PyArrayObject*)PyDict_GetItemString(chunk, "Biomes");
Py_INCREF(dest->biomes);
dest->new_biomes = PyObject_IsTrue(PyDict_GetItemString(chunk, "NewBiomes"));
for (i = 0; i < PySequence_Fast_GET_SIZE(sections); i++) {
PyObject* ycoord = NULL;
@@ -193,12 +195,12 @@ unload_all_chunks(RenderState* state) {
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
if (state->chunks[i][j].loaded) {
Py_XDECREF(state->chunks[i][j].biomes);
for (k = 0; k < SECTIONS_PER_CHUNK; k++) {
Py_XDECREF(state->chunks[i][j].sections[k].blocks);
Py_XDECREF(state->chunks[i][j].sections[k].data);
Py_XDECREF(state->chunks[i][j].sections[k].skylight);
Py_XDECREF(state->chunks[i][j].sections[k].blocklight);
Py_XDECREF(state->chunks[i][j].sections[k].biomes);
}
state->chunks[i][j].loaded = 0;
}

View File

@@ -29,9 +29,9 @@
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
// increment this value if you've made a change to the c extesion
// increment this value if you've made a change to the c extension
// and want to force users to rebuild
#define OVERVIEWER_EXTENSION_VERSION 78
#define OVERVIEWER_EXTENSION_VERSION 79
#include <stdbool.h>
#include <stdint.h>
@@ -84,10 +84,12 @@ typedef struct {
int32_t loaded;
/* chunk biome array */
PyArrayObject* biomes;
/* whether this is a 3d biome array */
bool new_biomes;
/* all the sections in a given chunk */
struct {
/* all there is to know about each section */
PyArrayObject *blocks, *data, *skylight, *blocklight, *biomes;
PyArrayObject *blocks, *data, *skylight, *blocklight;
} sections[SECTIONS_PER_CHUNK];
} ChunkData;
typedef struct {
@@ -210,7 +212,7 @@ static inline uint32_t get_data(RenderState* state, DataType type, int32_t x, in
data_array = state->chunks[chunkx][chunkz].sections[chunky].skylight;
break;
case BIOMES:
data_array = state->chunks[chunkx][chunkz].sections[chunky].biomes;
data_array = state->chunks[chunkx][chunkz].biomes;
};
if (data_array == NULL)
@@ -218,8 +220,13 @@ static inline uint32_t get_data(RenderState* state, DataType type, int32_t x, in
if (type == BLOCKS)
return getArrayShort3D(data_array, x, y, z);
if (type == BIOMES)
return getArrayByte2D(data_array, x, z);
if (type == BIOMES) {
if (state->chunks[chunkx][chunkz].new_biomes) {
return getArrayByte3D(data_array, x / 4, y / 4, z / 4);
} else {
return getArrayByte2D(data_array, x, z);
}
}
return getArrayByte3D(data_array, x, y, z);
}