Merged master into brownan-chunkscan
This pulls in all the 1.9prep and textures.py updates into brownan-chunkscan
This commit is contained in:
@@ -57,6 +57,7 @@ feature.
|
|||||||
* Ryan McCue <ryanmccue@cubegames.net>
|
* Ryan McCue <ryanmccue@cubegames.net>
|
||||||
* Morlok8k <otis.spankmeyer@gmail.com>
|
* Morlok8k <otis.spankmeyer@gmail.com>
|
||||||
* Ryan Rector <rmrector@gmail.com>
|
* Ryan Rector <rmrector@gmail.com>
|
||||||
|
* Jason Scheirer <jason.scheirer@gmail.com>
|
||||||
* Gregory Short <gshort2@gmail.com>
|
* Gregory Short <gshort2@gmail.com>
|
||||||
* Sam Steele <sam@sigbox.c99.org>
|
* Sam Steele <sam@sigbox.c99.org>
|
||||||
* timwolla <timwolla@mail.develfusion.com>
|
* timwolla <timwolla@mail.develfusion.com>
|
||||||
|
|||||||
@@ -24,6 +24,41 @@ files.
|
|||||||
Command line options
|
Command line options
|
||||||
====================
|
====================
|
||||||
|
|
||||||
|
All Options:
|
||||||
|
|
||||||
|
======================================== ==================================
|
||||||
|
:option:`--advanced-help` Print out help on all options
|
||||||
|
:option:`--bg-color` Change the background of the map
|
||||||
|
:option:`--changelist` Outputs a list of changed tiles
|
||||||
|
:option:`--changelist-format` Sets the format of the change list
|
||||||
|
:option:`--check-terrain` Output information on the textures
|
||||||
|
:option:`--display-config` Displays the configuration
|
||||||
|
:option:`--forcerender` Forces every tile to render
|
||||||
|
:option:`-h`, :option:`--help <-h>` Prints help on the basic options
|
||||||
|
:option:`--imgformat` Choose from png or jpg output
|
||||||
|
:option:`--imgquality` Change jpg output quality
|
||||||
|
:option:`--list-rendermodes` List the installed rendermodes
|
||||||
|
:option:`--no-signs` Do not place signs on the map
|
||||||
|
:option:`--north-direction` Choose which direction is north
|
||||||
|
:option:`--optimize-img` Run pngcrush on outputted tiles
|
||||||
|
:option:`-p`, :option:`--processes <-p>` Choose the number of worker processes
|
||||||
|
:option:`-q`, :option:`--quiet <-q>` Print less output
|
||||||
|
:option:`--regionlist` Only render specified areas of a map
|
||||||
|
:option:`--rendermodes` Choose which rendermode(s) to use
|
||||||
|
:option:`--settings` Specify an external settings file
|
||||||
|
:option:`--skip-js` Do not output generated javascript files
|
||||||
|
:option:`--stochastic-render` Re-render parts of the map randomly
|
||||||
|
:option:`--textures-path` Specify custom textures to use
|
||||||
|
:option:`-v`, :option:`--verbose <-v>` Print more output
|
||||||
|
:option:`-V`, :option:`--version <-V>` Print out the version
|
||||||
|
:option:`--web-assets-path` Specify alternate web assets
|
||||||
|
:option:`-z`, :option:`--zoom <-z>` Do not touch
|
||||||
|
======================================== ==================================
|
||||||
|
|
||||||
|
|
||||||
|
Help Options
|
||||||
|
------------
|
||||||
|
|
||||||
.. cmdoption:: -h, --help
|
.. cmdoption:: -h, --help
|
||||||
|
|
||||||
Shows the list of options and exits
|
Shows the list of options and exits
|
||||||
@@ -280,6 +315,11 @@ Less Useful Options
|
|||||||
a certain date. Or perhaps you can incrementally update your map by passing
|
a certain date. Or perhaps you can incrementally update your map by passing
|
||||||
in a subset of regions each time. It's up to you!
|
in a subset of regions each time. It's up to you!
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
This option may currently be broken. Use at your own risk! Patches
|
||||||
|
welcome!
|
||||||
|
|
||||||
**Settings file:**
|
**Settings file:**
|
||||||
Option name: ``regionlist``
|
Option name: ``regionlist``
|
||||||
|
|
||||||
@@ -318,9 +358,11 @@ Less Useful Options
|
|||||||
|
|
||||||
.. cmdoption:: --textures-path <path>
|
.. cmdoption:: --textures-path <path>
|
||||||
|
|
||||||
Use this option to specify an alternate terrain.png to use for textures when
|
Use this option to specify an alternate terrain.png (and other
|
||||||
rendering a world. ``path`` specifies the **containing directory** of
|
textures) to when rendering a world. ``path`` specifies the
|
||||||
terrain.png.
|
**containing directory** of terrain.png. Alternately, ``path`` can
|
||||||
|
specify a zip file containing the textures, such as a texture
|
||||||
|
pack.
|
||||||
|
|
||||||
The Overviewer will look for terrain.png in the following places in this
|
The Overviewer will look for terrain.png in the following places in this
|
||||||
order: path specified by this option, the program's directory, the
|
order: path specified by this option, the program's directory, the
|
||||||
|
|||||||
@@ -90,9 +90,13 @@ You have several options:
|
|||||||
file in the same directory as overviewer.py or overviewer.exe. For
|
file in the same directory as overviewer.py or overviewer.exe. For
|
||||||
installations, you will need to specify the path... see the next bullet.
|
installations, you will need to specify the path... see the next bullet.
|
||||||
|
|
||||||
* You can put a terrain.png file anywhere you want and point to its location
|
* You can put a terrain.png file anywhere you want and point to its
|
||||||
with the :option:`--textures-path` option. This should point to the directory containing
|
location with the :option:`--textures-path` option. This should
|
||||||
the terrain.png, not to the file itself.
|
point to the directory containing the terrain.png, not to the file
|
||||||
|
itself.
|
||||||
|
|
||||||
|
* Alternately, you can download any texture pack ZIP you like and
|
||||||
|
point to this directly with :option:`--textures-path`.
|
||||||
|
|
||||||
Note: the :option:`--check-terrain` option is useful for debugging terrain.png issues.
|
Note: the :option:`--check-terrain` option is useful for debugging terrain.png issues.
|
||||||
For example::
|
For example::
|
||||||
|
|||||||
@@ -547,6 +547,9 @@ if __name__ == "__main__":
|
|||||||
try:
|
try:
|
||||||
main()
|
main()
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
|
if e.message == "Exiting":
|
||||||
|
logging.info("Exiting...")
|
||||||
|
sys.exit(0)
|
||||||
logging.exception("""An error has occurred. This may be a bug. Please let us know!
|
logging.exception("""An error has occurred. This may be a bug. Please let us know!
|
||||||
See http://docs.overviewer.org/en/latest/index.html#help
|
See http://docs.overviewer.org/en/latest/index.html#help
|
||||||
|
|
||||||
|
|||||||
@@ -125,25 +125,6 @@ def get_tileentity_data(level):
|
|||||||
data = level['TileEntities']
|
data = level['TileEntities']
|
||||||
return data
|
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, 29, 30, 31, 32, 33,
|
|
||||||
34, 37, 38, 39, 40, 44, 50, 51, 52, 53, 55, 59, 63, 64,
|
|
||||||
65, 66, 67, 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79,
|
|
||||||
81, 83, 85, 90, 92, 93, 94, 96, 101, 102, 104, 105,
|
|
||||||
106, 107, 108, 109])
|
|
||||||
|
|
||||||
# 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,
|
|
||||||
23, 24, 25, 35, 41, 42, 43, 44, 45, 46, 47, 48, 49, 53, 54, 56, 57, 58, 60,
|
|
||||||
61, 62, 67, 73, 74, 78, 79, 80, 81, 82, 84, 86, 87, 88, 89, 91])
|
|
||||||
|
|
||||||
# This set holds block ids that are fluid blocks
|
|
||||||
fluid_blocks = set([8,9,10,11])
|
|
||||||
|
|
||||||
# This set holds block ids that are not candidates for spawning mobs on
|
|
||||||
# (glass, slabs, stairs, fluids, ice, pistons, webs,TNT, wheat, cactus, iron bars, glass planes, fences, fence gate, cake, bed, repeaters, trapdoor)
|
|
||||||
nospawn_blocks = set([20,26, 29, 30, 33, 34, 44, 46, 53, 59, 67, 79, 81, 85, 92, 93, 94, 96, 107, 109, 101, 102]).union(fluid_blocks)
|
|
||||||
|
|
||||||
class ChunkCorrupt(Exception):
|
class ChunkCorrupt(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -412,7 +393,7 @@ def generate_facemasks():
|
|||||||
left = Image.new("L", (24,24), 0)
|
left = Image.new("L", (24,24), 0)
|
||||||
whole = Image.new("L", (24,24), 0)
|
whole = Image.new("L", (24,24), 0)
|
||||||
|
|
||||||
toppart = textures.transform_image(white)
|
toppart = textures.transform_image_top(white)
|
||||||
leftpart = textures.transform_image_side(white)
|
leftpart = textures.transform_image_side(white)
|
||||||
|
|
||||||
# using the real PIL paste here (not alpha_over) because there is
|
# using the real PIL paste here (not alpha_over) because there is
|
||||||
|
|||||||
@@ -337,7 +337,12 @@ class QuadtreeGen(object):
|
|||||||
quad = Image.open(path[1]).resize((192,192), Image.ANTIALIAS)
|
quad = Image.open(path[1]).resize((192,192), Image.ANTIALIAS)
|
||||||
img.paste(quad, path[0])
|
img.paste(quad, path[0])
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
logging.warning("Couldn't open %s. It may be corrupt, you may need to delete it. %s", path[1], e)
|
logging.warning("Couldn't open %s. It may be corrupt. Error was '%s'", path[1], e)
|
||||||
|
logging.warning("I'm going to try and delete it. You will need to run the render again")
|
||||||
|
try:
|
||||||
|
os.unlink(path[1])
|
||||||
|
except Exception, e:
|
||||||
|
logging.error("I couldn't delete it. You will need to delete it yourself. Error was '%s'", e)
|
||||||
|
|
||||||
# Save it
|
# Save it
|
||||||
if self.imgformat == 'jpg':
|
if self.imgformat == 'jpg':
|
||||||
|
|||||||
@@ -20,12 +20,22 @@
|
|||||||
static PyObject *textures = NULL;
|
static PyObject *textures = NULL;
|
||||||
static PyObject *chunk_mod = NULL;
|
static PyObject *chunk_mod = NULL;
|
||||||
static PyObject *blockmap = NULL;
|
static PyObject *blockmap = NULL;
|
||||||
static PyObject *special_blocks = NULL;
|
|
||||||
static PyObject *specialblockmap = NULL;
|
unsigned int max_blockid = 0;
|
||||||
|
unsigned int max_data = 0;
|
||||||
|
unsigned char *block_properties = NULL;
|
||||||
|
|
||||||
|
static PyObject *known_blocks = NULL;
|
||||||
static PyObject *transparent_blocks = NULL;
|
static PyObject *transparent_blocks = NULL;
|
||||||
|
static PyObject *solid_blocks = NULL;
|
||||||
|
static PyObject *fluid_blocks = NULL;
|
||||||
|
static PyObject *nospawn_blocks = NULL;
|
||||||
|
|
||||||
PyObject *init_chunk_render(PyObject *self, PyObject *args) {
|
PyObject *init_chunk_render(PyObject *self, PyObject *args) {
|
||||||
|
|
||||||
|
PyObject *tmp = NULL;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
/* this function only needs to be called once, anything more should be
|
/* this function only needs to be called once, anything more should be
|
||||||
* ignored */
|
* ignored */
|
||||||
if (blockmap) {
|
if (blockmap) {
|
||||||
@@ -47,29 +57,54 @@ PyObject *init_chunk_render(PyObject *self, PyObject *args) {
|
|||||||
blockmap = PyObject_GetAttrString(textures, "blockmap");
|
blockmap = PyObject_GetAttrString(textures, "blockmap");
|
||||||
if (!blockmap)
|
if (!blockmap)
|
||||||
return NULL;
|
return NULL;
|
||||||
special_blocks = PyObject_GetAttrString(textures, "special_blocks");
|
|
||||||
if (!special_blocks)
|
tmp = PyObject_GetAttrString(textures, "max_blockid");
|
||||||
|
if (!tmp)
|
||||||
return NULL;
|
return NULL;
|
||||||
specialblockmap = PyObject_GetAttrString(textures, "specialblockmap");
|
max_blockid = PyInt_AsLong(tmp);
|
||||||
if (!specialblockmap)
|
tmp = PyObject_GetAttrString(textures, "max_data");
|
||||||
|
if (!tmp)
|
||||||
return NULL;
|
return NULL;
|
||||||
transparent_blocks = PyObject_GetAttrString(chunk_mod, "transparent_blocks");
|
max_data = PyInt_AsLong(tmp);
|
||||||
|
|
||||||
|
/* assemble the property table */
|
||||||
|
known_blocks = PyObject_GetAttrString(textures, "known_blocks");
|
||||||
|
if (!known_blocks)
|
||||||
|
return NULL;
|
||||||
|
transparent_blocks = PyObject_GetAttrString(textures, "transparent_blocks");
|
||||||
if (!transparent_blocks)
|
if (!transparent_blocks)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
solid_blocks = PyObject_GetAttrString(textures, "solid_blocks");
|
||||||
|
if (!solid_blocks)
|
||||||
|
return NULL;
|
||||||
|
fluid_blocks = PyObject_GetAttrString(textures, "fluid_blocks");
|
||||||
|
if (!fluid_blocks)
|
||||||
|
return NULL;
|
||||||
|
nospawn_blocks = PyObject_GetAttrString(textures, "nospawn_blocks");
|
||||||
|
if (!nospawn_blocks)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
block_properties = calloc(max_blockid, sizeof(unsigned char));
|
||||||
|
for (i = 0; i < max_blockid; i++) {
|
||||||
|
PyObject *block = PyInt_FromLong(i);
|
||||||
|
|
||||||
|
if (PySequence_Contains(known_blocks, block))
|
||||||
|
block_properties[i] |= 1 << KNOWN;
|
||||||
|
if (PySequence_Contains(transparent_blocks, block))
|
||||||
|
block_properties[i] |= 1 << TRANSPARENT;
|
||||||
|
if (PySequence_Contains(solid_blocks, block))
|
||||||
|
block_properties[i] |= 1 << SOLID;
|
||||||
|
if (PySequence_Contains(fluid_blocks, block))
|
||||||
|
block_properties[i] |= 1 << FLUID;
|
||||||
|
if (PySequence_Contains(nospawn_blocks, block))
|
||||||
|
block_properties[i] |= 1 << NOSPAWN;
|
||||||
|
|
||||||
|
Py_DECREF(block);
|
||||||
|
}
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
is_transparent(unsigned char b) {
|
|
||||||
PyObject *block = PyInt_FromLong(b);
|
|
||||||
int ret = PySequence_Contains(transparent_blocks, block);
|
|
||||||
Py_DECREF(block);
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned char
|
unsigned char
|
||||||
check_adjacent_blocks(RenderState *state, int x,int y,int z, unsigned char blockid) {
|
check_adjacent_blocks(RenderState *state, int x,int y,int z, unsigned char blockid) {
|
||||||
/*
|
/*
|
||||||
@@ -284,14 +319,15 @@ generate_pseudo_data(RenderState *state, unsigned char ancilData) {
|
|||||||
|
|
||||||
return final_data;
|
return final_data;
|
||||||
|
|
||||||
/* portal, iron bars and glass panes
|
} else if ((state->block == 101) || (state->block == 102)) {
|
||||||
* Note: iron bars and glass panes "stick" to other blocks, but
|
/* iron bars and glass panes:
|
||||||
* at the moment of writing this is not clear which ones stick and
|
* they seem to stick to almost everything but air, but
|
||||||
* which others no, so for the moment stick only with himself.
|
* not sure yet! Still a TODO! */
|
||||||
* This is a TODO!
|
/* return check adjacent blocks with air, bit inverted */
|
||||||
*/
|
return check_adjacent_blocks(state, x, y, z, 0) ^ 0x0f;
|
||||||
} else if ((state->block == 90) || (state->block == 101) ||
|
|
||||||
(state->block == 102)) {
|
} else if ((state->block == 90) || (state->block == 113)) {
|
||||||
|
/* portal and nether brick fences */
|
||||||
return check_adjacent_blocks(state, x, y, z, state->block);
|
return check_adjacent_blocks(state, x, y, z, state->block);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,14 +408,15 @@ chunk_render(PyObject *self, PyObject *args) {
|
|||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
/* set up the render coordinates */
|
/* set up the render coordinates */
|
||||||
state.imgx = xoff + state.x*12 + state.y*12;
|
state.imgx = xoff + state.x*12 + state.y*12;
|
||||||
/* 128*12 -- offset for z direction, 15*6 -- offset for x */
|
/* 128*12 -- offset for z direction, 15*6 -- offset for x */
|
||||||
state.imgy = yoff - state.x*6 + state.y*6 + 128*12 + 15*6;
|
state.imgy = yoff - state.x*6 + state.y*6 + 128*12 + 15*6;
|
||||||
|
|
||||||
for (state.z = 0; state.z < 128; state.z++) {
|
for (state.z = 0; state.z < 128; state.z++) {
|
||||||
|
unsigned char ancilData;
|
||||||
|
|
||||||
state.imgy -= 12;
|
state.imgy -= 12;
|
||||||
|
|
||||||
/* get blockid */
|
/* get blockid */
|
||||||
@@ -395,63 +432,46 @@ chunk_render(PyObject *self, PyObject *args) {
|
|||||||
if ((state.imgy >= imgsize1 + 24) || (state.imgy <= -24)) {
|
if ((state.imgy >= imgsize1 + 24) || (state.imgy <= -24)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* decref'd on replacement *and* at the end of the z for block */
|
/* check for occlusion */
|
||||||
if (blockid) {
|
|
||||||
Py_DECREF(blockid);
|
|
||||||
}
|
|
||||||
blockid = PyInt_FromLong(state.block);
|
|
||||||
|
|
||||||
// check for occlusion
|
|
||||||
if (render_mode_occluded(rendermode, state.x, state.y, state.z)) {
|
if (render_mode_occluded(rendermode, state.x, state.y, state.z)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// everything stored here will be a borrowed ref
|
/* everything stored here will be a borrowed ref */
|
||||||
|
|
||||||
/* get the texture and mask from block type / ancil. data */
|
ancilData = getArrayByte3D(state.blockdata_expanded, state.x, state.y, state.z);
|
||||||
if (!PySequence_Contains(special_blocks, blockid)) {
|
state.block_data = ancilData;
|
||||||
/* t = textures.blockmap[blockid] */
|
/* block that need pseudo ancildata:
|
||||||
t = PyList_GetItem(blockmap, state.block);
|
* grass, water, glass, chest, restone wire,
|
||||||
|
* ice, fence, portal, iron bars, glass panes */
|
||||||
|
if ((state.block == 2) || (state.block == 9) ||
|
||||||
|
(state.block == 20) || (state.block == 54) ||
|
||||||
|
(state.block == 55) || (state.block == 79) ||
|
||||||
|
(state.block == 85) || (state.block == 90) ||
|
||||||
|
(state.block == 101) || (state.block == 102) ||
|
||||||
|
(state.block == 113)) {
|
||||||
|
ancilData = generate_pseudo_data(&state, ancilData);
|
||||||
|
state.block_pdata = ancilData;
|
||||||
} else {
|
} else {
|
||||||
PyObject *tmp;
|
state.block_pdata = 0;
|
||||||
|
|
||||||
unsigned char ancilData = getArrayByte3D(state.blockdata_expanded, state.x, state.y, state.z);
|
|
||||||
state.block_data = ancilData;
|
|
||||||
/* block that need pseudo ancildata:
|
|
||||||
* grass, water, glass, chest, restone wire,
|
|
||||||
* ice, fence, portal, iron bars, glass panes */
|
|
||||||
if ((state.block == 2) || (state.block == 9) ||
|
|
||||||
(state.block == 20) || (state.block == 54) ||
|
|
||||||
(state.block == 55) || (state.block == 79) ||
|
|
||||||
(state.block == 85) || (state.block == 90) ||
|
|
||||||
(state.block == 101) || (state.block == 102)) {
|
|
||||||
ancilData = generate_pseudo_data(&state, ancilData);
|
|
||||||
state.block_pdata = ancilData;
|
|
||||||
} else {
|
|
||||||
state.block_pdata = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = PyTuple_New(2);
|
|
||||||
|
|
||||||
Py_INCREF(blockid); /* because SetItem steals */
|
|
||||||
PyTuple_SetItem(tmp, 0, blockid);
|
|
||||||
PyTuple_SetItem(tmp, 1, PyInt_FromLong(ancilData));
|
|
||||||
|
|
||||||
/* this is a borrowed reference. no need to decref */
|
|
||||||
t = PyDict_GetItem(specialblockmap, tmp);
|
|
||||||
Py_DECREF(tmp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* make sure our block info is in-bounds */
|
||||||
|
if (state.block >= max_blockid || ancilData >= max_data)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* get the texture */
|
||||||
|
t = PyList_GET_ITEM(blockmap, max_data * state.block + ancilData);
|
||||||
|
|
||||||
/* if we found a proper texture, render it! */
|
/* if we found a proper texture, render it! */
|
||||||
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;
|
int randx = 0, randy = 0;
|
||||||
src = PyTuple_GetItem(t, 0);
|
src = PyTuple_GetItem(t, 0);
|
||||||
mask = PyTuple_GetItem(t, 1);
|
mask = PyTuple_GetItem(t, 0);
|
||||||
mask_light = PyTuple_GetItem(t, 2);
|
mask_light = PyTuple_GetItem(t, 1);
|
||||||
|
|
||||||
if (mask == Py_None)
|
if (mask == Py_None)
|
||||||
mask = src;
|
mask = src;
|
||||||
@@ -473,11 +493,6 @@ chunk_render(PyObject *self, PyObject *args) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blockid) {
|
|
||||||
Py_DECREF(blockid);
|
|
||||||
blockid = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
// increment this value if you've made a change to the c extesion
|
// increment this value if you've made a change to the c extesion
|
||||||
// and want to force users to rebuild
|
// and want to force users to rebuild
|
||||||
#define OVERVIEWER_EXTENSION_VERSION 12
|
#define OVERVIEWER_EXTENSION_VERSION 13
|
||||||
|
|
||||||
/* Python PIL, and numpy headers */
|
/* Python PIL, and numpy headers */
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
@@ -94,8 +94,32 @@ typedef struct {
|
|||||||
PyObject *right_blocks;
|
PyObject *right_blocks;
|
||||||
} RenderState;
|
} RenderState;
|
||||||
PyObject *init_chunk_render(PyObject *self, PyObject *args);
|
PyObject *init_chunk_render(PyObject *self, PyObject *args);
|
||||||
int is_transparent(unsigned char b);
|
|
||||||
PyObject *chunk_render(PyObject *self, PyObject *args);
|
PyObject *chunk_render(PyObject *self, PyObject *args);
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
KNOWN,
|
||||||
|
TRANSPARENT,
|
||||||
|
SOLID,
|
||||||
|
FLUID,
|
||||||
|
NOSPAWN,
|
||||||
|
} BlockProperty;
|
||||||
|
/* globals set in init_chunk_render, here because they're used
|
||||||
|
in block_has_property */
|
||||||
|
extern unsigned int max_blockid;
|
||||||
|
extern unsigned int max_data;
|
||||||
|
extern unsigned char *block_properties;
|
||||||
|
static inline int
|
||||||
|
block_has_property(unsigned char b, BlockProperty prop) {
|
||||||
|
if (b >= max_blockid || !(block_properties[b] & (1 << KNOWN))) {
|
||||||
|
/* block is unknown, return defaults */
|
||||||
|
if (prop == TRANSPARENT)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return block_properties[b] & (1 << prop);
|
||||||
|
}
|
||||||
|
#define is_transparent(b) block_has_property((b), TRANSPARENT)
|
||||||
|
|
||||||
/* pull in the rendermode info */
|
/* pull in the rendermode info */
|
||||||
#include "rendermodes.h"
|
#include "rendermodes.h"
|
||||||
|
|||||||
@@ -173,7 +173,9 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject *
|
|||||||
* get constant brown color (see textures.py) */
|
* get constant brown color (see textures.py) */
|
||||||
(((state->block == 104) || (state->block == 105)) && (state->block_data != 7)) ||
|
(((state->block == 104) || (state->block == 105)) && (state->block_data != 7)) ||
|
||||||
/* vines */
|
/* vines */
|
||||||
state->block == 106)
|
state->block == 106 ||
|
||||||
|
/* lily pads */
|
||||||
|
state->block == 111)
|
||||||
{
|
{
|
||||||
/* do the biome stuff! */
|
/* do the biome stuff! */
|
||||||
PyObject *facemask = mask;
|
PyObject *facemask = mask;
|
||||||
@@ -240,6 +242,10 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject *
|
|||||||
/* vines */
|
/* vines */
|
||||||
color = PySequence_GetItem(self->grasscolor, index);
|
color = PySequence_GetItem(self->grasscolor, index);
|
||||||
break;
|
break;
|
||||||
|
case 111:
|
||||||
|
/* lily padas */
|
||||||
|
color = PySequence_GetItem(self->grasscolor, index);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
@@ -270,7 +276,8 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject *
|
|||||||
facemask = NULL;
|
facemask = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->block == 18 || state->block == 106) /* leaves and vines */
|
if (state->block == 18 || state->block == 106 || state->block == 111)
|
||||||
|
/* leaves, vines and lyli pads */
|
||||||
{
|
{
|
||||||
r = 37;
|
r = 37;
|
||||||
g = 118;
|
g = 118;
|
||||||
|
|||||||
@@ -37,10 +37,6 @@ rendermode_overlay_start(void *data, RenderState *state, PyObject *options) {
|
|||||||
Py_DECREF(facemasks_py);
|
Py_DECREF(facemasks_py);
|
||||||
|
|
||||||
self->white_color = PyObject_GetAttrString(state->chunk, "white_color");
|
self->white_color = PyObject_GetAttrString(state->chunk, "white_color");
|
||||||
|
|
||||||
self->solid_blocks = PyObject_GetAttrString(state->chunk, "solid_blocks");
|
|
||||||
self->fluid_blocks = PyObject_GetAttrString(state->chunk, "fluid_blocks");
|
|
||||||
|
|
||||||
self->get_color = get_color;
|
self->get_color = get_color;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -52,8 +48,6 @@ rendermode_overlay_finish(void *data, RenderState *state) {
|
|||||||
|
|
||||||
Py_DECREF(self->facemask_top);
|
Py_DECREF(self->facemask_top);
|
||||||
Py_DECREF(self->white_color);
|
Py_DECREF(self->white_color);
|
||||||
Py_DECREF(self->solid_blocks);
|
|
||||||
Py_DECREF(self->fluid_blocks);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -81,8 +75,7 @@ static void
|
|||||||
rendermode_overlay_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) {
|
rendermode_overlay_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) {
|
||||||
RenderModeOverlay *self = (RenderModeOverlay *)data;
|
RenderModeOverlay *self = (RenderModeOverlay *)data;
|
||||||
unsigned char r, g, b, a;
|
unsigned char r, g, b, a;
|
||||||
PyObject *top_block_py, *block_py;
|
|
||||||
|
|
||||||
// exactly analogous to edge-line code for these special blocks
|
// exactly analogous to edge-line code for these special blocks
|
||||||
int increment=0;
|
int increment=0;
|
||||||
if (state->block == 44) // half-step
|
if (state->block == 44) // half-step
|
||||||
@@ -101,27 +94,19 @@ rendermode_overlay_draw(void *data, RenderState *state, PyObject *src, PyObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check to be sure this block is solid/fluid */
|
/* check to be sure this block is solid/fluid */
|
||||||
top_block_py = PyInt_FromLong(top_block);
|
if (block_has_property(top_block, SOLID) || block_has_property(top_block, FLUID)) {
|
||||||
if (PySequence_Contains(self->solid_blocks, top_block_py) ||
|
|
||||||
PySequence_Contains(self->fluid_blocks, top_block_py)) {
|
|
||||||
|
|
||||||
/* top block is fluid or solid, skip drawing */
|
/* top block is fluid or solid, skip drawing */
|
||||||
Py_DECREF(top_block_py);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Py_DECREF(top_block_py);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check to be sure this block is solid/fluid */
|
/* check to be sure this block is solid/fluid */
|
||||||
block_py = PyInt_FromLong(state->block);
|
if (!block_has_property(state->block, SOLID) && !block_has_property(state->block, FLUID)) {
|
||||||
if (!PySequence_Contains(self->solid_blocks, block_py) &&
|
|
||||||
!PySequence_Contains(self->fluid_blocks, block_py)) {
|
|
||||||
|
|
||||||
/* not fluid or solid, skip drawing the overlay */
|
/* not fluid or solid, skip drawing the overlay */
|
||||||
Py_DECREF(block_py);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Py_DECREF(block_py);
|
|
||||||
|
|
||||||
/* get our color info */
|
/* get our color info */
|
||||||
self->get_color(data, state, &r, &g, &b, &a);
|
self->get_color(data, state, &r, &g, &b, &a);
|
||||||
|
|||||||
@@ -35,13 +35,10 @@ static void get_color(void *data, RenderState *state,
|
|||||||
/* default to no overlay, until told otherwise */
|
/* default to no overlay, until told otherwise */
|
||||||
*a = 0;
|
*a = 0;
|
||||||
|
|
||||||
block_py = PyInt_FromLong(state->block);
|
if (block_has_property(state->block, NOSPAWN)) {
|
||||||
if (PySequence_Contains(self->nospawn_blocks, block_py)) {
|
|
||||||
/* nothing can spawn on this */
|
/* nothing can spawn on this */
|
||||||
Py_DECREF(block_py);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Py_DECREF(block_py);
|
|
||||||
|
|
||||||
blocklight = getArrayByte3D(self->blocklight, x, y, MIN(127, z_light));
|
blocklight = getArrayByte3D(self->blocklight, x, y, MIN(127, z_light));
|
||||||
|
|
||||||
@@ -72,7 +69,6 @@ rendermode_spawn_start(void *data, RenderState *state, PyObject *options) {
|
|||||||
|
|
||||||
/* now do custom initializations */
|
/* now do custom initializations */
|
||||||
self = (RenderModeSpawn *)data;
|
self = (RenderModeSpawn *)data;
|
||||||
self->nospawn_blocks = PyObject_GetAttrString(state->chunk, "nospawn_blocks");
|
|
||||||
self->blocklight = PyObject_GetAttrString(state->self, "blocklight");
|
self->blocklight = PyObject_GetAttrString(state->self, "blocklight");
|
||||||
self->skylight = PyObject_GetAttrString(state->self, "skylight");
|
self->skylight = PyObject_GetAttrString(state->self, "skylight");
|
||||||
|
|
||||||
@@ -87,7 +83,6 @@ rendermode_spawn_finish(void *data, RenderState *state) {
|
|||||||
/* first free all *our* stuff */
|
/* first free all *our* stuff */
|
||||||
RenderModeSpawn* self = (RenderModeSpawn *)data;
|
RenderModeSpawn* self = (RenderModeSpawn *)data;
|
||||||
|
|
||||||
Py_DECREF(self->nospawn_blocks);
|
|
||||||
Py_DECREF(self->blocklight);
|
Py_DECREF(self->blocklight);
|
||||||
Py_DECREF(self->skylight);
|
Py_DECREF(self->skylight);
|
||||||
|
|
||||||
|
|||||||
@@ -143,8 +143,6 @@ extern RenderModeInterface rendermode_normal;
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
/* top facemask and white color image, for drawing overlays */
|
/* top facemask and white color image, for drawing overlays */
|
||||||
PyObject *facemask_top, *white_color;
|
PyObject *facemask_top, *white_color;
|
||||||
/* only show overlay on top of solid or fluid blocks */
|
|
||||||
PyObject *solid_blocks, *fluid_blocks;
|
|
||||||
/* can be overridden in derived classes to control
|
/* can be overridden in derived classes to control
|
||||||
overlay alpha and color
|
overlay alpha and color
|
||||||
last four vars are r, g, b, a out */
|
last four vars are r, g, b, a out */
|
||||||
@@ -206,8 +204,6 @@ typedef struct {
|
|||||||
/* inherits from overlay */
|
/* inherits from overlay */
|
||||||
RenderModeOverlay parent;
|
RenderModeOverlay parent;
|
||||||
|
|
||||||
/* used to figure out which blocks are spawnable */
|
|
||||||
PyObject *nospawn_blocks;
|
|
||||||
PyObject *skylight, *blocklight;
|
PyObject *skylight, *blocklight;
|
||||||
} RenderModeSpawn;
|
} RenderModeSpawn;
|
||||||
extern RenderModeInterface rendermode_spawn;
|
extern RenderModeInterface rendermode_spawn;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -303,7 +303,7 @@ class DumbFormatter(HighlightingFormatter):
|
|||||||
line = "*" * min(79,len(line)) + "\n" + line
|
line = "*" * min(79,len(line)) + "\n" + line
|
||||||
return line
|
return line
|
||||||
else:
|
else:
|
||||||
return super(DumbFormatter, self).highlight(record)
|
return HighlightingFormatter.highlight(self, record)
|
||||||
|
|
||||||
|
|
||||||
class ANSIColorFormatter(HighlightingFormatter):
|
class ANSIColorFormatter(HighlightingFormatter):
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
################################################################################
|
################################################################################
|
||||||
# Please see the README or https://github.com/overviewer/Minecraft-Overviewer/wiki/DTT-Upgrade-Guide
|
# This is a SAMPLE settings file.
|
||||||
# for more details.
|
|
||||||
|
|
||||||
# This file is not meant to be used directly, but instead it is supposed to
|
# THIS FILE IS NOT MEANT TO BE USED DIRECTLY, BUT INSTEAD IT IS SUPPOSED TO
|
||||||
# provide examples of interesting things you can do with the settings file. Most
|
# PROVIDE EXAMPLES OF INTERESTING THINGS YOU CAN DO WITH THE SETTINGS FILE.
|
||||||
# of the time, a simple 'setting_name = value' will work.
|
|
||||||
|
# THIS IS NOT A BASE FOR YOUR OWN SETTINGS FILE. CREATE A BLANK SETTINGS FILE
|
||||||
|
# AND PUT YOUR OPTIONS AND CUSOMIZATIONS IN THERE.
|
||||||
|
|
||||||
|
# See http://docs.overviewer.org/en/latest/options/#command-line-options
|
||||||
|
# for options you can set
|
||||||
|
|
||||||
|
# See http://docs.overviewer.org/en/latest/options/#settings-file
|
||||||
|
# for more info about settings files.
|
||||||
|
|
||||||
# This file is a python script, so you can import any python module you wish or
|
# This file is a python script, so you can import any python module you wish or
|
||||||
# use any built-in python function, though this is not normally necessary
|
# use any built-in python function, though this is not normally necessary
|
||||||
@@ -169,4 +176,9 @@ north_direction = "upper-right"
|
|||||||
### a guide. Be sure to read what each option does before you set it.
|
### a guide. Be sure to read what each option does before you set it.
|
||||||
### See the README for more details.
|
### See the README for more details.
|
||||||
import sys
|
import sys
|
||||||
sys.exit("This sample-settings file shouldn't be used directly!")
|
sys.exit("""
|
||||||
|
The sample-settings file shouldn't be used! It contains lots of things you
|
||||||
|
don't want, and is just a set of examples to give you ideas of what's possible.
|
||||||
|
You must instead create a blank file and put your options and customizations in
|
||||||
|
there.
|
||||||
|
""")
|
||||||
|
|||||||
Reference in New Issue
Block a user