From 05f16148935a3bc2e59f3bdc1b1287ec17f30900 Mon Sep 17 00:00:00 2001 From: kay27 Date: Tue, 4 Jan 2022 04:13:28 +0400 Subject: [PATCH] #62 Spawn Ender Dragon --- mods/MAPGEN/mcl_mapgen_core/init.lua | 45 ++++++++++++++++++++++------ mods/MAPGEN/mcl_structures/init.lua | 30 +++++++++++++++---- 2 files changed, 61 insertions(+), 14 deletions(-) diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index 04448d3f1..96995396f 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -1247,16 +1247,43 @@ local function generate_clay(minp, maxp, blockseed, voxelmanip_data, voxelmanip_ return lvm_used end -local function generate_end_exit_portal(pos) - local obj = minetest.add_entity(vector.add(pos, vector.new(3, 11, 3)), "mobs_mc:enderdragon") - if obj then - local dragon_entity = obj:get_luaentity() - dragon_entity._initial = true - dragon_entity._portal_pos = pos - else - minetest.log("error", "[mcl_mapgen_core] ERROR! Ender dragon doesn't want to spawn") +local dragon_spawn_pos = false +local dragon_spawned, portal_generated = false, false + +local function spawn_ender_dragon() + local obj = minetest.add_entity(dragon_spawn_pos, "mobs_mc:enderdragon") + if not obj then return false end + local dragon_entity = obj:get_luaentity() + dragon_entity._initial = true + dragon_entity._portal_pos = pos + return obj +end + +local function try_to_spawn_ender_dragon() + if spawn_ender_dragon() then + dragon_spawned = true + return end - mcl_structures.call_struct(pos, "end_exit_portal") + minetest.after(2, try_to_spawn_ender_dragon) + minetest.log("warning", "[mcl_mapgen_core] WARNING! Ender dragon doesn't want to spawn at "..minetest.pos_to_string(dragon_spawn_pos)) +end + +if portal_generated and not dragon_spawned then + minetest.after(10, try_to_spawn_ender_dragon) +end + +local function generate_end_exit_portal(pos) + if dragon_spawn_pos then return false end + dragon_spawn_pos = vector.add(pos, vector.new(3, 11, 3)) + mcl_structures.call_struct(pos, "end_exit_portal", nil, nil, function() + minetest.after(2, function() + minetest.emerge_area(vector.subtract(dragon_spawn_pos, {x = 64, y = 12, z = 5}), vector.add(dragon_spawn_pos, {x = 3, y = 3, z = 5}), function(blockpos, action, calls_remaining, param) + if calls_remaining > 0 then return end + minetest.after(2, try_to_spawn_ender_dragon) + end) + end) + end) + portal_generated = true end -- TODO: Try to use more efficient structure generating code diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index be1be0f67..ef5fa8cd2 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -69,7 +69,7 @@ local function init_node_construct(pos) end -- The call of Struct -function mcl_structures.call_struct(pos, struct_style, rotation, pr) +function mcl_structures.call_struct(pos, struct_style, rotation, pr, callback) minetest.log("action","[mcl_structures] call_struct " .. struct_style.." at "..minetest.pos_to_string(pos)) if not rotation then rotation = "random" @@ -91,13 +91,31 @@ function mcl_structures.call_struct(pos, struct_style, rotation, pr) elseif struct_style == "fossil" then return mcl_structures.generate_fossil(pos, rotation, pr) elseif struct_style == "end_exit_portal" then - return mcl_structures.generate_end_exit_portal(pos, rotation) + return mcl_structures.generate_end_exit_portal(pos, rotation, pr, callback) elseif struct_style == "end_exit_portal_open" then return mcl_structures.generate_end_exit_portal_open(pos, rotation) elseif struct_style == "end_gateway_portal" then return mcl_structures.generate_end_gateway_portal(pos, rotation) elseif struct_style == "end_portal_shrine" then return mcl_structures.generate_end_portal_shrine(pos, rotation, pr) + elseif struct_style == "end_portal" then + return mcl_structures.generate_end_portal(pos, rotation, pr) + end +end + +function mcl_structures.generate_end_portal(pos, rotation, pr) + -- todo: proper facedir + local x0, y0, z0 = pos.x - 2, pos.y, pos.z - 2 + for x = 0, 4 do + for z = 0, 4 do + if x % 4 == 0 or z % 4 == 0 then + if x % 4 ~= 0 or z % 4 ~= 0 then + minetest.swap_node({x = x0 + x, y = y0, z = z0 + z}, {name = "mcl_portals:end_portal_frame_eye"}) + end + else + minetest.swap_node({x = x0 + x, y = y0, z = z0 + z}, {name = "mcl_portals:portal_end"}) + end + end end end @@ -324,9 +342,9 @@ function mcl_structures.generate_fossil(pos, rotation, pr) return mcl_structures.place_schematic(newpos, path, rotation or "random", nil, true) end -function mcl_structures.generate_end_exit_portal(pos, rot) +function mcl_structures.generate_end_exit_portal(pos, rot, pr, callback) local path = modpath.."/schematics/mcl_structures_end_exit_portal.mts" - return mcl_structures.place_schematic(pos, path, rot or "0", {["mcl_portals:portal_end"] = "air"}, true) + return mcl_structures.place_schematic(pos, path, rot or "0", {["mcl_portals:portal_end"] = "air"}, true, nil, callback) end function mcl_structures.generate_end_exit_portal_open(pos, rot) @@ -556,7 +574,7 @@ end -- Debug command minetest.register_chatcommand("spawnstruct", { - params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_exit_portal_open | end_gateway_portal | end_portal_shrine | nether_portal | dungeon", + params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_exit_portal_open | end_gateway_portal | end_portal_shrine | end_portal | nether_portal | dungeon", description = S("Generate a pre-defined structure near your position."), privs = {debug = true}, func = function(name, param) @@ -596,6 +614,8 @@ minetest.register_chatcommand("spawnstruct", { 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 == "end_portal" then + mcl_structures.generate_end_portal(pos, rot, pr) elseif param == "nether_portal" and mcl_portals and mcl_portals.spawn_nether_portal then mcl_portals.spawn_nether_portal(pos, rot, pr, name) elseif param == "" then