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)
|
||||
facemasks = generate_facemasks()
|
||||
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))
|
||||
|
||||
# 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
|
||||
# FIXME hook this into render_modes in setup.py, somehow
|
||||
overlay_types = ['overlay']
|
||||
overlay_types = ['spawn']
|
||||
maptypedata = map(lambda q: {'label' : q.rendermode.capitalize(),
|
||||
'path' : q.tiledir,
|
||||
'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("--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
|
||||
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("--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)
|
||||
|
||||
@@ -18,21 +18,63 @@
|
||||
#include "overviewer.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
|
||||
rendermode_spawn_start(void *data, RenderState *state) {
|
||||
RenderModeSpawn* self;
|
||||
|
||||
/* first, chain up */
|
||||
int ret = rendermode_night.start(data, state);
|
||||
int ret = rendermode_overlay.start(data, state);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
/* now do custom initializations */
|
||||
self = (RenderModeSpawn *)data;
|
||||
self->solid_blocks = PyObject_GetAttrString(state->chunk, "solid_blocks");
|
||||
self->nospawn_blocks = PyObject_GetAttrString(state->chunk, "nospawn_blocks");
|
||||
self->fluid_blocks = PyObject_GetAttrString(state->chunk, "fluid_blocks");
|
||||
self->red_color = PyObject_GetAttrString(state->chunk, "red_color");
|
||||
self->blocklight = PyObject_GetAttrString(state->self, "blocklight");
|
||||
self->skylight = PyObject_GetAttrString(state->self, "skylight");
|
||||
|
||||
/* setup custom color */
|
||||
self->parent.get_color = get_color;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -40,81 +82,26 @@ rendermode_spawn_start(void *data, RenderState *state) {
|
||||
static void
|
||||
rendermode_spawn_finish(void *data, RenderState *state) {
|
||||
/* 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->fluid_blocks);
|
||||
Py_DECREF(self->blocklight);
|
||||
Py_DECREF(self->skylight);
|
||||
|
||||
/* now, chain up */
|
||||
rendermode_night.finish(data, state);
|
||||
rendermode_overlay.finish(data, state);
|
||||
}
|
||||
|
||||
static int
|
||||
rendermode_spawn_occluded(void *data, RenderState *state) {
|
||||
/* no special occlusion here */
|
||||
return rendermode_night.occluded(data, state);
|
||||
return rendermode_overlay.occluded(data, state);
|
||||
}
|
||||
|
||||
static void
|
||||
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 */
|
||||
rendermode_night.draw(data, state, src, mask);
|
||||
|
||||
/* reset black_color, if needed */
|
||||
if (old_black_color != NULL) {
|
||||
lighting->black_color = old_black_color;
|
||||
}
|
||||
rendermode_overlay.draw(data, state, src, mask);
|
||||
}
|
||||
|
||||
RenderModeInterface rendermode_spawn = {
|
||||
|
||||
@@ -31,10 +31,6 @@ RenderModeInterface *get_render_mode(RenderState *state) {
|
||||
iface = &rendermode_night;
|
||||
} else if (strcmp(rendermode, "spawn") == 0) {
|
||||
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);
|
||||
|
||||
@@ -115,13 +115,12 @@ extern RenderModeInterface rendermode_night;
|
||||
|
||||
/* SPAWN */
|
||||
typedef struct {
|
||||
/* inherits from night */
|
||||
RenderModeNight parent;
|
||||
/* inherits from overlay */
|
||||
RenderModeOverlay parent;
|
||||
|
||||
/* used to figure out which blocks are spawnable */
|
||||
PyObject *solid_blocks, *nospawn_blocks, *fluid_blocks;
|
||||
/* replacement for black_color */
|
||||
PyObject *red_color;
|
||||
PyObject *nospawn_blocks;
|
||||
PyObject *skylight, *blocklight;
|
||||
} RenderModeSpawn;
|
||||
extern RenderModeInterface rendermode_spawn;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user