From bdcf03ae36553f4c7ba48d18ef8d67f05590dd60 Mon Sep 17 00:00:00 2001
From: kwolekr <kwolekr@minetest.net>
Date: Sun, 4 Jan 2015 22:37:20 -0500
Subject: [PATCH] Add minetest.generate_ores() and
 minetest.generate_decorations()

---
 doc/lua_api.txt                 |  4 ++++
 src/mapgen.cpp                  |  1 +
 src/mg_decoration.cpp           | 24 ++++++++++----------
 src/mg_decoration.h             | 13 ++++++-----
 src/mg_ore.cpp                  | 28 +++++++++++------------
 src/mg_ore.h                    | 12 +++++-----
 src/script/lua_api/l_mapgen.cpp | 39 +++++++++++++++++++++++++++++++++
 src/script/lua_api/l_mapgen.h   |  6 +++++
 src/script/lua_api/l_vmanip.h   |  3 ++-
 9 files changed, 93 insertions(+), 37 deletions(-)

diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index b40dd2c48..fc8b02e50 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -1851,6 +1851,10 @@ and `minetest.auth_reload` call the authetification handler.
     * Sets the noiseparams setting of `name` to the noiseparams table specified in `noiseparams`.
     * `set_default` is an optional boolean (default: `true`) that specifies whether the setting
       should be applied to the default config or current active config
+* `minetest.generate_ores(vm)`
+   * Generate all registered ores within the VoxelManip specified by `vm`.
+* `minetest.generate_decorations(vm)`
+   * Generate all registered decorations within the VoxelManip specified by `vm`.
 * `minetest.clear_objects()`
     * clear all objects in the environments
 * `minetest.line_of_sight(pos1, pos2, stepsize)`: returns `boolean, pos`
diff --git a/src/mapgen.cpp b/src/mapgen.cpp
index 44df35a07..d61e56819 100644
--- a/src/mapgen.cpp
+++ b/src/mapgen.cpp
@@ -356,6 +356,7 @@ void Mapgen::calcLightingOld(v3s16 nmin, v3s16 nmax)
 
 GenerateNotifier::GenerateNotifier()
 {
+	m_notify_on = 0;
 }
 
 
diff --git a/src/mg_decoration.cpp b/src/mg_decoration.cpp
index 1848024dc..415c1f752 100644
--- a/src/mg_decoration.cpp
+++ b/src/mg_decoration.cpp
@@ -44,7 +44,8 @@ DecorationManager::DecorationManager(IGameDef *gamedef) :
 }
 
 
-size_t DecorationManager::placeAllDecos(Mapgen *mg, u32 seed, v3s16 nmin, v3s16 nmax)
+size_t DecorationManager::placeAllDecos(Mapgen *mg, u32 blockseed,
+	v3s16 nmin, v3s16 nmax)
 {
 	size_t nplaced = 0;
 
@@ -53,8 +54,8 @@ size_t DecorationManager::placeAllDecos(Mapgen *mg, u32 seed, v3s16 nmin, v3s16
 		if (!deco)
 			continue;
 
-		nplaced += deco->placeDeco(mg, seed, nmin, nmax);
-		seed++;
+		nplaced += deco->placeDeco(mg, blockseed, nmin, nmax);
+		blockseed++;
 	}
 
 	return nplaced;
@@ -167,7 +168,7 @@ size_t Decoration::placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
 			}
 
 			v3s16 pos(x, y, z);
-			if (generate(mg, &ps, max_y, pos))
+			if (generate(mg->vm, &ps, max_y, pos))
 				mg->gennotify.addEvent(GENNOTIFY_DECORATION, pos, id);
 		}
 	}
@@ -286,10 +287,9 @@ bool DecoSimple::canPlaceDecoration(ManualMapVoxelManipulator *vm, v3s16 p)
 }
 
 
-size_t DecoSimple::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p)
+size_t DecoSimple::generate(ManualMapVoxelManipulator *vm, PseudoRandom *pr,
+	s16 max_y, v3s16 p)
 {
-	ManualMapVoxelManipulator *vm = mg->vm;
-
 	if (!canPlaceDecoration(vm, p))
 		return 0;
 
@@ -325,10 +325,9 @@ int DecoSimple::getHeight()
 ///////////////////////////////////////////////////////////////////////////////
 
 
-size_t DecoSchematic::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p)
+size_t DecoSchematic::generate(ManualMapVoxelManipulator *vm, PseudoRandom *pr,
+	s16 max_y, v3s16 p)
 {
-	ManualMapVoxelManipulator *vm = mg->vm;
-
 	if (flags & DECO_PLACE_CENTER_X)
 		p.X -= (schematic->size.X + 1) / 2;
 	if (flags & DECO_PLACE_CENTER_Y)
@@ -336,6 +335,9 @@ size_t DecoSchematic::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p)
 	if (flags & DECO_PLACE_CENTER_Z)
 		p.Z -= (schematic->size.Z + 1) / 2;
 
