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) ^ Return world-specific perlin noise (int(worldseed)+seeddiff)
minetest.get_voxel_manip() minetest.get_voxel_manip()
^ Return voxel manipulator object ^ 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 ^ Set the types of on-generate notifications that should be collected
^ flags is a comma-delimited combination of: ^ flags is a flag field with the available flags:
^ dungeon, temple, cave_begin, cave_end, large_cave_begin, large_cave_end ^ 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) minetest.get_mapgen_object(objectname)
^ Return requested mapgen object if available (see Mapgen objects) ^ Return requested mapgen object if available (see Mapgen objects)
minetest.set_mapgen_params(MapgenParams) 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 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 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(). 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 Registered entities
-------------------- --------------------

@ -109,21 +109,21 @@ void CaveV6::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) {
(float)(ps->next() % ar.Z) + 0.5 (float)(ps->next() % ar.Z) + 0.5
); );
int notifytype = large_cave ? GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN; // Add generation notify begin event
if (mg->gennotify & (1 << notifytype)) { v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
std::vector <v3s16> *nvec = mg->gen_notifications[notifytype]; GenNotifyType notifytype = large_cave ?
nvec->push_back(v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z)); GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN;
} mg->gennotify.addEvent(notifytype, abs_pos);
// Generate some tunnel starting from orp // Generate some tunnel starting from orp
for (u16 j = 0; j < tunnel_routepoints; j++) for (u16 j = 0; j < tunnel_routepoints; j++)
makeTunnel(j % dswitchint == 0); makeTunnel(j % dswitchint == 0);
notifytype = large_cave ? GENNOTIFY_LARGECAVE_END : GENNOTIFY_CAVE_END; // Add generation notify end event
if (mg->gennotify & (1 << notifytype)) { abs_pos = v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
std::vector <v3s16> *nvec = mg->gen_notifications[notifytype]; notifytype = large_cave ?
nvec->push_back(v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z)); 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 (float)(ps->next() % ar.Z) + 0.5
); );
int notifytype = large_cave ? GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN; // Add generation notify begin event
if (mg->gennotify & (1 << notifytype)) { v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
std::vector <v3s16> *nvec = mg->gen_notifications[notifytype]; GenNotifyType notifytype = large_cave ?
nvec->push_back(v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z)); GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN;
} mg->gennotify.addEvent(notifytype, abs_pos);
// Generate some tunnel starting from orp // Generate some tunnel starting from orp
for (u16 j = 0; j < tunnel_routepoints; j++) for (u16 j = 0; j < tunnel_routepoints; j++)
makeTunnel(j % dswitchint == 0); makeTunnel(j % dswitchint == 0);
notifytype = large_cave ? GENNOTIFY_LARGECAVE_END : GENNOTIFY_CAVE_END; // Add generation notify end event
if (mg->gennotify & (1 << notifytype)) { abs_pos = v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
std::vector <v3s16> *nvec = mg->gen_notifications[notifytype]; notifytype = large_cave ?
nvec->push_back(v3s16(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z)); 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); makeRoom(roomsize, roomplace);
v3s16 room_center = roomplace + v3s16(roomsize.X / 2, 1, roomsize.Z / 2); v3s16 room_center = roomplace + v3s16(roomsize.X / 2, 1, roomsize.Z / 2);
if (mg->gennotify & (1 << dp.notifytype)) { mg->gennotify.addEvent(dp.notifytype, room_center);
std::vector <v3s16> *nvec = mg->gen_notifications[dp.notifytype];
nvec->push_back(room_center);
}
#ifdef DGEN_USE_TORCHES #ifdef DGEN_USE_TORCHES
// Place torch at room center (for testing) // 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 "voxel.h"
#include "noise.h" #include "noise.h"
#include "mapgen.h"
#define VMANIP_FLAG_DUNGEON_INSIDE VOXELFLAG_CHECKED1 #define VMANIP_FLAG_DUNGEON_INSIDE VOXELFLAG_CHECKED1
#define VMANIP_FLAG_DUNGEON_PRESERVE VOXELFLAG_CHECKED2 #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 ManualMapVoxelManipulator;
class INodeDefManager; class INodeDefManager;
class Mapgen;
v3s16 rand_ortho_dir(PseudoRandom &random, bool diagonal_dirs); v3s16 rand_ortho_dir(PseudoRandom &random, bool diagonal_dirs);
v3s16 turn_xz(v3s16 olddir, int t); v3s16 turn_xz(v3s16 olddir, int t);
@ -44,7 +44,7 @@ struct DungeonParams {
content_t c_moss; content_t c_moss;
content_t c_stair; content_t c_stair;
int notifytype; GenNotifyType notifytype;
bool diagonal_dirs; bool diagonal_dirs;
float mossratio; float mossratio;
v3s16 holesize; v3s16 holesize;

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

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

@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "map.h" #include "map.h"
#include "content_sao.h" #include "content_sao.h"
#include "nodedef.h" #include "nodedef.h"
#include "emerge.h"
#include "content_mapnode.h" // For content_mapnode_get_new_name #include "content_mapnode.h" // For content_mapnode_get_new_name
#include "voxelalgorithms.h" #include "voxelalgorithms.h"
#include "profiler.h" #include "profiler.h"
@ -55,36 +56,53 @@ FlagDesc flagdesc_gennotify[] = {
{"cave_end", 1 << GENNOTIFY_CAVE_END}, {"cave_end", 1 << GENNOTIFY_CAVE_END},
{"large_cave_begin", 1 << GENNOTIFY_LARGECAVE_BEGIN}, {"large_cave_begin", 1 << GENNOTIFY_LARGECAVE_BEGIN},
{"large_cave_end", 1 << GENNOTIFY_LARGECAVE_END}, {"large_cave_end", 1 << GENNOTIFY_LARGECAVE_END},
{"decoration", 1 << GENNOTIFY_DECORATION},
{NULL, 0} {NULL, 0}
}; };
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
Mapgen::Mapgen()
Mapgen::Mapgen() { {
seed = 0;
water_level = 0;
generating = false; generating = false;
id = -1; id = -1;
seed = 0;
water_level = 0;
flags = 0;
vm = NULL; vm = NULL;
ndef = NULL; ndef = NULL;
heightmap = NULL; heightmap = NULL;
biomemap = NULL; biomemap = NULL;
for (unsigned int i = 0; i != NUM_GEN_NOTIFY; i++)
gen_notifications[i] = new std::vector<v3s16>;
} }
Mapgen::~Mapgen() { Mapgen::Mapgen(int mapgenid, MapgenParams *params, EmergeManager *emerge) :
for (unsigned int i = 0; i != NUM_GEN_NOTIFY; i++) gennotify(emerge->gen_notify_on, &emerge->gen_notify_on_deco_ids)
delete gen_notifications[i]; {
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 // 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(); v3s16 em = vm->m_area.getExtent();
s16 y_nodes_max = vm->m_area.MaxEdge.Y; s16 y_nodes_max = vm->m_area.MaxEdge.Y;
s16 y_nodes_min = vm->m_area.MinEdge.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(); v3s16 em = vm->m_area.getExtent();
u32 i = vm->m_area.index(p2d.X, ymax, p2d.Y); u32 i = vm->m_area.index(p2d.X, ymax, p2d.Y);
s16 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) if (!heightmap)
return; 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; bool isliquid, wasliquid;
v3s16 em = vm->m_area.getExtent(); 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); ScopeProfiler sp(g_profiler, "EmergeThread: mapgen lighting update", SPT_AVG);
VoxelArea a(nmin, nmax); 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)) if (light <= 1 || !a.contains(p))
return; 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); VoxelArea a(nmin, nmax);
bool block_is_underground = (water_level >= nmax.Y); 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}; enum LightBank banks[2] = {LIGHTBANK_DAY, LIGHTBANK_NIGHT};
VoxelArea a(nmin, nmax); VoxelArea a(nmin, nmax);
bool block_is_underground = (water_level > nmax.Y); 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_FLAT 0x08
#define MG_LIGHT 0x10 #define MG_LIGHT 0x10
#define NUM_GEN_NOTIFY 6
class Settings; class Settings;
class ManualMapVoxelManipulator; class ManualMapVoxelManipulator;
class INodeDefManager; class INodeDefManager;
@ -61,13 +59,39 @@ enum MapgenObject {
MGOBJ_GENNOTIFY MGOBJ_GENNOTIFY
}; };
enum GenNotify { enum GenNotifyType {
GENNOTIFY_DUNGEON, GENNOTIFY_DUNGEON,
GENNOTIFY_TEMPLE, GENNOTIFY_TEMPLE,
GENNOTIFY_CAVE_BEGIN, GENNOTIFY_CAVE_BEGIN,
GENNOTIFY_CAVE_END, GENNOTIFY_CAVE_END,
GENNOTIFY_LARGECAVE_BEGIN, 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 { struct MapgenSpecificParams {
@ -85,7 +109,8 @@ struct MapgenParams {
MapgenSpecificParams *sparams; MapgenSpecificParams *sparams;
MapgenParams() { MapgenParams()
{
mg_name = DEFAULT_MAPGEN; mg_name = DEFAULT_MAPGEN;
seed = 0; seed = 0;
water_level = 1; water_level = 1;
@ -99,6 +124,7 @@ class Mapgen {
public: public:
int seed; int seed;
int water_level; int water_level;
u32 flags;
bool generating; bool generating;
int id; int id;
ManualMapVoxelManipulator *vm; ManualMapVoxelManipulator *vm;
@ -108,10 +134,10 @@ public:
u8 *biomemap; u8 *biomemap;
v3s16 csize; v3s16 csize;
u32 gennotify; GenerateNotifier gennotify;
std::vector<v3s16> *gen_notifications[NUM_GEN_NOTIFY];
Mapgen(); Mapgen();
Mapgen(int mapgenid, MapgenParams *params, EmergeManager *emerge);
virtual ~Mapgen(); virtual ~Mapgen();
s16 findGroundLevelFull(v2s16 p2d); s16 findGroundLevelFull(v2s16 p2d);

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

@ -47,19 +47,12 @@ FlagDesc flagdesc_mapgen_v5[] = {
}; };
MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge_) { MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge_)
this->generating = false; : Mapgen(mapgenid, params, emerge)
this->id = mapgenid; {
this->emerge = emerge_; this->emerge = emerge_;
this->bmgr = emerge->biomemgr; 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 // amount of elements to skip for the next index
// for noise/height/biome maps (not vmanip) // for noise/height/biome maps (not vmanip)
this->ystride = csize.X; this->ystride = csize.X;
@ -69,7 +62,6 @@ MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge_) {
this->heightmap = new s16[csize.X * csize.Z]; this->heightmap = new s16[csize.X * csize.Z];
MapgenV5Params *sp = (MapgenV5Params *)params->sparams; MapgenV5Params *sp = (MapgenV5Params *)params->sparams;
this->spflags = sp->spflags; this->spflags = sp->spflags;
// Terrain noise // Terrain noise

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

@ -49,21 +49,13 @@ FlagDesc flagdesc_mapgen_v6[] = {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
MapgenV6::MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge) { MapgenV6::MapgenV6(int mapgenid, MapgenParams *params, EmergeManager *emerge)
this->generating = false; : Mapgen(mapgenid, params, emerge)
this->id = mapgenid; {
this->emerge = 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 this->ystride = csize.X; //////fix this
MapgenV6Params *sp = (MapgenV6Params *)params->sparams; MapgenV6Params *sp = (MapgenV6Params *)params->sparams;
this->spflags = sp->spflags; this->spflags = sp->spflags;
this->freq_desert = sp->freq_desert; this->freq_desert = sp->freq_desert;
this->freq_beach = sp->freq_beach; this->freq_beach = sp->freq_beach;

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

@ -49,19 +49,12 @@ FlagDesc flagdesc_mapgen_v7[] = {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge) { MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge)
this->generating = false; : Mapgen(mapgenid, params, emerge)
this->id = mapgenid; {
this->emerge = emerge; this->emerge = emerge;
this->bmgr = emerge->biomemgr; 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 //// amount of elements to skip for the next index
//// for noise/height/biome maps (not vmanip) //// for noise/height/biome maps (not vmanip)
this->ystride = csize.X; this->ystride = csize.X;

@ -57,7 +57,6 @@ public:
int ystride; int ystride;
int zstride; int zstride;
u32 flags;
u32 spflags; u32 spflags;
u32 blockseed; 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; ManualMapVoxelManipulator *vm = mg->vm;
if (!canPlaceDecoration(vm, p)) if (!canPlaceDecoration(vm, p))
return; return 0;
content_t c_place = c_decos[pr->range(0, c_decos.size() - 1)]; 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); 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; 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); u32 vi = vm->m_area.index(p);
content_t c = vm->m_data[vi].getContent(); content_t c = vm->m_data[vi].getContent();
if (!CONTAINS(c_place_on, c)) if (!CONTAINS(c_place_on, c))
return; return 0;
Rotation rot = (rotation == ROTATE_RAND) ? Rotation rot = (rotation == ROTATE_RAND) ?
(Rotation)pr->range(ROTATE_0, ROTATE_270) : rotation; (Rotation)pr->range(ROTATE_0, ROTATE_270) : rotation;
schematic->blitToVManip(p, vm, rot, false, mg->ndef); 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 placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
size_t placeCutoffs(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; virtual int getHeight() = 0;
}; };
@ -92,7 +92,7 @@ public:
~DecoSimple() {} ~DecoSimple() {}
bool canPlaceDecoration(ManualMapVoxelManipulator *vm, v3s16 p); 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(); virtual int getHeight();
}; };
@ -105,7 +105,7 @@ public:
~DecoSchematic() {} ~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(); virtual int getHeight();
}; };

@ -95,7 +95,7 @@ size_t Ore::placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
nmax.Y = ymax; nmax.Y = ymax;
generate(mg->vm, mg->seed, blockseed, nmin, nmax); 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; return 1;
} }
case MGOBJ_GENNOTIFY: { case MGOBJ_GENNOTIFY: {
lua_newtable(L); std::map<std::string, std::vector<v3s16> >event_map;
for (int i = 0; flagdesc_gennotify[i].name; i++) { std::map<std::string, std::vector<v3s16> >::iterator it;
if (!(emerge->gennotify & flagdesc_gennotify[i].flag))
continue;
std::vector<v3s16> *posvec = mg->gen_notifications[i]; mg->gennotify.getEvents(event_map);
if (!posvec)
return 0;
lua_newtable(L); lua_newtable(L);
for (unsigned int j = 0; j != posvec->size(); j++) { for (it = event_map.begin(); it != event_map.end(); ++it) {
push_v3s16(L, (*posvec)[j]); 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_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; return 1;
@ -291,14 +289,24 @@ int ModApiMapgen::l_set_noiseparam_defaults(lua_State *L)
return 0; return 0;
} }
// set_gen_notify(string) // set_gen_notify(flags, {deco_id_table})
int ModApiMapgen::l_set_gen_notify(lua_State *L) int ModApiMapgen::l_set_gen_notify(lua_State *L)
{ {
u32 flags = 0, flagmask = 0; u32 flags = 0, flagmask = 0;
EmergeManager *emerge = getServer(L)->getEmergeManager();
if (read_flags(L, 1, flagdesc_gennotify, &flags, &flagmask)) { if (read_flags(L, 1, flagdesc_gennotify, &flags, &flagmask)) {
EmergeManager *emerge = getServer(L)->getEmergeManager(); emerge->gen_notify_on &= ~flagmask;
emerge->gennotify = flags; 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; return 0;