GenElementManager: Pass opaque handles to Lua and rename to ObjDefManager
authorkwolekr <kwolekr@minetest.net>
Tue, 31 Mar 2015 03:40:35 +0000 (23:40 -0400)
committerkwolekr <kwolekr@minetest.net>
Tue, 31 Mar 2015 05:11:51 +0000 (01:11 -0400)
Add core.clear_registered_schematics() and refactor schematics somewhat

16 files changed:
doc/lua_api.txt
src/mapgen.cpp
src/mapgen.h
src/mapgen_v5.cpp
src/mapgen_v7.cpp
src/mg_biome.cpp
src/mg_biome.h
src/mg_decoration.cpp
src/mg_decoration.h
src/mg_ore.cpp
src/mg_ore.h
src/mg_schematic.cpp
src/mg_schematic.h
src/script/lua_api/l_mapgen.cpp
src/util/numeric.cpp
src/util/numeric.h

index 1431181f172e633b0bbd437593595957e2f6958d..19d4f16722ea8e248ddda62057a254885fc8c305 100644 (file)
@@ -419,6 +419,11 @@ the global `minetest.registered_*` tables.
 * `minetest.register_craftitem(name, item definition)`
     * added to `minetest.registered_items[name]`
 
+* `minetest.register_biome(biome definition)`
+    * returns an integer uniquely identifying the registered biome
+    * added to `minetest.registered_biome` with the key of `biome.name`
+    * if `biome.name` is nil, the key is the returned ID
+
 * `minetest.register_ore(ore definition)`
     * returns an integer uniquely identifying the registered ore
     * added to `minetest.registered_ores` with the key of `ore.name`
@@ -429,11 +434,23 @@ the global `minetest.registered_*` tables.
     * added to `minetest.registered_decorations` with the key of `decoration.name`
     * if `decoration.name` is nil, the key is the returned ID
 
+* `minetest.register_schematic(schematic definition)`
+    * returns an integer uniquely identifying the registered schematic
+    * added to `minetest.registered_schematic` with the key of `schematic.name`
+    * if `schematic.name` is nil, the key is the returned ID
+    * if the schematic is loaded from a file, schematic.name is set to the filename
+
+* `minetest.clear_registered_biomes()`
+    * clears all biomes currently registered
+
 * `minetest.clear_registered_ores()`
-   * clears all ores currently registered
+    * clears all ores currently registered
 
 * `minetest.clear_registered_decorations()`
-   * clears all decorations currently registered
+    * clears all decorations currently registered
+
+* `minetest.clear_registered_schematics()`
+    * clears all schematics currently registered
 
 Note that in some cases you will stumble upon things that are not contained
 in these tables (e.g. when a mod has been removed). Always check for
index 851f018ee2f9f86d03bdaf8ffe8b12e79413cb74..fcde5bdb8cc75dbccaeff8e50f0e007f481ff09a 100644 (file)
@@ -36,11 +36,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "treegen.h"
 #include "serialization.h"
 #include "util/serialize.h"
+#include "util/numeric.h"
 #include "filesys.h"
 #include "log.h"
 
