Add minetest.get_mapgen_object to API
authorkwolekr <kwolekr@minetest.net>
Wed, 26 Jun 2013 21:19:39 +0000 (17:19 -0400)
committerkwolekr <kwolekr@minetest.net>
Fri, 28 Jun 2013 02:35:35 +0000 (22:35 -0400)
14 files changed:
doc/lua_api.txt
src/emerge.cpp
src/emerge.h
src/jthread/jthread.h
src/jthread/pthread/jthread.cpp
src/jthread/win32/jthread.cpp
src/mapgen.h
src/mapgen_v6.h
src/mapgen_v7.h
src/script/lua_api/l_env.cpp
src/script/lua_api/l_env.h
src/script/lua_api/l_item.cpp
src/script/lua_api/l_vmanip.cpp
src/script/lua_api/l_vmanip.h

index 62fe94b45d3f509dc5a12867a17efccc1f839b7c..84769f8d8b717787146fd6660ac18468c7e15ef5 100644 (file)
@@ -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:
index aed9af7b56775ecab34effdfd779fa5e4fc45cf2..e1e6c6574ad7a3153caf68a211f3e89495c6c5a4 100644 (file)
@@ -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;
index 084956932eef2df2aabd2397affa01e8f6cd49f3..d51177110366d077b9fcc4b99de50db4b98bc00d 100644 (file)
@@ -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;
        
index 9440a158d95ed76b2cc999efced8214ce46ecc81..cd78231e9c176c97d68c74b6c3eb40b3ba74242a 100644 (file)
@@ -47,6 +47,7 @@ public:
        virtual void *Thread() = 0;
        bool IsRunning();
        void *GetReturnValue();
+       bool IsSameThread();
 protected:
        void ThreadStarted();
 private:
index 978cac20ab6529b7fa2163ff82ad8fce1e7f0e7d..4a5c736eb896fdf068a517154af8421779c99304 100644 (file)
@@ -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;
index 54b110bfd6456df6caf4a2a052e1ec23c8278fac..c07425dcad8f38bd893d4f839034fd477c000066 100644 (file)
@@ -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
index 0ed64f85c589784bf3668b0c7bd11e4c467aa057..96a27ade77588feadbfb90ef90ee6a18cdf59329 100644 (file)
@@ -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,
index f4ffd25f3c241f6b4c47db1b99449695423707c2..14736e3d0fef1a43f38876af0cb97204bf379df3 100644 (file)
@@ -84,7 +84,6 @@ public:
        EmergeManager *emerge;
 
        int ystride;
-       v3s16 csize;
        u32 flags;
 
        u32 blockseed;
index 3bba9938c3f0e4a7d7a1174b0268821335c3a534..6267350d633dc368ccc2847eb98cab0eabf59ef7 100644 (file)
@@ -58,7 +58,6 @@ public:
        BiomeDefManager *bmgr;
 
        int ystride;
-       v3s16 csize;
        u32 flags;
        bool lighting;
        bool ridges;
index 6f663646c930accbcc3b40ab30cc5b6510e50ecd..b5c40977ef2960de65900b98dcb7f91d16a2dacc 100644 (file)
@@ -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);
index 24700d27cd74cb5f957158b9343da478ba6c8dce..8f769e35001b3484f8ab1a90a3066ddb69ddfbfe 100644 (file)
@@ -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);
 };
index c69562ddad171199afec4cb9539c41d33b9d7bd1..4069c61cea871bfb63ec9e50b7e0bb56fad8a4ed 100644 (file)
@@ -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 */
 }
 
index e0397dfce7169f99f95622cc4fa39a7b2ad6ffb8..6743f40f9c97911c0cbac2ea85d879e2b85ef39b 100644 (file)
@@ -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);
index 568f7104ed74df256eddd2b22e995606a0c5a7c1..5a57d6bfad9fd644835b74aac66525aecb4a2328 100644 (file)
@@ -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();