0

added slime overlay, colors chunks green if slimes can spawn

This commit is contained in:
Aaron Griffith
2012-06-05 23:18:15 -04:00
parent f4a1c32d1a
commit 05bfaaf967
8 changed files with 150 additions and 8 deletions

View File

@@ -715,6 +715,11 @@ SpawnOverlay
this on top of other modes, or on top of ClearBase to create a this on top of other modes, or on top of ClearBase to create a
pure overlay. pure overlay.
SlimeOverlay
Color the map green in chunks where slimes can spawn. Either use
this on top of other modes, or on top of ClearBase to create a
pure overlay.
MineralOverlay MineralOverlay
Color the map according to what minerals can be found Color the map according to what minerals can be found
underneath. Either use this on top of other modes, or on top of underneath. Either use this on top of other modes, or on top of

View File

@@ -423,7 +423,7 @@ dir but you forgot to put quotes around the directory, since it contains spaces.
render['name'] = render_name # perhaps a hack. This is stored here for the asset manager render['name'] = render_name # perhaps a hack. This is stored here for the asset manager
tileSetOpts = util.dict_subset(render, ["name", "imgformat", "renderchecks", "rerenderprob", "bgcolor", "imgquality", "optimizeimg", "rendermode", "worldname_orig", "title", "dimension", "changelist","showspawn", "overlay","base"]) tileSetOpts = util.dict_subset(render, ["name", "imgformat", "renderchecks", "rerenderprob", "bgcolor", "imgquality", "optimizeimg", "rendermode", "worldname_orig", "title", "dimension", "changelist","showspawn", "overlay","base"])
tileSetOpts.update({"spawn": w.find_true_spawn()}) # TODO find a better way to do this tileSetOpts.update({"spawn": w.find_true_spawn()}) # TODO find a better way to do this
tset = tileset.TileSet(rset, assetMrg, tex, tileSetOpts, tileset_dir) tset = tileset.TileSet(w, rset, assetMrg, tex, tileSetOpts, tileset_dir)
tilesets.append(tset) tilesets.append(tset)
# Do tileset preprocessing here, before we start dispatching jobs # Do tileset preprocessing here, before we start dispatching jobs

View File

