converted spawn into a overlay-based rendermode
This commit is contained in:
1
chunk.py
1
chunk.py
@@ -502,7 +502,6 @@ def generate_facemasks():
|
|||||||
return (top, left, right)
|
return (top, left, right)
|
||||||
facemasks = generate_facemasks()
|
facemasks = generate_facemasks()
|
||||||
black_color = Image.new("RGB", (24,24), (0,0,0))
|
black_color = Image.new("RGB", (24,24), (0,0,0))
|
||||||
red_color = Image.new("RGB", (24,24), (229,36,38))
|
|
||||||
white_color = Image.new("RGB", (24,24), (255,255,255))
|
white_color = Image.new("RGB", (24,24), (255,255,255))
|
||||||
|
|
||||||
# Render 128 different color images for color coded depth blending in cave mode
|
# Render 128 different color images for color coded depth blending in cave mode
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ class MapGen(object):
|
|||||||
|
|
||||||
# create generated map type data, from given quadtrees
|
# create generated map type data, from given quadtrees
|
||||||
# FIXME hook this into render_modes in setup.py, somehow
|
# FIXME hook this into render_modes in setup.py, somehow
|
||||||
overlay_types = ['overlay']
|
overlay_types = ['spawn']
|
||||||
maptypedata = map(lambda q: {'label' : q.rendermode.capitalize(),
|
maptypedata = map(lambda q: {'label' : q.rendermode.capitalize(),
|
||||||
'path' : q.tiledir,
|
'path' : q.tiledir,
|
||||||
'overlay' : q.rendermode in overlay_types},
|
'overlay' : q.rendermode in overlay_types},
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ def main():
|
|||||||
parser.add_option("-d", "--delete", dest="delete", help="Clear all caches. Next time you render your world, it will have to start completely over again. This is probably not a good idea for large worlds. Use this if you change texture packs and want to re-render everything.", action="store_true", commandLineOnly=True)
|
parser.add_option("-d", "--delete", dest="delete", help="Clear all caches. Next time you render your world, it will have to start completely over again. This is probably not a good idea for large worlds. Use this if you change texture packs and want to re-render everything.", action="store_true", commandLineOnly=True)
|
||||||
parser.add_option("--chunklist", dest="chunklist", help="A file containing, on each line, a path to a chunkfile to update. Instead of scanning the world directory for chunks, it will just use this list. Normal caching rules still apply.")
|
parser.add_option("--chunklist", dest="chunklist", help="A file containing, on each line, a path to a chunkfile to update. Instead of scanning the world directory for chunks, it will just use this list. Normal caching rules still apply.")
|
||||||
# TODO hook this up to render_modes in setup.py
|
# TODO hook this up to render_modes in setup.py
|
||||||
parser.add_option("--rendermodes", dest="rendermode", help="Specifies the render type: normal (default), lighting, night, or spawn.", type="choice", choices=["normal", "lighting", "night", "spawn", "overlay"], required=True, default="normal", listify=True)
|
parser.add_option("--rendermodes", dest="rendermode", help="Specifies the render type: normal (default), lighting, night, or spawn.", type="choice", choices=["normal", "lighting", "night", "spawn"], required=True, default="normal", listify=True)
|
||||||
parser.add_option("--imgformat", dest="imgformat", help="The image output format to use. Currently supported: png(default), jpg. NOTE: png will always be used as the intermediate image format.", configFileOnly=True )
|
parser.add_option("--imgformat", dest="imgformat", help="The image output format to use. Currently supported: png(default), jpg. NOTE: png will always be used as the intermediate image format.", configFileOnly=True )
|
||||||
parser.add_option("--optimize-img", dest="optimizeimg", help="If using png, perform image file size optimizations on the output. Specify 1 for pngcrush, 2 for pngcrush+optipng+advdef. This may double (or more) render times, but will produce up to 30% smaller images. NOTE: requires corresponding programs in $PATH or %PATH%", configFileOnly=True)
|
parser.add_option("--optimize-img", dest="optimizeimg", help="If using png, perform image file size optimizations on the output. Specify 1 for pngcrush, 2 for pngcrush+optipng+advdef. This may double (or more) render times, but will produce up to 30% smaller images. NOTE: requires corresponding programs in $PATH or %PATH%", configFileOnly=True)
|
||||||
parser.add_option("--web-assets-hook", dest="web_assets_hook", help="If provided, run this function after the web assets have been copied, but before actual tile rendering begins. It should accept a QuadtreeGen object as its only argument.", action="store", metavar="SCRIPT", type="function", configFileOnly=True)
|
parser.add_option("--web-assets-hook", dest="web_assets_hook", help="If provided, run this function after the web assets have been copied, but before actual tile rendering begins. It should accept a QuadtreeGen object as its only argument.", action="store", metavar="SCRIPT", type="function", configFileOnly=True)
|
||||||
|
|||||||
@@ -18,21 +18,63 @@
|
|||||||
#include "overviewer.h"
|
#include "overviewer.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
static void get_color(void *data, RenderState *state,
|
||||||
|
unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a) {
|
||||||
|
|
||||||
|
RenderModeSpawn* self = (RenderModeSpawn *)data;
|
||||||
|
int x = state->x, y = state->y, z = state->z;
|
||||||
|
unsigned char blocklight, skylight;
|
||||||
|
PyObject *block_py;
|
||||||
|
|
||||||
|
/* set a nice, pretty red color */
|
||||||
|
*r = 229;
|
||||||
|
*g = 36;
|
||||||
|
*b = 38;
|
||||||
|
|
||||||
|
/* default to no overlay, until told otherwise */
|
||||||
|
*a = 0;
|
||||||
|
|
||||||
|
/* if we're at the top, skip */
|
||||||
|
if (z == 127)
|
||||||
|
return;
|
||||||
|
|
||||||
|
block_py = PyInt_FromLong(state->block);
|
||||||
|
if (PySequence_Contains(self->nospawn_blocks, block_py)) {
|
||||||
|
/* nothing can spawn on this */
|
||||||
|
Py_DECREF(block_py);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Py_DECREF(block_py);
|
||||||
|
|
||||||
|
blocklight = getArrayByte3D(self->blocklight, x, y, z+1);
|
||||||
|
skylight = getArrayByte3D(self->skylight, x, y, z+1);
|
||||||
|
|
||||||
|
if (MAX(blocklight, skylight) <= 7) {
|
||||||
|
/* hostile mobs spawn in daylight */
|
||||||
|
*a = 240;
|
||||||
|
} else if (MAX(blocklight, skylight - 11) <= 7) {
|
||||||
|
/* hostile mobs spawn at night */
|
||||||
|
*a = 150;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rendermode_spawn_start(void *data, RenderState *state) {
|
rendermode_spawn_start(void *data, RenderState *state) {
|
||||||
RenderModeSpawn* self;
|
RenderModeSpawn* self;
|
||||||
|
|
||||||
/* first, chain up */
|
/* first, chain up */
|
||||||
int ret = rendermode_night.start(data, state);
|
int ret = rendermode_overlay.start(data, state);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* now do custom initializations */
|
/* now do custom initializations */
|
||||||
self = (RenderModeSpawn *)data;
|
self = (RenderModeSpawn *)data;
|
||||||
self->solid_blocks = PyObject_GetAttrString(state->chunk, "solid_blocks");
|
|
||||||
self->nospawn_blocks = PyObject_GetAttrString(state->chunk, "nospawn_blocks");
|
self->nospawn_blocks = PyObject_GetAttrString(state->chunk, "nospawn_blocks");
|
||||||
self->fluid_blocks = PyObject_GetAttrString(state->chunk, "fluid_blocks");
|
self->blocklight = PyObject_GetAttrString(state->self, "blocklight");
|
||||||
self->red_color = PyObject_GetAttrString(state->chunk, "red_color");
|
self->skylight = PyObject_GetAttrString(state->self, "skylight");
|
||||||
|
|
||||||
|
/* setup custom color */
|
||||||
|
self->parent.get_color = get_color;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -40,81 +82,26 @@ rendermode_spawn_start(void *data, RenderState *state) {
|
|||||||
static void
|
static void
|
||||||
rendermode_spawn_finish(void *data, RenderState *state) {
|
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->solid_blocks);
|
|
||||||
Py_DECREF(self->nospawn_blocks);
|
Py_DECREF(self->nospawn_blocks);
|
||||||
Py_DECREF(self->fluid_blocks);
|
Py_DECREF(self->blocklight);
|
||||||
|
Py_DECREF(self->skylight);
|
||||||
|
|
||||||
/* now, chain up */
|
/* now, chain up */
|
||||||
rendermode_night.finish(data, state);
|
rendermode_overlay.finish(data, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rendermode_spawn_occluded(void *data, RenderState *state) {
|
rendermode_spawn_occluded(void *data, RenderState *state) {
|
||||||
/* no special occlusion here */
|
/* no special occlusion here */
|
||||||
return rendermode_night.occluded(data, state);
|
return rendermode_overlay.occluded(data, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rendermode_spawn_draw(void *data, RenderState *state, PyObject *src, PyObject *mask) {
|
rendermode_spawn_draw(void *data, RenderState *state, PyObject *src, PyObject *mask) {
|
||||||
/* different versions of self (spawn, lighting) */
|
|
||||||
RenderModeSpawn* self = (RenderModeSpawn *)data;
|
|
||||||
RenderModeLighting *lighting = (RenderModeLighting *)self;
|
|
||||||
|
|
||||||
int x = state->x, y = state->y, z = state->z;
|
|
||||||
PyObject *old_black_color = NULL;
|
|
||||||
|
|
||||||
/* figure out the appropriate darkness:
|
|
||||||
this block for transparents, the block above for non-transparent */
|
|
||||||
float darkness = 0.0;
|
|
||||||
if (is_transparent(state->block)) {
|
|
||||||
darkness = get_lighting_coefficient((RenderModeLighting *)self, state, x, y, z, NULL);
|
|
||||||
} else {
|
|
||||||
darkness = get_lighting_coefficient((RenderModeLighting *)self, state, x, y, z+1, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if it's dark enough... */
|
|
||||||
if (darkness > 0.8) {
|
|
||||||
PyObject *block_py = PyInt_FromLong(state->block);
|
|
||||||
|
|
||||||
/* make sure it's solid */
|
|
||||||
if (PySequence_Contains(self->solid_blocks, block_py)) {
|
|
||||||
int spawnable = 1;
|
|
||||||
|
|
||||||
/* not spawnable if its in the nospawn list */
|
|
||||||
if (PySequence_Contains(self->nospawn_blocks, block_py))
|
|
||||||
spawnable = 0;
|
|
||||||
|
|
||||||
/* check the block above for solid or fluid */
|
|
||||||
if (spawnable && z != 127) {
|
|
||||||
PyObject *top_block_py = PyInt_FromLong(getArrayByte3D(state->blocks, x, y, z+1));
|
|
||||||
if (PySequence_Contains(self->solid_blocks, top_block_py) ||
|
|
||||||
PySequence_Contains(self->fluid_blocks, top_block_py)) {
|
|
||||||
|
|
||||||
spawnable = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Py_DECREF(top_block_py);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if we passed all the checks, replace black_color with red_color */
|
|
||||||
if (spawnable) {
|
|
||||||
old_black_color = lighting->black_color;
|
|
||||||
lighting->black_color = self->red_color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Py_DECREF(block_py);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* draw normally */
|
/* draw normally */
|
||||||
rendermode_night.draw(data, state, src, mask);
|
rendermode_overlay.draw(data, state, src, mask);
|
||||||
|
|
||||||
/* reset black_color, if needed */
|
|
||||||
if (old_black_color != NULL) {
|
|
||||||
lighting->black_color = old_black_color;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderModeInterface rendermode_spawn = {
|
RenderModeInterface rendermode_spawn = {
|
||||||
|
|||||||
@@ -31,10 +31,6 @@ RenderModeInterface *get_render_mode(RenderState *state) {
|
|||||||
iface = &rendermode_night;
|
iface = &rendermode_night;
|
||||||
} else if (strcmp(rendermode, "spawn") == 0) {
|
} else if (strcmp(rendermode, "spawn") == 0) {
|
||||||
iface = &rendermode_spawn;
|
iface = &rendermode_spawn;
|
||||||
} else if (strcmp(rendermode, "overlay") == 0) {
|
|
||||||
/* TODO temporarily use overlay directly, but later on
|
|
||||||
you want to use overlay-derived modes */
|
|
||||||
iface = &rendermode_overlay;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_DECREF(rendermode_py);
|
Py_DECREF(rendermode_py);
|
||||||
|
|||||||
@@ -115,13 +115,12 @@ extern RenderModeInterface rendermode_night;
|
|||||||
|
|
||||||
/* SPAWN */
|
/* SPAWN */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* inherits from night */
|
/* inherits from overlay */
|
||||||
RenderModeNight parent;
|
RenderModeOverlay parent;
|
||||||
|
|
||||||
/* used to figure out which blocks are spawnable */
|
/* used to figure out which blocks are spawnable */
|
||||||
PyObject *solid_blocks, *nospawn_blocks, *fluid_blocks;
|
PyObject *nospawn_blocks;
|
||||||
/* replacement for black_color */
|
PyObject *skylight, *blocklight;
|
||||||
PyObject *red_color;
|
|
||||||
} RenderModeSpawn;
|
} RenderModeSpawn;
|
||||||
extern RenderModeInterface rendermode_spawn;
|
extern RenderModeInterface rendermode_spawn;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user