+	if (!vm->m_area.contains(p))
+		return 0;
+
 	u32 vi = vm->m_area.index(p);
 	content_t c = vm->m_data[vi].getContent();
 	if (!CONTAINS(c_place_on, c))
@@ -344,7 +346,7 @@ size_t DecoSchematic::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p)
 	Rotation rot = (rotation == ROTATE_RAND) ?
 		(Rotation)pr->range(ROTATE_0, ROTATE_270) : rotation;
 
-	schematic->blitToVManip(p, vm, rot, false, mg->ndef);
+	schematic->blitToVManip(p, vm, rot, false, m_ndef);
 
 	return 1;
 }
diff --git a/src/mg_decoration.h b/src/mg_decoration.h
index 59c3ff558..1693fb9cd 100644
--- a/src/mg_decoration.h
+++ b/src/mg_decoration.h
@@ -81,9 +81,10 @@ class Decoration : public GenElement, public NodeResolver {
 	virtual void resolveNodeNames(NodeResolveInfo *nri);
 
 	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 size_t generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p) = 0;
+	virtual size_t generate(ManualMapVoxelManipulator *vm, PseudoRandom *pr,
+		s16 max_y, v3s16 p) = 0;
 	virtual int getHeight() = 0;
 };
 
@@ -98,7 +99,8 @@ class DecoSimple : public Decoration {
 	virtual void resolveNodeNames(NodeResolveInfo *nri);
 
 	bool canPlaceDecoration(ManualMapVoxelManipulator *vm, v3s16 p);
-	virtual size_t generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p);
+	virtual size_t generate(ManualMapVoxelManipulator *vm, PseudoRandom *pr,
+		s16 max_y, v3s16 p);
 	virtual int getHeight();
 };
 
@@ -108,7 +110,8 @@ class DecoSchematic : public Decoration {
 	Schematic *schematic;
 	std::string filename;
 
-	virtual size_t generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p);
+	virtual size_t generate(ManualMapVoxelManipulator *vm, PseudoRandom *pr,
+		s16 max_y, v3s16 p);
 	virtual int getHeight();
 };
 
@@ -144,7 +147,7 @@ class DecorationManager : public GenElementManager {
 
 	void clear();
 
-	size_t placeAllDecos(Mapgen *mg, u32 seed, v3s16 nmin, v3s16 nmax);
+	size_t placeAllDecos(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
 };
 
 #endif
diff --git a/src/mg_ore.cpp b/src/mg_ore.cpp
index 5bbc40e13..7d1a38e1d 100644
--- a/src/mg_ore.cpp
+++ b/src/mg_ore.cpp
@@ -41,7 +41,7 @@ OreManager::OreManager(IGameDef *gamedef) :
 }
 
 
