aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/lua_api.txt21
-rw-r--r--src/mapgen.cpp153
-rw-r--r--src/mapgen.h66
-rw-r--r--src/mapgen_v5.cpp4
-rw-r--r--src/mapgen_v7.cpp4
-rw-r--r--src/mg_biome.cpp24
-rw-r--r--src/mg_biome.h12
-rw-r--r--src/mg_decoration.cpp16
-rw-r--r--src/mg_decoration.h12
-rw-r--r--src/mg_ore.cpp14
-rw-r--r--src/mg_ore.h12
-rw-r--r--src/mg_schematic.cpp10
-rw-r--r--src/mg_schematic.h14
-rw-r--r--src/script/lua_api/l_mapgen.cpp181
-rw-r--r--src/util/numeric.cpp1
-rw-r--r--src/util/numeric.h22
16 files changed, 363 insertions, 203 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 1431181f1..19d4f1672 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -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
diff --git a/src/mapgen.cpp b/src/mapgen.cpp
index 851f018ee..fcde5bdb8 100644
--- a/src/mapgen.cpp
+++ b/src/mapgen.cpp
@@ -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;
diff --git a/src/mapgen.h b/src/mapgen.h
index 5b5ed19a2..59fe2fca7 100644
--- a/src/mapgen.h
+++ b/src/mapgen.h
@@ -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
diff --git a/src/mapgen_v5.cpp b/src/mapgen_v5.cpp
index 240ae500a..7d74c80bd 100644
--- a/src/mapgen_v5.cpp
+++ b/src/mapgen_v5.cpp
@@ -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;
diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp
index 44cb37f11..3e7188a2c 100644
--- a/src/mapgen_v7.cpp
+++ b/src/mapgen_v7.cpp
@@ -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))
diff --git a/src/mg_biome.cpp b/src/mg_biome.cpp
index e076d3092..a8b150e53 100644
--- a/src/mg_biome.cpp
+++ b/src/mg_biome.cpp
@@ -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);
}
diff --git a/src/mg_biome.h b/src/mg_biome.h
index 3648c085d..4e7e3fd7e 100644
--- a/src/mg_biome.h
+++ b/src/mg_biome.h
@@ -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;
diff --git a/src/mg_decoration.cpp b/src/mg_decoration.cpp
index 23bbfa730..1858e346a 100644
--- a/src/mg_decoration.cpp
+++ b/src/mg_decoration.cpp
@@ -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);
}
}
diff --git a/src/mg_decoration.h b/src/mg_decoration.h
index 20a22d449..3b809b8d4 100644
--- a/src/mg_decoration.h
+++ b/src/mg_decoration.h
@@ -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) {
diff --git a/src/mg_ore.cpp b/src/mg_ore.cpp
index 850f25516..e7e062c69 100644
--- a/src/mg_ore.cpp
+++ b/src/mg_ore.cpp
@@ -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();
}
diff --git a/src/mg_ore.h b/src/mg_ore.h
index 67ca9a849..978b8ae3d 100644
--- a/src/mg_ore.h
+++ b/src/mg_ore.h
@@ -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) {
diff --git a/src/mg_schematic.cpp b/src/mg_schematic.cpp
index 23b62115f..f154f4fda 100644
--- a/src/mg_schematic.cpp
+++ b/src/mg_schematic.cpp
@@ -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);
diff --git a/src/mg_schematic.h b/src/mg_schematic.h
index ad5afb15f..4a85f69a6 100644
--- a/src/mg_schematic.h
+++ b/src/mg_schematic.h
@@ -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;
diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp
index 172f2b5cc..5af6cf457 100644
--- a/src/script/lua_api/l_mapgen.cpp
+++ b/src/script/lua_api/l_mapgen.cpp
@@ -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;
}
diff --git a/src/util/numeric.cpp b/src/util/numeric.cpp
index a1f1fd0ab..2306976ec 100644
--- a/src/util/numeric.cpp
+++ b/src/util/numeric.cpp
@@ -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
diff --git a/src/util/numeric.h b/src/util/numeric.h
index ccc9fbee4..74c1dfea6 100644
--- a/src/util/numeric.h
+++ b/src/util/numeric.h
@@ -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,