Merge branch 'master' into rendermode-options
Conflicts: overviewer_core/chunk.py overviewer_core/src/iterate.c
This commit is contained in:
@@ -41,6 +41,7 @@ feature.
|
|||||||
|
|
||||||
* arrai <array.of.intellect@gmail.com>
|
* arrai <array.of.intellect@gmail.com>
|
||||||
* Kyle Brantley <kyle@averageurl.com>
|
* Kyle Brantley <kyle@averageurl.com>
|
||||||
|
* but2002 <barryt_9@hotmail.com>
|
||||||
* Eric Carr <eric@carr.no>
|
* Eric Carr <eric@carr.no>
|
||||||
* cbarber <CraigBarber@taryx.com>
|
* cbarber <CraigBarber@taryx.com>
|
||||||
* Alex Cline <cline@vivisimo.com>
|
* Alex Cline <cline@vivisimo.com>
|
||||||
|
|||||||
@@ -4,6 +4,6 @@ include CONTRIBUTORS.rst
|
|||||||
include overviewer.py
|
include overviewer.py
|
||||||
include sample.settings.py
|
include sample.settings.py
|
||||||
recursive-include contrib/ *.py
|
recursive-include contrib/ *.py
|
||||||
recursive-include overviewer_core/*.py
|
recursive-include overviewer_core/ *.py
|
||||||
recursive-include overviewer_core/src/ *.c *.h
|
recursive-include overviewer_core/src/ *.c *.h
|
||||||
recursive-include overviewer_core/data/ *.png *.js index.html style.css
|
recursive-include overviewer_core/data/ *
|
||||||
|
|||||||
@@ -188,6 +188,11 @@ def main():
|
|||||||
parser.print_help()
|
parser.print_help()
|
||||||
logging.error("Invalid world number")
|
logging.error("Invalid world number")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
# final sanity check for worlddir
|
||||||
|
if not os.path.exists(os.path.join(worlddir, 'level.dat')):
|
||||||
|
logging.error("Invalid world path -- does not contain level.dat")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
if len(args) < 2:
|
if len(args) < 2:
|
||||||
if options.delete:
|
if options.delete:
|
||||||
|
|||||||
@@ -114,10 +114,10 @@ def get_tileentity_data(level):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
# This set holds blocks ids that can be seen through, for occlusion calculations
|
# This set holds blocks ids that can be seen through, for occlusion calculations
|
||||||
transparent_blocks = set([ 0, 6, 8, 9, 18, 20, 26, 27, 28, 30, 31, 32, 37, 38,
|
transparent_blocks = set([ 0, 6, 8, 9, 18, 20, 26, 27, 28, 29, 30, 31, 32, 33,
|
||||||
39, 40, 44, 50, 51, 52, 53, 55, 59, 63, 64, 65, 66, 67,
|
34, 37, 38, 39, 40, 44, 50, 51, 52, 53, 55, 59, 63, 64,
|
||||||
68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 81, 83, 85,
|
65, 66, 67, 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79,
|
||||||
90, 92, 93, 94, 96])
|
81, 83, 85, 90, 92, 93, 94, 96])
|
||||||
|
|
||||||
# This set holds block ids that are solid blocks
|
# 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,
|
solid_blocks = set([1, 2, 3, 4, 5, 7, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
|
||||||
@@ -335,67 +335,6 @@ class ChunkRenderer(object):
|
|||||||
return self._up_left_blocklight
|
return self._up_left_blocklight
|
||||||
up_left_blocklight = property(_load_up_left_blocklight)
|
up_left_blocklight = property(_load_up_left_blocklight)
|
||||||
|
|
||||||
def generate_pseudo_ancildata(self,x,y,z,blockid, north_position = 0 ):
|
|
||||||
""" Generates a pseudo ancillary data for blocks that depend of
|
|
||||||
what are surrounded and don't have ancillary data
|
|
||||||
|
|
||||||
This uses a binary number of 4 digits to encode the info.
|
|
||||||
The encode is:
|
|
||||||
|
|
||||||
Bit: 1 2 3 4
|
|
||||||
Side: x y -x -y
|
|
||||||
Values: bit = 0 -> The corresponding side block has different blockid
|
|
||||||
bit = 1 -> The corresponding side block has same blockid
|
|
||||||
Example: if the bit1 is 1 that means that there is a block with
|
|
||||||
blockid in the side of the +x direction.
|
|
||||||
|
|
||||||
You can rotate the pseudo data multiplying by 2 and
|
|
||||||
if it is > 15 subtracting 15 and adding 1. (moving bits
|
|
||||||
in the left direction is like rotate 90 degree in anticlockwise
|
|
||||||
direction). In this way can be used for maps with other
|
|
||||||
north orientation.
|
|
||||||
|
|
||||||
North position can have the values 0, 1, 2, 3, corresponding to
|
|
||||||
north in bottom-left, bottom-right, top-right and top-left of
|
|
||||||
the screen.
|
|
||||||
|
|
||||||
The rotation feature is not used anywhere yet.
|
|
||||||
"""
|
|
||||||
|
|
||||||
blocks = self.blocks
|
|
||||||
up_left_blocks = self.up_left_blocks
|
|
||||||
up_right_blocks = self.up_right_blocks
|
|
||||||
left_blocks = self.left_blocks
|
|
||||||
right_blocks = self.right_blocks
|
|
||||||
|
|
||||||
pseudo_data = 0
|
|
||||||
|
|
||||||
# first check if we are in the border of a chunk, next check for chunks adjacent to this
|
|
||||||
# and finally check for a block with same blockid. I we aren't in the border of a chunk,
|
|
||||||
# check for the block having the sme blockid.
|
|
||||||
|
|
||||||
if (up_right_blocks is not None and up_right_blocks[0,y,z] == blockid) if x == 15 else blocks[x+1,y,z] == blockid:
|
|
||||||
pseudo_data = pseudo_data | 0b1000
|
|
||||||
|
|
||||||
if (right_blocks is not None and right_blocks[x,0,z] == blockid) if y == 15 else blocks[x,y + 1,z] == blockid:
|
|
||||||
pseudo_data = pseudo_data | 0b0100
|
|
||||||
|
|
||||||
if (left_blocks is not None and left_blocks[15,y,z] == blockid) if x == 0 else blocks[x - 1,y,z] == blockid:
|
|
||||||
pseudo_data = pseudo_data | 0b0010
|
|
||||||
|
|
||||||
if (up_left_blocks is not None and up_left_blocks[x,15,z] == blockid) if y == 0 else blocks[x,y - 1,z] == blockid:
|
|
||||||
pseudo_data = pseudo_data | 0b0001
|
|
||||||
|
|
||||||
# rotate the bits for other north orientations
|
|
||||||
while north_position > 0:
|
|
||||||
pseudo_data *= 2
|
|
||||||
if pseudo_data > 15:
|
|
||||||
pseudo_data -= 16
|
|
||||||
pseudo_data +=1
|
|
||||||
north_position -= 1
|
|
||||||
|
|
||||||
return pseudo_data
|
|
||||||
|
|
||||||
def chunk_render(self, img=None, xoff=0, yoff=0, cave=False):
|
def chunk_render(self, img=None, xoff=0, yoff=0, cave=False):
|
||||||
"""Renders a chunk with the given parameters, and returns the image.
|
"""Renders a chunk with the given parameters, and returns the image.
|
||||||
If img is given, the chunk is rendered to that image object. Otherwise,
|
If img is given, the chunk is rendered to that image object. Otherwise,
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ var overviewer = {
|
|||||||
overviewer.util.initializeMarkers();
|
overviewer.util.initializeMarkers();
|
||||||
overviewer.util.initializeRegions();
|
overviewer.util.initializeRegions();
|
||||||
overviewer.util.createMapControls();
|
overviewer.util.createMapControls();
|
||||||
overviewer.util.createSearchBox();
|
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* This adds some methods to these classes because Javascript is stupid
|
* This adds some methods to these classes because Javascript is stupid
|
||||||
@@ -166,6 +165,9 @@ var overviewer = {
|
|||||||
var zoom = overviewerConfig.map.defaultZoom;
|
var zoom = overviewerConfig.map.defaultZoom;
|
||||||
var mapcenter;
|
var mapcenter;
|
||||||
var queryParams = overviewer.util.parseQueryString();
|
var queryParams = overviewer.util.parseQueryString();
|
||||||
|
if (queryParams.debug) {
|
||||||
|
overviewerConfig.map.debug=true;
|
||||||
|
}
|
||||||
if (queryParams.lat) {
|
if (queryParams.lat) {
|
||||||
lat = parseFloat(queryParams.lat);
|
lat = parseFloat(queryParams.lat);
|
||||||
}
|
}
|
||||||
@@ -311,6 +313,9 @@ var overviewer = {
|
|||||||
'title': jQuery.trim(item.msg),
|
'title': jQuery.trim(item.msg),
|
||||||
'icon': overviewerConfig.CONST.image.queryMarker
|
'icon': overviewerConfig.CONST.image.queryMarker
|
||||||
});
|
});
|
||||||
|
google.maps.event.addListener(marker, 'click', function(){ marker.setVisible(false); });
|
||||||
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -392,59 +397,76 @@ var overviewer = {
|
|||||||
point.x, point.y, point.z));
|
point.x, point.y, point.z));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (region.label) {
|
||||||
|
var name = region.label;
|
||||||
|
} else {
|
||||||
|
var name = "rawr";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(region.opacity) {
|
||||||
|
var strokeOpacity = region.opacity;
|
||||||
|
var fillOpacity = region.opacity * 0.25;
|
||||||
|
} else {
|
||||||
|
var strokeOpacity = region.strokeOpacity;
|
||||||
|
var fillOpacity = region.fillOpacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
var shapeOptions = {
|
||||||
|
'name': name,
|
||||||
|
'geodesic': false,
|
||||||
|
'map': null,
|
||||||
|
'strokeColor': region.color,
|
||||||
|
'strokeOpacity': strokeOpacity,
|
||||||
|
'strokeWeight': overviewerConfig.CONST.regionStrokeWeight,
|
||||||
|
'zIndex': j
|
||||||
|
};
|
||||||
|
if (region.closed) {
|
||||||
|
shapeOptions["fillColor"] = region.color;
|
||||||
|
shapeOptions["fillOpacity"] = fillOpacity;
|
||||||
|
shapeOptions["paths"] = converted;
|
||||||
|
} else {
|
||||||
|
shapeOptions["path"] = converted;
|
||||||
|
}
|
||||||
|
|
||||||
|
var matched = false;
|
||||||
|
|
||||||
for (k in overviewerConfig.objectGroups.regions) {
|
for (k in overviewerConfig.objectGroups.regions) {
|
||||||
var regionGroup = overviewerConfig.objectGroups.regions[k];
|
var regionGroup = overviewerConfig.objectGroups.regions[k];
|
||||||
var clickable = regionGroup.clickable;
|
var clickable = regionGroup.clickable;
|
||||||
var label = regionGroup.label;
|
var label = regionGroup.label;
|
||||||
|
|
||||||
if(region.label) {
|
if (!regionGroup.match(region))
|
||||||
var name = region.label
|
continue;
|
||||||
} else {
|
matched = true;
|
||||||
var name = 'rawr';
|
|
||||||
|
if (!region.label) {
|
||||||
clickable = false; // if it doesn't have a name, we dont have to show it.
|
clickable = false; // if it doesn't have a name, we dont have to show it.
|
||||||
}
|
}
|
||||||
|
|
||||||
if(region.opacity) {
|
if (region.closed) {
|
||||||
var strokeOpacity = region.opacity;
|
var shape = new google.maps.Polygon(shapeOptions);
|
||||||
var fillOpacity = region.opacity * 0.25;
|
|
||||||
} else {
|
} else {
|
||||||
var strokeOpacity = region.strokeOpacity;
|
var shape = new google.maps.Polyline(shapeOptions);
|
||||||
var fillOpacity = region.fillOpacity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (region.closed) {
|
|
||||||
var shape = new google.maps.Polygon({
|
|
||||||
'name': name,
|
|
||||||
'clickable': clickable,
|
|
||||||
'geodesic': false,
|
|
||||||
'map': null,
|
|
||||||
'strokeColor': region.color,
|
|
||||||
'strokeOpacity': strokeOpacity,
|
|
||||||
'strokeWeight': overviewerConfig.CONST.regionStrokeWeight,
|
|
||||||
'fillColor': region.color,
|
|
||||||
'fillOpacity': fillOpacity,
|
|
||||||
'zIndex': j,
|
|
||||||
'paths': converted
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
var shape = new google.maps.Polyline({
|
|
||||||
'name': name,
|
|
||||||
'clickable': clickable,
|
|
||||||
'geodesic': false,
|
|
||||||
'map': null,
|
|
||||||
'strokeColor': region.color,
|
|
||||||
'strokeOpacity': strokeOpacity,
|
|
||||||
'strokeWeight': overviewerConfig.CONST.regionStrokeWeight,
|
|
||||||
'zIndex': j,
|
|
||||||
'path': converted
|
|
||||||
});
|
|
||||||
}
|
|
||||||
overviewer.collections.regions[label].push(shape);
|
overviewer.collections.regions[label].push(shape);
|
||||||
|
|
||||||
if (clickable) {
|
if (clickable) {
|
||||||
overviewer.util.createRegionInfoWindow(shape);
|
overviewer.util.createRegionInfoWindow(shape);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if we haven't matched anything, go ahead and add it
|
||||||
|
if (!matched) {
|
||||||
|
if (region.closed) {
|
||||||
|
var shape = new google.maps.Polygon(shapeOptions);
|
||||||
|
} else {
|
||||||
|
var shape = new google.maps.Polyline(shapeOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
shape.setMap(overviewer.map);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -512,7 +534,7 @@ var overviewer = {
|
|||||||
// the width and height of all the highest-zoom tiles combined,
|
// the width and height of all the highest-zoom tiles combined,
|
||||||
// inverted
|
// inverted
|
||||||
var perPixel = 1.0 / (overviewerConfig.CONST.tileSize *
|
var perPixel = 1.0 / (overviewerConfig.CONST.tileSize *
|
||||||
Math.pow(2, overviewerConfig.map.maxZoom));
|
Math.pow(2, overviewerConfig.map.zoomLevels));
|
||||||
|
|
||||||
// This information about where the center column is may change with
|
// This information about where the center column is may change with
|
||||||
// a different drawing implementation -- check it again after any
|
// a different drawing implementation -- check it again after any
|
||||||
@@ -520,13 +542,13 @@ var overviewer = {
|
|||||||
|
|
||||||
// point (0, 0, 127) is at (0.5, 0.0) of tile (tiles/2 - 1, tiles/2)
|
// point (0, 0, 127) is at (0.5, 0.0) of tile (tiles/2 - 1, tiles/2)
|
||||||
// so the Y coordinate is at 0.5, and the X is at 0.5 -
|
// so the Y coordinate is at 0.5, and the X is at 0.5 -
|
||||||
// ((tileSize / 2) / (tileSize * 2^maxZoom))
|
// ((tileSize / 2) / (tileSize * 2^zoomLevels))
|
||||||
// or equivalently, 0.5 - (1 / 2^(maxZoom + 1))
|
// or equivalently, 0.5 - (1 / 2^(zoomLevels + 1))
|
||||||
var lng = 0.5 - (1.0 / Math.pow(2, overviewerConfig.map.maxZoom + 1));
|
var lng = 0.5 - (1.0 / Math.pow(2, overviewerConfig.map.zoomLevels + 1));
|
||||||
var lat = 0.5;
|
var lat = 0.5;
|
||||||
|
|
||||||
// the following metrics mimic those in ChunkRenderer.chunk_render
|
// the following metrics mimic those in
|
||||||
// in "chunk.py" or, equivalently, chunk_render in src/iterate.c
|
// chunk_render in src/iterate.c
|
||||||
|
|
||||||
// each block on X axis adds 12px to x and subtracts 6px from y
|
// each block on X axis adds 12px to x and subtracts 6px from y
|
||||||
lng += 12 * x * perPixel;
|
lng += 12 * x * perPixel;
|
||||||
@@ -564,11 +586,11 @@ var overviewer = {
|
|||||||
// the width and height of all the highest-zoom tiles combined,
|
// the width and height of all the highest-zoom tiles combined,
|
||||||
// inverted
|
// inverted
|
||||||
var perPixel = 1.0 / (overviewerConfig.CONST.tileSize *
|
var perPixel = 1.0 / (overviewerConfig.CONST.tileSize *
|
||||||
Math.pow(2, overviewerConfig.map.maxZoom));
|
Math.pow(2, overviewerConfig.map.zoomLevels));
|
||||||
|
|
||||||
// Revert base positioning
|
// Revert base positioning
|
||||||
// See equivalent code in fromWorldToLatLng()
|
// See equivalent code in fromWorldToLatLng()
|
||||||
lng -= 0.5 - (1.0 / Math.pow(2, overviewerConfig.map.maxZoom + 1));
|
lng -= 0.5 - (1.0 / Math.pow(2, overviewerConfig.map.zoomLevels + 1));
|
||||||
lat -= 0.5;
|
lat -= 0.5;
|
||||||
|
|
||||||
// I'll admit, I plugged this into Wolfram Alpha:
|
// I'll admit, I plugged this into Wolfram Alpha:
|
||||||
@@ -617,7 +639,10 @@ var overviewer = {
|
|||||||
var coordsDiv = document.createElement('DIV');
|
var coordsDiv = document.createElement('DIV');
|
||||||
coordsDiv.id = 'coordsDiv';
|
coordsDiv.id = 'coordsDiv';
|
||||||
coordsDiv.innerHTML = '';
|
coordsDiv.innerHTML = '';
|
||||||
overviewer.map.controls[google.maps.ControlPosition.BOTTOM_LEFT].push(coordsDiv);
|
if (overviewerConfig.map.controls.coordsBox) {
|
||||||
|
overviewer.map.controls[google.maps.ControlPosition.BOTTOM_LEFT].push(coordsDiv);
|
||||||
|
}
|
||||||
|
|
||||||
// Update coords on mousemove
|
// Update coords on mousemove
|
||||||
google.maps.event.addListener(overviewer.map, 'mousemove', function (event) {
|
google.maps.event.addListener(overviewer.map, 'mousemove', function (event) {
|
||||||
var worldcoords = overviewer.util.fromLatLngToWorld(event.latLng.lat(), event.latLng.lng());
|
var worldcoords = overviewer.util.fromLatLngToWorld(event.latLng.lat(), event.latLng.lng());
|
||||||
@@ -684,7 +709,7 @@ var overviewer = {
|
|||||||
overviewer.util.createDropDown('Regions', items);
|
overviewer.util.createDropDown('Regions', items);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (overviewer.collections.overlays.length > 0) {
|
if (overviewerConfig.map.controls.overlays && overviewer.collections.overlays.length > 0) {
|
||||||
// overlay maps control
|
// overlay maps control
|
||||||
var items = [];
|
var items = [];
|
||||||
for (i in overviewer.collections.overlays) {
|
for (i in overviewer.collections.overlays) {
|
||||||
@@ -712,6 +737,9 @@ var overviewer = {
|
|||||||
}
|
}
|
||||||
overviewer.util.createDropDown('Overlays', items);
|
overviewer.util.createDropDown('Overlays', items);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// call out to create search box, as it's pretty complicated
|
||||||
|
overviewer.util.createSearchBox();
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Reusable method for creating drop-down menus
|
* Reusable method for creating drop-down menus
|
||||||
@@ -832,8 +860,10 @@ var overviewer = {
|
|||||||
$(searchDropDown).fadeOut();
|
$(searchDropDown).fadeOut();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
overviewer.map.controls[google.maps.ControlPosition.TOP_RIGHT].push(searchControl);
|
if (overviewerConfig.map.controls.searchBox) {
|
||||||
|
overviewer.map.controls[google.maps.ControlPosition.TOP_RIGHT].push(searchControl);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Create the pop-up infobox for when you click on a region, this can't
|
* Create the pop-up infobox for when you click on a region, this can't
|
||||||
|
|||||||
@@ -50,9 +50,18 @@ var overviewerConfig = {
|
|||||||
*/
|
*/
|
||||||
'mapType': true,
|
'mapType': true,
|
||||||
/**
|
/**
|
||||||
* The small box at the bottom that displays the link to the current map view.
|
* The coordsBox control is the box showing the XYZ coordinates
|
||||||
|
* under the cursor.
|
||||||
*/
|
*/
|
||||||
'link': true
|
'coordsBox': true,
|
||||||
|
/**
|
||||||
|
* The overlays control is the drop-down box for selecting overlays.
|
||||||
|
*/
|
||||||
|
'overlays': true,
|
||||||
|
/**
|
||||||
|
* The searchBox control is the search box for markers.
|
||||||
|
*/
|
||||||
|
'searchBox': true
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* The zoom level when the page is loaded without a specific zoom setting
|
* The zoom level when the page is loaded without a specific zoom setting
|
||||||
@@ -66,6 +75,12 @@ var overviewerConfig = {
|
|||||||
* This controls how close you can zoom in.
|
* This controls how close you can zoom in.
|
||||||
*/
|
*/
|
||||||
'maxZoom': {maxzoom},
|
'maxZoom': {maxzoom},
|
||||||
|
/**
|
||||||
|
* This tells us how many total zoom levels Overviewer rendered.
|
||||||
|
* DO NOT change this, even if you change minZoom and maxZoom, because
|
||||||
|
* it's used for marker position calculations and map resizing.
|
||||||
|
*/
|
||||||
|
'zoomLevels': {zoomlevels},
|
||||||
/**
|
/**
|
||||||
* Center on this point, in world coordinates. Should be an array, ex:
|
* Center on this point, in world coordinates. Should be an array, ex:
|
||||||
* [0,0,0]
|
* [0,0,0]
|
||||||
|
|||||||
@@ -114,6 +114,8 @@ class MapGen(object):
|
|||||||
"{minzoom}", str(0))
|
"{minzoom}", str(0))
|
||||||
config = config.replace(
|
config = config.replace(
|
||||||
"{maxzoom}", str(zoomlevel))
|
"{maxzoom}", str(zoomlevel))
|
||||||
|
config = config.replace(
|
||||||
|
"{zoomlevels}", str(zoomlevel))
|
||||||
|
|
||||||
config = config.replace("{spawn_coords}",
|
config = config.replace("{spawn_coords}",
|
||||||
json.dumps(list(self.world.spawn)))
|
json.dumps(list(self.world.spawn)))
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ class QuadtreeGen(object):
|
|||||||
indexfile = os.path.join(self.destdir, "overviewerConfig.js")
|
indexfile = os.path.join(self.destdir, "overviewerConfig.js")
|
||||||
if not os.path.exists(indexfile):
|
if not os.path.exists(indexfile):
|
||||||
return -1
|
return -1
|
||||||
matcher = re.compile(r"maxZoom.*:\s*(\d+)")
|
matcher = re.compile(r"zoomLevels(?:\'|\")\s*:\s*(\d+)")
|
||||||
p = -1
|
p = -1
|
||||||
for line in open(indexfile, "r"):
|
for line in open(indexfile, "r"):
|
||||||
res = matcher.search(line)
|
res = matcher.search(line)
|
||||||
@@ -426,21 +426,21 @@ class QuadtreeGen(object):
|
|||||||
needs_rerender = False
|
needs_rerender = False
|
||||||
get_region_mtime = world.get_region_mtime
|
get_region_mtime = world.get_region_mtime
|
||||||
for col, row, chunkx, chunky, regionfile in chunks:
|
for col, row, chunkx, chunky, regionfile in chunks:
|
||||||
|
region, regionMtime = get_region_mtime(regionfile)
|
||||||
|
|
||||||
|
# don't even check if it's not in the regionlist
|
||||||
|
if self.world.regionlist and os.path.abspath(region._filename) not in self.world.regionlist:
|
||||||
|
continue
|
||||||
|
|
||||||
# bail early if forcerender is set
|
# bail early if forcerender is set
|
||||||
if self.forcerender:
|
if self.forcerender:
|
||||||
needs_rerender = True
|
needs_rerender = True
|
||||||
break
|
break
|
||||||
|
|
||||||
# check region file mtime first.
|
# check region file mtime first.
|
||||||
region,regionMtime = get_region_mtime(regionfile)
|
|
||||||
if regionMtime <= tile_mtime:
|
if regionMtime <= tile_mtime:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# don't even check if it's not in the regionlist
|
|
||||||
if self.world.regionlist and os.path.abspath(region._filename) not in self.world.regionlist:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# checking chunk mtime
|
# checking chunk mtime
|
||||||
if region.get_chunk_timestamp(chunkx, chunky) > tile_mtime:
|
if region.get_chunk_timestamp(chunkx, chunky) > tile_mtime:
|
||||||
needs_rerender = True
|
needs_rerender = True
|
||||||
|
|||||||
@@ -173,12 +173,18 @@ generate_pseudo_data(RenderState *state, unsigned char ancilData) {
|
|||||||
data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f);
|
data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
} else if (state->block == 20) { /* glass */
|
||||||
|
/* an aditional bit for top is added to the 4 bits of check_adjacent_blocks */
|
||||||
|
if ((z != 127) && (getArrayByte3D(state->blocks, x, y, z+1) == 20)) {
|
||||||
|
data = 0;
|
||||||
|
} else {
|
||||||
|
data = 16;
|
||||||
|
}
|
||||||
|
data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f) | data;
|
||||||
|
return data;
|
||||||
} else if (state->block == 85) { /* fences */
|
} else if (state->block == 85) { /* fences */
|
||||||
return check_adjacent_blocks(state, x, y, z, state->block);
|
return check_adjacent_blocks(state, x, y, z, state->block);
|
||||||
|
|
||||||
|
|
||||||
} else if (state->block == 55) { /* redstone */
|
} else if (state->block == 55) { /* redstone */
|
||||||
/* three addiotional bit are added, one for on/off state, and
|
/* three addiotional bit are added, one for on/off state, and
|
||||||
* another two for going-up redstone wire in the same block
|
* another two for going-up redstone wire in the same block
|
||||||
@@ -352,6 +358,10 @@ chunk_render(PyObject *self, PyObject *args) {
|
|||||||
up_right_blocks_py = PyObject_GetAttrString(state.self, "up_right_blocks");
|
up_right_blocks_py = PyObject_GetAttrString(state.self, "up_right_blocks");
|
||||||
state.up_right_blocks = up_right_blocks_py;
|
state.up_right_blocks = up_right_blocks_py;
|
||||||
|
|
||||||
|
/* set up the random number generator again for each chunk
|
||||||
|
so tallgrass is in the same place, no matter what mode is used */
|
||||||
|
srand(1);
|
||||||
|
|
||||||
for (state.x = 15; state.x > -1; state.x--) {
|
for (state.x = 15; state.x > -1; state.x--) {
|
||||||
for (state.y = 0; state.y < 16; state.y++) {
|
for (state.y = 0; state.y < 16; state.y++) {
|
||||||
PyObject *blockid = NULL;
|
PyObject *blockid = NULL;
|
||||||
@@ -364,7 +374,7 @@ chunk_render(PyObject *self, PyObject *args) {
|
|||||||
for (state.z = 0; state.z < 128; state.z++) {
|
for (state.z = 0; state.z < 128; state.z++) {
|
||||||
state.imgy -= 12;
|
state.imgy -= 12;
|
||||||
|
|
||||||
/* get blockid */
|
/* get blockid */
|
||||||
state.block = getArrayByte3D(blocks_py, state.x, state.y, state.z);
|
state.block = getArrayByte3D(blocks_py, state.x, state.y, state.z);
|
||||||
if (state.block == 0) {
|
if (state.block == 0) {
|
||||||
continue;
|
continue;
|
||||||
@@ -400,7 +410,10 @@ chunk_render(PyObject *self, PyObject *args) {
|
|||||||
PyObject *tmp;
|
PyObject *tmp;
|
||||||
|
|
||||||
unsigned char ancilData = getArrayByte3D(state.blockdata_expanded, state.x, state.y, state.z);
|
unsigned char ancilData = getArrayByte3D(state.blockdata_expanded, state.x, state.y, state.z);
|
||||||
if ((state.block == 85) || (state.block == 9) || (state.block == 55) || (state.block == 54) || (state.block == 2) || (state.block == 90)) {
|
if ((state.block == 2) || (state.block == 9) ||
|
||||||
|
(state.block == 20) || (state.block == 54) ||
|
||||||
|
(state.block == 55) || (state.block == 85) ||
|
||||||
|
(state.block == 90)) {
|
||||||
ancilData = generate_pseudo_data(&state, ancilData);
|
ancilData = generate_pseudo_data(&state, ancilData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -419,14 +432,29 @@ chunk_render(PyObject *self, PyObject *args) {
|
|||||||
if (t != NULL && t != Py_None)
|
if (t != NULL && t != Py_None)
|
||||||
{
|
{
|
||||||
PyObject *src, *mask, *mask_light;
|
PyObject *src, *mask, *mask_light;
|
||||||
|
int randx = 0, randy = 0;
|
||||||
src = PyTuple_GetItem(t, 0);
|
src = PyTuple_GetItem(t, 0);
|
||||||
mask = PyTuple_GetItem(t, 1);
|
mask = PyTuple_GetItem(t, 1);
|
||||||
mask_light = PyTuple_GetItem(t, 2);
|
mask_light = PyTuple_GetItem(t, 2);
|
||||||
|
|
||||||
if (mask == Py_None)
|
if (mask == Py_None)
|
||||||
mask = src;
|
mask = src;
|
||||||
|
|
||||||
|
if (state.block == 31) {
|
||||||
|
/* add a random offset to the postion of the tall grass to make it more wild */
|
||||||
|
randx = rand() % 6 + 1 - 3;
|
||||||
|
randy = rand() % 6 + 1 - 3;
|
||||||
|
state.imgx += randx;
|
||||||
|
state.imgy += randy;
|
||||||
|
}
|
||||||
|
|
||||||
render_mode_draw(rendermode, src, mask, mask_light);
|
render_mode_draw(rendermode, src, mask, mask_light);
|
||||||
|
|
||||||
|
if (state.block == 31) {
|
||||||
|
/* undo the random offsets */
|
||||||
|
state.imgx -= randx;
|
||||||
|
state.imgy -= randy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -154,7 +154,6 @@ rendermode_normal_occluded(void *data, RenderState *state, int x, int y, int z)
|
|||||||
static void
|
static void
|
||||||
rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) {
|
rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) {
|
||||||
RenderModeNormal *self = (RenderModeNormal *)data;
|
RenderModeNormal *self = (RenderModeNormal *)data;
|
||||||
int randx = 0,randy = 0;
|
|
||||||
unsigned char data_byte;
|
unsigned char data_byte;
|
||||||
|
|
||||||
/* first, check to see if we should use biome-compatible src, mask */
|
/* first, check to see if we should use biome-compatible src, mask */
|
||||||
@@ -162,11 +161,6 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject *
|
|||||||
if (state->block == 18) {
|
if (state->block == 18) {
|
||||||
src = mask = self->leaf_texture;
|
src = mask = self->leaf_texture;
|
||||||
} else if (state->block == 31) {
|
} else if (state->block == 31) {
|
||||||
/* add a random offset to the postion of the tall grass to make it more wild */
|
|
||||||
randx = rand() % 6 + 1 - 3;
|
|
||||||
randy = rand() % 6 + 1 - 3;
|
|
||||||
state->imgx = state->imgx + randx;
|
|
||||||
state->imgy = state->imgy + randy;
|
|
||||||
data_byte = getArrayByte3D(state->blockdata_expanded, state->x, state->y, state->z);
|
data_byte = getArrayByte3D(state->blockdata_expanded, state->x, state->y, state->z);
|
||||||
if (data_byte == 1) {
|
if (data_byte == 1) {
|
||||||
src = mask = self->tall_grass_texture;
|
src = mask = self->tall_grass_texture;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import util
|
|||||||
import composite
|
import composite
|
||||||
|
|
||||||
_find_file_local_path = None
|
_find_file_local_path = None
|
||||||
def _find_file(filename, mode="rb"):
|
def _find_file(filename, mode="rb", verbose=False):
|
||||||
"""Searches for the given file and returns an open handle to it.
|
"""Searches for the given file and returns an open handle to it.
|
||||||
This searches the following locations in this order:
|
This searches the following locations in this order:
|
||||||
|
|
||||||
@@ -47,11 +47,13 @@ def _find_file(filename, mode="rb"):
|
|||||||
if _find_file_local_path:
|
if _find_file_local_path:
|
||||||
path = os.path.join(_find_file_local_path, filename)
|
path = os.path.join(_find_file_local_path, filename)
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
|
if verbose: print "Found %s in '%s'" % (filename, path)
|
||||||
return open(path, mode)
|
return open(path, mode)
|
||||||
|
|
||||||
programdir = util.get_program_path()
|
programdir = util.get_program_path()
|
||||||
path = os.path.join(programdir, filename)
|
path = os.path.join(programdir, filename)
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
|
if verbose: print "Found %s in '%s'" % (filename, path)
|
||||||
return open(path, mode)
|
return open(path, mode)
|
||||||
|
|
||||||
path = os.path.join(programdir, "overviewer_core", "data", "textures", filename)
|
path = os.path.join(programdir, "overviewer_core", "data", "textures", filename)
|
||||||
@@ -61,11 +63,13 @@ def _find_file(filename, mode="rb"):
|
|||||||
# windows special case, when the package dir doesn't exist
|
# windows special case, when the package dir doesn't exist
|
||||||
path = os.path.join(programdir, "textures", filename)
|
path = os.path.join(programdir, "textures", filename)
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
|
if verbose: print "Found %s in '%s'" % (filename, path)
|
||||||
return open(path, mode)
|
return open(path, mode)
|
||||||
|
|
||||||
if sys.platform == "darwin":
|
if sys.platform == "darwin":
|
||||||
path = os.path.join("/Applications/Minecraft", filename)
|
path = os.path.join("/Applications/Minecraft", filename)
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
|
if verbose: print "Found %s in '%s'" % (filename, path)
|
||||||
return open(path, mode)
|
return open(path, mode)
|
||||||
|
|
||||||
# Find minecraft.jar.
|
# Find minecraft.jar.
|
||||||
@@ -85,6 +89,7 @@ def _find_file(filename, mode="rb"):
|
|||||||
if os.path.exists(jarpath):
|
if os.path.exists(jarpath):
|
||||||
try:
|
try:
|
||||||
jar = zipfile.ZipFile(jarpath)
|
jar = zipfile.ZipFile(jarpath)
|
||||||
|
if verbose: print "Found %s in '%s'" % (filename, jarpath)
|
||||||
return jar.open(filename)
|
return jar.open(filename)
|
||||||
except (KeyError, IOError):
|
except (KeyError, IOError):
|
||||||
pass
|
pass
|
||||||
@@ -321,34 +326,34 @@ def _build_full_block(top, side1, side2, side3, side4, bottom=None, blockID=None
|
|||||||
|
|
||||||
A non transparent block uses top, side 3 and side 4.
|
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
|
If top is a tuple then first item is the top image and the second
|
||||||
member is an increment (integer) from 0 to 12. This increment will
|
item is an increment (integer) from 0 to 16 (pixels in the
|
||||||
used to crop the side images to look like a block and to paste all
|
original minecraft texture). This increment will be used to crop the
|
||||||
the images increment pixels lower. Using increment = 6 will create
|
side images and to paste the top image increment pixels lower, so if
|
||||||
a half-block.
|
you use an increment of 8, it willll draw a half-block.
|
||||||
|
|
||||||
NOTE: this method uses the top of the texture image (as done in
|
NOTE: this method uses the bottom of the texture image (as done in
|
||||||
minecraft with beds)
|
minecraft with beds and cackes)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
increment = 0
|
increment = 0
|
||||||
if isinstance(top, tuple):
|
if isinstance(top, tuple):
|
||||||
increment = top[1]
|
increment = int(round((top[1] / 16.)*12.)) # range increment in the block height in pixels (half texture size)
|
||||||
crop_height = int(increment * 16./12.)
|
crop_height = increment
|
||||||
top = top[0]
|
top = top[0]
|
||||||
if side1 != None:
|
if side1 != None:
|
||||||
side1 = side1.copy()
|
side1 = side1.copy()
|
||||||
ImageDraw.Draw(side1).rectangle((0, 16 - crop_height,16,16),outline=(0,0,0,0),fill=(0,0,0,0))
|
ImageDraw.Draw(side1).rectangle((0, 0,16,crop_height),outline=(0,0,0,0),fill=(0,0,0,0))
|
||||||
if side2 != None:
|
if side2 != None:
|
||||||
side2 = side2.copy()
|
side2 = side2.copy()
|
||||||
ImageDraw.Draw(side2).rectangle((0, 16 - crop_height,16,16),outline=(0,0,0,0),fill=(0,0,0,0))
|
ImageDraw.Draw(side2).rectangle((0, 0,16,crop_height),outline=(0,0,0,0),fill=(0,0,0,0))
|
||||||
if side3 != None:
|
if side3 != None:
|
||||||
side3 = side3.copy()
|
side3 = side3.copy()
|
||||||
ImageDraw.Draw(side3).rectangle((0, 16 - crop_height,16,16),outline=(0,0,0,0),fill=(0,0,0,0))
|
ImageDraw.Draw(side3).rectangle((0, 0,16,crop_height),outline=(0,0,0,0),fill=(0,0,0,0))
|
||||||
if side4 != None:
|
if side4 != None:
|
||||||
side4 = side4.copy()
|
side4 = side4.copy()
|
||||||
ImageDraw.Draw(side4).rectangle((0, 16 - crop_height,16,16),outline=(0,0,0,0),fill=(0,0,0,0))
|
ImageDraw.Draw(side4).rectangle((0, 0,16,crop_height),outline=(0,0,0,0),fill=(0,0,0,0))
|
||||||
|
|
||||||
img = Image.new("RGBA", (24,24), (38,92,255,0))
|
img = Image.new("RGBA", (24,24), (38,92,255,0))
|
||||||
|
|
||||||
@@ -362,7 +367,7 @@ def _build_full_block(top, side1, side2, side3, side4, bottom=None, blockID=None
|
|||||||
side1 = ImageEnhance.Brightness(side1).enhance(0.9)
|
side1 = ImageEnhance.Brightness(side1).enhance(0.9)
|
||||||
side1.putalpha(sidealpha)
|
side1.putalpha(sidealpha)
|
||||||
|
|
||||||
composite.alpha_over(img, side1, (0,0 + increment), side1)
|
composite.alpha_over(img, side1, (0,0), side1)
|
||||||
|
|
||||||
|
|
||||||
if side2 != None :
|
if side2 != None :
|
||||||
@@ -373,11 +378,11 @@ def _build_full_block(top, side1, side2, side3, side4, bottom=None, blockID=None
|
|||||||
side2 = ImageEnhance.Brightness(side2).enhance(0.8)
|
side2 = ImageEnhance.Brightness(side2).enhance(0.8)
|
||||||
side2.putalpha(sidealpha2)
|
side2.putalpha(sidealpha2)
|
||||||
|
|
||||||
composite.alpha_over(img, side2, (12,0 + increment), side2)
|
composite.alpha_over(img, side2, (12,0), side2)
|
||||||
|
|
||||||
if bottom != None :
|
if bottom != None :
|
||||||
bottom = transform_image(bottom, blockID)
|
bottom = transform_image(bottom, blockID)
|
||||||
composite.alpha_over(img, bottom, (0,12), top)
|
composite.alpha_over(img, bottom, (0,12), bottom)
|
||||||
|
|
||||||
# front sides
|
# front sides
|
||||||
if side3 != None :
|
if side3 != None :
|
||||||
@@ -388,7 +393,7 @@ def _build_full_block(top, side1, side2, side3, side4, bottom=None, blockID=None
|
|||||||
side3 = ImageEnhance.Brightness(side3).enhance(0.9)
|
side3 = ImageEnhance.Brightness(side3).enhance(0.9)
|
||||||
side3.putalpha(sidealpha)
|
side3.putalpha(sidealpha)
|
||||||
|
|
||||||
composite.alpha_over(img, side3, (0,6 + increment), side3)
|
composite.alpha_over(img, side3, (0,6), side3)
|
||||||
|
|
||||||
if side4 != None :
|
if side4 != None :
|
||||||
side4 = transform_image_side(side4, blockID)
|
side4 = transform_image_side(side4, blockID)
|
||||||
@@ -399,7 +404,7 @@ def _build_full_block(top, side1, side2, side3, side4, bottom=None, blockID=None
|
|||||||
side4 = ImageEnhance.Brightness(side4).enhance(0.8)
|
side4 = ImageEnhance.Brightness(side4).enhance(0.8)
|
||||||
side4.putalpha(sidealpha)
|
side4.putalpha(sidealpha)
|
||||||
|
|
||||||
composite.alpha_over(img, side4, (12,6 + increment), side4)
|
composite.alpha_over(img, side4, (12,6), side4)
|
||||||
|
|
||||||
if top != None :
|
if top != None :
|
||||||
top = transform_image(top, blockID)
|
top = transform_image(top, blockID)
|
||||||
@@ -420,7 +425,7 @@ def _build_blockimages():
|
|||||||
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
# 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,
|
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
|
# 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
||||||
34, -1, 52, 48, 49,160,144, -1,176, 74, -1, -1, -1, -1, 11, -1,
|
34, -1, 52, 48, -1,160,144, -1,176, 74, -1, -1, -1, -1, 11, -1,
|
||||||
# 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
|
# 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
|
||||||
55, -1, -1, -1, -1, 13, 12, 29, 28, 23, 22, -1, -1, 7, 9, 4,
|
55, -1, -1, -1, -1, 13, 12, 29, 28, 23, 22, -1, -1, 7, 9, 4,
|
||||||
# 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
# 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
||||||
@@ -437,7 +442,7 @@ def _build_blockimages():
|
|||||||
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
# 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,
|
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
|
# 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
||||||
34, -1, 52, 48, 49,160,144, -1,192, 74, -1, -1,- 1, -1, 11, -1,
|
34, -1, 52, 48, -1,160,144, -1,192, 74, -1, -1,- 1, -1, 11, -1,
|
||||||
# 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
|
# 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
|
||||||
55, -1, -1, -1, -1, 13, 12, 29, 28, 23, 22, -1, -1, 7, 8, 35,
|
55, -1, -1, -1, -1, 13, 12, 29, 28, 23, 22, -1, -1, 7, 8, 35,
|
||||||
# 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
# 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
||||||
@@ -548,33 +553,35 @@ def generate_special_texture(blockID, data):
|
|||||||
return generate_texture_tuple(img, blockID)
|
return generate_texture_tuple(img, blockID)
|
||||||
|
|
||||||
|
|
||||||
if blockID == 9: # spring water, flowing water and waterfall water
|
if blockID == 9 or blockID == 20: # spring water, flowing water and waterfall water, AND glass
|
||||||
|
# water and glass share the way to be rendered
|
||||||
watertexture = _load_image("water.png")
|
if blockID == 9:
|
||||||
|
texture = _load_image("water.png")
|
||||||
|
else:
|
||||||
|
texture = terrain_images[49]
|
||||||
|
|
||||||
if (data & 0b10000) == 16:
|
if (data & 0b10000) == 16:
|
||||||
top = watertexture
|
top = texture
|
||||||
|
|
||||||
else: top = None
|
else: top = None
|
||||||
|
|
||||||
if (data & 0b0001) == 1:
|
if (data & 0b0001) == 1:
|
||||||
side1 = watertexture # top left
|
side1 = texture # top left
|
||||||
else: side1 = None
|
else: side1 = None
|
||||||
|
|
||||||
if (data & 0b1000) == 8:
|
if (data & 0b1000) == 8:
|
||||||
side2 = watertexture # top right
|
side2 = texture # top right
|
||||||
else: side2 = None
|
else: side2 = None
|
||||||
|
|
||||||
if (data & 0b0010) == 2:
|
if (data & 0b0010) == 2:
|
||||||
side3 = watertexture # bottom left
|
side3 = texture # bottom left
|
||||||
else: side3 = None
|
else: side3 = None
|
||||||
|
|
||||||
if (data & 0b0100) == 4:
|
if (data & 0b0100) == 4:
|
||||||
side4 = watertexture # bottom right
|
side4 = texture # bottom right
|
||||||
else: side4 = None
|
else: side4 = None
|
||||||
|
|
||||||
img = _build_full_block(top,None,None,side3,side4)
|
img = _build_full_block(top,None,None,side3,side4)
|
||||||
|
|
||||||
return generate_texture_tuple(img, blockID)
|
return generate_texture_tuple(img, blockID)
|
||||||
|
|
||||||
|
|
||||||
@@ -600,7 +607,7 @@ def generate_special_texture(blockID, data):
|
|||||||
|
|
||||||
|
|
||||||
if blockID == 26: # bed
|
if blockID == 26: # bed
|
||||||
increment = 5
|
increment = 8
|
||||||
left_face = None
|
left_face = None
|
||||||
right_face = None
|
right_face = None
|
||||||
if data & 0x8 == 0x8: # head of the bed
|
if data & 0x8 == 0x8: # head of the bed
|
||||||
@@ -644,6 +651,7 @@ def generate_special_texture(blockID, data):
|
|||||||
|
|
||||||
return generate_texture_tuple(img, blockID)
|
return generate_texture_tuple(img, blockID)
|
||||||
|
|
||||||
|
|
||||||
if blockID == 31: # tall grass
|
if blockID == 31: # tall grass
|
||||||
if data == 0: # dead shrub
|
if data == 0: # dead shrub
|
||||||
texture = terrain_images[55]
|
texture = terrain_images[55]
|
||||||
@@ -656,8 +664,134 @@ def generate_special_texture(blockID, data):
|
|||||||
|
|
||||||
img = _build_block(texture, texture, blockID)
|
img = _build_block(texture, texture, blockID)
|
||||||
return generate_texture_tuple(img,31)
|
return generate_texture_tuple(img,31)
|
||||||
|
|
||||||
|
|
||||||
|
if blockID in (29,33): # sticky and normal body piston.
|
||||||
|
if blockID == 29: # sticky
|
||||||
|
piston_t = terrain_images[106].copy()
|
||||||
|
else: # normal
|
||||||
|
piston_t = terrain_images[107].copy()
|
||||||
|
|
||||||
|
# other textures
|
||||||
|
side_t = terrain_images[108].copy()
|
||||||
|
back_t = terrain_images[109].copy()
|
||||||
|
interior_t = terrain_images[110].copy()
|
||||||
|
|
||||||
|
if data & 0x08 == 0x08: # pushed out, non full blocks, tricky stuff
|
||||||
|
# remove piston texture from piston body
|
||||||
|
ImageDraw.Draw(side_t).rectangle((0, 0,16,3),outline=(0,0,0,0),fill=(0,0,0,0))
|
||||||
|
|
||||||
|
if data & 0x07 == 0x0: # down
|
||||||
|
side_t = side_t.rotate(180)
|
||||||
|
img = _build_full_block(back_t ,None ,None ,side_t, side_t)
|
||||||
|
|
||||||
|
elif data & 0x07 == 0x1: # up
|
||||||
|
img = _build_full_block((interior_t, 4) ,None ,None ,side_t, side_t)
|
||||||
|
|
||||||
|
elif data & 0x07 == 0x2: # east
|
||||||
|
img = _build_full_block(side_t , None, None ,side_t.rotate(90), back_t)
|
||||||
|
|
||||||
|
elif data & 0x07 == 0x3: # west
|
||||||
|
img = _build_full_block(side_t.rotate(180) ,None ,None ,side_t.rotate(270), None)
|
||||||
|
temp = transform_image_side(interior_t, blockID)
|
||||||
|
temp = temp.transpose(Image.FLIP_LEFT_RIGHT)
|
||||||
|
composite.alpha_over(img, temp, (9,5), temp)
|
||||||
|
|
||||||
|
elif data & 0x07 == 0x4: # north
|
||||||
|
img = _build_full_block(side_t.rotate(90) ,None ,None , None, side_t.rotate(270))
|
||||||
|
temp = transform_image_side(interior_t, blockID)
|
||||||
|
composite.alpha_over(img, temp, (3,5), temp)
|
||||||
|
|
||||||
|
elif data & 0x07 == 0x5: # south
|
||||||
|
img = _build_full_block(side_t.rotate(270) ,None , None ,back_t, side_t.rotate(90))
|
||||||
|
|
||||||
|
else: # pushed in, normal full blocks, easy stuff
|
||||||
|
if data & 0x07 == 0x0: # down
|
||||||
|
side_t = side_t.rotate(180)
|
||||||
|
img = _build_full_block(back_t ,None ,None ,side_t, side_t)
|
||||||
|
elif data & 0x07 == 0x1: # up
|
||||||
|
img = _build_full_block(piston_t ,None ,None ,side_t, side_t)
|
||||||
|
elif data & 0x07 == 0x2: # east
|
||||||
|
img = _build_full_block(side_t ,None ,None ,side_t.rotate(90), back_t)
|
||||||
|
elif data & 0x07 == 0x3: # west
|
||||||
|
img = _build_full_block(side_t.rotate(180) ,None ,None ,side_t.rotate(270), piston_t)
|
||||||
|
elif data & 0x07 == 0x4: # north
|
||||||
|
img = _build_full_block(side_t.rotate(90) ,None ,None ,piston_t, side_t.rotate(270))
|
||||||
|
elif data & 0x07 == 0x5: # south
|
||||||
|
img = _build_full_block(side_t.rotate(270) ,None ,None ,back_t, side_t.rotate(90))
|
||||||
|
|
||||||
|
|
||||||
|
return generate_texture_tuple(img, blockID)
|
||||||
|
|
||||||
|
|
||||||
|
if blockID == 34: # piston extension (sticky and normal)
|
||||||
|
if (data & 0x8) == 0x8: # sticky
|
||||||
|
piston_t = terrain_images[106].copy()
|
||||||
|
else: # normal
|
||||||
|
piston_t = terrain_images[107].copy()
|
||||||
|
|
||||||
|
# other textures
|
||||||
|
side_t = terrain_images[108].copy()
|
||||||
|
back_t = terrain_images[107].copy()
|
||||||
|
# crop piston body
|
||||||
|
ImageDraw.Draw(side_t).rectangle((0, 4,16,16),outline=(0,0,0,0),fill=(0,0,0,0))
|
||||||
|
|
||||||
|
# generate the horizontal piston extension stick
|
||||||
|
h_stick = Image.new("RGBA", (24,24), (38,92,255,0))
|
||||||
|
temp = transform_image_side(side_t, blockID)
|
||||||
|
composite.alpha_over(h_stick, temp, (1,7), temp)
|
||||||
|
temp = transform_image(side_t.rotate(90))
|
||||||
|
composite.alpha_over(h_stick, temp, (1,1), temp)
|
||||||
|
# Darken it
|
||||||
|
sidealpha = h_stick.split()[3]
|
||||||
|
h_stick = ImageEnhance.Brightness(h_stick).enhance(0.85)
|
||||||
|
h_stick.putalpha(sidealpha)
|
||||||
|
|
||||||
|
# generate the vertical piston extension stick
|
||||||
|
v_stick = Image.new("RGBA", (24,24), (38,92,255,0))
|
||||||
|
temp = transform_image_side(side_t.rotate(90), blockID)
|
||||||
|
composite.alpha_over(v_stick, temp, (12,6), temp)
|
||||||
|
temp = temp.transpose(Image.FLIP_LEFT_RIGHT)
|
||||||
|
composite.alpha_over(v_stick, temp, (1,6), temp)
|
||||||
|
# Darken it
|
||||||
|
sidealpha = v_stick.split()[3]
|
||||||
|
v_stick = ImageEnhance.Brightness(v_stick).enhance(0.85)
|
||||||
|
v_stick.putalpha(sidealpha)
|
||||||
|
|
||||||
|
# Piston orientation is stored in the 3 first bits
|
||||||
|
if data & 0x07 == 0x0: # down
|
||||||
|
side_t = side_t.rotate(180)
|
||||||
|
img = _build_full_block((back_t, 12) ,None ,None ,side_t, side_t)
|
||||||
|
composite.alpha_over(img, v_stick, (0,-3), v_stick)
|
||||||
|
elif data & 0x07 == 0x1: # up
|
||||||
|
img = Image.new("RGBA", (24,24), (38,92,255,0))
|
||||||
|
img2 = _build_full_block(piston_t ,None ,None ,side_t, side_t)
|
||||||
|
composite.alpha_over(img, v_stick, (0,4), v_stick)
|
||||||
|
composite.alpha_over(img, img2, (0,0), img2)
|
||||||
|
elif data & 0x07 == 0x2: # east
|
||||||
|
img = _build_full_block(side_t ,None ,None ,side_t.rotate(90), None)
|
||||||
|
temp = transform_image_side(back_t, blockID).transpose(Image.FLIP_LEFT_RIGHT)
|
||||||
|
composite.alpha_over(img, temp, (2,2), temp)
|
||||||
|
composite.alpha_over(img, h_stick, (6,3), h_stick)
|
||||||
|
elif data & 0x07 == 0x3: # west
|
||||||
|
img = Image.new("RGBA", (24,24), (38,92,255,0))
|
||||||
|
img2 = _build_full_block(side_t.rotate(180) ,None ,None ,side_t.rotate(270), piston_t)
|
||||||
|
composite.alpha_over(img, h_stick, (0,0), h_stick)
|
||||||
|
composite.alpha_over(img, img2, (0,0), img2)
|
||||||
|
elif data & 0x07 == 0x4: # north
|
||||||
|
img = _build_full_block(side_t.rotate(90) ,None ,None , piston_t, side_t.rotate(270))
|
||||||
|
composite.alpha_over(img, h_stick.transpose(Image.FLIP_LEFT_RIGHT), (0,0), h_stick.transpose(Image.FLIP_LEFT_RIGHT))
|
||||||
|
elif data & 0x07 == 0x5: # south
|
||||||
|
img = Image.new("RGBA", (24,24), (38,92,255,0))
|
||||||
|
img2 = _build_full_block(side_t.rotate(270) ,None ,None ,None, side_t.rotate(90))
|
||||||
|
temp = transform_image_side(back_t, blockID)
|
||||||
|
composite.alpha_over(img2, temp, (10,2), temp)
|
||||||
|
composite.alpha_over(img, img2, (0,0), img2)
|
||||||
|
composite.alpha_over(img, h_stick.transpose(Image.FLIP_LEFT_RIGHT), (-3,2), h_stick.transpose(Image.FLIP_LEFT_RIGHT))
|
||||||
|
|
||||||
|
return generate_texture_tuple(img, blockID)
|
||||||
|
|
||||||
|
|
||||||
if blockID == 35: # wool
|
if blockID == 35: # wool
|
||||||
if data == 0: # white
|
if data == 0: # white
|
||||||
top = side = terrain_images[64]
|
top = side = terrain_images[64]
|
||||||
@@ -1076,7 +1210,7 @@ def generate_special_texture(blockID, data):
|
|||||||
|
|
||||||
# mask out the high bits to figure out the orientation
|
# mask out the high bits to figure out the orientation
|
||||||
img = Image.new("RGBA", (24,24), (38,92,255,0))
|
img = Image.new("RGBA", (24,24), (38,92,255,0))
|
||||||
if (data & 0x03) == 0:
|
if (data & 0x03) == 0: # northeast corner
|
||||||
if not swung:
|
if not swung:
|
||||||
tex = transform_image_side(raw_door)
|
tex = transform_image_side(raw_door)
|
||||||
composite.alpha_over(img, tex, (0,6), tex)
|
composite.alpha_over(img, tex, (0,6), tex)
|
||||||
@@ -1086,7 +1220,7 @@ def generate_special_texture(blockID, data):
|
|||||||
tex = tex.transpose(Image.FLIP_LEFT_RIGHT)
|
tex = tex.transpose(Image.FLIP_LEFT_RIGHT)
|
||||||
composite.alpha_over(img, tex, (0,0), tex)
|
composite.alpha_over(img, tex, (0,0), tex)
|
||||||
|
|
||||||
if (data & 0x03) == 1:
|
if (data & 0x03) == 1: # southeast corner
|
||||||
if not swung:
|
if not swung:
|
||||||
tex = transform_image_side(raw_door).transpose(Image.FLIP_LEFT_RIGHT)
|
tex = transform_image_side(raw_door).transpose(Image.FLIP_LEFT_RIGHT)
|
||||||
composite.alpha_over(img, tex, (0,0), tex)
|
composite.alpha_over(img, tex, (0,0), tex)
|
||||||
@@ -1094,7 +1228,7 @@ def generate_special_texture(blockID, data):
|
|||||||
tex = transform_image_side(raw_door)
|
tex = transform_image_side(raw_door)
|
||||||
composite.alpha_over(img, tex, (12,0), tex)
|
composite.alpha_over(img, tex, (12,0), tex)
|
||||||
|
|
||||||
if (data & 0x03) == 2:
|
if (data & 0x03) == 2: # southwest corner
|
||||||
if not swung:
|
if not swung:
|
||||||
tex = transform_image_side(raw_door.transpose(Image.FLIP_LEFT_RIGHT))
|
tex = transform_image_side(raw_door.transpose(Image.FLIP_LEFT_RIGHT))
|
||||||
composite.alpha_over(img, tex, (12,0), tex)
|
composite.alpha_over(img, tex, (12,0), tex)
|
||||||
@@ -1102,7 +1236,7 @@ def generate_special_texture(blockID, data):
|
|||||||
tex = transform_image_side(raw_door).transpose(Image.FLIP_LEFT_RIGHT)
|
tex = transform_image_side(raw_door).transpose(Image.FLIP_LEFT_RIGHT)
|
||||||
composite.alpha_over(img, tex, (12,6), tex)
|
composite.alpha_over(img, tex, (12,6), tex)
|
||||||
|
|
||||||
if (data & 0x03) == 3:
|
if (data & 0x03) == 3: # northwest corner
|
||||||
if not swung:
|
if not swung:
|
||||||
tex = transform_image_side(raw_door.transpose(Image.FLIP_LEFT_RIGHT)).transpose(Image.FLIP_LEFT_RIGHT)
|
tex = transform_image_side(raw_door.transpose(Image.FLIP_LEFT_RIGHT)).transpose(Image.FLIP_LEFT_RIGHT)
|
||||||
composite.alpha_over(img, tex, (12,6), tex)
|
composite.alpha_over(img, tex, (12,6), tex)
|
||||||
@@ -1388,21 +1522,21 @@ def generate_special_texture(blockID, data):
|
|||||||
|
|
||||||
img = Image.new("RGBA", (24,24), (38,92,255,0))
|
img = Image.new("RGBA", (24,24), (38,92,255,0))
|
||||||
|
|
||||||
composite.alpha_over(img, side, (1,12), side)
|
composite.alpha_over(img, side, (1,6), side)
|
||||||
composite.alpha_over(img, otherside, (11,13), otherside) # workaround, fixes a hole
|
composite.alpha_over(img, otherside, (11,7), otherside) # workaround, fixes a hole
|
||||||
composite.alpha_over(img, otherside, (12,12), otherside)
|
composite.alpha_over(img, otherside, (12,6), otherside)
|
||||||
composite.alpha_over(img, top, (0,6), top)
|
composite.alpha_over(img, top, (0,6), top)
|
||||||
|
|
||||||
return generate_texture_tuple(img, blockID)
|
return generate_texture_tuple(img, blockID)
|
||||||
|
|
||||||
|
|
||||||
if blockID in (93, 94): # redstone repeaters, ON and OFF
|
if blockID in (93, 94): # redstone repeaters (diodes), ON and OFF
|
||||||
# NOTE: this function uses the redstone torches generated above,
|
# NOTE: this function uses the redstone torches generated above,
|
||||||
# this must run after the function of the torches.
|
# this must run after the function of the torches.
|
||||||
|
|
||||||
top = terrain_images[131] if blockID == 93 else terrain_images[147]
|
top = terrain_images[131] if blockID == 93 else terrain_images[147]
|
||||||
side = terrain_images[5]
|
side = terrain_images[5]
|
||||||
increment = 9
|
increment = 13
|
||||||
|
|
||||||
if (data & 0x3) == 0: # pointing east
|
if (data & 0x3) == 0: # pointing east
|
||||||
pass
|
pass
|
||||||
@@ -1527,7 +1661,7 @@ def generate_special_texture(blockID, data):
|
|||||||
img = _build_full_block(None, None, None, texture, None)
|
img = _build_full_block(None, None, None, texture, None)
|
||||||
|
|
||||||
elif data & 0x4 == 0: # closed trapdoor
|
elif data & 0x4 == 0: # closed trapdoor
|
||||||
img = _build_full_block((texture, 9), None, None, texture, texture)
|
img = _build_full_block((texture, 12), None, None, texture, texture)
|
||||||
|
|
||||||
return generate_texture_tuple(img, blockID)
|
return generate_texture_tuple(img, blockID)
|
||||||
|
|
||||||
@@ -1604,9 +1738,10 @@ def getBiomeData(worlddir, chunkX, chunkY):
|
|||||||
# (when adding new blocks here and in generate_special_textures,
|
# (when adding new blocks here and in generate_special_textures,
|
||||||
# please, if possible, keep the ascending order of blockid value)
|
# please, if possible, keep the ascending order of blockid value)
|
||||||
|
|
||||||
special_blocks = set([ 2, 6, 9, 17, 18, 26, 23, 27, 28, 31, 35, 43, 44,
|
special_blocks = set([ 2, 6, 9, 17, 18, 20, 26, 23, 27, 28, 29, 31, 33,
|
||||||
50, 51, 53, 54, 55, 58, 59, 61, 62, 63, 64, 65, 66,
|
34, 35, 43, 44, 50, 51, 53, 54, 55, 58, 59, 61, 62,
|
||||||
67, 68, 71, 75, 76, 85, 86, 90, 91, 92, 93, 94, 96])
|
63, 64, 65, 66, 67, 68, 71, 75, 76, 85, 86, 90, 91,
|
||||||
|
92, 93, 94, 96])
|
||||||
|
|
||||||
# this is a map of special blockIDs to a list of all
|
# this is a map of special blockIDs to a list of all
|
||||||
# possible values for ancillary data that it might have.
|
# possible values for ancillary data that it might have.
|
||||||
@@ -1616,10 +1751,14 @@ special_map = {}
|
|||||||
special_map[6] = range(16) # saplings: usual, spruce, birch and future ones (rendered as usual saplings)
|
special_map[6] = range(16) # saplings: usual, spruce, birch and future ones (rendered as usual saplings)
|
||||||
special_map[9] = range(32) # water: spring,flowing, waterfall, and others (unknown) ancildata values, uses pseudo data
|
special_map[9] = range(32) # water: spring,flowing, waterfall, and others (unknown) ancildata values, uses pseudo data
|
||||||
special_map[17] = range(3) # wood: normal, birch and pine
|
special_map[17] = range(3) # wood: normal, birch and pine
|
||||||
|
special_map[20] = range(32) # glass, used to only render the exterior surface, uses pseudo data
|
||||||
special_map[26] = range(12) # bed, orientation
|
special_map[26] = range(12) # bed, orientation
|
||||||
special_map[23] = range(6) # dispensers, orientation
|
special_map[23] = range(6) # dispensers, orientation
|
||||||
special_map[27] = range(14) # powered rail, orientation/slope and powered/unpowered
|
special_map[27] = range(14) # powered rail, orientation/slope and powered/unpowered
|
||||||
special_map[28] = range(6) # detector rail, orientation/slope
|
special_map[28] = range(6) # detector rail, orientation/slope
|
||||||
|
special_map[29] = (0,1,2,3,4,5,8,9,10,11,12,13) # sticky piston body, orientation, pushed in/out
|
||||||
|
special_map[33] = (0,1,2,3,4,5,8,9,10,11,12,13) # normal piston body, orientation, pushed in/out
|
||||||
|
special_map[34] = (0,1,2,3,4,5,8,9,10,11,12,13) # normal and sticky piston extension, orientation, sticky/normal
|
||||||
special_map[35] = range(16) # wool, colored and white
|
special_map[35] = range(16) # wool, colored and white
|
||||||
special_map[43] = range(4) # stone, sandstone, wooden and cobblestone double-slab
|
special_map[43] = range(4) # stone, sandstone, wooden and cobblestone double-slab
|
||||||
special_map[44] = range(4) # stone, sandstone, wooden and cobblestone slab
|
special_map[44] = range(4) # stone, sandstone, wooden and cobblestone slab
|
||||||
@@ -1670,9 +1809,10 @@ biome_tall_fern_texture = None
|
|||||||
biome_leaf_texture = None
|
biome_leaf_texture = None
|
||||||
specialblockmap = None
|
specialblockmap = None
|
||||||
|
|
||||||
def generate(path=None):
|
def generate(path=None,texture_size=24):
|
||||||
global _find_file_local_path
|
global _find_file_local_path, texture_dimensions
|
||||||
_find_file_local_path = path
|
_find_file_local_path = path
|
||||||
|
texture_dimensions = (texture_size, texture_size)
|
||||||
|
|
||||||
# This maps terainids to 16x16 images
|
# This maps terainids to 16x16 images
|
||||||
global terrain_images
|
global terrain_images
|
||||||
@@ -1696,3 +1836,30 @@ def generate(path=None):
|
|||||||
for blockID in special_blocks:
|
for blockID in special_blocks:
|
||||||
for data in special_map[blockID]:
|
for data in special_map[blockID]:
|
||||||
specialblockmap[(blockID, data)] = generate_special_texture(blockID, data)
|
specialblockmap[(blockID, data)] = generate_special_texture(blockID, data)
|
||||||
|
|
||||||
|
if texture_size != 24:
|
||||||
|
# rescale biome textures.
|
||||||
|
biome_grass_texture = biome_grass_texture.resize(texture_dimensions, Image.ANTIALIAS)
|
||||||
|
biome_leaf_texture = biome_leaf_texture.resize(texture_dimensions, Image.ANTIALIAS)
|
||||||
|
biome_tall_grass_texture = biome_tall_grass_texture.resize(texture_dimensions, Image.ANTIALIAS)
|
||||||
|
biome_tall_fern_texture = biome_tall_fern_texture.resize(texture_dimensions, Image.ANTIALIAS)
|
||||||
|
|
||||||
|
# rescale the normal block images
|
||||||
|
for i in range(len(blockmap)):
|
||||||
|
if blockmap[i] != None:
|
||||||
|
block = blockmap[i]
|
||||||
|
alpha = block[1]
|
||||||
|
block = block[0]
|
||||||
|
block.putalpha(alpha)
|
||||||
|
scaled_block = block.resize(texture_dimensions, Image.ANTIALIAS)
|
||||||
|
blockmap[i] = generate_texture_tuple(scaled_block, i)
|
||||||
|
|
||||||
|
# rescale the special block images
|
||||||
|
for blockid, data in iter(specialblockmap):
|
||||||
|
block = specialblockmap[(blockid,data)]
|
||||||
|
if block != None:
|
||||||
|
alpha = block[1]
|
||||||
|
block = block[0]
|
||||||
|
block.putalpha(alpha)
|
||||||
|
scaled_block = block.resize(texture_dimensions, Image.ANTIALIAS)
|
||||||
|
specialblockmap[(blockid,data)] = generate_texture_tuple(scaled_block, blockid)
|
||||||
|
|||||||
@@ -209,25 +209,27 @@ class World(object):
|
|||||||
chunkX = spawnX/16
|
chunkX = spawnX/16
|
||||||
chunkY = spawnZ/16
|
chunkY = spawnZ/16
|
||||||
|
|
||||||
## The filename of this chunk
|
try:
|
||||||
chunkFile = self.get_region_path(chunkX, chunkY)
|
## The filename of this chunk
|
||||||
|
chunkFile = self.get_region_path(chunkX, chunkY)
|
||||||
if chunkFile is not None:
|
if chunkFile is not None:
|
||||||
data = nbt.load_from_region(chunkFile, chunkX, chunkY)[1]
|
data = nbt.load_from_region(chunkFile, chunkX, chunkY)[1]
|
||||||
if data is not None:
|
if data is not None:
|
||||||
level = data['Level']
|
level = data['Level']
|
||||||
blockArray = numpy.frombuffer(level['Blocks'], dtype=numpy.uint8).reshape((16,16,128))
|
blockArray = numpy.frombuffer(level['Blocks'], dtype=numpy.uint8).reshape((16,16,128))
|
||||||
|
|
||||||
## The block for spawn *within* the chunk
|
## The block for spawn *within* the chunk
|
||||||
inChunkX = spawnX - (chunkX*16)
|
inChunkX = spawnX - (chunkX*16)
|
||||||
inChunkZ = spawnZ - (chunkY*16)
|
inChunkZ = spawnZ - (chunkY*16)
|
||||||
|
|
||||||
## find the first air block
|
## find the first air block
|
||||||
while (blockArray[inChunkX, inChunkZ, spawnY] != 0):
|
while (blockArray[inChunkX, inChunkZ, spawnY] != 0):
|
||||||
spawnY += 1
|
spawnY += 1
|
||||||
if spawnY == 128:
|
if spawnY == 128:
|
||||||
break
|
break
|
||||||
|
except ChunkCorrupt:
|
||||||
|
#ignore corrupt spawn, and continue
|
||||||
|
pass
|
||||||
self.POI.append( dict(x=spawnX, y=spawnY, z=spawnZ,
|
self.POI.append( dict(x=spawnX, y=spawnY, z=spawnZ,
|
||||||
msg="Spawn", type="spawn", chunk=(chunkX, chunkY)))
|
msg="Spawn", type="spawn", chunk=(chunkX, chunkY)))
|
||||||
self.spawn = (spawnX, spawnY, spawnZ)
|
self.spawn = (spawnX, spawnY, spawnZ)
|
||||||
|
|||||||
55
setup.py
55
setup.py
@@ -6,6 +6,7 @@ from distutils.command.build import build
|
|||||||
from distutils.command.clean import clean
|
from distutils.command.clean import clean
|
||||||
from distutils.command.build_ext import build_ext
|
from distutils.command.build_ext import build_ext
|
||||||
from distutils.command.sdist import sdist
|
from distutils.command.sdist import sdist
|
||||||
|
from distutils.cmd import Command
|
||||||
from distutils.dir_util import remove_tree
|
from distutils.dir_util import remove_tree
|
||||||
from distutils.sysconfig import get_python_inc
|
from distutils.sysconfig import get_python_inc
|
||||||
from distutils import log
|
from distutils import log
|
||||||
@@ -74,6 +75,17 @@ def recursive_data_files(src, dest=None):
|
|||||||
ret.append((current_dest, current_sources))
|
ret.append((current_dest, current_sources))
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
# helper to create a 'package_data'-type sequence recursively for a given dir
|
||||||
|
def recursive_package_data(src, package_dir='overviewer_core'):
|
||||||
|
full_src = os.path.join(package_dir, src)
|
||||||
|
ret = []
|
||||||
|
for dirpath, dirnames, filenames in os.walk(full_src, topdown=False):
|
||||||
|
current_path = os.path.relpath(dirpath, package_dir)
|
||||||
|
for filename in filenames:
|
||||||
|
ret.append(os.path.join(current_path, filename))
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
#
|
#
|
||||||
# py2exe options
|
# py2exe options
|
||||||
#
|
#
|
||||||
@@ -105,9 +117,8 @@ if py2app is not None:
|
|||||||
|
|
||||||
setup_kwargs['packages'] = ['overviewer_core']
|
setup_kwargs['packages'] = ['overviewer_core']
|
||||||
setup_kwargs['scripts'] = ['overviewer.py']
|
setup_kwargs['scripts'] = ['overviewer.py']
|
||||||
setup_kwargs['package_data'] = {'overviewer_core':
|
setup_kwargs['package_data'] = {'overviewer_core': recursive_package_data('data/textures') + recursive_package_data('data/web_assets')}
|
||||||
['data/textures/*',
|
|
||||||
'data/web_assets/*']}
|
|
||||||
if py2exe is None:
|
if py2exe is None:
|
||||||
setup_kwargs['data_files'] = [('share/doc/minecraft-overviewer', doc_files)]
|
setup_kwargs['data_files'] = [('share/doc/minecraft-overviewer', doc_files)]
|
||||||
|
|
||||||
@@ -175,12 +186,15 @@ class CustomClean(clean):
|
|||||||
pretty_fname)
|
pretty_fname)
|
||||||
|
|
||||||
versionpath = os.path.join("overviewer_core", "overviewer_version.py")
|
versionpath = os.path.join("overviewer_core", "overviewer_version.py")
|
||||||
try:
|
if os.path.exists(versionpath):
|
||||||
if not self.dry_run:
|
try:
|
||||||
os.remove(versionpath)
|
if not self.dry_run:
|
||||||
log.info("removing '%s'", versionpath)
|
os.remove(versionpath)
|
||||||
except OSError:
|
log.info("removing '%s'", versionpath)
|
||||||
log.warn("'%s' could not be cleaned -- permission denied", versionpath)
|
except OSError:
|
||||||
|
log.warn("'%s' could not be cleaned -- permission denied", versionpath)
|
||||||
|
else:
|
||||||
|
log.debug("'%s' does not exist -- can't clean it", versionpath)
|
||||||
|
|
||||||
# now try to purge all *.pyc files
|
# now try to purge all *.pyc files
|
||||||
for root, dirs, files in os.walk(os.path.join(os.path.dirname(__file__), ".")):
|
for root, dirs, files in os.walk(os.path.join(os.path.dirname(__file__), ".")):
|
||||||
@@ -203,7 +217,7 @@ def generate_version_py():
|
|||||||
f.write(outstr)
|
f.write(outstr)
|
||||||
f.close()
|
f.close()
|
||||||
except:
|
except:
|
||||||
print "WARNING: failed to build overview_version file"
|
print "WARNING: failed to build overviewer_version file"
|
||||||
|
|
||||||
class CustomSDist(sdist):
|
class CustomSDist(sdist):
|
||||||
def run(self):
|
def run(self):
|
||||||
@@ -232,11 +246,32 @@ class CustomBuildExt(build_ext):
|
|||||||
self.inplace = True
|
self.inplace = True
|
||||||
build_ext.build_extensions(self)
|
build_ext.build_extensions(self)
|
||||||
|
|
||||||
|
class CheckTerrain(Command):
|
||||||
|
user_options=[]
|
||||||
|
def initialize_options(self):
|
||||||
|
pass
|
||||||
|
def finalize_options(self):
|
||||||
|
pass
|
||||||
|
def run(self):
|
||||||
|
from overviewer_core.textures import _find_file
|
||||||
|
import hashlib
|
||||||
|
import zipfile
|
||||||
|
print "checking..."
|
||||||
|
try:
|
||||||
|
f = _find_file("terrain.png", verbose=True)
|
||||||
|
except IOError:
|
||||||
|
log.error("Could not find the file terrain.png")
|
||||||
|
return
|
||||||
|
|
||||||
|
h = hashlib.sha1()
|
||||||
|
h.update(f.read())
|
||||||
|
log.info("Hash of terrain.png file is: %s", h.hexdigest())
|
||||||
|
|
||||||
setup_kwargs['cmdclass']['clean'] = CustomClean
|
setup_kwargs['cmdclass']['clean'] = CustomClean
|
||||||
setup_kwargs['cmdclass']['sdist'] = CustomSDist
|
setup_kwargs['cmdclass']['sdist'] = CustomSDist
|
||||||
setup_kwargs['cmdclass']['build'] = CustomBuild
|
setup_kwargs['cmdclass']['build'] = CustomBuild
|
||||||
setup_kwargs['cmdclass']['build_ext'] = CustomBuildExt
|
setup_kwargs['cmdclass']['build_ext'] = CustomBuildExt
|
||||||
|
setup_kwargs['cmdclass']['check_terrain'] = CheckTerrain
|
||||||
###
|
###
|
||||||
|
|
||||||
setup(**setup_kwargs)
|
setup(**setup_kwargs)
|
||||||
|
|||||||
Reference in New Issue
Block a user