From c60180f7938efb2485b3a043abf451908a361c97 Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Mon, 22 Nov 2010 22:51:21 -0500 Subject: [PATCH] Biome data from Biome Extractor is now used if it is present. If the BIOMEEXTRACTOR data is not available, then non-biome aware tinting will be used Open biome data in binary mode (Windows requires this) --- chunk.py | 28 ++++++++++++++-------------- gmap.py | 7 ++++++- template.html | 10 +++++----- textures.py | 38 +++++++++++++++++++++++++++++--------- world.py | 3 ++- 5 files changed, 56 insertions(+), 30 deletions(-) diff --git a/chunk.py b/chunk.py index 4c360d2..7a2fd3d 100644 --- a/chunk.py +++ b/chunk.py @@ -496,7 +496,8 @@ class ChunkRenderer(object): tileEntities = get_tileentity_data(self.level) - biomeColorData = textures.prepareBiomeData(self.world.worlddir, + if self.world.useBiomeData: + biomeColorData = textures.prepareBiomeData(self.world.worlddir, self.chunkX, self.chunkY) # in the 8x8 block of biome data, what chunk is this?l startX = (self.chunkX - int(math.floor(self.chunkX/8)*8)) @@ -534,20 +535,19 @@ class ChunkRenderer(object): if not t: continue + + if self.world.useBiomeData: + if blockid == 2: #grass + index = biomeColorData[ ((startY*16)+y) * 128 + (startX*16) + x] + c = textures.grasscolor[index] - if blockid == 2: #grass - index = biomeColorData[ ((startY*16)+y) * 128 + (startX*16) + x] - c = textures.grasscolor[index] - - # only tint the top texture - t = textures.prepareGrassTexture(c) - elif blockid == 18: # leaves - index = biomeColorData[ ((startY*16)+y) * 128 + (startX*16) + x] - c = textures.foliagecolor[index] - #i = textures.tintTexture(t,c) - i = ImageOps.colorize(ImageOps.grayscale(t[0]), (0,0,0), c) - i.putalpha(t[1]) - t = (i, t[1]) + # only tint the top texture + t = textures.prepareGrassTexture(c) + elif blockid == 18: # leaves + index = biomeColorData[ ((startY*16)+y) * 128 + (startX*16) + x] + c = textures.foliagecolor[index] + + t = textures.prepareLeafTexture(c) diff --git a/gmap.py b/gmap.py index 43f37b0..512a25a 100755 --- a/gmap.py +++ b/gmap.py @@ -115,8 +115,13 @@ def main(): logging.info("Welcome to Minecraft Overviewer!") logging.debug("Current log level: {0}".format(logging.getLogger().level)) + + useBiomeData = os.path.exists(os.path.join(worlddir, 'EXTRACTEDBIOMES')) + if not useBiomeData: + logging.info("Notice: Not using biome data for tinting") + # First generate the world's chunk images - w = world.WorldRenderer(worlddir, cachedir, chunklist=chunklist, lighting=options.lighting, night=options.night) + w = world.WorldRenderer(worlddir, cachedir, chunklist=chunklist, lighting=options.lighting, night=options.night, useBiomeData=useBiomeData) w.go(options.procs) # Now generate the tiles diff --git a/template.html b/template.html index b804ae2..99b33ca 100644 --- a/template.html +++ b/template.html @@ -16,7 +16,7 @@ defaultZoom: 1, maxZoom: {maxzoom}, cacheMinutes: 0, // Change this to have browsers automatically request new images every x minutes - debug: true + debug: false }; // our custom projection maps Latitude to Y, and Longitude to X as normal, @@ -136,7 +136,7 @@ var markersInit = false; function prepareSignMarker(marker, item) { - + var c = "

" + item.msg.replace(/\n/g,"
") + "

"; var infowindow = new google.maps.InfoWindow({ content: c @@ -149,7 +149,7 @@ google.maps.event.addListener(marker, 'click', function() { function initMarkers() { if (markersInit) { return; } - + markersInit = true; for (i in markerData) { @@ -157,7 +157,7 @@ google.maps.event.addListener(marker, 'click', function() { // a default: var iconURL = ''; - + if (item.type == 'spawn') { iconURL = 'http://google-maps-icons.googlecode.com/files/home.png';} if (item.type == 'sign') { iconURL = 'signpost_icon.png';} @@ -165,7 +165,7 @@ google.maps.event.addListener(marker, 'click', function() { var marker = new google.maps.Marker({ position: converted, map: map, - title: item.msg, + title: item.msg, icon: iconURL }); diff --git a/textures.py b/textures.py index aecc1dd..e8cb391 100644 --- a/textures.py +++ b/textures.py @@ -498,7 +498,7 @@ def generate_special_texture(blockID, data): return (img.convert("RGB"), img.split()[3]) if blockID == 2: # grass - top = transform_image(tintTexture(terrain_images[0],(170,255,50))) + top = transform_image(tintTexture(terrain_images[0],(115,175,71))) side1 = transform_image_side(terrain_images[3]) side2 = transform_image_side(terrain_images[3]).transpose(Image.FLIP_LEFT_RIGHT) @@ -510,7 +510,7 @@ def generate_special_texture(blockID, data): return (img.convert("RGB"), img.split()[3]) if blockID == 18: # leaves - t = tintTexture(terrain_images[52], (170, 255, 50)) + t = tintTexture(terrain_images[52], (37, 118, 25)) top = transform_image(t) side1 = transform_image_side(t) side2 = transform_image_side(t).transpose(Image.FLIP_LEFT_RIGHT) @@ -542,9 +542,29 @@ def prepareGrassTexture(color): img.paste(top, (0,0), top) return (img.convert("RGB"), img.split()[3]) -# TODO be more intelligent about where to find these files -grasscolor = list(Image.open("grasscolor.png").getdata()) -foliagecolor = list(Image.open("foliagecolor.png").getdata()) + +def prepareLeafTexture(color): + t = tintTexture(terrain_images[52], color) + top = transform_image(t) + side1 = transform_image_side(t) + side2 = transform_image_side(t).transpose(Image.FLIP_LEFT_RIGHT) + + img = Image.new("RGBA", (24,24), (38,92,255,0)) + + img.paste(side1, (0,6), side1) + img.paste(side2, (12,6), side2) + img.paste(top, (0,0), top) + return (img.convert("RGB"), img.split()[3]) + +#useBiomeData = os.path.exists(os.path.join(self.world, EXTRACTEDBIOMES)) +#if not useBiomeData: +# logging.info("Notice: Not using biome data for tinting") + +try: + grasscolor = list(Image.open(_find_file("grasscolor.png")).getdata()) + foliagecolor = list(Image.open(_find_file("foliagecolor.png")).getdata()) +except: + pass currentBiomeFile = None currentBiomeData = None @@ -566,7 +586,7 @@ def prepareBiomeData(worlddir, chunkX, chunkY): t.currentBiomeFile = biomeFile - f = open(os.path.join(worlddir, "EXTRACTEDBIOMES", biomeFile)) + f = open(os.path.join(worlddir, "EXTRACTEDBIOMES", biomeFile), "rb") rawdata = f.read() f.close() @@ -577,7 +597,7 @@ def prepareBiomeData(worlddir, chunkX, chunkY): # This set holds block ids that require special pre-computing. These are typically # things that require ancillary data to render properly (i.e. ladder plus orientation) -special_blocks = set([66,59,61,62, 65,64,71,91,86]) +special_blocks = set([66,59,61,62, 65,64,71,91,86,2,18]) # this is a map of special blockIDs to a list of all # possible values for ancillary data that it might have. @@ -594,8 +614,8 @@ special_map[86] = range(5) # pumpkin # apparently pumpkins and jack-o-lanterns have ancillary data, but it's unknown # what that data represents. For now, assume that the range for data is 0 to 5 # like torches -#special_map[2] = (0,) # grass -#special_map[18] = range(16) # leaves +special_map[2] = (0,) # grass +special_map[18] = range(16) # leaves # grass and leaves are now 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 diff --git a/world.py b/world.py index 8d94164..770c5ef 100644 --- a/world.py +++ b/world.py @@ -94,12 +94,13 @@ class WorldRenderer(object): files to update. If it includes a trailing newline, it is stripped, so you can pass in file handles just fine. """ - def __init__(self, worlddir, cachedir, chunklist=None, lighting=False, night=False): + def __init__(self, worlddir, cachedir, chunklist=None, lighting=False, night=False, useBiomeData=False): self.worlddir = worlddir self.caves = False self.lighting = lighting or night self.night = night self.cachedir = cachedir + self.useBiomeData = useBiomeData self.chunklist = chunklist