Generate end portal rooms in the world

This commit is contained in:
Wuzzy 2017-12-10 18:39:02 +01:00
parent aff2020731
commit 2d8ad7ebf0
5 changed files with 110 additions and 2 deletions

View File

@ -0,0 +1,3 @@
mcl_init
mcl_structures
mcl_mapgen_core

View File

@ -0,0 +1 @@
Generates strongholds with end portals in the Overworld

View File

@ -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)

View File

@ -0,0 +1 @@
name = mcl_strongholds

View File

@ -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