added slime overlay, colors chunks green if slimes can spawn
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 = {
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
126
overviewer_core/src/primitives/overlay-slime.c
Normal file
126
overviewer_core/src/primitives/overlay-slime.c
Normal 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,
|
||||||
|
};
|
||||||
@@ -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:
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user