From f4636520dd04548d7a583b6577bb4d24785ec70a Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Sun, 10 Jul 2011 19:40:05 -0400 Subject: [PATCH 01/26] Added new check_terrain command --- overviewer_core/textures.py | 7 ++++++- setup.py | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/overviewer_core/textures.py b/overviewer_core/textures.py index f1da1b2..4a1f407 100644 --- a/overviewer_core/textures.py +++ b/overviewer_core/textures.py @@ -28,7 +28,7 @@ import util import composite _find_file_local_path = None -def _find_file(filename, mode="rb"): +def _find_file(filename, mode="rb", verbose=False): """Searches for the given file and returns an open handle to it. This searches the following locations in this order: @@ -47,11 +47,13 @@ def _find_file(filename, mode="rb"): if _find_file_local_path: path = os.path.join(_find_file_local_path, filename) if os.path.exists(path): + if verbose: print "Found %s in '%s'" % (filename, path) return open(path, mode) programdir = util.get_program_path() path = os.path.join(programdir, filename) if os.path.exists(path): + if verbose: print "Found %s in '%s'" % (filename, path) return open(path, mode) path = os.path.join(programdir, "overviewer_core", "data", "textures", filename) @@ -61,11 +63,13 @@ def _find_file(filename, mode="rb"): # windows special case, when the package dir doesn't exist path = os.path.join(programdir, "textures", filename) if os.path.exists(path): + if verbose: print "Found %s in '%s'" % (filename, path) return open(path, mode) if sys.platform == "darwin": path = os.path.join("/Applications/Minecraft", filename) if os.path.exists(path): + if verbose: print "Found %s in '%s'" % (filename, path) return open(path, mode) # Find minecraft.jar. @@ -85,6 +89,7 @@ def _find_file(filename, mode="rb"): if os.path.exists(jarpath): try: jar = zipfile.ZipFile(jarpath) + if verbose: print "Found %s in '%s'" % (filename, jarpath) return jar.open(filename) except (KeyError, IOError): pass diff --git a/setup.py b/setup.py index d21e1be..52d7a50 100755 --- a/setup.py +++ b/setup.py @@ -6,6 +6,7 @@ from distutils.command.build import build from distutils.command.clean import clean from distutils.command.build_ext import build_ext from distutils.command.sdist import sdist +from distutils.cmd import Command from distutils.dir_util import remove_tree from distutils.sysconfig import get_python_inc from distutils import log @@ -232,11 +233,32 @@ class CustomBuildExt(build_ext): self.inplace = True build_ext.build_extensions(self) +class CheckTerrain(Command): + user_options=[] + def initialize_options(self): + pass + def finalize_options(self): + pass + def run(self): + from overviewer_core.textures import _find_file + import hashlib + import zipfile + print "checking..." + try: + f = _find_file("terrain.png", verbose=True) + except IOError: + log.error("Could not find the file terrain.png") + return + + h = hashlib.sha1() + h.update(f.read()) + log.info("Hash of terrain.png file is: %s", h.hexdigest()) setup_kwargs['cmdclass']['clean'] = CustomClean setup_kwargs['cmdclass']['sdist'] = CustomSDist setup_kwargs['cmdclass']['build'] = CustomBuild setup_kwargs['cmdclass']['build_ext'] = CustomBuildExt +setup_kwargs['cmdclass']['check_terrain'] = CheckTerrain ### setup(**setup_kwargs) From af63ff9992380e9005daea861982b8a616694df4 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Tue, 12 Jul 2011 18:39:49 -0400 Subject: [PATCH 02/26] fixed recursive web_assets handling (closes issue #430) --- MANIFEST.in | 4 ++-- setup.py | 31 ++++++++++++++++++++++--------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index fe84bcb..ecc747a 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -4,6 +4,6 @@ include CONTRIBUTORS.rst include overviewer.py include sample.settings.py recursive-include contrib/ *.py -recursive-include overviewer_core/*.py +recursive-include overviewer_core/ *.py recursive-include overviewer_core/src/ *.c *.h -recursive-include overviewer_core/data/ *.png *.js index.html style.css +recursive-include overviewer_core/data/ * diff --git a/setup.py b/setup.py index 52d7a50..74a4408 100755 --- a/setup.py +++ b/setup.py @@ -75,6 +75,17 @@ def recursive_data_files(src, dest=None): ret.append((current_dest, current_sources)) return ret +# helper to create a 'package_data'-type sequence recursively for a given dir +def recursive_package_data(src, package_dir='overviewer_core'): + full_src = os.path.join(package_dir, src) + ret = [] + for dirpath, dirnames, filenames in os.walk(full_src, topdown=False): + current_path = os.path.relpath(dirpath, package_dir) + for filename in filenames: + ret.append(os.path.join(current_path, filename)) + + return ret + # # py2exe options # @@ -106,9 +117,8 @@ if py2app is not None: setup_kwargs['packages'] = ['overviewer_core'] setup_kwargs['scripts'] = ['overviewer.py'] -setup_kwargs['package_data'] = {'overviewer_core': - ['data/textures/*', - 'data/web_assets/*']} +setup_kwargs['package_data'] = {'overviewer_core': recursive_package_data('data/textures') + recursive_package_data('data/web_assets')} + if py2exe is None: setup_kwargs['data_files'] = [('share/doc/minecraft-overviewer', doc_files)] @@ -176,12 +186,15 @@ class CustomClean(clean): pretty_fname) versionpath = os.path.join("overviewer_core", "overviewer_version.py") - try: - if not self.dry_run: - os.remove(versionpath) - log.info("removing '%s'", versionpath) - except OSError: - log.warn("'%s' could not be cleaned -- permission denied", versionpath) + if os.path.exists(versionpath): + try: + if not self.dry_run: + os.remove(versionpath) + log.info("removing '%s'", versionpath) + except OSError: + log.warn("'%s' could not be cleaned -- permission denied", versionpath) + else: + log.debug("'%s' does not exist -- can't clean it", versionpath) # now try to purge all *.pyc files for root, dirs, files in os.walk(os.path.join(os.path.dirname(__file__), ".")): From 173e66245759375978eaccc08b4670f5934c0ce2 Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Thu, 14 Jul 2011 22:22:58 -0400 Subject: [PATCH 03/26] Adding ?debug=1 to a map URL enables debug mode --- overviewer_core/data/web_assets/overviewer.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/overviewer_core/data/web_assets/overviewer.js b/overviewer_core/data/web_assets/overviewer.js index a97341c..7c7a960 100644 --- a/overviewer_core/data/web_assets/overviewer.js +++ b/overviewer_core/data/web_assets/overviewer.js @@ -166,6 +166,9 @@ var overviewer = { var zoom = overviewerConfig.map.defaultZoom; var mapcenter; var queryParams = overviewer.util.parseQueryString(); + if (queryParams.debug) { + overviewerConfig.map.debug=true; + } if (queryParams.lat) { lat = parseFloat(queryParams.lat); } From cbd48fa2eb6561b61387399cbede46cb86815ba1 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Thu, 14 Jul 2011 22:52:13 -0400 Subject: [PATCH 04/26] fixed typo in setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 74a4408..e105bf6 100755 --- a/setup.py +++ b/setup.py @@ -217,7 +217,7 @@ def generate_version_py(): f.write(outstr) f.close() except: - print "WARNING: failed to build overview_version file" + print "WARNING: failed to build overviewer_version file" class CustomSDist(sdist): def run(self): From f7015396ab1b030127e66642ef14a7d8b11fe63d Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Thu, 14 Jul 2011 23:07:32 -0400 Subject: [PATCH 05/26] added options to overviewerConfig.js for search box, coords box, overlay menu --- overviewer_core/data/web_assets/overviewer.js | 17 ++++++++++++----- .../data/web_assets/overviewerConfig.js | 13 +++++++++++-- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/overviewer_core/data/web_assets/overviewer.js b/overviewer_core/data/web_assets/overviewer.js index 7c7a960..78eda41 100644 --- a/overviewer_core/data/web_assets/overviewer.js +++ b/overviewer_core/data/web_assets/overviewer.js @@ -58,7 +58,6 @@ var overviewer = { overviewer.util.initializeMarkers(); overviewer.util.initializeRegions(); overviewer.util.createMapControls(); - overviewer.util.createSearchBox(); }, /** * This adds some methods to these classes because Javascript is stupid @@ -620,7 +619,10 @@ var overviewer = { var coordsDiv = document.createElement('DIV'); coordsDiv.id = 'coordsDiv'; coordsDiv.innerHTML = ''; - overviewer.map.controls[google.maps.ControlPosition.BOTTOM_LEFT].push(coordsDiv); + if (overviewerConfig.map.controls.coordsBox) { + 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()); @@ -687,7 +689,7 @@ var overviewer = { overviewer.util.createDropDown('Regions', items); } - if (overviewer.collections.overlays.length > 0) { + if (overviewerConfig.map.controls.overlays && overviewer.collections.overlays.length > 0) { // overlay maps control var items = []; for (i in overviewer.collections.overlays) { @@ -715,6 +717,9 @@ var overviewer = { } overviewer.util.createDropDown('Overlays', items); } + + // call out to create search box, as it's pretty complicated + overviewer.util.createSearchBox(); }, /** * Reusable method for creating drop-down menus @@ -835,8 +840,10 @@ var overviewer = { $(searchDropDown).fadeOut(); } }); - - overviewer.map.controls[google.maps.ControlPosition.TOP_RIGHT].push(searchControl); + + if (overviewerConfig.map.controls.searchBox) { + overviewer.map.controls[google.maps.ControlPosition.TOP_RIGHT].push(searchControl); + } }, /** * Create the pop-up infobox for when you click on a region, this can't diff --git a/overviewer_core/data/web_assets/overviewerConfig.js b/overviewer_core/data/web_assets/overviewerConfig.js index ce38479..9363bf9 100644 --- a/overviewer_core/data/web_assets/overviewerConfig.js +++ b/overviewer_core/data/web_assets/overviewerConfig.js @@ -50,9 +50,18 @@ var overviewerConfig = { */ 'mapType': true, /** - * The small box at the bottom that displays the link to the current map view. + * The coordsBox control is the box showing the XYZ coordinates + * under the cursor. */ - 'link': true + 'coordsBox': true, + /** + * The overlays control is the drop-down box for selecting overlays. + */ + 'overlays': true, + /** + * The searchBox control is the search box for markers. + */ + 'searchBox': true }, /** * The zoom level when the page is loaded without a specific zoom setting From c5ba5edbcc47666026666d9c87405c15b7afa59f Mon Sep 17 00:00:00 2001 From: Xon Date: Fri, 15 Jul 2011 21:50:18 +0800 Subject: [PATCH 06/26] Permit overviewer to keep running even if the chunk the spawn is in is corrupt. --- overviewer_core/world.py | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/overviewer_core/world.py b/overviewer_core/world.py index 1344d10..fbd61a9 100644 --- a/overviewer_core/world.py +++ b/overviewer_core/world.py @@ -209,25 +209,27 @@ class World(object): chunkX = spawnX/16 chunkY = spawnZ/16 - ## The filename of this chunk - chunkFile = self.get_region_path(chunkX, chunkY) - - 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)) + try: + ## The filename of this chunk + chunkFile = self.get_region_path(chunkX, chunkY) + 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) + ## 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 - + ## find the first air block + while (blockArray[inChunkX, inChunkZ, spawnY] != 0): + spawnY += 1 + if spawnY == 128: + break + except ChunkCorrupt: + #ignore corrupt spawn, and continue + pass self.POI.append( dict(x=spawnX, y=spawnY, z=spawnZ, msg="Spawn", type="spawn", chunk=(chunkX, chunkY))) self.spawn = (spawnX, spawnY, spawnZ) From a83a0826599558c3247fdcb7417bb7612b4cb1b7 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Fri, 8 Jul 2011 00:44:18 +0200 Subject: [PATCH 07/26] Add code in textures.py to resize textures in blockmap and special_blocks. --- overviewer_core/textures.py | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/overviewer_core/textures.py b/overviewer_core/textures.py index 4a1f407..7eb6aae 100644 --- a/overviewer_core/textures.py +++ b/overviewer_core/textures.py @@ -1675,9 +1675,10 @@ biome_tall_fern_texture = None biome_leaf_texture = None specialblockmap = None -def generate(path=None): - global _find_file_local_path +def generate(path=None,texture_size=24): + global _find_file_local_path, texture_dimensions _find_file_local_path = path + texture_dimensions = (texture_size, texture_size) # This maps terainids to 16x16 images global terrain_images @@ -1701,3 +1702,24 @@ def generate(path=None): for blockID in special_blocks: for data in special_map[blockID]: specialblockmap[(blockID, data)] = generate_special_texture(blockID, data) + + if texture_size != 24: + # rescale the normal block images + for i in range(len(blockmap)): + if blockmap[i] != None: + block = blockmap[i] + alpha = block[1] + block = block[0] + block.putalpha(alpha) + scaled_block = block.resize(texture_dimensions, Image.ANTIALIAS) + blockmap[i] = generate_texture_tuple(scaled_block, i) + + # rescale the special block images + for blockid, data in iter(specialblockmap): + block = specialblockmap[(blockid,data)] + if block != None: + alpha = block[1] + block = block[0] + block.putalpha(alpha) + scaled_block = block.resize(texture_dimensions, Image.ANTIALIAS) + specialblockmap[(blockid,data)] = generate_texture_tuple(scaled_block, blockid) From 8bb19ee388bf1e59dabab2139a9c553e50f17e45 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Fri, 8 Jul 2011 01:16:55 +0200 Subject: [PATCH 08/26] Forget about tall grass... resize them too. --- overviewer_core/textures.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/overviewer_core/textures.py b/overviewer_core/textures.py index 7eb6aae..fa0d864 100644 --- a/overviewer_core/textures.py +++ b/overviewer_core/textures.py @@ -1675,7 +1675,7 @@ biome_tall_fern_texture = None biome_leaf_texture = None specialblockmap = None -def generate(path=None,texture_size=24): +def generate(path=None,texture_size=10): global _find_file_local_path, texture_dimensions _find_file_local_path = path texture_dimensions = (texture_size, texture_size) @@ -1704,6 +1704,12 @@ def generate(path=None,texture_size=24): specialblockmap[(blockID, data)] = generate_special_texture(blockID, data) if texture_size != 24: + # rescale biome textures. + biome_grass_texture = biome_grass_texture.resize(texture_dimensions, Image.ANTIALIAS) + biome_leaf_texture = biome_leaf_texture.resize(texture_dimensions, Image.ANTIALIAS) + biome_tall_grass_texture = biome_tall_grass_texture.resize(texture_dimensions, Image.ANTIALIAS) + biome_tall_fern_texture = biome_tall_fern_texture.resize(texture_dimensions, Image.ANTIALIAS) + # rescale the normal block images for i in range(len(blockmap)): if blockmap[i] != None: From b17f51404bc824e2b80d656f44c242dbd6efdb15 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Fri, 8 Jul 2011 01:20:30 +0200 Subject: [PATCH 09/26] oops... --- overviewer_core/textures.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/overviewer_core/textures.py b/overviewer_core/textures.py index fa0d864..6c01da3 100644 --- a/overviewer_core/textures.py +++ b/overviewer_core/textures.py @@ -1675,7 +1675,7 @@ biome_tall_fern_texture = None biome_leaf_texture = None specialblockmap = None -def generate(path=None,texture_size=10): +def generate(path=None,texture_size=24): global _find_file_local_path, texture_dimensions _find_file_local_path = path texture_dimensions = (texture_size, texture_size) From 641e9f5c18e7f27490308028e173191e098cb035 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Sun, 17 Jul 2011 01:15:23 +0200 Subject: [PATCH 10/26] Update function generate_full_block, fix problems with beds, cakes, and trapdoors. --- overviewer_core/textures.py | 48 ++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/overviewer_core/textures.py b/overviewer_core/textures.py index 6c01da3..86baf24 100644 --- a/overviewer_core/textures.py +++ b/overviewer_core/textures.py @@ -326,34 +326,34 @@ def _build_full_block(top, side1, side2, side3, side4, bottom=None, blockID=None A non transparent block uses top, side 3 and side 4. - If top is a tuple then first member is the top image and the second - member is an increment (integer) from 0 to 12. This increment will - used to crop the side images to look like a block and to paste all - the images increment pixels lower. Using increment = 6 will create - a half-block. + If top is a tuple then first item is the top image and the second + item is an increment (integer) from 0 to 16 (pixels in the + original minecraft texture). This increment will be used to crop the + side images and to paste the top image increment pixels lower, so if + you use an increment of 8, it willll draw a half-block. - NOTE: this method uses the top of the texture image (as done in - minecraft with beds) + NOTE: this method uses the bottom of the texture image (as done in + minecraft with beds and cackes) """ increment = 0 if isinstance(top, tuple): - increment = top[1] - crop_height = int(increment * 16./12.) + increment = math.floor((top[1] / 16.)*12.) # range increment in the block height in pixels (half texture size) + crop_height = increment top = top[0] if side1 != None: side1 = side1.copy() - ImageDraw.Draw(side1).rectangle((0, 16 - crop_height,16,16),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(side1).rectangle((0, 0,16,crop_height),outline=(0,0,0,0),fill=(0,0,0,0)) if side2 != None: side2 = side2.copy() - ImageDraw.Draw(side2).rectangle((0, 16 - crop_height,16,16),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(side2).rectangle((0, 0,16,crop_height),outline=(0,0,0,0),fill=(0,0,0,0)) if side3 != None: side3 = side3.copy() - ImageDraw.Draw(side3).rectangle((0, 16 - crop_height,16,16),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(side3).rectangle((0, 0,16,crop_height),outline=(0,0,0,0),fill=(0,0,0,0)) if side4 != None: side4 = side4.copy() - ImageDraw.Draw(side4).rectangle((0, 16 - crop_height,16,16),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(side4).rectangle((0, 0,16,crop_height),outline=(0,0,0,0),fill=(0,0,0,0)) img = Image.new("RGBA", (24,24), (38,92,255,0)) @@ -367,7 +367,7 @@ def _build_full_block(top, side1, side2, side3, side4, bottom=None, blockID=None side1 = ImageEnhance.Brightness(side1).enhance(0.9) side1.putalpha(sidealpha) - composite.alpha_over(img, side1, (0,0 + increment), side1) + composite.alpha_over(img, side1, (0,0), side1) if side2 != None : @@ -378,7 +378,7 @@ def _build_full_block(top, side1, side2, side3, side4, bottom=None, blockID=None side2 = ImageEnhance.Brightness(side2).enhance(0.8) side2.putalpha(sidealpha2) - composite.alpha_over(img, side2, (12,0 + increment), side2) + composite.alpha_over(img, side2, (12,0), side2) if bottom != None : bottom = transform_image(bottom, blockID) @@ -393,7 +393,7 @@ def _build_full_block(top, side1, side2, side3, side4, bottom=None, blockID=None side3 = ImageEnhance.Brightness(side3).enhance(0.9) side3.putalpha(sidealpha) - composite.alpha_over(img, side3, (0,6 + increment), side3) + composite.alpha_over(img, side3, (0,6), side3) if side4 != None : side4 = transform_image_side(side4, blockID) @@ -404,7 +404,7 @@ def _build_full_block(top, side1, side2, side3, side4, bottom=None, blockID=None side4 = ImageEnhance.Brightness(side4).enhance(0.8) side4.putalpha(sidealpha) - composite.alpha_over(img, side4, (12,6 + increment), side4) + composite.alpha_over(img, side4, (12,6), side4) if top != None : top = transform_image(top, blockID) @@ -605,7 +605,7 @@ def generate_special_texture(blockID, data): if blockID == 26: # bed - increment = 5 + increment = 8 left_face = None right_face = None if data & 0x8 == 0x8: # head of the bed @@ -1393,21 +1393,21 @@ def generate_special_texture(blockID, data): img = Image.new("RGBA", (24,24), (38,92,255,0)) - composite.alpha_over(img, side, (1,12), side) - composite.alpha_over(img, otherside, (11,13), otherside) # workaround, fixes a hole - composite.alpha_over(img, otherside, (12,12), otherside) + composite.alpha_over(img, side, (1,6), side) + composite.alpha_over(img, otherside, (11,7), otherside) # workaround, fixes a hole + composite.alpha_over(img, otherside, (12,6), otherside) composite.alpha_over(img, top, (0,6), top) return generate_texture_tuple(img, blockID) - if blockID in (93, 94): # redstone repeaters, ON and OFF + if blockID in (93, 94): # redstone repeaters (diodes), ON and OFF # NOTE: this function uses the redstone torches generated above, # this must run after the function of the torches. top = terrain_images[131] if blockID == 93 else terrain_images[147] side = terrain_images[5] - increment = 9 + increment = 13 if (data & 0x3) == 0: # pointing east pass @@ -1532,7 +1532,7 @@ def generate_special_texture(blockID, data): 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) + img = _build_full_block((texture, 12), None, None, texture, texture) return generate_texture_tuple(img, blockID) From 340f847f8c8d0d5ba42159a116998620661c48cf Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Sun, 17 Jul 2011 01:31:47 +0200 Subject: [PATCH 11/26] composite expects an int --- overviewer_core/textures.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/overviewer_core/textures.py b/overviewer_core/textures.py index 86baf24..0f12a70 100644 --- a/overviewer_core/textures.py +++ b/overviewer_core/textures.py @@ -339,7 +339,7 @@ def _build_full_block(top, side1, side2, side3, side4, bottom=None, blockID=None increment = 0 if isinstance(top, tuple): - increment = math.floor((top[1] / 16.)*12.) # range increment in the block height in pixels (half texture size) + increment = int(math.floor((top[1] / 16.)*12.)) # range increment in the block height in pixels (half texture size) crop_height = increment top = top[0] if side1 != None: From ef6ad9608021d8a91e547f04adae91e291006d79 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Fri, 22 Jul 2011 08:19:18 -0400 Subject: [PATCH 12/26] fixed region group handling to actually use matcher, and to show non-matched regions --- overviewer_core/data/web_assets/overviewer.js | 91 +++++++++++-------- 1 file changed, 54 insertions(+), 37 deletions(-) diff --git a/overviewer_core/data/web_assets/overviewer.js b/overviewer_core/data/web_assets/overviewer.js index 78eda41..5bc06f0 100644 --- a/overviewer_core/data/web_assets/overviewer.js +++ b/overviewer_core/data/web_assets/overviewer.js @@ -394,59 +394,76 @@ var overviewer = { point.x, point.y, point.z)); } + + if (region.label) { + var name = region.label; + } else { + var name = "rawr"; + } + + if(region.opacity) { + var strokeOpacity = region.opacity; + var fillOpacity = region.opacity * 0.25; + } else { + var strokeOpacity = region.strokeOpacity; + var fillOpacity = region.fillOpacity; + } + + var shapeOptions = { + 'name': name, + 'geodesic': false, + 'map': null, + 'strokeColor': region.color, + 'strokeOpacity': strokeOpacity, + 'strokeWeight': overviewerConfig.CONST.regionStrokeWeight, + 'zIndex': j + }; + if (region.closed) { + shapeOptions["fillColor"] = region.color; + shapeOptions["fillOpacity"] = fillOpacity; + shapeOptions["paths"] = converted; + } else { + shapeOptions["path"] = converted; + } + + var matched = false; + for (k in overviewerConfig.objectGroups.regions) { var regionGroup = overviewerConfig.objectGroups.regions[k]; var clickable = regionGroup.clickable; var label = regionGroup.label; - - if(region.label) { - var name = region.label - } else { - var name = 'rawr'; + + if (!regionGroup.match(region)) + continue; + matched = true; + + if (!region.label) { clickable = false; // if it doesn't have a name, we dont have to show it. } - if(region.opacity) { - var strokeOpacity = region.opacity; - var fillOpacity = region.opacity * 0.25; + if (region.closed) { + var shape = new google.maps.Polygon(shapeOptions); } else { - var strokeOpacity = region.strokeOpacity; - var fillOpacity = region.fillOpacity; + var shape = new google.maps.Polyline(shapeOptions); } - if (region.closed) { - var shape = new google.maps.Polygon({ - 'name': name, - 'clickable': clickable, - 'geodesic': false, - 'map': null, - 'strokeColor': region.color, - 'strokeOpacity': strokeOpacity, - 'strokeWeight': overviewerConfig.CONST.regionStrokeWeight, - 'fillColor': region.color, - 'fillOpacity': fillOpacity, - 'zIndex': j, - 'paths': converted - }); - } else { - var shape = new google.maps.Polyline({ - 'name': name, - 'clickable': clickable, - 'geodesic': false, - 'map': null, - 'strokeColor': region.color, - 'strokeOpacity': strokeOpacity, - 'strokeWeight': overviewerConfig.CONST.regionStrokeWeight, - 'zIndex': j, - 'path': converted - }); - } overviewer.collections.regions[label].push(shape); if (clickable) { overviewer.util.createRegionInfoWindow(shape); } } + + // if we haven't matched anything, go ahead and add it + if (!matched) { + if (region.closed) { + var shape = new google.maps.Polygon(shapeOptions); + } else { + var shape = new google.maps.Polyline(shapeOptions); + } + + shape.setMap(overviewer.map); + } } } }, From 85a55c25c3fd4a286398b96e7e111f32485bcb05 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Mon, 25 Jul 2011 11:05:21 -0400 Subject: [PATCH 13/26] more helpful error if given worlddir does not contain level.dat --- overviewer.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/overviewer.py b/overviewer.py index 29502aa..f86a83d 100755 --- a/overviewer.py +++ b/overviewer.py @@ -176,6 +176,11 @@ def main(): parser.print_help() logging.error("Invalid world number") sys.exit(1) + + # final sanity check for worlddir + if not os.path.exists(os.path.join(worlddir, 'level.dat')): + logging.error("Invalid world path -- does not contain level.dat") + sys.exit(1) if len(args) < 2: if options.delete: From 2f3f358d8472bd88e9fae1ced9051717937e8a60 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Tue, 26 Jul 2011 00:13:48 +0200 Subject: [PATCH 14/26] Add pistons to textures.py --- overviewer_core/chunk.py | 8 +- overviewer_core/textures.py | 149 +++++++++++++++++++++++++++++++++--- 2 files changed, 144 insertions(+), 13 deletions(-) diff --git a/overviewer_core/chunk.py b/overviewer_core/chunk.py index f8aa1f6..dad71e4 100644 --- a/overviewer_core/chunk.py +++ b/overviewer_core/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, 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, 96]) +transparent_blocks = set([ 0, 6, 8, 9, 18, 20, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 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, 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/overviewer_core/textures.py b/overviewer_core/textures.py index 0f12a70..fb15001 100644 --- a/overviewer_core/textures.py +++ b/overviewer_core/textures.py @@ -339,7 +339,7 @@ def _build_full_block(top, side1, side2, side3, side4, bottom=None, blockID=None increment = 0 if isinstance(top, tuple): - increment = int(math.floor((top[1] / 16.)*12.)) # range increment in the block height in pixels (half texture size) + increment = int(round((top[1] / 16.)*12.)) # range increment in the block height in pixels (half texture size) crop_height = increment top = top[0] if side1 != None: @@ -382,7 +382,7 @@ def _build_full_block(top, side1, side2, side3, side4, bottom=None, blockID=None if bottom != None : bottom = transform_image(bottom, blockID) - composite.alpha_over(img, bottom, (0,12), top) + composite.alpha_over(img, bottom, (0,12), bottom) # front sides if side3 != None : @@ -649,6 +649,7 @@ 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] @@ -661,8 +662,134 @@ def generate_special_texture(blockID, data): img = _build_block(texture, texture, blockID) return generate_texture_tuple(img,31) + + + if blockID in (29,33): # sticky and normal body piston. + if blockID == 29: # sticky + piston_t = terrain_images[106].copy() + else: # normal + piston_t = terrain_images[107].copy() + # other textures + side_t = terrain_images[108].copy() + back_t = terrain_images[109].copy() + interior_t = terrain_images[110].copy() + + if data & 0x08 == 0x08: # pushed out, non full blocks, tricky stuff + # remove piston texture from piston body + ImageDraw.Draw(side_t).rectangle((0, 0,16,3),outline=(0,0,0,0),fill=(0,0,0,0)) + if data & 0x07 == 0x0: # down + side_t = side_t.rotate(180) + img = _build_full_block(back_t ,None ,None ,side_t, side_t) + + elif data & 0x07 == 0x1: # up + img = _build_full_block((interior_t, 4) ,None ,None ,side_t, side_t) + + elif data & 0x07 == 0x2: # east + img = _build_full_block(side_t , None, None ,side_t.rotate(90), back_t) + + elif data & 0x07 == 0x3: # west + img = _build_full_block(side_t.rotate(180) ,None ,None ,side_t.rotate(270), None) + temp = transform_image_side(interior_t, blockID) + temp = temp.transpose(Image.FLIP_LEFT_RIGHT) + composite.alpha_over(img, temp, (9,5), temp) + + elif data & 0x07 == 0x4: # north + img = _build_full_block(side_t.rotate(90) ,None ,None , None, side_t.rotate(270)) + temp = transform_image_side(interior_t, blockID) + composite.alpha_over(img, temp, (3,5), temp) + + elif data & 0x07 == 0x5: # south + img = _build_full_block(side_t.rotate(270) ,None , None ,back_t, side_t.rotate(90)) + + else: # pushed in, normal full blocks, easy stuff + if data & 0x07 == 0x0: # down + side_t = side_t.rotate(180) + img = _build_full_block(back_t ,None ,None ,side_t, side_t) + elif data & 0x07 == 0x1: # up + img = _build_full_block(piston_t ,None ,None ,side_t, side_t) + elif data & 0x07 == 0x2: # east + img = _build_full_block(side_t ,None ,None ,side_t.rotate(90), back_t) + elif data & 0x07 == 0x3: # west + img = _build_full_block(side_t.rotate(180) ,None ,None ,side_t.rotate(270), piston_t) + elif data & 0x07 == 0x4: # north + img = _build_full_block(side_t.rotate(90) ,None ,None ,piston_t, side_t.rotate(270)) + elif data & 0x07 == 0x5: # south + img = _build_full_block(side_t.rotate(270) ,None ,None ,back_t, side_t.rotate(90)) + + + return generate_texture_tuple(img, blockID) + + + if blockID == 34: # piston extension (sticky and normal) + if (data & 0x8) == 0x8: # sticky + piston_t = terrain_images[106].copy() + else: # normal + piston_t = terrain_images[107].copy() + + # other textures + side_t = terrain_images[108].copy() + back_t = terrain_images[107].copy() + # crop piston body + ImageDraw.Draw(side_t).rectangle((0, 4,16,16),outline=(0,0,0,0),fill=(0,0,0,0)) + + # generate the horizontal piston extension stick + h_stick = Image.new("RGBA", (24,24), (38,92,255,0)) + temp = transform_image_side(side_t, blockID) + composite.alpha_over(h_stick, temp, (1,7), temp) + temp = transform_image(side_t.rotate(90)) + composite.alpha_over(h_stick, temp, (1,1), temp) + # Darken it + sidealpha = h_stick.split()[3] + h_stick = ImageEnhance.Brightness(h_stick).enhance(0.85) + h_stick.putalpha(sidealpha) + + # generate the vertical piston extension stick + v_stick = Image.new("RGBA", (24,24), (38,92,255,0)) + temp = transform_image_side(side_t.rotate(90), blockID) + composite.alpha_over(v_stick, temp, (12,6), temp) + temp = temp.transpose(Image.FLIP_LEFT_RIGHT) + composite.alpha_over(v_stick, temp, (1,6), temp) + # Darken it + sidealpha = v_stick.split()[3] + v_stick = ImageEnhance.Brightness(v_stick).enhance(0.85) + v_stick.putalpha(sidealpha) + + # Piston orientation is stored in the 3 first bits + if data & 0x07 == 0x0: # down + side_t = side_t.rotate(180) + img = _build_full_block((back_t, 12) ,None ,None ,side_t, side_t) + composite.alpha_over(img, v_stick, (0,-3), v_stick) + elif data & 0x07 == 0x1: # up + img = Image.new("RGBA", (24,24), (38,92,255,0)) + img2 = _build_full_block(piston_t ,None ,None ,side_t, side_t) + composite.alpha_over(img, v_stick, (0,4), v_stick) + composite.alpha_over(img, img2, (0,0), img2) + elif data & 0x07 == 0x2: # east + img = _build_full_block(side_t ,None ,None ,side_t.rotate(90), None) + temp = transform_image_side(back_t, blockID).transpose(Image.FLIP_LEFT_RIGHT) + composite.alpha_over(img, temp, (2,2), temp) + composite.alpha_over(img, h_stick, (6,3), h_stick) + elif data & 0x07 == 0x3: # west + img = Image.new("RGBA", (24,24), (38,92,255,0)) + img2 = _build_full_block(side_t.rotate(180) ,None ,None ,side_t.rotate(270), piston_t) + composite.alpha_over(img, h_stick, (0,0), h_stick) + composite.alpha_over(img, img2, (0,0), img2) + elif data & 0x07 == 0x4: # north + img = _build_full_block(side_t.rotate(90) ,None ,None , piston_t, side_t.rotate(270)) + composite.alpha_over(img, h_stick.transpose(Image.FLIP_LEFT_RIGHT), (0,0), h_stick.transpose(Image.FLIP_LEFT_RIGHT)) + elif data & 0x07 == 0x5: # south + img = Image.new("RGBA", (24,24), (38,92,255,0)) + img2 = _build_full_block(side_t.rotate(270) ,None ,None ,None, side_t.rotate(90)) + temp = transform_image_side(back_t, blockID) + composite.alpha_over(img2, temp, (10,2), temp) + composite.alpha_over(img, img2, (0,0), img2) + composite.alpha_over(img, h_stick.transpose(Image.FLIP_LEFT_RIGHT), (-3,2), h_stick.transpose(Image.FLIP_LEFT_RIGHT)) + + return generate_texture_tuple(img, blockID) + + if blockID == 35: # wool if data == 0: # white top = side = terrain_images[64] @@ -1081,7 +1208,7 @@ def generate_special_texture(blockID, data): # mask out the high bits to figure out the orientation img = Image.new("RGBA", (24,24), (38,92,255,0)) - if (data & 0x03) == 0: + if (data & 0x03) == 0: # northeast corner if not swung: tex = transform_image_side(raw_door) composite.alpha_over(img, tex, (0,6), tex) @@ -1091,7 +1218,7 @@ def generate_special_texture(blockID, data): tex = tex.transpose(Image.FLIP_LEFT_RIGHT) composite.alpha_over(img, tex, (0,0), tex) - if (data & 0x03) == 1: + if (data & 0x03) == 1: # southeast corner if not swung: tex = transform_image_side(raw_door).transpose(Image.FLIP_LEFT_RIGHT) composite.alpha_over(img, tex, (0,0), tex) @@ -1099,7 +1226,7 @@ def generate_special_texture(blockID, data): tex = transform_image_side(raw_door) composite.alpha_over(img, tex, (12,0), tex) - if (data & 0x03) == 2: + if (data & 0x03) == 2: # southwest corner if not swung: tex = transform_image_side(raw_door.transpose(Image.FLIP_LEFT_RIGHT)) composite.alpha_over(img, tex, (12,0), tex) @@ -1107,7 +1234,7 @@ def generate_special_texture(blockID, data): tex = transform_image_side(raw_door).transpose(Image.FLIP_LEFT_RIGHT) composite.alpha_over(img, tex, (12,6), tex) - if (data & 0x03) == 3: + if (data & 0x03) == 3: # northwest corner if not swung: tex = transform_image_side(raw_door.transpose(Image.FLIP_LEFT_RIGHT)).transpose(Image.FLIP_LEFT_RIGHT) composite.alpha_over(img, tex, (12,6), tex) @@ -1609,9 +1736,10 @@ 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, 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, 96]) +special_blocks = set([ 2, 6, 9, 17, 18, 26, 23, 27, 28, 29, 31, 33, 34, + 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, 96]) # this is a map of special blockIDs to a list of all # possible values for ancillary data that it might have. @@ -1625,6 +1753,9 @@ 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 special_map[28] = range(6) # detector rail, orientation/slope +special_map[29] = (0,1,2,3,4,5,8,9,10,11,12,13) # sticky piston body, orientation, pushed in/out +special_map[33] = (0,1,2,3,4,5,8,9,10,11,12,13) # normal piston body, orientation, pushed in/out +special_map[34] = (0,1,2,3,4,5,8,9,10,11,12,13) # normal and sticky piston extension, orientation, sticky/normal special_map[35] = range(16) # wool, colored and white special_map[43] = range(4) # stone, sandstone, wooden and cobblestone double-slab special_map[44] = range(4) # stone, sandstone, wooden and cobblestone slab From bef7f62e4377a588d4faa78a8511c4e0afa83675 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Tue, 26 Jul 2011 00:55:32 +0200 Subject: [PATCH 15/26] Now glass renders as in game (glass is rendered in the same way as water is) --- overviewer_core/src/iterate.c | 17 +++++++++++++---- overviewer_core/textures.py | 33 ++++++++++++++++++--------------- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/overviewer_core/src/iterate.c b/overviewer_core/src/iterate.c index 29d1219..6a77ccf 100644 --- a/overviewer_core/src/iterate.c +++ b/overviewer_core/src/iterate.c @@ -174,12 +174,18 @@ generate_pseudo_data(RenderState *state, unsigned char ancilData) { data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f); return data; } - - + } else if (state->block == 20) { /* glass */ + /* an aditional bit for top is added to the 4 bits of check_adjacent_blocks */ + if ((z != 127) && (getArrayByte3D(state->blocks, x, y, z+1) == 20)) { + data = 0; + } else { + data = 16; + } + data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f) | data; + return data; } else if (state->block == 85) { /* fences */ return check_adjacent_blocks(state, x, y, z, state->block); - } else if (state->block == 55) { /* redstone */ /* three addiotional bit are added, one for on/off state, and * another two for going-up redstone wire in the same block @@ -402,7 +408,10 @@ chunk_render(PyObject *self, PyObject *args) { PyObject *tmp; 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)) { + if ((state.block == 2) || (state.block == 9) || + (state.block == 20) || (state.block == 54) || + (state.block == 55) || (state.block == 85) || + (state.block == 90)) { ancilData = generate_pseudo_data(&state, ancilData); } diff --git a/overviewer_core/textures.py b/overviewer_core/textures.py index fb15001..f7d4dfb 100644 --- a/overviewer_core/textures.py +++ b/overviewer_core/textures.py @@ -425,7 +425,7 @@ def _build_blockimages(): # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 topids = [ -1, 1, 0, 2, 16, 4, -1, 17,205,205,237,237, 18, 19, 32, 33, # 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, + 34, -1, 52, 48, -1,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 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 @@ -442,7 +442,7 @@ def _build_blockimages(): # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 sideids = [ -1, 1, 3, 2, 16, 4, -1, 17,205,205,237,237, 18, 19, 32, 33, # 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, + 34, -1, 52, 48, -1,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 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 @@ -553,33 +553,35 @@ def generate_special_texture(blockID, data): return generate_texture_tuple(img, blockID) - if blockID == 9: # spring water, flowing water and waterfall water - - watertexture = _load_image("water.png") + if blockID == 9 or blockID == 20: # spring water, flowing water and waterfall water, AND glass + # water and glass share the way to be rendered + if blockID == 9: + texture = _load_image("water.png") + else: + texture = terrain_images[49] if (data & 0b10000) == 16: - top = watertexture + top = texture else: top = None if (data & 0b0001) == 1: - side1 = watertexture # top left + side1 = texture # top left else: side1 = None if (data & 0b1000) == 8: - side2 = watertexture # top right + side2 = texture # top right else: side2 = None if (data & 0b0010) == 2: - side3 = watertexture # bottom left + side3 = texture # bottom left else: side3 = None if (data & 0b0100) == 4: - side4 = watertexture # bottom right + side4 = texture # bottom right else: side4 = None img = _build_full_block(top,None,None,side3,side4) - return generate_texture_tuple(img, blockID) @@ -1736,10 +1738,10 @@ 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, 29, 31, 33, 34, - 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, 96]) +special_blocks = set([ 2, 6, 9, 17, 18, 20, 26, 23, 27, 28, 29, 31, 33, + 34, 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, 96]) # this is a map of special blockIDs to a list of all # possible values for ancillary data that it might have. @@ -1749,6 +1751,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(3) # wood: normal, birch and pine +special_map[20] = range(32) # glass, used to only render the exterior surface, uses pseudo data 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 aecb39bbbc2b34100683decac76ffb592ef73d41 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Tue, 26 Jul 2011 00:57:12 +0200 Subject: [PATCH 16/26] Delete generate_pseudo_ancil_data function from chunk.py --- overviewer_core/chunk.py | 61 ---------------------------------------- 1 file changed, 61 deletions(-) diff --git a/overviewer_core/chunk.py b/overviewer_core/chunk.py index dad71e4..6a3344b 100644 --- a/overviewer_core/chunk.py +++ b/overviewer_core/chunk.py @@ -321,67 +321,6 @@ class ChunkRenderer(object): return self._up_left_skylight up_left_skylight = property(_load_up_left_skylight) - def generate_pseudo_ancildata(self,x,y,z,blockid, north_position = 0 ): - """ Generates a pseudo ancillary data for blocks that depend of - what are surrounded and don't have ancillary data - - This uses a binary number of 4 digits to encode the info. - The encode is: - - Bit: 1 2 3 4 - Side: x y -x -y - Values: bit = 0 -> The corresponding side block has different blockid - bit = 1 -> The corresponding side block has same blockid - Example: if the bit1 is 1 that means that there is a block with - blockid in the side of the +x direction. - - You can rotate the pseudo data multiplying by 2 and - if it is > 15 subtracting 15 and adding 1. (moving bits - in the left direction is like rotate 90 degree in anticlockwise - direction). In this way can be used for maps with other - north orientation. - - North position can have the values 0, 1, 2, 3, corresponding to - north in bottom-left, bottom-right, top-right and top-left of - the screen. - - The rotation feature is not used anywhere yet. - """ - - blocks = self.blocks - up_left_blocks = self.up_left_blocks - up_right_blocks = self.up_right_blocks - left_blocks = self.left_blocks - right_blocks = self.right_blocks - - pseudo_data = 0 - - # first check if we are in the border of a chunk, next check for chunks adjacent to this - # and finally check for a block with same blockid. I we aren't in the border of a chunk, - # check for the block having the sme blockid. - - if (up_right_blocks is not None and up_right_blocks[0,y,z] == blockid) if x == 15 else blocks[x+1,y,z] == blockid: - pseudo_data = pseudo_data | 0b1000 - - if (right_blocks is not None and right_blocks[x,0,z] == blockid) if y == 15 else blocks[x,y + 1,z] == blockid: - pseudo_data = pseudo_data | 0b0100 - - if (left_blocks is not None and left_blocks[15,y,z] == blockid) if x == 0 else blocks[x - 1,y,z] == blockid: - pseudo_data = pseudo_data | 0b0010 - - if (up_left_blocks is not None and up_left_blocks[x,15,z] == blockid) if y == 0 else blocks[x,y - 1,z] == blockid: - pseudo_data = pseudo_data | 0b0001 - - # rotate the bits for other north orientations - while north_position > 0: - pseudo_data *= 2 - if pseudo_data > 15: - pseudo_data -= 16 - pseudo_data +=1 - north_position -= 1 - - return pseudo_data - def chunk_render(self, img=None, xoff=0, yoff=0, cave=False): """Renders a chunk with the given parameters, and returns the image. If img is given, the chunk is rendered to that image object. Otherwise, From 154cd2c1fdf5e0bb623ac881d04281ff985919f8 Mon Sep 17 00:00:00 2001 From: but2002 Date: Fri, 29 Jul 2011 17:23:33 -0500 Subject: [PATCH 17/26] The "querypos" marker that appears when linked to a location on the map will be removable by a click. --- overviewer_core/data/web_assets/overviewer.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/overviewer_core/data/web_assets/overviewer.js b/overviewer_core/data/web_assets/overviewer.js index 5bc06f0..e450746 100644 --- a/overviewer_core/data/web_assets/overviewer.js +++ b/overviewer_core/data/web_assets/overviewer.js @@ -313,6 +313,9 @@ var overviewer = { 'title': jQuery.trim(item.msg), 'icon': overviewerConfig.CONST.image.queryMarker }); + google.maps.event.addListener(marker, 'click', function(){ marker.setVisible(false); }); + + continue; } From ebd3497a5f210f9a8c2df0db3b54655caaf5b4eb Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Sun, 31 Jul 2011 12:27:53 -0400 Subject: [PATCH 18/26] made forcerender and regionlist work together (closes #444) --- overviewer_core/quadtree.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/overviewer_core/quadtree.py b/overviewer_core/quadtree.py index fc00b01..d82f262 100644 --- a/overviewer_core/quadtree.py +++ b/overviewer_core/quadtree.py @@ -426,21 +426,20 @@ 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 os.path.abspath(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) + 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 From 30a8b851b609906218ab2b4dfdaaff722f6b0c31 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Sun, 31 Jul 2011 12:38:19 -0400 Subject: [PATCH 19/26] added separate 'zoomLevels' JS config var for marker positioning use (closes #401) --- overviewer_core/data/web_assets/overviewer.js | 16 ++++++++-------- .../data/web_assets/overviewerConfig.js | 6 ++++++ overviewer_core/googlemap.py | 2 ++ overviewer_core/quadtree.py | 2 +- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/overviewer_core/data/web_assets/overviewer.js b/overviewer_core/data/web_assets/overviewer.js index e450746..c5083fc 100644 --- a/overviewer_core/data/web_assets/overviewer.js +++ b/overviewer_core/data/web_assets/overviewer.js @@ -534,7 +534,7 @@ var overviewer = { // the width and height of all the highest-zoom tiles combined, // inverted var perPixel = 1.0 / (overviewerConfig.CONST.tileSize * - Math.pow(2, overviewerConfig.map.maxZoom)); + Math.pow(2, overviewerConfig.map.zoomLevels)); // This information about where the center column is may change with // a different drawing implementation -- check it again after any @@ -542,13 +542,13 @@ var overviewer = { // point (0, 0, 127) is at (0.5, 0.0) of tile (tiles/2 - 1, tiles/2) // so the Y coordinate is at 0.5, and the X is at 0.5 - - // ((tileSize / 2) / (tileSize * 2^maxZoom)) - // or equivalently, 0.5 - (1 / 2^(maxZoom + 1)) - var lng = 0.5 - (1.0 / Math.pow(2, overviewerConfig.map.maxZoom + 1)); + // ((tileSize / 2) / (tileSize * 2^zoomLevels)) + // or equivalently, 0.5 - (1 / 2^(zoomLevels + 1)) + var lng = 0.5 - (1.0 / Math.pow(2, overviewerConfig.map.zoomLevels + 1)); var lat = 0.5; - // the following metrics mimic those in ChunkRenderer.chunk_render - // in "chunk.py" or, equivalently, chunk_render in src/iterate.c + // the following metrics mimic those in + // chunk_render in src/iterate.c // each block on X axis adds 12px to x and subtracts 6px from y lng += 12 * x * perPixel; @@ -586,11 +586,11 @@ var overviewer = { // the width and height of all the highest-zoom tiles combined, // inverted var perPixel = 1.0 / (overviewerConfig.CONST.tileSize * - Math.pow(2, overviewerConfig.map.maxZoom)); + Math.pow(2, overviewerConfig.map.zoomLevels)); // Revert base positioning // See equivalent code in fromWorldToLatLng() - lng -= 0.5 - (1.0 / Math.pow(2, overviewerConfig.map.maxZoom + 1)); + lng -= 0.5 - (1.0 / Math.pow(2, overviewerConfig.map.zoomLevels + 1)); lat -= 0.5; // I'll admit, I plugged this into Wolfram Alpha: diff --git a/overviewer_core/data/web_assets/overviewerConfig.js b/overviewer_core/data/web_assets/overviewerConfig.js index 9363bf9..bdb6015 100644 --- a/overviewer_core/data/web_assets/overviewerConfig.js +++ b/overviewer_core/data/web_assets/overviewerConfig.js @@ -75,6 +75,12 @@ var overviewerConfig = { * This controls how close you can zoom in. */ 'maxZoom': {maxzoom}, + /** + * This tells us how many total zoom levels Overviewer rendered. + * DO NOT change this, even if you change minZoom and maxZoom, because + * it's used for marker position calculations and map resizing. + */ + 'zoomLevels': {zoomlevels}, /** * Center on this point, in world coordinates. Should be an array, ex: * [0,0,0] diff --git a/overviewer_core/googlemap.py b/overviewer_core/googlemap.py index 7d4dc7e..3b2475e 100644 --- a/overviewer_core/googlemap.py +++ b/overviewer_core/googlemap.py @@ -114,6 +114,8 @@ class MapGen(object): "{minzoom}", str(0)) config = config.replace( "{maxzoom}", str(zoomlevel)) + config = config.replace( + "{zoomlevels}", str(zoomlevel)) config = config.replace("{spawn_coords}", json.dumps(list(self.world.spawn))) diff --git a/overviewer_core/quadtree.py b/overviewer_core/quadtree.py index d82f262..8acbefc 100644 --- a/overviewer_core/quadtree.py +++ b/overviewer_core/quadtree.py @@ -120,7 +120,7 @@ class QuadtreeGen(object): indexfile = os.path.join(self.destdir, "overviewerConfig.js") if not os.path.exists(indexfile): return -1 - matcher = re.compile(r"maxZoom.*:\s*(\d+)") + matcher = re.compile(r"zoomLevels(?:\'|\")\s*:\s*(\d+)") p = -1 for line in open(indexfile, "r"): res = matcher.search(line) From f36cb98911764cb3364bbf55a9fad238ff0dc4ce Mon Sep 17 00:00:00 2001 From: but2002 Date: Sun, 31 Jul 2011 17:37:59 -0500 Subject: [PATCH 20/26] Fixed undefined variable. --- overviewer_core/quadtree.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/overviewer_core/quadtree.py b/overviewer_core/quadtree.py index 8acbefc..d40e266 100644 --- a/overviewer_core/quadtree.py +++ b/overviewer_core/quadtree.py @@ -426,6 +426,11 @@ 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) + 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 @@ -434,11 +439,6 @@ class QuadtreeGen(object): if self.forcerender: needs_rerender = True break - - # check region file mtime first. - region, regionMtime = get_region_mtime(regionfile) - if regionMtime <= tile_mtime: - continue # checking chunk mtime if region.get_chunk_timestamp(chunkx, chunky) > tile_mtime: From 3ccb188a11be0d7b1127cca1bb0ce06de799cbc0 Mon Sep 17 00:00:00 2001 From: but2002 Date: Sun, 31 Jul 2011 17:39:56 -0500 Subject: [PATCH 21/26] Fixed an error in my original change, moved code to original location. --- overviewer_core/quadtree.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/overviewer_core/quadtree.py b/overviewer_core/quadtree.py index d40e266..5a8d880 100644 --- a/overviewer_core/quadtree.py +++ b/overviewer_core/quadtree.py @@ -426,10 +426,7 @@ 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) - if regionMtime <= tile_mtime: - continue + region, regionMtime = get_region_mtime(regionfile) # 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: @@ -439,6 +436,10 @@ class QuadtreeGen(object): if self.forcerender: needs_rerender = True break + + # check region file mtime first. + if regionMtime <= tile_mtime: + continue # checking chunk mtime if region.get_chunk_timestamp(chunkx, chunky) > tile_mtime: From 5e10ff1a3025a7e5fc0d43e407f612e5e38bc54f Mon Sep 17 00:00:00 2001 From: but2002 Date: Sun, 31 Jul 2011 17:41:57 -0500 Subject: [PATCH 22/26] Fixed indentation style to match the rest of the code. --- overviewer_core/quadtree.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/overviewer_core/quadtree.py b/overviewer_core/quadtree.py index 5a8d880..2e77576 100644 --- a/overviewer_core/quadtree.py +++ b/overviewer_core/quadtree.py @@ -426,7 +426,7 @@ class QuadtreeGen(object): needs_rerender = False get_region_mtime = world.get_region_mtime for col, row, chunkx, chunky, regionfile in chunks: - region, regionMtime = get_region_mtime(regionfile) + region, regionMtime = get_region_mtime(regionfile) # 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: From 142c621cc81e632ac5b193c5ee7aea2965e20cc3 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Sun, 31 Jul 2011 20:47:25 -0400 Subject: [PATCH 23/26] added but2002 to CONTRIBUTORS.rst --- CONTRIBUTORS.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index 30c5ffe..174ebe7 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -41,6 +41,7 @@ feature. * arrai * Kyle Brantley + * but2002 * Eric Carr * cbarber * Alex Cline From 69bb23b74c7c786478ae7288c2baec4ab2b3672f Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Sun, 31 Jul 2011 22:18:01 -0400 Subject: [PATCH 24/26] fixed tallgrass offsets affecting blocks above --- overviewer_core/src/rendermode-normal.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/overviewer_core/src/rendermode-normal.c b/overviewer_core/src/rendermode-normal.c index cee7431..c9f037a 100644 --- a/overviewer_core/src/rendermode-normal.c +++ b/overviewer_core/src/rendermode-normal.c @@ -125,7 +125,7 @@ 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; + int offx = 0, offy = 0; unsigned char data_byte; /* first, check to see if we should use biome-compatible src, mask */ @@ -133,11 +133,6 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject * 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; data_byte = getArrayByte3D(state->blockdata_expanded, state->x, state->y, state->z); if (data_byte == 1) { src = mask = self->tall_grass_texture; @@ -147,8 +142,14 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject * } } + if (state->block == 31) { + /* add a random offset to the postion of the tall grass to make it more wild */ + offx = rand() % 6 + 1 - 3; + offy = rand() % 6 + 1 - 3; + } + /* draw the block! */ - alpha_over(state->img, src, mask, state->imgx, state->imgy, 0, 0); + alpha_over(state->img, src, mask, state->imgx + offx, state->imgy + offy, 0, 0); if (self->biome_data) { /* do the biome stuff! */ @@ -166,7 +167,7 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject * 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); + alpha_over(state->img, self->grass_texture, self->grass_texture, state->imgx + offx, state->imgy + offy, 0, 0); break; case 18: /* leaves */ @@ -195,7 +196,7 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject * b = PyInt_AsLong(PyTuple_GET_ITEM(color, 2)); Py_DECREF(color); - tint_with_mask(state->img, r, g, b, 255, facemask, state->imgx, state->imgy, 0, 0); + tint_with_mask(state->img, r, g, b, 255, facemask, state->imgx + offx, state->imgy + offy, 0, 0); } } From 91b3010db31dbca735ee77dbfafb1247e5f7ab60 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Sun, 31 Jul 2011 22:28:28 -0400 Subject: [PATCH 25/26] fixed lighting bug introduced by tall grass fix --- overviewer_core/src/iterate.c | 17 ++++++++++++++++- overviewer_core/src/rendermode-normal.c | 13 +++---------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/overviewer_core/src/iterate.c b/overviewer_core/src/iterate.c index 6a77ccf..fbc3849 100644 --- a/overviewer_core/src/iterate.c +++ b/overviewer_core/src/iterate.c @@ -372,7 +372,7 @@ chunk_render(PyObject *self, PyObject *args) { for (state.z = 0; state.z < 128; state.z++) { state.imgy -= 12; - /* get blockid */ + /* get blockid */ state.block = getArrayByte3D(blocks_py, state.x, state.y, state.z); if (state.block == 0) { continue; @@ -430,14 +430,29 @@ chunk_render(PyObject *self, PyObject *args) { if (t != NULL && t != Py_None) { PyObject *src, *mask, *mask_light; + int randx = 0, randy = 0; src = PyTuple_GetItem(t, 0); mask = PyTuple_GetItem(t, 1); mask_light = PyTuple_GetItem(t, 2); if (mask == Py_None) mask = src; + + 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 += randx; + state.imgy += randy; + } rendermode->draw(rm_data, &state, src, mask, mask_light); + + if (state.block == 31) { + /* undo the random offsets */ + state.imgx -= randx; + state.imgy -= randy; + } } } diff --git a/overviewer_core/src/rendermode-normal.c b/overviewer_core/src/rendermode-normal.c index c9f037a..cbc2d49 100644 --- a/overviewer_core/src/rendermode-normal.c +++ b/overviewer_core/src/rendermode-normal.c @@ -125,7 +125,6 @@ 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 offx = 0, offy = 0; unsigned char data_byte; /* first, check to see if we should use biome-compatible src, mask */ @@ -142,14 +141,8 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject * } } - if (state->block == 31) { - /* add a random offset to the postion of the tall grass to make it more wild */ - offx = rand() % 6 + 1 - 3; - offy = rand() % 6 + 1 - 3; - } - /* draw the block! */ - alpha_over(state->img, src, mask, state->imgx + offx, state->imgy + offy, 0, 0); + alpha_over(state->img, src, mask, state->imgx, state->imgy, 0, 0); if (self->biome_data) { /* do the biome stuff! */ @@ -167,7 +160,7 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject * break; color = PySequence_GetItem(self->grasscolor, index); facemask = self->grass_texture; - alpha_over(state->img, self->grass_texture, self->grass_texture, state->imgx + offx, state->imgy + offy, 0, 0); + alpha_over(state->img, self->grass_texture, self->grass_texture, state->imgx, state->imgy, 0, 0); break; case 18: /* leaves */ @@ -196,7 +189,7 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject * b = PyInt_AsLong(PyTuple_GET_ITEM(color, 2)); Py_DECREF(color); - tint_with_mask(state->img, r, g, b, 255, facemask, state->imgx + offx, state->imgy + offy, 0, 0); + tint_with_mask(state->img, r, g, b, 255, facemask, state->imgx, state->imgy, 0, 0); } } From 6a5eb517d6104206cff9b135174c031a335ec4df Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Sun, 31 Jul 2011 22:33:49 -0400 Subject: [PATCH 26/26] tallgrass now appears in the same place, no matter what mode is used --- overviewer_core/src/iterate.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/overviewer_core/src/iterate.c b/overviewer_core/src/iterate.c index fbc3849..5639ae9 100644 --- a/overviewer_core/src/iterate.c +++ b/overviewer_core/src/iterate.c @@ -360,6 +360,10 @@ chunk_render(PyObject *self, PyObject *args) { up_right_blocks_py = PyObject_GetAttrString(state.self, "up_right_blocks"); state.up_right_blocks = up_right_blocks_py; + /* set up the random number generator again for each chunk + so tallgrass is in the same place, no matter what mode is used */ + srand(1); + for (state.x = 15; state.x > -1; state.x--) { for (state.y = 0; state.y < 16; state.y++) { PyObject *blockid = NULL;