forked from VoxeLibre/VoxeLibre
Implement /spawnstruct dungeon
This commit is contained in:
parent
f3fb80200d
commit
45c0c576f7
|
@ -1,5 +1,7 @@
|
||||||
-- FIXME: Chests may appear at openings
|
-- FIXME: Chests may appear at openings
|
||||||
|
|
||||||
|
mcl_dungeons = {}
|
||||||
|
|
||||||
local mg_name = minetest.get_mapgen_setting("mg_name")
|
local mg_name = minetest.get_mapgen_setting("mg_name")
|
||||||
|
|
||||||
-- Are dungeons disabled?
|
-- Are dungeons disabled?
|
||||||
|
@ -10,6 +12,11 @@ end
|
||||||
local min_y = math.max(mcl_vars.mg_overworld_min, mcl_vars.mg_bedrock_overworld_max) + 1
|
local min_y = math.max(mcl_vars.mg_overworld_min, mcl_vars.mg_bedrock_overworld_max) + 1
|
||||||
local max_y = mcl_vars.mg_overworld_max - 1
|
local max_y = mcl_vars.mg_overworld_max - 1
|
||||||
|
|
||||||
|
-- Calculate the number of dungeon spawn attempts
|
||||||
|
-- In Minecraft, there 8 dungeon spawn attempts Minecraft chunk (16*256*16 = 65536 blocks).
|
||||||
|
-- Minetest chunks don't have this size, so scale the number accordingly.
|
||||||
|
local attempts = math.ceil(((mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE) ^ 3) / 8192) -- 63 = 80*80*80/8192
|
||||||
|
|
||||||
local dungeonsizes = {
|
local dungeonsizes = {
|
||||||
{ x=5, y=4, z=5},
|
{ x=5, y=4, z=5},
|
||||||
{ x=5, y=4, z=7},
|
{ x=5, y=4, z=7},
|
||||||
|
@ -91,24 +98,20 @@ if mg_name == "v6" then
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Calculate the number of dungeon spawn attempts
|
|
||||||
-- In Minecraft, there 8 dungeon spawn attempts Minecraft chunk (16*256*16 = 65536 blocks).
|
|
||||||
-- Minetest chunks don't have this size, so scale the number accordingly.
|
|
||||||
local attempts = math.ceil(((mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE) ^ 3) / 8192) -- 63 = 80*80*80/8192
|
|
||||||
|
|
||||||
local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
|
local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
|
||||||
if calls_remaining >= 1 then return end
|
if calls_remaining >= 1 then return end
|
||||||
|
|
||||||
local p1, p2, dim, pr = param.p1, param.p2, param.dim, param.pr
|
local p1, p2, dim, pr = param.p1, param.p2, param.dim, param.pr
|
||||||
local x, y, z = p1.x, p1.y, p1.z
|
local x, y, z = p1.x, p1.y, p1.z
|
||||||
|
local check = not (param.dontcheck or false)
|
||||||
|
|
||||||
-- Check floor and ceiling: Must be *completely* solid
|
-- Check floor and ceiling: Must be *completely* solid
|
||||||
local y_floor = y
|
local y_floor = y
|
||||||
local y_ceiling = y + dim.y + 1
|
local y_ceiling = y + dim.y + 1
|
||||||
for tx = x, x + dim.x do for tz = z, z + dim.z do
|
if check then for tx = x, x + dim.x do for tz = z, z + dim.z do
|
||||||
if not minetest.registered_nodes[mcl_mapgen_core.get_node({x = tx, y = y_floor , z = tz}).name].walkable
|
if not minetest.registered_nodes[mcl_mapgen_core.get_node({x = tx, y = y_floor , z = tz}).name].walkable
|
||||||
or not minetest.registered_nodes[mcl_mapgen_core.get_node({x = tx, y = y_ceiling, z = tz}).name].walkable then return false end
|
or not minetest.registered_nodes[mcl_mapgen_core.get_node({x = tx, y = y_ceiling, z = tz}).name].walkable then return false end
|
||||||
end end
|
end end end
|
||||||
|
|
||||||
-- Check for air openings (2 stacked air at ground level) in wall positions
|
-- Check for air openings (2 stacked air at ground level) in wall positions
|
||||||
local openings_counter = 0
|
local openings_counter = 0
|
||||||
|
@ -182,7 +185,7 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check conditions. If okay, start generating
|
-- Check conditions. If okay, start generating
|
||||||
if openings_counter < 1 or openings_counter > 5 then return end
|
if check and (openings_counter < 1 or openings_counter > 5) then return end
|
||||||
|
|
||||||
minetest.log("action","[mcl_dungeons] Placing new dungeon at "..minetest.pos_to_string({x=x,y=y,z=z}))
|
minetest.log("action","[mcl_dungeons] Placing new dungeon at "..minetest.pos_to_string({x=x,y=y,z=z}))
|
||||||
-- Okay! Spawning starts!
|
-- Okay! Spawning starts!
|
||||||
|
@ -349,4 +352,13 @@ local function dungeons_nodes(minp, maxp, blockseed)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function mcl_dungeons.spawn_dungeon(p1, _, pr)
|
||||||
|
if not p1 or not pr or not p1.x or not p1.y or not p1.z then return end
|
||||||
|
local dim = dungeonsizes[pr:next(1, #dungeonsizes)]
|
||||||
|
local p2 = {x = p1.x+dim.x+1, y = p1.y+dim.y+1, z = p1.z+dim.z+1}
|
||||||
|
minetest.log("verbose","[mcl_dungeons] size=" ..minetest.pos_to_string(dim) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2))
|
||||||
|
local param = {p1=p1, p2=p2, dim=dim, pr=pr, dontcheck=true}
|
||||||
|
minetest.emerge_area(p1, p2, ecb_spawn_dungeon, param)
|
||||||
|
end
|
||||||
|
|
||||||
mcl_mapgen_core.register_generator("dungeons", nil, dungeons_nodes, 999999)
|
mcl_mapgen_core.register_generator("dungeons", nil, dungeons_nodes, 999999)
|
||||||
|
|
|
@ -92,10 +92,10 @@ mcl_structures.call_struct = function(pos, struct_style, rotation, pr)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
mcl_structures.generate_desert_well = function(pos)
|
mcl_structures.generate_desert_well = function(pos, rot)
|
||||||
local newpos = {x=pos.x,y=pos.y-2,z=pos.z}
|
local newpos = {x=pos.x,y=pos.y-2,z=pos.z}
|
||||||
local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_desert_well.mts"
|
local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_desert_well.mts"
|
||||||
return mcl_structures.place_schematic(newpos, path, "0", nil, true)
|
return mcl_structures.place_schematic(newpos, path, rot or "0", nil, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
mcl_structures.generate_igloo = function(pos, rotation, pr)
|
mcl_structures.generate_igloo = function(pos, rotation, pr)
|
||||||
|
@ -265,7 +265,7 @@ mcl_structures.generate_boulder = function(pos, rotation, pr)
|
||||||
|
|
||||||
local newpos = {x=pos.x,y=pos.y-1,z=pos.z}
|
local newpos = {x=pos.x,y=pos.y-1,z=pos.z}
|
||||||
|
|
||||||
return minetest.place_schematic(newpos, path) -- don't serialize schematics for registered biome decorations, for MT 5.4.0, https://github.com/minetest/minetest/issues/10995
|
return minetest.place_schematic(newpos, path, rotation) -- don't serialize schematics for registered biome decorations, for MT 5.4.0, https://github.com/minetest/minetest/issues/10995
|
||||||
end
|
end
|
||||||
|
|
||||||
local function hut_placement_callback(p1, p2, size, orientation, pr)
|
local function hut_placement_callback(p1, p2, size, orientation, pr)
|
||||||
|
@ -284,14 +284,14 @@ mcl_structures.generate_witch_hut = function(pos, rotation, pr)
|
||||||
mcl_structures.place_schematic(pos, path, rotation, nil, true, nil, hut_placement_callback, pr)
|
mcl_structures.place_schematic(pos, path, rotation, nil, true, nil, hut_placement_callback, pr)
|
||||||
end
|
end
|
||||||
|
|
||||||
mcl_structures.generate_ice_spike_small = function(pos)
|
mcl_structures.generate_ice_spike_small = function(pos, rotation)
|
||||||
local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_ice_spike_small.mts"
|
local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_ice_spike_small.mts"
|
||||||
return minetest.place_schematic(pos, path, "random", nil, false) -- don't serialize schematics for registered biome decorations, for MT 5.4.0
|
return minetest.place_schematic(pos, path, rotation or "random", nil, false) -- don't serialize schematics for registered biome decorations, for MT 5.4.0
|
||||||
end
|
end
|
||||||
|
|
||||||
mcl_structures.generate_ice_spike_large = function(pos)
|
mcl_structures.generate_ice_spike_large = function(pos, rotation)
|
||||||
local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_ice_spike_large.mts"
|
local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_ice_spike_large.mts"
|
||||||
return minetest.place_schematic(pos, path, "random", nil, false) -- don't serialize schematics for registered biome decorations, for MT 5.4.0
|
return minetest.place_schematic(pos, path, rotation or "random", nil, false) -- don't serialize schematics for registered biome decorations, for MT 5.4.0
|
||||||
end
|
end
|
||||||
|
|
||||||
mcl_structures.generate_fossil = function(pos, rotation, pr)
|
mcl_structures.generate_fossil = function(pos, rotation, pr)
|
||||||
|
@ -309,12 +309,12 @@ mcl_structures.generate_fossil = function(pos, rotation, pr)
|
||||||
}
|
}
|
||||||
local r = pr:next(1, #fossils)
|
local r = pr:next(1, #fossils)
|
||||||
local path = minetest.get_modpath("mcl_structures").."/schematics/"..fossils[r]
|
local path = minetest.get_modpath("mcl_structures").."/schematics/"..fossils[r]
|
||||||
return mcl_structures.place_schematic(newpos, path, "random", nil, true)
|
return mcl_structures.place_schematic(newpos, path, rotation or "random", nil, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
mcl_structures.generate_end_exit_portal = function(pos)
|
mcl_structures.generate_end_exit_portal = function(pos, rot)
|
||||||
local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_exit_portal.mts"
|
local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_exit_portal.mts"
|
||||||
return mcl_structures.place_schematic(pos, path, "0", nil, true)
|
return mcl_structures.place_schematic(pos, path, rot or "0", nil, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function shrine_placement_callback(p1, p2, size, rotation, pr)
|
local function shrine_placement_callback(p1, p2, size, rotation, pr)
|
||||||
|
@ -401,7 +401,7 @@ mcl_structures.generate_end_portal_shrine = function(pos, rotation, pr)
|
||||||
local newpos = { x = pos.x - offset.x, y = pos.y, z = pos.z - offset.z }
|
local newpos = { x = pos.x - offset.x, y = pos.y, z = pos.z - offset.z }
|
||||||
|
|
||||||
local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_portal_room_simple.mts"
|
local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_portal_room_simple.mts"
|
||||||
mcl_structures.place_schematic(newpos, path, "0", nil, true, nil, shrine_placement_callback, pr)
|
mcl_structures.place_schematic(newpos, path, rotation or "0", nil, true, nil, shrine_placement_callback, pr)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function temple_placement_callback(p1, p2, size, rotation, pr)
|
local function temple_placement_callback(p1, p2, size, rotation, pr)
|
||||||
|
@ -488,7 +488,7 @@ mcl_structures.generate_desert_temple = function(pos, rotation, pr)
|
||||||
if newpos == nil then
|
if newpos == nil then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
mcl_structures.place_schematic(newpos, path, "random", nil, true, nil, temple_placement_callback, pr)
|
mcl_structures.place_schematic(newpos, path, rotation or "random", nil, true, nil, temple_placement_callback, pr)
|
||||||
end
|
end
|
||||||
|
|
||||||
local registered_structures = {}
|
local registered_structures = {}
|
||||||
|
@ -534,7 +534,7 @@ end
|
||||||
|
|
||||||
-- Debug command
|
-- Debug command
|
||||||
minetest.register_chatcommand("spawnstruct", {
|
minetest.register_chatcommand("spawnstruct", {
|
||||||
params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_portal_shrine",
|
params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_portal_shrine | dungeon",
|
||||||
description = S("Generate a pre-defined structure near your position."),
|
description = S("Generate a pre-defined structure near your position."),
|
||||||
privs = {debug = true},
|
privs = {debug = true},
|
||||||
func = function(name, param)
|
func = function(name, param)
|
||||||
|
@ -551,7 +551,7 @@ minetest.register_chatcommand("spawnstruct", {
|
||||||
if param == "desert_temple" then
|
if param == "desert_temple" then
|
||||||
mcl_structures.generate_desert_temple(pos, rot, pr)
|
mcl_structures.generate_desert_temple(pos, rot, pr)
|
||||||
elseif param == "desert_well" then
|
elseif param == "desert_well" then
|
||||||
mcl_structures.generate_desert_well(pos, rot, pr)
|
mcl_structures.generate_desert_well(pos, rot)
|
||||||
elseif param == "igloo" then
|
elseif param == "igloo" then
|
||||||
mcl_structures.generate_igloo(pos, rot, pr)
|
mcl_structures.generate_igloo(pos, rot, pr)
|
||||||
elseif param == "witch_hut" then
|
elseif param == "witch_hut" then
|
||||||
|
@ -568,6 +568,8 @@ minetest.register_chatcommand("spawnstruct", {
|
||||||
mcl_structures.generate_end_exit_portal(pos, rot, pr)
|
mcl_structures.generate_end_exit_portal(pos, rot, pr)
|
||||||
elseif param == "end_portal_shrine" then
|
elseif param == "end_portal_shrine" then
|
||||||
mcl_structures.generate_end_portal_shrine(pos, rot, pr)
|
mcl_structures.generate_end_portal_shrine(pos, rot, pr)
|
||||||
|
elseif param == "dungeon" and mcl_dungeons and mcl_dungeons.spawn_dungeon then
|
||||||
|
mcl_dungeons.spawn_dungeon(pos, rot, pr)
|
||||||
elseif param == "" then
|
elseif param == "" then
|
||||||
message = S("Error: No structure type given. Please use “/spawnstruct <type>”.")
|
message = S("Error: No structure type given. Please use “/spawnstruct <type>”.")
|
||||||
errord = true
|
errord = true
|
||||||
|
|
Loading…
Reference in New Issue