aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkwolekr <kwolekr@minetest.net>2013-06-26 17:19:39 -0400
committerkwolekr <kwolekr@minetest.net>2013-06-27 22:35:35 -0400
commit8aa930f28e69f3518831500022988ca2a4b6985d (patch)
tree5699c9b0cd8eaa54f4fadf8dcd7d0ba98a9c3c74
parent2c0b51795e6fa6747d881f1871c89830abb6e6e8 (diff)
downloadminetest-8aa930f28e69f3518831500022988ca2a4b6985d.tar.gz
minetest-8aa930f28e69f3518831500022988ca2a4b6985d.tar.bz2
minetest-8aa930f28e69f3518831500022988ca2a4b6985d.zip
Add minetest.get_mapgen_object to API
-rw-r--r--doc/lua_api.txt31
-rw-r--r--src/emerge.cpp10
-rw-r--r--src/emerge.h3
-rw-r--r--src/jthread/jthread.h1
-rw-r--r--src/jthread/pthread/jthread.cpp5
-rw-r--r--src/jthread/win32/jthread.cpp5
-rw-r--r--src/mapgen.h10
-rw-r--r--src/mapgen_v6.h1
-rw-r--r--src/mapgen_v7.h1
-rw-r--r--src/script/lua_api/l_env.cpp108
-rw-r--r--src/script/lua_api/l_env.h8
-rw-r--r--src/script/lua_api/l_item.cpp2
-rw-r--r--src/script/lua_api/l_vmanip.cpp10
-rw-r--r--src/script/lua_api/l_vmanip.h2
14 files changed, 188 insertions, 9 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 62fe94b45..84769f8d8 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -1116,6 +1116,8 @@ minetest.get_perlin(seeddiff, octaves, persistence, scale)
^ Return world-specific perlin noise (int(worldseed)+seeddiff)
minetest.get_voxel_manip()
^ Return voxel manipulator object
+minetest.get_mapgen_object(objectname)
+^ Return requested mapgen object if available (see Mapgen objects)
minetest.clear_objects()
^ clear all objects in the environments
minetest.line_of_sight(pos1,pos2,stepsize) ->true/false
@@ -1544,6 +1546,35 @@ methods:
^ To be used only by VoxelManip objects passed to a callback; otherwise, calculated lighting will be ignored
- update_liquids(): Update liquid flow
+Mapgen objects
+---------------
+A mapgen object is a construct used in map generation. Mapgen objects can be used by an on_generate
+callback to speed up operations by avoiding unnecessary recalculations; these can be retrieved using the
+minetest.get_mapgen_object() function. If the requested Mapgen object is unavailable, or
+get_mapgen_object() was called outside of an on_generate() callback, nil is returned.
+
+The following Mapgen objects are currently available:
+
+- voxelmanip
+ This returns four values; the VoxelManip object to be used, the voxel data, minimum emerge position,
+and maximum emerged position. All mapgens support this object.
+
+- heightmap
+ Returns an array containing the y coordinates of the ground levels of nodes in the most recently
+generated chunk by the current mapgen.
+
+- biomemap
+ Returns an array containing the biome IDs of nodes in the most recently generated chunk by the
+current mapgen.
+
+- heatmap
+ Returns an array containing the temperature values of nodes in the most recently generated chunk by
+the current mapgen.
+
+- humiditymap
+ Returns an array containing the humidity values of nodes in the most recently generated chunk by the
+current mapgen.
+
Registered entities
--------------------
- Functions receive a "luaentity" as self:
diff --git a/src/emerge.cpp b/src/emerge.cpp
index aed9af7b5..e1e6c6574 100644
--- a/src/emerge.cpp
+++ b/src/emerge.cpp
@@ -144,6 +144,16 @@ void EmergeManager::initMapgens(MapgenParams *mgparams) {
}
+Mapgen *EmergeManager::getCurrentMapgen() {
+ for (unsigned int i = 0; i != emergethread.size(); i++) {
+ if (emergethread[i]->IsSameThread())
+ return emergethread[i]->mapgen;
+ }
+
+ return NULL;
+}
+
+
bool EmergeManager::enqueueBlockEmerge(u16 peer_id, v3s16 p, bool allow_generate) {
std::map<v3s16, BlockEmergeData *>::const_iterator iter;
BlockEmergeData *bedata;
diff --git a/src/emerge.h b/src/emerge.h
index 084956932..d51177110 100644
--- a/src/emerge.h
+++ b/src/emerge.h
@@ -93,6 +93,7 @@ public:
~EmergeManager();
void initMapgens(MapgenParams *mgparams);
+ Mapgen *getCurrentMapgen();
Mapgen *createMapgen(std::string mgname, int mgid,
MapgenParams *mgparams);
MapgenParams *createMapgenParams(std::string mgname);
@@ -111,6 +112,7 @@ public:
class EmergeThread : public SimpleThread
{
+public:
Server *m_server;
ServerMap *map;
EmergeManager *emerge;
@@ -118,7 +120,6 @@ class EmergeThread : public SimpleThread
bool enable_mapgen_debug_info;
int id;
-public:
Event qevent;
std::queue<v3s16> blockqueue;
diff --git a/src/jthread/jthread.h b/src/jthread/jthread.h
index 9440a158d..cd78231e9 100644
--- a/src/jthread/jthread.h
+++ b/src/jthread/jthread.h
@@ -47,6 +47,7 @@ public:
virtual void *Thread() = 0;
bool IsRunning();
void *GetReturnValue();
+ bool IsSameThread();
protected:
void ThreadStarted();
private:
diff --git a/src/jthread/pthread/jthread.cpp b/src/jthread/pthread/jthread.cpp
index 978cac20a..4a5c736eb 100644
--- a/src/jthread/pthread/jthread.cpp
+++ b/src/jthread/pthread/jthread.cpp
@@ -148,6 +148,11 @@ void *JThread::GetReturnValue()
return val;
}
+bool JThread::IsSameThread()
+{
+ return pthread_equal(pthread_self(), threadid);
+}
+
void *JThread::TheThread(void *param)
{
JThread *jthread;
diff --git a/src/jthread/win32/jthread.cpp b/src/jthread/win32/jthread.cpp
index 54b110bfd..c07425dca 100644
--- a/src/jthread/win32/jthread.cpp
+++ b/src/jthread/win32/jthread.cpp
@@ -141,6 +141,11 @@ void *JThread::GetReturnValue()
return val;
}
+bool JThread::IsSameThread()
+{
+ return GetCurrentThreadId() == threadid;
+}
+
#ifndef _WIN32_WCE
UINT __stdcall JThread::TheThread(void *param)
#else
diff --git a/src/mapgen.h b/src/mapgen.h
index 0ed64f85c..96a27ade7 100644
--- a/src/mapgen.h
+++ b/src/mapgen.h
@@ -93,8 +93,10 @@ public:
int id;
ManualMapVoxelManipulator *vm;
INodeDefManager *ndef;
+
s16 *heightmap;
u8 *biomemap;
+ v3s16 csize;
Mapgen();
virtual ~Mapgen() {}
@@ -124,6 +126,14 @@ struct MapgenFactory {
virtual ~MapgenFactory() {}
};
+enum MapgenObject {
+ MGOBJ_VMANIP,
+ MGOBJ_HEIGHTMAP,
+ MGOBJ_BIOMEMAP,
+ MGOBJ_HEATMAP,
+ MGOBJ_HUMIDMAP
+};
+
enum OreType {
ORE_SCATTER,
ORE_SHEET,
diff --git a/src/mapgen_v6.h b/src/mapgen_v6.h
index f4ffd25f3..14736e3d0 100644
--- a/src/mapgen_v6.h
+++ b/src/mapgen_v6.h
@@ -84,7 +84,6 @@ public:
EmergeManager *emerge;
int ystride;
- v3s16 csize;
u32 flags;
u32 blockseed;
diff --git a/src/mapgen_v7.h b/src/mapgen_v7.h
index 3bba9938c..6267350d6 100644
--- a/src/mapgen_v7.h
+++ b/src/mapgen_v7.h
@@ -58,7 +58,6 @@ public:
BiomeDefManager *bmgr;
int ystride;
- v3s16 csize;
u32 flags;
bool lighting;
bool ridges;
diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp
index 6f663646c..b5c40977e 100644
--- a/src/script/lua_api/l_env.cpp
+++ b/src/script/lua_api/l_env.cpp
@@ -35,11 +35,27 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "lua_api/l_noise.h"
#include "treegen.h"
#include "pathfinder.h"
+#include "emerge.h"
+#include "mapgen_v7.h"
#define GET_ENV_PTR ServerEnvironment* env = \
dynamic_cast<ServerEnvironment*>(getEnv(L)); \
if( env == NULL) return 0
+
+struct EnumString ModApiEnvMod::es_MapgenObject[] =
+{
+ {MGOBJ_VMANIP, "voxelmanip"},
+ {MGOBJ_HEIGHTMAP, "heightmap"},
+ {MGOBJ_BIOMEMAP, "biomemap"},
+ {MGOBJ_HEATMAP, "heatmap"},
+ {MGOBJ_HUMIDMAP, "humiditymap"},
+ {0, NULL},
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+
void LuaABM::trigger(ServerEnvironment *env, v3s16 p, MapNode n,
u32 active_object_count, u32 active_object_count_wider)
@@ -541,14 +557,101 @@ int ModApiEnvMod::l_get_voxel_manip(lua_State *L)
GET_ENV_PTR;
Map *map = &(env->getMap());
- LuaVoxelManip *vm = new LuaVoxelManip(map);
+ LuaVoxelManip *o = new LuaVoxelManip(map);
- *(void **)(lua_newuserdata(L, sizeof(void *))) = vm;
+ *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
luaL_getmetatable(L, "VoxelManip");
lua_setmetatable(L, -2);
return 1;
}
+// minetest.get_mapgen_object(objectname)
+// returns the requested object used during map generation
+int ModApiEnvMod::l_get_mapgen_object(lua_State *L)
+{
+ const char *mgobjstr = lua_tostring(L, 1);
+
+ int mgobjint;
+ if (!string_to_enum(es_MapgenObject, mgobjint, mgobjstr ? mgobjstr : ""))
+ return 0;
+
+ enum MapgenObject mgobj = (MapgenObject)mgobjint;
+
+ EmergeManager *emerge = getServer(L)->getEmergeManager();
+ Mapgen *mg = emerge->getCurrentMapgen();
+
+ size_t maplen = mg->csize.X * mg->csize.Z;
+
+ int nargs = 1;
+
+ switch (mgobj) {
+ case MGOBJ_VMANIP: {
+ ManualMapVoxelManipulator *vm = mg->vm;
+
+ // VoxelManip object
+ LuaVoxelManip *o = new LuaVoxelManip(vm, false);
+ *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
+ luaL_getmetatable(L, "VoxelManip");
+ lua_setmetatable(L, -2);
+
+ // VoxelManip data
+ int volume = vm->m_area.getVolume();
+ lua_newtable(L);
+ for (int i = 0; i != volume; i++) {
+ lua_Number cid = vm->m_data[i].getContent();
+ lua_pushnumber(L, cid);
+ lua_rawseti(L, -2, i + 1);
+ }
+
+ // emerged min pos
+ push_v3s16(L, vm->m_area.MinEdge);
+
+ // emerged max pos
+ push_v3s16(L, vm->m_area.MaxEdge);
+
+ nargs = 4;
+
+ break; }
+ case MGOBJ_HEIGHTMAP: {
+ if (!mg->heightmap)
+ return 0;
+
+ lua_newtable(L);
+ for (size_t i = 0; i != maplen; i++) {
+ lua_pushinteger(L, mg->heightmap[i]);
+ lua_rawseti(L, -2, i + 1);
+ }
+ break; }
+ case MGOBJ_BIOMEMAP: {
+ if (!mg->heightmap)
+ return 0;
+
+ lua_newtable(L);
+ for (size_t i = 0; i != maplen; i++) {
+ lua_pushinteger(L, mg->biomemap[i]);
+ lua_rawseti(L, -2, i + 1);
+ }
+ break; }
+ case MGOBJ_HEATMAP: { // Mapgen V7 specific objects
+ case MGOBJ_HUMIDMAP:
+ MapgenV7 *mgv7 = (MapgenV7 *)mg;
+
+ float *arr = (mgobj == MGOBJ_HEATMAP) ?
+ mgv7->noise_heat->result : mgv7->noise_humidity->result;
+ if (!arr)
+ return 0;
+
+ lua_newtable(L);
+ for (size_t i = 0; i != maplen; i++) {
+ lua_pushnumber(L, arr[i]);
+ lua_rawseti(L, -2, i + 1);
+ }
+ break; }
+ }
+
+ return nargs;
+}
+
// minetest.clear_objects()
// clear all objects in the environment
int ModApiEnvMod::l_clear_objects(lua_State *L)
@@ -695,6 +798,7 @@ bool ModApiEnvMod::Initialize(lua_State *L,int top)
retval &= API_FCT(get_perlin);
retval &= API_FCT(get_perlin_map);
retval &= API_FCT(get_voxel_manip);
+ retval &= API_FCT(get_mapgen_object);
retval &= API_FCT(clear_objects);
retval &= API_FCT(spawn_tree);
retval &= API_FCT(find_path);
diff --git a/src/script/lua_api/l_env.h b/src/script/lua_api/l_env.h
index 24700d27c..8f769e350 100644
--- a/src/script/lua_api/l_env.h
+++ b/src/script/lua_api/l_env.h
@@ -113,6 +113,10 @@ private:
// minetest.get_voxel_manip()
// returns world-specific voxel manipulator
static int l_get_voxel_manip(lua_State *L);
+
+ // minetest.get_mapgen_object(objectname)
+ // returns the requested object used during map generation
+ static int l_get_mapgen_object(lua_State *L);
// minetest.clear_objects()
// clear all objects in the environment
@@ -127,7 +131,9 @@ private:
// minetest.find_path(pos1, pos2, searchdistance,
// max_jump, max_drop, algorithm) -> table containing path
static int l_find_path(lua_State *L);
-
+
+ static struct EnumString es_MapgenObject[];
+
public:
bool Initialize(lua_State *L, int top);
};
diff --git a/src/script/lua_api/l_item.cpp b/src/script/lua_api/l_item.cpp
index c69562dda..4069c61ce 100644
--- a/src/script/lua_api/l_item.cpp
+++ b/src/script/lua_api/l_item.cpp
@@ -466,7 +466,7 @@ int ModApiItemMod::l_get_content_id(lua_State *L)
INodeDefManager *ndef = STACK_TO_SERVER(L)->getNodeDefManager();
content_t c = ndef->getId(name);
- lua_pushnumber(L, c);
+ lua_pushinteger(L, c);
return 1; /* number of results */
}
diff --git a/src/script/lua_api/l_vmanip.cpp b/src/script/lua_api/l_vmanip.cpp
index e0397dfce..6743f40f9 100644
--- a/src/script/lua_api/l_vmanip.cpp
+++ b/src/script/lua_api/l_vmanip.cpp
@@ -33,7 +33,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
int LuaVoxelManip::gc_object(lua_State *L)
{
LuaVoxelManip *o = *(LuaVoxelManip **)(lua_touserdata(L, 1));
- delete o;
+ if (o->do_gc)
+ delete o;
return 0;
}
@@ -82,7 +83,6 @@ int LuaVoxelManip::l_write_chunk(lua_State *L)
vm->m_data[i].setContent(c);
lua_pop(L, 1);
-
}
vm->blitBackAll(&o->modified_blocks);
@@ -184,6 +184,12 @@ int LuaVoxelManip::l_update_map(lua_State *L)
return 0;
}
+LuaVoxelManip::LuaVoxelManip(ManualMapVoxelManipulator *mmvm, bool dogc)
+{
+ this->vm = mmvm;
+ this->do_gc = dogc;
+}
+
LuaVoxelManip::LuaVoxelManip(Map *map)
{
vm = new ManualMapVoxelManipulator(map);
diff --git a/src/script/lua_api/l_vmanip.h b/src/script/lua_api/l_vmanip.h
index 568f7104e..5a57d6bfa 100644
--- a/src/script/lua_api/l_vmanip.h
+++ b/src/script/lua_api/l_vmanip.h
@@ -36,6 +36,7 @@ class LuaVoxelManip
private:
ManualMapVoxelManipulator *vm;
std::map<v3s16, MapBlock *> modified_blocks;
+ bool do_gc;
static const char className[];
static const luaL_reg methods[];
@@ -50,6 +51,7 @@ private:
static int l_set_lighting(lua_State *L);
public:
+ LuaVoxelManip(ManualMapVoxelManipulator *mmvm, bool dogc);
LuaVoxelManip(Map *map);
~LuaVoxelManip();