From 60feb4ad25003b4ed5f93f7fda7f4b8177a0ba51 Mon Sep 17 00:00:00 2001
From: kwolekr <kwolekr@minetest.net>
Date: Sat, 6 Dec 2014 18:08:08 -0500
Subject: [PATCH] Add minetest.clear_registered_biomes() api

---
 src/mapgen.cpp                  | 15 +++++++-------
 src/mapgen.h                    |  4 ++--
 src/mg_biome.cpp                | 35 +++++++++++++++++++++++----------
 src/mg_biome.h                  |  5 +++++
 src/script/lua_api/l_mapgen.cpp |  8 ++++++++
 src/script/lua_api/l_mapgen.h   |  3 +++
 6 files changed, 51 insertions(+), 19 deletions(-)

diff --git a/src/mapgen.cpp b/src/mapgen.cpp
index 44ce0c615..880ea1eea 100644
--- a/src/mapgen.cpp
+++ b/src/mapgen.cpp
@@ -419,22 +419,17 @@ GenElement *GenElementManager::get(u32 id)
 }
 
 
-GenElement *GenElementManager::getByName(const char *name)
+GenElement *GenElementManager::getByName(const std::string &name)
 {
 	for (size_t i = 0; i != m_elements.size(); i++) {
 		GenElement *elem = m_elements[i];
-		if (elem && !strcmp(elem->name.c_str(), name))
+		if (elem && name == elem->name)
 			return elem;
 	}
 
 	return NULL;
 }
 
-GenElement *GenElementManager::getByName(std::string &name)
-{
-	return getByName(name.c_str());
-}
-
 
 GenElement *GenElementManager::update(u32 id, GenElement *elem)
 {
@@ -451,3 +446,9 @@ GenElement *GenElementManager::remove(u32 id)
 {
 	return update(id, NULL);
 }
+
+
+void GenElementManager::clear()
+{
+	m_elements.clear();
+}
diff --git a/src/mapgen.h b/src/mapgen.h
index 9cdb157e1..5feeaf97c 100644
--- a/src/mapgen.h
+++ b/src/mapgen.h
@@ -181,9 +181,9 @@ class GenElementManager {
 	virtual GenElement *get(u32 id);
 	virtual GenElement *update(u32 id, GenElement *elem);
 	virtual GenElement *remove(u32 id);
+	virtual void clear();
 
-	virtual GenElement *getByName(const char *name);
-	virtual GenElement *getByName(std::string &name);
+	virtual GenElement *getByName(const std::string &name);
 
 protected:
 	std::vector<GenElement *> m_elements;
diff --git a/src/mg_biome.cpp b/src/mg_biome.cpp
index 9a986b3de..91b7290d8 100644
--- a/src/mg_biome.cpp
+++ b/src/mg_biome.cpp
@@ -35,11 +35,9 @@ NoiseParams nparams_biome_def_humidity(50, 50, v3f(500.0, 500.0, 500.0), 842, 3,
 
 ///////////////////////////////////////////////////////////////////////////////
 
-
 BiomeManager::BiomeManager(IGameDef *gamedef)
 {
-	NodeResolver *resolver = gamedef->getNodeDefManager()->getResolver();
-
+	m_resolver  = gamedef->getNodeDefManager()->getResolver();
 	np_heat     = &nparams_biome_def_heat;
 	np_humidity = &nparams_biome_def_humidity;
 
@@ -56,12 +54,12 @@ BiomeManager::BiomeManager(IGameDef *gamedef)
 	b->heat_point     = 0.0;
 	b->humidity_point = 0.0;
 
-	resolver->addNode("air",                 "", CONTENT_AIR, &b->c_top);
-	resolver->addNode("air",                 "", CONTENT_AIR, &b->c_filler);
-	resolver->addNode("mapgen_stone",        "", CONTENT_AIR, &b->c_stone);
-	resolver->addNode("mapgen_water_source", "", CONTENT_AIR, &b->c_water);
-	resolver->addNode("air",                 "", CONTENT_AIR, &b->c_dust);
-	resolver->addNode("mapgen_water_source", "", CONTENT_AIR, &b->c_dust_water);
+	m_resolver->addNode("air",                 "", CONTENT_AIR, &b->c_top);
+	m_resolver->addNode("air",                 "", CONTENT_AIR, &b->c_filler);
+	m_resolver->addNode("mapgen_stone",        "", CONTENT_AIR, &b->c_stone);
+	m_resolver->addNode("mapgen_water_source", "", CONTENT_AIR, &b->c_water);
+	m_resolver->addNode("air",                 "", CONTENT_AIR, &b->c_dust);
+	m_resolver->addNode("mapgen_water_source", "", CONTENT_AIR, &b->c_dust_water);
 
 	add(b);
 }
@@ -110,7 +108,24 @@ Biome *BiomeManager::getBiome(float heat, float humidity, s16 y)
 			biome_closest = b;
 		}
 	}
-	
+
 	return biome_closest ? biome_closest : (Biome *)m_elements[0];
 }
 
+void BiomeManager::clear()
+{
+	for (size_t i = 1; i < m_elements.size(); i++) {
+		Biome *b = (Biome *)m_elements[i];
+		if (!b)
+			continue;
+
+		m_resolver->cancelNode(&b->c_top);
+		m_resolver->cancelNode(&b->c_filler);
+		m_resolver->cancelNode(&b->c_stone);
+		m_resolver->cancelNode(&b->c_water);
+		m_resolver->cancelNode(&b->c_dust);
+		m_resolver->cancelNode(&b->c_dust_water);
+	}
+	m_elements.resize(1);
+}
+
diff --git a/src/mg_biome.h b/src/mg_biome.h
index 7a62998e3..9180069df 100644
--- a/src/mg_biome.h
+++ b/src/mg_biome.h
@@ -72,9 +72,14 @@ class BiomeManager : public GenElementManager {
 		return new Biome;
 	}
 
+	void clear();
+
 	void calcBiomes(s16 sx, s16 sy, float *heat_map, float *humidity_map,
 		s16 *height_map, u8 *biomeid_map);
 	Biome *getBiome(float heat, float humidity, s16 y);
+
+private:
+	NodeResolver *m_resolver;
 };
 
 #endif
diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp
index a8f55cd25..5f9266c2b 100644
--- a/src/script/lua_api/l_mapgen.cpp
+++ b/src/script/lua_api/l_mapgen.cpp
@@ -360,6 +360,13 @@ int ModApiMapgen::l_register_biome(lua_State *L)
 	return 1;
 }
 
+int ModApiMapgen::l_clear_registered_biomes(lua_State *L)
+{
+	BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr;
+	bmgr->clear();
+	return 0;
+}
+
 // register_decoration({lots of stuff})
 int ModApiMapgen::l_register_decoration(lua_State *L)
 {
@@ -678,6 +685,7 @@ void ModApiMapgen::Initialize(lua_State *L, int top)
 	API_FCT(register_biome);
 	API_FCT(register_decoration);
 	API_FCT(register_ore);
+	API_FCT(clear_registered_biomes);
 
 	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 dac0f00a7..d76190f27 100644
--- a/src/script/lua_api/l_mapgen.h
+++ b/src/script/lua_api/l_mapgen.h
@@ -52,6 +52,9 @@ class ModApiMapgen : public ModApiBase {
 	// register_ore({lots of stuff})
 	static int l_register_ore(lua_State *L);
 
+	// clear_registered_biomes()
+	static int l_clear_registered_biomes(lua_State *L);
+
 	// create_schematic(p1, p2, probability_list, filename)
 	static int l_create_schematic(lua_State *L);
 
-- 
GitLab