-size_t OreManager::placeAllOres(Mapgen *mg, u32 seed, v3s16 nmin, v3s16 nmax)
+size_t OreManager::placeAllOres(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
 {
 	size_t nplaced = 0;
 
@@ -50,8 +50,8 @@ size_t OreManager::placeAllOres(Mapgen *mg, u32 seed, v3s16 nmin, v3s16 nmax)
 		if (!ore)
 			continue;
 
-		nplaced += ore->placeOre(mg, seed, nmin, nmax);
-		seed++;
+		nplaced += ore->placeOre(mg, blockseed, nmin, nmax);
+		blockseed++;
 	}
 
 	return nplaced;
@@ -123,7 +123,7 @@ size_t Ore::placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
 ///////////////////////////////////////////////////////////////////////////////
 
 
-void OreScatter::generate(ManualMapVoxelManipulator *vm, int seed,
+void OreScatter::generate(ManualMapVoxelManipulator *vm, int mapseed,
 	u32 blockseed, v3s16 nmin, v3s16 nmax)
 {
 	PseudoRandom pr(blockseed);
@@ -142,7 +142,7 @@ void OreScatter::generate(ManualMapVoxelManipulator *vm, int seed,
 		int z0 = pr.range(nmin.Z, nmax.Z - csize + 1);
 
 		if ((flags & OREFLAG_USE_NOISE) &&
-			(NoisePerlin3D(&np, x0, y0, z0, seed) < nthresh))
+			(NoisePerlin3D(&np, x0, y0, z0, mapseed) < nthresh))
 			continue;
 
 		for (int z1 = 0; z1 != csize; z1++)
@@ -164,7 +164,7 @@ void OreScatter::generate(ManualMapVoxelManipulator *vm, int seed,
 ///////////////////////////////////////////////////////////////////////////////
 
 
-void OreSheet::generate(ManualMapVoxelManipulator *vm, int seed,
+void OreSheet::generate(ManualMapVoxelManipulator *vm, int mapseed,
 	u32 blockseed, v3s16 nmin, v3s16 nmax)
 {
 	PseudoRandom pr(blockseed + 4234);
@@ -178,7 +178,7 @@ void OreSheet::generate(ManualMapVoxelManipulator *vm, int seed,
 		int sz = nmax.Z - nmin.Z + 1;
 		noise = new Noise(&np, 0, sx, sz);
 	}
-	noise->seed = seed + y_start;
+	noise->seed = mapseed + y_start;
 	noise->perlinMap2D(nmin.X, nmin.Z);
 
 	size_t index = 0;
@@ -206,8 +206,8 @@ void OreSheet::generate(ManualMapVoxelManipulator *vm, int seed,
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void OreBlob::generate(ManualMapVoxelManipulator *vm, int seed, u32 blockseed,
-	v3s16 nmin, v3s16 nmax)
+void OreBlob::generate(ManualMapVoxelManipulator *vm, int mapseed,
+	u32 blockseed, v3s16 nmin, v3s16 nmax)
 {
 	PseudoRandom pr(blockseed + 2404);
 	MapNode n_ore(c_ore, 0, ore_param2);
@@ -219,7 +219,7 @@ void OreBlob::generate(ManualMapVoxelManipulator *vm, int seed, u32 blockseed,
 	int nblobs = volume / clust_scarcity;
 
 	if (!noise)
-		noise = new Noise(&np, seed, csize, csize, csize);
+		noise = new Noise(&np, mapseed, csize, csize, csize);
 
 	for (int i = 0; i != nblobs; i++) {
 		int x0 = pr.range(nmin.X, nmax.X - csize + 1);
@@ -269,8 +269,8 @@ OreVein::~OreVein()
 }
 
 
-void OreVein::generate(ManualMapVoxelManipulator *vm, int seed, u32 blockseed,
-	v3s16 nmin, v3s16 nmax)
+void OreVein::generate(ManualMapVoxelManipulator *vm, int mapseed,
+	u32 blockseed, v3s16 nmin, v3s16 nmax)
 {
 	PseudoRandom pr(blockseed + 520);
 	MapNode n_ore(c_ore, 0, ore_param2);
@@ -279,8 +279,8 @@ void OreVein::generate(ManualMapVoxelManipulator *vm, int seed, u32 blockseed,
 		int sx = nmax.X - nmin.X + 1;
 		int sy = nmax.Y - nmin.Y + 1;
 		int sz = nmax.Z - nmin.Z + 1;
-		noise  = new Noise(&np, seed, sx, sy, sz);
-		noise2 = new Noise(&np, seed + 436, sx, sy, sz);
+		noise  = new Noise(&np, mapseed, sx, sy, sz);
+		noise2 = new Noise(&np, mapseed + 436, sx, sy, sz);
 	}
 	bool noise_generated = false;
 
diff --git a/src/mg_ore.h b/src/mg_ore.h
index dc33873d4..efa514f5f 100644
--- a/src/mg_ore.h
+++ b/src/mg_ore.h
@@ -70,7 +70,7 @@ class Ore : public GenElement, public NodeResolver {
 	virtual void resolveNodeNames(NodeResolveInfo *nri);
 
 	size_t placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
-	virtual void generate(ManualMapVoxelManipulator *vm, int seed,
+	virtual void generate(ManualMapVoxelManipulator *vm, int mapseed,
 		u32 blockseed, v3s16 nmin, v3s16 nmax) = 0;
 };
 
@@ -78,7 +78,7 @@ class OreScatter : public Ore {
 public:
 	static const bool NEEDS_NOISE = false;
 
-	virtual void generate(ManualMapVoxelManipulator *vm, int seed,
+	virtual void generate(ManualMapVoxelManipulator *vm, int mapseed,
 		u32 blockseed, v3s16 nmin, v3s16 nmax);
 };
 
@@ -86,7 +86,7 @@ class OreSheet : public Ore {
 public:
 	static const bool NEEDS_NOISE = true;
 
-	virtual void generate(ManualMapVoxelManipulator *vm, int seed,
+	virtual void generate(ManualMapVoxelManipulator *vm, int mapseed,
 		u32 blockseed, v3s16 nmin, v3s16 nmax);
 };
 
@@ -94,7 +94,7 @@ class OreBlob : public Ore {
 public:
 	static const bool NEEDS_NOISE = true;
 
-	virtual void generate(ManualMapVoxelManipulator *vm, int seed,
+	virtual void generate(ManualMapVoxelManipulator *vm, int mapseed,
 		u32 blockseed, v3s16 nmin, v3s16 nmax);
 };
 
@@ -107,7 +107,7 @@ class OreVein : public Ore {
 
 	virtual ~OreVein();
 
-	virtual void generate(ManualMapVoxelManipulator *vm, int seed,
+	virtual void generate(ManualMapVoxelManipulator *vm, int mapseed,
 		u32 blockseed, v3s16 nmin, v3s16 nmax);
 };
 
@@ -137,7 +137,7 @@ class OreManager : public GenElementManager {
 
 	void clear();
 
-	size_t placeAllOres(Mapgen *mg, u32 seed, v3s16 nmin, v3s16 nmax);
+	size_t placeAllOres(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
 };
 
 #endif
diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp
index 7d9987e72..bff8ccfe6 100644
--- a/src/script/lua_api/l_mapgen.cpp
+++ b/src/script/lua_api/l_mapgen.cpp
@@ -810,6 +810,42 @@ int ModApiMapgen::l_create_schematic(lua_State *L)
 	return 1;
 }
 
+// generate_ores(vm, [ore_id])
+int ModApiMapgen::l_generate_ores(lua_State *L)
+{
+	EmergeManager *emerge = getServer(L)->getEmergeManager();
+
+	Mapgen mg;
+	mg.seed = emerge->params.seed;
+	mg.vm   = LuaVoxelManip::checkobject(L, 1)->vm;
+	mg.ndef = getServer(L)->getNodeDefManager();
+
+	u32 blockseed = Mapgen::getBlockSeed(mg.vm->m_area.MinEdge, mg.seed);
+
+	emerge->oremgr->placeAllOres(&mg, blockseed,
+		mg.vm->m_area.MinEdge, mg.vm->m_area.MaxEdge);
+
+	return 0;
+}
+
+// generate_decorations(vm, [deco_id])
+int ModApiMapgen::l_generate_decorations(lua_State *L)
+{
+	EmergeManager *emerge = getServer(L)->getEmergeManager();
+
+	Mapgen mg;
+	mg.seed = emerge->params.seed;
+	mg.vm   = LuaVoxelManip::checkobject(L, 1)->vm;
+	mg.ndef = getServer(L)->getNodeDefManager();
+
+	u32 blockseed = Mapgen::getBlockSeed(mg.vm->m_area.MinEdge, mg.seed);
+
+	emerge->decomgr->placeAllDecos(&mg, blockseed,
+		mg.vm->m_area.MinEdge, mg.vm->m_area.MaxEdge);
+
+	return 0;
+}
+
 // place_schematic(p, schematic, rotation, replacement)
 int ModApiMapgen::l_place_schematic(lua_State *L)
 {
@@ -864,6 +900,9 @@ void ModApiMapgen::Initialize(lua_State *L, int top)
 	API_FCT(clear_registered_decorations);
 	API_FCT(clear_registered_ores);
 
+	API_FCT(generate_ores);
+	API_FCT(generate_decorations);
+
 	API_FCT(create_schematic);
 	API_FCT(place_schematic);
 }
diff --git a/src/script/lua_api/l_mapgen.h b/src/script/lua_api/l_mapgen.h
index e98838470..dd96a009e 100644
--- a/src/script/lua_api/l_mapgen.h
+++ b/src/script/lua_api/l_mapgen.h
@@ -62,6 +62,12 @@ class ModApiMapgen : public ModApiBase {
 	// clear_registered_decorations()
 	static int l_clear_registered_decorations(lua_State *L);
 
+	// generate_ores(vm)
+	static int l_generate_ores(lua_State *L);
+
+	// generate_decorations(vm)
+	static int l_generate_decorations(lua_State *L);
+
 	// clear_registered_ores
 	static int l_clear_registered_ores(lua_State *L);
 
diff --git a/src/script/lua_api/l_vmanip.h b/src/script/lua_api/l_vmanip.h
index 887b18663..82c807240 100644
--- a/src/script/lua_api/l_vmanip.h
+++ b/src/script/lua_api/l_vmanip.h
@@ -33,7 +33,6 @@ class ManualMapVoxelManipulator;
  */
 class LuaVoxelManip : public ModApiBase {
 private:
-	ManualMapVoxelManipulator *vm;
 	std::map<v3s16, MapBlock *> modified_blocks;
 	bool is_mapgen_vm;
 
@@ -65,6 +64,8 @@ class LuaVoxelManip : public ModApiBase {
 	static int l_get_emerged_area(lua_State *L);
 
 public:
+	ManualMapVoxelManipulator *vm;
+
 	LuaVoxelManip(ManualMapVoxelManipulator *mmvm, bool is_mapgen_vm);
 	LuaVoxelManip(Map *map, v3s16 p1, v3s16 p2);
 	LuaVoxelManip(Map *map);
-- 
GitLab