From ad0e38f7bbbb7ea5f8380a7c58649833e4e2a55b Mon Sep 17 00:00:00 2001 From: Jeffrey Warren Date: Mon, 18 Apr 2011 09:44:10 -0400 Subject: [PATCH 01/36] live updating hashes instead of permalinks --- web_assets/functions.js | 23 ++++++++--------------- web_assets/style.css | 12 +++++++++--- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/web_assets/functions.js b/web_assets/functions.js index 96742af..19e3902 100644 --- a/web_assets/functions.js +++ b/web_assets/functions.js @@ -240,11 +240,7 @@ function initMarkers() { function makeLink() { - var a=location.href.substring(0,location.href.lastIndexOf(location.search)) - + "?lat=" + map.getCenter().lat().toFixed(6) - + "&lng=" + map.getCenter().lng().toFixed(6) - + "&zoom=" + map.getZoom(); - document.getElementById("link").innerHTML = a; + location.hash = "#/"+map.getCenter().lat().toFixed(3)+"/"+map.getCenter().lng().toFixed(3)+"/"+map.getZoom(); } function initialize() { @@ -254,17 +250,14 @@ function initialize() { var lat = 0.5; var lng = 0.5; var zoom = config.defaultZoom; - var pairs = query.split("&"); - for (var i=0; i 1) { + lat = parseFloat(params[1]) + lng = parseFloat(params[2]) + zoom = parseInt(params[3]) } var mapTyepControlToggle = false diff --git a/web_assets/style.css b/web_assets/style.css index e6029dc..e4e9f6e 100644 --- a/web_assets/style.css +++ b/web_assets/style.css @@ -1,7 +1,14 @@ -html { height: 100% } +html { + height: 100%; + font-family: lucida grande, lucida sans console, sans-serif; +} body { height: 100%; margin: 0px; padding: 0px ; background-color: #000; } #mcmap { height: 100% } +#mcmap div div a img, #mcmap div div div a { + display:none; +} + .infoWindow { height: 100px; } @@ -20,10 +27,10 @@ body { height: 100%; margin: 0px; padding: 0px ; background-color: #000; } #signControl { padding: 5px; height: 15px; - font-family: Arial, sans-serif; } #signControl > div#top { + display:none; background-color: #fff; border: 2px solid #000; text-align: center; @@ -44,7 +51,6 @@ body { height: 100%; margin: 0px; padding: 0px ; background-color: #000; } #link { background-color: #fff; /* fallback */ background-color: rgba(255,255,255,0.55); - border: 1px solid rgb(0, 0, 0); font-size: 9pt; padding-left: 2px; padding-right: 2px; From 4c07eb0c7aedda03e5f3f70d7e7f31fc35c96d8d Mon Sep 17 00:00:00 2001 From: Jeffrey Warren Date: Sat, 30 Apr 2011 15:08:29 -0400 Subject: [PATCH 02/36] live URL hash rewriting as you drag/zoom instead of permalink at bottom, hard named permalinks such as foo.com/#/jeffs-island --- web_assets/overviewer.css | 18 ++-------- web_assets/overviewer.js | 71 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 69 insertions(+), 20 deletions(-) diff --git a/web_assets/overviewer.css b/web_assets/overviewer.css index e29ec4f..6b5cff4 100644 --- a/web_assets/overviewer.css +++ b/web_assets/overviewer.css @@ -1,25 +1,13 @@ html { height: 100%; -<<<<<<< HEAD:web_assets/style.css font-family: lucida grande, lucida sans console, sans-serif; } body { height: 100%; margin: 0px; padding: 0px ; background-color: #000; } -#mcmap { height: 100% } -======= -} - -body { - height: 100%; - margin: 0px; - padding: 0px; - background-color: #000; -} #mcmap { width: 100%; height: 100%; } ->>>>>>> f20d81c39f0302a44e02a6f42f6eb0d13b9fcc18:web_assets/overviewer.css #mcmap div div a img, #mcmap div div div a { display:none; @@ -43,14 +31,13 @@ body { #customControl { padding: 5px; height: 15px; + display:none; } -<<<<<<< HEAD:web_assets/style.css #signControl > div#top { display:none; -======= +} #customControl > div#top { ->>>>>>> f20d81c39f0302a44e02a6f42f6eb0d13b9fcc18:web_assets/overviewer.css background-color: #fff; border: 2px solid #000; text-align: center; @@ -76,6 +63,7 @@ body { #link { + display:none; background-color: #fff; /* fallback */ background-color: rgba(255,255,255,0.55); font-size: 9pt; diff --git a/web_assets/overviewer.js b/web_assets/overviewer.js index f927625..ab2ad51 100644 --- a/web_assets/overviewer.js +++ b/web_assets/overviewer.js @@ -58,6 +58,7 @@ var overviewer = { overviewer.util.initializeMarkers(); overviewer.util.initializeRegions(); overviewer.util.createMapControls(); + setInterval(overviewer.goToHash,500); }, /** * This adds some methods to these classes because Javascript is stupid @@ -141,11 +142,14 @@ var overviewer = { var defaultCenter = overviewer.util.fromWorldToLatLng( overviewerConfig.map.center[0], overviewerConfig.map.center[1], overviewerConfig.map.center[2]); + var lat = defaultCenter.lat(); var lng = defaultCenter.lng(); var zoom = overviewerConfig.map.defaultZoom; + var mapcenter; queryParams = overviewer.util.parseQueryString(); + queryParams = overviewer.readHash(queryParams); if (queryParams.lat) { lat = parseFloat(queryParams.lat); } @@ -162,10 +166,10 @@ var overviewer = { if (zoom < 0 && zoom + overviewerConfig.map.maxZoom >= 0) { //if zoom is negative, try to treat as "zoom out from max zoom" zoom += overviewerConfig.map.maxZoom; - } else { + } //else { //fall back to default zoom - zoom = overviewerConfig.map.defaultZoom; - } + //zoom = overviewerConfig.map.defaultZoom; + //} } } if (queryParams.x && queryParams.y && queryParams.z) { @@ -234,6 +238,14 @@ var overviewer = { }); // We can now set the map to use the 'coordinate' map type overviewer.map.setMapTypeId(overviewer.util.getDefaultMapTypeId()); + + // Make the link again whenever the map changes + google.maps.event.addListener(overviewer.map, 'zoom_changed', function() { + overviewer.setHash(); + }); + google.maps.event.addListener(overviewer.map, 'center_changed', function() { + overviewer.setHash(); + }); }, /** * Read through overviewer.collections.markerDatas and create Marker @@ -301,7 +313,7 @@ var overviewer = { 'map': overviewer.map, 'title': jQuery.trim(item.msg), 'icon': iconURL, - 'visible': false + 'visible': true }); overviewer.util.debug(label); overviewer.collections.markers[label].push(marker); @@ -889,5 +901,54 @@ var overviewer = { return(urlBase + url); } } - } + }, + setHash: function() { + var hash = window.location.hash + var params = hash.split("/") + if (params.length > 1) { + if (overviewer.permalinks[params[1]]) { + hard_permalink = true; + } + } + location.hash = "#/"+overviewer.map.getCenter().lat().toFixed(3)+"/"+overviewer.map.getCenter().lng().toFixed(3)+"/"+overviewer.map.getZoom(); + }, + permalinks: { + "rent": { + text: "Rent is $200/month jeff@ unterbahn.com", + position: {lat: 0.546875, lng: 0.48046875, zoom: 6} + } + }, + openSign: function(markerName) { + var marker = null; + for (i=0;i 1) { + if (params[1] == "rent") { + mapOptions = overviewer.permalinks[params[1]].position + if (overviewer.collections.markers.All) openSign("rent"); + } else { + mapOptions.lat = parseFloat(params[1]) + mapOptions.lng = parseFloat(params[2]) + mapOptions.zoom = parseInt(params[3]) + } + } + return mapOptions + }, + goToHash: function() { + mapOptions = overviewer.readHash(); + if (overviewer.map) overviewer.map.setCenter(new google.maps.LatLng(mapOptions.lat, mapOptions.lng)) + if (overviewer.map) overviewer.map.setZoom(mapOptions.zoom) + } }; From 9f9ae1e1fe1c46e08c0867197255658f3adaaca7 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Tue, 3 May 2011 09:11:55 +0200 Subject: [PATCH 03/36] Fix diamond-ore textures. --- textures.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/textures.py b/textures.py index 1b9e3a1..8e764c8 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, -1, -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, 50, 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, -1,101, 98, 24, -1, -1, 86, -1, -1, -1, + 36, 37, -1, -1, 65, -1, -1,101, 50, 24, -1, -1, 86, -1, -1, -1, # 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 -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 From bac0c7604d18171ca800a8292ede82d686c41179 Mon Sep 17 00:00:00 2001 From: Jeffrey Warren Date: Thu, 5 May 2011 14:23:04 -0400 Subject: [PATCH 04/36] switched to dragend event for optimization --- web_assets/overviewer.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/web_assets/overviewer.js b/web_assets/overviewer.js index ab2ad51..9732511 100644 --- a/web_assets/overviewer.js +++ b/web_assets/overviewer.js @@ -58,6 +58,8 @@ var overviewer = { overviewer.util.initializeMarkers(); overviewer.util.initializeRegions(); overviewer.util.createMapControls(); + //window.addEventListener("hashchange",overviewer.goToHash,false); + //window.onhashchange = overviewer.goToHash; setInterval(overviewer.goToHash,500); }, /** @@ -240,10 +242,7 @@ var overviewer = { overviewer.map.setMapTypeId(overviewer.util.getDefaultMapTypeId()); // Make the link again whenever the map changes - google.maps.event.addListener(overviewer.map, 'zoom_changed', function() { - overviewer.setHash(); - }); - google.maps.event.addListener(overviewer.map, 'center_changed', function() { + google.maps.event.addListener(overviewer.map, 'dragend', function() { overviewer.setHash(); }); }, From 1983036ac9587dd0e8c1c4436cfc1147d08f6a30 Mon Sep 17 00:00:00 2001 From: Jeffrey Warren Date: Thu, 5 May 2011 14:46:33 -0400 Subject: [PATCH 05/36] putting back in zoom_changed event... oops --- web_assets/overviewer.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web_assets/overviewer.js b/web_assets/overviewer.js index 9732511..e472881 100644 --- a/web_assets/overviewer.js +++ b/web_assets/overviewer.js @@ -245,6 +245,9 @@ var overviewer = { google.maps.event.addListener(overviewer.map, 'dragend', function() { overviewer.setHash(); }); + google.maps.event.addListener(overviewer.map, 'zoom_changed', function() { + overviewer.setHash(); + }); }, /** * Read through overviewer.collections.markerDatas and create Marker From 3c8d7e6442d3cf2bcf8736fa18beb007a3cd2d55 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Sun, 8 May 2011 02:10:19 +0200 Subject: [PATCH 06/36] Add portals to textures.py, needed changes in chunk.py and iterate.c and added beds to transparent blocks. --- chunk.py | 6 +++--- src/iterate.c | 4 +++- textures.py | 19 ++++++++++++++++++- textures/portal.png | Bin 0 -> 672 bytes 4 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 textures/portal.png diff --git a/chunk.py b/chunk.py index 59ccae0..f44b4db 100644 --- a/chunk.py +++ b/chunk.py @@ -114,9 +114,9 @@ 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, 27, 28, 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, 92]) +transparent_blocks = set([ 0, 6, 8, 9, 18, 20, 26, 27, 28, 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]) # 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/src/iterate.c b/src/iterate.c index 1828409..7fd3d3f 100644 --- a/src/iterate.c +++ b/src/iterate.c @@ -276,6 +276,8 @@ generate_pseudo_data(RenderState *state, unsigned char ancilData) { return final_data; + } else if (state->block == 90) { + return check_adjacent_blocks(state, x, y, z, state->block); } @@ -398,7 +400,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) || (state.block == 2)) { + if ((state.block == 85) || (state.block == 9) || (state.block == 55) || (state.block == 54) || (state.block == 2) || (state.block == 90)) { ancilData = generate_pseudo_data(&state, ancilData); } diff --git a/textures.py b/textures.py index 8e764c8..28d44f0 100644 --- a/textures.py +++ b/textures.py @@ -1186,6 +1186,22 @@ def generate_special_texture(blockID, data): return (img.convert("RGB"), img.split()[3]) + if blockID == 90: # portal + portaltexture = _load_image("portal.png") + img = Image.new("RGBA", (24,24), (38,92,255,0)) + + side = transform_image_side(portaltexture) + otherside = side.transpose(Image.FLIP_TOP_BOTTOM) + + if data in (1,4): + composite.alpha_over(img, side, (5,4), side) + + if data in (2,8): + composite.alpha_over(img, otherside, (5,4), otherside) + + return (img.convert("RGB"), img.split()[3]) + + if blockID == 92: # cake! (without bites, at the moment) top = terrain_images[121] @@ -1292,7 +1308,7 @@ def getBiomeData(worlddir, chunkX, chunkY): special_blocks = set([ 2, 6, 9, 17, 18, 23, 27, 28, 35, 43, 44, 50, 51, 53, 54, 55, 58, 59, 61, 62, 64, 65, 66, 67, 71, 75, - 76, 85, 86, 91, 92]) + 76, 85, 86, 90, 91, 92]) # this is a map of special blockIDs to a list of all # possible values for ancillary data that it might have. @@ -1326,6 +1342,7 @@ 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, uses pseudo data special_map[86] = range(5) # pumpkin, orientation +special_map[90] = (1,2,4,8) # portal, in 2 orientations, 4 cases, uses pseudo data special_map[91] = range(5) # jack-o-lantern, orientation special_map[92] = range(6) # cake! diff --git a/textures/portal.png b/textures/portal.png new file mode 100644 index 0000000000000000000000000000000000000000..c6199204854714620b203859875747d5b13e2a14 GIT binary patch literal 672 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s77>k44ofy`glX=O&z`&N| z?e4-*$q>Xa_YJ$wGX@3*&H|6fVg?3oVGw3ym^DX&fq{X&#M9T6{WdGR2n$=e)hv*Z zWQl7;iF1B#Zfaf$gL6@8Vo7R>LV0FMhJw4NZ$Nk>pEv^p<8MzF#}JFtt&>j{-8K+# zkrxZP;~H6{I#vGU^e4@qX75}!$1BHEEPUdTLozCt!)~rT!)j6T{fmjgqubZt+qY#t zs$aU~$>+P%lzcPK+uF;^Pjpf!e?3WqM?68wRi4Y@{m)vP3;gMuEFPXNbD#PA#P$Wb zfd%n-c`j3GS~(OM8bz9vd^IPD>|O8Yb8N%OqEkBc>DAF|R{rigDX}HU=FR*cTW&Hi zW$RWMwb^*?(Dz9OD*|E}1Bhu=a7l zbq~dkLjuobe!n`haplL&`z23CbZ-<}J0)q38k_8g=RbEesAXTge%ZqP^7rc#lG`#5 zRsMhF;JI~Ag9y`OnS0f9zMsf;S7eEtGeMp6;DQzX_md7R3a+q;cCuz=PB#QEYHMp=lX^@0o^LxC;a&Ys@@(qPJ>N?LON66D z+U`7M_3~t4%AH%i-Qw7-r~jt?`LuPh!ILXyJ;xTzzx_=1WxQys;=*fJVvjFe$M}Og YRPXb*Ndex<3=9kmp00i_>zopr0C|NQQ~&?~ literal 0 HcmV?d00001 From a289ac2adcaa7d7afbacf898f9595d95e6bee0f0 Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Sun, 8 May 2011 01:47:40 -0400 Subject: [PATCH 07/36] Better error reporting when the wrong number of arguments are used --- overviewer.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/overviewer.py b/overviewer.py index c8e7500..bd4ef7b 100755 --- a/overviewer.py +++ b/overviewer.py @@ -164,10 +164,18 @@ def main(): logging.error("Invalid world number") sys.exit(1) - if len(args) != 2: + if len(args) < 2: if options.delete: return delete_all(worlddir, None) - parser.error("Where do you want to save the tiles?") + logging.error("Where do you want to save the tiles?") + sys.exit(1) + elif len(args) > 2: + if options.delete: + return delete_all(worlddir, None) + parser.print_help() + logging.error("Sorry, you specified too many arguments") + sys.exit(1) + destdir = args[1] if options.display_config: From 3a18d81842e9427d506543201c4ebd7ef046f0d6 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Sun, 8 May 2011 10:11:13 +0200 Subject: [PATCH 08/36] Increase the portal texture transparency. --- textures/portal.png | Bin 672 -> 672 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/textures/portal.png b/textures/portal.png index c6199204854714620b203859875747d5b13e2a14..1f75ca3d3b211ae75907f5839202dfdbff9effe4 100644 GIT binary patch delta 555 zcmZ3$x`1_pIp=?d{|x^Z>|H*2qJshl2M4Ex->S`fCT1AcN9Nsj5OBG#vt&p2rWBPE zu0@k%G|Er)GO>5+o_wS=X|sX+q)hIz3IAsPT(N51x|w44_tpJ3^b!8At*Scz{Wg(I zuj+R{fBxtYVcHoz-6e4c!)1+M0S7A2zkl3VXEFIGXZ$wnQ#S7VSaZ9Zeis!hFM6Ww z!okR~L_j3dYvPg@wWak*Ms2>+g42Fl-@cvXd$-)@*n+8#68|4rewIxjBKzWG!zZ4H zY9o{OF3yVHmFU3bD0cjbXA^^3w&&v+wWW^|_p4u!dSGNH0)L$+-DE;lYmkv5Cx zH^SBXe0%5rJ?n8Ss%LA)Qjy0dhA$fI&mU(siR|7t@0jJRef!&FjD3X9)&CA>_geLo zb%}t)^AGnP?{SZ_=2ATIsKv(9<6etS@761|?G3Ddf{YE$8#4q-2(ist^;*olyIG}+ zV@ulHH1CYMd4dNrc)YxpOgLja=lH{Aoop7SyeG9D+4PBcb_I1UdvAD6DC=xqEK|V> ztz8e98&5{ny`6u-Yh(2EC969ew06}OKG4(e2-j|q-X!u!X#*G29~gmnp`s zeIOOJz%=xB(LA+P>-J8V5>>bQo>=ypVw>%}$D(c(pU==c{dDj0?nSdNEHZearyt;@ zB#`m?&hDdz*Yv(`e=>c&Y^&n(ZHXpqfA5&R_xQg`gNJkLvUgT|rMw5?cZYwz@JT1| S8v{231B0ilpUXO@geCy0?gXy@ delta 555 zcmZ3$x`1_pIcFt95X0Oz>^jdTIw)|ki?FbjTg{S~m|<9dvgo#ffQ!6X&>h#vBGsw# zC#OGY{xo~%vN>Kko?_t>j~tRwxg2(LOdbea3i=O?x=$PFxr&&zX}Qq#(z z$j~U#q~xnPNo4POzj~iz8%`FT(y33cj$X6!ci%~gEkQPK=Kt7olYuE)x5}u^#&d_h z_nPvMTyJw855*IYX4rTN97xg4l-a!A&*sf{mMG>Jw}^DfM1h30j{~lID0UnYcrNq% z)sc-WKW^SHc`~AVquAOhNpsZLWIsIrxuZcX`{MP>7Vek7U!RcNmU*bM{{Jfn&#ikJ zM3^4S+^e4R{Y19AB1`0)3F@3DXHQtVaoVo;0vj6Qv)GK+2W4LMTX_e6eC^d9G|G<8R&KKi|w%}r?ofNdNc5a zx|-K07(||4|5rFlv+VVx5>Y`9SMz$lJ5O0ZX0aAHPjiZ433F_ipRSfYbIsEmCQDX} z#yE3tS(X)j?y}3(t>Tk{PUl~}ozz>}_k7#I2=D55l4nzQ?)hF4SRx!H(st)5tCuGW zQ|{dA?H0#wJ^eTB&!?@64W3*v>p8Yy{_SV7FXKg96&GH+5_^2%I>sN|p?aUcO$zW< SX5eOEVDNPHb6Mw<&;$UNngTEY From e437a15abcc3c4f4448bcc22185831600523468d Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Sun, 8 May 2011 12:24:58 +0200 Subject: [PATCH 09/36] Add beds and some changes in _build_full_block to simplify the building of fractions of a block. --- textures.py | 93 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 84 insertions(+), 9 deletions(-) diff --git a/textures.py b/textures.py index 28d44f0..72fec24 100644 --- a/textures.py +++ b/textures.py @@ -273,9 +273,37 @@ def _build_full_block(top, side1, side2, side3, side4, bottom=None, blockID=None side3 is in the -x (bottom left, north) side4 is in the +y (bottom right, west) - A non transparent block uses top, side 3 and side 4 + 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. + + NOTE: this method uses the top of the texture image (as done in + minecraft with beds) """ + + increment = 0 + if isinstance(top, tuple): + increment = top[1] + crop_height = int(increment * 16./12.) + 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)) + 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)) + 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)) + 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)) + img = Image.new("RGBA", (24,24), (38,92,255,0)) # first back sides @@ -288,7 +316,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), side1) + composite.alpha_over(img, side1, (0,0 + increment), side1) if side2 != None : @@ -299,7 +327,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), side2) + composite.alpha_over(img, side2, (12,0 + increment), side2) if bottom != None : bottom = transform_image(bottom, blockID) @@ -314,7 +342,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), side3) + composite.alpha_over(img, side3, (0,6 + increment), side3) if side4 != None : side4 = transform_image_side(side4, blockID) @@ -325,11 +353,11 @@ 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), side4) + composite.alpha_over(img, side4, (12,6 + increment), side4) if top != None : top = transform_image(top, blockID) - composite.alpha_over(img, top, (0,0), top) + composite.alpha_over(img, top, (0, increment), top) return img @@ -516,6 +544,52 @@ def generate_special_texture(blockID, data): return (img.convert("RGB"), img.split()[3]) + if blockID == 26: # bed + increment = 5 + left_face = None + right_face = None + if data & 0x8 == 0x8: # head of the bed + top = terrain_images[135] + if data & 0x00 == 0x00: # head pointing to West + top = top.copy().rotate(270) + left_face = terrain_images[151] + right_face = terrain_images[152] + if data & 0x01 == 0x01: # ... North + top = top.rotate(270) + left_face = terrain_images[152] + right_face = terrain_images[151] + if data & 0x02 == 0x02: # East + top = top.rotate(180) + left_face = terrain_images[151].transpose(Image.FLIP_LEFT_RIGHT) + right_face = None + if data & 0x03 == 0x03: # South + right_face = None + right_face = terrain_images[151].transpose(Image.FLIP_LEFT_RIGHT) + + else: # foot of the bed + top = terrain_images[134] + if data & 0x00 == 0x00: # head pointing to West + top = top.rotate(270) + left_face = terrain_images[150] + right_face = None + if data & 0x01 == 0x01: # ... North + top = top.rotate(270) + left_face = None + right_face = terrain_images[150] + if data & 0x02 == 0x02: # East + top = top.rotate(180) + left_face = terrain_images[150].transpose(Image.FLIP_LEFT_RIGHT) + right_face = terrain_images[149].transpose(Image.FLIP_LEFT_RIGHT) + if data & 0x03 == 0x03: # South + left_face = terrain_images[149] + right_face = terrain_images[150].transpose(Image.FLIP_LEFT_RIGHT) + + top = (top, increment) + img = _build_full_block(top, None, None, left_face, right_face) + + return (img.convert("RGB"), img.split()[3]) + + if blockID == 35: # wool if data == 0: # white top = side = terrain_images[64] @@ -1306,9 +1380,9 @@ def getBiomeData(worlddir, chunkX, chunkY): # (when adding new blocks here and in generate_special_textures, # please, if possible, keep the ascending order of blockid value) -special_blocks = set([ 2, 6, 9, 17, 18, 23, 27, 28, 35, 43, 44, 50, 51, - 53, 54, 55, 58, 59, 61, 62, 64, 65, 66, 67, 71, 75, - 76, 85, 86, 90, 91, 92]) +special_blocks = set([ 2, 6, 9, 17, 18, 26, 23, 27, 28, 35, 43, 44, 50, + 51, 53, 54, 55, 58, 59, 61, 62, 64, 65, 66, 67, 71, + 75, 76, 85, 86, 90, 91, 92]) # this is a map of special blockIDs to a list of all # possible values for ancillary data that it might have. @@ -1318,6 +1392,7 @@ special_map = {} special_map[6] = range(16) # saplings: usual, spruce, birch and future ones (rendered as usual saplings) special_map[9] = range(32) # water: spring,flowing, waterfall, and others (unknown) ancildata values, uses pseudo data special_map[17] = range(4) # wood: normal, birch and pine +special_map[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 From 808bfb7cfe42944df02adfe94f351d77f2ad41ba Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Sun, 8 May 2011 13:04:36 +0200 Subject: [PATCH 10/36] Add repeaters without torches, make needed changes in rendermode-normal for edge block lines. Delete some non used code in cake. --- src/rendermode-normal.c | 2 +- textures.py | 30 ++++++++++++++++++++++++++---- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/rendermode-normal.c b/src/rendermode-normal.c index be14a92..b4118e3 100644 --- a/src/rendermode-normal.c +++ b/src/rendermode-normal.c @@ -177,7 +177,7 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject * int increment=0; if (state->block == 44) // half-step increment=6; - else if (state->block == 78) // snow + else if ((state->block == 78) || (state->block == 93) || (state->block == 94)) // snow, redstone repeaters (on and off) increment=9; if ((state->x == 15) && (state->up_right_blocks != Py_None)) { diff --git a/textures.py b/textures.py index 72fec24..fced944 100644 --- a/textures.py +++ b/textures.py @@ -1296,10 +1296,30 @@ def generate_special_texture(blockID, data): composite.alpha_over(img, side, (2,12), side) composite.alpha_over(img, otherside, (10,12), otherside) composite.alpha_over(img, top, (0,8), top) + + return (img.convert("RGB"), img.split()[3]) + + + if blockID in (93, 94): # redstone repeaters, ON and OFF + + top = terrain_images[131] if blockID == 93 else terrain_images[147] + side = terrain_images[5] + increment = 9 + + if (data & 0x3) == 0: # pointing east + pass + + if (data & 0x3) == 1: # pointing south + top = top.rotate(270) + + if (data & 0x3) == 2: # pointing west + top = top.rotate(180) + + if (data & 0x3) == 3: # pointing north + top = top.rotate(90) + + img = _build_full_block( (top, increment), None, None, side, side) - #~ composite.alpha_over(img, side, (2,6), side) - #~ composite.alpha_over(img, otherside, (10,6), otherside) - #~ composite.alpha_over(img, top, (0,2), top) return (img.convert("RGB"), img.split()[3]) @@ -1382,7 +1402,7 @@ def getBiomeData(worlddir, chunkX, chunkY): special_blocks = set([ 2, 6, 9, 17, 18, 26, 23, 27, 28, 35, 43, 44, 50, 51, 53, 54, 55, 58, 59, 61, 62, 64, 65, 66, 67, 71, - 75, 76, 85, 86, 90, 91, 92]) + 75, 76, 85, 86, 90, 91, 92, 93, 94]) # this is a map of special blockIDs to a list of all # possible values for ancillary data that it might have. @@ -1420,6 +1440,8 @@ special_map[86] = range(5) # pumpkin, orientation special_map[90] = (1,2,4,8) # portal, in 2 orientations, 4 cases, uses pseudo data special_map[91] = range(5) # jack-o-lantern, orientation special_map[92] = range(6) # cake! +special_map[93] = range(16) # OFF redstone repeater, orientation and delay (delay not implemented) +special_map[94] = range(16) # ON redstone repeater, orientation and delay (delay not implemented) # grass and leaves are graysacle in terrain.png # we treat them as special so we can manually tint them From fc99f9f978420ac8bca6ff8b371047930d243283 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Sun, 8 May 2011 16:18:56 +0200 Subject: [PATCH 11/36] Add torches to the repeaters. --- textures.py | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/textures.py b/textures.py index fced944..764df40 100644 --- a/textures.py +++ b/textures.py @@ -1301,6 +1301,8 @@ def generate_special_texture(blockID, data): 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. top = terrain_images[131] if blockID == 93 else terrain_images[147] side = terrain_images[5] @@ -1320,6 +1322,99 @@ def generate_special_texture(blockID, data): img = _build_full_block( (top, increment), None, None, side, side) + # paste redstone torches everywhere! + t = specialblockmap[(75,5)] if blockID == 93 else specialblockmap[(76,5)] + torch = t[0].copy() # textures are stored as tuples (RGB,A) + torch.putalpha(t[1]) + + # the torch is too tall for the repeater, crop the bottom. + ImageDraw.Draw(torch).rectangle((0,16,24,24),outline=(0,0,0,0),fill=(0,0,0,0)) + + # touch up the 3d effect with big rectangles, just in case, for other texture packs + ImageDraw.Draw(torch).rectangle((0,24,10,15),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(torch).rectangle((12,15,24,24),outline=(0,0,0,0),fill=(0,0,0,0)) + + # torch positions for every redstone torch orientation. + # + # This is a horrible list of torch orientations. I tried to + # obtain these orientations by rotating the positions for one + # orientation, but pixel rounding is horrible and messes the + # torches. + + if (data & 0x3) == 0: # pointing east + if (data & 0xC) == 0: # one tick delay + moving_torch = (1,1) + static_torch = (-3,-1) + + elif (data & 0xC) == 4: # two ticks delay + moving_torch = (2,2) + static_torch = (-3,-1) + + elif (data & 0xC) == 8: # three ticks delay + moving_torch = (3,2) + static_torch = (-3,-1) + + elif (data & 0xC) == 12: # four ticks delay + moving_torch = (4,3) + static_torch = (-3,-1) + + elif (data & 0x3) == 1: # pointing south + if (data & 0xC) == 0: # one tick delay + moving_torch = (1,1) + static_torch = (5,-1) + + elif (data & 0xC) == 4: # two ticks delay + moving_torch = (2,0) + static_torch = (5,-1) + + elif (data & 0xC) == 8: # three ticks delay + moving_torch = (3,0) + static_torch = (5,-1) + + elif (data & 0xC) == 12: # four ticks delay + moving_torch = (4,-1) + static_torch = (5,-1) + + elif (data & 0x3) == 2: # pointing west + if (data & 0xC) == 0: # one tick delay + moving_torch = (1,1) + static_torch = (5,3) + + elif (data & 0xC) == 4: # two ticks delay + moving_torch = (0,0) + static_torch = (5,3) + + elif (data & 0xC) == 8: # three ticks delay + moving_torch = (-1,0) + static_torch = (5,3) + + elif (data & 0xC) == 12: # four ticks delay + moving_torch = (-2,-1) + static_torch = (5,3) + + elif (data & 0x3) == 3: # pointing north + if (data & 0xC) == 0: # one tick delay + moving_torch = (1,1) + static_torch = (-3,3) + + elif (data & 0xC) == 4: # two ticks delay + moving_torch = (2,0) + static_torch = (-3,3) + + elif (data & 0xC) == 8: # three ticks delay + moving_torch = (3,0) + static_torch = (-3,3) + + elif (data & 0xC) == 12: # four ticks delay + moving_torch = (4,-1) + static_torch = (-3,3) + + # this paste order it's ok for east and south orientation + # but it's wrong for north and west orientations. But using the + # default texture pack the torches are small enough to no overlap. + composite.alpha_over(img, torch, static_torch, torch) + composite.alpha_over(img, torch, moving_torch, torch) + return (img.convert("RGB"), img.split()[3]) From 86b891d9f2bba190d8c4f22ee214e4c48bfc8a92 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Sun, 8 May 2011 16:25:35 +0200 Subject: [PATCH 12/36] Fix the top texture for TNT. Remove non helpful comments or outdated comments. --- textures.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/textures.py b/textures.py index 764df40..543458a 100644 --- a/textures.py +++ b/textures.py @@ -374,13 +374,13 @@ 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, -1, -1, # Cloths are left out, sandstone (it has top, side, and bottom wich is ignored here), note block + 34, -1, 52, 48, 49,160,144, -1,176, 74, -1, -1, -1, -1, -1, -1, # 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 - -1, -1, -1, -1, -1, 13, 12, 29, 28, 23, 22, -1, -1, 7, 8, 4, # Gold/iron blocks? Doublestep? TNT from above? + -1, -1, -1, -1, -1, 13, 12, 29, 28, 23, 22, -1, -1, 7, 9, 4, # 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 - 36, 37, -1, -1, 65, -1, -1, -1, 50, 24, -1, -1, 86, -1, -1, -1, # Torch from above? leaving out fire. Redstone wire? Crops/furnaces handled elsewhere. sign post + 36, 37, -1, -1, 65, -1, -1, -1, 50, 24, -1, -1, 86, -1, -1, -1, # 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 - -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 + -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 66, 69, 72, 73, 75, -1,102,103,104,105,-1, 102 # clay? ] From 4297e49f203bb7cf26d0d2db04f6c222a1b332e3 Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Sun, 8 May 2011 12:05:04 -0400 Subject: [PATCH 13/36] Add portal.png to data_files for py2exe --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 497b5ac..415e1a4 100644 --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ setup_kwargs['cmdclass'] = {} if py2exe is not None: setup_kwargs['console'] = ['overviewer.py'] - setup_kwargs['data_files'] = [('textures', ['textures/lava.png', 'textures/water.png', 'textures/fire.png']), + setup_kwargs['data_files'] = [('textures', ['textures/lava.png', 'textures/water.png', 'textures/fire.png', 'textures/portal.png']), ('', ['overviewerConfig.js', 'COPYING.txt', 'README.rst']), ('web_assets', glob.glob('web_assets/*'))] setup_kwargs['zipfile'] = None From ef8dd359ac68cdd34470363014d1586369d4bd7e Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Mon, 9 May 2011 01:58:42 +0200 Subject: [PATCH 14/36] Make cactus as is in game. Improve cake. Add web block, at the moment is rendered as a sprite. --- chunk.py | 6 +++--- textures.py | 32 ++++++++++++++------------------ 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/chunk.py b/chunk.py index f44b4db..894c767 100644 --- a/chunk.py +++ b/chunk.py @@ -114,9 +114,9 @@ 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, 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]) +transparent_blocks = set([ 0, 6, 8, 9, 18, 20, 26, 27, 28, 30, 37, 38, 39, 40, + 44, 50, 51, 52, 53, 55, 59, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 74, 75, 76, 77, 78, 79, 81, 83, 85, 90, 92]) # This set holds block ids that are solid blocks solid_blocks = set([1, 2, 3, 4, 5, 7, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, diff --git a/textures.py b/textures.py index 543458a..b5fb86a 100644 --- a/textures.py +++ b/textures.py @@ -121,14 +121,9 @@ def transform_image(img, blockID=None): """ - if blockID in (81,92): # cacti and cake - # Resize to 15x15, since the cactus and the cake textures are a little smaller than the other textures - img = img.resize((15, 15), Image.ANTIALIAS) - - else: - # Resize to 17x17, since the diagonal is approximately 24 pixels, a nice - # even number that can be split in half twice - img = img.resize((17, 17), Image.ANTIALIAS) + # Resize to 17x17, since the diagonal is approximately 24 pixels, a nice + # even number that can be split in half twice + img = img.resize((17, 17), Image.ANTIALIAS) # Build the Affine transformation matrix for this perspective transform = numpy.matrix(numpy.identity(3)) @@ -223,7 +218,7 @@ def _build_block(top, side, blockID=None): otherside.putalpha(othersidealpha) ## special case for non-block things - if blockID in (37,38,6,39,40,83): ## flowers, sapling, mushrooms, reeds + if blockID in (37,38,6,39,40,83,30): ## flowers, sapling, mushrooms, reeds, web # # instead of pasting these blocks at the cube edges, place them in the middle: # and omit the top @@ -233,9 +228,9 @@ def _build_block(top, side, blockID=None): if blockID in (81,): # cacti! - composite.alpha_over(img, side, (2,6), side) - composite.alpha_over(img, otherside, (10,6), otherside) - composite.alpha_over(img, top, (0,2), top) + composite.alpha_over(img, side, (1,6), side) + composite.alpha_over(img, otherside, (11,6), otherside) + composite.alpha_over(img, top, (0,0), top) elif blockID in (44,): # half step # shift each texture down 6 pixels composite.alpha_over(img, side, (0,12), side) @@ -374,7 +369,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, -1, -1, + 34, -1, 52, 48, 49,160,144, -1,176, 74, -1, -1, -1, -1, 11, -1, # 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 -1, -1, -1, -1, -1, 13, 12, 29, 28, 23, 22, -1, -1, 7, 9, 4, # 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 @@ -391,7 +386,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, -1, -1, + 34, -1, 52, 48, 49,160,144, -1,192, 74, -1, -1,- 1, -1, 11, -1, # 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 -1, -1, -1, -1, -1, 13, 12, 29, 28, 23, 22, -1, -1, 7, 8, 35, # 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 @@ -399,7 +394,7 @@ def _build_blockimages(): # 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 - 66, 69, 72, 73, 74,-1 ,118,103,104,105, -1, 118 + 66, 70, 72, 73, 74,-1 ,118,103,104,105, -1, 118 ] # This maps block id to the texture that goes on the side of the block @@ -1293,9 +1288,10 @@ def generate_special_texture(blockID, data): img = Image.new("RGBA", (24,24), (38,92,255,0)) - composite.alpha_over(img, side, (2,12), side) - composite.alpha_over(img, otherside, (10,12), otherside) - composite.alpha_over(img, top, (0,8), top) + 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, top, (0,6), top) return (img.convert("RGB"), img.split()[3]) From d735053febb1aa08749986e69fd3547328e49ca7 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Mon, 9 May 2011 02:15:31 +0200 Subject: [PATCH 15/36] Add repeaters to the list of transaprent blocks. Fixes problem in night rendermode showing repeaters as strange black block. --- chunk.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/chunk.py b/chunk.py index 894c767..048b650 100644 --- a/chunk.py +++ b/chunk.py @@ -116,7 +116,8 @@ def get_tileentity_data(level): # This set holds blocks ids that can be seen through, for occlusion calculations transparent_blocks = set([ 0, 6, 8, 9, 18, 20, 26, 27, 28, 30, 37, 38, 39, 40, 44, 50, 51, 52, 53, 55, 59, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 74, 75, 76, 77, 78, 79, 81, 83, 85, 90, 92]) + 70, 71, 72, 74, 75, 76, 77, 78, 79, 81, 83, 85, 90, 92, + 93, 94]) # This set holds block ids that are solid blocks solid_blocks = set([1, 2, 3, 4, 5, 7, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, From d92a0bc59cb3d768236336ccf9b35711d450cfbd Mon Sep 17 00:00:00 2001 From: Michael Writhe Date: Mon, 9 May 2011 09:37:09 -0600 Subject: [PATCH 16/36] allowed for opacity of fill/stroke to be definned independantly. will continue to support legacy declaration of opacity --- web_assets/overviewer.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/web_assets/overviewer.js b/web_assets/overviewer.js index 6220a16..eea2f7d 100644 --- a/web_assets/overviewer.js +++ b/web_assets/overviewer.js @@ -368,6 +368,14 @@ var overviewer = { 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; + } else { + var strokeOpacity = region.strokeOpacity; + var fillOpacity = region.fillOpacity; + } + if (region.closed) { var shape = new google.maps.Polygon({ 'name': name, @@ -375,10 +383,10 @@ var overviewer = { 'geodesic': false, 'map': null, 'strokeColor': region.color, - 'strokeOpacity': region.opacity, + 'strokeOpacity': strokeOpacity, 'strokeWeight': overviewerConfig.CONST.regionStrokeWeight, 'fillColor': region.color, - 'fillOpacity': region.opacity * 0.25, + 'fillOpacity': fillOpacity, 'zIndex': j, 'paths': converted }); @@ -389,7 +397,7 @@ var overviewer = { 'geodesic': false, 'map': null, 'strokeColor': region.color, - 'strokeOpacity': region.opacity, + 'strokeOpacity': strokeOpacity, 'strokeWeight': overviewerConfig.CONST.regionStrokeWeight, 'zIndex': j, 'path': converted From 5a483ba4cc5fd36f2e6fbaeb9dad1bcfbcdba058 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Tue, 10 May 2011 20:34:09 -0400 Subject: [PATCH 17/36] added pironic to CONTRIBUTORS.rst --- CONTRIBUTORS.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index e251b41..cc5acef 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -28,6 +28,7 @@ for many different parts of the code. * Aaron Griffith * Alex Headley * Alex Jurkiewicz + * Michael Writhe * Xon ------------------------ From ec6fb82c7f3aca57a6cb8e1d57c42f1669c71487 Mon Sep 17 00:00:00 2001 From: Michael Writhe Date: Wed, 11 May 2011 15:36:39 -0600 Subject: [PATCH 18/36] regin click should show clicked spot in xyz not lat/lng --- web_assets/overviewer.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/web_assets/overviewer.js b/web_assets/overviewer.js index eea2f7d..dc02467 100644 --- a/web_assets/overviewer.js +++ b/web_assets/overviewer.js @@ -775,9 +775,11 @@ var overviewer = { overviewer.collections.infoWindow.close(); } // Replace our Info Window's content and position + var point = overviewer.util.fromLatLngToWorld(event.latLng.lat(),event.latLng.lng()); var contentString = 'Region: ' + shape.name + '
' + - 'Clicked Location:
' + event.latLng.lat() + ', ' + - event.latLng.lng() + '
'; + 'Clicked Location:
' + Math.round(point.x,1) + ', ' + point.y + + ', ' + Math.round(point.z,1) + + '
'; infowindow.setContent(contentString); infowindow.setPosition(event.latLng); infowindow.open(overviewer.map); From 2db3f57d38229249825cc3583409d3c82184d4ad Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Thu, 12 May 2011 14:54:25 +0200 Subject: [PATCH 19/36] Add signposts. Add transform_image_angle function. --- textures.py | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 3 deletions(-) diff --git a/textures.py b/textures.py index b5fb86a..80de34b 100644 --- a/textures.py +++ b/textures.py @@ -19,7 +19,7 @@ import os.path import zipfile from cStringIO import StringIO import math - +from random import randint import numpy from PIL import Image, ImageEnhance, ImageOps, ImageDraw @@ -189,7 +189,47 @@ def transform_image_slope(img, blockID=None): newimg = img.transform((24,24), Image.AFFINE, transform) return newimg + + +def transform_image_angle(img, angle, blockID=None): + """Takes an image an shears it in arbitrary angle with the axis of + rotation being vertical. + WARNING! Don't use angle = pi/2 (or multiplies), it will return + a blank image (or maybe garbage). + + NOTE: angle is in the image not in game, so for the left side of a + block angle = 30 degree. + """ + + # Take the same size as trasform_image_side + img = img.resize((12,12), Image.ANTIALIAS) + + # some values + cos_angle = math.cos(angle) + sin_angle = math.sin(angle) + + # function_x and function_y are used to keep the result image in the + # same position, and constant_x and constant_y are the coordinates + # for the center for angle = 0. + constant_x = 6. + constant_y = 6. + function_x = 6.*(1-cos_angle) + function_y = -6*sin_angle + big_term = ( (sin_angle * (function_x + constant_x)) - cos_angle* (function_y + constant_y))/cos_angle + + # The numpy array is not really used, but is helpful to + # see the matrix used for the transformation. + transform = numpy.array([[1./cos_angle, 0, -(function_x + constant_x)/cos_angle], + [-sin_angle/(cos_angle), 1., big_term ], + [0, 0, 1.]]) + + transform = tuple(transform[0]) + tuple(transform[1]) + + newimg = img.transform((24,24), Image.AFFINE, transform) + + return newimg + def _build_block(top, side, blockID=None): """From a top texture and a side texture, build a block image. @@ -982,6 +1022,49 @@ def generate_special_texture(blockID, data): return (img.convert("RGB"), img.split()[3]) + if blockID == 63: # singposts + + texture = terrain_images[4].copy() + # cut the wood 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 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): + for i in range(15): + x = randint(4,11) + y = randint(3,7) + texture.putpixel((x,y),(0,0,0,255)) + + # Minecraft uses wood texture for the signpost stick + texture_stick = terrain_images[20] + texture_stick = texture_stick.resize((12,12), Image.ANTIALIAS) + ImageDraw.Draw(texture_stick).rectangle((2,0,12,12),outline=(0,0,0,0),fill=(0,0,0,0)) + + img = Image.new("RGBA", (24,24), (38,92,255,0)) + + # W N ~90 E S ~270 + angles = (330.,345.,0.,15.,30.,55.,95.,120.,150.,165.,180.,195.,210.,230.,265.,310.) + angle = math.radians(angles[data]) + post = transform_image_angle(texture, angle) + + # choose the position of the "3D effect" + incrementx = 0 + if data in (1,6,7,8,9,14): + incrementx = -1 + elif data in (3,4,5,11,12,13): + incrementx = +1 + + composite.alpha_over(img, texture_stick,(11, 8),texture_stick) + # post2 is a brighter signpost pasted with a small sift, + # gives to the signpost some 3D effect. + post2 = ImageEnhance.Brightness(post).enhance(1.2) + composite.alpha_over(img, post2,(incrementx, -3),post2) + composite.alpha_over(img, post, (0,-2), post) + + return (img.convert("RGB"), img.split()[3]) + + if blockID in (64,71): #wooden door, or iron door if data & 0x8 == 0x8: # top of the door raw_door = terrain_images[81 if blockID == 64 else 82] @@ -1492,8 +1575,8 @@ def getBiomeData(worlddir, chunkX, chunkY): # please, if possible, keep the ascending order of blockid value) special_blocks = set([ 2, 6, 9, 17, 18, 26, 23, 27, 28, 35, 43, 44, 50, - 51, 53, 54, 55, 58, 59, 61, 62, 64, 65, 66, 67, 71, - 75, 76, 85, 86, 90, 91, 92, 93, 94]) + 51, 53, 54, 55, 58, 59, 61, 62, 63, 64, 65, 66, 67, + 71, 75, 76, 85, 86, 90, 91, 92, 93, 94]) # this is a map of special blockIDs to a list of all # possible values for ancillary data that it might have. @@ -1519,6 +1602,7 @@ special_map[58] = (0,) # crafting table special_map[59] = range(8) # crops, grow from 0 to 7 special_map[61] = range(6) # furnace, orientation special_map[62] = range(6) # burning furnace, orientation +special_map[63] = range(16) # signpost, 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 From 04fe00e315b30c559ad7f583217e215f6720b769 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Thu, 12 May 2011 15:31:46 +0200 Subject: [PATCH 20/36] Add wall signs. Fix torch positios for south oriented repeater. --- textures.py | 44 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/textures.py b/textures.py index 80de34b..ec77795 100644 --- a/textures.py +++ b/textures.py @@ -1025,7 +1025,7 @@ def generate_special_texture(blockID, data): if blockID == 63: # singposts texture = terrain_images[4].copy() - # cut the wood to the size of a signpost + # 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 the signpost is looking directly to the image, draw some @@ -1223,6 +1223,39 @@ def generate_special_texture(blockID, data): return (img.convert("RGB"), img.split()[3]) + if blockID == 68: # wall sign + 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)) + + # draw some random black dots, they will look as text + if data in (3,4): + for i in range(15): + x = randint(4,11) + y = randint(3,7) + texture.putpixel((x,y),(0,0,0,255)) + + img = Image.new("RGBA", (24,24), (38,92,255,0)) + + incrementx = 0 + if data == 2: # east + incrementx = +1 + sign = _build_full_block(None, None, None, None, texture) + elif data == 3: # west + incrementx = -1 + sign = _build_full_block(None, texture, None, None, None) + elif data == 4: # north + incrementx = +1 + sign = _build_full_block(None, None, texture, None, None) + elif data == 5: # south + incrementx = -1 + sign = _build_full_block(None, None, None, texture, None) + + sign2 = ImageEnhance.Brightness(sign).enhance(1.2) + composite.alpha_over(img, sign2,(incrementx, 2),sign2) + composite.alpha_over(img, sign, (0,3), sign) + + return (img.convert("RGB"), img.split()[3]) if blockID == 85: # fences # create needed images for Big stick fence @@ -1443,15 +1476,15 @@ def generate_special_texture(blockID, data): static_torch = (5,-1) elif (data & 0xC) == 4: # two ticks delay - moving_torch = (2,0) + moving_torch = (0,2) static_torch = (5,-1) elif (data & 0xC) == 8: # three ticks delay - moving_torch = (3,0) + moving_torch = (-1,2) static_torch = (5,-1) elif (data & 0xC) == 12: # four ticks delay - moving_torch = (4,-1) + moving_torch = (-2,3) static_torch = (5,-1) elif (data & 0x3) == 2: # pointing west @@ -1576,7 +1609,7 @@ def getBiomeData(worlddir, chunkX, chunkY): special_blocks = set([ 2, 6, 9, 17, 18, 26, 23, 27, 28, 35, 43, 44, 50, 51, 53, 54, 55, 58, 59, 61, 62, 63, 64, 65, 66, 67, - 71, 75, 76, 85, 86, 90, 91, 92, 93, 94]) + 68, 71, 75, 76, 85, 86, 90, 91, 92, 93, 94]) # this is a map of special blockIDs to a list of all # possible values for ancillary data that it might have. @@ -1607,6 +1640,7 @@ 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 special_map[67] = range(4) # cobblestone stairs, orientation +special_map[68] = (2,3,4,5) # wall sing, 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 From cb934ef18f8aca363f7f0a410db9cfefb7ff31e7 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Thu, 12 May 2011 16:30:32 +0200 Subject: [PATCH 21/36] Remove "text" from wall signs, they are used for chairs! --- textures.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/textures.py b/textures.py index ec77795..b740420 100644 --- a/textures.py +++ b/textures.py @@ -1229,12 +1229,15 @@ def generate_special_texture(blockID, data): ImageDraw.Draw(texture).rectangle((0,12,15,15),outline=(0,0,0,0),fill=(0,0,0,0)) # draw some random black dots, they will look as text + """ don't draw text at the moment, they are used in blank for decoration + if data in (3,4): for i in range(15): x = randint(4,11) y = randint(3,7) texture.putpixel((x,y),(0,0,0,255)) - + """ + img = Image.new("RGBA", (24,24), (38,92,255,0)) incrementx = 0 From 027419fa5fcdc77a432ffe3d6b67b7493b182c29 Mon Sep 17 00:00:00 2001 From: CounterPillow Date: Tue, 10 May 2011 18:28:25 +0200 Subject: [PATCH 22/36] Moved the blockid check further up in the for-loop to increase performance while rendering empty chunks. --- src/iterate.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/iterate.c b/src/iterate.c index 7fd3d3f..9f9be9a 100644 --- a/src/iterate.c +++ b/src/iterate.c @@ -364,6 +364,12 @@ chunk_render(PyObject *self, PyObject *args) { for (state.z = 0; state.z < 128; state.z++) { state.imgy -= 12; + + /* get blockid */ + state.block = getArrayByte3D(blocks_py, state.x, state.y, state.z); + if (state.block == 0) { + continue; + } /* make sure we're rendering inside the image boundaries */ if ((state.imgx >= imgsize0 + 24) || (state.imgx <= -24)) { @@ -373,11 +379,6 @@ chunk_render(PyObject *self, PyObject *args) { continue; } - /* get blockid */ - state.block = getArrayByte3D(blocks_py, state.x, state.y, state.z); - if (state.block == 0) { - continue; - } /* decref'd on replacement *and* at the end of the z for block */ if (blockid) { From 58034780603b3b6a89b8530688a0fa0524b196fc Mon Sep 17 00:00:00 2001 From: CounterPillow Date: Wed, 11 May 2011 21:33:24 +0200 Subject: [PATCH 23/36] Re-Implemented jywarrens live hash updating --- web_assets/overviewer.js | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/web_assets/overviewer.js b/web_assets/overviewer.js index eea2f7d..8b3cd97 100644 --- a/web_assets/overviewer.js +++ b/web_assets/overviewer.js @@ -225,13 +225,23 @@ var overviewer = { overviewer.collections.mapTypes[i].name, overviewer.collections.mapTypes[i]); } - + + /* // Make the link again whenever the map changes google.maps.event.addListener(overviewer.map, 'maptypeid_changed', function() { $('#'+overviewerConfig.CONST.mapDivId).css( 'background-color', overviewer.util.getMapTypeBackgroundColor( overviewer.map.getMapTypeId())); }); + */ + + // Add live hash update listener + google.maps.event.addListener(overviewer.map, 'dragend', function() { overviewer.updateHash(); }); + google.maps.event.addListener(overviewer.map, 'zoom_changed', function() { overviewer.updateHash(); }); + // Jump to the hash if given + overviewer.initHash(); + + // We can now set the map to use the 'coordinate' map type overviewer.map.setMapTypeId(overviewer.util.getDefaultMapTypeId()); }, @@ -858,6 +868,22 @@ var overviewer = { this.tileSize = tileSize; } }, + 'initHash': function() { + if(window.location.hash.split("/").length > 1) { + overviewer.goToHash(); + } + }, + 'setHash': function(lat, lng, zoom) { + window.location.replace("#/" + lat + "/" + lng + "/" + zoom); + }, + 'updateHash': function() { + overviewer.setHash(overviewer.map.getCenter().lat(), overviewer.map.getCenter().lng(), overviewer.map.getZoom()); + }, + 'goToHash': function() { + coords = window.location.hash.split("/"); + overviewer.map.setCenter(coords[1], coords[2]); + overviewer.map.setZoom(coords[3]); + }, /** * Stuff that we give to the google maps code instead of using ourselves * goes in here. From 4b9307d769da103cc7a99c67a8538695a6935eb1 Mon Sep 17 00:00:00 2001 From: CounterPillow Date: Wed, 11 May 2011 22:25:22 +0200 Subject: [PATCH 24/36] various fixes --- web_assets/overviewer.js | 46 +++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/web_assets/overviewer.js b/web_assets/overviewer.js index 8b3cd97..5760101 100644 --- a/web_assets/overviewer.js +++ b/web_assets/overviewer.js @@ -236,10 +236,14 @@ var overviewer = { */ // Add live hash update listener - google.maps.event.addListener(overviewer.map, 'dragend', function() { overviewer.updateHash(); }); - google.maps.event.addListener(overviewer.map, 'zoom_changed', function() { overviewer.updateHash(); }); + google.maps.event.addListener(overviewer.map, 'dragend', function() { + overviewer.util.updateHash(); + }); + google.maps.event.addListener(overviewer.map, 'zoom_changed', function() { + overviewer.util.updateHash(); + }); // Jump to the hash if given - overviewer.initHash(); + overviewer.util.initHash(); // We can now set the map to use the 'coordinate' map type @@ -812,7 +816,25 @@ var overviewer = { infowindow.open(overviewer.map, marker); overviewer.collections.infoWindow = infowindow; }); - } + }, + 'initHash': function() { + if(window.location.hash.split("/").length > 1) { + overviewer.util.goToHash(); + } + }, + 'setHash': function(x, z, zoom) { + window.location.replace("#/" + x.toFixed(3) + "/" + z.toFixed(3) + "/" + zoom); + }, + 'updateHash': function() { + var coordinates = overviewer.util.fromLatLngToWorld(overviewer.map.getCenter().lat(), overviewer.map.getCenter().lng()); + overviewer.util.setHash(coordinates.x, coordinates.z, overviewer.map.getZoom()); + }, + 'goToHash': function() { + var coords = window.location.hash.split("/"); + var latlngcoords = overviewer.util.fromWorldToLatLng(parseFloat(coords[1]), parseFloat(coords[2]), 64); + overviewer.map.setCenter(latlngcoords); + overviewer.map.setZoom(parseInt(coords[3])); + }, }, /** * The various classes needed in this file. @@ -868,22 +890,6 @@ var overviewer = { this.tileSize = tileSize; } }, - 'initHash': function() { - if(window.location.hash.split("/").length > 1) { - overviewer.goToHash(); - } - }, - 'setHash': function(lat, lng, zoom) { - window.location.replace("#/" + lat + "/" + lng + "/" + zoom); - }, - 'updateHash': function() { - overviewer.setHash(overviewer.map.getCenter().lat(), overviewer.map.getCenter().lng(), overviewer.map.getZoom()); - }, - 'goToHash': function() { - coords = window.location.hash.split("/"); - overviewer.map.setCenter(coords[1], coords[2]); - overviewer.map.setZoom(coords[3]); - }, /** * Stuff that we give to the google maps code instead of using ourselves * goes in here. From 8a38fa859d1de8d437bf6f46fb2abd066181fdf4 Mon Sep 17 00:00:00 2001 From: CounterPillow Date: Thu, 12 May 2011 00:17:26 +0200 Subject: [PATCH 25/36] Switched to x y z zoom format, using floor(), removed viewURL box --- web_assets/overviewer.js | 102 ++++++++++++--------------------------- 1 file changed, 31 insertions(+), 71 deletions(-) diff --git a/web_assets/overviewer.js b/web_assets/overviewer.js index 5760101..9c1d005 100644 --- a/web_assets/overviewer.js +++ b/web_assets/overviewer.js @@ -225,27 +225,25 @@ var overviewer = { overviewer.collections.mapTypes[i].name, overviewer.collections.mapTypes[i]); } - - /* + // Make the link again whenever the map changes google.maps.event.addListener(overviewer.map, 'maptypeid_changed', function() { $('#'+overviewerConfig.CONST.mapDivId).css( 'background-color', overviewer.util.getMapTypeBackgroundColor( overviewer.map.getMapTypeId())); }); - */ - - // Add live hash update listener - google.maps.event.addListener(overviewer.map, 'dragend', function() { - overviewer.util.updateHash(); - }); - google.maps.event.addListener(overviewer.map, 'zoom_changed', function() { - overviewer.util.updateHash(); - }); - // Jump to the hash if given - overviewer.util.initHash(); - - + + // Add live hash update listener + google.maps.event.addListener(overviewer.map, 'dragend', function() { + overviewer.util.updateHash(); + }); + google.maps.event.addListener(overviewer.map, 'zoom_changed', function() { + overviewer.util.updateHash(); + }); + // Jump to the hash if given + overviewer.util.initHash(); + + // We can now set the map to use the 'coordinate' map type overviewer.map.setMapTypeId(overviewer.util.getDefaultMapTypeId()); }, @@ -471,29 +469,6 @@ var overviewer = { } return results; }, - /** - * Set the link (at the bottom of the screen) to the current view. - * TODO: make this preserve the mapTypeId as well - */ - 'setViewUrl': function() { - var displayZoom = overviewer.map.getZoom(); - if (displayZoom == overviewerConfig.map.maxZoom) { - displayZoom = 'max'; - } else { - displayZoom -= overviewerConfig.map.maxZoom; - } - var point; - var point = overviewer.util.fromLatLngToWorld( - overviewer.map.getCenter().lat(), overviewer.map.getCenter().lng()); - var viewUrl = location.href.substring(0, location.href.lastIndexOf( - location.search)) - + '?x=' + Math.floor(point.x) - + '&y=' + Math.floor(point.y) - + '&z=' + Math.floor(point.z) - + '&zoom=' + displayZoom; - document.getElementById('link').innerHTML = viewUrl; - - }, 'getDefaultMapTypeId': function() { return overviewer.collections.mapTypeIds[0]; }, @@ -593,21 +568,6 @@ var overviewer = { * like the compass, current view link, etc. */ 'createMapControls': function() { - // viewstate link (little link to where you're looking at the map, - // normally bottom left) - var viewStateDiv = document.createElement('DIV'); - viewStateDiv.id='link'; - // add it to the map, bottom left. - if (overviewerConfig.map.controls.link) { - google.maps.event.addListener(overviewer.map, 'zoom_changed', function() { - overviewer.util.setViewUrl(); - }); - google.maps.event.addListener(overviewer.map, 'center_changed', function() { - overviewer.util.setViewUrl(); - }); - overviewer.map.controls[google.maps.ControlPosition.BOTTOM_LEFT].push(viewStateDiv); - } - // compass rose, in the top right corner var compassDiv = document.createElement('DIV'); compassDiv.style.padding = '5px'; @@ -817,24 +777,24 @@ var overviewer = { overviewer.collections.infoWindow = infowindow; }); }, - 'initHash': function() { - if(window.location.hash.split("/").length > 1) { - overviewer.util.goToHash(); - } - }, - 'setHash': function(x, z, zoom) { - window.location.replace("#/" + x.toFixed(3) + "/" + z.toFixed(3) + "/" + zoom); - }, - 'updateHash': function() { - var coordinates = overviewer.util.fromLatLngToWorld(overviewer.map.getCenter().lat(), overviewer.map.getCenter().lng()); - overviewer.util.setHash(coordinates.x, coordinates.z, overviewer.map.getZoom()); - }, - 'goToHash': function() { - var coords = window.location.hash.split("/"); - var latlngcoords = overviewer.util.fromWorldToLatLng(parseFloat(coords[1]), parseFloat(coords[2]), 64); - overviewer.map.setCenter(latlngcoords); - overviewer.map.setZoom(parseInt(coords[3])); - }, + 'initHash': function() { + if(window.location.hash.split("/").length > 1) { + overviewer.util.goToHash(); + } + }, + 'setHash': function(x, y, z, zoom) { + window.location.replace("#/" + Math.floor(x) + "/" + Math.floor(y) + "/" + Math.floor(z) + "/" + zoom); + }, + 'updateHash': function() { + var coordinates = overviewer.util.fromLatLngToWorld(overviewer.map.getCenter().lat(), overviewer.map.getCenter().lng()); + overviewer.util.setHash(coordinates.x, coordinates.y, coordinates.z, overviewer.map.getZoom()); + }, + 'goToHash': function() { + var coords = window.location.hash.split("/"); + var latlngcoords = overviewer.util.fromWorldToLatLng(parseInt(coords[1]), parseInt(coords[2]), parseInt(coords[3])); + overviewer.map.setCenter(latlngcoords); + overviewer.map.setZoom(parseInt(coords[4])); + }, }, /** * The various classes needed in this file. From 63d387c2808ac613c5db548f337347309d1967aa Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Thu, 12 May 2011 14:14:27 -0400 Subject: [PATCH 26/36] added Jeffrey Warren and CounterPillow to CONTRIBUTORS.rst --- CONTRIBUTORS.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index cc5acef..ae100b4 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -42,6 +42,7 @@ feature. * Kyle Brantley * cbarber * Alex Cline + * CounterPillow * Stephen Fluin * Benjamin Herr * Ryan Hitchman @@ -52,3 +53,4 @@ feature. * Gregory Short * Sam Steele * timwolla + * Jeffrey Warren From 2bca2b6db3f468ab2a3b84aa93523135aca5661a Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Thu, 12 May 2011 17:53:13 -0400 Subject: [PATCH 27/36] added generator meta tag --- googlemap.py | 1 + web_assets/index.html | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/googlemap.py b/googlemap.py index af56fbe..331a4ea 100644 --- a/googlemap.py +++ b/googlemap.py @@ -128,6 +128,7 @@ class MapGen(object): index = open(indexpath, 'r').read() index = index.replace( "{time}", str(strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime()))) + index = index.replace("{version}", util.findGitVersion()) with open(os.path.join(self.destdir, "index.html"), 'w') as output: output.write(index) diff --git a/web_assets/index.html b/web_assets/index.html index 3798f17..7fa8e31 100644 --- a/web_assets/index.html +++ b/web_assets/index.html @@ -1,15 +1,22 @@ + + + + + + +
From d2c9b8023978c2fdac2818d6b41a7612cf018095 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Thu, 12 May 2011 18:42:13 -0400 Subject: [PATCH 28/36] live hash Spawn button fix, negative zoom, and markers --- web_assets/overviewer.js | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/web_assets/overviewer.js b/web_assets/overviewer.js index 90856e6..4cbfc11 100644 --- a/web_assets/overviewer.js +++ b/web_assets/overviewer.js @@ -145,7 +145,7 @@ var overviewer = { var lng = defaultCenter.lng(); var zoom = overviewerConfig.map.defaultZoom; var mapcenter; - queryParams = overviewer.util.parseQueryString(); + var queryParams = overviewer.util.parseQueryString(); if (queryParams.lat) { lat = parseFloat(queryParams.lat); } @@ -782,6 +782,15 @@ var overviewer = { 'initHash': function() { if(window.location.hash.split("/").length > 1) { overviewer.util.goToHash(); + + // Add a marker indicating the user-supplied position + var coordinates = overviewer.util.fromLatLngToWorld(overviewer.map.getCenter().lat(), overviewer.map.getCenter().lng()); + overviewer.collections.markerDatas.push([{ + 'msg': 'Coordinates ' + Math.floor(coordinates.x) + ', ' + Math.floor(coordinates.y) + ', ' + Math.floor(coordinates.z), + 'x': coordinates.x, + 'y': coordinates.y, + 'z': coordinates.z, + 'type': 'querypos'}]); } }, 'setHash': function(x, y, z, zoom) { @@ -789,13 +798,37 @@ var overviewer = { }, 'updateHash': function() { var coordinates = overviewer.util.fromLatLngToWorld(overviewer.map.getCenter().lat(), overviewer.map.getCenter().lng()); - overviewer.util.setHash(coordinates.x, coordinates.y, coordinates.z, overviewer.map.getZoom()); + var zoom = overviewer.map.getZoom(); + if (zoom == overviewerConfig.map.maxZoom) { + zoom = 'max'; + } else if (zoom == overviewerConfig.map.minZoom) { + zoom = 'min'; + } else { + // default to (map-update friendly) negative zooms + zoom -= overviewerConfig.map.maxZoom; + } + overviewer.util.setHash(coordinates.x, coordinates.y, coordinates.z, zoom); }, 'goToHash': function() { var coords = window.location.hash.split("/"); var latlngcoords = overviewer.util.fromWorldToLatLng(parseInt(coords[1]), parseInt(coords[2]), parseInt(coords[3])); + var zoom = coords[4]; + if (zoom == 'max') { + zoom = overviewerConfig.map.maxZoom; + } else if (zoom == 'min') { + zoom = overviewerConfig.map.minZoom; + } else { + zoom = parseInt(zoom); + if (zoom < 0 && zoom + overviewerConfig.map.maxZoom >= 0) { + // if zoom is negative, treat it as a "zoom out from max" + zoom += overviewerConfig.map.maxZoom; + } else { + // fall back to default zoom + zoom = overviewerConfig.map.defaultZoom; + } + } overviewer.map.setCenter(latlngcoords); - overviewer.map.setZoom(parseInt(coords[4])); + overviewer.map.setZoom(zoom); }, }, /** @@ -829,6 +862,7 @@ var overviewer = { overviewerConfig.map.center[0], overviewerConfig.map.center[1], overviewerConfig.map.center[2])); + overviewer.util.updateHash(); }); }, /** From 93424c296d1b608ea8dd98613aa840aa8c72e8f1 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Fri, 13 May 2011 12:30:13 -0400 Subject: [PATCH 29/36] textures are now only generated when actual *rendering* is done --- rendernode.py | 14 ++++++++++++-- src/iterate.c | 42 ++++++++++++++++++++---------------------- src/main.c | 8 ++------ src/overviewer.h | 4 ++-- textures.py | 43 +++++++++++++++++++++++++++---------------- 5 files changed, 63 insertions(+), 48 deletions(-) diff --git a/rendernode.py b/rendernode.py index 9dce5cc..f99c087 100644 --- a/rendernode.py +++ b/rendernode.py @@ -26,6 +26,8 @@ import collections import json import logging import util +import textures +import c_overviewer import cPickle import stat import errno @@ -59,14 +61,22 @@ def pool_initializer(rendernode): logging.debug("Child process {0}".format(os.getpid())) #stash the quadtree objects in a global variable after fork() for windows compat. global child_rendernode - child_rendernode = rendernode + child_rendernode = rendernode + + # make sure textures are generated for this process + # and initialize c_overviewer + textures.generate() + c_overviewer.init_chunk_render() + + # load biome data in each process, if needed for quadtree in rendernode.quadtrees: if quadtree.world.useBiomeData: - import textures # make sure we've at least *tried* to load the color arrays in this process... textures.prepareBiomeData(quadtree.world.worlddir) if not textures.grasscolor or not textures.foliagecolor: raise Exception("Can't find grasscolor.png or foliagecolor.png") + # only load biome data once + break #http://docs.python.org/library/itertools.html def roundrobin(iterables): diff --git a/src/iterate.c b/src/iterate.c index 9f9be9a..b55e3df 100644 --- a/src/iterate.c +++ b/src/iterate.c @@ -24,43 +24,41 @@ static PyObject *special_blocks = NULL; static PyObject *specialblockmap = NULL; static PyObject *transparent_blocks = NULL; -int init_chunk_render(void) { +PyObject *init_chunk_render(PyObject *self, PyObject *args) { - /* if blockmap (or any of these) is not NULL, then that means that we've - * somehow called this function twice. error out so we can notice this - * */ - if (blockmap) return 1; + /* this function only needs to be called once, anything more is an + * error... */ + if (blockmap) { + PyErr_SetString(PyExc_RuntimeError, "init_chunk_render should only be called once per process."); + return NULL; + } textures = PyImport_ImportModule("textures"); /* ensure none of these pointers are NULL */ if ((!textures)) { - fprintf(stderr, "\ninit_chunk_render failed to load; textures\n"); - PyErr_Print(); - return 1; + return NULL; } chunk_mod = PyImport_ImportModule("chunk"); /* ensure none of these pointers are NULL */ if ((!chunk_mod)) { - fprintf(stderr, "\ninit_chunk_render failed to load; chunk\n"); - PyErr_Print(); - return 1; + return NULL; } blockmap = PyObject_GetAttrString(textures, "blockmap"); + if (!blockmap) + return NULL; special_blocks = PyObject_GetAttrString(textures, "special_blocks"); + if (!special_blocks) + return NULL; specialblockmap = PyObject_GetAttrString(textures, "specialblockmap"); + if (!specialblockmap) + return NULL; transparent_blocks = PyObject_GetAttrString(chunk_mod, "transparent_blocks"); + if (!transparent_blocks) + return NULL; - /* ensure none of these pointers are NULL */ - if ((!transparent_blocks) || (!blockmap) || (!special_blocks) || (!specialblockmap)) { - fprintf(stderr, "\ninit_chunk_render failed\n"); - PyErr_Print(); - return 1; - } - - return 0; - + Py_RETURN_NONE; } int @@ -310,7 +308,7 @@ chunk_render(PyObject *self, PyObject *args) { PyObject *t = NULL; if (!PyArg_ParseTuple(args, "OOiiO", &state.self, &state.img, &xoff, &yoff, &blockdata_expanded)) - return Py_BuildValue("i", "-1"); + return NULL; /* fill in important modules */ state.textures = textures; @@ -435,7 +433,7 @@ chunk_render(PyObject *self, PyObject *args) { blockid = NULL; } } - } + } /* free up the rendermode info */ rendermode->finish(rm_data, &state); diff --git a/src/main.c b/src/main.c index 4de7eec..19d3612 100644 --- a/src/main.c +++ b/src/main.c @@ -26,6 +26,8 @@ static PyMethodDef COverviewerMethods[] = { {"alpha_over", alpha_over_wrap, METH_VARARGS, "alpha over composite function"}, + {"init_chunk_render", init_chunk_render, METH_VARARGS, + "Initializes the stuffs renderer."}, {"render_loop", chunk_render, METH_VARARGS, "Renders stuffs"}, @@ -53,12 +55,6 @@ initc_overviewer(void) (void)Py_InitModule("c_overviewer", COverviewerMethods); /* for numpy */ import_array(); - - /* initialize some required variables in iterage.c */ - if (init_chunk_render()) { - fprintf(stderr, "failed to init_chunk_render\n"); - exit(1); // TODO better way to indicate error? - } init_endian(); } diff --git a/src/overviewer.h b/src/overviewer.h index 55243a5..5ee89dc 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 5 +#define OVERVIEWER_EXTENSION_VERSION 6 /* Python PIL, and numpy headers */ #include @@ -76,7 +76,7 @@ typedef struct { PyObject *left_blocks; PyObject *right_blocks; } RenderState; -int init_chunk_render(void); +PyObject *init_chunk_render(PyObject *self, PyObject *args); int is_transparent(unsigned char b); PyObject *chunk_render(PyObject *self, PyObject *args); diff --git a/textures.py b/textures.py index b740420..8a63d3c 100644 --- a/textures.py +++ b/textures.py @@ -112,9 +112,6 @@ def _split_terrain(terrain): return textures -# This maps terainids to 16x16 images -terrain_images = _split_terrain(_get_terrain_image()) - def transform_image(img, blockID=None): """Takes a PIL image and rotates it left 45 degrees and shrinks the y axis by a factor of 2. Returns the resulting image, which will be 24x12 pixels @@ -460,7 +457,6 @@ def _build_blockimages(): while len(allimages) < 256: allimages.append(None) return allimages -blockmap = _build_blockimages() def load_water(): """Evidentially, the water and lava textures are not loaded from any files @@ -482,8 +478,6 @@ def load_water(): lavablock = _build_block(lavatexture, lavatexture) blockmap[10] = lavablock.convert("RGB"), lavablock blockmap[11] = blockmap[10] -load_water() - def generate_special_texture(blockID, data): """Generates a special texture, such as a correctly facing minecraft track""" @@ -1541,11 +1535,6 @@ def tintTexture(im, c): i.putalpha(im.split()[3]); # copy the alpha band back in. assuming RGBA return i -# generate biome (still grayscale) leaf, grass textures -biome_grass_texture = _build_block(terrain_images[0], terrain_images[38], 2) -biome_leaf_texture = _build_block(terrain_images[52], terrain_images[52], 18) - - currentBiomeFile = None currentBiomeData = None grasscolor = None @@ -1665,9 +1654,31 @@ special_map[2] = range(11) + [0x10,] # grass, grass has not ancildata but is # and is harmless for normal maps special_map[18] = range(16) # leaves, birch, normal or pine leaves (not implemented) +# placeholders that are generated in generate() +terrain_images = None +blockmap = None +biome_grass_texture = None +biome_leaf_texture = None +specialblockmap = None -specialblockmap = {} - -for blockID in special_blocks: - for data in special_map[blockID]: - specialblockmap[(blockID, data)] = generate_special_texture(blockID, data) +def generate(): + # This maps terainids to 16x16 images + global terrain_images + terrain_images = _split_terrain(_get_terrain_image()) + + # generate the normal blocks + global blockmap + blockmap = _build_blockimages() + load_water() + + # generate biome (still grayscale) leaf, grass textures + global biome_grass_texture, biome_leaf_texture + biome_grass_texture = _build_block(terrain_images[0], terrain_images[38], 2) + biome_leaf_texture = _build_block(terrain_images[52], terrain_images[52], 18) + + # generate the special blocks + global specialblockmap, special_blocks + specialblockmap = {} + for blockID in special_blocks: + for data in special_map[blockID]: + specialblockmap[(blockID, data)] = generate_special_texture(blockID, data) From dacd45e5d32aab58258a0722495c6b86c9dc0534 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Fri, 13 May 2011 17:21:48 -0400 Subject: [PATCH 30/36] configurable settings.py, web_assets, textures paths --- configParser.py | 11 +++++- googlemap.py | 34 +++++++++++-------- overviewer.py | 4 ++- rendernode.py | 5 +-- textures.py | 29 +++++++++------- .../overviewerConfig.js | 0 6 files changed, 52 insertions(+), 31 deletions(-) rename overviewerConfig.js => web_assets/overviewerConfig.js (100%) diff --git a/configParser.py b/configParser.py index 5b275f0..c779fc2 100644 --- a/configParser.py +++ b/configParser.py @@ -22,6 +22,9 @@ class ConfigOptionParser(object): self.customArgs = ["required", "commandLineOnly", "default", "listify", "listdelim", "choices"] self.requiredArgs = [] + + # add the *very* special config-file path option + self.add_option("--config-file", dest="config_file", help="Specifies a configuration file to load, by name. This file's format is discussed in the README.", metavar="PATH", type="string", commandLineOnly=True) def display_config(self): logging.info("Using the following settings:") @@ -68,8 +71,14 @@ class ConfigOptionParser(object): # if this has a default, use that to seed the globals dict if a.get("default", None): g[n] = a['default'] g['args'] = args - + try: + if options.config_file: + self.configFile = options.config_file + elif os.path.exists(self.configFile): + # warn about automatic loading + logging.warning("Automatic settings.py loading is DEPRECATED, and may be removed in the future. Please use --config-file instead.") + if os.path.exists(self.configFile): execfile(self.configFile, g, l) except NameError, ex: diff --git a/googlemap.py b/googlemap.py index 331a4ea..daf0e0e 100644 --- a/googlemap.py +++ b/googlemap.py @@ -68,6 +68,7 @@ class MapGen(object): self.skipjs = configInfo.get('skipjs', None) self.web_assets_hook = configInfo.get('web_assets_hook', None) + self.web_assets_path = configInfo.get('web_assets_path', None) self.bg_color = configInfo.get('bg_color') if not len(quadtrees) > 0: @@ -81,14 +82,28 @@ class MapGen(object): raise ValueError("all the given quadtrees must have the same destdir and world") self.quadtrees = quadtrees - + def go(self, procs): """Writes out config.js, marker.js, and region.js Copies web assets into the destdir""" zoomlevel = self.p - configpath = os.path.join(util.get_program_path(), "overviewerConfig.js") - config = open(configpath, 'r').read() + bgcolor = (int(self.bg_color[1:3],16), int(self.bg_color[3:5],16), int(self.bg_color[5:7],16), 0) + blank = Image.new("RGBA", (1,1), bgcolor) + # Write a blank image + for quadtree in self.quadtrees: + tileDir = os.path.join(self.destdir, quadtree.tiledir) + if not os.path.exists(tileDir): os.mkdir(tileDir) + blank.save(os.path.join(tileDir, "blank."+quadtree.imgformat)) + + # copy web assets into destdir: + mirror_dir(os.path.join(util.get_program_path(), "web_assets"), self.destdir) + # do the same with the local copy, if we have it + if self.web_assets_path: + mirror_dir(self.web_assets_path, self.destdir) + + # replace the config js stuff + config = open(os.path.join(self.destdir, 'overviewerConfig.js'), 'r').read() config = config.replace( "{minzoom}", str(0)) config = config.replace( @@ -111,18 +126,7 @@ class MapGen(object): with open(os.path.join(self.destdir, "overviewerConfig.js"), 'w') as output: output.write(config) - bgcolor = (int(self.bg_color[1:3],16), int(self.bg_color[3:5],16), int(self.bg_color[5:7],16), 0) - blank = Image.new("RGBA", (1,1), bgcolor) - # Write a blank image - for quadtree in self.quadtrees: - tileDir = os.path.join(self.destdir, quadtree.tiledir) - if not os.path.exists(tileDir): os.mkdir(tileDir) - blank.save(os.path.join(tileDir, "blank."+quadtree.imgformat)) - - # copy web assets into destdir: - mirror_dir(os.path.join(util.get_program_path(), "web_assets"), self.destdir) - - # Add time in index.html + # Add time and version in index.html indexpath = os.path.join(self.destdir, "index.html") index = open(indexpath, 'r').read() diff --git a/overviewer.py b/overviewer.py index bd4ef7b..396cee8 100755 --- a/overviewer.py +++ b/overviewer.py @@ -101,6 +101,8 @@ def main(): 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) + parser.add_option("--web-assets-path", dest="web_assets_path", help="Specifies a non-standard web_assets directory to use. Files here will overwrite the default web assets.", metavar="PATH", type="string", configFileOnly=True) + parser.add_option("--textures-path", dest="textures_path", help="Specifies a non-standard textures path, from which terrain.png and other textures are loaded.", metavar="PATH", type="string", configFileOnly=True) parser.add_option("-q", "--quiet", dest="quiet", action="count", default=0, help="Print less output. You can specify this option multiple times.") parser.add_option("-v", "--verbose", dest="verbose", action="count", default=0, help="Print more output. You can specify this option multiple times.") parser.add_option("--skip-js", dest="skipjs", action="store_true", help="Don't output marker.js or regions.js") @@ -242,7 +244,7 @@ def main(): qtree.go(options.procs) # create the distributed render - r = rendernode.RenderNode(q) + r = rendernode.RenderNode(q, options) # write out the map and web assets m = googlemap.MapGen(q, configInfo=options) diff --git a/rendernode.py b/rendernode.py index f99c087..6f6c76e 100644 --- a/rendernode.py +++ b/rendernode.py @@ -65,7 +65,7 @@ def pool_initializer(rendernode): # make sure textures are generated for this process # and initialize c_overviewer - textures.generate() + textures.generate(path=rendernode.options.get('textures_path', None)) c_overviewer.init_chunk_render() # load biome data in each process, if needed @@ -94,12 +94,13 @@ def roundrobin(iterables): class RenderNode(object): - def __init__(self, quadtrees): + def __init__(self, quadtrees, options): """Distributes the rendering of a list of quadtrees.""" if not len(quadtrees) > 0: raise ValueError("there must be at least one quadtree to work on") + self.options = options self.quadtrees = quadtrees #bind an index value to the quadtree so we can find it again #and figure out which worlds are where diff --git a/textures.py b/textures.py index 8a63d3c..611353a 100644 --- a/textures.py +++ b/textures.py @@ -26,11 +26,14 @@ from PIL import Image, ImageEnhance, ImageOps, ImageDraw import util import composite +_find_file_local_path = None def _find_file(filename, mode="rb"): """Searches for the given file and returns an open handle to it. This searches the following locations in this order: + * the textures_path given in the config file (if present) * The program dir (same dir as this file) + * The program dir / textures * On Darwin, in /Applications/Minecraft * Inside minecraft.jar, which is looked for at these locations @@ -38,14 +41,21 @@ def _find_file(filename, mode="rb"): * On Darwin, at $HOME/Library/Application Support/minecraft/bin/minecraft.jar * at $HOME/.minecraft/bin/minecraft.jar - * The current working directory - * The program dir / textures - """ + + if _find_file_local_path: + path = os.path.join(_find_file_local_path, filename) + if os.path.exists(path): + return open(path, mode) + programdir = util.get_program_path() path = os.path.join(programdir, filename) if os.path.exists(path): return open(path, mode) + + path = os.path.join(programdir, "textures", filename) + if os.path.exists(path): + return open(path, mode) if sys.platform == "darwin": path = os.path.join("/Applications/Minecraft", filename) @@ -73,14 +83,6 @@ def _find_file(filename, mode="rb"): except (KeyError, IOError): pass - path = filename - if os.path.exists(path): - return open(path, mode) - - path = os.path.join(programdir, "textures", filename) - if os.path.exists(path): - return open(path, mode) - raise IOError("Could not find the file {0}. Is Minecraft installed? If so, I couldn't find the minecraft.jar file.".format(filename)) def _load_image(filename): @@ -1661,7 +1663,10 @@ biome_grass_texture = None biome_leaf_texture = None specialblockmap = None -def generate(): +def generate(path=None): + global _find_file_local_path + _find_file_local_path = path + # This maps terainids to 16x16 images global terrain_images terrain_images = _split_terrain(_get_terrain_image()) diff --git a/overviewerConfig.js b/web_assets/overviewerConfig.js similarity index 100% rename from overviewerConfig.js rename to web_assets/overviewerConfig.js From 21de6222ca80a251e4fc92514e7278e7442b8e84 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Fri, 13 May 2011 18:22:00 -0400 Subject: [PATCH 31/36] renamed --config-file to --settings, updated README with new options --- README.rst | 23 +++++++++++++++++++++-- configParser.py | 4 ++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index 1d0e9ab..11f9f10 100644 --- a/README.rst +++ b/README.rst @@ -191,11 +191,18 @@ Options --list-rendermodes List the available render modes, and a short description of each. +--settings=PATH + Use this option to load settings from a file. The format of this file is + given below. + Settings -------- -You can optionally store settings in a file named settings.py. It is a regular -python script, so you can use any python functions or modules you want. + +You can optionally store settings in a file named settings.py (or really, +anything you want). It is a regular python script, so you can use any python +functions or modules you want. To use a settings file, use the --settings +command line option. For a sample settings file, look at 'sample.settings.py'. Note that this file is not meant to be used directly, but instead it should be used as a @@ -241,6 +248,18 @@ web_assets_hook This function should accept one argument: a QuadtreeGen object. +web_assets_path + This option lets you provide alternative web assets to use when + rendering. The contents of this folder will be copied into the output folder + during render, and will overwrite any default files already copied by + Overviewer. See the web_assets folder included with Overviewer for the + default assets. + +textures_path + This is like web_assets_path, but instead it provides an alternative texture + source. Overviewer looks in here for terrain.png and other textures before + it looks anywhere else. + Viewing the Results ------------------- Within the output directory you will find two things: an index.html file, and a diff --git a/configParser.py b/configParser.py index c779fc2..01e6a14 100644 --- a/configParser.py +++ b/configParser.py @@ -24,7 +24,7 @@ class ConfigOptionParser(object): self.requiredArgs = [] # add the *very* special config-file path option - self.add_option("--config-file", dest="config_file", help="Specifies a configuration file to load, by name. This file's format is discussed in the README.", metavar="PATH", type="string", commandLineOnly=True) + self.add_option("--settings", dest="config_file", help="Specifies a settings file to load, by name. This file's format is discussed in the README.", metavar="PATH", type="string", commandLineOnly=True) def display_config(self): logging.info("Using the following settings:") @@ -77,7 +77,7 @@ class ConfigOptionParser(object): self.configFile = options.config_file elif os.path.exists(self.configFile): # warn about automatic loading - logging.warning("Automatic settings.py loading is DEPRECATED, and may be removed in the future. Please use --config-file instead.") + logging.warning("Automatic settings.py loading is DEPRECATED, and may be removed in the future. Please use --settings instead.") if os.path.exists(self.configFile): execfile(self.configFile, g, l) From 6dd3ac067c8d635ed91c5366633dcfeacbb62818 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Fri, 13 May 2011 21:30:26 -0400 Subject: [PATCH 32/36] fixed setup.py info to account for overviewerConfig.js move --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 415e1a4..a5baa97 100644 --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ setup_kwargs['cmdclass'] = {} if py2exe is not None: setup_kwargs['console'] = ['overviewer.py'] setup_kwargs['data_files'] = [('textures', ['textures/lava.png', 'textures/water.png', 'textures/fire.png', 'textures/portal.png']), - ('', ['overviewerConfig.js', 'COPYING.txt', 'README.rst']), + ('', ['COPYING.txt', 'README.rst']), ('web_assets', glob.glob('web_assets/*'))] setup_kwargs['zipfile'] = None if platform.system() == 'Windows' and '64bit' in platform.architecture(): From 7c5a809e713184a316d1ab4e2bd2395b731637da Mon Sep 17 00:00:00 2001 From: CounterPillow Date: Fri, 20 May 2011 14:18:05 +0200 Subject: [PATCH 33/36] Added maptypes to live hash updating, implemented some checks to catch incomplete hashes --- web_assets/overviewer.js | 64 +++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/web_assets/overviewer.js b/web_assets/overviewer.js index 4cbfc11..ae8b0b7 100644 --- a/web_assets/overviewer.js +++ b/web_assets/overviewer.js @@ -225,27 +225,28 @@ var overviewer = { overviewer.collections.mapTypes[i].name, overviewer.collections.mapTypes[i]); } - - // Make the link again whenever the map changes + + // Jump to the hash if given + overviewer.util.initHash(); + + // Add live hash update listeners + // Note: It is important to add them after jumping to the hash + google.maps.event.addListener(overviewer.map, 'dragend', function() { + overviewer.util.updateHash(); + }); + + google.maps.event.addListener(overviewer.map, 'zoom_changed', function() { + overviewer.util.updateHash(); + }); + + // Make the link again whenever the map changes google.maps.event.addListener(overviewer.map, 'maptypeid_changed', function() { $('#'+overviewerConfig.CONST.mapDivId).css( 'background-color', overviewer.util.getMapTypeBackgroundColor( overviewer.map.getMapTypeId())); + //smuggled this one in here for maptypeid hash generation --CounterPillow + overviewer.util.updateHash(); }); - - // Add live hash update listener - google.maps.event.addListener(overviewer.map, 'dragend', function() { - overviewer.util.updateHash(); - }); - google.maps.event.addListener(overviewer.map, 'zoom_changed', function() { - overviewer.util.updateHash(); - }); - // Jump to the hash if given - overviewer.util.initHash(); - - - // We can now set the map to use the 'coordinate' map type - overviewer.map.setMapTypeId(overviewer.util.getDefaultMapTypeId()); }, /** * Read through overviewer.collections.markerDatas and create Marker @@ -782,6 +783,8 @@ var overviewer = { 'initHash': function() { if(window.location.hash.split("/").length > 1) { overviewer.util.goToHash(); + // Clean up the hash. + overviewer.util.updateHash(); // Add a marker indicating the user-supplied position var coordinates = overviewer.util.fromLatLngToWorld(overviewer.map.getCenter().lat(), overviewer.map.getCenter().lng()); @@ -791,14 +794,15 @@ var overviewer = { 'y': coordinates.y, 'z': coordinates.z, 'type': 'querypos'}]); - } + } }, - 'setHash': function(x, y, z, zoom) { - window.location.replace("#/" + Math.floor(x) + "/" + Math.floor(y) + "/" + Math.floor(z) + "/" + zoom); + 'setHash': function(x, y, z, zoom, maptype) { + window.location.replace("#/" + Math.floor(x) + "/" + Math.floor(y) + "/" + Math.floor(z) + "/" + zoom + "/" + maptype); }, 'updateHash': function() { var coordinates = overviewer.util.fromLatLngToWorld(overviewer.map.getCenter().lat(), overviewer.map.getCenter().lng()); var zoom = overviewer.map.getZoom(); + var maptype = overviewer.map.getMapTypeId(); if (zoom == overviewerConfig.map.maxZoom) { zoom = 'max'; } else if (zoom == overviewerConfig.map.minZoom) { @@ -807,12 +811,22 @@ var overviewer = { // default to (map-update friendly) negative zooms zoom -= overviewerConfig.map.maxZoom; } - overviewer.util.setHash(coordinates.x, coordinates.y, coordinates.z, zoom); + overviewer.util.setHash(coordinates.x, coordinates.y, coordinates.z, zoom, maptype); }, 'goToHash': function() { + // Note: the actual data begins at coords[1], coords[0] is empty. var coords = window.location.hash.split("/"); var latlngcoords = overviewer.util.fromWorldToLatLng(parseInt(coords[1]), parseInt(coords[2]), parseInt(coords[3])); - var zoom = coords[4]; + var zoom; + var maptype = ''; + // The if-statements try to prevent unexpected behaviour when using incomplete hashes, e.g. older links + if (coords.length > 4) { + zoom = coords[4]; + } + if (coords.length > 5) { + maptype = coords[5]; + } + if (zoom == 'max') { zoom = overviewerConfig.map.maxZoom; } else if (zoom == 'min') { @@ -827,6 +841,14 @@ var overviewer = { zoom = overviewerConfig.map.defaultZoom; } } + // If the maptype isn't set, set the default one. + if (maptype == '') { + // We can now set the map to use the 'coordinate' map type + overviewer.map.setMapTypeId(overviewer.util.getDefaultMapTypeId()); + } else { + overviewer.map.setMapTypeId(maptype); + } + overviewer.map.setCenter(latlngcoords); overviewer.map.setZoom(zoom); }, From f82911e04e607894a922d9de9c579f4a80842ba7 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Tue, 24 May 2011 18:22:08 -0400 Subject: [PATCH 34/36] added overview map control (tiny, zoomed out map in corner) (hidden by default) --- web_assets/overviewer.js | 1 + 1 file changed, 1 insertion(+) diff --git a/web_assets/overviewer.js b/web_assets/overviewer.js index 4cbfc11..13bd106 100644 --- a/web_assets/overviewer.js +++ b/web_assets/overviewer.js @@ -194,6 +194,7 @@ var overviewer = { }, mapTypeId: overviewer.util.getDefaultMapTypeId(), streetViewControl: false, + overviewMapControl: true, zoomControl: overviewerConfig.map.controls.zoom, backgroundColor: overviewer.util.getMapTypeBackgroundColor( overviewer.util.getDefaultMapTypeId()) From dc12ba2751e48a82ea610574569f4e1b7fdf2892 Mon Sep 17 00:00:00 2001 From: aheadley Date: Thu, 26 May 2011 16:35:47 -0400 Subject: [PATCH 35/36] fixed issue #374 --- web_assets/overviewerConfig.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_assets/overviewerConfig.js b/web_assets/overviewerConfig.js index acb4529..ce38479 100644 --- a/web_assets/overviewerConfig.js +++ b/web_assets/overviewerConfig.js @@ -79,7 +79,7 @@ var overviewerConfig = { * Set to true to turn on debug mode, which adds a grid to the map along * with co-ordinates and a bunch of console output. */ - 'debug': false, + 'debug': false }, /** * Group definitions for objects that are partially selectable (signs and From d3551324b7560f54344ee6691b9b3c3b6e09794c Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Thu, 26 May 2011 20:44:45 -0400 Subject: [PATCH 36/36] --regionlist should be working now --- overviewer.py | 10 +++++----- quadtree.py | 4 +++- world.py | 13 ++++++++++--- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/overviewer.py b/overviewer.py index 396cee8..5f3400c 100755 --- a/overviewer.py +++ b/overviewer.py @@ -93,7 +93,7 @@ def main(): parser.add_option("-p", "--processes", dest="procs", help="How many worker processes to start. Default %s" % cpus, default=cpus, action="store", type="int") parser.add_option("-z", "--zoom", dest="zoom", help="Sets the zoom level manually instead of calculating it. This can be useful if you have outlier chunks that make your world too big. This value will make the highest zoom level contain (2**ZOOM)^2 tiles", action="store", type="int", configFileOnly=True) parser.add_option("-d", "--delete", dest="delete", help="Clear all caches. Next time you render your world, it will have to start completely over again. This is probably not a good idea for large worlds. Use this if you change texture packs and want to re-render everything.", action="store_true", commandLineOnly=True) - parser.add_option("--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("--regionlist", dest="regionlist", help="A file containing, on each line, a path to a regionlist to update. Instead of scanning the world directory for regions, it will just use this list. Normal caching rules still apply.") parser.add_option("--rendermodes", dest="rendermode", help="Specifies the render types, separated by commas. Use --list-rendermodes to list them all.", type="choice", choices=avail_rendermodes, required=True, default=avail_rendermodes[0], listify=True) parser.add_option("--list-rendermodes", dest="list_rendermodes", action="store_true", help="List available render modes and exit.", commandLineOnly=True) parser.add_option("--imgformat", dest="imgformat", help="The image output format to use. Currently supported: png(default), jpg.", configFileOnly=True ) @@ -189,10 +189,10 @@ def main(): if options.delete: return delete_all(worlddir, destdir) - if options.chunklist: - chunklist = open(options.chunklist, 'r') + if options.regionlist: + regionlist = map(str.strip, open(options.regionlist, 'r')) else: - chunklist = None + regionlist = None if options.imgformat: if options.imgformat not in ('jpg','png'): @@ -221,7 +221,7 @@ def main(): logging.info("Notice: Not using biome data for tinting") # First do world-level preprocessing - w = world.World(worlddir, useBiomeData=useBiomeData) + w = world.World(worlddir, useBiomeData=useBiomeData, regionlist=regionlist) w.go(options.procs) logging.info("Rending the following tilesets: %s", ",".join(options.rendermode)) diff --git a/quadtree.py b/quadtree.py index 688db93..5d240db 100644 --- a/quadtree.py +++ b/quadtree.py @@ -246,7 +246,7 @@ class QuadtreeGen(object): regiony = regiony_ _, _, c, mcr = get_region((regionx, regiony),(None,None,None,None)) - if c is not None and mcr.chunkExists(chunkx,chunky): + if c is not None and mcr.chunkExists(chunkx,chunky): chunklist.append((col, row, chunkx, chunky, c)) return chunklist @@ -427,6 +427,8 @@ class QuadtreeGen(object): for col, row, chunkx, chunky, regionfile in chunks: # check region file mtime first. region,regionMtime = get_region_mtime(regionfile) + if self.world.regionlist and region._filename not in self.world.regionlist: + continue if regionMtime <= tile_mtime: continue diff --git a/world.py b/world.py index 7f7bab1..348aff3 100644 --- a/world.py +++ b/world.py @@ -78,7 +78,8 @@ class World(object): logging.info("Scanning regions") regionfiles = {} self.regions = {} - for x, y, regionfile in self._iterate_regionfiles(): + self.regionlist = regionlist # a list of paths + for x, y, regionfile in self._iterate_regionfiles(): mcr = self.reload_region(regionfile) mcr.get_chunk_info() regionfiles[(x,y)] = (x,y,regionfile,mcr) @@ -277,16 +278,22 @@ class World(object): """Returns an iterator of all of the region files, along with their coordinates + Note: the regionlist here will be used to determinte the size of the + world. + Returns (regionx, regiony, filename)""" join = os.path.join if regionlist is not None: for path in regionlist: - if path.endswith("\n"): - path = path[:-1] + path = path.strip() f = os.path.basename(path) 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)) + else: + logging.warning("Ignore path '%s' in regionlist", f) + else: for path in glob(os.path.join(self.worlddir, 'region') + "/r.*.*.mcr"): dirpath, f = os.path.split(path)