Skip to content

Commit ed10005

Browse files
committedMar 31, 2015
GenElementManager: Pass opaque handles to Lua and rename to ObjDefManager
Add core.clear_registered_schematics() and refactor schematics somewhat
1 parent 6a48844 commit ed10005

16 files changed

+363
-203
lines changed
 

Diff for: ‎doc/lua_api.txt

+19-2
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,11 @@ the global `minetest.registered_*` tables.
419419
* `minetest.register_craftitem(name, item definition)`
420420
* added to `minetest.registered_items[name]`
421421

422+
* `minetest.register_biome(biome definition)`
423+
* returns an integer uniquely identifying the registered biome
424+
* added to `minetest.registered_biome` with the key of `biome.name`
425+
* if `biome.name` is nil, the key is the returned ID
426+
422427
* `minetest.register_ore(ore definition)`
423428
* returns an integer uniquely identifying the registered ore
424429
* added to `minetest.registered_ores` with the key of `ore.name`
@@ -429,11 +434,23 @@ the global `minetest.registered_*` tables.
429434
* added to `minetest.registered_decorations` with the key of `decoration.name`
430435
* if `decoration.name` is nil, the key is the returned ID
431436

437+
* `minetest.register_schematic(schematic definition)`
438+
* returns an integer uniquely identifying the registered schematic
439+
* added to `minetest.registered_schematic` with the key of `schematic.name`
440+
* if `schematic.name` is nil, the key is the returned ID
441+
* if the schematic is loaded from a file, schematic.name is set to the filename
442+
443+
* `minetest.clear_registered_biomes()`
444+
* clears all biomes currently registered
445+
432446
* `minetest.clear_registered_ores()`
433-
* clears all ores currently registered
447+
* clears all ores currently registered
434448

435449
* `minetest.clear_registered_decorations()`
436-
* clears all decorations currently registered
450+
* clears all decorations currently registered
451+
452+
* `minetest.clear_registered_schematics()`
453+
* clears all schematics currently registered
437454

438455
Note that in some cases you will stumble upon things that are not contained
439456
in these tables (e.g. when a mod has been removed). Always check for

Diff for: ‎src/mapgen.cpp

+115-38
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
3636
#include "treegen.h"
3737
#include "serialization.h"
3838
#include "util/serialize.h"
39+
#include "util/numeric.h"
3940
#include "filesys.h"
4041
#include "log.h"
4142

42-
const char *GenElementManager::ELEMENT_TITLE = "element";
43-
4443
FlagDesc flagdesc_mapgen[] = {
4544
{"trees", MG_TREES},
4645
{"caves", MG_CAVES},
@@ -64,6 +63,7 @@ FlagDesc flagdesc_gennotify[] = {
6463

6564
///////////////////////////////////////////////////////////////////////////////
6665

66+
6767
Mapgen::Mapgen()
6868
{
6969
generating = false;
@@ -431,85 +431,162 @@ void GenerateNotifier::getEvents(
431431
///////////////////////////////////////////////////////////////////////////////
432432

433433

434-
GenElementManager::GenElementManager(IGameDef *gamedef)
434+
ObjDefManager::ObjDefManager(IGameDef *gamedef, ObjDefType type)
435435
{
436+
m_objtype = type;
436437
m_ndef = gamedef->getNodeDefManager();
437438
}
438439

439440

440-
GenElementManager::~GenElementManager()
441+
ObjDefManager::~ObjDefManager()
441442
{
442-
for (size_t i = 0; i != m_elements.size(); i++)
443-
delete m_elements[i];
443+
for (size_t i = 0; i != m_objects.size(); i++)
444+
delete m_objects[i];
444445
}
445446

446447

447-
u32 GenElementManager::add(GenElement *elem)
448+
ObjDefHandle ObjDefManager::add(ObjDef *obj)
448449
{
449-
size_t nelem = m_elements.size();
450+
assert(obj);
450451

451-
for (size_t i = 0; i != nelem; i++) {
452-
if (m_elements[i] == NULL) {
453-
elem->id = i;
454-
m_elements[i] = elem;
455-
return i;
456-
}
457-
}
452+
if (obj->name.length() && getByName(obj->name))
453+
return OBJDEF_INVALID_HANDLE;
454+
455+
u32 index = addRaw(obj);
456+
if (index == OBJDEF_INVALID_INDEX)
457+
return OBJDEF_INVALID_HANDLE;
458458

459-
if (nelem >= this->ELEMENT_LIMIT)
459+
obj->handle = createHandle(index, m_objtype, obj->uid);
460+
return obj->handle;
461+
}
462+
463+
464+
ObjDef *ObjDefManager::get(ObjDefHandle handle) const
465+
{
466+
u32 index = validateHandle(handle);
467+
return (index != OBJDEF_INVALID_INDEX) ? getRaw(index) : NULL;
468+
}
469+
470+
471+
ObjDef *ObjDefManager::set(ObjDefHandle handle, ObjDef *obj)
472+
{
473+
u32 index = validateHandle(handle);
474+
return (index != OBJDEF_INVALID_INDEX) ? setRaw(index, obj) : NULL;
475+
}
476+
477+
478+
u32 ObjDefManager::addRaw(ObjDef *obj)
479+
{
480+
size_t nobjects = m_objects.size();
481+
if (nobjects >= OBJDEF_MAX_ITEMS)
460482
return -1;
461483

462-
elem->id = nelem;
463-
m_elements.push_back(elem);
484+
obj->index = nobjects;
485+
486+
// Ensure UID is nonzero so that a valid handle == OBJDEF_INVALID_HANDLE
487+
// is not possible. The slight randomness bias isn't very significant.
488+
obj->uid = myrand() & OBJDEF_UID_MASK;
489+
if (obj->uid == 0)
490+
obj->uid = 1;
491+
492+
m_objects.push_back(obj);
464493

465-
verbosestream << "GenElementManager: added " << this->ELEMENT_TITLE
466-
<< " element '" << elem->name << "'" << std::endl;
494+
infostream << "ObjDefManager: added " << getObjectTitle()
495+
<< ": name=\"" << obj->name
496+
<< "\" index=" << obj->index
497+
<< " uid=" << obj->uid
498+
<< std::endl;
467499

468-
return nelem;
500+
return nobjects;
469501
}
470502

471503

472-
GenElement *GenElementManager::get(u32 id)
504+
ObjDef *ObjDefManager::getRaw(u32 index) const
473505
{
474-
return (id < m_elements.size()) ? m_elements[id] : NULL;
506+
return m_objects[index];
475507
}
476508

477509

478-
GenElement *GenElementManager::getByName(const std::string &name)
510+
ObjDef *ObjDefManager::setRaw(u32 index, ObjDef *obj)
479511
{
480-
for (size_t i = 0; i != m_elements.size(); i++) {
481-
GenElement *elem = m_elements[i];
482-
if (elem && name == elem->name)
483-
return elem;
512+
ObjDef *old_obj = m_objects[index];
513+
m_objects[index] = obj;
514+
return old_obj;
515+
}
516+
517+
518+
ObjDef *ObjDefManager::getByName(const std::string &name) const
519+
{
520+
for (size_t i = 0; i != m_objects.size(); i++) {
521+
ObjDef *obj = m_objects[i];
522+
if (obj && !strcasecmp(name.c_str(), obj->name.c_str()))
Has a conversation. Original line has a conversation.
523+
return obj;
484524
}
485525

486526
return NULL;
487527
}
488528

489529

490-
GenElement *GenElementManager::update(u32 id, GenElement *elem)
530+
void ObjDefManager::clear()
491531
{
492-
if (id >= m_elements.size())
493-
return NULL;
532+
for (size_t i = 0; i != m_objects.size(); i++)
533+
delete m_objects[i];
494534

495-
GenElement *old_elem = m_elements[id];
496-
m_elements[id] = elem;
497-
return old_elem;
535+
m_objects.clear();
498536
}
499537

500538

501-
GenElement *GenElementManager::remove(u32 id)
539+
u32 ObjDefManager::validateHandle(ObjDefHandle handle) const
502540
{
503-
return update(id, NULL);
541+
ObjDefType type;
542+
u32 index;
543+
u32 uid;
544+
545+
bool is_valid =
546+
(handle != OBJDEF_INVALID_HANDLE) &&
547+
decodeHandle(handle, &index, &type, &uid) &&
548+
(type == m_objtype) &&
549+
(index < m_objects.size()) &&
550+
(m_objects[index]->uid == uid);
551+
552+
return is_valid ? index : -1;
504553
}
505554

506555

507-
void GenElementManager::clear()
556+
ObjDefHandle ObjDefManager::createHandle(u32 index, ObjDefType type, u32 uid)
508557
{
509-
m_elements.clear();
558+
ObjDefHandle handle = 0;
559+
set_bits(&handle, 0, 18, index);
560+
set_bits(&handle, 18, 6, type);
561+
set_bits(&handle, 24, 7, uid);
562+
563+
u32 parity = calc_parity(handle);
564+
set_bits(&handle, 31, 1, parity);
565+
566+
return handle ^ OBJDEF_HANDLE_SALT;
510567
}
511568

512569

570+
bool ObjDefManager::decodeHandle(ObjDefHandle handle, u32 *index,
571+
ObjDefType *type, u32 *uid)
572+
{
573+
handle ^= OBJDEF_HANDLE_SALT;
574+
575+
u32 parity = get_bits(handle, 31, 1);
576+
set_bits(&handle, 31, 1, 0);
577+
if (parity != calc_parity(handle))
578+
return false;
579+
580+
*index = get_bits(handle, 0, 18);
581+
*type = (ObjDefType)get_bits(handle, 18, 6);
582+
*uid = get_bits(handle, 24, 7);
583+
return true;
584+
}
585+
586+
587+
///////////////////////////////////////////////////////////////////////////////
588+
589+
513590
void MapgenParams::load(const Settings &settings)
514591
{
515592
std::string seed_str;

Diff for: ‎src/mapgen.h

+49-17
Original file line numberDiff line numberDiff line change
@@ -179,36 +179,68 @@ struct MapgenFactory {
179179
virtual ~MapgenFactory() {}
180180
};
181181

182-
class GenElement {
182+
typedef std::map<std::string, std::string> StringMap;
183+
typedef u32 ObjDefHandle;
184+
185+
#define OBJDEF_INVALID_INDEX ((u32)(-1))
186+
#define OBJDEF_INVALID_HANDLE 0
187+
#define OBJDEF_HANDLE_SALT 0x00585e6fu
188+
#define OBJDEF_MAX_ITEMS (1 << 18)
189+
#define OBJDEF_UID_MASK ((1 << 7) - 1)
190+
191+
enum ObjDefType {
192+
OBJDEF_GENERIC,
193+
OBJDEF_BIOME,
194+
OBJDEF_ORE,
195+
OBJDEF_DECORATION,
196+
OBJDEF_SCHEMATIC,
197+
};
198+
199+
class ObjDef {
183200
public:
184-
virtual ~GenElement() {}
185-
u32 id;
201+
virtual ~ObjDef() {}
202+
203+
u32 index;
204+
u32 uid;
205+
ObjDefHandle handle;
186206
std::string name;
187207
};
188208

189-
class GenElementManager {
209+
class ObjDefManager {
190210
public:
191-
static const char *ELEMENT_TITLE;
192-
static const size_t ELEMENT_LIMIT = -1;
211+
ObjDefManager(IGameDef *gamedef, ObjDefType type);
212+
virtual ~ObjDefManager();
193213

194-
GenElementManager(IGameDef *gamedef);
195-
virtual ~GenElementManager();
214+
virtual const char *getObjectTitle() const = 0;
196215

197-
virtual GenElement *create(int type) = 0;
198-
199-
virtual u32 add(GenElement *elem);
200-
virtual GenElement *get(u32 id);
201-
virtual GenElement *update(u32 id, GenElement *elem);
202-
virtual GenElement *remove(u32 id);
216+
virtual ObjDef *create(int type) = 0;
203217
virtual void clear();
218+
virtual ObjDef *getByName(const std::string &name) const;
219+
220+
//// Add new/get/set object definitions by handle
221+
virtual ObjDefHandle add(ObjDef *obj);
222+
virtual ObjDef *get(ObjDefHandle handle) const;
223+
virtual ObjDef *set(ObjDefHandle handle, ObjDef *obj);
224+
225+
//// Raw variants that work on indexes
226+
virtual u32 addRaw(ObjDef *obj);
227+
228+
// It is generally assumed that getRaw() will always return a valid object
229+
// This won't be true if people do odd things such as call setRaw() with NULL
230+
virtual ObjDef *getRaw(u32 index) const;
231+
virtual ObjDef *setRaw(u32 index, ObjDef *obj);
204232

205-
virtual GenElement *getByName(const std::string &name);
233+
INodeDefManager *getNodeDef() const { return m_ndef; }
206234

207-
INodeDefManager *getNodeDef() { return m_ndef; }
235+
u32 validateHandle(ObjDefHandle handle) const;
236+
static ObjDefHandle createHandle(u32 index, ObjDefType type, u32 uid);
237+
static bool decodeHandle(ObjDefHandle handle, u32 *index,
238+
ObjDefType *type, u32 *uid);
208239

209240
protected:
210241
INodeDefManager *m_ndef;
211-
std::vector<GenElement *> m_elements;
242+
std::vector<ObjDef *> m_objects;
243+
ObjDefType m_objtype;
212244
};
213245

214246
#endif

Diff for: ‎src/mapgen_v5.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ void MapgenV5::generateCaves(int max_stone_y)
479479
for (s16 y=node_min.Y - 1; y<=node_max.Y + 1; y++) {
480480
u32 i = vm->m_area.index(node_min.X, y, z);
481481
for (s16 x=node_min.X; x<=node_max.X; x++, i++, index++, index2d++) {
482-
Biome *biome = (Biome *)bmgr->get(biomemap[index2d]);
482+
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
483483
content_t c = vm->m_data[i].getContent();
484484
if (c == CONTENT_AIR
485485
|| (y <= water_level
@@ -519,7 +519,7 @@ void MapgenV5::dustTopNodes()
519519

520520
for (s16 z = node_min.Z; z <= node_max.Z; z++)
521521
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
522-
Biome *biome = (Biome *)bmgr->get(biomemap[index]);
522+
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index]);
523523

524524
if (biome->c_dust == CONTENT_IGNORE)
525525
continue;

Diff for: ‎src/mapgen_v7.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,7 @@ void MapgenV7::dustTopNodes()
674674

675675
for (s16 z = node_min.Z; z <= node_max.Z; z++)
676676
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
677-
Biome *biome = (Biome *)bmgr->get(biomemap[index]);
677+
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index]);
678678

679679
if (biome->c_dust == CONTENT_IGNORE)
680680
continue;
@@ -821,7 +821,7 @@ void MapgenV7::generateCaves(int max_stone_y)
821821
u32 i = vm->m_area.index(node_min.X, y, z);
822822
for (s16 x = node_min.X; x <= node_max.X;
823823
x++, i++, index++, index2d++) {
824-
Biome *biome = (Biome *)bmgr->get(biomemap[index2d]);
824+
Biome *biome = (Biome *)bmgr->getRaw(biomemap[index2d]);
825825
content_t c = vm->m_data[i].getContent();
826826
if (c == CONTENT_AIR || (y <= water_level &&
827827
c != biome->c_stone && c != c_stone))

Diff for: ‎src/mg_biome.cpp

+12-12
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2727
#include "util/mathconstants.h"
2828
#include "porting.h"
2929

30-
const char *BiomeManager::ELEMENT_TITLE = "biome";
31-
3230

3331
///////////////////////////////////////////////////////////////////////////////
3432

33+
3534
BiomeManager::BiomeManager(IGameDef *gamedef) :
36-
GenElementManager(gamedef)
35+
ObjDefManager(gamedef, OBJDEF_BIOME)
3736
{
3837
// Create default biome to be used in case none exist
3938
Biome *b = new Biome;
4039

41-
b->id = 0;
4240
b->name = "Default";
4341
b->flags = 0;
4442
b->depth_top = 0;
@@ -75,8 +73,10 @@ BiomeManager::~BiomeManager()
7573
void BiomeManager::calcBiomes(s16 sx, s16 sy, float *heat_map,
7674
float *humidity_map, s16 *height_map, u8 *biomeid_map)
7775
{
78-
for (s32 i = 0; i != sx * sy; i++)
79-
biomeid_map[i] = getBiome(heat_map[i], humidity_map[i], height_map[i])->id;
76+
for (s32 i = 0; i != sx * sy; i++) {
77+
Biome *biome = getBiome(heat_map[i], humidity_map[i], height_map[i]);
78+
biomeid_map[i] = biome->index;
79+
}
8080
}
8181

8282

@@ -85,8 +85,8 @@ Biome *BiomeManager::getBiome(float heat, float humidity, s16 y)
8585
Biome *b, *biome_closest = NULL;
8686
float dist_min = FLT_MAX;
8787

88-
for (size_t i = 1; i < m_elements.size(); i++) {
89-
b = (Biome *)m_elements[i];
88+
for (size_t i = 1; i < m_objects.size(); i++) {
89+
b = (Biome *)m_objects[i];
9090
if (!b || y > b->y_max || y < b->y_min)
9191
continue;
9292

@@ -100,18 +100,18 @@ Biome *BiomeManager::getBiome(float heat, float humidity, s16 y)
100100
}
101101
}
102102

103-
return biome_closest ? biome_closest : (Biome *)m_elements[0];
103+
return biome_closest ? biome_closest : (Biome *)m_objects[0];
104104
}
105105

106106
void BiomeManager::clear()
107107
{
108108

109-
for (size_t i = 1; i < m_elements.size(); i++) {
110-
Biome *b = (Biome *)m_elements[i];
109+
for (size_t i = 1; i < m_objects.size(); i++) {
110+
Biome *b = (Biome *)m_objects[i];
111111
delete b;
112112
}
113113

114-
m_elements.resize(1);
114+
m_objects.resize(1);
115115
}
116116

117117

Diff for: ‎src/mg_biome.h

+8-4
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ enum BiomeType
3333
BIOME_TYPE_FLAT
3434
};
3535

36-
class Biome : public GenElement, public NodeResolver {
36+
class Biome : public ObjDef, public NodeResolver {
3737
public:
3838
u32 flags;
3939

@@ -56,14 +56,18 @@ class Biome : public GenElement, public NodeResolver {
5656
virtual void resolveNodeNames(NodeResolveInfo *nri);
5757
};
5858

59-
class BiomeManager : public GenElementManager {
59+
class BiomeManager : public ObjDefManager {
6060
public:
61-
static const char *ELEMENT_TITLE;
62-
static const size_t ELEMENT_LIMIT = 0x100;
61+
static const char *OBJECT_TITLE;
6362

6463
BiomeManager(IGameDef *gamedef);
6564
~BiomeManager();
6665

66+
const char *getObjectTitle() const
67+
{
68+
return "biome";
69+
}
70+
6771
Biome *create(int btt)
6872
{
6973
return new Biome;

Diff for: ‎src/mg_decoration.cpp

+7-9
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2525
#include "log.h"
2626
#include "util/numeric.h"
2727

28-
const char *DecorationManager::ELEMENT_TITLE = "decoration";
29-
3028
FlagDesc flagdesc_deco[] = {
3129
{"place_center_x", DECO_PLACE_CENTER_X},
3230
{"place_center_y", DECO_PLACE_CENTER_Y},
@@ -40,7 +38,7 @@ FlagDesc flagdesc_deco[] = {
4038

4139

4240
DecorationManager::DecorationManager(IGameDef *gamedef) :
43-
GenElementManager(gamedef)
41+
ObjDefManager(gamedef, OBJDEF_DECORATION)
4442
{
4543
}
4644

@@ -50,8 +48,8 @@ size_t DecorationManager::placeAllDecos(Mapgen *mg, u32 blockseed,
5048
{
5149
size_t nplaced = 0;
5250

53-
for (size_t i = 0; i != m_elements.size(); i++) {
54-
Decoration *deco = (Decoration *)m_elements[i];
51+
for (size_t i = 0; i != m_objects.size(); i++) {
52+
Decoration *deco = (Decoration *)m_objects[i];
5553
if (!deco)
5654
continue;
5755

@@ -65,11 +63,11 @@ size_t DecorationManager::placeAllDecos(Mapgen *mg, u32 blockseed,
6563

6664
void DecorationManager::clear()
6765
{
68-
for (size_t i = 0; i < m_elements.size(); i++) {
69-
Decoration *deco = (Decoration *)m_elements[i];
66+
for (size_t i = 0; i < m_objects.size(); i++) {
67+
Decoration *deco = (Decoration *)m_objects[i];
7068
delete deco;
7169
}
72-
m_elements.clear();
70+
m_objects.clear();
7371
}
7472

7573

@@ -169,7 +167,7 @@ size_t Decoration::placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
169167

170168
v3s16 pos(x, y, z);
171169
if (generate(mg->vm, &ps, pos))
172-
mg->gennotify.addEvent(GENNOTIFY_DECORATION, pos, id);
170+
mg->gennotify.addEvent(GENNOTIFY_DECORATION, pos, index);
173171
}
174172
}
175173

Diff for: ‎src/mg_decoration.h

+7-5
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ struct CutoffData {
5959
};
6060
#endif
6161

62-
class Decoration : public GenElement, public NodeResolver {
62+
class Decoration : public ObjDef, public NodeResolver {
6363
public:
6464
INodeDefManager *ndef;
6565

@@ -121,14 +121,16 @@ class DecoLSystem : public Decoration {
121121
};
122122
*/
123123

124-
class DecorationManager : public GenElementManager {
124+
class DecorationManager : public ObjDefManager {
125125
public:
126-
static const char *ELEMENT_TITLE;
127-
static const size_t ELEMENT_LIMIT = 0x10000;
128-
129126
DecorationManager(IGameDef *gamedef);
130127
~DecorationManager() {}
131128

129+
const char *getObjectTitle() const
130+
{
131+
return "decoration";
132+
}
133+
132134
Decoration *create(int type)
133135
{
134136
switch (type) {

Diff for: ‎src/mg_ore.cpp

+6-8
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2424
#include "map.h"
2525
#include "log.h"
2626

27-
const char *OreManager::ELEMENT_TITLE = "ore";
28-
2927
FlagDesc flagdesc_ore[] = {
3028
{"absheight", OREFLAG_ABSHEIGHT},
3129
{NULL, 0}
@@ -36,7 +34,7 @@ FlagDesc flagdesc_ore[] = {
3634

3735

3836
OreManager::OreManager(IGameDef *gamedef) :
39-
GenElementManager(gamedef)
37+
ObjDefManager(gamedef, OBJDEF_ORE)
4038
{
4139
}
4240

@@ -45,8 +43,8 @@ size_t OreManager::placeAllOres(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nma
4543
{
4644
size_t nplaced = 0;
4745

48-
for (size_t i = 0; i != m_elements.size(); i++) {
49-
Ore *ore = (Ore *)m_elements[i];
46+
for (size_t i = 0; i != m_objects.size(); i++) {
47+
Ore *ore = (Ore *)m_objects[i];
5048
if (!ore)
5149
continue;
5250

@@ -60,11 +58,11 @@ size_t OreManager::placeAllOres(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nma
6058

6159
void OreManager::clear()
6260
{
63-
for (size_t i = 0; i < m_elements.size(); i++) {
64-
Ore *ore = (Ore *)m_elements[i];
61+
for (size_t i = 0; i < m_objects.size(); i++) {
62+
Ore *ore = (Ore *)m_objects[i];
6563
delete ore;
6664
}
67-
m_elements.clear();
65+
m_objects.clear();
6866
}
6967

7068

Diff for: ‎src/mg_ore.h

+7-5
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ enum OreType {
4747

4848
extern FlagDesc flagdesc_ore[];
4949

50-
class Ore : public GenElement, public NodeResolver {
50+
class Ore : public ObjDef, public NodeResolver {
5151
public:
5252
static const bool NEEDS_NOISE = false;
5353

@@ -112,14 +112,16 @@ class OreVein : public Ore {
112112
v3s16 nmin, v3s16 nmax);
113113
};
114114

115-
class OreManager : public GenElementManager {
115+
class OreManager : public ObjDefManager {
116116
public:
117-
static const char *ELEMENT_TITLE;
118-
static const size_t ELEMENT_LIMIT = 0x10000;
119-
120117
OreManager(IGameDef *gamedef);
121118
~OreManager() {}
122119

120+
const char *getObjectTitle() const
121+
{
122+
return "ore";
123+
}
124+
123125
Ore *create(int type)
124126
{
125127
switch (type) {

Diff for: ‎src/mg_schematic.cpp

+4-6
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2828
#include "serialization.h"
2929
#include "filesys.h"
3030

31-
const char *SchematicManager::ELEMENT_TITLE = "schematic";
32-
3331
///////////////////////////////////////////////////////////////////////////////
3432

3533

3634
SchematicManager::SchematicManager(IGameDef *gamedef) :
37-
GenElementManager(gamedef)
35+
ObjDefManager(gamedef, OBJDEF_SCHEMATIC)
3836
{
3937
}
4038

@@ -201,7 +199,7 @@ void Schematic::placeStructure(Map *map, v3s16 p, u32 flags, Rotation rot,
201199

202200

203201
bool Schematic::loadSchematicFromFile(const char *filename, INodeDefManager *ndef,
204-
std::map<std::string, std::string> &replace_names)
202+
StringMap *replace_names)
205203
{
206204
content_t cignore = CONTENT_IGNORE;
207205
bool have_cignore = false;
@@ -246,8 +244,8 @@ bool Schematic::loadSchematicFromFile(const char *filename, INodeDefManager *nde
246244
}
247245

248246
std::map<std::string, std::string>::iterator it;
249-
it = replace_names.find(name);
250-
if (it != replace_names.end())
247+
it = replace_names->find(name);
248+
if (it != replace_names->end())
251249
name = it->second;
252250

253251
nri->nodenames.push_back(name);

Diff for: ‎src/mg_schematic.h

+8-6
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class NodeResolver;
4242
#define MTSCHEM_PROB_ALWAYS 0xFF
4343

4444

45-
class Schematic : public GenElement, public NodeResolver {
45+
class Schematic : public ObjDef, public NodeResolver {
4646
public:
4747
std::vector<content_t> c_nodes;
4848

@@ -62,7 +62,7 @@ class Schematic : public GenElement, public NodeResolver {
6262
Rotation rot, bool force_placement, INodeDefManager *ndef);
6363

6464
bool loadSchematicFromFile(const char *filename, INodeDefManager *ndef,
65-
std::map<std::string, std::string> &replace_names);
65+
StringMap *replace_names);
6666
void saveSchematicToFile(const char *filename, INodeDefManager *ndef);
6767
bool getSchematicFromMap(Map *map, v3s16 p1, v3s16 p2);
6868

@@ -73,14 +73,16 @@ class Schematic : public GenElement, public NodeResolver {
7373
std::vector<std::pair<s16, u8> > *splist);
7474
};
7575

76-
class SchematicManager : public GenElementManager {
76+
class SchematicManager : public ObjDefManager {
7777
public:
78-
static const char *ELEMENT_TITLE;
79-
static const size_t ELEMENT_LIMIT = 0x10000;
80-
8178
SchematicManager(IGameDef *gamedef);
8279
~SchematicManager() {}
8380

81+
const char *getObjectTitle() const
82+
{
83+
return "schematic";
84+
}
85+
8486
Schematic *create(int type)
8587
{
8688
return new Schematic;

Diff for: ‎src/script/lua_api/l_mapgen.cpp

+95-86
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,56 @@ struct EnumString ModApiMapgen::es_Rotation[] =
8686
};
8787

8888

89+
bool read_schematic_def(lua_State *L, int index, Schematic *schem,
90+
INodeDefManager *ndef, StringMap *replace_names);
91+
8992
///////////////////////////////////////////////////////////////////////////////
9093

9194

95+
Schematic *get_schematic(lua_State *L, int index,
96+
SchematicManager *schemmgr, StringMap *replace_names)
97+
{
98+
if (index < 0)
99+
index = lua_gettop(L) + 1 + index;
100+
101+
Schematic *schem;
102+
103+
if (lua_isnumber(L, index)) {
104+
return (Schematic *)schemmgr->get(lua_tointeger(L, index));
105+
} else if (lua_istable(L, index)) {
106+
schem = new Schematic;
107+
if (!read_schematic_def(L, index, schem,
108+
schemmgr->getNodeDef(), replace_names)) {
109+
delete schem;
110+
return NULL;
111+
}
112+
} else if (lua_isstring(L, index)) {
113+
const char *filename = lua_tostring(L, index);
114+
schem = (Schematic *)schemmgr->getByName(filename);
115+
if (schem)
116+
return schem;
117+
118+
schem = new Schematic;
119+
if (!schem->loadSchematicFromFile(filename,
120+
schemmgr->getNodeDef(), replace_names)) {
121+
delete schem;
122+
return NULL;
123+
}
124+
} else {
125+
return NULL;
126+
}
127+
128+
if (schemmgr->add(schem) == OBJDEF_INVALID_HANDLE) {
129+
delete schem;
130+
return NULL;
131+
}
132+
133+
return schem;
134+
}
135+
136+
92137
bool read_schematic_def(lua_State *L, int index, Schematic *schem,
93-
INodeDefManager *ndef, std::map<std::string, std::string> &replace_names)
138+
INodeDefManager *ndef, StringMap *replace_names)
94139
{
95140
//// Get schematic size
96141
lua_getfield(L, index, "size");
@@ -128,9 +173,8 @@ bool read_schematic_def(lua_State *L, int index, Schematic *schem,
128173
param2 = !lua_isnil(L, -1) ? lua_tonumber(L, -1) : 0;
129174
lua_pop(L, 1);
130175

131-
std::map<std::string, std::string>::iterator it;
132-
it = replace_names.find(name);
133-
if (it != replace_names.end())
176+
StringMap::iterator it = replace_names->find(name);
177+
if (it != replace_names->end())
134178
name = it->second;
135179

136180
schemdata[i] = MapNode(ndef, name, param1, param2);
@@ -175,51 +219,12 @@ bool read_schematic_def(lua_State *L, int index, Schematic *schem,
175219
}
176220

177221

178-
Schematic *get_schematic(lua_State *L, int index, SchematicManager *schemmgr,
179-
std::map<std::string, std::string> &replace_names)
222+
223+
void read_schematic_replacements(lua_State *L, int index, StringMap *replace_names)
180224
{
181225
if (index < 0)
182226
index = lua_gettop(L) + 1 + index;
183227

184-
Schematic *schem;
185-
186-
if (lua_isnumber(L, index)) {
187-
return (Schematic *)schemmgr->get(lua_tointeger(L, index));
188-
} else if (lua_istable(L, index)) {
189-
schem = new Schematic;
190-
if (!read_schematic_def(L, index, schem,
191-
schemmgr->getNodeDef(), replace_names)) {
192-
delete schem;
193-
return NULL;
194-
}
195-
} else if (lua_isstring(L, index)) {
196-
const char *filename = lua_tostring(L, index);
197-
schem = (Schematic *)schemmgr->getByName(filename);
198-
if (schem)
199-
return schem;
200-
201-
schem = new Schematic;
202-
if (!schem->loadSchematicFromFile(filename,
203-
schemmgr->getNodeDef(), replace_names)) {
204-
delete schem;
205-
return NULL;
206-
}
207-
} else {
208-
return NULL;
209-
}
210-
211-
if (schemmgr->add(schem) == (u32)-1) {
212-
delete schem;
213-
return 0;
214-
}
215-
216-
return schem;
217-
}
218-
219-
220-
void read_schematic_replacements(lua_State *L,
221-
std::map<std::string, std::string> &replace_names, int index)
222-
{
223228
lua_pushnil(L);
224229
while (lua_next(L, index)) {
225230
std::string replace_from;
@@ -238,7 +243,7 @@ void read_schematic_replacements(lua_State *L,
238243
replace_to = lua_tostring(L, -1);
239244
}
240245

241-
replace_names[replace_from] = replace_to;
246+
replace_names->insert(std::make_pair(replace_from, replace_to));
242247
lua_pop(L, 1);
243248
}
244249
}
@@ -477,24 +482,23 @@ int ModApiMapgen::l_register_biome(lua_State *L)
477482
b->humidity_point = getfloatfield_default(L, index, "humidity_point", 0.f);
478483
b->flags = 0; //reserved
479484

480-
u32 id = bmgr->add(b);
481-
if (id == (u32)-1) {
485+
ObjDefHandle handle = bmgr->add(b);
486+
if (handle == OBJDEF_INVALID_HANDLE) {
482487
delete b;
483488
return 0;
484489
}
485490

486491
NodeResolveInfo *nri = new NodeResolveInfo(b);
487492
std::list<std::string> &nnames = nri->nodenames;
488-
nnames.push_back(getstringfield_default(L, index, "node_top", ""));
489-
nnames.push_back(getstringfield_default(L, index, "node_filler", ""));
490-
nnames.push_back(getstringfield_default(L, index, "node_stone", ""));
491-
nnames.push_back(getstringfield_default(L, index, "node_water_top", ""));
492-
nnames.push_back(getstringfield_default(L, index, "node_water", ""));
493-
nnames.push_back(getstringfield_default(L, index, "node_dust", ""));
493+
nnames.push_back(getstringfield_default(L, index, "node_top", ""));
494+
nnames.push_back(getstringfield_default(L, index, "node_filler", ""));
495+
nnames.push_back(getstringfield_default(L, index, "node_stone", ""));
496+
nnames.push_back(getstringfield_default(L, index, "node_water_top", ""));
497+
nnames.push_back(getstringfield_default(L, index, "node_water", ""));
498+
nnames.push_back(getstringfield_default(L, index, "node_dust", ""));
494499
ndef->pendNodeResolve(nri);
495500

496-
verbosestream << "register_biome: " << b->name << std::endl;
497-
lua_pushinteger(L, id);
501+
lua_pushinteger(L, handle);
498502
return 1;
499503
}
500504

@@ -556,20 +560,20 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
556560
if (!b)
557561
continue;
558562

559-
deco->biomes.insert(b->id);
563+
deco->biomes.insert(b->index);
560564
}
561565

562566
//// Handle decoration type-specific parameters
563567
bool success = false;
564568
switch (decotype) {
565-
case DECO_SIMPLE:
566-
success = regDecoSimple(L, nri, (DecoSimple *)deco);
567-
break;
568-
case DECO_SCHEMATIC:
569-
success = regDecoSchematic(L, schemmgr, (DecoSchematic *)deco);
570-
break;
571-
case DECO_LSYSTEM:
572-
break;
569+
case DECO_SIMPLE:
570+
success = regDecoSimple(L, nri, (DecoSimple *)deco);
571+
break;
572+
case DECO_SCHEMATIC:
573+
success = regDecoSchematic(L, schemmgr, (DecoSchematic *)deco);
574+
break;
575+
case DECO_LSYSTEM:
576+
break;
573577
}
574578

575579
ndef->pendNodeResolve(nri);
@@ -579,14 +583,13 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
579583
return 0;
580584
}
581585

582-
u32 id = decomgr->add(deco);
583-
if (id == (u32)-1) {
586+
ObjDefHandle handle = decomgr->add(deco);
587+
if (handle == OBJDEF_INVALID_HANDLE) {
584588
delete deco;
585589
return 0;
586590
}
587591

588-
verbosestream << "register_decoration: " << deco->name << std::endl;
589-
lua_pushinteger(L, id);
592+
lua_pushinteger(L, handle);
590593
return 1;
591594
}
592595

@@ -638,14 +641,14 @@ bool ModApiMapgen::regDecoSchematic(lua_State *L,
638641
deco->rotation = (Rotation)getenumfield(L, index, "rotation",
639642
es_Rotation, ROTATE_0);
640643

641-
std::map<std::string, std::string> replace_names;
644+
StringMap replace_names;
642645
lua_getfield(L, index, "replacements");
643646
if (lua_istable(L, -1))
644-
read_schematic_replacements(L, replace_names, lua_gettop(L));
647+
read_schematic_replacements(L, -1, &replace_names);
645648
lua_pop(L, 1);
646649

647650
lua_getfield(L, index, "schematic");
648-
Schematic *schem = get_schematic(L, -1, schemmgr, replace_names);
651+
Schematic *schem = get_schematic(L, -1, schemmgr, &replace_names);
649652
lua_pop(L, 1);
650653

651654
deco->schematic = schem;
@@ -719,8 +722,8 @@ int ModApiMapgen::l_register_ore(lua_State *L)
719722
"random_factor", 1.f);
720723
}
721724

722-
u32 id = oremgr->add(ore);
723-
if (id == (u32)-1) {
725+
ObjDefHandle handle = oremgr->add(ore);
726+
if (handle == OBJDEF_INVALID_HANDLE) {
724727
delete ore;
725728
return 0;
726729
}
@@ -736,8 +739,7 @@ int ModApiMapgen::l_register_ore(lua_State *L)
736739

737740
ndef->pendNodeResolve(nri);
738741

739-
verbosestream << "register_ore: " << ore->name << std::endl;
740-
lua_pushinteger(L, id);
742+
lua_pushinteger(L, handle);
741743
return 1;
742744
}
743745

@@ -746,16 +748,21 @@ int ModApiMapgen::l_register_schematic(lua_State *L)
746748
{
747749
SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr;
748750

749-
std::map<std::string, std::string> replace_names;
751+
StringMap replace_names;
750752
if (lua_istable(L, 2))
751-
read_schematic_replacements(L, replace_names, 2);
753+
read_schematic_replacements(L, 2, &replace_names);
752754

753-
Schematic *schem = get_schematic(L, 1, schemmgr, replace_names);
755+
Schematic *schem = get_schematic(L, 1, schemmgr, &replace_names);
754756
if (!schem)
755757
return 0;
756-
printf("register_schematic!\n");
757-
verbosestream << "register_schematic: " << schem->name << std::endl;
758-
lua_pushinteger(L, schem->id);
758+
759+
ObjDefHandle handle = schemmgr->add(schem);
760+
if (handle == OBJDEF_INVALID_HANDLE) {
761+
delete schem;
762+
return 0;
763+
}
764+
765+
lua_pushinteger(L, handle);
759766
return 1;
760767
}
761768

@@ -837,7 +844,7 @@ int ModApiMapgen::l_generate_decorations(lua_State *L)
837844
return 0;
838845
}
839846

840-
// create_schematic(p1, p2, probability_list, filename)
847+
// create_schematic(p1, p2, probability_list, filename, y_slice_prob_list)
841848
int ModApiMapgen::l_create_schematic(lua_State *L)
842849
{
843850
Schematic schem;
@@ -894,6 +901,7 @@ int ModApiMapgen::l_create_schematic(lua_State *L)
894901
actionstream << "create_schematic: saved schematic file '"
895902
<< filename << "'." << std::endl;
896903

904+
lua_pushboolean(L, true);
897905
return 1;
898906
}
899907

@@ -917,12 +925,12 @@ int ModApiMapgen::l_place_schematic(lua_State *L)
917925
force_placement = lua_toboolean(L, 5);
918926

919927
//// Read node replacements
920-
std::map<std::string, std::string> replace_names;
928+
StringMap replace_names;
921929
if (lua_istable(L, 4))
922-
read_schematic_replacements(L, replace_names, 4);
930+
read_schematic_replacements(L, 4, &replace_names);
923931

924932
//// Read schematic
925-
Schematic *schem = get_schematic(L, 2, schemmgr, replace_names);
933+
Schematic *schem = get_schematic(L, 2, schemmgr, &replace_names);
926934
if (!schem) {
927935
errorstream << "place_schematic: failed to get schematic" << std::endl;
928936
return 0;
@@ -931,6 +939,7 @@ int ModApiMapgen::l_place_schematic(lua_State *L)
931939
schem->placeStructure(map, p, 0, (Rotation)rot, force_placement,
932940
schemmgr->getNodeDef());
933941

942+
lua_pushboolean(L, true);
934943
return 1;
935944
}
936945

Diff for: ‎src/util/numeric.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,6 @@ u64 murmur_hash_64_ua(const void *key, int len, unsigned int seed)
183183
return h;
184184
}
185185

186-
187186
/*
188187
blockpos: position of block in block coordinates
189188
camera_pos: position of camera in nodes

Diff for: ‎src/util/numeric.h

+22
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,28 @@ int myrand_range(int min, int max);
249249
Miscellaneous functions
250250
*/
251251

252+
inline u32 get_bits(u32 x, u32 pos, u32 len)
253+
{
254+
u32 mask = (1 << len) - 1;
255+
return (x >> pos) & mask;
256+
}
257+
258+
inline void set_bits(u32 *x, u32 pos, u32 len, u32 val)
259+
{
260+
u32 mask = (1 << len) - 1;
261+
*x &= ~(mask << len);
262+
*x |= (val & mask) << pos;
263+
}
264+
265+
inline u32 calc_parity(u32 v)
266+
{
267+
v ^= v >> 16;
268+
v ^= v >> 8;
269+
v ^= v >> 4;
270+
v &= 0xf;
271+
return (0x6996 >> v) & 1;
272+
}
273+
252274
u64 murmur_hash_64_ua(const void *key, int len, unsigned int seed);
253275

254276
bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,

0 commit comments

Comments
 (0)
Please sign in to comment.