diff --git a/mods/MAPGEN/mcl_strongholds/depends.txt b/mods/MAPGEN/mcl_strongholds/depends.txt new file mode 100644 index 0000000000..76570fa33a --- /dev/null +++ b/mods/MAPGEN/mcl_strongholds/depends.txt @@ -0,0 +1,3 @@ +mcl_init +mcl_structures +mcl_mapgen_core diff --git a/mods/MAPGEN/mcl_strongholds/description.txt b/mods/MAPGEN/mcl_strongholds/description.txt new file mode 100644 index 0000000000..2f761edbea --- /dev/null +++ b/mods/MAPGEN/mcl_strongholds/description.txt @@ -0,0 +1 @@ +Generates strongholds with end portals in the Overworld diff --git a/mods/MAPGEN/mcl_strongholds/init.lua b/mods/MAPGEN/mcl_strongholds/init.lua new file mode 100644 index 0000000000..a9822ab8ad --- /dev/null +++ b/mods/MAPGEN/mcl_strongholds/init.lua @@ -0,0 +1,101 @@ +-- Generate strongholds. + +-- A total of 128 strongholds are generated in rings around the world origin. +-- This is the list of rings, starting with the innermost ring first. +local stronghold_rings = { + -- amount: Number of strongholds in ring. + -- min, max: Minimum and maximum distance from (X=0, Z=0). + { amount = 3, min = 1408, max = 2688 }, + { amount = 6, min = 4480, max = 5760 }, + { amount = 10, min = 7552, max = 8832 }, + { amount = 15, min = 10624, max = 11904 }, + { amount = 21, min = 13696, max = 14976 }, + { amount = 28, min = 16768, max = 18048 }, + { amount = 36, min = 19840, max = 21120 }, + { amount = 9, min = 22912, max = 24192 }, +} + +local strongholds = {} +local strongholds_inited = false + +local mg_name = minetest.get_mapgen_setting("mg_name") + +-- Determine the stronghold positions and store them into the strongholds table. +-- The stronghold positions are based on the world seed. +-- The actual position might be offset by a few blocks because it might be shifted +-- to make sure the end portal room is completely within the boundaries of a mapchunk. +local init_strongholds = function() + if strongholds_inited then + return + end + -- Don't generate strongholds in singlenode + if mg_name == "singlenode" then + strongholds_inited = true + return + end + local seed = tonumber(minetest.get_mapgen_setting("seed")) + local pr = PseudoRandom(seed) + for s=1, #stronghold_rings do + local ring = stronghold_rings[s] + + -- Get random angle + local angle = pr:next() + -- Scale angle to 0 .. 2*math.pi + angle = (angle / 32767) * (math.pi*2) + for a=1, ring.amount do + local dist = pr:next(ring.min, ring.max) + local y + if mg_name == "flat" then + y = mcl_vars.mg_bedrock_overworld_max + pr:next(1, 4) + else + y = pr:next(mcl_vars.mg_bedrock_overworld_max+1, mcl_vars.mg_overworld_min+48) + end + local pos = { x = math.cos(angle) * dist, y = y, z = math.sin(angle) * dist } + pos = vector.round(pos) + table.insert(strongholds, { pos = pos }) + + -- Rotate angle by (360 / amount) degrees. + -- This will cause the angles to be evenly distributed in the stronghold ring + angle = math.fmod(angle + ((math.pi*2) / ring.amount), math.pi*2) + end + end + strongholds_inited = true +end + +-- Stronghold generation for register_on_generated. +local generate_strongholds = function(minp, maxp) + for s=1, #strongholds do + if not strongholds[s].generated then + local pos = strongholds[s].pos + if minp.x <= pos.x and maxp.x >= pos.x and minp.z <= pos.z and maxp.z >= pos.z and minp.y <= pos.y and maxp.y >= pos.y then + -- Make sure the end portal room is completely within the current mapchunk + -- The original pos is changed intentionally. + if pos.x - 6 < minp.x then + pos.x = minp.x + 7 + end + if pos.x + 6 > maxp.x then + pos.x = maxp.x - 7 + end + if pos.z - 6 < minp.z then + pos.z = minp.z + 7 + end + if pos.z + 6 > maxp.z then + pos.z = maxp.z - 7 + end + + mcl_structures.call_struct(pos, "end_portal_room") + strongholds[s].generated = true + end + end + end +end + + +init_strongholds() + +--[[ Note this mod depends on mcl_mapgen_core to make sure the core mapgen runs FIRST. +This is important because we need this to make sure the stronghold isn't instantly +overwritten by the core mapgen (since it uses LuaVoxelManip). ]] +minetest.register_on_generated(function(minp, maxp, blockseed) + generate_strongholds(minp, maxp) +end) diff --git a/mods/MAPGEN/mcl_strongholds/mod.conf b/mods/MAPGEN/mcl_strongholds/mod.conf new file mode 100644 index 0000000000..22c99de4fd --- /dev/null +++ b/mods/MAPGEN/mcl_strongholds/mod.conf @@ -0,0 +1 @@ +name = mcl_strongholds diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index c7fd7f0ed0..1fb949867a 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -127,13 +127,15 @@ end mcl_structures.generate_end_portal_room = function(pos) local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_portal_room_simple.mts" + local offset = {x=6, y=8, z=6} local size = {x=13, y=8, z=13} - local ret = minetest.place_schematic(pos, path, "0", nil, true) + local newpos = { x = pos.x - offset.x, y = pos.y, z = pos.z - offset.z } + local ret = minetest.place_schematic(newpos, path, "0", nil, true) if ret == nil then return ret end - local area_start, area_end = {x=pos.x-size.x, y=pos.y, z=pos.z-size.z}, vector.add(pos, size) + local area_start, area_end = newpos, vector.add(newpos, size) -- Find and setup spawner with silverfish local spawners = minetest.find_nodes_in_area(area_start, area_end, "mcl_mobspawners:spawner") for s=1, #spawners do