From 803104e19300c844809899e5dda3d3f38a8534b1 Mon Sep 17 00:00:00 2001 From: Michael Writhe Date: Sat, 30 Apr 2011 20:17:14 -0600 Subject: [PATCH 01/10] resolved 2 issues with signs and regions not working for 'checked' items. issue 347 and 349 --- web_assets/overviewer.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/web_assets/overviewer.js b/web_assets/overviewer.js index f927625..06c0f0e 100644 --- a/web_assets/overviewer.js +++ b/web_assets/overviewer.js @@ -623,12 +623,12 @@ var overviewer = { 'checked': signGroup.checked, 'icon': iconURL, 'action': function(n, item, checked) { - jQuery.each(overviewer.collections.markers[item.label], + jQuery.each(overviewer.collections.markers[item], function(i, elem) { elem.setVisible(checked); } ); - overviewer.util.debug('Adding sign item: ' + item.label); + overviewer.util.debug('Adding sign item: ' + item); } }); } @@ -645,11 +645,13 @@ var overviewer = { 'label': regionGroup.label, 'checked': regionGroup.checked, 'action': function(n, item, checked) { - jQuery.each(overviewer.collections.regions[item.label], + jQuery.each(overviewer.collections.regions[item], function(i,elem) { // Thanks to LeastWeasel for this line! elem.setMap(checked ? overviewer.map : null); }); + overviewer.util.debug('Adding region item: ' + item); + } }); } From d163e7c5271da50a9584fcbdcd3d179c49cc4c9d Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Thu, 28 Apr 2011 19:18:29 -0400 Subject: [PATCH 02/10] support for biome coloring on side grass (closes issue #341) --- src/overviewer.h | 2 +- src/rendermode-normal.c | 16 ++++------------ textures.py | 7 ++++--- 3 files changed, 9 insertions(+), 16 deletions(-) diff --git a/src/overviewer.h b/src/overviewer.h index b18462a..55243a5 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 4 +#define OVERVIEWER_EXTENSION_VERSION 5 /* Python PIL, and numpy headers */ #include diff --git a/src/rendermode-normal.c b/src/rendermode-normal.c index 9f139a3..c656d2e 100644 --- a/src/rendermode-normal.c +++ b/src/rendermode-normal.c @@ -120,17 +120,8 @@ 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) { - switch (state->block) { - case 2: - src = mask = self->grass_texture; - break; - case 18: - src = mask = self->leaf_texture; - break; - default: - break; - }; + if (self->biome_data && state->block == 18) { + src = mask = self->leaf_texture; } /* draw the block! */ @@ -149,7 +140,8 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject * case 2: /* grass */ color = PySequence_GetItem(self->grasscolor, index); - facemask = self->facemask_top; + facemask = self->grass_texture; + alpha_over(state->img, self->grass_texture, self->grass_texture, state->imgx, state->imgy, 0, 0); break; case 18: /* leaves */ diff --git a/textures.py b/textures.py index 567942a..0f73932 100644 --- a/textures.py +++ b/textures.py @@ -432,8 +432,9 @@ def generate_special_texture(blockID, data): # all need to behandled here (and in chunkpy) if blockID == 2: # grass - top = tintTexture(terrain_images[0],(115,175,71)) - img = _build_block(top, terrain_images[3], 2) + img = _build_block(terrain_images[0], terrain_images[3], 2) + colored = tintTexture(biome_grass_texture, (115, 175, 71)) + composite.alpha_over(img, colored, (0, 0), colored) return (img.convert("RGB"), img.split()[3]) @@ -1179,7 +1180,7 @@ def tintTexture(im, c): return i # generate biome (still grayscale) leaf, grass textures -biome_grass_texture = _build_block(terrain_images[0], terrain_images[3], 2) +biome_grass_texture = _build_block(terrain_images[0], terrain_images[38], 2) biome_leaf_texture = _build_block(terrain_images[52], terrain_images[52], 18) From 9a537e76e2780450f67ee22b32e0b67343fa1b1d Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Sat, 30 Apr 2011 23:06:44 -0400 Subject: [PATCH 03/10] some config file clarifications --- quadtree.py | 2 +- sample.settings.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/quadtree.py b/quadtree.py index 701aa27..6d5a567 100644 --- a/quadtree.py +++ b/quadtree.py @@ -91,7 +91,7 @@ class QuadtreeGen(object): yradius >= worldobj.maxrow and -yradius <= worldobj.minrow: break else: - raise ValueError("Your map is waaaay too big! Use the '-z' or '--zoom' options.") + raise ValueError("Your map is waaaay too big! Use the 'zoom' option in 'settings.py'.") self.p = p else: diff --git a/sample.settings.py b/sample.settings.py index ee0d050..2872506 100644 --- a/sample.settings.py +++ b/sample.settings.py @@ -2,8 +2,9 @@ # Please see the README or https://github.com/brownan/Minecraft-Overviewer/wiki/DTT-Upgrade-Guide # for more details. -# To use this file, simply copy it to settings.py and make any necessary changes -# to suite your needs. +# This file is not meant to be used directly, but instead it is supposed to +# 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 # use any built-in python function, though this is not normally necessary From a68079de848ff890ca87f60a8d4f76aa918064cc Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Sun, 1 May 2011 12:35:11 -0400 Subject: [PATCH 04/10] Fixed signpost regression from a09d7f3 a09d7f3 fixed issue #349, but introduced a new regression. This commit reverts a09d7f3, and fixes #349 in a different way --- web_assets/overviewer.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web_assets/overviewer.js b/web_assets/overviewer.js index 06c0f0e..6220a16 100644 --- a/web_assets/overviewer.js +++ b/web_assets/overviewer.js @@ -623,7 +623,7 @@ var overviewer = { 'checked': signGroup.checked, 'icon': iconURL, 'action': function(n, item, checked) { - jQuery.each(overviewer.collections.markers[item], + jQuery.each(overviewer.collections.markers[item.label], function(i, elem) { elem.setVisible(checked); } @@ -645,7 +645,7 @@ var overviewer = { 'label': regionGroup.label, 'checked': regionGroup.checked, 'action': function(n, item, checked) { - jQuery.each(overviewer.collections.regions[item], + jQuery.each(overviewer.collections.regions[item.label], function(i,elem) { // Thanks to LeastWeasel for this line! elem.setMap(checked ? overviewer.map : null); @@ -738,7 +738,7 @@ var overviewer = { // if its checked, its gotta do something, do that here. if (item.checked) { itemInput.checked = true; - item.action(i, item.label, item.checked); + item.action(i, item, item.checked); } dropdownDiv.appendChild(itemDiv); itemDiv.appendChild(itemInput); From 724bf114e7c15e5715eabaf76436916a74b2a4f3 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Sun, 1 May 2011 16:30:40 +0200 Subject: [PATCH 05/10] Fix new saplings. --- textures.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/textures.py b/textures.py index 0f73932..2f28b64 100644 --- a/textures.py +++ b/textures.py @@ -210,9 +210,8 @@ def _build_block(top, side, blockID=None): return img side = transform_image_side(side, blockID) - otherside = side.transpose(Image.FLIP_LEFT_RIGHT) - + # 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 # the block transparent) @@ -224,8 +223,6 @@ def _build_block(top, side, blockID=None): otherside.putalpha(othersidealpha) ## special case for non-block things - # TODO once torches are handled by generate_special_texture, remove - # them from this list if blockID in (37,38,6,39,40,83): ## flowers, sapling, mushrooms, reeds # # instead of pasting these blocks at the cube edges, place them in the middle: @@ -439,18 +436,25 @@ def generate_special_texture(blockID, data): if blockID == 6: # saplings - if data == 1: # spruce sapling + # The bottom two bits are used fo the sapling type, the top two + # bits are used as a grow-counter for the tree. + + if data & 0x3 == 0: # usual saplings + toptexture = terrain_images[15] + sidetexture = terrain_images[15] + + if data & 0x3 == 1: # spruce sapling toptexture = terrain_images[63] sidetexture = terrain_images[63] - if data == 2: # birch sapling + if data & 0x3 == 2: # birch sapling toptexture = terrain_images[79] sidetexture = terrain_images[79] - - else: # usual and future saplings + + if data & 0x3 == 3: # unused usual sapling toptexture = terrain_images[15] sidetexture = terrain_images[15] - + img = _build_block(toptexture, sidetexture, blockID) return (img.convert("RGB"),img.split()[3]) @@ -1257,7 +1261,7 @@ special_blocks = set([ 2, 6, 9, 17, 18, 23, 27, 28, 35, 43, 44, 50, 51, special_map = {} -special_map[6] = range(4) # saplings: usual, spruce, birch and future ones (rendered as usual saplings) +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. special_map[17] = range(4) # wood: normal, birch and pine special_map[23] = range(6) # dispensers, orientation From 8b99db7bf6004dd2fcbbca701f03c85ac98b1346 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Sun, 1 May 2011 17:13:58 +0200 Subject: [PATCH 06/10] Add orientation for furnaces, dispensers, pumpkins, and jack-o-lanterns. --- textures.py | 73 +++++++++++++++++++++++------------------------------ 1 file changed, 32 insertions(+), 41 deletions(-) diff --git a/textures.py b/textures.py index 2f28b64..422ba8d 100644 --- a/textures.py +++ b/textures.py @@ -509,18 +509,6 @@ def generate_special_texture(blockID, data): t = tintTexture(terrain_images[52], (37, 118, 25)) img = _build_block(t, t, 18) return (img.convert("RGB"), img.split()[3]) - - if blockID == 23: # dispenser - top = transform_image(terrain_images[62]) - side1 = transform_image_side(terrain_images[46]) - side2 = transform_image_side(terrain_images[45]).transpose(Image.FLIP_LEFT_RIGHT) - - img = Image.new("RGBA", (24,24), (38,92,255,0)) - - composite.alpha_over(img, side1, (0,6), side1) - composite.alpha_over(img, side2, (12,6), side2) - composite.alpha_over(img, top, (0,0), top) - return (img.convert("RGB"), img.split()[3]) if blockID == 35: # wool @@ -853,29 +841,28 @@ def generate_special_texture(blockID, data): return (img.convert("RGB"), img.split()[3]) - if blockID == 61: #furnace - top = transform_image(terrain_images[62]) - side1 = transform_image_side(terrain_images[45]) - side2 = transform_image_side(terrain_images[44]).transpose(Image.FLIP_LEFT_RIGHT) + if blockID in (61, 62, 23): #furnace and burning furnace + top = terrain_images[62] + side = terrain_images[45] - img = Image.new("RGBA", (24,24), (38,92,255,0)) + if blockID == 61: + front = terrain_images[44] - composite.alpha_over(img, side1, (0,6), side1) - composite.alpha_over(img, side2, (12,6), side2) - composite.alpha_over(img, top, (0,0), top) - return (img.convert("RGB"), img.split()[3]) + elif blockID == 62: + front = terrain_images[45+16] + elif blockID == 23: + front = terrain_images[46] - if blockID == 62: # lit furnace - top = transform_image(terrain_images[62]) - side1 = transform_image_side(terrain_images[45]) - side2 = transform_image_side(terrain_images[45+16]).transpose(Image.FLIP_LEFT_RIGHT) + if data == 3: # pointing west + img = _build_full_block(top, None, None, side, front) + + elif data == 4: # pointing north + img = _build_full_block(top, None, None, front, side) + + else: # in any other direction the front can't be seen + img = _build_full_block(top, None, None, side, side) - img = Image.new("RGBA", (24,24), (38,92,255,0)) - - composite.alpha_over(img, side1, (0,6), side1) - composite.alpha_over(img, side2, (12,6), side2) - composite.alpha_over(img, top, (0,0), top) return (img.convert("RGB"), img.split()[3]) @@ -1135,16 +1122,20 @@ def generate_special_texture(blockID, data): if blockID in (86,91): # pumpkins, jack-o-lantern - top = transform_image(terrain_images[102]) + top = terrain_images[102] frontID = 119 if blockID == 86 else 120 - side1 = transform_image_side(terrain_images[frontID]) - side2 = transform_image_side(terrain_images[118]).transpose(Image.FLIP_LEFT_RIGHT) + front = terrain_images[frontID] + side = terrain_images[118] - img = Image.new("RGBA", (24,24), (38,92,255,0)) + if data == 0: # pointing west + img = _build_full_block(top, None, None, side, front) + + elif data == 1: # pointing north + img = _build_full_block(top, None, None, front, side) + + else: # in any other direction the front can't be seen + img = _build_full_block(top, None, None, side, side) - composite.alpha_over(img, side1, (0,6), side1) - composite.alpha_over(img, side2, (12,6), side2) - composite.alpha_over(img, top, (0,0), top) return (img.convert("RGB"), img.split()[3]) @@ -1276,8 +1267,8 @@ special_map[53] = range(4) # wooden stairs, orientation special_map[55] = range(128) # redstone wire, all the possible combinations special_map[58] = (0,) # crafting table special_map[59] = range(8) # crops, grow from 0 to 7 -special_map[61] = range(6) # furnace, orientation (not implemented) -special_map[62] = range(6) # burning furnace, orientation (not implemented) +special_map[61] = range(6) # furnace, orientation +special_map[62] = range(6) # burning furnace, orientation special_map[64] = range(16) # wooden door, open/close and orientation special_map[65] = (2,3,4,5) # ladder, orientation special_map[66] = range(10) # minecrart tracks, orientation, slope @@ -1286,8 +1277,8 @@ special_map[71] = range(16) # iron door, open/close and orientation special_map[75] = (1,2,3,4,5) # off redstone torch, orientation special_map[76] = (1,2,3,4,5) # on redstone torch, orientation special_map[85] = range(17) # fences, all the possible combination -special_map[86] = range(5) # pumpkin, orientation (not implemented) -special_map[91] = range(5) # jack-o-lantern, orientation (not implemented) +special_map[86] = range(5) # pumpkin, orientation +special_map[91] = range(5) # jack-o-lantern, orientation special_map[92] = range(6) # cake! # grass and leaves are graysacle in terrain.png From d58da71f1d602c3b78a3aa00e20c900e7f96a9d9 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Sun, 1 May 2011 17:28:36 +0200 Subject: [PATCH 07/10] Fix bookshelve and jukebox tops. --- textures.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/textures.py b/textures.py index 422ba8d..ee439ea 100644 --- a/textures.py +++ b/textures.py @@ -348,13 +348,13 @@ 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, -1, -1, # Cloths are left out, sandstone (it has top, side, and bottom wich is ignored here), note block # 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, # Gold/iron blocks? Doublestep? TNT from above? + -1, -1, -1, -1, -1, 13, 12, 29, 28, 23, 22, -1, -1, 7, 8, 4, # Gold/iron blocks? Doublestep? TNT from above? # 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 36, 37, -1, -1, 65, -1, 25, -1, 98, 24, -1, -1, 86, -1, -1, -1, # Torch from above? leaving out fire. Redstone wire? Crops/furnaces handled elsewhere. sign post # 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 -1, -1, -1, -1, -1, -1, -1, -1, -1, 51, 51, -1, -1, -1, 66, 67, # door,ladder left out. Minecart rail orientation, redstone torches # 80 81 82 83 84 85 86 87 88 89 90 91 - 66, 69, 72, 73, 74, -1,102,103,104,105,-1, 102 # clay? + 66, 69, 72, 73, 75, -1,102,103,104,105,-1, 102 # clay? ] # NOTE: For non-block textures, the sideid is ignored, but can't be -1 From 24c1e0dfd5786cac68b78a67072ba1fe938a17ef Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Mon, 2 May 2011 00:06:40 +0200 Subject: [PATCH 08/10] Add single and double chests with orientation to the textures. Add some comments about textures using pseudo data. --- src/iterate.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++-- textures.py | 57 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 116 insertions(+), 9 deletions(-) diff --git a/src/iterate.c b/src/iterate.c index 71bd7e3..2c0f1da 100644 --- a/src/iterate.c +++ b/src/iterate.c @@ -207,9 +207,73 @@ generate_pseudo_data(RenderState *state, unsigned char ancilData) { if ((above_level_data & 0x08)) { /* draw top right going up redstonewire */ final_data = final_data | 0x10; } - return final_data; + return final_data; + + } else if (state-> block == 54) { /* chests */ + /* the top 2 bits are used to store the type of chest + * (single or double), the 2 bottom bits are used for + * orientation, look textures.py for more information. */ + + /* if placed alone chests always face west, return 0 to make a + * chest facing west */ + unsigned char chest_data = 0, air_data = 0, final_data = 0; + + /* search for chests */ + chest_data = check_adjacent_blocks(state, x, y, z, 54); + + /* search for air */ + air_data = check_adjacent_blocks(state, x, y, z, 0); + + if (chest_data == 1) { /* another chest in the east */ + final_data = final_data | 0x8; /* only can face to north or south */ + if ( (air_data & 0x2) == 2 ) { + final_data = final_data | 0x1; /* facing north */ + } else { + final_data = final_data | 0x3; /* facing south */ + } + + } else if (chest_data == 2) { /* in the north */ + final_data = final_data | 0x4; /* only can face to east or west */ + if ( !((air_data & 0x4) == 4) ) { /* 0 = west */ + final_data = final_data | 0x2; /* facing east */ + } + + } else if (chest_data == 4) { /*in the west */ + final_data = final_data | 0x4; + if ( (air_data & 0x2) == 2 ) { + final_data = final_data | 0x1; /* facing north */ + } else { + final_data = final_data | 0x3; /* facing south */ + } + + } else if (chest_data == 8) { /*in the south */ + final_data = final_data | 0x8; + if ( !((air_data & 0x4) == 4) ) { + final_data = final_data | 0x2; /* facing east */ + } + + } else if (chest_data == 0) { + /* Single chest, determine the orientation */ + if ( ((air_data & 0x8) == 0) && ((air_data & 0x2) == 2) ) { /* block in +x and no block in -x */ + final_data = final_data | 0x1; /* facing north */ + + } else if ( ((air_data & 0x2) == 0) && ((air_data & 0x8) == 8)) { + final_data = final_data | 0x3; + + } else if ( ((air_data & 0x4) == 0) && ((air_data & 0x1) == 1)) { + final_data = final_data | 0x2; + } /* else, facing west, value = 0 */ + + } else { + /* more than one adjacent chests! render as normal chest */ + return 0; + } + + return final_data; + } + return 0; } @@ -329,7 +393,7 @@ chunk_render(PyObject *self, PyObject *args) { PyObject *tmp; unsigned char ancilData = getArrayByte3D(blockdata_expanded, state.x, state.y, state.z); - if ((state.block == 85) || (state.block == 9) || (state.block == 55)) { + if ((state.block == 85) || (state.block == 9) || (state.block == 55) || (state.block == 54) ) { ancilData = generate_pseudo_data(&state, ancilData); } diff --git a/textures.py b/textures.py index ee439ea..2564a97 100644 --- a/textures.py +++ b/textures.py @@ -350,7 +350,7 @@ def _build_blockimages(): # 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, 4, # Gold/iron blocks? Doublestep? TNT from above? # 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 - 36, 37, -1, -1, 65, -1, 25, -1, 98, 24, -1, -1, 86, -1, -1, -1, # Torch from above? leaving out fire. Redstone wire? Crops/furnaces handled elsewhere. sign post + 36, 37, -1, -1, 65, -1, -1, -1, 98, 24, -1, -1, 86, -1, -1, -1, # Torch from above? leaving out fire. Redstone wire? Crops/furnaces handled elsewhere. sign post # 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 -1, -1, -1, -1, -1, -1, -1, -1, -1, 51, 51, -1, -1, -1, 66, 67, # door,ladder left out. Minecart rail orientation, redstone torches # 80 81 82 83 84 85 86 87 88 89 90 91 @@ -367,7 +367,7 @@ def _build_blockimages(): # 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, # 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 - 36, 37, -1, -1, 65, -1, 25,101, 98, 24, -1, -1, 86, -1, -1, -1, + 36, 37, -1, -1, 65, -1, -1,101, 98, 24, -1, -1, 86, -1, -1, -1, # 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 -1, -1, -1, -1, -1, -1, -1, -1, -1, 51, 51, -1, -1, -1, 66, 67, # 80 81 82 83 84 85 86 87 88 89 90 91 @@ -740,6 +740,48 @@ def generate_special_texture(blockID, data): return (img.convert("RGB"), img.split()[3]) + if blockID == 54: # chests + # First to bits of the pseudo data store if it's a single chest + # or it's a double chest, first half or second half. + # The to last bits store the orientation. + + top = terrain_images[25] + side = terrain_images[26] + + if data & 12 == 0: # single chest + front = terrain_images[27] + back = terrain_images[26] + + elif data & 12 == 4: # double, first half + front = terrain_images[41] + back = terrain_images[57] + + elif data & 12 == 8: # double, second half + front = terrain_images[42] + back = terrain_images[58] + + else: # just in case + front = terrain_images[25] + side = terrain_images[25] + back = terrain_images[25] + + if data & 3 == 0: # facing west + img = _build_full_block(top, None, None, side, front) + + elif data & 3 == 1: # north + img = _build_full_block(top, None, None, front, side) + + elif data & 3 == 2: # east + img = _build_full_block(top, None, None, side, back) + + elif data & 3 == 3: # south + img = _build_full_block(top, None, None, back, side) + + else: + img = _build_full_block(top, None, None, back, side) + + return (img.convert("RGB"), img.split()[3]) + if blockID == 55: # redstone wire @@ -1244,8 +1286,8 @@ def getBiomeData(worlddir, chunkX, chunkY): # please, if possible, keep the ascending order of blockid value) special_blocks = set([ 2, 6, 9, 17, 18, 23, 27, 28, 35, 43, 44, 50, 51, - 53, 55, 58, 59, 61, 62, 64, 65, 66, 67, 71, 75, 76, - 85, 86, 91, 92]) + 53, 54, 55, 58, 59, 61, 62, 64, 65, 66, 67, 71, 75, + 76, 85, 86, 91, 92]) # this is a map of special blockIDs to a list of all # possible values for ancillary data that it might have. @@ -1253,7 +1295,7 @@ special_blocks = set([ 2, 6, 9, 17, 18, 23, 27, 28, 35, 43, 44, 50, 51, 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. +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[23] = range(6) # dispensers, orientation special_map[27] = range(14) # powered rail, orientation/slope and powered/unpowered @@ -1264,7 +1306,8 @@ special_map[44] = range(4) # stone, sandstone, wooden and cobblestone slab special_map[50] = (1,2,3,4,5) # torch, position in the block special_map[51] = range(16) # fire, position in the block (not implemented) special_map[53] = range(4) # wooden stairs, orientation -special_map[55] = range(128) # redstone wire, all the possible combinations +special_map[54] = range(12) # chests, orientation and type (single or double), uses pseudo data +special_map[55] = range(128) # redstone wire, all the possible combinations, uses pseudo data special_map[58] = (0,) # crafting table special_map[59] = range(8) # crops, grow from 0 to 7 special_map[61] = range(6) # furnace, orientation @@ -1276,7 +1319,7 @@ special_map[67] = range(4) # cobblestone stairs, orientation special_map[71] = range(16) # iron door, open/close and orientation special_map[75] = (1,2,3,4,5) # off redstone torch, orientation special_map[76] = (1,2,3,4,5) # on redstone torch, orientation -special_map[85] = range(17) # fences, all the possible combination +special_map[85] = range(17) # fences, all the possible combination, uses pseudo data special_map[86] = range(5) # pumpkin, orientation special_map[91] = range(5) # jack-o-lantern, orientation special_map[92] = range(6) # cake! From c1e71f0fdad0ff20feeec1023f34bf456d7c5f9c Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Sun, 1 May 2011 19:42:27 -0400 Subject: [PATCH 09/10] grass now has snowy sides when covered in snow --- src/iterate.c | 9 +++++++-- src/rendermode-normal.c | 4 +++- textures.py | 20 +++++++++++++------- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/iterate.c b/src/iterate.c index 2c0f1da..1828409 100644 --- a/src/iterate.c +++ b/src/iterate.c @@ -155,7 +155,12 @@ generate_pseudo_data(RenderState *state, unsigned char ancilData) { int x = state->x, y = state->y, z = state->z; unsigned char data = 0; - if (state->block == 9) { /* water */ + if (state->block == 2) { /* grass */ + /* return 0x10 if grass is covered in snow */ + if (z < 127 && getArrayByte3D(state->blocks, x, y, z+1) == 78) + return 0x10; + 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 */ data = 16; @@ -393,7 +398,7 @@ chunk_render(PyObject *self, PyObject *args) { PyObject *tmp; unsigned char ancilData = getArrayByte3D(blockdata_expanded, state.x, state.y, state.z); - if ((state.block == 85) || (state.block == 9) || (state.block == 55) || (state.block == 54) ) { + if ((state.block == 85) || (state.block == 9) || (state.block == 55) || (state.block == 54) || (state.block == 2)) { ancilData = generate_pseudo_data(&state, ancilData); } diff --git a/src/rendermode-normal.c b/src/rendermode-normal.c index c656d2e..be14a92 100644 --- a/src/rendermode-normal.c +++ b/src/rendermode-normal.c @@ -138,7 +138,9 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject * switch (state->block) { case 2: - /* grass */ + /* grass -- skip for snowgrass */ + if (state->z < 127 && getArrayByte3D(state->blocks, state->x, state->y, state->z+1) == 78) + break; color = PySequence_GetItem(self->grasscolor, index); facemask = self->grass_texture; alpha_over(state->img, self->grass_texture, self->grass_texture, state->imgx, state->imgy, 0, 0); diff --git a/textures.py b/textures.py index 2564a97..1b9e3a1 100644 --- a/textures.py +++ b/textures.py @@ -429,9 +429,14 @@ def generate_special_texture(blockID, data): # all need to behandled here (and in chunkpy) if blockID == 2: # grass - img = _build_block(terrain_images[0], terrain_images[3], 2) - colored = tintTexture(biome_grass_texture, (115, 175, 71)) - composite.alpha_over(img, colored, (0, 0), colored) + # data & 0x10 means SNOW sides + side_img = terrain_images[3] + if data & 0x10: + side_img = terrain_images[68] + img = _build_block(terrain_images[0], side_img, 2) + 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]) @@ -1327,10 +1332,11 @@ special_map[92] = range(6) # cake! # grass and leaves are graysacle in terrain.png # we treat them as special so we can manually tint them # it is unknown how the specific tint (biomes) is calculated -special_map[2] = range(11) # grass, grass has not ancildata but is used - # in the mod WildGrass, and this small fix - # shows the map as expected, and is harmless - # for normal maps +# also, 0x10 means SNOW sides +special_map[2] = range(11) + [0x10,] # grass, grass has not ancildata but is + # used in the mod WildGrass, and this + # 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) From 4a82e749cadfc3a96b7202c77d708bb5de7d9050 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Mon, 2 May 2011 18:02:13 -0400 Subject: [PATCH 10/10] added imgquality config file option for setting JPG quality Original code by alexjurkiewicz, ported to new DTT code. This closes #83. --- overviewer.py | 5 +++-- quadtree.py | 10 +++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/overviewer.py b/overviewer.py index 115644f..c8e7500 100755 --- a/overviewer.py +++ b/overviewer.py @@ -96,7 +96,8 @@ def main(): parser.add_option("--chunklist", dest="chunklist", help="A file containing, on each line, a path to a chunkfile to update. Instead of scanning the world directory for chunks, it will just use this list. Normal caching rules still apply.") 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. NOTE: png will always be used as the intermediate image format.", configFileOnly=True ) + 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("--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) @@ -220,7 +221,7 @@ def main(): # create the quadtrees # TODO chunklist q = [] - qtree_args = {'depth' : options.zoom, 'imgformat' : imgformat, 'optimizeimg' : optimizeimg, 'bgcolor':bgcolor} + qtree_args = {'depth' : options.zoom, 'imgformat' : imgformat, 'imgquality' : options.imgquality, 'optimizeimg' : optimizeimg, 'bgcolor' : bgcolor} 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 6d5a567..688db93 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, optimizeimg=None, rendermode="normal"): + def __init__(self, worldobj, destdir, bgcolor, depth=None, tiledir=None, imgformat=None, imgquality=95, optimizeimg=None, rendermode="normal"): """Generates a quadtree from the world given into the given dest directory @@ -61,6 +61,7 @@ class QuadtreeGen(object): """ assert(imgformat) self.imgformat = imgformat + self.imgquality = imgquality self.optimizeimg = optimizeimg self.bgcolor = bgcolor self.rendermode = rendermode @@ -336,7 +337,7 @@ class QuadtreeGen(object): # Save it if self.imgformat == 'jpg': - img.save(imgpath, quality=95, subsampling=0) + img.save(imgpath, quality=self.imgquality, subsampling=0) else: # png img.save(imgpath) @@ -463,7 +464,10 @@ class QuadtreeGen(object): pass # Save them - tileimg.save(imgpath) + if self.imgformat == 'jpg': + tileimg.save(imgpath, quality=self.imgquality, subsampling=0) + else: # png + tileimg.save(imgpath) if self.optimizeimg: optimize_image(imgpath, self.imgformat, self.optimizeimg)