-const char *GenElementManager::ELEMENT_TITLE = "element";
-
 FlagDesc flagdesc_mapgen[] = {
        {"trees",    MG_TREES},
        {"caves",    MG_CAVES},
@@ -64,6 +63,7 @@ FlagDesc flagdesc_gennotify[] = {
 
 ///////////////////////////////////////////////////////////////////////////////
 
+
 Mapgen::Mapgen()
 {
        generating    = false;
@@ -431,85 +431,162 @@ void GenerateNotifier::getEvents(
 ///////////////////////////////////////////////////////////////////////////////
 
 
-GenElementManager::GenElementManager(IGameDef *gamedef)
+ObjDefManager::ObjDefManager(IGameDef *gamedef, ObjDefType type)
 {
+       m_objtype = type;
        m_ndef = gamedef->getNodeDefManager();
 }
 
 
-GenElementManager::~GenElementManager()
+ObjDefManager::~ObjDefManager()
 {
-       for (size_t i = 0; i != m_elements.size(); i++)
-               delete m_elements[i];
+       for (size_t i = 0; i != m_objects.size(); i++)
+               delete m_objects[i];
 }
 
 
-u32 GenElementManager::add(GenElement *elem)
+ObjDefHandle ObjDefManager::add(ObjDef *obj)
 {
-       size_t nelem = m_elements.size();
+       assert(obj);
 
-       for (size_t i = 0; i != nelem; i++) {
-               if (m_elements[i] == NULL) {
-                       elem->id = i;
-                       m_elements[i] = elem;
-                       return i;
-               }
-       }
+       if (obj->name.length() && getByName(obj->name))
+               return OBJDEF_INVALID_HANDLE;
+
+       u32 index = addRaw(obj);
+       if (index == OBJDEF_INVALID_INDEX)
+               return OBJDEF_INVALID_HANDLE;
 
-       if (nelem >= this->ELEMENT_LIMIT)
+       obj->handle = createHandle(index, m_objtype, obj->uid);
+       return obj->handle;
+}
+
+
+ObjDef *ObjDefManager::get(ObjDefHandle handle) const
+{
+       u32 index = validateHandle(handle);
+       return (index != OBJDEF_INVALID_INDEX) ? getRaw(index) : NULL;
+}
+
+
+ObjDef *ObjDefManager::set(ObjDefHandle handle, ObjDef *obj)
+{
+       u32 index = validateHandle(handle);
+       return (index != OBJDEF_INVALID_INDEX) ? setRaw(index, obj) : NULL;
+}
+
+
+u32 ObjDefManager::addRaw(ObjDef *obj)
+{
+       size_t nobjects = m_objects.size();
+       if (nobjects >= OBJDEF_MAX_ITEMS)
                return -1;
 
-       elem->id = nelem;
-       m_elements.push_back(elem);
+       obj->index = nobjects;
+
+       // Ensure UID is nonzero so that a valid handle == OBJDEF_INVALID_HANDLE
+       // is not possible.  The slight randomness bias isn't very significant.
+       obj->uid = myrand() & OBJDEF_UID_MASK;
+       if (obj->uid == 0)
+               obj->uid = 1;
+
+       m_objects.push_back(obj);
 
-       verbosestream << "GenElementManager: added " << this->ELEMENT_TITLE
-               << " element '" << elem->name << "'" << std::endl;
+       infostream << "ObjDefManager: added " << getObjectTitle()
+               << ": name=\"" << obj->name
+               << "\" index=" << obj->index
+               << " uid="     << obj->uid
+               << std::endl;
 
-       return nelem;
+       return nobjects;
 }
 
 
-GenElement *GenElementManager::get(u32 id)
+ObjDef *ObjDefManager::getRaw(u32 index) const
 {
-       return (id < m_elements.size()) ? m_elements[id] : NULL;
+       return m_objects[index];
 }
 
 
-GenElement *GenElementManager::getByName(const std::string &name)
+ObjDef *ObjDefManager::setRaw(u32 index, ObjDef *obj)
 {
-       for (size_t i = 0; i != m_elements.size(); i++) {
-               GenElement *elem = m_elements[i];
-               if (elem && name == elem->name)
-                       return elem;
+       ObjDef *old_obj = m_objects[index];
+       m_objects[index] = obj;
+       return old_obj;
+}
+
+
+ObjDef *ObjDefManager::getByName(const std::string &name) const
+{
+       for (size_t i = 0; i != m_objects.size(); i++) {
+               ObjDef *obj = m_objects[i];
+               if (obj && !strcasecmp(name.c_str(), obj->name.c_str()))
+                       return obj;
        }
 
        return NULL;
 }
 
 
-GenElement *GenElementManager::update(u32 id, GenElement *elem)
+void ObjDefManager::clear()
 {
-       if (id >= m_elements.size())
-               return NULL;
+       for (size_t i = 0; i != m_objects.size(); i++)
+               delete m_objects[i];
 
-       GenElement *old_elem = m_elements[id];
-       m_elements[id] = elem;
-       return old_elem;
+       m_objects.clear();
 }
 
 
-GenElement *GenElementManager::remove(u32 id)
+u32 ObjDefManager::validateHandle(ObjDefHandle handle) const
 {
-       return update(id, NULL);
+       ObjDefType type;
+       u32 index;
+       u32 uid;
+
+       bool is_valid =
+               (handle != OBJDEF_INVALID_HANDLE)         &&
+               decodeHandle(handle, &index, &type, &uid) &&
+               (type == m_objtype)                       &&
+               (index < m_objects.size())                &&
+               (m_objects[index]->uid == uid);
+
+       return is_valid ? index : -1;
 }
 
 
-void GenElementManager::clear()
+ObjDefHandle ObjDefManager::createHandle(u32 index, ObjDefType type, u32 uid)
 {
-       m_elements.clear();
+       ObjDefHandle handle = 0;
+       set_bits(&handle, 0, 18, index);
+       set_bits(&handle, 18, 6, type);
+       set_bits(&handle, 24, 7, uid);
+
+       u32 parity = calc_parity(handle);
+       set_bits(&handle, 31, 1, parity);
+
+       return handle ^ OBJDEF_HANDLE_SALT;
 }
 
 
+bool ObjDefManager::decodeHandle(ObjDefHandle handle, u32 *index,
+       ObjDefType *type, u32 *uid)
+{
+       handle ^= OBJDEF_HANDLE_SALT;
+
+       u32 parity = get_bits(handle, 31, 1);
+       set_bits(&handle, 31, 1, 0);
+       if (parity != calc_parity(handle))
+               return false;
+
+       *index = get_bits(handle, 0, 18);
+       *type  = (ObjDefType)get_bits(handle, 18, 6);
+       *uid   = get_bits(handle, 24, 7);
+       return true;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+
 void MapgenParams::load(const Settings &settings)
 {
        std::string seed_str;
index 5b5ed19a28b172d24e4cdac99db6a0a4e898ef34..59fe2fca7ce75ef3c3dcd6a8dd191b969540113b 100644 (file)
@@ -179,36 +179,68 @@ struct MapgenFactory {
        virtual ~MapgenFactory() {}
 };
 
-class GenElement {
+typedef std::map<std::string, std::string> StringMap;
+typedef u32 ObjDefHandle;
+
+#define OBJDEF_INVALID_INDEX ((u32)(-1))
+#define OBJDEF_INVALID_HANDLE 0
+#define OBJDEF_HANDLE_SALT 0x00585e6fu
+#define OBJDEF_MAX_ITEMS (1 << 18)
+#define OBJDEF_UID_MASK ((1 << 7) - 1)
+
+enum ObjDefType {
+       OBJDEF_GENERIC,
+       OBJDEF_BIOME,
+       OBJDEF_ORE,
+       OBJDEF_DECORATION,
+       OBJDEF_SCHEMATIC,
+};
+
+class ObjDef {
 public:
-       virtual ~GenElement() {}
-       u32 id;
+       virtual ~ObjDef() {}
+
+       u32 index;
+       u32 uid;
+       ObjDefHandle handle;
        std::string name;
 };
 
-class GenElementManager {
+class ObjDefManager {
 public:
-       static const char *ELEMENT_TITLE;
-       static const size_t ELEMENT_LIMIT = -1;
+       ObjDefManager(IGameDef *gamedef, ObjDefType type);
+       virtual ~ObjDefManager();
 
-       GenElementManager(IGameDef *gamedef);
-       virtual ~GenElementManager();
+       virtual const char *getObjectTitle() const = 0;
 
-       virtual GenElement *create(int type) = 0;
-
-       virtual u32 add(GenElement *elem);
-       virtual GenElement *get(u32 id);
-       virtual GenElement *update(u32 id, GenElement *elem);
-       virtual GenElement *remove(u32 id);
+       virtual ObjDef *create(int type) = 0;
        virtual void clear();
+       virtual ObjDef *getByName(const std::string &name) const;
+
+       //// Add new/get/set object definitions by handle
+       virtual ObjDefHandle add(ObjDef *obj);
+       virtual ObjDef *get(ObjDefHandle handle) const;
+       virtual ObjDef *set(ObjDefHandle handle, ObjDef *obj);
+
+       //// Raw variants that work on indexes
+       virtual u32 addRaw(ObjDef *obj);
+
+       // It is generally assumed that getRaw() will always return a valid object
+       // This won't be true if people do odd things such as call setRaw() with NULL
+       virtual ObjDef *getRaw(u32 index) const;
+       virtual ObjDef *setRaw(u32 index, ObjDef *obj);
 
-       virtual GenElement *getByName(const std::string &name);
+       INodeDefManager *getNodeDef() const { return m_ndef; }
 
-       INodeDefManager *getNodeDef() { return m_ndef; }
+       u32 validateHandle(ObjDefHandle handle) const;
+       static ObjDefHandle createHandle(u32 index, ObjDefType type, u32 uid);
+       static bool decodeHandle(ObjDefHandle handle, u32 *index,
+               ObjDefType *type, u32 *uid);
 
 protected:
        INodeDefManager *m_ndef;
-       std::vector<GenElement *> m_elements;
+       std::vector<ObjDef *> m_objects;
+       ObjDefType m_objtype;
 };
 
 #endif
index 240ae500a0ccad19bd555a478908db9744f7fef3..7d74c80bddc5f25b9fe3e39ae622a0b80a80ea62 100644 (file)
@@ -479,7 +479,7 @@ void MapgenV5::generateCaves(int max_stone_y)
                for (s16 y=node_min.Y - 1; y<=node_max.Y + 1; y++) {
                        u32 i = vm->m_area.index(node_min.X, y, z);
                        for (s16 x=node_min.X; x<=node_max.X; x++, i++, index++, index2d++) {
-                               Biome *biome = (Biome *)bmgr->get(biomemap[index2d]);
+                               Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
                                content_t c = vm->m_data[i].getContent();
                                if (c == CONTENT_AIR
                                                || (y <= water_level
@@ -519,7 +519,7 @@ void MapgenV5::dustTopNodes()
 
        for (s16 z = node_min.Z; z <= node_max.Z; z++)
        for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
-               Biome *biome = (Biome *)bmgr->get(biomemap[index]);
+               Biome *biome = (Biome *)bmgr->getRaw(biomemap[index]);
 
                if (biome->c_dust == CONTENT_IGNORE)
                        continue;
index 44cb37f11ffbce8b50529c9a1bb70753c4e3f835..3e7188a2c9d11847b2d9ceaa3deb1704c6dd7600 100644 (file)
@@ -674,7 +674,7 @@ void MapgenV7::dustTopNodes()
 
        for (s16 z = node_min.Z; z <= node_max.Z; z++)
        for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
-               Biome *biome = (Biome *)bmgr->get(biomemap[index]);
+               Biome *biome = (Biome *)bmgr->getRaw(biomemap[index]);
 
                if (biome->c_dust == CONTENT_IGNORE)
                        continue;
@@ -821,7 +821,7 @@ void MapgenV7::generateCaves(int max_stone_y)
                                u32 i = vm->m_area.index(node_min.X, y, z);
                                for (s16 x = node_min.X; x <= node_max.X;
                                                x++, i++, index++, index2d++) {
-                                       Biome *biome = (Biome *)bmgr->get(biomemap[index2d]);
+                                       Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
                                        content_t c = vm->m_data[i].getContent();
                                        if (c == CONTENT_AIR || (y <= water_level &&
                                                c != biome->c_stone && c != c_stone))
index e076d30922dcdcf48591c1ccb1ca4ae92119d6dc..a8b150e53c94499d34b78bce2fc5c870691b442b 100644 (file)
@@ -27,18 +27,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "util/mathconstants.h"
 #include "porting.h"
 
-const char *BiomeManager::ELEMENT_TITLE = "biome";
-
 
 ///////////////////////////////////////////////////////////////////////////////
 
+
 BiomeManager::BiomeManager(IGameDef *gamedef) :
-       GenElementManager(gamedef)
+       ObjDefManager(gamedef, OBJDEF_BIOME)
 {
        // Create default biome to be used in case none exist
        Biome *b = new Biome;
 
-       b->id              = 0;
        b->name            = "Default";
        b->flags           = 0;
        b->depth_top       = 0;
@@ -75,8 +73,10 @@ BiomeManager::~BiomeManager()
 void BiomeManager::calcBiomes(s16 sx, s16 sy, float *heat_map,
        float *humidity_map, s16 *height_map, u8 *biomeid_map)
 {
-       for (s32 i = 0; i != sx * sy; i++)
-               biomeid_map[i] = getBiome(heat_map[i], humidity_map[i], height_map[i])->id;
+       for (s32 i = 0; i != sx * sy; i++) {
+               Biome *biome = getBiome(heat_map[i], humidity_map[i], height_map[i]);
+               biomeid_map[i] = biome->index;
+       }
 }
 
 
@@ -85,8 +85,8 @@ Biome *BiomeManager::getBiome(float heat, float humidity, s16 y)
        Biome *b, *biome_closest = NULL;
        float dist_min = FLT_MAX;
 
-       for (size_t i = 1; i < m_elements.size(); i++) {
-               b = (Biome *)m_elements[i];
+       for (size_t i = 1; i < m_objects.size(); i++) {
+               b = (Biome *)m_objects[i];
                if (!b || y > b->y_max || y < b->y_min)
                        continue;
 
@@ -100,18 +100,18 @@ Biome *BiomeManager::getBiome(float heat, float humidity, s16 y)
                }
        }
 
-       return biome_closest ? biome_closest : (Biome *)m_elements[0];
+       return biome_closest ? biome_closest : (Biome *)m_objects[0];
 }
 
 void BiomeManager::clear()
 {
 
-       for (size_t i = 1; i < m_elements.size(); i++) {
-               Biome *b = (Biome *)m_elements[i];
+       for (size_t i = 1; i < m_objects.size(); i++) {
+               Biome *b = (Biome *)m_objects[i];
                delete b;
        }
 
-       m_elements.resize(1);
+       m_objects.resize(1);
 }
 
 
index 3648c085dfec21f27f46f08b892c3b63f44124f9..4e7e3fd7e449d37061dc84cecfda84dc4adb9d91 100644 (file)
@@ -33,7 +33,7 @@ enum BiomeType
        BIOME_TYPE_FLAT
 };
 
-class Biome : public GenElement, public NodeResolver {
+class Biome : public ObjDef, public NodeResolver {
 public:
        u32 flags;
 
@@ -56,14 +56,18 @@ public:
        virtual void resolveNodeNames(NodeResolveInfo *nri);
 };
 
-class BiomeManager : public GenElementManager {
+class BiomeManager : public ObjDefManager {
 public:
-       static const char *ELEMENT_TITLE;
-       static const size_t ELEMENT_LIMIT = 0x100;
+       static const char *OBJECT_TITLE;
 
        BiomeManager(IGameDef *gamedef);
        ~BiomeManager();
 
+       const char *getObjectTitle() const
+       {
+               return "biome";
+       }
+
        Biome *create(int btt)
        {
                return new Biome;
index 23bbfa7305b5dc4e2b13c36045b7cefe19a7f76f..1858e346ad2310dbe98d7a07d45efc74fe85ffb3 100644 (file)
@@ -25,8 +25,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "log.h"
 #include "util/numeric.h"
 
-const char *DecorationManager::ELEMENT_TITLE = "decoration";
-
 FlagDesc flagdesc_deco[] = {
        {"place_center_x", DECO_PLACE_CENTER_X},
        {"place_center_y", DECO_PLACE_CENTER_Y},
@@ -40,7 +38,7 @@ FlagDesc flagdesc_deco[] = {
 
 
 DecorationManager::DecorationManager(IGameDef *gamedef) :
-       GenElementManager(gamedef)
+       ObjDefManager(gamedef, OBJDEF_DECORATION)
 {
 }
 
@@ -50,8 +48,8 @@ size_t DecorationManager::placeAllDecos(Mapgen *mg, u32 blockseed,
 {
        size_t nplaced = 0;
 
-       for (size_t i = 0; i != m_elements.size(); i++) {
-               Decoration *deco = (Decoration *)m_elements[i];
+       for (size_t i = 0; i != m_objects.size(); i++) {
+               Decoration *deco = (Decoration *)m_objects[i];
                if (!deco)
                        continue;
 
@@ -65,11 +63,11 @@ size_t DecorationManager::placeAllDecos(Mapgen *mg, u32 blockseed,
 
 void DecorationManager::clear()
 {
-       for (size_t i = 0; i < m_elements.size(); i++) {
-               Decoration *deco = (Decoration *)m_elements[i];
+       for (size_t i = 0; i < m_objects.size(); i++) {
+               Decoration *deco = (Decoration *)m_objects[i];
                delete deco;
        }
-       m_elements.clear();
+       m_objects.clear();
 }
 
 
@@ -169,7 +167,7 @@ size_t Decoration::placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
 
                        v3s16 pos(x, y, z);
                        if (generate(mg->vm, &ps, pos))
-                               mg->gennotify.addEvent(GENNOTIFY_DECORATION, pos, id);
+                               mg->gennotify.addEvent(GENNOTIFY_DECORATION, pos, index);
                }
        }
 
index 20a22d449e058ad08193f159f1538b419dbf5e13..3b809b8d4916e8ff4582d0166a3022162f50f9d5 100644 (file)
@@ -59,7 +59,7 @@ struct CutoffData {
 };
 #endif
 
-class Decoration : public GenElement, public NodeResolver {
+class Decoration : public ObjDef, public NodeResolver {
 public:
        INodeDefManager *ndef;
 
@@ -121,14 +121,16 @@ public:
 };
 */
 
-class DecorationManager : public GenElementManager {
+class DecorationManager : public ObjDefManager {
 public:
-       static const char *ELEMENT_TITLE;
-       static const size_t ELEMENT_LIMIT = 0x10000;
-
        DecorationManager(IGameDef *gamedef);
        ~DecorationManager() {}
 
+       const char *getObjectTitle() const
+       {
+               return "decoration";
+       }
+
        Decoration *create(int type)
        {
                switch (type) {
index 850f2551688afa3e6692d9b0ba80961ecea928d7..e7e062c695cc439760a9002534bbd265aa6d1fc4 100644 (file)
@@ -24,8 +24,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "map.h"
 #include "log.h"
 
-const char *OreManager::ELEMENT_TITLE = "ore";
-
 FlagDesc flagdesc_ore[] = {
        {"absheight", OREFLAG_ABSHEIGHT},
        {NULL,        0}
@@ -36,7 +34,7 @@ FlagDesc flagdesc_ore[] = {
 
 
 OreManager::OreManager(IGameDef *gamedef) :
-       GenElementManager(gamedef)
+       ObjDefManager(gamedef, OBJDEF_ORE)
 {
 }
 
@@ -45,8 +43,8 @@ size_t OreManager::placeAllOres(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nma
 {
        size_t nplaced = 0;
 
-       for (size_t i = 0; i != m_elements.size(); i++) {
-               Ore *ore = (Ore *)m_elements[i];
+       for (size_t i = 0; i != m_objects.size(); i++) {
+               Ore *ore = (Ore *)m_objects[i];
                if (!ore)
                        continue;
 
@@ -60,11 +58,11 @@ size_t OreManager::placeAllOres(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nma
 
 void OreManager::clear()
 {
-       for (size_t i = 0; i < m_elements.size(); i++) {
-               Ore *ore = (Ore *)m_elements[i];
+       for (size_t i = 0; i < m_objects.size(); i++) {
+               Ore *ore = (Ore *)m_objects[i];
                delete ore;
        }
-       m_elements.clear();
+       m_objects.clear();
 }
 
 
index 67ca9a849630f03d1ad5801ab157ecf4e10874e1..978b8ae3dda3296a147032215e77aafb59c3c349 100644 (file)
@@ -47,7 +47,7 @@ enum OreType {
 
 extern FlagDesc flagdesc_ore[];
 
-class Ore : public GenElement, public NodeResolver {
+class Ore : public ObjDef, public NodeResolver {
 public:
        static const bool NEEDS_NOISE = false;
 
@@ -112,14 +112,16 @@ public:
                v3s16 nmin, v3s16 nmax);
 };
 
-class OreManager : public GenElementManager {
+class OreManager : public ObjDefManager {
 public:
-       static const char *ELEMENT_TITLE;
-       static const size_t ELEMENT_LIMIT = 0x10000;
-
        OreManager(IGameDef *gamedef);
        ~OreManager() {}
 
+       const char *getObjectTitle() const
+       {
+               return "ore";
+       }
+
        Ore *create(int type)
        {
                switch (type) {
index 23b62115f2078b6ebe19d1bb7add1756f8e87c35..f154f4fda6685e69c4d06804e7923991966625de 100644 (file)
@@ -28,13 +28,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "serialization.h"
 #include "filesys.h"
 
-const char *SchematicManager::ELEMENT_TITLE = "schematic";
-
 ///////////////////////////////////////////////////////////////////////////////
 
 
 SchematicManager::SchematicManager(IGameDef *gamedef) :
-       GenElementManager(gamedef)
+       ObjDefManager(gamedef, OBJDEF_SCHEMATIC)
 {
 }
 
@@ -201,7 +199,7 @@ void Schematic::placeStructure(Map *map, v3s16 p, u32 flags, Rotation rot,
 
 
 bool Schematic::loadSchematicFromFile(const char *filename, INodeDefManager *ndef,
-       std::map<std::string, std::string> &replace_names)
+       StringMap *replace_names)
 {
        content_t cignore = CONTENT_IGNORE;
        bool have_cignore = false;
@@ -246,8 +244,8 @@ bool Schematic::loadSchematicFromFile(const char *filename, INodeDefManager *nde
                }
 
                std::map<std::string, std::string>::iterator it;
-               it = replace_names.find(name);
-               if (it != replace_names.end())
+               it = replace_names->find(name);
+               if (it != replace_names->end())
                        name = it->second;
 
                nri->nodenames.push_back(name);
index ad5afb15f5d3a864032fbc5351b53f5c5b51dfb5..4a85f69a679787ea0491a4d9c17b4f450c216d5a 100644 (file)
@@ -42,7 +42,7 @@ class NodeResolver;
 #define MTSCHEM_PROB_ALWAYS 0xFF
 
 
-class Schematic : public GenElement, public NodeResolver {
+class Schematic : public ObjDef, public NodeResolver {
 public:
        std::vector<content_t> c_nodes;
 
@@ -62,7 +62,7 @@ public:
                Rotation rot, bool force_placement, INodeDefManager *ndef);
 
        bool loadSchematicFromFile(const char *filename, INodeDefManager *ndef,
-               std::map<std::string, std::string> &replace_names);
+               StringMap *replace_names);
        void saveSchematicToFile(const char *filename, INodeDefManager *ndef);
        bool getSchematicFromMap(Map *map, v3s16 p1, v3s16 p2);
 
@@ -73,14 +73,16 @@ public:
                std::vector<std::pair<s16, u8> > *splist);
 };
 
-class SchematicManager : public GenElementManager {
+class SchematicManager : public ObjDefManager {
 public:
-       static const char *ELEMENT_TITLE;
-       static const size_t ELEMENT_LIMIT = 0x10000;
-
        SchematicManager(IGameDef *gamedef);
        ~SchematicManager() {}
 
+       const char *getObjectTitle() const
+       {
+               return "schematic";
+       }
+
        Schematic *create(int type)
        {
                return new Schematic;
index 172f2b5cc000db5fff3e5b9761f10eb1c7dfb81d..5af6cf457f7adf447ae1535da9e78266bed5644a 100644 (file)
@@ -86,11 +86,56 @@ struct EnumString ModApiMapgen::es_Rotation[] =
 };
 
 
+bool read_schematic_def(lua_State *L, int index, Schematic *schem,
+       INodeDefManager *ndef, StringMap *replace_names);
+
 ///////////////////////////////////////////////////////////////////////////////
 
 
+Schematic *get_schematic(lua_State *L, int index,
+       SchematicManager *schemmgr, StringMap *replace_names)
+{
+       if (index < 0)
+               index = lua_gettop(L) + 1 + index;
+
+       Schematic *schem;
+
+       if (lua_isnumber(L, index)) {
+               return (Schematic *)schemmgr->get(lua_tointeger(L, index));
+       } else if (lua_istable(L, index)) {
+               schem = new Schematic;
+               if (!read_schematic_def(L, index, schem,
+                               schemmgr->getNodeDef(), replace_names)) {
+                       delete schem;
+                       return NULL;
+               }
+       } else  if (lua_isstring(L, index)) {
+               const char *filename = lua_tostring(L, index);
+               schem = (Schematic *)schemmgr->getByName(filename);
+               if (schem)
+                       return schem;
+
+               schem = new Schematic;
+               if (!schem->loadSchematicFromFile(filename,
+                               schemmgr->getNodeDef(), replace_names)) {
+                       delete schem;
+                       return NULL;
+               }
+       } else {
+               return NULL;
+       }
+
+       if (schemmgr->add(schem) == OBJDEF_INVALID_HANDLE) {
+               delete schem;
+               return NULL;
+       }
+
+       return schem;
+}
+
+
 bool read_schematic_def(lua_State *L, int index, Schematic *schem,
-       INodeDefManager *ndef, std::map<std::string, std::string> &replace_names)
+       INodeDefManager *ndef, StringMap *replace_names)
 {
        //// Get schematic size
        lua_getfield(L, index, "size");
@@ -128,9 +173,8 @@ bool read_schematic_def(lua_State *L, int index, Schematic *schem,
                param2 = !lua_isnil(L, -1) ? lua_tonumber(L, -1) : 0;
                lua_pop(L, 1);
 
-               std::map<std::string, std::string>::iterator it;
-               it = replace_names.find(name);
-               if (it != replace_names.end())
+               StringMap::iterator it = replace_names->find(name);
+               if (it != replace_names->end())
                        name = it->second;
 
                schemdata[i] = MapNode(ndef, name, param1, param2);
@@ -175,51 +219,12 @@ bool read_schematic_def(lua_State *L, int index, Schematic *schem,
 }
 
 
-Schematic *get_schematic(lua_State *L, int index, SchematicManager *schemmgr,
-       std::map<std::string, std::string> &replace_names)
+
+void read_schematic_replacements(lua_State *L, int index, StringMap *replace_names)
 {
        if (index < 0)
                index = lua_gettop(L) + 1 + index;
 
-       Schematic *schem;
-
-       if (lua_isnumber(L, index)) {
-               return (Schematic *)schemmgr->get(lua_tointeger(L, index));
-       } else if (lua_istable(L, index)) {
-               schem = new Schematic;
-               if (!read_schematic_def(L, index, schem,
-                               schemmgr->getNodeDef(), replace_names)) {
-                       delete schem;
-                       return NULL;
-               }
-       } else  if (lua_isstring(L, index)) {
-               const char *filename = lua_tostring(L, index);
-               schem = (Schematic *)schemmgr->getByName(filename);
-               if (schem)
-                       return schem;
-
-               schem = new Schematic;
-               if (!schem->loadSchematicFromFile(filename,
-                               schemmgr->getNodeDef(), replace_names)) {
-                       delete schem;
-                       return NULL;
-               }
-       } else {
-               return NULL;
-       }
-
-       if (schemmgr->add(schem) == (u32)-1) {
-               delete schem;
-               return 0;
-       }
-
-       return schem;
-}
-
-
-void read_schematic_replacements(lua_State *L,
-       std::map<std::string, std::string> &replace_names, int index)
-{
        lua_pushnil(L);
        while (lua_next(L, index)) {
                std::string replace_from;
@@ -238,7 +243,7 @@ void read_schematic_replacements(lua_State *L,
                        replace_to = lua_tostring(L, -1);
                }
 
-               replace_names[replace_from] = replace_to;
+               replace_names->insert(std::make_pair(replace_from, replace_to));
                lua_pop(L, 1);
        }
 }
@@ -477,24 +482,23 @@ int ModApiMapgen::l_register_biome(lua_State *L)
        b->humidity_point  = getfloatfield_default(L, index, "humidity_point", 0.f);
        b->flags           = 0; //reserved
 
-       u32 id = bmgr->add(b);
-       if (id == (u32)-1) {
+       ObjDefHandle handle = bmgr->add(b);
+       if (handle == OBJDEF_INVALID_HANDLE) {
                delete b;
                return 0;
        }
 
        NodeResolveInfo *nri = new NodeResolveInfo(b);
        std::list<std::string> &nnames = nri->nodenames;
-       nnames.push_back(getstringfield_default(L, index, "node_top",          ""));
-       nnames.push_back(getstringfield_default(L, index, "node_filler",       ""));
-       nnames.push_back(getstringfield_default(L, index, "node_stone",        ""));
-       nnames.push_back(getstringfield_default(L, index, "node_water_top",    ""));
-       nnames.push_back(getstringfield_default(L, index, "node_water",        ""));
-       nnames.push_back(getstringfield_default(L, index, "node_dust",         ""));
+       nnames.push_back(getstringfield_default(L, index, "node_top",       ""));
+       nnames.push_back(getstringfield_default(L, index, "node_filler",    ""));
+       nnames.push_back(getstringfield_default(L, index, "node_stone",     ""));
+       nnames.push_back(getstringfield_default(L, index, "node_water_top", ""));
+       nnames.push_back(getstringfield_default(L, index, "node_water",     ""));
+       nnames.push_back(getstringfield_default(L, index, "node_dust",      ""));
        ndef->pendNodeResolve(nri);
 
-       verbosestream << "register_biome: " << b->name << std::endl;
-       lua_pushinteger(L, id);
+       lua_pushinteger(L, handle);
        return 1;
 }
 
@@ -556,20 +560,20 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
                if (!b)
                        continue;
 
-               deco->biomes.insert(b->id);
+               deco->biomes.insert(b->index);
        }
 
        //// Handle decoration type-specific parameters
        bool success = false;
        switch (decotype) {
-               case DECO_SIMPLE:
-                       success = regDecoSimple(L, nri, (DecoSimple *)deco);
-                       break;
-               case DECO_SCHEMATIC:
-                       success = regDecoSchematic(L, schemmgr, (DecoSchematic *)deco);
-                       break;
-               case DECO_LSYSTEM:
-                       break;
+       case DECO_SIMPLE:
+               success = regDecoSimple(L, nri, (DecoSimple *)deco);
+               break;
+       case DECO_SCHEMATIC:
+               success = regDecoSchematic(L, schemmgr, (DecoSchematic *)deco);
+               break;
+       case DECO_LSYSTEM:
+               break;
        }
 
        ndef->pendNodeResolve(nri);
@@ -579,14 +583,13 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
                return 0;
        }
 
-       u32 id = decomgr->add(deco);
-       if (id == (u32)-1) {
+       ObjDefHandle handle = decomgr->add(deco);
+       if (handle == OBJDEF_INVALID_HANDLE) {
                delete deco;
                return 0;
        }
 
-       verbosestream << "register_decoration: " << deco->name << std::endl;
-       lua_pushinteger(L, id);
+       lua_pushinteger(L, handle);
        return 1;
 }
 
@@ -638,14 +641,14 @@ bool ModApiMapgen::regDecoSchematic(lua_State *L,
        deco->rotation = (Rotation)getenumfield(L, index, "rotation",
                es_Rotation, ROTATE_0);
 
-       std::map<std::string, std::string> replace_names;
+       StringMap replace_names;
        lua_getfield(L, index, "replacements");
        if (lua_istable(L, -1))
-               read_schematic_replacements(L, replace_names, lua_gettop(L));
+               read_schematic_replacements(L, -1, &replace_names);
        lua_pop(L, 1);
 
        lua_getfield(L, index, "schematic");
-       Schematic *schem = get_schematic(L, -1, schemmgr, replace_names);
+       Schematic *schem = get_schematic(L, -1, schemmgr, &replace_names);
        lua_pop(L, 1);
 
        deco->schematic = schem;
@@ -719,8 +722,8 @@ int ModApiMapgen::l_register_ore(lua_State *L)
                        "random_factor", 1.f);
        }
 
-       u32 id = oremgr->add(ore);
-       if (id == (u32)-1) {
+       ObjDefHandle handle = oremgr->add(ore);
+       if (handle == OBJDEF_INVALID_HANDLE) {
                delete ore;
                return 0;
        }
@@ -736,8 +739,7 @@ int ModApiMapgen::l_register_ore(lua_State *L)
 
        ndef->pendNodeResolve(nri);
 
-       verbosestream << "register_ore: " << ore->name << std::endl;
-       lua_pushinteger(L, id);
+       lua_pushinteger(L, handle);
        return 1;
 }
 
@@ -746,16 +748,21 @@ int ModApiMapgen::l_register_schematic(lua_State *L)
 {
        SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr;
 
-       std::map<std::string, std::string> replace_names;
+       StringMap replace_names;
        if (lua_istable(L, 2))
-               read_schematic_replacements(L, replace_names, 2);
+               read_schematic_replacements(L, 2, &replace_names);
 
-       Schematic *schem = get_schematic(L, 1, schemmgr, replace_names);
+       Schematic *schem = get_schematic(L, 1, schemmgr, &replace_names);
        if (!schem)
                return 0;
-       printf("register_schematic!\n");
-       verbosestream << "register_schematic: " << schem->name << std::endl;
-       lua_pushinteger(L, schem->id);
+
+       ObjDefHandle handle = schemmgr->add(schem);
+       if (handle == OBJDEF_INVALID_HANDLE) {
+               delete schem;
+               return 0;
+       }
+
+       lua_pushinteger(L, handle);
        return 1;
 }
 
@@ -837,7 +844,7 @@ int ModApiMapgen::l_generate_decorations(lua_State *L)
        return 0;
 }
 
-// create_schematic(p1, p2, probability_list, filename)
+// create_schematic(p1, p2, probability_list, filename, y_slice_prob_list)
 int ModApiMapgen::l_create_schematic(lua_State *L)
 {
        Schematic schem;
@@ -894,6 +901,7 @@ int ModApiMapgen::l_create_schematic(lua_State *L)
        actionstream << "create_schematic: saved schematic file '"
                << filename << "'." << std::endl;
 
+       lua_pushboolean(L, true);
        return 1;
 }
 
@@ -917,12 +925,12 @@ int ModApiMapgen::l_place_schematic(lua_State *L)
                force_placement = lua_toboolean(L, 5);
 
        //// Read node replacements
-       std::map<std::string, std::string> replace_names;
+       StringMap replace_names;
        if (lua_istable(L, 4))
-               read_schematic_replacements(L, replace_names, 4);
+               read_schematic_replacements(L, 4, &replace_names);
 
        //// Read schematic
-       Schematic *schem = get_schematic(L, 2, schemmgr, replace_names);
+       Schematic *schem = get_schematic(L, 2, schemmgr, &replace_names);
        if (!schem) {
                errorstream << "place_schematic: failed to get schematic" << std::endl;
                return 0;
@@ -931,6 +939,7 @@ int ModApiMapgen::l_place_schematic(lua_State *L)
        schem->placeStructure(map, p, 0, (Rotation)rot, force_placement,
                schemmgr->getNodeDef());
 
+       lua_pushboolean(L, true);
        return 1;
 }
 
index a1f1fd0ab1d308cec13a6d6c94a18d6be3f13f30..2306976ecd0803a03f7f12519cb0192698da438a 100644 (file)
@@ -183,7 +183,6 @@ u64 murmur_hash_64_ua(const void *key, int len, unsigned int seed)
        return h;
 }
 
-
 /*
        blockpos: position of block in block coordinates
        camera_pos: position of camera in nodes
index ccc9fbee4192112b4b2b914269cc6b063cbad346..74c1dfea623cbfeadbe5ea5f4117c89c9751aab5 100644 (file)
@@ -249,6 +249,28 @@ int myrand_range(int min, int max);
        Miscellaneous functions
 */
 
+inline u32 get_bits(u32 x, u32 pos, u32 len)
+{
+       u32 mask = (1 << len) - 1;
+       return (x >> pos) & mask;
+}
+
+inline void set_bits(u32 *x, u32 pos, u32 len, u32 val)
+{
+       u32 mask = (1 << len) - 1;
+       *x &= ~(mask << len);
+       *x |= (val & mask) << pos;
+}
+
+inline u32 calc_parity(u32 v)
+{
+       v ^= v >> 16;
+       v ^= v >> 8;
+       v ^= v >> 4;
+       v &= 0xf;
+       return (0x6996 >> v) & 1;
+}
+
 u64 murmur_hash_64_ua(const void *key, int len, unsigned int seed);
 
 bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,