From a58f23d128365a56487019d8eb83bf0ec1a949da Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Sat, 28 May 2011 01:02:33 +0200 Subject: [PATCH 01/44] Fix bad looking waterfalls. --- src/iterate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/iterate.c b/src/iterate.c index b55e3df..89ae0a2 100644 --- a/src/iterate.c +++ b/src/iterate.c @@ -160,13 +160,13 @@ generate_pseudo_data(RenderState *state, unsigned char ancilData) { return ancilData; } else if (state->block == 9) { /* water */ /* an aditional bit for top is added to the 4 bits of check_adjacent_blocks */ - if ((ancilData == 0) || (ancilData >= 10)) { /* static water, only top, and unkown ancildata values */ + if (ancilData == 0) { /* static water, only top, and unkown ancildata values */ data = 16; return data; /* = 0b10000 */ } else if ((ancilData > 0) && (ancilData < 8)) { /* flowing water */ data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f) | 0x10; return data; - } else if ((ancilData == 8) || (ancilData == 9)) { /* falling water */ + } else if (ancilData >= 8) { /* falling water */ data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f); return data; } From e0a3f0c4ce31251db98f94a96e7cc1483f33739b Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Sat, 28 May 2011 01:08:55 +0200 Subject: [PATCH 02/44] Make seas more like in-game (draw only the top surface). --- src/iterate.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/iterate.c b/src/iterate.c index 89ae0a2..84de2d9 100644 --- a/src/iterate.c +++ b/src/iterate.c @@ -160,8 +160,12 @@ generate_pseudo_data(RenderState *state, unsigned char ancilData) { return ancilData; } else if (state->block == 9) { /* water */ /* an aditional bit for top is added to the 4 bits of check_adjacent_blocks */ - if (ancilData == 0) { /* static water, only top, and unkown ancildata values */ - data = 16; + if (ancilData == 0) { /* static water */ + if ((z != 127) && (getArrayByte3D(state->blocks, x, y, z+1) == 9)) { + data = 0; + } else { + data = 16; + } return data; /* = 0b10000 */ } else if ((ancilData > 0) && (ancilData < 8)) { /* flowing water */ data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f) | 0x10; From 7ff6a4833b20c31f0c8a5a3b7ce3d9e8c99e1d58 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Sun, 29 May 2011 23:31:04 +0200 Subject: [PATCH 03/44] Add another element to the texture tuple with a mask for the lighting. Make needed changes in textures.py. Because some textures have garbage in the alpha channel, this new method has some problems. --- src/iterate.c | 7 +- src/rendermode-cave.c | 4 +- src/rendermode-lighting.c | 6 +- src/rendermode-night.c | 4 +- src/rendermode-normal.c | 2 +- src/rendermode-overlay.c | 2 +- src/rendermode-spawn.c | 4 +- src/rendermodes.h | 2 +- textures.py | 198 ++++++++++++++++---------------------- 9 files changed, 99 insertions(+), 130 deletions(-) diff --git a/src/iterate.c b/src/iterate.c index 84de2d9..e829373 100644 --- a/src/iterate.c +++ b/src/iterate.c @@ -421,14 +421,15 @@ chunk_render(PyObject *self, PyObject *args) { /* if we found a proper texture, render it! */ if (t != NULL && t != Py_None) { - PyObject *src, *mask; + PyObject *src, *mask, *mask_light; src = PyTuple_GetItem(t, 0); mask = PyTuple_GetItem(t, 1); - + mask_light = PyTuple_GetItem(t, 2); + if (mask == Py_None) mask = src; - rendermode->draw(rm_data, &state, src, mask); + rendermode->draw(rm_data, &state, src, mask, mask_light); } } diff --git a/src/rendermode-cave.c b/src/rendermode-cave.c index f8334b2..c5a2e07 100644 --- a/src/rendermode-cave.c +++ b/src/rendermode-cave.c @@ -202,7 +202,7 @@ rendermode_cave_finish(void *data, RenderState *state) { } static void -rendermode_cave_draw(void *data, RenderState *state, PyObject *src, PyObject *mask) { +rendermode_cave_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { RenderModeCave* self; int z, r, g, b; self = (RenderModeCave *)data; @@ -211,7 +211,7 @@ rendermode_cave_draw(void *data, RenderState *state, PyObject *src, PyObject *ma r = 0, g = 0, b = 0; /* draw the normal block */ - rendermode_normal.draw(data, state, src, mask); + rendermode_normal.draw(data, state, src, mask, mask_light); /* get the colors and tint and tint */ /* TODO TODO for a nether mode there isn't tinting! */ diff --git a/src/rendermode-lighting.c b/src/rendermode-lighting.c index 83b38d3..e342c7d 100644 --- a/src/rendermode-lighting.c +++ b/src/rendermode-lighting.c @@ -206,19 +206,19 @@ rendermode_lighting_occluded(void *data, RenderState *state) { } static void -rendermode_lighting_draw(void *data, RenderState *state, PyObject *src, PyObject *mask) { +rendermode_lighting_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { RenderModeLighting* self; int x, y, z; /* first, chain up */ - rendermode_normal.draw(data, state, src, mask); + rendermode_normal.draw(data, state, src, mask, mask_light); self = (RenderModeLighting *)data; x = state->x, y = state->y, z = state->z; if (is_transparent(state->block)) { /* transparent: do shading on whole block */ - do_shading_with_mask(self, state, x, y, z, mask); + do_shading_with_mask(self, state, x, y, z, mask_light); } else { /* opaque: do per-face shading */ do_shading_with_mask(self, state, x, y, z+1, self->facemasks[0]); diff --git a/src/rendermode-night.c b/src/rendermode-night.c index 46ca7c2..81fc38f 100644 --- a/src/rendermode-night.c +++ b/src/rendermode-night.c @@ -54,9 +54,9 @@ rendermode_night_occluded(void *data, RenderState *state) { } static void -rendermode_night_draw(void *data, RenderState *state, PyObject *src, PyObject *mask) { +rendermode_night_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { /* nothing special to do */ - rendermode_lighting.draw(data, state, src, mask); + rendermode_lighting.draw(data, state, src, mask, mask_light); } RenderModeInterface rendermode_night = { diff --git a/src/rendermode-normal.c b/src/rendermode-normal.c index b4118e3..0e06e0e 100644 --- a/src/rendermode-normal.c +++ b/src/rendermode-normal.c @@ -116,7 +116,7 @@ rendermode_normal_occluded(void *data, RenderState *state) { } static void -rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject *mask) { +rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { RenderModeNormal *self = (RenderModeNormal *)data; /* first, check to see if we should use biome-compatible src, mask */ diff --git a/src/rendermode-overlay.c b/src/rendermode-overlay.c index fb4e765..04c87bf 100644 --- a/src/rendermode-overlay.c +++ b/src/rendermode-overlay.c @@ -71,7 +71,7 @@ rendermode_overlay_occluded(void *data, RenderState *state) { } static void -rendermode_overlay_draw(void *data, RenderState *state, PyObject *src, PyObject *mask) { +rendermode_overlay_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { RenderModeOverlay *self = (RenderModeOverlay *)data; unsigned char r, g, b, a; PyObject *top_block_py, *block_py; diff --git a/src/rendermode-spawn.c b/src/rendermode-spawn.c index 498ed17..2781a2a 100644 --- a/src/rendermode-spawn.c +++ b/src/rendermode-spawn.c @@ -102,9 +102,9 @@ rendermode_spawn_occluded(void *data, RenderState *state) { } static void -rendermode_spawn_draw(void *data, RenderState *state, PyObject *src, PyObject *mask) { +rendermode_spawn_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { /* draw normally */ - rendermode_overlay.draw(data, state, src, mask); + rendermode_overlay.draw(data, state, src, mask, mask_light); } RenderModeInterface rendermode_spawn = { diff --git a/src/rendermodes.h b/src/rendermodes.h index fd0b479..d6de559 100644 --- a/src/rendermodes.h +++ b/src/rendermodes.h @@ -56,7 +56,7 @@ struct _RenderModeInterface { /* returns non-zero to skip rendering this block */ int (*occluded)(void *, RenderState *); /* last two arguments are img and mask, from texture lookup */ - void (*draw)(void *, RenderState *, PyObject *, PyObject *); + void (*draw)(void *, RenderState *, PyObject *, PyObject *, PyObject *); }; /* figures out the render mode to use from the given ChunkRenderer */ diff --git a/textures.py b/textures.py index 611353a..ad54a41 100644 --- a/textures.py +++ b/textures.py @@ -453,7 +453,7 @@ def _build_blockimages(): ## of the block or the texture ID img = _build_block(toptexture, sidetexture, blockID) - allimages.append((img.convert("RGB"), img.split()[3])) + allimages.append(generate_texture_tuple(img, blockID)) # Future block types: while len(allimages) < 256: @@ -472,15 +472,32 @@ def load_water(): watertexture = _load_image("water.png") w1 = _build_block(watertexture, None) - blockmap[9] = w1.convert("RGB"), w1 + blockmap[9] = generate_texture_tuple(w1,9) w2 = _build_block(watertexture, watertexture) - blockmap[8] = w2.convert("RGB"), w2 + blockmap[8] = generate_texture_tuple(w2,8) lavatexture = _load_image("lava.png") lavablock = _build_block(lavatexture, lavatexture) - blockmap[10] = lavablock.convert("RGB"), lavablock + blockmap[10] = generate_texture_tuple(lavablock,10) blockmap[11] = blockmap[10] +def generate_opaque_mask(img): + alpha = img.split()[3] + pixel = alpha.load() + + for x in range(img.size[0]): + for y in range(img.size[1]): + if pixel[x,y] != 0: + pixel[x,y] = 255 + + return alpha + +def generate_texture_tuple(img, blockid): + if blockid in (8,9,79,85): + return (img.convert("RGB"), img.split()[3], generate_opaque_mask(img)) + else: + return (img.convert("RGB"), img.split()[3], img.split()[3]) + def generate_special_texture(blockID, data): """Generates a special texture, such as a correctly facing minecraft track""" #print "%s has ancillary data: %X" %(blockID, data) @@ -496,7 +513,7 @@ def generate_special_texture(blockID, data): if not data & 0x10: colored = tintTexture(biome_grass_texture, (115, 175, 71)) composite.alpha_over(img, colored, (0, 0), colored) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 6: # saplings @@ -520,7 +537,7 @@ def generate_special_texture(blockID, data): sidetexture = terrain_images[15] img = _build_block(toptexture, sidetexture, blockID) - return (img.convert("RGB"),img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 9: # spring water, flowing water and waterfall water @@ -548,9 +565,9 @@ def generate_special_texture(blockID, data): side4 = watertexture # bottom right else: side4 = None - img = _build_full_block(top,side1,side2,side3,side4) + img = _build_full_block(top,None,None,side3,side4) - return (img.convert("RGB"),img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 17: # wood: normal, birch and pines @@ -558,21 +575,20 @@ def generate_special_texture(blockID, data): if data == 0: side = terrain_images[20] img = _build_block(top, side, 17) - return (img.convert("RGB"), img.split()[3]) if data == 1: side = terrain_images[116] img = _build_block(top, side, 17) - return (img.convert("RGB"), img.split()[3]) if data == 2: side = terrain_images[117] img = _build_block(top, side, 17) - return (img.convert("RGB"), img.split()[3]) + + return generate_texture_tuple(img, blockID) if blockID == 18: # leaves t = tintTexture(terrain_images[52], (37, 118, 25)) img = _build_block(t, t, 18) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 26: # bed @@ -618,74 +634,45 @@ def generate_special_texture(blockID, data): top = (top, increment) img = _build_full_block(top, None, None, left_face, right_face) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 35: # wool if data == 0: # white top = side = terrain_images[64] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 1: # orange + elif data == 1: # orange top = side = terrain_images[210] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 2: # magenta + elif data == 2: # magenta top = side = terrain_images[194] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 3: # light blue + elif data == 3: # light blue top = side = terrain_images[178] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 4: # yellow + elif data == 4: # yellow top = side = terrain_images[162] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 5: # light green + elif data == 5: # light green top = side = terrain_images[146] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 6: # pink + elif data == 6: # pink top = side = terrain_images[130] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 7: # grey + elif data == 7: # grey top = side = terrain_images[114] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 8: # light grey + elif data == 8: # light grey top = side = terrain_images[225] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 9: # cyan + elif data == 9: # cyan top = side = terrain_images[209] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 10: # purple + elif data == 10: # purple top = side = terrain_images[193] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 11: # blue + elif data == 11: # blue top = side = terrain_images[177] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 12: # brown + elif data == 12: # brown top = side = terrain_images[161] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 13: # dark green + elif data == 13: # dark green top = side = terrain_images[145] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 14: # red + elif data == 14: # red top = side = terrain_images[129] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 15: # black + elif data == 15: # black top = side = terrain_images[113] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) + + img = _build_block(top, side, 35) + return generate_texture_tuple(img, blockID) if blockID in (43,44): # slab and double-slab @@ -693,24 +680,16 @@ def generate_special_texture(blockID, data): if data == 0: # stone slab top = terrain_images[6] side = terrain_images[5] - img = _build_block(top, side, blockID) - return (img.convert("RGB"), img.split()[3]) - if data == 1: # stone slab top = terrain_images[176] side = terrain_images[192] - img = _build_block(top, side, blockID) - return (img.convert("RGB"), img.split()[3]) - if data == 2: # wooden slab top = side = terrain_images[4] - img = _build_block(top, side, blockID) - return (img.convert("RGB"), img.split()[3]) - if data == 3: # cobblestone slab top = side = terrain_images[16] - img = _build_block(top, side, blockID) - return (img.convert("RGB"), img.split()[3]) + + img = _build_block(top, side, blockID) + return generate_texture_tuple(img, blockID) if blockID in (50,75,76): # torch, off redstone torch, on redstone torch @@ -763,7 +742,7 @@ def generate_special_texture(blockID, data): composite.alpha_over(img, small_crop, (6,5)) composite.alpha_over(img, slice, (6,6)) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 51: # fire @@ -779,7 +758,7 @@ def generate_special_texture(blockID, data): composite.alpha_over(img, side1, (0,6), side1) composite.alpha_over(img, side2, (12,6), side2) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID in (53,67): # wooden and cobblestone stairs. @@ -848,7 +827,7 @@ def generate_special_texture(blockID, data): # touch up a (horrible) pixel img.putpixel((18,3),(0,0,0,0)) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 54: # chests # First to bits of the pseudo data store if it's a single chest @@ -890,7 +869,7 @@ def generate_special_texture(blockID, data): else: img = _build_full_block(top, None, None, back, side) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 55: # redstone wire @@ -968,7 +947,7 @@ def generate_special_texture(blockID, data): img = _build_full_block(None,side1,side2,None,None,bottom) - return (img.convert("RGB"),img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 58: # crafting table @@ -977,7 +956,7 @@ def generate_special_texture(blockID, data): side4 = terrain_images[43+16+1] img = _build_full_block(top, None, None, side3, side4, None, 58) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 59: # crops @@ -990,7 +969,7 @@ def generate_special_texture(blockID, data): composite.alpha_over(img, crop1, (0,12), crop1) composite.alpha_over(img, crop2, (6,3), crop2) composite.alpha_over(img, crop3, (6,3), crop3) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID in (61, 62, 23): #furnace and burning furnace @@ -1015,7 +994,7 @@ def generate_special_texture(blockID, data): else: # in any other direction the front can't be seen img = _build_full_block(top, None, None, side, side) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 63: # singposts @@ -1058,7 +1037,7 @@ def generate_special_texture(blockID, data): composite.alpha_over(img, post2,(incrementx, -3),post2) composite.alpha_over(img, post, (0,-2), post) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID in (64,71): #wooden door, or iron door @@ -1110,10 +1089,11 @@ def generate_special_texture(blockID, data): tex = transform_image_side(raw_door.transpose(Image.FLIP_LEFT_RIGHT)) composite.alpha_over(img, tex, (0,6), tex) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 65: # ladder + img = Image.new("RGBA", (24,24), (38,92,255,0)) raw_texture = terrain_images[83] #print "ladder is facing: %d" % data if data == 5: @@ -1121,28 +1101,25 @@ def generate_special_texture(blockID, data): # but since ladders can apparently be placed on transparent blocks, we # have to render this thing anyway. same for data == 2 tex = transform_image_side(raw_texture) - img = Image.new("RGBA", (24,24), (38,92,255,0)) composite.alpha_over(img, tex, (0,6), tex) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if data == 2: tex = transform_image_side(raw_texture).transpose(Image.FLIP_LEFT_RIGHT) - img = Image.new("RGBA", (24,24), (38,92,255,0)) composite.alpha_over(img, tex, (12,6), tex) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if data == 3: tex = transform_image_side(raw_texture).transpose(Image.FLIP_LEFT_RIGHT) - img = Image.new("RGBA", (24,24), (38,92,255,0)) composite.alpha_over(img, tex, (0,0), tex) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if data == 4: tex = transform_image_side(raw_texture) - img = Image.new("RGBA", (24,24), (38,92,255,0)) composite.alpha_over(img, tex, (12,0), tex) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID in (27, 28, 66): # minetrack: - + img = Image.new("RGBA", (24,24), (38,92,255,0)) + if blockID == 27: # powered rail if data & 0x8 == 0: # unpowered raw_straight = terrain_images[163] @@ -1165,58 +1142,48 @@ def generate_special_texture(blockID, data): ## use transform_image to scale and shear if data == 0: track = transform_image(raw_straight, blockID) + composite.alpha_over(img, track, (0,12), track) elif data == 6: track = transform_image(raw_corner, blockID) + composite.alpha_over(img, track, (0,12), track) elif data == 7: track = transform_image(raw_corner.rotate(270), blockID) + composite.alpha_over(img, track, (0,12), track) elif data == 8: # flip track = transform_image(raw_corner.transpose(Image.FLIP_TOP_BOTTOM).rotate(90), blockID) + composite.alpha_over(img, track, (0,12), track) elif data == 9: track = transform_image(raw_corner.transpose(Image.FLIP_TOP_BOTTOM), blockID) + composite.alpha_over(img, track, (0,12), track) elif data == 1: track = transform_image(raw_straight.rotate(90), blockID) + composite.alpha_over(img, track, (0,12), track) #slopes elif data == 2: # slope going up in +x direction track = transform_image_slope(raw_straight,blockID) track = track.transpose(Image.FLIP_LEFT_RIGHT) - img = Image.new("RGBA", (24,24), (38,92,255,0)) composite.alpha_over(img, track, (2,0), track) # the 2 pixels move is needed to fit with the adjacent tracks - return (img.convert("RGB"), img.split()[3]) elif data == 3: # slope going up in -x direction # tracks are sprites, in this case we are seeing the "side" of # the sprite, so draw a line to make it beautiful. - img = Image.new("RGBA", (24,24), (38,92,255,0)) ImageDraw.Draw(img).line([(11,11),(23,17)],fill=(164,164,164)) # grey from track texture (exterior grey). # the track doesn't start from image corners, be carefull drawing the line! - return (img.convert("RGB"), img.split()[3]) - elif data == 4: # slope going up in -y direction track = transform_image_slope(raw_straight,blockID) - img = Image.new("RGBA", (24,24), (38,92,255,0)) composite.alpha_over(img, track, (0,0), track) - return (img.convert("RGB"), img.split()[3]) - + elif data == 5: # slope going up in +y direction # same as "data == 3" - img = Image.new("RGBA", (24,24), (38,92,255,0)) ImageDraw.Draw(img).line([(1,17),(12,11)],fill=(164,164,164)) - return (img.convert("RGB"), img.split()[3]) - - else: # just in case - track = transform_image(raw_straight, blockID) - - img = Image.new("RGBA", (24,24), (38,92,255,0)) - composite.alpha_over(img, track, (0,12), track) - - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 68: # wall sign @@ -1254,7 +1221,7 @@ def generate_special_texture(blockID, data): composite.alpha_over(img, sign2,(incrementx, 2),sign2) composite.alpha_over(img, sign, (0,3), sign) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 85: # fences # create needed images for Big stick fence @@ -1349,7 +1316,8 @@ def generate_special_texture(blockID, data): if (data & 0b0100) == 4: composite.alpha_over(img,fence_small_side, pos_bottom_right,fence_small_side) # bottom right - return (img.convert("RGB"),img.split()[3]) + img.save("fence" + str(data) + ".png") + return generate_texture_tuple(img, blockID) if blockID in (86,91): # pumpkins, jack-o-lantern @@ -1367,7 +1335,7 @@ def generate_special_texture(blockID, data): else: # in any other direction the front can't be seen img = _build_full_block(top, None, None, side, side) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 90: # portal @@ -1383,7 +1351,7 @@ def generate_special_texture(blockID, data): if data in (2,8): composite.alpha_over(img, otherside, (5,4), otherside) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 92: # cake! (without bites, at the moment) @@ -1408,7 +1376,7 @@ def generate_special_texture(blockID, data): composite.alpha_over(img, otherside, (12,12), otherside) composite.alpha_over(img, top, (0,6), top) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID in (93, 94): # redstone repeaters, ON and OFF @@ -1526,7 +1494,7 @@ def generate_special_texture(blockID, data): composite.alpha_over(img, torch, static_torch, torch) composite.alpha_over(img, torch, moving_torch, torch) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) return None @@ -1612,7 +1580,7 @@ special_map = {} special_map[6] = range(16) # saplings: usual, spruce, birch and future ones (rendered as usual saplings) special_map[9] = range(32) # water: spring,flowing, waterfall, and others (unknown) ancildata values, uses pseudo data -special_map[17] = range(4) # wood: normal, birch and pine +special_map[17] = range(3) # wood: normal, birch and pine special_map[26] = range(12) # bed, orientation special_map[23] = range(6) # dispensers, orientation special_map[27] = range(14) # powered rail, orientation/slope and powered/unpowered From fb0a393c140dbf281ceb48e6a3f43b309245de2f Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Sun, 29 May 2011 23:46:22 +0200 Subject: [PATCH 04/44] Delete saving image... --- textures.py | 1 - 1 file changed, 1 deletion(-) diff --git a/textures.py b/textures.py index ad54a41..c585885 100644 --- a/textures.py +++ b/textures.py @@ -1316,7 +1316,6 @@ def generate_special_texture(blockID, data): if (data & 0b0100) == 4: composite.alpha_over(img,fence_small_side, pos_bottom_right,fence_small_side) # bottom right - img.save("fence" + str(data) + ".png") return generate_texture_tuple(img, blockID) From 4cc957c16b5b13da8e89da241d80c4fd734f10db Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Mon, 30 May 2011 00:48:58 +0200 Subject: [PATCH 05/44] Fix problem with fence textures. --- textures.py | 58 ++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/textures.py b/textures.py index c585885..f632472 100644 --- a/textures.py +++ b/textures.py @@ -1225,24 +1225,26 @@ def generate_special_texture(blockID, data): if blockID == 85: # fences # create needed images for Big stick fence - raw_texture = terrain_images[4] - raw_fence_top = Image.new("RGBA", (16,16), (38,92,255,0)) - raw_fence_side = Image.new("RGBA", (16,16), (38,92,255,0)) - fence_top_mask = Image.new("RGBA", (16,16), (38,92,255,0)) - fence_side_mask = Image.new("RGBA", (16,16), (38,92,255,0)) - - # generate the masks images for textures of the fence - ImageDraw.Draw(fence_top_mask).rectangle((6,6,9,9),outline=(0,0,0),fill=(0,0,0)) - ImageDraw.Draw(fence_side_mask).rectangle((6,1,9,15),outline=(0,0,0),fill=(0,0,0)) - # create textures top and side for fence big stick - composite.alpha_over(raw_fence_top,raw_texture,(0,0),fence_top_mask) - composite.alpha_over(raw_fence_side,raw_texture,(0,0),fence_side_mask) + fence_top = terrain_images[4].copy() + fence_side = terrain_images[4].copy() + + # generate the textures of the fence + ImageDraw.Draw(fence_top).rectangle((0,0,5,15),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(fence_top).rectangle((10,0,15,15),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(fence_top).rectangle((0,0,15,5),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(fence_top).rectangle((0,10,15,15),outline=(0,0,0,0),fill=(0,0,0,0)) + fence_top.save("fence_top.png") + + ImageDraw.Draw(fence_side).rectangle((0,0,15,0),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(fence_side).rectangle((0,0,5,15),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(fence_side).rectangle((10,0,15,15),outline=(0,0,0,0),fill=(0,0,0,0)) + fence_side.save("fence_side.png") # Create the sides and the top of the big stick - fence_side = transform_image_side(raw_fence_side,85) + fence_side = transform_image_side(fence_side,85) fence_other_side = fence_side.transpose(Image.FLIP_LEFT_RIGHT) - fence_top = transform_image(raw_fence_top,85) + fence_top = transform_image(fence_top,85) # Darken the sides slightly. These methods also affect the alpha layer, # so save them first (we don't want to "darken" the alpha layer making @@ -1262,18 +1264,18 @@ def generate_special_texture(blockID, data): # Now render the small sticks. # Create needed images - raw_fence_small_side = Image.new("RGBA", (16,16), (38,92,255,0)) - fence_small_side_mask = Image.new("RGBA", (16,16), (38,92,255,0)) + fence_small_side = terrain_images[4].copy() # Generate mask - ImageDraw.Draw(fence_small_side_mask).rectangle((10,1,15,3),outline=(0,0,0),fill=(0,0,0)) - ImageDraw.Draw(fence_small_side_mask).rectangle((10,7,15,9),outline=(0,0,0),fill=(0,0,0)) - - # create the texture for the side of small sticks fence - composite.alpha_over(raw_fence_small_side,raw_texture,(0,0),fence_small_side_mask) - + ImageDraw.Draw(fence_small_side).rectangle((0,0,15,0),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(fence_small_side).rectangle((0,4,15,6),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(fence_small_side).rectangle((0,10,15,16),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(fence_small_side).rectangle((0,0,4,15),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(fence_small_side).rectangle((11,0,15,15),outline=(0,0,0,0),fill=(0,0,0,0)) + fence_small_side.save("fence_small_side.png") + # Create the sides and the top of the small sticks - fence_small_side = transform_image_side(raw_fence_small_side,85) + fence_small_side = transform_image_side(fence_small_side,85) fence_small_other_side = fence_small_side.transpose(Image.FLIP_LEFT_RIGHT) # Darken the sides slightly. These methods also affect the alpha layer, @@ -1286,18 +1288,16 @@ def generate_special_texture(blockID, data): fence_small_side = ImageEnhance.Brightness(fence_small_side).enhance(0.9) fence_small_side.putalpha(sidealpha) - # Create img to compose the fence - img = Image.new("RGBA", (24,24), (38,92,255,0)) # Position of fence small sticks in img. # These postitions are strange because the small sticks of the # fence are at the very left and at the very right of the 16x16 images - pos_top_left = (-2,0) - pos_top_right = (14,0) - pos_bottom_right = (6,4) - pos_bottom_left = (6,4) + pos_top_left = (2,3) + pos_top_right = (10,3) + pos_bottom_right = (10,7) + pos_bottom_left = (2,7) # +x axis points top right direction # +y axis points bottom right direction From 490e1f26103ef1c77c11e84a2114ace5fde3ec97 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Tue, 31 May 2011 15:24:07 +0200 Subject: [PATCH 06/44] Clean and comment. --- textures.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/textures.py b/textures.py index f632472..54c713e 100644 --- a/textures.py +++ b/textures.py @@ -482,21 +482,23 @@ def load_water(): blockmap[11] = blockmap[10] def generate_opaque_mask(img): + """ Takes the alpha channel of the image and generates a mask + (used for lighting the block) that deprecates values of alpha + smallers than 50, and sets every other value to 255. """ + alpha = img.split()[3] pixel = alpha.load() - for x in range(img.size[0]): for y in range(img.size[1]): - if pixel[x,y] != 0: + if pixel[x,y] > 25: pixel[x,y] = 255 return alpha def generate_texture_tuple(img, blockid): - if blockid in (8,9,79,85): - return (img.convert("RGB"), img.split()[3], generate_opaque_mask(img)) - else: - return (img.convert("RGB"), img.split()[3], img.split()[3]) + """ This takes a image and returns the needed tuple for the blockmap + list and specialblockmap dictionary.""" + return (img.convert("RGB"), img.split()[3], generate_opaque_mask(img)) def generate_special_texture(blockID, data): """Generates a special texture, such as a correctly facing minecraft track""" @@ -1234,12 +1236,10 @@ def generate_special_texture(blockID, data): ImageDraw.Draw(fence_top).rectangle((10,0,15,15),outline=(0,0,0,0),fill=(0,0,0,0)) ImageDraw.Draw(fence_top).rectangle((0,0,15,5),outline=(0,0,0,0),fill=(0,0,0,0)) ImageDraw.Draw(fence_top).rectangle((0,10,15,15),outline=(0,0,0,0),fill=(0,0,0,0)) - fence_top.save("fence_top.png") ImageDraw.Draw(fence_side).rectangle((0,0,15,0),outline=(0,0,0,0),fill=(0,0,0,0)) ImageDraw.Draw(fence_side).rectangle((0,0,5,15),outline=(0,0,0,0),fill=(0,0,0,0)) ImageDraw.Draw(fence_side).rectangle((10,0,15,15),outline=(0,0,0,0),fill=(0,0,0,0)) - fence_side.save("fence_side.png") # Create the sides and the top of the big stick fence_side = transform_image_side(fence_side,85) @@ -1272,7 +1272,6 @@ def generate_special_texture(blockID, data): ImageDraw.Draw(fence_small_side).rectangle((0,10,15,16),outline=(0,0,0,0),fill=(0,0,0,0)) ImageDraw.Draw(fence_small_side).rectangle((0,0,4,15),outline=(0,0,0,0),fill=(0,0,0,0)) ImageDraw.Draw(fence_small_side).rectangle((11,0,15,15),outline=(0,0,0,0),fill=(0,0,0,0)) - fence_small_side.save("fence_small_side.png") # Create the sides and the top of the small sticks fence_small_side = transform_image_side(fence_small_side,85) From 87cd001b9130b8a79a59635ab9842c1fd6ce39c3 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Tue, 31 May 2011 16:01:54 +0200 Subject: [PATCH 07/44] Add tall grass and dead shrubs. --- chunk.py | 8 ++++---- textures.py | 32 +++++++++++++++++++++++--------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/chunk.py b/chunk.py index 048b650..7eb61ab 100644 --- a/chunk.py +++ b/chunk.py @@ -114,10 +114,10 @@ def get_tileentity_data(level): return data # This set holds blocks ids that can be seen through, for occlusion calculations -transparent_blocks = set([ 0, 6, 8, 9, 18, 20, 26, 27, 28, 30, 37, 38, 39, 40, - 44, 50, 51, 52, 53, 55, 59, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 74, 75, 76, 77, 78, 79, 81, 83, 85, 90, 92, - 93, 94]) +transparent_blocks = set([ 0, 6, 8, 9, 18, 20, 26, 27, 28, 30, 31, 32, 37, 38, + 39, 40, 44, 50, 51, 52, 53, 55, 59, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 81, 83, 85, + 90, 92, 93, 94]) # This set holds block ids that are solid blocks solid_blocks = set([1, 2, 3, 4, 5, 7, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, diff --git a/textures.py b/textures.py index 54c713e..c19fc09 100644 --- a/textures.py +++ b/textures.py @@ -257,7 +257,7 @@ def _build_block(top, side, blockID=None): otherside.putalpha(othersidealpha) ## special case for non-block things - if blockID in (37,38,6,39,40,83,30): ## flowers, sapling, mushrooms, reeds, web + if blockID in (31,32,37,38,6,39,40,83,30): ## tall grass, dead shrubs, flowers, sapling, mushrooms, reeds, web # # instead of pasting these blocks at the cube edges, place them in the middle: # and omit the top @@ -410,7 +410,7 @@ def _build_blockimages(): # 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 34, -1, 52, 48, 49,160,144, -1,176, 74, -1, -1, -1, -1, 11, -1, # 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 - -1, -1, -1, -1, -1, 13, 12, 29, 28, 23, 22, -1, -1, 7, 9, 4, + 55, -1, -1, -1, -1, 13, 12, 29, 28, 23, 22, -1, -1, 7, 9, 4, # 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 36, 37, -1, -1, 65, -1, -1, -1, 50, 24, -1, -1, 86, -1, -1, -1, # 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 @@ -427,7 +427,7 @@ def _build_blockimages(): # 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 34, -1, 52, 48, 49,160,144, -1,192, 74, -1, -1,- 1, -1, 11, -1, # 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 - -1, -1, -1, -1, -1, 13, 12, 29, 28, 23, 22, -1, -1, 7, 8, 35, + 55, -1, -1, -1, -1, 13, 12, 29, 28, 23, 22, -1, -1, 7, 8, 35, # 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 36, 37, -1, -1, 65, -1, -1,101, 50, 24, -1, -1, 86, -1, -1, -1, # 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 @@ -496,8 +496,8 @@ def generate_opaque_mask(img): return alpha def generate_texture_tuple(img, blockid): - """ This takes a image and returns the needed tuple for the blockmap - list and specialblockmap dictionary.""" + """ This takes an image and returns the needed tuple for the + blockmap list and specialblockmap dictionary.""" return (img.convert("RGB"), img.split()[3], generate_opaque_mask(img)) def generate_special_texture(blockID, data): @@ -638,7 +638,20 @@ def generate_special_texture(blockID, data): return generate_texture_tuple(img, blockID) - + if blockID == 31: # tall grass + if data == 0: # dead shrub + texture = terrain_images[55] + elif data == 1: # tall grass + texture = terrain_images[39].copy() + texture = tintTexture(texture, (115, 175, 71)) + elif data == 2: # fern + texture = terrain_images[56].copy() + texture = tintTexture(texture, (115, 175, 71)) + + img = _build_block(texture, texture, blockID) + return generate_texture_tuple(img,31) + + if blockID == 35: # wool if data == 0: # white top = side = terrain_images[64] @@ -1567,9 +1580,9 @@ def getBiomeData(worlddir, chunkX, chunkY): # (when adding new blocks here and in generate_special_textures, # please, if possible, keep the ascending order of blockid value) -special_blocks = set([ 2, 6, 9, 17, 18, 26, 23, 27, 28, 35, 43, 44, 50, - 51, 53, 54, 55, 58, 59, 61, 62, 63, 64, 65, 66, 67, - 68, 71, 75, 76, 85, 86, 90, 91, 92, 93, 94]) +special_blocks = set([ 2, 6, 9, 17, 18, 26, 23, 27, 28, 31, 35, 43, 44, + 50, 51, 53, 54, 55, 58, 59, 61, 62, 63, 64, 65, 66, + 67, 68, 71, 75, 76, 85, 86, 90, 91, 92, 93, 94]) # this is a map of special blockIDs to a list of all # possible values for ancillary data that it might have. @@ -1621,6 +1634,7 @@ special_map[2] = range(11) + [0x10,] # grass, grass has not ancildata but is # small fix shows the map as expected, # and is harmless for normal maps special_map[18] = range(16) # leaves, birch, normal or pine leaves (not implemented) +special_map[31] = range(3) # tall grass, dead shrub, fern and tall grass itself # placeholders that are generated in generate() terrain_images = None From fcd29234fffd339fb38afc2db5c6ab95b4de4322 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Tue, 31 May 2011 17:03:18 +0200 Subject: [PATCH 08/44] Add trapdoors. --- chunk.py | 2 +- textures.py | 21 ++++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/chunk.py b/chunk.py index 7eb61ab..f8aa1f6 100644 --- a/chunk.py +++ b/chunk.py @@ -117,7 +117,7 @@ def get_tileentity_data(level): transparent_blocks = set([ 0, 6, 8, 9, 18, 20, 26, 27, 28, 30, 31, 32, 37, 38, 39, 40, 44, 50, 51, 52, 53, 55, 59, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 81, 83, 85, - 90, 92, 93, 94]) + 90, 92, 93, 94, 96]) # This set holds block ids that are solid blocks solid_blocks = set([1, 2, 3, 4, 5, 7, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, diff --git a/textures.py b/textures.py index c19fc09..17bce0e 100644 --- a/textures.py +++ b/textures.py @@ -1506,6 +1506,24 @@ def generate_special_texture(blockID, data): composite.alpha_over(img, torch, moving_torch, torch) return generate_texture_tuple(img, blockID) + + + if blockID == 96: # trapdoor + texture = terrain_images[84] + if data & 0x4 == 0x4: # opened trapdoor + if data & 0x3 == 0: # west + img = _build_full_block(None, None, None, None, texture) + if data & 0x3 == 1: # east + img = _build_full_block(None, texture, None, None, None) + if data & 0x3 == 2: # south + img = _build_full_block(None, None, texture, None, None) + if data & 0x3 == 3: # north + img = _build_full_block(None, None, None, texture, None) + + elif data & 0x4 == 0: # closed trapdoor + img = _build_full_block((texture, 9), None, None, texture, texture) + + return generate_texture_tuple(img, blockID) return None @@ -1582,7 +1600,7 @@ def getBiomeData(worlddir, chunkX, chunkY): special_blocks = set([ 2, 6, 9, 17, 18, 26, 23, 27, 28, 31, 35, 43, 44, 50, 51, 53, 54, 55, 58, 59, 61, 62, 63, 64, 65, 66, - 67, 68, 71, 75, 76, 85, 86, 90, 91, 92, 93, 94]) + 67, 68, 71, 75, 76, 85, 86, 90, 91, 92, 93, 94, 96]) # this is a map of special blockIDs to a list of all # possible values for ancillary data that it might have. @@ -1624,6 +1642,7 @@ special_map[91] = range(5) # jack-o-lantern, orientation special_map[92] = range(6) # cake! special_map[93] = range(16) # OFF redstone repeater, orientation and delay (delay not implemented) special_map[94] = range(16) # ON redstone repeater, orientation and delay (delay not implemented) +special_map[96] = range(8) # trapdoor, open, closed, orientation # grass and leaves are graysacle in terrain.png # we treat them as special so we can manually tint them From d95ae73286e12b5b3ee7a034ccf5fcc20f933805 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Tue, 31 May 2011 18:21:47 +0200 Subject: [PATCH 09/44] Tall grass is now biome tinted. --- src/iterate.c | 5 ++--- src/overviewer.h | 1 + src/rendermode-normal.c | 26 ++++++++++++++++++++++++-- src/rendermodes.h | 2 +- textures.py | 6 +++++- 5 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/iterate.c b/src/iterate.c index e829373..d86ecbf 100644 --- a/src/iterate.c +++ b/src/iterate.c @@ -293,7 +293,6 @@ PyObject* chunk_render(PyObject *self, PyObject *args) { RenderState state; - PyObject *blockdata_expanded; int xoff, yoff; PyObject *imgsize, *imgsize0_py, *imgsize1_py; @@ -311,7 +310,7 @@ chunk_render(PyObject *self, PyObject *args) { PyObject *t = NULL; - if (!PyArg_ParseTuple(args, "OOiiO", &state.self, &state.img, &xoff, &yoff, &blockdata_expanded)) + if (!PyArg_ParseTuple(args, "OOiiO", &state.self, &state.img, &xoff, &yoff, &state.blockdata_expanded)) return NULL; /* fill in important modules */ @@ -402,7 +401,7 @@ chunk_render(PyObject *self, PyObject *args) { } else { PyObject *tmp; - unsigned char ancilData = getArrayByte3D(blockdata_expanded, state.x, state.y, state.z); + unsigned char ancilData = getArrayByte3D(state.blockdata_expanded, state.x, state.y, state.z); if ((state.block == 85) || (state.block == 9) || (state.block == 55) || (state.block == 54) || (state.block == 2) || (state.block == 90)) { ancilData = generate_pseudo_data(&state, ancilData); } diff --git a/src/overviewer.h b/src/overviewer.h index 5ee89dc..184cd4e 100644 --- a/src/overviewer.h +++ b/src/overviewer.h @@ -70,6 +70,7 @@ typedef struct { /* the block position and type, and the block array */ int x, y, z; unsigned char block; + PyObject *blockdata_expanded; PyObject *blocks; PyObject *up_left_blocks; PyObject *up_right_blocks; diff --git a/src/rendermode-normal.c b/src/rendermode-normal.c index 0e06e0e..e4247fa 100644 --- a/src/rendermode-normal.c +++ b/src/rendermode-normal.c @@ -56,6 +56,7 @@ rendermode_normal_start(void *data, RenderState *state) { self->leaf_texture = NULL; self->grass_texture = NULL; + self->tall_grass_texture = NULL; self->facemask_top = NULL; } else { @@ -64,6 +65,7 @@ rendermode_normal_start(void *data, RenderState *state) { self->leaf_texture = PyObject_GetAttrString(state->textures, "biome_leaf_texture"); self->grass_texture = PyObject_GetAttrString(state->textures, "biome_grass_texture"); + self->tall_grass_texture = PyObject_GetAttrString(state->textures, "biome_tall_grass_texture"); facemasks_py = PyObject_GetAttrString(state->chunk, "facemasks"); /* borrowed reference, needs to be incref'd if we keep it */ @@ -78,6 +80,7 @@ rendermode_normal_start(void *data, RenderState *state) { self->leaf_texture = NULL; self->grass_texture = NULL; + self->tall_grass_texture = NULL; self->facemask_top = NULL; } @@ -98,6 +101,7 @@ rendermode_normal_finish(void *data, RenderState *state) { Py_XDECREF(self->grasscolor); Py_XDECREF(self->leaf_texture); Py_XDECREF(self->grass_texture); + Py_XDECREF(self->tall_grass_texture); Py_XDECREF(self->facemask_top); } @@ -120,8 +124,17 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject * RenderModeNormal *self = (RenderModeNormal *)data; /* first, check to see if we should use biome-compatible src, mask */ - if (self->biome_data && state->block == 18) { - src = mask = self->leaf_texture; + if (self->biome_data) { + if (state->block == 18) { + src = mask = self->leaf_texture; + } else if (state->block == 31) { + unsigned char data = getArrayByte3D(state->blockdata_expanded, state->x, state->y, state->z); + if (data == 1) { + src = mask = self->tall_grass_texture; + } else if (data == 2) { + src = mask = self->tall_fern_texture; + } + } } /* draw the block! */ @@ -150,6 +163,15 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject * color = PySequence_GetItem(self->foliagecolor, index); facemask = mask; break; + case 31: + /* tall grass */ + if ( getArrayByte3D(state->blockdata_expanded, state->x, state->y, state->z) != 0 ) + { /* do not tint dead shrubs */ + color = PySequence_GetItem(self->grasscolor, index); + facemask = mask; + break; + } + break; default: break; }; diff --git a/src/rendermodes.h b/src/rendermodes.h index d6de559..80126a4 100644 --- a/src/rendermodes.h +++ b/src/rendermodes.h @@ -79,7 +79,7 @@ typedef struct { /* grasscolor and foliagecolor lookup tables */ PyObject *grasscolor, *foliagecolor; /* biome-compatible grass/leaf textures */ - PyObject *grass_texture, *leaf_texture; + PyObject *grass_texture, *leaf_texture, *tall_grass_texture, *tall_fern_texture; /* top facemask for grass biome tinting */ PyObject *facemask_top; } RenderModeNormal; diff --git a/textures.py b/textures.py index 17bce0e..02c26c3 100644 --- a/textures.py +++ b/textures.py @@ -1659,6 +1659,8 @@ special_map[31] = range(3) # tall grass, dead shrub, fern and tall grass itself terrain_images = None blockmap = None biome_grass_texture = None +biome_tall_grass_texture = None +biome_tall_fern_texture = None biome_leaf_texture = None specialblockmap = None @@ -1676,9 +1678,11 @@ def generate(path=None): load_water() # generate biome (still grayscale) leaf, grass textures - global biome_grass_texture, biome_leaf_texture + global biome_grass_texture, biome_leaf_texture, biome_tall_grass_texture biome_grass_texture = _build_block(terrain_images[0], terrain_images[38], 2) biome_leaf_texture = _build_block(terrain_images[52], terrain_images[52], 18) + biome_tall_grass_texture = _build_block(terrain_images[39], terrain_images[39], 31) + biome_tall_fern_texture = _build_block(terrain_images[56], terrain_images[56], 31) # generate the special blocks global specialblockmap, special_blocks From 9d4b48b5ae8a388bc833cfc249d5c09841dbddd6 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Wed, 1 Jun 2011 00:19:23 +0200 Subject: [PATCH 10/44] Add the agrif's fix for stairs. With 1.6 this is no more a quick fix (I think they are now as slabs are). --- src/rendermode-lighting.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rendermode-lighting.c b/src/rendermode-lighting.c index e342c7d..c38fd1e 100644 --- a/src/rendermode-lighting.c +++ b/src/rendermode-lighting.c @@ -91,7 +91,7 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state, /* only do special half-step handling if no authoratative pointer was passed in, which is a sign that we're recursing */ - if (block == 44 && authoratative == NULL) { + if ((block == 44 || block == 53 || block == 67) && authoratative == NULL) { float average_gather = 0.0f; unsigned int average_count = 0; int auth; From 8565919c898a6981e603a60936fceae69eaa9058 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Tue, 31 May 2011 20:05:45 -0400 Subject: [PATCH 11/44] fixed uninitialized texture pointer, and bumped extension version --- src/overviewer.h | 2 +- src/rendermode-normal.c | 3 +++ textures.py | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/overviewer.h b/src/overviewer.h index 184cd4e..49e70fa 100644 --- a/src/overviewer.h +++ b/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 6 +#define OVERVIEWER_EXTENSION_VERSION 7 /* Python PIL, and numpy headers */ #include diff --git a/src/rendermode-normal.c b/src/rendermode-normal.c index e4247fa..d975ed9 100644 --- a/src/rendermode-normal.c +++ b/src/rendermode-normal.c @@ -66,6 +66,7 @@ rendermode_normal_start(void *data, RenderState *state) { self->leaf_texture = PyObject_GetAttrString(state->textures, "biome_leaf_texture"); self->grass_texture = PyObject_GetAttrString(state->textures, "biome_grass_texture"); self->tall_grass_texture = PyObject_GetAttrString(state->textures, "biome_tall_grass_texture"); + self->tall_fern_texture = PyObject_GetAttrString(state->textures, "biome_tall_fern_texture"); facemasks_py = PyObject_GetAttrString(state->chunk, "facemasks"); /* borrowed reference, needs to be incref'd if we keep it */ @@ -81,6 +82,7 @@ rendermode_normal_start(void *data, RenderState *state) { self->leaf_texture = NULL; self->grass_texture = NULL; self->tall_grass_texture = NULL; + self->tall_fern_texture = NULL; self->facemask_top = NULL; } @@ -102,6 +104,7 @@ rendermode_normal_finish(void *data, RenderState *state) { Py_XDECREF(self->leaf_texture); Py_XDECREF(self->grass_texture); Py_XDECREF(self->tall_grass_texture); + Py_XDECREF(self->tall_fern_texture); Py_XDECREF(self->facemask_top); } diff --git a/textures.py b/textures.py index 02c26c3..101b933 100644 --- a/textures.py +++ b/textures.py @@ -1678,7 +1678,7 @@ def generate(path=None): load_water() # generate biome (still grayscale) leaf, grass textures - global biome_grass_texture, biome_leaf_texture, biome_tall_grass_texture + global biome_grass_texture, biome_leaf_texture, biome_tall_grass_texture, biome_tall_fern_texture biome_grass_texture = _build_block(terrain_images[0], terrain_images[38], 2) biome_leaf_texture = _build_block(terrain_images[52], terrain_images[52], 18) biome_tall_grass_texture = _build_block(terrain_images[39], terrain_images[39], 31) From 733e816dbc0fd6454c2f1bc13c70abd790933e4b Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Tue, 31 May 2011 19:48:07 -0400 Subject: [PATCH 12/44] fixed biome loading order --- world.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/world.py b/world.py index 348aff3..f02098c 100644 --- a/world.py +++ b/world.py @@ -100,9 +100,6 @@ class World(object): logging.error("Sorry, This version of Minecraft-Overviewer only works with the new McRegion chunk format") sys.exit(1) - if self.useBiomeData: - textures.prepareBiomeData(worlddir) - # stores Points Of Interest to be mapped with markers # a list of dictionaries, see below for an example self.POI = [] From e65b77ac579f9e96ccce682725265b25da0a666d Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Thu, 2 Jun 2011 00:57:43 +0200 Subject: [PATCH 13/44] Fix optimizeimg=2 transparency issue not messing with the color type in optipng. --- optimizeimages.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/optimizeimages.py b/optimizeimages.py index e1699b0..01799e4 100644 --- a/optimizeimages.py +++ b/optimizeimages.py @@ -45,7 +45,8 @@ def optimize_image(imgpath, imgformat, optimizeimg): os.rename(imgpath+".tmp", imgpath) if optimizeimg >= 2: - subprocess.Popen([optipng, imgpath], stderr=subprocess.STDOUT, + # the "-nc" it's needed to no broke the transparency of tiles + subprocess.Popen([optipng, "-nc", imgpath], stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0] subprocess.Popen([advdef, "-z4",imgpath], stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0] From 5249aca936785e2ecbf37b20311dacbaa26d58bd Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Wed, 1 Jun 2011 23:15:45 -0400 Subject: [PATCH 14/44] Tweak fromLatLngToWorld to fix issue #381 --- web_assets/overviewer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web_assets/overviewer.js b/web_assets/overviewer.js index d8673c1..94bb8cc 100644 --- a/web_assets/overviewer.js +++ b/web_assets/overviewer.js @@ -560,8 +560,8 @@ var overviewer = { // Adjust for the fact that we we can't figure out what Y is given // only latitude and longitude, so assume Y=64. - point.x += 64 + 1; - point.z -= 64 + 2; + point.x += 64; + point.z -= 64; return point; }, From f47e7fe4063846da2aa68e62b26027be169b11ed Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Thu, 2 Jun 2011 13:06:12 -0400 Subject: [PATCH 15/44] Fixed rerenderBlocks contrib script --- contrib/rerenderBlocks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/rerenderBlocks.py b/contrib/rerenderBlocks.py index d0fa0df..eb93871 100644 --- a/contrib/rerenderBlocks.py +++ b/contrib/rerenderBlocks.py @@ -20,7 +20,7 @@ import sys sys.path.insert(0,".") import nbt -from chunk import get_blockarray_fromfile +from chunk import get_blockarray_fromfile, get_blockarray import os import re From 91c3e74ef213203a452cf7a3fac84bb914a84087 Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Fri, 3 Jun 2011 21:56:04 -0400 Subject: [PATCH 16/44] Updated sample settings file * Causes Overviewer to exit if someone uses the sample settings file directly * Fixed up the regionlist example so it doesn't throw errors --- sample.settings.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sample.settings.py b/sample.settings.py index 2872506..863b266 100644 --- a/sample.settings.py +++ b/sample.settings.py @@ -50,10 +50,13 @@ zoom = 9 ## Example: Dynamically create regionlist of only regions older than 2 days import os, time +# the following two lines are needed to the lambda to work +globals()['os'] = os +globals()['time'] = time regionDir = os.path.join(args[0], "region") regionFiles = filter(lambda x: x.endswith(".mcr"), os.listdir(regionDir)) def olderThanTwoDays(f): - return time.time() - os.stat(f).st_mtime > (60*60*24*2) + return time.time() - os.stat(os.path.join(args[0], 'region',f)).st_mtime > (60*60*24*2) oldRegionFiles = filter(olderThanTwoDays, regionFiles) with open("regionlist.txt", "w") as f: f.write("\n".join(oldRegionFiles)) @@ -148,3 +151,9 @@ if "web_assets_hook" in locals(): skipjs = True + + +### As a reminder, don't use this file verbatim, it should only be used as +### a guide. +import sys +sys.exit("This sample-settings file shouldn't be used directly!") From 36df63caa4a6edc7978b7e4df8f9778e681bae32 Mon Sep 17 00:00:00 2001 From: TJ09 Date: Sat, 4 Jun 2011 13:28:24 -0400 Subject: [PATCH 17/44] Change ids to classes. Fixes #387 --- web_assets/overviewer.css | 8 ++++---- web_assets/overviewer.js | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/web_assets/overviewer.css b/web_assets/overviewer.css index 19b9b34..14585e6 100644 --- a/web_assets/overviewer.css +++ b/web_assets/overviewer.css @@ -29,13 +29,13 @@ body { font-family: monospace; } -#customControl { +.customControl { padding: 5px; height: 15px; font-family: Arial, sans-serif; } -#customControl > div#top { +.customControl > div.top { background-color: #fff; border: 2px solid #000; text-align: center; @@ -45,14 +45,14 @@ body { cursor: pointer; } -#customControl > div#dropDown { +.customControl > div.dropDown { border: 1px solid #000; font-size: 12px; background-color: #fff; display: none; } -#customControl > div#button { +.customControl > div.button { border: 1px solid #000; font-size: 12px; background-color: #fff; diff --git a/web_assets/overviewer.js b/web_assets/overviewer.js index 94bb8cc..467affb 100644 --- a/web_assets/overviewer.js +++ b/web_assets/overviewer.js @@ -585,7 +585,7 @@ var overviewer = { // Spawn button var homeControlDiv = document.createElement('DIV'); var homeControl = new overviewer.classes.HomeControl(homeControlDiv); - homeControlDiv.id = 'customControl'; + $(homeControlDiv).addClass('customControl'); homeControlDiv.index = 1; if (overviewerConfig.map.controls.spawn) { overviewer.map.controls[google.maps.ControlPosition.TOP_RIGHT].push(homeControlDiv); @@ -680,18 +680,18 @@ var overviewer = { 'createDropDown': function(title, items) { var control = document.createElement('DIV'); // let's let a style sheet do most of the styling here - control.id = 'customControl'; + $(control).addClass('customControl'); var controlText = document.createElement('DIV'); controlText.innerHTML = title; var controlBorder = document.createElement('DIV'); - controlBorder.id='top'; + $(controlBorder).addClass('top'); control.appendChild(controlBorder); controlBorder.appendChild(controlText); var dropdownDiv = document.createElement('DIV'); - dropdownDiv.id='dropDown'; + $(dropdownDiv).addClass('dropDown'); control.appendChild(dropdownDiv); dropdownDiv.innerHTML=''; @@ -868,14 +868,14 @@ var overviewer = { controlDiv.style.padding = '5px'; // Set CSS for the control border var control = document.createElement('DIV'); - control.id='top'; + $(control).addClass('top'); control.title = 'Click to center the map on the Spawn'; controlDiv.appendChild(control); // Set CSS for the control interior var controlText = document.createElement('DIV'); controlText.innerHTML = 'Spawn'; - controlText.id='button'; + $(controlText).addClass('button'); control.appendChild(controlText); // Setup the click event listeners: simply set the map to map center From ac91268c668f0ce1d0cb8b27136502fe03c9b482 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Sat, 4 Jun 2011 20:05:09 -0400 Subject: [PATCH 18/44] added --forcerender option --- overviewer.py | 3 ++- quadtree.py | 14 +++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/overviewer.py b/overviewer.py index 5f3400c..e217949 100755 --- a/overviewer.py +++ b/overviewer.py @@ -94,6 +94,7 @@ def main(): parser.add_option("-z", "--zoom", dest="zoom", help="Sets the zoom level manually instead of calculating it. This can be useful if you have outlier chunks that make your world too big. This value will make the highest zoom level contain (2**ZOOM)^2 tiles", action="store", type="int", configFileOnly=True) parser.add_option("-d", "--delete", dest="delete", help="Clear all caches. Next time you render your world, it will have to start completely over again. This is probably not a good idea for large worlds. Use this if you change texture packs and want to re-render everything.", action="store_true", commandLineOnly=True) parser.add_option("--regionlist", dest="regionlist", help="A file containing, on each line, a path to a regionlist to update. Instead of scanning the world directory for regions, it will just use this list. Normal caching rules still apply.") + parser.add_option("--forcerender", dest="forcerender", help="Force re-rendering the entire map (or the given regionlist). Useful for re-rendering without deleting the entire map with --delete.", action="store_true") parser.add_option("--rendermodes", dest="rendermode", help="Specifies the render types, separated by commas. Use --list-rendermodes to list them all.", type="choice", choices=avail_rendermodes, required=True, default=avail_rendermodes[0], listify=True) parser.add_option("--list-rendermodes", dest="list_rendermodes", action="store_true", help="List available render modes and exit.", commandLineOnly=True) parser.add_option("--imgformat", dest="imgformat", help="The image output format to use. Currently supported: png(default), jpg.", configFileOnly=True ) @@ -231,7 +232,7 @@ def main(): # create the quadtrees # TODO chunklist q = [] - qtree_args = {'depth' : options.zoom, 'imgformat' : imgformat, 'imgquality' : options.imgquality, 'optimizeimg' : optimizeimg, 'bgcolor' : bgcolor} + qtree_args = {'depth' : options.zoom, 'imgformat' : imgformat, 'imgquality' : options.imgquality, 'optimizeimg' : optimizeimg, 'bgcolor' : bgcolor, 'forcerender' : options.forcerender} for rendermode in options.rendermode: if rendermode == 'normal': qtree = quadtree.QuadtreeGen(w, destdir, rendermode=rendermode, tiledir='tiles', **qtree_args) diff --git a/quadtree.py b/quadtree.py index 5d240db..f1c4b1d 100644 --- a/quadtree.py +++ b/quadtree.py @@ -49,7 +49,7 @@ def iterate_base4(d): return itertools.product(xrange(4), repeat=d) class QuadtreeGen(object): - def __init__(self, worldobj, destdir, bgcolor, depth=None, tiledir=None, imgformat=None, imgquality=95, optimizeimg=None, rendermode="normal"): + def __init__(self, worldobj, destdir, bgcolor, depth=None, tiledir=None, forcerender=False, imgformat=None, imgquality=95, optimizeimg=None, rendermode="normal"): """Generates a quadtree from the world given into the given dest directory @@ -60,6 +60,7 @@ class QuadtreeGen(object): """ assert(imgformat) + self.forcerender = forcerender self.imgformat = imgformat self.imgquality = imgquality self.optimizeimg = optimizeimg @@ -425,10 +426,17 @@ class QuadtreeGen(object): needs_rerender = False get_region_mtime = world.get_region_mtime for col, row, chunkx, chunky, regionfile in chunks: - # check region file mtime first. - region,regionMtime = get_region_mtime(regionfile) + # don't even check if it's not in the regionlist if self.world.regionlist and region._filename not in self.world.regionlist: continue + + # bail early if forcerender is set + if self.forcerender: + needs_rerender = True + break + + # check region file mtime first. + region,regionMtime = get_region_mtime(regionfile) if regionMtime <= tile_mtime: continue From 89eb1939b171b0b27344b17f3c85d02871c83572 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Mon, 6 Jun 2011 00:08:31 +0200 Subject: [PATCH 19/44] Change the optimizing programs. Add new value for the option optimizeimg. --- optimizeimages.py | 7 +++---- overviewer.py | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/optimizeimages.py b/optimizeimages.py index 01799e4..4422feb 100644 --- a/optimizeimages.py +++ b/optimizeimages.py @@ -28,7 +28,7 @@ def check_programs(level): result = filter(lambda x: os.path.exists(os.path.join(x, prog)), path) return len(result) != 0 - for prog,l in [(pngcrush,1), (optipng,2), (advdef,2)]: + for prog,l in [(pngcrush,1), (advdef,2)]: if l <= level: if (not exists_in_path(prog)) and (not exists_in_path(prog + ".exe")): raise Exception("Optimization prog %s for level %d not found!" % (prog, l)) @@ -46,8 +46,7 @@ def optimize_image(imgpath, imgformat, optimizeimg): if optimizeimg >= 2: # the "-nc" it's needed to no broke the transparency of tiles - subprocess.Popen([optipng, "-nc", imgpath], stderr=subprocess.STDOUT, - stdout=subprocess.PIPE).communicate()[0] - subprocess.Popen([advdef, "-z4",imgpath], stderr=subprocess.STDOUT, + recompress_option = "-z2" if optimizeimg == 2 else "-z4" + subprocess.Popen([advdef, recompress_option,imgpath], stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0] diff --git a/overviewer.py b/overviewer.py index e217949..22a103c 100755 --- a/overviewer.py +++ b/overviewer.py @@ -100,7 +100,7 @@ def main(): parser.add_option("--imgformat", dest="imgformat", help="The image output format to use. Currently supported: png(default), jpg.", configFileOnly=True ) parser.add_option("--imgquality", dest="imgquality", default=95, help="Specify the quality of image output when using imgformat=\"jpg\".", type="int", configFileOnly=True) parser.add_option("--bg_color", dest="bg_color", help="Configures the background color for the GoogleMap output. Specify in #RRGGBB format", configFileOnly=True, type="string", default="#1A1A1A") - parser.add_option("--optimize-img", dest="optimizeimg", help="If using png, perform image file size optimizations on the output. Specify 1 for pngcrush, 2 for pngcrush+optipng+advdef. This may double (or more) render times, but will produce up to 30% smaller images. NOTE: requires corresponding programs in $PATH or %PATH%", configFileOnly=True) + parser.add_option("--optimize-img", dest="optimizeimg", help="If using png, perform image file size optimizations on the output. Specify 1 for pngcrush, 2 for pngcrush+advdef and 3 for pngcrush-advdef with more agressive settings. This may double (or more) render times, but will produce up to 30% smaller images. NOTE: requires corresponding programs in $PATH or %PATH%", configFileOnly=True) parser.add_option("--web-assets-hook", dest="web_assets_hook", help="If provided, run this function after the web assets have been copied, but before actual tile rendering begins. It should accept a QuadtreeGen object as its only argument.", action="store", metavar="SCRIPT", type="function", configFileOnly=True) parser.add_option("--web-assets-path", dest="web_assets_path", help="Specifies a non-standard web_assets directory to use. Files here will overwrite the default web assets.", metavar="PATH", type="string", configFileOnly=True) parser.add_option("--textures-path", dest="textures_path", help="Specifies a non-standard textures path, from which terrain.png and other textures are loaded.", metavar="PATH", type="string", configFileOnly=True) From ab1d444a460c0620cbd3b246dd5245c7b5880201 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Wed, 8 Jun 2011 00:28:58 +0200 Subject: [PATCH 20/44] Update sample.settings.py with the new optimizeimg options. --- sample.settings.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sample.settings.py b/sample.settings.py index 863b266..8c85a3e 100644 --- a/sample.settings.py +++ b/sample.settings.py @@ -92,9 +92,11 @@ imgformat = "jpg" ################################################################################ ### optimizeimg ## If using png, perform image file size optimizations on the output. Specify 1 -## for pngcrush, 2 for pngcrush+optipng+advdef. This may double (or more) -## render times, but will produce up to 30% smaller images. NOTE: requires -## corresponding programs in $PATH or %PATH% +## for pngcrush, 2 for pngcrush+advdef, 3 for pngcrush+advdef with more agressive +## options. Option 1 gives around 19% of reduction, option 2 gives around 21% +## (it doubles the optimizing time) and option 3 gives around 23% (it doubles, +## again, the optimizing time). Using this option may double (or more) +## render times. NOTE: requires corresponding programs in $PATH or %PATH% ## Default: not set ## Type: integer ## Example: From bc51e6745ffc97d19e4c53fd6179ca1482c95372 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Wed, 8 Jun 2011 16:20:50 +0200 Subject: [PATCH 21/44] Improve the lighting of the stairs and double-blocks using the skylevel value of the upper block when posible. --- src/rendermode-lighting.c | 45 +++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/src/rendermode-lighting.c b/src/rendermode-lighting.c index c38fd1e..e836fcf 100644 --- a/src/rendermode-lighting.c +++ b/src/rendermode-lighting.c @@ -93,27 +93,44 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state, passed in, which is a sign that we're recursing */ if ((block == 44 || block == 53 || block == 67) && authoratative == NULL) { float average_gather = 0.0f; - unsigned int average_count = 0; + unsigned int average_count = 0, upper_block; int auth; float coeff; - /* iterate through all surrounding blocks to take an average */ - int dx, dy, dz; - for (dx = -1; dx <= 1; dx += 2) { - for (dy = -1; dy <= 1; dy += 2) { - for (dz = -1; dz <= 1; dz += 2) { - coeff = get_lighting_coefficient(self, state, x+dx, y+dy, z+dz, &auth); - if (auth) { - average_gather += coeff; - average_count++; + if (local_z != 127) { /* stairs and half-blocks take the skylevel from the upper block if it's transparent */ + upper_block = getArrayByte3D(blocks, local_x, local_y, local_z + 1); + if (is_transparent(upper_block)) { + skylevel = getArrayByte3D(skylight, local_x, local_y, local_z + 1); + } + blocklevel = getArrayByte3D(blocklight, local_x, local_y, local_z); + } else { + upper_block = 0; + skylevel = 15; + blocklevel = getArrayByte3D(blocklight, local_x, local_y, local_z); + } + + if (skylevel) { /* if we have a good skylevel use it, if not iterate */ + return calculate_darkness(skylevel, blocklevel); + } else { + + /* iterate through all surrounding blocks to take an average */ + int dx, dy, dz; + for (dx = -1; dx <= 1; dx += 2) { + for (dy = -1; dy <= 1; dy += 2) { + for (dz = -1; dz <= 1; dz += 2) { + coeff = get_lighting_coefficient(self, state, x+dx, y+dy, z+dz, &auth); + if (auth) { + average_gather += coeff; + average_count++; + } } } } + + /* only return the average if at least one was authoratative */ + if (average_count > 0) + return average_gather / average_count; } - - /* only return the average if at least one was authoratative */ - if (average_count > 0) - return average_gather / average_count; } if (block == 10 || block == 11) { From c2bf7ff34e02b5add60799d54df300f24c143781 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Wed, 8 Jun 2011 14:41:43 -0400 Subject: [PATCH 22/44] added --no-signs option --- googlemap.py | 12 +++++++++--- overviewer.py | 1 + 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/googlemap.py b/googlemap.py index daf0e0e..0e99639 100644 --- a/googlemap.py +++ b/googlemap.py @@ -66,7 +66,8 @@ class MapGen(object): image format, and world. Note:tiledir for each quadtree should be unique. By default the tiledir is determined by the rendermode""" - self.skipjs = configInfo.get('skipjs', None) + self.skipjs = configInfo.get('skipjs', False) + self.nosigns = configInfo.get('nosigns', False) self.web_assets_hook = configInfo.get('web_assets_hook', None) self.web_assets_path = configInfo.get('web_assets_path', None) self.bg_color = configInfo.get('bg_color') @@ -153,13 +154,18 @@ class MapGen(object): # we need to merge self.world.POI with the persistant data in world.PersistentData self.world.POI += filter(lambda x: x['type'] != 'spawn', self.world.persistentData['POI']) + + if self.nosigns: + markers = filter(lambda x: x['type'] != 'sign', self.world.POI) + else: + markers = self.world.POI # write out the default marker table with open(os.path.join(self.destdir, "markers.js"), 'w') as output: output.write("overviewer.collections.markerDatas.push([\n") - for marker in self.world.POI: + for marker in markers: output.write(json.dumps(marker)) - if marker != self.world.POI[-1]: + if marker != markers[-1]: output.write(",") output.write("\n") output.write("]);\n") diff --git a/overviewer.py b/overviewer.py index 22a103c..1bf6790 100755 --- a/overviewer.py +++ b/overviewer.py @@ -107,6 +107,7 @@ def main(): parser.add_option("-q", "--quiet", dest="quiet", action="count", default=0, help="Print less output. You can specify this option multiple times.") parser.add_option("-v", "--verbose", dest="verbose", action="count", default=0, help="Print more output. You can specify this option multiple times.") parser.add_option("--skip-js", dest="skipjs", action="store_true", help="Don't output marker.js or regions.js") + parser.add_option("--no-signs", dest="nosigns", action="store_true", help="Don't output signs to markers.js") parser.add_option("--display-config", dest="display_config", action="store_true", help="Display the configuration parameters, but don't render the map. Requires all required options to be specified", commandLineOnly=True) #parser.add_option("--write-config", dest="write_config", action="store_true", help="Writes out a sample config file", commandLineOnly=True) From 454c1537a6099d5dc2168c11b1cf0a5db2507891 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Wed, 8 Jun 2011 14:57:21 -0400 Subject: [PATCH 23/44] sign drop-down now only shows rules that actually match something --- web_assets/overviewer.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/web_assets/overviewer.js b/web_assets/overviewer.js index 467affb..615e78a 100644 --- a/web_assets/overviewer.js +++ b/web_assets/overviewer.js @@ -598,6 +598,11 @@ var overviewer = { var items = []; for (i in overviewerConfig.objectGroups.signs) { var signGroup = overviewerConfig.objectGroups.signs[i]; + // don't create an option for this group if empty + if (overviewer.collections.markers[signGroup.label].length == 0) { + continue; + } + var iconURL = signGroup.icon; if(!iconURL) { iconURL = overviewerConfig.CONST.image.defaultMarker; @@ -616,7 +621,11 @@ var overviewer = { } }); } - overviewer.util.createDropDown('Signposts', items); + + // only create drop down if there's used options + if (items.length > 0) { + overviewer.util.createDropDown('Signposts', items); + } } // if there are any regions data, lets show the option to hide/show them. From e519aaa8a06ab59e8ae11427ac81bc863fe11039 Mon Sep 17 00:00:00 2001 From: untergrundbiber Date: Wed, 8 Jun 2011 15:28:04 -0400 Subject: [PATCH 24/44] Local time in timestamp --- googlemap.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/googlemap.py b/googlemap.py index 0e99639..48fede1 100644 --- a/googlemap.py +++ b/googlemap.py @@ -19,7 +19,7 @@ import stat import cPickle import Image import shutil -from time import strftime, gmtime +from time import strftime, localtime import json import util @@ -132,7 +132,7 @@ class MapGen(object): index = open(indexpath, 'r').read() index = index.replace( - "{time}", str(strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime()))) + "{time}", str(strftime("%a, %d %b %Y %H:%M:%S %Z", localtime()))) index = index.replace("{version}", util.findGitVersion()) with open(os.path.join(self.destdir, "index.html"), 'w') as output: From 6bb39a87ca96c5efb2ab7951492ee9a5c41832f5 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Wed, 8 Jun 2011 16:48:29 -0400 Subject: [PATCH 25/44] basic styling for custom control buttons --- web_assets/overviewer.css | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/web_assets/overviewer.css b/web_assets/overviewer.css index 14585e6..4bce661 100644 --- a/web_assets/overviewer.css +++ b/web_assets/overviewer.css @@ -32,16 +32,21 @@ body { .customControl { padding: 5px; height: 15px; + color: black; font-family: Arial, sans-serif; } .customControl > div.top { - background-color: #fff; - border: 2px solid #000; - text-align: center; - width: 70px; font-size: 12px; - width: 70px; + line-height: 160%; + text-align: center; + padding: 0px 6px; + + background-color: white; + + border: 1px solid #A9BBDF; + border-radius: 2px 2px; + box-shadow: rgba(0, 0, 0, 0.347656) 2px 2px 3px; cursor: pointer; } From 71d8da5f83a4c099a93fb184dff502b8f0c6e86a Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Wed, 8 Jun 2011 12:01:38 +0200 Subject: [PATCH 26/44] Iprove tall-grass looking. Draw the sprite in the correct angle, and draw it at a random offset (as done in game). --- src/rendermode-normal.c | 6 ++++++ textures.py | 13 ++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/rendermode-normal.c b/src/rendermode-normal.c index d975ed9..b112192 100644 --- a/src/rendermode-normal.c +++ b/src/rendermode-normal.c @@ -125,12 +125,18 @@ rendermode_normal_occluded(void *data, RenderState *state) { static void rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { RenderModeNormal *self = (RenderModeNormal *)data; + int randx = 0,randy = 0; /* first, check to see if we should use biome-compatible src, mask */ if (self->biome_data) { if (state->block == 18) { src = mask = self->leaf_texture; } else if (state->block == 31) { + /* add a random offset to the postion of the tall grass to make it more wild */ + randx = rand() % 6 + 1 - 3; + randy = rand() % 6 + 1 - 3; + state->imgx = state->imgx + randx; + state->imgy = state->imgy + randy; unsigned char data = getArrayByte3D(state->blockdata_expanded, state->x, state->y, state->z); if (data == 1) { src = mask = self->tall_grass_texture; diff --git a/textures.py b/textures.py index 101b933..be81977 100644 --- a/textures.py +++ b/textures.py @@ -236,7 +236,8 @@ def _build_block(top, side, blockID=None): """ img = Image.new("RGBA", (24,24), (38,92,255,0)) - + + original_texture = top.copy() top = transform_image(top, blockID) if not side: @@ -256,8 +257,15 @@ def _build_block(top, side, blockID=None): otherside = ImageEnhance.Brightness(otherside).enhance(0.8) otherside.putalpha(othersidealpha) + ## special case for tall-grass, fern and dead shrub, they are the only sprite-blocks + ## that have the sprites in the diagonal of the block + if blockID in (31,32): + front = original_texture.resize((14,11), Image.ANTIALIAS) + composite.alpha_over(img, front, (5,9)) + return img + ## special case for non-block things - if blockID in (31,32,37,38,6,39,40,83,30): ## tall grass, dead shrubs, flowers, sapling, mushrooms, reeds, web + if blockID in (37,38,6,39,40,83,30): ## flowers, sapling, mushrooms, reeds, web # # instead of pasting these blocks at the cube edges, place them in the middle: # and omit the top @@ -265,7 +273,6 @@ def _build_block(top, side, blockID=None): composite.alpha_over(img, otherside, (6,3), otherside) return img - if blockID in (81,): # cacti! composite.alpha_over(img, side, (1,6), side) composite.alpha_over(img, otherside, (11,6), otherside) From 1a1e8b1239dee7d3c03f41cbc3e77fa33c143fa7 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Thu, 9 Jun 2011 00:02:58 +0200 Subject: [PATCH 27/44] Delete false comment. --- textures.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/textures.py b/textures.py index be81977..5171285 100644 --- a/textures.py +++ b/textures.py @@ -257,8 +257,7 @@ def _build_block(top, side, blockID=None): otherside = ImageEnhance.Brightness(otherside).enhance(0.8) otherside.putalpha(othersidealpha) - ## special case for tall-grass, fern and dead shrub, they are the only sprite-blocks - ## that have the sprites in the diagonal of the block + ## special case for tall-grass, fern and dead shrub, if blockID in (31,32): front = original_texture.resize((14,11), Image.ANTIALIAS) composite.alpha_over(img, front, (5,9)) From 57d2a525ff036740d65327cfd9c3d09b0a11cde9 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Thu, 9 Jun 2011 01:11:38 +0200 Subject: [PATCH 28/44] Add self. --- src/rendermode-lighting.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rendermode-lighting.c b/src/rendermode-lighting.c index e836fcf..d0d4c64 100644 --- a/src/rendermode-lighting.c +++ b/src/rendermode-lighting.c @@ -110,7 +110,7 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state, } if (skylevel) { /* if we have a good skylevel use it, if not iterate */ - return calculate_darkness(skylevel, blocklevel); + return self->calculate_darkness(skylevel, blocklevel); } else { /* iterate through all surrounding blocks to take an average */ From 512b2032b27aae41c867cad12c0f9e48579f2182 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Wed, 8 Jun 2011 19:58:18 -0400 Subject: [PATCH 29/44] finished styling controls --- web_assets/control-bg-active.png | Bin 0 -> 2802 bytes web_assets/control-bg.png | Bin 0 -> 2785 bytes web_assets/overviewer.css | 23 ++++++++++++++++++++--- web_assets/overviewer.js | 1 + 4 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 web_assets/control-bg-active.png create mode 100644 web_assets/control-bg.png diff --git a/web_assets/control-bg-active.png b/web_assets/control-bg-active.png new file mode 100644 index 0000000000000000000000000000000000000000..67fb91521947a6ae70adf908e50327307ab1a885 GIT binary patch literal 2802 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 literal 0 HcmV?d00001 diff --git a/web_assets/control-bg.png b/web_assets/control-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..b6387179b576930eb563c10e5ca33848ff62bbe5 GIT binary patch literal 2785 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 div.top:hover { + border: 1px solid #678AC7; +} + +.customControl > div.top-active { + color: white; + font-weight: bold; + padding: 0px 5px; + border: 1px solid #678AC7; + background-image: url('control-bg-active.png'); +} + .customControl > div.dropDown { - border: 1px solid #000; font-size: 12px; - background-color: #fff; + background-color: white; + + border: 1px solid #A9BBDF; + border-radius: 2px 2px; + box-shadow: rgba(0, 0, 0, 0.347656) 2px 2px 3px; + display: none; } diff --git a/web_assets/overviewer.js b/web_assets/overviewer.js index 615e78a..ceeb7dc 100644 --- a/web_assets/overviewer.js +++ b/web_assets/overviewer.js @@ -706,6 +706,7 @@ var overviewer = { // add the functionality to toggle visibility of the items $(controlText).click(function() { + $(controlBorder).toggleClass('top-active'); $(dropdownDiv).toggle(); }); From 56a2e1f8340cc955435f88189169715118003a0a Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Thu, 9 Jun 2011 11:45:36 -0400 Subject: [PATCH 30/44] Move decl to top of block --- src/rendermode-normal.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rendermode-normal.c b/src/rendermode-normal.c index b112192..c6a7ab9 100644 --- a/src/rendermode-normal.c +++ b/src/rendermode-normal.c @@ -126,6 +126,7 @@ static void rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { RenderModeNormal *self = (RenderModeNormal *)data; int randx = 0,randy = 0; + unsigned char data; /* first, check to see if we should use biome-compatible src, mask */ if (self->biome_data) { @@ -137,7 +138,7 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject * randy = rand() % 6 + 1 - 3; state->imgx = state->imgx + randx; state->imgy = state->imgy + randy; - unsigned char data = getArrayByte3D(state->blockdata_expanded, state->x, state->y, state->z); + data = getArrayByte3D(state->blockdata_expanded, state->x, state->y, state->z); if (data == 1) { src = mask = self->tall_grass_texture; } else if (data == 2) { From b1ee31bffa777a8ccc3b24358cf6ed7a64410a1d Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Thu, 9 Jun 2011 11:47:51 -0400 Subject: [PATCH 31/44] Proper fix for build issue (Fixes #395) --- src/rendermode-normal.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rendermode-normal.c b/src/rendermode-normal.c index c6a7ab9..cee7431 100644 --- a/src/rendermode-normal.c +++ b/src/rendermode-normal.c @@ -126,7 +126,7 @@ static void rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { RenderModeNormal *self = (RenderModeNormal *)data; int randx = 0,randy = 0; - unsigned char data; + unsigned char data_byte; /* first, check to see if we should use biome-compatible src, mask */ if (self->biome_data) { @@ -138,10 +138,10 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject * randy = rand() % 6 + 1 - 3; state->imgx = state->imgx + randx; state->imgy = state->imgy + randy; - data = getArrayByte3D(state->blockdata_expanded, state->x, state->y, state->z); - if (data == 1) { + data_byte = getArrayByte3D(state->blockdata_expanded, state->x, state->y, state->z); + if (data_byte == 1) { src = mask = self->tall_grass_texture; - } else if (data == 2) { + } else if (data_byte == 2) { src = mask = self->tall_fern_texture; } } From 13c9750a43f2cb84e79a94e73a0d3ae3b64f6fa4 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Sat, 11 Jun 2011 04:58:51 -0400 Subject: [PATCH 32/44] fixed crash when spawn point does not have an associated region file (closes issue #399) --- world.py | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/world.py b/world.py index f02098c..564d193 100644 --- a/world.py +++ b/world.py @@ -208,23 +208,25 @@ class World(object): ## The filename of this chunk chunkFile = self.get_region_path(chunkX, chunkY) - - data=nbt.load_from_region(chunkFile, chunkX, chunkY)[1] - level = data['Level'] - blockArray = numpy.frombuffer(level['Blocks'], dtype=numpy.uint8).reshape((16,16,128)) - - ## The block for spawn *within* the chunk - inChunkX = spawnX - (chunkX*16) - inChunkZ = spawnZ - (chunkY*16) - - ## find the first air block - while (blockArray[inChunkX, inChunkZ, spawnY] != 0): - spawnY += 1 - if spawnY == 128: - break + + if chunkFile is not None: + data = nbt.load_from_region(chunkFile, chunkX, chunkY)[1] + if data is not None: + level = data['Level'] + blockArray = numpy.frombuffer(level['Blocks'], dtype=numpy.uint8).reshape((16,16,128)) + + ## The block for spawn *within* the chunk + inChunkX = spawnX - (chunkX*16) + inChunkZ = spawnZ - (chunkY*16) + + ## find the first air block + while (blockArray[inChunkX, inChunkZ, spawnY] != 0): + spawnY += 1 + if spawnY == 128: + break self.POI.append( dict(x=spawnX, y=spawnY, z=spawnZ, - msg="Spawn", type="spawn", chunk=(inChunkX,inChunkZ))) + msg="Spawn", type="spawn", chunk=(chunkX, chunkY))) self.spawn = (spawnX, spawnY, spawnZ) def go(self, procs): From c3e79459d4b30af0139dc761328979df5471257f Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Wed, 15 Jun 2011 00:28:32 -0400 Subject: [PATCH 33/44] fix for running on PIL 1.1.5 and earlier --- textures.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/textures.py b/textures.py index 5171285..5e2db3b 100644 --- a/textures.py +++ b/textures.py @@ -493,13 +493,7 @@ def generate_opaque_mask(img): smallers than 50, and sets every other value to 255. """ alpha = img.split()[3] - pixel = alpha.load() - for x in range(img.size[0]): - for y in range(img.size[1]): - if pixel[x,y] > 25: - pixel[x,y] = 255 - - return alpha + return alpha.point(lambda a: int(min(a, 25.5) * 10)) def generate_texture_tuple(img, blockid): """ This takes an image and returns the needed tuple for the From 0bb484bdf7891e564157527d5426475d1ea48c8e Mon Sep 17 00:00:00 2001 From: Eric Carr Date: Wed, 15 Jun 2011 15:09:04 +0200 Subject: [PATCH 34/44] Added mouseover coords --- web_assets/overviewer.css | 2 +- web_assets/overviewer.js | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/web_assets/overviewer.css b/web_assets/overviewer.css index dc435fa..dbb3830 100644 --- a/web_assets/overviewer.css +++ b/web_assets/overviewer.css @@ -82,7 +82,7 @@ body { } -#link { +#link, #coordsDiv { background-color: #fff; /* fallback */ background-color: rgba(255,255,255,0.55); border: 1px solid rgb(0, 0, 0); diff --git a/web_assets/overviewer.js b/web_assets/overviewer.js index ceeb7dc..ea87a19 100644 --- a/web_assets/overviewer.js +++ b/web_assets/overviewer.js @@ -591,6 +591,17 @@ var overviewer = { overviewer.map.controls[google.maps.ControlPosition.TOP_RIGHT].push(homeControlDiv); } + // Coords box + var coordsDiv = document.createElement('DIV'); + coordsDiv.id = 'coordsDiv'; + coordsDiv.innerHTML = ''; + overviewer.map.controls[google.maps.ControlPosition.BOTTOM_LEFT].push(coordsDiv); + // Update coords on mousemove + google.maps.event.addListener(overviewer.map, 'mousemove', function (event) { + var worldcoords = overviewer.util.fromLatLngToWorld(event.latLng.lat(), event.latLng.lng()); + coordsDiv.innerHTML = "Coords: X " + Math.round(worldcoords.x) + ", Z " + Math.round(worldcoords.z); + }); + // only need to create the control if there are items in the list. // as defined in config.js if (overviewerConfig.objectGroups.signs.length > 0) { From 091a76fe60becbea77d757e602248c18c38ea9f1 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Wed, 15 Jun 2011 10:26:16 -0400 Subject: [PATCH 35/44] added sans-serif font styling to whole page, in line with other controls --- web_assets/overviewer.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web_assets/overviewer.css b/web_assets/overviewer.css index dbb3830..f4bdd98 100644 --- a/web_assets/overviewer.css +++ b/web_assets/overviewer.css @@ -7,6 +7,10 @@ body { margin: 0px; padding: 0px; background-color: #000; + + font-family: Arial, sans-serif; + font-size: 12px; + line-height: 160%; } #mcmap { From b1a386cae98560d4df2638880c02b96ef0d14099 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Thu, 16 Jun 2011 06:26:58 -0700 Subject: [PATCH 36/44] fixed sample.settings.py typo --- sample.settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample.settings.py b/sample.settings.py index 8c85a3e..3b6aed2 100644 --- a/sample.settings.py +++ b/sample.settings.py @@ -6,7 +6,7 @@ # provide examples of interesting things you can do with the settings file. Most # of the time, a simple 'setting_name = value' will work. -# This file is a python script, so you can import and python module you wish or +# This file is a python script, so you can import any python module you wish or # use any built-in python function, though this is not normally necessary # Lines that start with a hash mark are comments From 6cf0cc514715a4e79751489810231a1678857755 Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Sat, 18 Jun 2011 11:51:13 -0400 Subject: [PATCH 37/44] Fixed regionlist regression --- quadtree.py | 9 +++++---- world.py | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/quadtree.py b/quadtree.py index f1c4b1d..fc00b01 100644 --- a/quadtree.py +++ b/quadtree.py @@ -426,9 +426,6 @@ class QuadtreeGen(object): needs_rerender = False get_region_mtime = world.get_region_mtime for col, row, chunkx, chunky, regionfile in chunks: - # don't even check if it's not in the regionlist - if self.world.regionlist and region._filename not in self.world.regionlist: - continue # bail early if forcerender is set if self.forcerender: @@ -439,7 +436,11 @@ class QuadtreeGen(object): region,regionMtime = get_region_mtime(regionfile) if regionMtime <= tile_mtime: continue - + + # don't even check if it's not in the regionlist + if self.world.regionlist and os.path.abspath(region._filename) not in self.world.regionlist: + continue + # checking chunk mtime if region.get_chunk_timestamp(chunkx, chunky) > tile_mtime: needs_rerender = True diff --git a/world.py b/world.py index 564d193..7d4ce0d 100644 --- a/world.py +++ b/world.py @@ -78,7 +78,7 @@ class World(object): logging.info("Scanning regions") regionfiles = {} self.regions = {} - self.regionlist = regionlist # a list of paths + self.regionlist = map(os.path.abspath, regionlist) # a list of paths for x, y, regionfile in self._iterate_regionfiles(): mcr = self.reload_region(regionfile) mcr.get_chunk_info() From 312624e96cc780ab4de9c3f1d7aef56d900ab9ae Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Sat, 18 Jun 2011 14:59:37 -0400 Subject: [PATCH 38/44] Fix regression introduced by regression fix --- world.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/world.py b/world.py index 7d4ce0d..1344d10 100644 --- a/world.py +++ b/world.py @@ -78,7 +78,10 @@ class World(object): logging.info("Scanning regions") regionfiles = {} self.regions = {} - self.regionlist = map(os.path.abspath, regionlist) # a list of paths + if regionlist: + self.regionlist = map(os.path.abspath, regionlist) # a list of paths + else: + self.regionlist = None for x, y, regionfile in self._iterate_regionfiles(): mcr = self.reload_region(regionfile) mcr.get_chunk_info() From fdadda0ea60133a5b89e37f59fcaadebe095fb1c Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Sun, 19 Jun 2011 01:10:03 +0200 Subject: [PATCH 39/44] Move the average lighting coeff to another function. Take the average over blockmap. Fixes problems with stairs in night and lighting rendermode. --- src/rendermode-lighting.c | 150 +++++++++++++++++++++++++++----------- src/rendermodes.h | 2 +- 2 files changed, 107 insertions(+), 45 deletions(-) diff --git a/src/rendermode-lighting.c b/src/rendermode-lighting.c index d0d4c64..35dc688 100644 --- a/src/rendermode-lighting.c +++ b/src/rendermode-lighting.c @@ -33,21 +33,106 @@ static float calculate_darkness(unsigned char skylight, unsigned char blocklight * was calculated correctly from available light data, it will be true. You * may (and probably should) pass NULL. */ + +inline unsigned char +estimate_blocklevel(RenderModeLighting *self, RenderState *state, + int x, int y, int z, int *authoratative) { + + /* placeholders for later data arrays, coordinates */ + PyObject *blocks = NULL; + PyObject *blocklight = NULL; + int local_x = x, local_y = y, local_z = z; + unsigned char block, blocklevel; + unsigned int average_count = 0, average_gather = 0, coeff = 0; + + /* defaults to "guess" until told otherwise */ + if (authoratative) + *authoratative = 0; + + /* find out what chunk we're in, and translate accordingly */ + if (x >= 0 && y < 16) { + blocks = state->blocks; + blocklight = self->blocklight; + } else if (x < 0) { + local_x += 16; + blocks = state->left_blocks; + blocklight = self->left_blocklight; + } else if (y >= 16) { + local_y -= 16; + blocks = state->right_blocks; + blocklight = self->right_blocklight; + } + + /* make sure we have correctly-ranged coordinates */ + if (!(local_x >= 0 && local_x < 16 && + local_y >= 0 && local_y < 16 && + local_z >= 0 && local_z < 128)) { + + return 0; + } + + /* also, make sure we have enough info to correctly calculate lighting */ + if (blocks == Py_None || blocks == NULL || + blocklight == Py_None || blocklight == NULL) { + + return 0; + } + + block = getArrayByte3D(blocks, local_x, local_y, local_z); + + if (authoratative == NULL) { + int auth; + + /* iterate through all surrounding blocks to take an average */ + int dx, dy, dz, local_block; + //~ printf("\n[Starting loop]\n"); + for (dx = -1; dx <= 1; dx += 2) { + for (dy = -1; dy <= 1; dy += 2) { + for (dz = -1; dz <= 1; dz += 2) { + coeff = estimate_blocklevel(self, state, x+dx, y+dy, z+dz, &auth); + local_block = getArrayByte3D(blocks, x+dx, y+dy, z+dz); + if (auth && is_transparent(local_block)) { + average_gather += coeff; + average_count++; + } + //~ printf(" [Inside the loop] Coeff = %d, average_gather = %d, average_count = %d, auth = %d, block = %d\n", coeff, average_gather, average_count, auth, local_block); + } + } + } + } + + /* only return the average if at least one was authoratative */ + if (average_count > 0) { + int result; + float resultf; + result = average_gather / average_count; + resultf = average_gather / average_count; + //~ printf("[Outside the loop] average_gather = %d, average_count = %d\n", average_gather, average_count); + //~ printf("[Outside the loop] result = %d, resultf = %f\n", result, resultf); + return average_gather / average_count; + } + + blocklevel = getArrayByte3D(blocklight, local_x, local_y, local_z); + + /* no longer a guess */ + if (!(block == 44 || block == 53 || block == 67) && authoratative) { + *authoratative = 1; + } + + return blocklevel; +} + inline float get_lighting_coefficient(RenderModeLighting *self, RenderState *state, - int x, int y, int z, int *authoratative) { - + int x, int y, int z) { + /* placeholders for later data arrays, coordinates */ PyObject *blocks = NULL; PyObject *skylight = NULL; PyObject *blocklight = NULL; int local_x = x, local_y = y, local_z = z; unsigned char block, skylevel, blocklevel; - - /* defaults to "guess" until told otherwise */ - if (authoratative) - *authoratative = 0; - + /* find out what chunk we're in, and translate accordingly */ if (x >= 0 && y < 16) { blocks = state->blocks; @@ -64,7 +149,7 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state, skylight = self->right_skylight; blocklight = self->right_blocklight; } - + /* make sure we have correctly-ranged coordinates */ if (!(local_x >= 0 && local_x < 16 && local_y >= 0 && local_y < 16 && @@ -72,7 +157,7 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state, return self->calculate_darkness(15, 0); } - + /* also, make sure we have enough info to correctly calculate lighting */ if (blocks == Py_None || blocks == NULL || skylight == Py_None || skylight == NULL || @@ -89,13 +174,16 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state, return self->calculate_darkness(15, 0); } + skylevel = getArrayByte3D(skylight, local_x, local_y, local_z); + blocklevel = getArrayByte3D(blocklight, local_x, local_y, local_z); + //~ if (block == 0 && blocklevel != 0) { + //~ printf("Para este aire tenemos skylevel %d, blocklevel %d\n", skylevel, blocklevel); + //~ } + /* only do special half-step handling if no authoratative pointer was passed in, which is a sign that we're recursing */ - if ((block == 44 || block == 53 || block == 67) && authoratative == NULL) { - float average_gather = 0.0f; - unsigned int average_count = 0, upper_block; - int auth; - float coeff; + if (block == 44 || block == 53 || block == 67) { + unsigned int upper_block; if (local_z != 127) { /* stairs and half-blocks take the skylevel from the upper block if it's transparent */ upper_block = getArrayByte3D(blocks, local_x, local_y, local_z + 1); @@ -108,29 +196,10 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state, skylevel = 15; blocklevel = getArrayByte3D(blocklight, local_x, local_y, local_z); } + + /* use given coordinates, no local ones! */ + blocklevel = estimate_blocklevel(self, state, x, y, z, NULL); - if (skylevel) { /* if we have a good skylevel use it, if not iterate */ - return self->calculate_darkness(skylevel, blocklevel); - } else { - - /* iterate through all surrounding blocks to take an average */ - int dx, dy, dz; - for (dx = -1; dx <= 1; dx += 2) { - for (dy = -1; dy <= 1; dy += 2) { - for (dz = -1; dz <= 1; dz += 2) { - coeff = get_lighting_coefficient(self, state, x+dx, y+dy, z+dz, &auth); - if (auth) { - average_gather += coeff; - average_count++; - } - } - } - } - - /* only return the average if at least one was authoratative */ - if (average_count > 0) - return average_gather / average_count; - } } if (block == 10 || block == 11) { @@ -138,13 +207,6 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state, return 0.0f; } - skylevel = getArrayByte3D(skylight, local_x, local_y, local_z); - blocklevel = getArrayByte3D(blocklight, local_x, local_y, local_z); - - /* no longer a guess */ - if (authoratative) - *authoratative = 1; - return self->calculate_darkness(skylevel, blocklevel); } @@ -164,7 +226,7 @@ do_shading_with_mask(RenderModeLighting *self, RenderState *state, } } - black_coeff = get_lighting_coefficient(self, state, x, y, z, NULL); + black_coeff = get_lighting_coefficient(self, state, x, y, z); alpha_over_full(state->img, self->black_color, mask, black_coeff, state->imgx, state->imgy, 0, 0); } diff --git a/src/rendermodes.h b/src/rendermodes.h index 80126a4..bd8748a 100644 --- a/src/rendermodes.h +++ b/src/rendermodes.h @@ -118,7 +118,7 @@ typedef struct { } RenderModeLighting; extern RenderModeInterface rendermode_lighting; inline float get_lighting_coefficient(RenderModeLighting *self, RenderState *state, - int x, int y, int z, int *authoratative); + int x, int y, int z); /* NIGHT */ typedef struct { From 8eda22055fcfab3241a0d3fa4e0378aedf70115b Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Sun, 19 Jun 2011 01:25:41 +0200 Subject: [PATCH 40/44] Add comments. Delete printfs. --- src/rendermode-lighting.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/rendermode-lighting.c b/src/rendermode-lighting.c index 35dc688..e5f75bc 100644 --- a/src/rendermode-lighting.c +++ b/src/rendermode-lighting.c @@ -85,17 +85,17 @@ estimate_blocklevel(RenderModeLighting *self, RenderState *state, /* iterate through all surrounding blocks to take an average */ int dx, dy, dz, local_block; - //~ printf("\n[Starting loop]\n"); for (dx = -1; dx <= 1; dx += 2) { for (dy = -1; dy <= 1; dy += 2) { for (dz = -1; dz <= 1; dz += 2) { coeff = estimate_blocklevel(self, state, x+dx, y+dy, z+dz, &auth); local_block = getArrayByte3D(blocks, x+dx, y+dy, z+dz); + /* only add if the block is transparent, this seems to look better than + using every block */ if (auth && is_transparent(local_block)) { average_gather += coeff; average_count++; } - //~ printf(" [Inside the loop] Coeff = %d, average_gather = %d, average_count = %d, auth = %d, block = %d\n", coeff, average_gather, average_count, auth, local_block); } } } @@ -103,12 +103,6 @@ estimate_blocklevel(RenderModeLighting *self, RenderState *state, /* only return the average if at least one was authoratative */ if (average_count > 0) { - int result; - float resultf; - result = average_gather / average_count; - resultf = average_gather / average_count; - //~ printf("[Outside the loop] average_gather = %d, average_count = %d\n", average_gather, average_count); - //~ printf("[Outside the loop] result = %d, resultf = %f\n", result, resultf); return average_gather / average_count; } @@ -176,16 +170,13 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state, skylevel = getArrayByte3D(skylight, local_x, local_y, local_z); blocklevel = getArrayByte3D(blocklight, local_x, local_y, local_z); - //~ if (block == 0 && blocklevel != 0) { - //~ printf("Para este aire tenemos skylevel %d, blocklevel %d\n", skylevel, blocklevel); - //~ } - /* only do special half-step handling if no authoratative pointer was - passed in, which is a sign that we're recursing */ + /* special half-step handling */ if (block == 44 || block == 53 || block == 67) { unsigned int upper_block; - if (local_z != 127) { /* stairs and half-blocks take the skylevel from the upper block if it's transparent */ + /* stairs and half-blocks take the skylevel from the upper block if it's transparent */ + if (local_z != 127) { upper_block = getArrayByte3D(blocks, local_x, local_y, local_z + 1); if (is_transparent(upper_block)) { skylevel = getArrayByte3D(skylight, local_x, local_y, local_z + 1); @@ -197,6 +188,7 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state, blocklevel = getArrayByte3D(blocklight, local_x, local_y, local_z); } + /* the block has a bad blocklevel, estimate it from neigborhood /* use given coordinates, no local ones! */ blocklevel = estimate_blocklevel(self, state, x, y, z, NULL); From 278eabbae312a7fbf021d9fe2ac0e1fd245995c4 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Sun, 19 Jun 2011 01:36:41 +0200 Subject: [PATCH 41/44] Remove unused access to blocklight array. --- src/rendermode-lighting.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/rendermode-lighting.c b/src/rendermode-lighting.c index e5f75bc..0a92554 100644 --- a/src/rendermode-lighting.c +++ b/src/rendermode-lighting.c @@ -181,11 +181,9 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state, if (is_transparent(upper_block)) { skylevel = getArrayByte3D(skylight, local_x, local_y, local_z + 1); } - blocklevel = getArrayByte3D(blocklight, local_x, local_y, local_z); } else { upper_block = 0; skylevel = 15; - blocklevel = getArrayByte3D(blocklight, local_x, local_y, local_z); } /* the block has a bad blocklevel, estimate it from neigborhood From aed6938d2271c1538e6ce6a8737095e6dddc9ac9 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Wed, 22 Jun 2011 14:19:50 -0400 Subject: [PATCH 42/44] now fails correctly if --settings is given but file does not exist --- configParser.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/configParser.py b/configParser.py index 01e6a14..7a9adaa 100644 --- a/configParser.py +++ b/configParser.py @@ -81,6 +81,10 @@ class ConfigOptionParser(object): if os.path.exists(self.configFile): execfile(self.configFile, g, l) + elif options.config_file: + # file does not exist, but *was* specified on the command line + logging.error("Could not open %s." % self.configFile) + sys.exit(1) except NameError, ex: import traceback traceback.print_exc() From 79944d4f9065477b6b5c66dc734e5e07082bdab6 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Thu, 23 Jun 2011 17:44:04 -0400 Subject: [PATCH 43/44] fixed out-of-bounds index segfault --- src/rendermode-lighting.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/rendermode-lighting.c b/src/rendermode-lighting.c index 0a92554..c515db5 100644 --- a/src/rendermode-lighting.c +++ b/src/rendermode-lighting.c @@ -88,6 +88,14 @@ estimate_blocklevel(RenderModeLighting *self, RenderState *state, for (dx = -1; dx <= 1; dx += 2) { for (dy = -1; dy <= 1; dy += 2) { for (dz = -1; dz <= 1; dz += 2) { + + /* skip if block is out of range */ + if (x+dx < 0 || x+dx >= 16 || + y+dy < 0 || y+dy >= 16 || + z+dz < 0 || z+dz >= 128) { + continue; + } + coeff = estimate_blocklevel(self, state, x+dx, y+dy, z+dz, &auth); local_block = getArrayByte3D(blocks, x+dx, y+dy, z+dz); /* only add if the block is transparent, this seems to look better than From 62119c37eff8045e1d18fe3d2e84b777105b297d Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Thu, 23 Jun 2011 15:21:46 -0700 Subject: [PATCH 44/44] bumped extension version for fix that closes #414 --- src/overviewer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overviewer.h b/src/overviewer.h index 49e70fa..a0c5316 100644 --- a/src/overviewer.h +++ b/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 7 +#define OVERVIEWER_EXTENSION_VERSION 8 /* Python PIL, and numpy headers */ #include