@@ -195,6 +195,9 @@ class Overlay(RenderPrimitive):
class SpawnOverlay(Overlay): class SpawnOverlay(Overlay):
name = "overlay-spawn" name = "overlay-spawn"
class SlimeOverlay(Overlay):
name = "overlay-slime"
class MineralOverlay(Overlay): class MineralOverlay(Overlay):
name = "overlay-mineral" name = "overlay-mineral"
options = { options = {

View File

@@ -432,7 +432,6 @@ generate_pseudo_data(RenderState *state, unsigned char ancilData) {
PyObject* PyObject*
chunk_render(PyObject *self, PyObject *args) { chunk_render(PyObject *self, PyObject *args) {
RenderState state; RenderState state;
PyObject *regionset;
PyObject *modeobj; PyObject *modeobj;
PyObject *blockmap; PyObject *blockmap;
@@ -453,7 +452,7 @@ chunk_render(PyObject *self, PyObject *args) {
PyObject *t = NULL; PyObject *t = NULL;
if (!PyArg_ParseTuple(args, "OiiiOiiOO", &state.regionset, &state.chunkx, &state.chunky, &state.chunkz, &state.img, &xoff, &yoff, &modeobj, &state.textures)) if (!PyArg_ParseTuple(args, "OOiiiOiiOO", &state.world, &state.regionset, &state.chunkx, &state.chunky, &state.chunkz, &state.img, &xoff, &yoff, &modeobj, &state.textures))
return NULL; return NULL;
/* set up the render mode */ /* set up the render mode */

View File

@@ -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 35 #define OVERVIEWER_EXTENSION_VERSION 36
/* Python PIL, and numpy headers */ /* Python PIL, and numpy headers */
#include <Python.h> #include <Python.h>
@@ -88,6 +88,7 @@ typedef struct {
} ChunkData; } ChunkData;
typedef struct { typedef struct {
/* the regionset object, and chunk coords */ /* the regionset object, and chunk coords */
PyObject *world;
PyObject *regionset; PyObject *regionset;
int chunkx, chunky, chunkz; int chunkx, chunky, chunkz;

View File

@@ -0,0 +1,126 @@
/*
* This file is part of the Minecraft Overviewer.
*
* Minecraft Overviewer is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Minecraft Overviewer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "overlay.h"
#include <math.h>
typedef struct {
/* inherits from overlay */
RenderPrimitiveOverlay parent;
long seed;
} RenderPrimitiveSlime;
/*
* random_* are a re-implementation of java's Random() class
* since Minecraft's slime algorithm depends on it
* http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Random.html
*/
static void random_set_seed(long *seed, long new_seed) {
*seed = (new_seed ^ 0x5deece66dL) & ((1L << 48) - 1);
}
static int random_next(long *seed, int bits) {
*seed = (*seed * 0x5deece66dL + 0xbL) & ((1L << 48) - 1);
return (int)(*seed >> (48 - bits));
}
static int random_next_int(long *seed, int n) {
int bits, val;
if (n <= 0) {
/* invalid */
return 0;
}
if ((n & -n) == n) {
/* n is a power of two */
return (int)((n * (long)random_next(seed, 31)) >> 31);
}
do {
bits = random_next(seed, 31);
val = bits % n;
} while (bits - val + (n - 1) < 0);
return val;
}
static int is_slime(long map_seed, long chunkx, long chunkz) {
/* lots of magic numbers, but they're all correct! I swear! */
long seed;
random_set_seed(&seed, map_seed + (chunkx * chunkx * 0x4c1906L) + (chunkx * 0x5ac0dbL) + (chunkz * chunkz * 0x4307a7L) + (chunkz * 0x5f24fL) ^ 0x3ad8025fL);
return (random_next_int(&seed, 10) == 0);
}
static void get_color(void *data, RenderState *state,
unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a) {
RenderPrimitiveSlime *self = (RenderPrimitiveSlime *)data;
/* set a nice, pretty green color */
*r = 40;
*g = 230;
*b = 40;
/* default to no overlay, until told otherwise */
*a = 0;
if (is_slime(self->seed, state->chunkx, state->chunkz)) {
/* slimes can spawn! */
*a = 240;
}
}
static int
overlay_slime_start(void *data, RenderState *state, PyObject *support) {
RenderPrimitiveSlime *self;
PyObject *pyseed;
/* first, chain up */
int ret = primitive_overlay.start(data, state, support);
if (ret != 0)
return ret;
/* now do custom initializations */
self = (RenderPrimitiveSlime *)data;
self->parent.get_color = get_color;
pyseed = PyObject_GetAttrString(state->world, "seed");
if (!pyseed)
return 1;
self->seed = PyInt_AsLong(pyseed);
Py_DECREF(pyseed);
if (PyErr_Occurred())
return 1;
return 0;
}
static void
overlay_slime_finish(void *data, RenderState *state) {
/* chain up */
primitive_overlay.finish(data, state);
}
RenderPrimitiveInterface primitive_overlay_slime = {
"overlay-slime",
sizeof(RenderPrimitiveSlime),
overlay_slime_start,
overlay_slime_finish,
NULL,
NULL,
overlay_draw,
};

View File

@@ -164,12 +164,14 @@ class TileSet(object):
""" """
def __init__(self, regionsetobj, assetmanagerobj, texturesobj, options, outputdir): def __init__(self, worldobj, regionsetobj, assetmanagerobj, texturesobj, options, outputdir):
"""Construct a new TileSet object with the given configuration options """Construct a new TileSet object with the given configuration options
dictionary. dictionary.
options is a dictionary of configuration parameters (strings mapping to options is a dictionary of configuration parameters (strings mapping to
values) that are interpreted by the rendering engine. values) that are interpreted by the rendering engine.
worldobj is the World object that regionsetobj is from.
regionsetobj is the RegionSet object that is used to render the tiles. regionsetobj is the RegionSet object that is used to render the tiles.
@@ -269,6 +271,7 @@ class TileSet(object):
""" """
self.options = options self.options = options
self.world = worldobj
self.regionset = regionsetobj self.regionset = regionsetobj
self.am = assetmanagerobj self.am = assetmanagerobj
self.textures = texturesobj self.textures = texturesobj
@@ -356,7 +359,7 @@ class TileSet(object):
# Only pickle the initial state. Don't pickle anything resulting from the # Only pickle the initial state. Don't pickle anything resulting from the
# do_preprocessing step # do_preprocessing step
def __getstate__(self): def __getstate__(self):
return self.regionset, self.am, self.textures, self.options, self.outputdir return self.world, self.regionset, self.am, self.textures, self.options, self.outputdir
def __setstate__(self, state): def __setstate__(self, state):
self.__init__(*state) self.__init__(*state)
@@ -946,7 +949,7 @@ class TileSet(object):
# draw the chunk! # draw the chunk!
try: try:
c_overviewer.render_loop(self.regionset, chunkx, chunky, c_overviewer.render_loop(self.world, self.regionset, chunkx, chunky,
chunkz, tileimg, xpos, ypos, chunkz, tileimg, xpos, ypos,
self.options['rendermode'], self.textures) self.options['rendermode'], self.textures)
except nbt.CorruptionError: except nbt.CorruptionError:

View File

@@ -136,7 +136,12 @@ class World(object):
except KeyError: except KeyError:
# but very old ones might not? so we'll just go with the world dir name if they don't # but very old ones might not? so we'll just go with the world dir name if they don't
self.name = os.path.basename(os.path.realpath(self.worlddir)) self.name = os.path.basename(os.path.realpath(self.worlddir))
try:
# level.dat also has a RandomSeed attribute
self.seed = data['RandomSeed']
except KeyError:
self.seed = 0 # oh well
# TODO figure out where to handle regionlists # TODO figure out where to handle regionlists