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

View File

@ -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
--------------------

View File

@ -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);
}

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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() {
seed = 0;
water_level = 0;
Mapgen::Mapgen()
{
generating = false;
id = -1;
seed = 0;
water_level = 0;
flags = 0;
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();
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -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);

View File

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

View File

@ -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,7 +62,6 @@ 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;
// Terrain noise

View File

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

View File

@ -49,21 +49,13 @@ FlagDesc flagdesc_mapgen_v6[] = {
///////////////////////////////////////////////////////////////////////////////
MapgenV6::MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge) {
this->generating = false;
this->id = mapgenid;
MapgenV6::MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge)
: Mapgen(mapgenid, params, emerge)
{
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;
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;

View File

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

View File

@ -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;

View File

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

View File

@ -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;
}

View File

@ -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();
};

View File

@ -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;
}

View File

@ -194,23 +194,21 @@ int ModApiMapgen::l_get_mapgen_object(lua_State *L)
return 1;
}
case MGOBJ_GENNOTIFY: {
lua_newtable(L);
for (int i = 0; flagdesc_gennotify[i].name; i++) {
if (!(emerge->gennotify & flagdesc_gennotify[i].flag))
continue;
std::map<std::string, std::vector<v3s16> >event_map;
std::map<std::string, std::vector<v3s16> >::iterator it;
std::vector<v3s16> *posvec = mg->gen_notifications[i];
if (!posvec)
return 0;
mg->gennotify.getEvents(event_map);
lua_newtable(L);
for (unsigned int j = 0; j != posvec->size(); j++) {
push_v3s16(L, (*posvec)[j]);
for (it = event_map.begin(); it != event_map.end(); ++it) {
lua_newtable(L);
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;