diff --git a/overviewer.py b/overviewer.py index 74c5414..79550fe 100755 --- a/overviewer.py +++ b/overviewer.py @@ -96,6 +96,7 @@ def main(): cpus = 1 avail_rendermodes = c_overviewer.get_render_modes() + avail_north_dirs = ['lower-left', 'upper-left', 'upper-right', 'lower-right'] parser = ConfigOptionParser(usage=helptext, config="settings.py") parser.add_option("-V", "--version", dest="version", help="Displays version information and then exits", action="store_true") @@ -118,7 +119,7 @@ def main(): parser.add_option("--skip-js", dest="skipjs", action="store_true", help="Don't output marker.js or regions.js") parser.add_option("--no-signs", dest="nosigns", action="store_true", help="Don't output signs to markers.js") parser.add_option("--display-config", dest="display_config", action="store_true", help="Display the configuration parameters, but don't render the map. Requires all required options to be specified", commandLineOnly=True) - parser.add_option("--north-direction", dest="north_direction", help="Specifies which corner of the screen North will point to.", type="string", default="upper-right") + parser.add_option("--north-direction", dest="north_direction", help="Specifies which corner of the screen north will point to. Valid options are: " + ", ".join(avail_north_dirs) + ".", type="choice", default=avail_north_dirs[0], choices=avail_north_dirs) #parser.add_option("--write-config", dest="write_config", action="store_true", help="Writes out a sample config file", commandLineOnly=True) options, args = parser.parse_args() diff --git a/sample.settings.py b/sample.settings.py index e31cd1f..01fcf2b 100644 --- a/sample.settings.py +++ b/sample.settings.py @@ -155,6 +155,7 @@ if "web_assets_hook" in locals(): ################################################################################ ### north_direction ## Make north point somewhere else! +## Valid options are 'lower-left', 'upper-left', 'upper-right', 'upper-left' ## default: upper-right ## Type: string ## Example: diff --git a/textures.py b/textures.py index 61ea8af..97f8b51 100644 --- a/textures.py +++ b/textures.py @@ -505,7 +505,9 @@ def generate_special_texture(blockID, data, north_direction): #print "%s has ancillary data: %X" %(blockID, data) # TODO ladders, stairs, levers, buttons, and signs # all need to behandled here (and in chunkpy) - + + data = convert_data(blockID, data, north_direction) + if blockID == 2: # grass # data & 0x10 means SNOW sides side_img = terrain_images[3] @@ -594,11 +596,6 @@ def generate_special_texture(blockID, data, north_direction): if blockID == 26: # bed - if north_direction == 'upper-right': - if (data & 0x3) == 0: data = data & 0x8 | 0x2 - elif (data & 0x3) == 1: data = data & 0x8 | 0x3 - elif (data & 0x3) == 2: data = data & 0x8 | 0x0 - elif (data & 0x3) == 3: data = data & 0x8 | 0x1 increment = 5 left_face = None right_face = None @@ -713,12 +710,6 @@ def generate_special_texture(blockID, data, north_direction): if blockID in (50,75,76): # torch, off redstone torch, on redstone torch - if north_direction == 'upper-right': - if data == 1: data = 2 - elif data == 2: data = 1 - elif data == 3: data = 4 - elif data == 4: data = 3 - # choose the proper texture if blockID == 50: # torch small = terrain_images[80] @@ -787,11 +778,6 @@ def generate_special_texture(blockID, data, north_direction): if blockID in (53,67): # wooden and cobblestone stairs. - if north_direction == 'upper-right': - if data == 0: data = 1 - elif data == 1: data = 0 - elif data == 2: data = 3 - elif data == 3: data = 2 if blockID == 53: # wooden texture = terrain_images[4] @@ -1003,11 +989,6 @@ def generate_special_texture(blockID, data, north_direction): if blockID in (61, 62, 23): #furnace and burning furnace - if north_direction == 'upper-right': - if data == 2: data = 3 - elif data == 3: data = 2 - elif data == 4: data = 5 - elif data == 5: data = 4 top = terrain_images[62] side = terrain_images[45] @@ -1033,13 +1014,10 @@ def generate_special_texture(blockID, data, north_direction): if blockID == 63: # singposts - texture = terrain_images[4].copy() # cut the planks to the size of a signpost ImageDraw.Draw(texture).rectangle((0,12,15,15),outline=(0,0,0,0),fill=(0,0,0,0)) - if north_direction == 'upper-right': - data = (data + 8) % 16 # If the signpost is looking directly to the image, draw some # random dots, they will look as text. if data in (0,1,2,3,4,5,15): @@ -1092,11 +1070,6 @@ def generate_special_texture(blockID, data, north_direction): # mask out the high bits to figure out the orientation img = Image.new("RGBA", (24,24), (38,92,255,0)) - if north_direction == 'upper-right': - if (data & 0x3) == 0: data = data & 0xc | 0x2 - elif (data & 0x3) == 1: data = data & 0xc | 0x3 - elif (data & 0x3) == 2: data = data & 0xc | 0x0 - elif (data & 0x3) == 3: data = data & 0xc | 0x1 if (data & 0x03) == 0: if not swung: tex = transform_image_side(raw_door) @@ -1135,11 +1108,6 @@ def generate_special_texture(blockID, data, north_direction): if blockID == 65: # ladder - if north_direction == 'upper-right': - if data == 2: data = 3 - elif data == 3: data = 2 - elif data == 4: data = 5 - elif data == 5: data = 4 img = Image.new("RGBA", (24,24), (38,92,255,0)) raw_texture = terrain_images[83] #print "ladder is facing: %d" % data @@ -1186,17 +1154,6 @@ def generate_special_texture(blockID, data, north_direction): raw_straight = terrain_images[128] raw_corner = terrain_images[112] - if north_direction == 'upper-right': - if data == 2: data = 3 - elif data == 3: data = 2 - elif data == 4: data = 5 - elif data == 5: data = 4 - - elif data == 6: data = 8 - elif data == 7: data = 9 - elif data == 8: data = 6 - elif data == 9: data = 7 - ## use transform_image to scale and shear if data == 0: track = transform_image(raw_straight, blockID) @@ -1245,11 +1202,6 @@ def generate_special_texture(blockID, data, north_direction): if blockID == 68: # wall sign - if north_direction == 'upper-right': - if data == 2: data = 3 - elif data == 3: data = 2 - elif data == 4: data = 5 - elif data == 5: data = 4 texture = terrain_images[4].copy() # cut the planks to the size of a signpost ImageDraw.Draw(texture).rectangle((0,12,15,15),outline=(0,0,0,0),fill=(0,0,0,0)) @@ -1380,11 +1332,6 @@ def generate_special_texture(blockID, data, north_direction): if blockID in (86,91): # pumpkins, jack-o-lantern - if north_direction == 'upper-right': - if data == 0: data = 2 - elif data == 1: data = 3 - elif data == 2: data = 0 - elif data == 3: data = 1 top = terrain_images[102] frontID = 119 if blockID == 86 else 120 front = terrain_images[frontID] @@ -1446,11 +1393,6 @@ def generate_special_texture(blockID, data, north_direction): if blockID in (93, 94): # redstone repeaters, ON and OFF # NOTE: this function uses the redstone torches generated above, # this must run after the function of the torches. - if north_direction == 'upper-right': - if (data & 0x3) == 0: data = data & 0xc | 0x2 - elif (data & 0x3) == 1: data = data & 0xc | 0x3 - elif (data & 0x3) == 2: data = data & 0xc | 0x0 - elif (data & 0x3) == 3: data = data & 0xc | 0x1 top = terrain_images[131] if blockID == 93 else terrain_images[147] side = terrain_images[5] @@ -1567,11 +1509,6 @@ def generate_special_texture(blockID, data, north_direction): if blockID == 96: # trapdoor - if north_direction == 'upper-right': - if (data & 0x3) == 0: data = data & 0x4 | 0x1 - elif (data & 0x3) == 1: data = data & 0x4 | 0x0 - elif (data & 0x3) == 2: data = data & 0x4 | 0x3 - elif (data & 0x3) == 3: data = data & 0x4 | 0x2 texture = terrain_images[84] if data & 0x4 == 0x4: # opened trapdoor if data & 0x3 == 0: # west @@ -1588,9 +1525,94 @@ def generate_special_texture(blockID, data, north_direction): return generate_texture_tuple(img, blockID) - return None +def convert_data(blockID, data, north_direction): + if blockID == 26: # bed + if north_direction == 'upper-right': + #Masked to not clobber block head/foot info + if (data & 0b0011) == 0: data = data & 0b1100 | 2 + elif (data & 0b0011) == 1: data = data & 0b1100 | 3 + elif (data & 0b0011) == 2: data = data & 0b1100 | 0 + elif (data & 0b0011) == 3: data = data & 0b1100 | 1 + if blockID in (27, 28, 66): # minetrack: + if north_direction == 'upper-right': + #Masked to not clobber powered rail on/off info + #Ascending + if (data & 0b0111) == 2: data = data & 0b1000 | 3 + elif (data & 0b0111) == 3: data = data & 0b1000 | 2 + elif (data & 0b0111) == 4: data = data & 0b1000 | 5 + elif (data & 0b0111) == 5: data = data & 0b1000 | 4 + if blockID == 66: #normal minetrack only + if north_direction == 'upper-right': + #Corners + if data == 6: data = 8 + elif data == 7: data = 9 + elif data == 8: data = 6 + elif data == 9: data = 7 + if blockID in (50, 75, 76): # torch, off/on redstone torch + if north_direction == 'upper-right': + if data == 1: data = 2 + elif data == 2: data = 1 + elif data == 3: data = 4 + elif data == 4: data = 3 + if blockID in (53,67): # wooden and cobblestone stairs. + if north_direction == 'upper-right': + if data == 0: data = 1 + elif data == 1: data = 0 + elif data == 2: data = 3 + elif data == 3: data = 2 + if blockID in (61, 62, 23): # furnace and burning furnace + if north_direction == 'upper-right': + if data == 2: data = 3 + elif data == 3: data = 2 + elif data == 4: data = 5 + elif data == 5: data = 4 + if blockID == 63: # signposts + if north_direction == 'upper-right': + data = (data + 8) % 16 + if blockID in (64,71): # wooden door, or iron door + if north_direction == 'upper-right': + #Masked to not clobber block top/bottom & swung info + if (data & 0b0011) == 0: data = data & 0b1100 | 2 + elif (data & 0b0011) == 1: data = data & 0b1100 | 3 + elif (data & 0b0011) == 2: data = data & 0b1100 | 0 + elif (data & 0b0011) == 3: data = data & 0b1100 | 1 + if blockID == 65: # ladder + if north_direction == 'upper-right': + if data == 2: data = 3 + elif data == 3: data = 2 + elif data == 4: data = 5 + elif data == 5: data = 4 + if blockID == 68: # wall sign + if north_direction == 'upper-right': + if data == 2: data = 3 + elif data == 3: data = 2 + elif data == 4: data = 5 + elif data == 5: data = 4 + if blockID in (86,91): # pumpkins, jack-o-lantern + if north_direction == 'upper-right': + if data == 0: data = 2 + elif data == 1: data = 3 + elif data == 2: data = 0 + elif data == 3: data = 1 + if blockID in (93, 94): # redstone repeaters, ON and OFF + if north_direction == 'upper-right': + #Masked to not clobber delay info + if (data & 0b0011) == 0: data = data & 0b1100 | 2 + elif (data & 0b0011) == 1: data = data & 0b1100 | 3 + elif (data & 0b0011) == 2: data = data & 0b1100 | 0 + elif (data & 0b0011) == 3: data = data & 0b1100 | 1 + if blockID == 96: # trapdoor + if north_direction == 'upper-right': + #Masked to not clobber opened/closed info + if (data & 0b0011) == 0: data = data & 0b1100 | 1 + elif (data & 0b0011) == 1: data = data & 0b1100 | 0 + elif (data & 0b0011) == 2: data = data & 0b1100 | 3 + elif (data & 0b0011) == 3: data = data & 0b1100 | 2 + + return data + def tintTexture(im, c): # apparently converting to grayscale drops the alpha channel? i = ImageOps.colorize(ImageOps.grayscale(im), (0,0,0), c) diff --git a/web_assets/overviewer.js b/web_assets/overviewer.js index 08f85b2..424cdc4 100644 --- a/web_assets/overviewer.js +++ b/web_assets/overviewer.js @@ -492,20 +492,17 @@ var overviewer = { var perPixel = 1.0 / (overviewerConfig.CONST.tileSize * Math.pow(2, overviewerConfig.map.maxZoom)); - if(overviewerConfig.map.north_direction == 'lower-left'){ - x = x; - y = y; - } else if(overviewerConfig.map.north_direction == 'upper-right'){ - x = -x-1; - y = -y-1; + if(overviewerConfig.map.north_direction == 'upper-right'){ + x = -x-1+512; + y = -y-1+512; } else if(overviewerConfig.map.north_direction == 'upper-left'){ temp = x; - x = -y-1; - y = temp-16; + x = -y-1+512; + y = temp; } else if(overviewerConfig.map.north_direction == 'lower-right'){ temp = x; x = y; - y = -temp-1+16; + y = -temp-1+512; } // This information about where the center column is may change with @@ -517,13 +514,7 @@ var overviewer = { // ((tileSize / 2) / (tileSize * 2^maxZoom)) // or equivalently, 0.5 - (1 / 2^(maxZoom + 1)) lat = 0.5; - if(overviewerConfig.map.north_direction == 'lower-left' || - overviewerConfig.map.north_direction == 'lower-right'){ - lng = 0.5 - (1.0 / Math.pow(2, overviewerConfig.map.maxZoom + 1)); - } else{ - lng = 0.5 + (1.0 / Math.pow(2, overviewerConfig.map.maxZoom + 1)); - } - + lng = 0.5 - (1.0 / Math.pow(2, overviewerConfig.map.maxZoom + 1)); // the following metrics mimic those in ChunkRenderer.chunk_render // in "chunk.py" or, equivalently, chunk_render in src/iterate.c @@ -570,12 +561,7 @@ var overviewer = { // See equivalent code in fromWorldToLatLng() lat -= 0.5; - if(overviewerConfig.map.north_direction == 'lower-left' || - overviewerConfig.map.north_direction == 'lower-right'){ - lng -= 0.5 - (1.0 / Math.pow(2, overviewerConfig.map.maxZoom + 1)); - } else{ - lng -= 0.5 + (1.0 / Math.pow(2, overviewerConfig.map.maxZoom + 1)); - } + lng -= 0.5 - (1.0 / Math.pow(2, overviewerConfig.map.maxZoom + 1)); // I'll admit, I plugged this into Wolfram Alpha: // a = (x * 12 * r) + (z * 12 * r), b = (z * 6 * r) - (x * 6 * r) @@ -591,20 +577,17 @@ var overviewer = { point.x += 64; point.z -= 64; - if(overviewerConfig.map.north_direction == 'lower-left'){ - point.x = point.x; - point.z = point.z; - } else if(overviewerConfig.map.north_direction == 'upper-right'){ - point.x = -point.x; - point.z = -point.z; + if(overviewerConfig.map.north_direction == 'upper-right'){ + point.x = -point.x+512; + point.z = -point.z+512; } else if(overviewerConfig.map.north_direction == 'upper-left'){ temp = point.z; - point.z = -point.x; - point.x = temp+16; + point.z = -point.x+512; + point.x = temp; } else if(overviewerConfig.map.north_direction == 'lower-right'){ temp = point.z; point.z = point.x; - point.x = -temp+16; + point.x = -temp+512; } return point; diff --git a/world.py b/world.py index a53b823..b5ce5a0 100644 --- a/world.py +++ b/world.py @@ -189,7 +189,6 @@ class World(object): def unconvert_coords(self, col, row): """Undoes what convert_coords does. Returns (chunkx, chunky).""" - return ((col - row) / 2, (row + col) / 2) def findTrueSpawn(self): @@ -285,6 +284,7 @@ class World(object): world. Returns (regionx, regiony, filename)""" + join = os.path.join if regionlist is not None: for path in regionlist: @@ -293,7 +293,20 @@ class World(object): if f.startswith("r.") and f.endswith(".mcr"): p = f.split(".") logging.debug("Using path %s from regionlist", f) - yield (int(p[1]), int(p[2]), join(self.worlddir, 'region', f)) + x = int(p[1]) + y = int(p[2]) + if self.north_direction == 'upper-right': + x = -x + y = -y + elif self.north_direction == 'upper-left': + temp = x + x = -y + y = temp + elif self.north_direction == 'lower-right': + temp = x + x = y + y = -temp + yield (x, y, join(self.worlddir, 'region', f)) else: logging.warning("Ignore path '%s' in regionlist", f) @@ -301,7 +314,20 @@ class World(object): for path in glob(os.path.join(self.worlddir, 'region') + "/r.*.*.mcr"): dirpath, f = os.path.split(path) p = f.split(".") - yield (int(p[1]), int(p[2]), join(dirpath, f)) + x = int(p[1]) + y = int(p[2]) + if self.north_direction == 'upper-right': + x = -x + y = -y + elif self.north_direction == 'upper-left': + temp = x + x = -y + y = temp + elif self.north_direction == 'lower-right': + temp = x + x = y + y = -temp + yield (x, y, join(dirpath, f)) def get_save_dir(): """Returns the path to the local saves directory