129 lines
4.1 KiB
Lua
129 lines
4.1 KiB
Lua
local ns = {
|
|
beacons = {},
|
|
teleports = {}
|
|
}
|
|
|
|
minetest.register_entity(":teleport_box", {
|
|
initial_properties = {
|
|
visual = "mesh",
|
|
mesh = "teleport_box.gltf",
|
|
textures = {"teleport_box.png"},
|
|
visual_size = vector.new(1,1,1) *5,
|
|
static_save = false,
|
|
use_texture_alpha = true,
|
|
backface_culling = false,
|
|
pointable = false,
|
|
glow = 14
|
|
},
|
|
on_activate = function(e)
|
|
e.object:set_armor_groups{immortal = 1}
|
|
end,
|
|
on_step = function(e, dtime)
|
|
|
|
end
|
|
})
|
|
|
|
minetest.register_entity(":teleport_beacon", {
|
|
initial_properties = {
|
|
visual = "mesh",
|
|
mesh = "teleport_beacon.gltf",
|
|
textures = {"teleport_beacon.png"},
|
|
use_texture_alpha = true,
|
|
backface_culling = false,
|
|
pointable = false,
|
|
glow = 14
|
|
},
|
|
on_activate = function(e, name)
|
|
if name then e.owner = name end
|
|
if not ns.beacons[e.owner] or ns.beacons[e.owner].marker then
|
|
e.object:remove()
|
|
return
|
|
end
|
|
ns.beacons[e.owner].marker = e.object
|
|
e.object:set_armor_groups{immortal = 1}
|
|
e.object:set_animation({x=1,y=1}, 1.5, 0, false)
|
|
end,
|
|
get_staticdata = function(e)
|
|
return e.owner
|
|
end
|
|
})
|
|
|
|
-- HACK: Override the builtin item to be teleportable, so that
|
|
-- entity teleportation can remain opt-in.
|
|
local def = table.copy(minetest.registered_entities["__builtin:item"])
|
|
def._teleportable = true
|
|
minetest.register_entity(":__builtin:item", def)
|
|
|
|
function ns.do_teleport(from, to, radius)
|
|
for obj in minetest.objects_in_area(from:offset(-radius, -radius, -radius), from:offset(radius, radius, radius)) do
|
|
if obj:is_player() or obj:get_luaentity()._teleportable then
|
|
obj:set_pos(obj:get_pos() -from +to)
|
|
end
|
|
end
|
|
end
|
|
|
|
function ns.begin_teleport(from, to, radius)
|
|
ns.teleports[to:to_string()] = true
|
|
radius = radius or 2.5
|
|
local box1 = minetest.add_entity(from, "teleport_box")
|
|
local box2 = minetest.add_entity(to, "teleport_box")
|
|
box1:set_animation({x=0,y=1.25}, 1, 0, false)
|
|
box2:set_animation({x=0,y=1.25}, 1, 0, false)
|
|
minetest.after(1, function()
|
|
box1:set_animation({x=1.25,y=2.25}, 1, 0, true)
|
|
box2:set_animation({x=1.25,y=2.25}, 1, 0, true)
|
|
end)
|
|
minetest.after(10, function()
|
|
box1:set_animation({x=2.25,y=2.5}, 1, 0, false)
|
|
box2:set_animation({x=2.25,y=2.5}, 1, 0, false)
|
|
minetest.after(0.25, function()
|
|
box1:set_animation({x=2.5,y=2.5}, 1, 0, false)
|
|
box2:set_animation({x=2.5,y=2.5}, 1, 0, false)
|
|
box1:set_properties{use_texture_alpha = false}
|
|
box2:set_properties{use_texture_alpha = false}
|
|
end)
|
|
minetest.after(1, function()
|
|
ns.do_teleport(from, to, radius)
|
|
minetest.after(0.5, function()
|
|
box1:set_animation({x=2.5,y=3}, 1, 0, false)
|
|
box2:set_animation({x=2.5,y=3}, 1, 0, false)
|
|
minetest.after(0.5, function()
|
|
box1:remove()
|
|
box2:remove()
|
|
ns.teleports[to:to_string()] = nil
|
|
end)
|
|
end)
|
|
end)
|
|
end)
|
|
end
|
|
|
|
function ns.place_beacon(name, pos)
|
|
if ns.beacons[name] and ns.beacons[name].marker then
|
|
ns.beacons[name].marker:remove()
|
|
end
|
|
ns.beacons[name] = {
|
|
pos = pos
|
|
}
|
|
local obj = minetest.add_entity(pos, "teleport_beacon", name)
|
|
obj:set_animation({x=0,y=1}, 1.5, 0, false)
|
|
end
|
|
|
|
minetest.register_craftitem(":teleport", {
|
|
inventory_image = "rgt_acacia_planks.png",
|
|
on_place = function(s, p, pt)
|
|
ns.place_beacon(p:get_player_name(), pt.above)
|
|
end,
|
|
on_use = function(s, p, pt)
|
|
local name = p:get_player_name()
|
|
if not pt.above then return end
|
|
if ns.beacons[name] then
|
|
if ns.teleports[ns.beacons[name].pos:to_string()] then
|
|
tell(name, "This destination is currently is use by another spell.")
|
|
else
|
|
ns.begin_teleport(pt.above, ns.beacons[name].pos)
|
|
end
|
|
else
|
|
tell(name, "No beacon placed.")
|
|
end
|
|
end
|
|
})
|