Add teleport spell

This commit is contained in:
Signal 2025-09-18 02:15:24 -04:00
parent eff46f3f3e
commit 71d58a4e48
8 changed files with 143 additions and 4 deletions

2
mods/rgt_misc/init.lua Normal file
View file

@ -0,0 +1,2 @@
include "teleport.lua"

2
mods/rgt_misc/mod.conf Normal file
View file

@ -0,0 +1,2 @@
name = rgt_misc
depends = rgt_player

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

129
mods/rgt_misc/teleport.lua Normal file
View file

@ -0,0 +1,129 @@
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
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 B

View file

@ -49,18 +49,18 @@ Player = {
local pos = m.object:get_pos()
if not pos then return end
m.health_display = minetest.add_entity(pos, "rgt_player:health_display")
m.health_display:set_attach(m.object, nil, vector.new(0, 17, 0))
m.health_display:set_attach(m.object, nil, vector.new(0, 22, 0))
m.health_display:get_luaentity().owner = m
end
local tx = "[combine:90x90"
for i = math.floor(hp /2), math.floor(m.props.hp_max /2) -1 do
tx = tx..":"..(i *9)..",0=rgt_heart_empty.png"
tx = tx..":"..(i *9)..",40=rgt_heart_empty.png"
end
for i = 0, math.floor(hp /2) -1 do
tx = tx..":"..(i *9)..",0=rgt_heart.png"
tx = tx..":"..(i *9)..",40=rgt_heart.png"
end
if hp %2 ~= 0 then
tx = tx..":"..((math.floor(hp /2)) *9)..",0=rgt_heart.png\\^[fill\\:5x9\\:4,0\\:#000\\^[makealpha\\:#000"
tx = tx..":"..((math.floor(hp /2)) *9)..",40=rgt_heart.png\\^[fill\\:5x9\\:4,0\\:#000\\^[makealpha\\:#000"
end
m.health_display:set_properties {
visual = "sprite",
@ -341,8 +341,12 @@ minetest.register_entity("rgt_player:health_display", {
initial_properties = {
visual = "sprite",
textures = {"blank.png"},
pointable = false,
static_save = false
},
on_activate = function(e)
e.object:set_armor_groups{immortal = 1}
end,
on_detach = function(e)
e.object:remove()
end,