minetest-teleport_book/init.lua

244 lines
6.5 KiB
Lua
Raw Permalink Normal View History

--= 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")