forked from MineClone5/MineClone5
114 lines
4.0 KiB
Lua
114 lines
4.0 KiB
Lua
local S = minetest.get_translator("mcl_portals")
|
|
local storage = mcl_portals.storage
|
|
|
|
local gateway_positions = {
|
|
{x = 96, y = -26925, z = 0},
|
|
{x = 91, y = -26925, z = 29},
|
|
{x = 77, y = -26925, z = 56},
|
|
{x = 56, y = -26925, z = 77},
|
|
{x = 29, y = -26925, z = 91},
|
|
{x = 0, y = -26925, z = 96},
|
|
{x = -29, y = -26925, z = 91},
|
|
{x = -56, y = -26925, z = 77},
|
|
{x = -77, y = -26925, z = 56},
|
|
{x = -91, y = -26925, z = 29},
|
|
{x = -96, y = -26925, z = 0},
|
|
{x = -91, y = -26925, z = -29},
|
|
{x = -77, y = -26925, z = -56},
|
|
{x = -56, y = -26925, z = -77},
|
|
{x = -29, y = -26925, z = -91},
|
|
{x = 0, y = -26925, z = -96},
|
|
{x = 29, y = -26925, z = -91},
|
|
{x = 56, y = -26925, z = -77},
|
|
{x = 77, y = -26925, z = -56},
|
|
{x = 91, y = -26925, z = -29},
|
|
}
|
|
|
|
local function spawn_gateway_portal(pos, dest_str)
|
|
local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_gateway_portal.mts"
|
|
return mcl_structures.place_schematic(vector.add(pos, vector.new(-1, -2, -1)), path, "0", nil, true, nil, dest_str and function()
|
|
minetest.get_meta(pos):set_string("mcl_portals:gateway_destination", dest_str)
|
|
end)
|
|
end
|
|
|
|
function mcl_portals.spawn_gateway_portal()
|
|
local id = storage:get_int("gateway_last_id") + 1
|
|
local pos = gateway_positions[id]
|
|
if not pos then return end
|
|
storage:set_int("gateway_last_id", id)
|
|
spawn_gateway_portal(pos)
|
|
end
|
|
|
|
local gateway_def = table.copy(minetest.registered_nodes["mcl_portals:portal_end"])
|
|
gateway_def.description = S("End Gateway Portal")
|
|
gateway_def._tt_help = S("Used to construct end gateway portals")
|
|
gateway_def._doc_items_longdesc = S("An End gateway portal teleports creatures and objects to the outer End (and back!).")
|
|
gateway_def._doc_items_usagehelp = S("Throw an ender pearl into the portal to teleport. Entering an Gateway portal near the Overworld teleports you to the outer End. At this destination another gateway portal will be constructed, which you can use to get back.")
|
|
gateway_def.after_destruct = nil
|
|
gateway_def.drawtype = "normal"
|
|
gateway_def.node_box = nil
|
|
gateway_def.walkable = true
|
|
gateway_def.tiles[3] = nil
|
|
minetest.register_node("mcl_portals:portal_gateway", gateway_def)
|
|
|
|
local function find_destination_pos(minp, maxp)
|
|
for y = maxp.y, minp.y, -1 do
|
|
for x = maxp.x, minp.x, -1 do
|
|
for z = maxp.z, minp.z, -1 do
|
|
local pos = vector.new(x, y, z)
|
|
local nn = minetest.get_node(pos).name
|
|
if nn ~= "ignore" and nn ~= "mcl_portals:portal_gateway" and nn ~= "mcl_core:bedrock" then
|
|
local def = minetest.registered_nodes[nn]
|
|
if def and def.walkable then
|
|
return vector.add(pos, vector.new(0, 1.5, 0))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local preparing = {}
|
|
|
|
local function teleport(pos, obj)
|
|
local meta = minetest.get_meta(pos)
|
|
local dest_portal
|
|
local dest_str = meta:get_string("mcl_portals:gateway_destination")
|
|
local pos_str = minetest.pos_to_string(pos)
|
|
if dest_str == "" then
|
|
dest_portal = vector.multiply(vector.direction(vector.new(0, pos.y, 0), pos), math.random(768, 1024))
|
|
dest_portal.y = -26970
|
|
spawn_gateway_portal(dest_portal, pos_str)
|
|
meta:set_string("mcl_portals:gateway_destination", minetest.pos_to_string(dest_portal))
|
|
else
|
|
dest_portal = minetest.string_to_pos(dest_str)
|
|
end
|
|
local minp = vector.subtract(dest_portal, vector.new(5, 40, 5))
|
|
local maxp = vector.add(dest_portal, vector.new(5, 10, 5))
|
|
preparing[pos_str] = true
|
|
minetest.emerge_area(minp, maxp, function(blockpos, action, calls_remaining, param)
|
|
if calls_remaining < 1 then
|
|
if obj and obj:is_player() or obj:get_luaentity() then
|
|
obj:set_pos(find_destination_pos(minp, maxp) or vector.add(dest_portal, vector.new(0, 3.5, 0)))
|
|
end
|
|
preparing[pos_str] = false
|
|
end
|
|
end)
|
|
end
|
|
|
|
minetest.register_abm({
|
|
label = "End gateway portal teleportation",
|
|
nodenames = {"mcl_portals:portal_gateway"},
|
|
interval = 0.1,
|
|
chance = 1,
|
|
action = function(pos)
|
|
if preparing[minetest.pos_to_string(pos)] then return end
|
|
for _, obj in pairs(minetest.get_objects_inside_radius(pos, 1)) do
|
|
if obj:get_hp() > 0 then
|
|
teleport(pos, obj)
|
|
return
|
|
end
|
|
end
|
|
end,
|
|
})
|