diff --git a/overviewer_core/src/iterate.c b/overviewer_core/src/iterate.c index ae5e985..58668ac 100644 --- a/overviewer_core/src/iterate.c +++ b/overviewer_core/src/iterate.c @@ -207,7 +207,7 @@ unload_all_chunks(RenderState *state) { } } -unsigned char +unsigned short check_adjacent_blocks(RenderState *state, int x,int y,int z, unsigned short blockid) { /* * Generates a pseudo ancillary data for blocks that depend of @@ -265,14 +265,14 @@ is_stairs(int block) { return 0; } -unsigned char -generate_pseudo_data(RenderState *state, unsigned char ancilData) { +unsigned short +generate_pseudo_data(RenderState *state, unsigned short ancilData) { /* * Generates a fake ancillary data for blocks that are drawn * depending on what are surrounded. */ int x = state->x, y = state->y, z = state->z; - unsigned char data = 0; + unsigned short data = 0; if (state->block == 2) { /* grass */ /* return 0x10 if grass is covered in snow */ @@ -295,15 +295,18 @@ generate_pseudo_data(RenderState *state, unsigned char ancilData) { data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f); return data; } - } else if ((state->block == 20) || (state->block == 79)) { /* glass and ice */ - /* an aditional bit for top is added to the 4 bits of check_adjacent_blocks */ - if (get_data(state, BLOCKS, x, y+1, z) == 20) { + } else if ((state->block == 20) || (state->block == 79) || (state->block == 95)) { /* glass and ice and stained glass*/ + /* an aditional bit for top is added to the 4 bits of check_adjacent_blocks + * Note that stained glass encodes 16 colors using 4 bits. this pushes us over the 8-bits of an unsigned char, + * forcing us to use an unsigned short to hold 16 bits of pseudo ancil data + * */ + if ((get_data(state, BLOCKS, x, y+1, z) == 20) || (get_data(state, BLOCKS, x, y+1, z) == 95)) { data = 0; } else { data = 16; } data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f) | data; - return data; + return (data << 4) | (ancilData & 0x0f); } else if (state->block == 85) { /* fences */ /* check for fences AND fence gates */ return check_adjacent_blocks(state, x, y, z, state->block) | check_adjacent_blocks(state, x, y, z, 107); @@ -379,12 +382,14 @@ generate_pseudo_data(RenderState *state, unsigned char ancilData) { } return final_data; - } else if ((state->block == 101) || (state->block == 102)) { + } else if ((state->block == 101) || (state->block == 102) || (state->block == 160)) { /* iron bars and glass panes: * they seem to stick to almost everything but air, * not sure yet! Still a TODO! */ /* return check adjacent blocks with air, bit inverted */ - return check_adjacent_blocks(state, x, y, z, 0) ^ 0x0f; + // shift up 4 bits because the lower 4 bits encode color + data = (check_adjacent_blocks(state, x, y, z, 0) ^ 0x0f); + return (data << 4) | (ancilData & 0xf); } else if ((state->block == 90) || (state->block == 113)) { /* portal and nether brick fences */ @@ -656,7 +661,7 @@ chunk_render(PyObject *self, PyObject *args) { state.imgy = yoff - state.x*6 + state.z*6 + 16*12 + 15*6; for (state.y = 0; state.y < 16; state.y++) { - unsigned char ancilData; + unsigned short ancilData; state.imgy -= 12; @@ -701,6 +706,7 @@ chunk_render(PyObject *self, PyObject *args) { (state.block == 101) || (state.block == 102) || (state.block == 111) || (state.block == 113) || (state.block == 139) || (state.block == 175) || + (state.block == 160) || (state.block == 95) || is_stairs(state.block)) { ancilData = generate_pseudo_data(&state, ancilData); state.block_pdata = ancilData; diff --git a/overviewer_core/src/overviewer.h b/overviewer_core/src/overviewer.h index bbeb433..e0c4a46 100644 --- a/overviewer_core/src/overviewer.h +++ b/overviewer_core/src/overviewer.h @@ -26,7 +26,7 @@ // increment this value if you've made a change to the c extesion // and want to force users to rebuild -#define OVERVIEWER_EXTENSION_VERSION 43 +#define OVERVIEWER_EXTENSION_VERSION 44 /* Python PIL, and numpy headers */ #include @@ -108,7 +108,7 @@ typedef struct { int x, y, z; unsigned short block; unsigned char block_data; - unsigned char block_pdata; + unsigned short block_pdata; /* useful information about this, and neighboring, chunks */ PyObject *blockdatas; diff --git a/overviewer_core/textures.py b/overviewer_core/textures.py index 52f4870..9557a59 100644 --- a/overviewer_core/textures.py +++ b/overviewer_core/textures.py @@ -914,15 +914,20 @@ def water(self, blockid, data): # other water, glass, and ice (no inner surfaces) # uses pseudo-ancildata found in iterate.c -@material(blockid=[9, 20, 79], data=range(32), fluid=(9,), transparent=True, nospawn=True, solid=(79, 20)) +@material(blockid=[9, 20, 79, 95], data=range(512), fluid=(9,), transparent=True, nospawn=True, solid=(79, 20, 95)) def no_inner_surfaces(self, blockid, data): if blockid == 9: texture = self.load_water() elif blockid == 20: texture = self.load_image_texture("assets/minecraft/textures/blocks/glass.png") + elif blockid == 95: + texture = self.load_image_texture("assets/minecraft/textures/blocks/glass_%s.png" % color_map[data & 0x0f]) else: texture = self.load_image_texture("assets/minecraft/textures/blocks/ice.png") - + + # now that we've used the lower 4 bits to get color, shift down to get the 5 bits that encode face hiding + data = data >> 4 + if (data & 0b10000) == 16: top = texture else: @@ -1774,7 +1779,8 @@ def stairs(self, blockid, data): return img # normal, locked (used in april's fool day), ender and trapped chest -@material(blockid=[54,95,130,146], data=range(30), transparent = True) +# NOTE: locked chest used to be id95 (which is now stained glass) +@material(blockid=[54,130,146], data=range(30), transparent = True) def chests(self, blockid, data): # the first 3 bits are the orientation as stored in minecraft, # bits 0x8 and 0x10 indicate which half of the double chest is it. @@ -1797,7 +1803,7 @@ def chests(self, blockid, data): elif orientation_data == 4: data = 3 | (data & 24) elif orientation_data == 5: data = 2 | (data & 24) - if blockid in (95,130) and not data in [2,3,4,5]: return None + if blockid == 130 and not data in [2,3,4,5]: return None # iterate.c will only return the ancil data (without pseudo # ancil data) for locked and ender chests, so only # ancilData = 2,3,4,5 are used for this blockids @@ -3333,12 +3339,14 @@ def huge_mushroom(self, blockid, data): # iron bars and glass pane # TODO glass pane is not a sprite, it has a texture for the side, # at the moment is not used -@material(blockid=[101,102], data=range(16), transparent=True, nospawn=True) +@material(blockid=[101,102, 160], data=range(256), transparent=True, nospawn=True) def panes(self, blockid, data): # no rotation, uses pseudo data if blockid == 101: # iron bars t = self.load_image_texture("assets/minecraft/textures/blocks/iron_bars.png") + elif blockid == 160: + t = self.load_image_texture("assets/minecraft/textures/blocks/glass_%s.png" % color_map[data & 0xf]) else: # glass panes t = self.load_image_texture("assets/minecraft/textures/blocks/glass.png") @@ -3362,6 +3370,9 @@ def panes(self, blockid, data): # First compose things in the back of the image, # then things in the front. + # the lower 4 bits encode color, the upper 4 encode adjencies + data = data >> 4 + if (data & 0b0001) == 1 or data == 0: alpha_over(img,up_left, (6,3),up_left) # top left if (data & 0b1000) == 8 or data == 0: