Rewrite generate notification mechanism

Add support for notify-on-decoration
Clean up mapgen constructors
Clean up mapgen.cpp code style somewhat
Remove trailing whitespace from some files
This commit is contained in:
kwolekr 2014-12-06 04:18:04 -05:00
parent 2b119e1e19
commit 5062b99cb0
19 changed files with 436 additions and 329 deletions

@ -1533,10 +1533,11 @@ minetest.get_perlin(seeddiff, octaves, persistence, scale)
^ Return world-specific perlin noise (int(worldseed)+seeddiff)
minetest.get_voxel_manip()
^ Return voxel manipulator object
minetest.set_gen_notify(flags)
minetest.set_gen_notify(flags, {deco_ids})
^ Set the types of on-generate notifications that should be collected
^ flags is a comma-delimited combination of:
^ dungeon, temple, cave_begin, cave_end, large_cave_begin, large_cave_end
^ flags is a flag field with the available flags:
^ dungeon, temple, cave_begin, cave_end, large_cave_begin, large_cave_end, decoration
^ The second parameter is a list of IDS of decorations which notification is requested for
minetest.get_mapgen_object(objectname)
^ Return requested mapgen object if available (see Mapgen objects)
minetest.set_mapgen_params(MapgenParams)
@ -2220,7 +2221,9 @@ current mapgen.
Returns a table mapping requested generation notification types to arrays of positions at which the
corresponding generated structures are located at within the current chunk. To set the capture of positions
of interest to be recorded on generate, use minetest.set_gen_notify().
Possible fields of the table returned are: dungeon, temple, cave_begin, cave_end, large_cave_begin, large_cave_end
Possible fields of the table returned are:
dungeon, temple, cave_begin, cave_end, large_cave_begin, large_cave_end, decoration
Decorations have a key in the format of "decoration#id", where id is the numeric unique decoration ID.
Registered entities
--------------------

@ -109,21 +109,21 @@ void CaveV6::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) {
(float)(ps->next() % ar.Z) + 0.5
);
int notifytype = large_cave ? GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN;
if (mg->gennotify & (1 << notifytype)) {
std::vector <v3s16> *nvec = mg->gen_notifications[notifytype];
nvec->push_back(v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z));
}
// Add generation notify begin event
v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
GenNotifyType notifytype = large_cave ?
GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN;
mg->gennotify.addEvent(notifytype, abs_pos);
// Generate some tunnel starting from orp
for (u16 j = 0; j < tunnel_routepoints; j++)
makeTunnel(j % dswitchint == 0);
notifytype = large_cave ? GENNOTIFY_LARGECAVE_END : GENNOTIFY_CAVE_END;
if (mg->gennotify & (1 << notifytype)) {
std::vector <v3s16> *nvec = mg->gen_notifications[notifytype];
nvec->push_back(v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z));
}
// Add generation notify end event
abs_pos = v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
notifytype = large_cave ?
GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN;
mg->gennotify.addEvent(notifytype, abs_pos);
}
@ -358,21 +358,21 @@ void CaveV7::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) {
(float)(ps->next() % ar.Z) + 0.5
);
int notifytype = large_cave ? GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN;
if (mg->gennotify & (1 << notifytype)) {
std::vector <v3s16> *nvec = mg->gen_notifications[notifytype];
nvec->push_back(v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z));
}
// Add generation notify begin event
v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
GenNotifyType notifytype = large_cave ?
GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN;
mg->gennotify.addEvent(notifytype, abs_pos);
// Generate some tunnel starting from orp
for (u16 j = 0; j < tunnel_routepoints; j++)
makeTunnel(j % dswitchint == 0);
notifytype = large_cave ? GENNOTIFY_LARGECAVE_END : GENNOTIFY_CAVE_END;
if (mg->gennotify & (1 << notifytype)) {
std::vector <v3s16> *nvec = mg->gen_notifications[notifytype];
nvec->push_back(v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z));
}
// Add generation notify end event
abs_pos = v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
notifytype = large_cave ?
GENNOTIFY_LARGECAVE_END : GENNOTIFY_CAVE_END;
mg->gennotify.addEvent(notifytype, abs_pos);
}

@ -181,10 +181,7 @@ void DungeonGen::makeDungeon(v3s16 start_padding)
makeRoom(roomsize, roomplace);
v3s16 room_center = roomplace + v3s16(roomsize.X / 2, 1, roomsize.Z / 2);
if (mg->gennotify & (1 << dp.notifytype)) {
std::vector <v3s16> *nvec = mg->gen_notifications[dp.notifytype];
nvec->push_back(room_center);
}
mg->gennotify.addEvent(dp.notifytype, room_center);
#ifdef DGEN_USE_TORCHES
// Place torch at room center (for testing)

@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "voxel.h"
#include "noise.h"
#include "mapgen.h"
#define VMANIP_FLAG_DUNGEON_INSIDE VOXELFLAG_CHECKED1
#define VMANIP_FLAG_DUNGEON_PRESERVE VOXELFLAG_CHECKED2
@ -30,7 +31,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class ManualMapVoxelManipulator;
class INodeDefManager;
class Mapgen;
v3s16 rand_ortho_dir(PseudoRandom &random, bool diagonal_dirs);
v3s16 turn_xz(v3s16 olddir, int t);
@ -44,7 +44,7 @@ struct DungeonParams {
content_t c_moss;
content_t c_stair;
int notifytype;
GenNotifyType notifytype;
bool diagonal_dirs;
float mossratio;
v3s16 holesize;

@ -94,7 +94,7 @@ EmergeManager::EmergeManager(IGameDef *gamedef) {
this->oremgr = new OreManager(gamedef);
this->decomgr = new DecorationManager(gamedef);
this->schemmgr = new SchematicManager(gamedef);
this->gennotify = 0;
this->gen_notify_on = 0;
// Note that accesses to this variable are not synchronized.
// This is because the *only* thread ever starting or stopping

@ -89,7 +89,8 @@ public:
u16 qlimit_diskonly;
u16 qlimit_generate;
u32 gennotify;
u32 gen_notify_on;
std::set<u32> gen_notify_on_deco_ids;
//// Block emerge queue data structures
JMutex queuemutex;

@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "map.h"
#include "content_sao.h"
#include "nodedef.h"
#include "emerge.h"
#include "content_mapnode.h" // For content_mapnode_get_new_name
#include "voxelalgorithms.h"
#include "profiler.h"
@ -55,36 +56,53 @@ FlagDesc flagdesc_gennotify[] = {
{"cave_end", 1 << GENNOTIFY_CAVE_END},
{"large_cave_begin", 1 << GENNOTIFY_LARGECAVE_BEGIN},
{"large_cave_end", 1 << GENNOTIFY_LARGECAVE_END},
{"decoration", 1 << GENNOTIFY_DECORATION},
{NULL, 0}
};
///////////////////////////////////////////////////////////////////////////////
Mapgen::Mapgen()
{
generating = false;
id = -1;
seed = 0;
water_level = 0;
flags = 0;
Mapgen::Mapgen() {
seed = 0;
water_level = 0;
generating = false;
id = -1;
vm = NULL;
ndef = NULL;
heightmap = NULL;
biomemap = NULL;
for (unsigned int i = 0; i != NUM_GEN_NOTIFY; i++)
gen_notifications[i] = new std::vector<v3s16>;
}
Mapgen::~Mapgen() {
for (unsigned int i = 0; i != NUM_GEN_NOTIFY; i++)
delete gen_notifications[i];
Mapgen::Mapgen(int mapgenid, MapgenParams *params, EmergeManager *emerge) :
gennotify(emerge->gen_notify_on, &emerge->gen_notify_on_deco_ids)
{
generating = false;
id = mapgenid;
seed = (int)params->seed;
water_level = params->water_level;
flags = params->flags;
csize = v3s16(1, 1, 1) * (params->chunksize * MAP_BLOCKSIZE);
vm = NULL;
ndef = NULL;
heightmap = NULL;
biomemap = NULL;
}
Mapgen::~Mapgen()
{
}
// Returns Y one under area minimum if not found
s16 Mapgen::findGroundLevelFull(v2s16 p2d) {
s16 Mapgen::findGroundLevelFull(v2s16 p2d)
{
v3s16 em = vm->m_area.getExtent();
s16 y_nodes_max = vm->m_area.MaxEdge.Y;
s16 y_nodes_min = vm->m_area.MinEdge.Y;
@ -102,7 +120,8 @@ s16 Mapgen::findGroundLevelFull(v2s16 p2d) {
}
s16 Mapgen::findGroundLevel(v2s16 p2d, s16 ymin, s16 ymax) {
s16 Mapgen::findGroundLevel(v2s16 p2d, s16 ymin, s16 ymax)
{
v3s16 em = vm->m_area.getExtent();
u32 i = vm->m_area.index(p2d.X, ymax, p2d.Y);
s16 y;
@ -118,7 +137,8 @@ s16 Mapgen::findGroundLevel(v2s16 p2d, s16 ymin, s16 ymax) {
}
void Mapgen::updateHeightmap(v3s16 nmin, v3s16 nmax) {
void Mapgen::updateHeightmap(v3s16 nmin, v3s16 nmax)
{
if (!heightmap)
return;
@ -141,7 +161,8 @@ void Mapgen::updateHeightmap(v3s16 nmin, v3s16 nmax) {
}
void Mapgen::updateLiquid(UniqueQueue<v3s16> *trans_liquid, v3s16 nmin, v3s16 nmax) {
void Mapgen::updateLiquid(UniqueQueue<v3s16> *trans_liquid, v3s16 nmin, v3s16 nmax)
{
bool isliquid, wasliquid;
v3s16 em = vm->m_area.getExtent();
@ -165,7 +186,8 @@ void Mapgen::updateLiquid(UniqueQueue<v3s16> *trans_liquid, v3s16 nmin, v3s16 nm
}
void Mapgen::setLighting(v3s16 nmin, v3s16 nmax, u8 light) {
void Mapgen::setLighting(v3s16 nmin, v3s16 nmax, u8 light)
{
ScopeProfiler sp(g_profiler, "EmergeThread: mapgen lighting update", SPT_AVG);
VoxelArea a(nmin, nmax);
@ -179,7 +201,8 @@ void Mapgen::setLighting(v3s16 nmin, v3s16 nmax, u8 light) {
}
void Mapgen::lightSpread(VoxelArea &a, v3s16 p, u8 light) {
void Mapgen::lightSpread(VoxelArea &a, v3s16 p, u8 light)
{
if (light <= 1 || !a.contains(p))
return;
@ -202,7 +225,8 @@ void Mapgen::lightSpread(VoxelArea &a, v3s16 p, u8 light) {
}
void Mapgen::calcLighting(v3s16 nmin, v3s16 nmax) {
void Mapgen::calcLighting(v3s16 nmin, v3s16 nmax)
{
VoxelArea a(nmin, nmax);
bool block_is_underground = (water_level >= nmax.Y);
@ -264,7 +288,8 @@ void Mapgen::calcLighting(v3s16 nmin, v3s16 nmax) {
}
void Mapgen::calcLightingOld(v3s16 nmin, v3s16 nmax) {
void Mapgen::calcLightingOld(v3s16 nmin, v3s16 nmax)
{
enum LightBank banks[2] = {LIGHTBANK_DAY, LIGHTBANK_NIGHT};
VoxelArea a(nmin, nmax);
bool block_is_underground = (water_level > nmax.Y);
@ -287,6 +312,72 @@ void Mapgen::calcLightingOld(v3s16 nmin, v3s16 nmax) {
}
///////////////////////////////////////////////////////////////////////////////
GenerateNotifier::GenerateNotifier()
{
}
GenerateNotifier::GenerateNotifier(u32 notify_on,
std::set<u32> *notify_on_deco_ids)
{
m_notify_on = notify_on;
m_notify_on_deco_ids = notify_on_deco_ids;
}
void GenerateNotifier::setNotifyOn(u32 notify_on)
{
m_notify_on = notify_on;
}
void GenerateNotifier::setNotifyOnDecoIds(std::set<u32> *notify_on_deco_ids)
{
m_notify_on_deco_ids = notify_on_deco_ids;
}
bool GenerateNotifier::addEvent(GenNotifyType type, v3s16 pos, u32 id)
{
if (!(m_notify_on & (1 << type)))
return false;
if (type == GENNOTIFY_DECORATION &&
m_notify_on_deco_ids->find(id) == m_notify_on_deco_ids->end())
return false;
GenNotifyEvent gne;
gne.type = type;
gne.pos = pos;
gne.id = id;
m_notify_events.push_back(gne);
return true;
}
void GenerateNotifier::getEvents(
std::map<std::string, std::vector<v3s16> > &event_map,
bool peek_events)
{
std::list<GenNotifyEvent>::iterator it;
for (it = m_notify_events.begin(); it != m_notify_events.end(); ++it) {
GenNotifyEvent &gn = *it;
std::string name = (gn.type == GENNOTIFY_DECORATION) ?
"decoration#"+ itos(gn.id) :
flagdesc_gennotify[gn.type].name;
event_map[name].push_back(gn.pos);
}
if (!peek_events)
m_notify_events.clear();
}
///////////////////////////////////////////////////////////////////////////////

@ -34,8 +34,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define MG_FLAT 0x08
#define MG_LIGHT 0x10
#define NUM_GEN_NOTIFY 6
class Settings;
class ManualMapVoxelManipulator;
class INodeDefManager;
@ -61,13 +59,39 @@ enum MapgenObject {
MGOBJ_GENNOTIFY
};
enum GenNotify {
enum GenNotifyType {
GENNOTIFY_DUNGEON,
GENNOTIFY_TEMPLE,
GENNOTIFY_CAVE_BEGIN,
GENNOTIFY_CAVE_END,
GENNOTIFY_LARGECAVE_BEGIN,
GENNOTIFY_LARGECAVE_END
GENNOTIFY_LARGECAVE_END,
GENNOTIFY_DECORATION,
NUM_GENNOTIFY_TYPES
};
struct GenNotifyEvent {
GenNotifyType type;
v3s16 pos;
u32 id;
};
class GenerateNotifier {
public:
GenerateNotifier();
GenerateNotifier(u32 notify_on, std::set<u32> *notify_on_deco_ids);
void setNotifyOn(u32 notify_on);
void setNotifyOnDecoIds(std::set<u32> *notify_on_deco_ids);
bool addEvent(GenNotifyType type, v3s16 pos, u32 id=0);
void getEvents(std::map<std::string, std::vector<v3s16> > &event_map,
bool peek_events=false);
private:
u32 m_notify_on;
std::set<u32> *m_notify_on_deco_ids;
std::list<GenNotifyEvent> m_notify_events;
};
struct MapgenSpecificParams {
@ -85,7 +109,8 @@ struct MapgenParams {
MapgenSpecificParams *sparams;
MapgenParams() {
MapgenParams()
{
mg_name = DEFAULT_MAPGEN;
seed = 0;
water_level = 1;
@ -99,6 +124,7 @@ class Mapgen {
public:
int seed;
int water_level;
u32 flags;
bool generating;
int id;
ManualMapVoxelManipulator *vm;
@ -108,10 +134,10 @@ public:
u8 *biomemap;
v3s16 csize;
u32 gennotify;
std::vector<v3s16> *gen_notifications[NUM_GEN_NOTIFY];
GenerateNotifier gennotify;
Mapgen();
Mapgen(int mapgenid, MapgenParams *params, EmergeManager *emerge);
virtual ~Mapgen();
s16 findGroundLevelFull(v2s16 p2d);

@ -39,7 +39,8 @@ void MapgenSinglenodeParams::writeParams(Settings *settings) {
///////////////////////////////////////////////////////////////////////////////
MapgenSinglenode::MapgenSinglenode(int mapgenid,
MapgenParams *params, EmergeManager *emerge)
MapgenParams *params, EmergeManager *emerge)
: Mapgen(mapgenid, params, emerge)
{
flags = params->flags;

@ -47,19 +47,12 @@ FlagDesc flagdesc_mapgen_v5[] = {
};
MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge_) {
this->generating = false;
this->id = mapgenid;
MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge_)
: Mapgen(mapgenid, params, emerge)
{
this->emerge = emerge_;
this->bmgr = emerge->biomemgr;
this->seed = (int)params->seed;
this->water_level = params->water_level;
this->flags = params->flags;
this->gennotify = emerge->gennotify;
this->csize = v3s16(1, 1, 1) * params->chunksize * MAP_BLOCKSIZE;
// amount of elements to skip for the next index
// for noise/height/biome maps (not vmanip)
this->ystride = csize.X;
@ -69,8 +62,7 @@ MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge_) {
this->heightmap = new s16[csize.X * csize.Z];
MapgenV5Params *sp = (MapgenV5Params *)params->sparams;
this->spflags = sp->spflags;
this->spflags = sp->spflags;
// Terrain noise
noise_filler_depth = new Noise(&sp->np_filler_depth, seed, csize.X, csize.Z);

@ -54,7 +54,6 @@ public:
int ystride;
int zstride;
u32 flags;
u32 spflags;
u32 blockseed;

@ -49,21 +49,13 @@ FlagDesc flagdesc_mapgen_v6[] = {
///////////////////////////////////////////////////////////////////////////////
MapgenV6::MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge) {
this->generating = false;
this->id = mapgenid;
this->emerge = emerge;
this->seed = (int)params->seed;
this->water_level = params->water_level;
this->flags = params->flags;
this->csize = v3s16(1, 1, 1) * params->chunksize * MAP_BLOCKSIZE;
this->gennotify = emerge->gennotify;
MapgenV6::MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge)
: Mapgen(mapgenid, params, emerge)
{
this->emerge = emerge;
this->ystride = csize.X; //////fix this
MapgenV6Params *sp = (MapgenV6Params *)params->sparams;
this->spflags = sp->spflags;
this->freq_desert = sp->freq_desert;
this->freq_beach = sp->freq_beach;

@ -68,7 +68,6 @@ public:
EmergeManager *emerge;
int ystride;
u32 flags;
u32 spflags;
u32 blockseed;

@ -49,19 +49,12 @@ FlagDesc flagdesc_mapgen_v7[] = {
///////////////////////////////////////////////////////////////////////////////
MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge) {
this->generating = false;
this->id = mapgenid;
MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge)
: Mapgen(mapgenid, params, emerge)
{
this->emerge = emerge;
this->bmgr = emerge->biomemgr;
this->seed = (int)params->seed;
this->water_level = params->water_level;
this->flags = params->flags;
this->gennotify = emerge->gennotify;
this->csize = v3s16(1, 1, 1) * params->chunksize * MAP_BLOCKSIZE;
//// amount of elements to skip for the next index
//// for noise/height/biome maps (not vmanip)
this->ystride = csize.X;

@ -57,7 +57,6 @@ public:
int ystride;
int zstride;
u32 flags;
u32 spflags;
u32 blockseed;

@ -144,7 +144,9 @@ size_t Decoration::placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
}
}
generate(mg, &ps, max_y, v3s16(x, y, z));
v3s16 pos(x, y, z);
if (generate(mg, &ps, max_y, pos))
mg->gennotify.addEvent(GENNOTIFY_DECORATION, pos, id);
}
}
@ -254,12 +256,12 @@ bool DecoSimple::canPlaceDecoration(ManualMapVoxelManipulator *vm, v3s16 p)
}
void DecoSimple::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p)
size_t DecoSimple::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p)
{
ManualMapVoxelManipulator *vm = mg->vm;
if (!canPlaceDecoration(vm, p))
return;
return 0;
content_t c_place = c_decos[pr->range(0, c_decos.size() - 1)];
@ -279,6 +281,8 @@ void DecoSimple::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p)
vm->m_data[vi] = MapNode(c_place);
}
return 1;
}
@ -291,7 +295,7 @@ int DecoSimple::getHeight()
///////////////////////////////////////////////////////////////////////////////
void DecoSchematic::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p)
size_t DecoSchematic::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p)
{
ManualMapVoxelManipulator *vm = mg->vm;
@ -305,12 +309,14 @@ void DecoSchematic::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p)
u32 vi = vm->m_area.index(p);
content_t c = vm->m_data[vi].getContent();
if (!CONTAINS(c_place_on, c))
return;
return 0;
Rotation rot = (rotation == ROTATE_RAND) ?
(Rotation)pr->range(ROTATE_0, ROTATE_270) : rotation;
schematic->blitToVManip(p, vm, rot, false, mg->ndef);
return 1;
}

@ -77,7 +77,7 @@ public:
size_t placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
size_t placeCutoffs(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
virtual void generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p) = 0;
virtual size_t generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p) = 0;
virtual int getHeight() = 0;
};
@ -92,7 +92,7 @@ public:
~DecoSimple() {}
bool canPlaceDecoration(ManualMapVoxelManipulator *vm, v3s16 p);
virtual void generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p);
virtual size_t generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p);
virtual int getHeight();
};
@ -105,7 +105,7 @@ public:
~DecoSchematic() {}
void generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p);
virtual size_t generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p);
virtual int getHeight();
};

@ -95,7 +95,7 @@ size_t Ore::placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
nmax.Y = ymax;
generate(mg->vm, mg->seed, blockseed, nmin, nmax);
return 0;
return 1;
}

@ -194,23 +194,21 @@ int ModApiMapgen::l_get_mapgen_object(lua_State *L)
return 1;
}
case MGOBJ_GENNOTIFY: {
std::map<std::string, std::vector<v3s16> >event_map;
std::map<std::string, std::vector<v3s16> >::iterator it;
mg->gennotify.getEvents(event_map);
lua_newtable(L);
for (int i = 0; flagdesc_gennotify[i].name; i++) {
if (!(emerge->gennotify & flagdesc_gennotify[i].flag))
continue;
std::vector<v3s16> *posvec = mg->gen_notifications[i];
if (!posvec)
return 0;
for (it = event_map.begin(); it != event_map.end(); ++it) {
lua_newtable(L);
for (unsigned int j = 0; j != posvec->size(); j++) {
push_v3s16(L, (*posvec)[j]);
for (size_t j = 0; j != it->second.size(); j++) {
push_v3s16(L, it->second[j]);
lua_rawseti(L, -2, j + 1);
}
lua_setfield(L, -2, flagdesc_gennotify[i].name);
posvec->clear();
lua_setfield(L, -2, it->first.c_str());
}
return 1;
@ -291,14 +289,24 @@ int ModApiMapgen::l_set_noiseparam_defaults(lua_State *L)
return 0;
}
// set_gen_notify(string)
// set_gen_notify(flags, {deco_id_table})
int ModApiMapgen::l_set_gen_notify(lua_State *L)
{
u32 flags = 0, flagmask = 0;
EmergeManager *emerge = getServer(L)->getEmergeManager();
if (read_flags(L, 1, flagdesc_gennotify, &flags, &flagmask)) {
EmergeManager *emerge = getServer(L)->getEmergeManager();
emerge->gennotify = flags;
emerge->gen_notify_on &= ~flagmask;
emerge->gen_notify_on |= flags;
}
if (lua_istable(L, 2)) {
lua_pushnil(L);
while (lua_next(L, 2)) {
if (lua_isnumber(L, -1))
emerge->gen_notify_on_deco_ids.insert(lua_tonumber(L, -1));
lua_pop(L, 1);
}
}
return 0;