From d1ea880be61795bf4d5e44a19d1460454125c68a Mon Sep 17 00:00:00 2001
From: Wuzzy <almikes@aol.com>
Date: Thu, 25 May 2017 05:01:50 +0200
Subject: [PATCH] Generate monster spawners in dungeons (kinda...)

---
 mods/ITEMS/mcl_monster_spawner/init.lua | 25 ++++++++++++-------
 mods/MAPGEN/mcl_dungeons/depends.txt    |  1 +
 mods/MAPGEN/mcl_dungeons/init.lua       | 33 ++++++++++++++++++++++---
 3 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/mods/ITEMS/mcl_monster_spawner/init.lua b/mods/ITEMS/mcl_monster_spawner/init.lua
index d34cb573..f952f821 100644
--- a/mods/ITEMS/mcl_monster_spawner/init.lua
+++ b/mods/ITEMS/mcl_monster_spawner/init.lua
@@ -299,17 +299,24 @@ minetest.register_abm({
 			{x = pos.x + 4, y = pos.y + 1 + yof, z = pos.z + 4},
 			{"air"})
 
-		-- spawn in random air block
-		if air and #air > 0 then
+		-- spawn up to 4 mobs in random air blocks
+		if air then
+			for a=1, 4 do
+				if #air <= 0 then
+					-- We're out of space! Stop spawning
+					break
+				end
+				local air_index = math.random(#air)
+				local pos2 = air[air_index]
+				local lig = minetest.get_node_light(pos2) or 0
 
-			local pos2 = air[math.random(#air)]
-			local lig = minetest.get_node_light(pos2) or 0
+				pos2.y = pos2.y + 0.5
 
-			pos2.y = pos2.y + 0.5
-
-			-- only if light levels are within range
-			if lig >= mlig and lig <= xlig then
-				minetest.add_entity(pos2, mob)
+				-- only if light levels are within range
+				if lig >= mlig and lig <= xlig then
+					minetest.add_entity(pos2, mob)
+				end
+				table.remove(air, air_index)
 			end
 		end
 
diff --git a/mods/MAPGEN/mcl_dungeons/depends.txt b/mods/MAPGEN/mcl_dungeons/depends.txt
index 7dc24c1d..6cb195b5 100644
--- a/mods/MAPGEN/mcl_dungeons/depends.txt
+++ b/mods/MAPGEN/mcl_dungeons/depends.txt
@@ -1,3 +1,4 @@
 mcl_init
 mcl_core
 mcl_chests
+mcl_monster_spawner
diff --git a/mods/MAPGEN/mcl_dungeons/init.lua b/mods/MAPGEN/mcl_dungeons/init.lua
index 8f12b26d..9dd10950 100644
--- a/mods/MAPGEN/mcl_dungeons/init.lua
+++ b/mods/MAPGEN/mcl_dungeons/init.lua
@@ -79,8 +79,9 @@ minetest.register_on_generated(function(minp, maxp)
 	local c_mossycobble = minetest.get_content_id("mcl_core:mossycobble")
 	local c_chest = minetest.get_content_id("mcl_chests:chest")
 
-	-- Remember chest positions to set metadata later
+	-- Remember spawner chest positions to set metadata later
 	local chest_posses = {}
+	local spawner_posses = {}
 
 	-- Calculate the number of dungeon spawn attempts
 	local sizevector = vector.subtract(maxp, minp)
@@ -190,7 +191,11 @@ minetest.register_on_generated(function(minp, maxp)
 			table.sort(chestSlots)
 			local currentChest = 1
 
-			-- Wall and floor
+			-- Calculate the monster spawner position, to be re-used for later
+			local spawner_pos = {x = x + math.ceil(dim.x/2), y = y+1, z = z + math.ceil(dim.z/2)}
+			table.insert(spawner_posses, spawner_pos)
+
+			-- Generate walls and floor
 			local maxx, maxy, maxz = x+dim.x+1, y+dim.y, z+dim.z+1
 			local chestSlotCounter = 1
 			for tx = x, maxx do
@@ -298,7 +303,7 @@ minetest.register_on_generated(function(minp, maxp)
 			chest_param2[c] = facedir
 		end
 
-		-- Actually generate the dungeon all at once (except the chests and the spawner)
+		-- Finally generate the dungeons all at once (except the chests and the spawners)
 		vm:set_data(data)
 		vm:calc_lighting()
 		vm:update_liquids()
@@ -315,6 +320,28 @@ minetest.register_on_generated(function(minp, maxp)
 				inv:set_stack("main", i, ItemStack(items[i]))
 			end
 		end
+
+		-- Monster spawners are placed seperately, too
+		-- We don't want to destroy non-ground nodes
+		for s=1, #spawner_posses do
+			local sp = spawner_posses[s]
+			local n = minetest.get_name_from_content_id(data[area:index(sp.x,sp.y,sp.z)])
+			if minetest.registered_nodes[n].is_ground_content then
+
+				-- ... and place it and select a random mob
+				minetest.set_node(sp, {name = "mcl_monster_spawner:spawner"})
+				local mobs = {
+					"mobs_mc:zombie",
+					"mobs_mc:zombie",
+					"mobs_mc:spider",
+					"mobs_mc:skeleton",
+				}
+				local spawner_mob = mobs[math.random(1, #mobs)]
+
+				mcl_monster_spawner.setup_spawner(sp, spawner_mob)
+			end
+		end
+
 	end
 
 end)