minetest-teleport_book/init.lua
Jan Andrle c89998d8bb
🎉
Signed-off-by: Jan Andrle <andrle.jan@centrum.cz>
2024-01-30 16:23:53 +01:00

244 lines
6.5 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

--= Teleport Book (paper) mod by jaandrle
--! based on Teleport Potion mod by TenPlus1 (SFX are license free)
--
-- !!! Mainly tested inside LOTT game !!!
-- support for MT game translation.
local S = default.get_translator
-- max teleport distance
local dist = tonumber(minetest.settings:get("map_generation_limit") or 31000)
local function check_coordinates(str)
if not str or str == "" then
return nil
end
-- get coords from string
local x, y, z = string.match(str, "^(-?%d+),(-?%d+),(-?%d+)$")
-- check coords
if x == nil or string.len(x) > 6
or y == nil or string.len(y) > 6
or z == nil or string.len(z) > 6 then
return nil
end
-- convert string coords to numbers
x = tonumber(x)
y = tonumber(y)
z = tonumber(z)
-- are coords in map range ?
if x > dist or x < -dist
or y > dist or y < -dist
or z > dist or z < -dist then
return nil
end
-- return ok coords
return {x = x, y = y, z = z}
end
-- particle effects
local function add_particlespawner(src, teleport_type)
local amount, xz, y, minexptime, maxexptime
local sound_name, max_hear_distance= "teleport", 30
if teleport_type=="teleport_to" then
amount= 100
xz= 0.4
y= 0.3
minexptime= 6
maxexptime= 12
else
amount= 50
xz= 0.2
y= 0.2
minexptime= 3
maxexptime= 4.5
end
minetest.sound_play({name=sound_name, gain=1}, {pos=src, max_hear_distance=max_hear_distance})
minetest.add_particlespawner({
amount= amount,
time= 0.1,
minpos= {x=src.x-0.4, y=src.y+0.25, z=src.z-0.4},
maxpos= {x=src.x+0.4, y=src.y+0.75, z=src.z+0.4},
minvel= {x=-xz, y=-y, z=-xz},
maxvel= {x=xz, y=y, z=xz},
minexptime= minexptime,
maxexptime= maxexptime,
minsize=1,
maxsize=1.25,
texture= "particle.png",
glow= 15
})
end
local teleport_paper_entity = {
physical = true,
visual = "sprite",
visual_size = {x = 1.0, y = 1.0},
textures = {"teleport_paper.png"},
collisionbox = {-0.1,-0.1,-0.1,0.1,0.1,0.1},
lastpos = {},
player = "",
}
teleport_paper_entity.on_step = function(self, dtime)
if not self.player then self.object:remove() return end
local pos = self.object:get_pos()
if self.lastpos.x ~= nil then
local vel = self.object:get_velocity()
-- only when potion hits something physical
if vel.x == 0
or vel.y == 0
or vel.z == 0 then
if self.player ~= "" then
-- round up coords to fix glitching through doors
self.lastpos = vector.round(self.lastpos)
self.player:set_pos(self.lastpos)
add_particlespawner(self.lastpos, "teleport_to")
end
self.object:remove()
return
end
end
self.lastpos = pos
end
minetest.register_entity("teleport_book:teleport_paper_entity", teleport_paper_entity)
local book_writers = {}
minetest.register_on_leaveplayer(function(player)
book_writers[player:get_player_name()] = nil
end)
local name_book= "Teleport book"
local id_book= "teleport_book:book"
minetest.register_craftitem(id_book, {
description= name_book,
inventory_image= "teleport_book.png",
stack_max= 1,
range= 2,
groups= { book= 1 },
on_use= function(itemstack, user)
local meta= itemstack:get_meta()
local dest= minetest.string_to_pos(meta:get_string("_dest"))
local src= user:getpos()
if dest == nil then
meta:set_string("_dest", minetest.pos_to_string(src))
meta:set_int("_usages", math.random(25, 75))
meta:set_string("description", name_book.." for "..minetest.pos_to_string(src, 2))
local player_name = user:get_player_name()
book_writers[player_name] = {wield_index = user:get_wield_index()}
minetest.show_formspec(player_name, id_book,
"size[5,3]" ..
"field[0.25,1.5;4.75,1;name;"..S("Write a description of the book (optional):")..";]" ..
"button_exit[1.5,2;2,1;exit;Save]")
add_particlespawner(src, "teleport_from")
return itemstack
end
local usages= meta:get_int("_usages") - 1
--minetest.chat_send_player(user:get_player_name(), usages)
if usages==1 then
meta:set_string("description",
meta:get_string("description").." almost destroyed!")
end
meta:set_int("_usages", usages)
add_particlespawner(src, "teleport_from")
user:setpos(dest)
add_particlespawner(dest, "teleport_to")
if usages==0 then itemstack:take_item() end
return itemstack
end
})
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= id_book then return end
local player_name = player:get_player_name()
local inv = player:get_inventory()
if not book_writers[player_name] or not fields.name or fields.name == "" then
return
end
local wield_index = book_writers[player_name].wield_index
local wield_list = player:get_wield_list()
local stack = inv:get_stack(wield_list, wield_index)
if stack:get_name() ~= id_book then
-- No book in the wield slot, abort & inform the player
minetest.chat_send_player(player_name, S("The book you were writing to mysteriously disappeared."))
return
end
local meta= stack:get_meta()
meta:set_string("description", name_book .. " " .. fields.name)
inv:set_stack(wield_list, wield_index, stack)
end)
minetest.register_node("teleport_book:paper", {
tiles = {"teleport_paper.png"},
drawtype = "signlike",
paramtype = "light",
paramtype2 = "wallmounted",
walkable = true,
sunlight_propagates = true,
description = "Teleport paper plane",
inventory_image = "teleport_paper.png",
wield_image = "teleport_paper.png",
selection_box = {type = "wallmounted"},
groups= { snappy = 2, flammable = 3, oddly_breakable_by_hand = 3, choppy = 2, carpet = 1 },
after_place_node= function(_1, _2, itemstack)
itemstack:take_item()
return itemstack
end,
on_dig= function(pos, node, player)
minetest.remove_node(pos)
player:get_inventory():add_item("main", "teleport_book:paper")
end,
on_drop= function(itemstack, player)
local playerpos = player:get_pos()
local obj = minetest.add_entity({
x = playerpos.x,
y = playerpos.y + 1.5,
z = playerpos.z
}, "teleport_book:teleport_paper_entity")
local dir = player:get_look_dir()
local velocity = 20
obj:set_velocity({
x = dir.x * velocity,
y = dir.y * velocity,
z = dir.z * velocity
})
obj:set_acceleration({
x = dir.x * -3,
y = -9.5,
z = dir.z * -3
})
obj:set_yaw(player:get_look_horizontal())
obj:get_luaentity().player = player
if math.random(0,6) > 5 then
itemstack:set_count(itemstack:get_count()-1)
end
return itemstack
end,
})
-- Recipes
minetest.register_craft({
output = "teleport_book:paper 27",
recipe = {
{"teleport_book:book"},
},
})
minetest.register_craft({
output = "teleport_book:book",
recipe = {
{"default:mese_crystal"},
{"default:book"},
},
})
print("[MOD] Teleport Book loaded")