Compare commits
10 Commits
493e23d3a8
...
01ad0c80b3
Author | SHA1 | Date | |
---|---|---|---|
|
01ad0c80b3 | ||
|
0a8f1683bc | ||
|
b2d71bf105 | ||
|
81c3bd5bd9 | ||
|
70fedaa536 | ||
|
0a6451608d | ||
|
c8e4942e41 | ||
|
b7fd67c431 | ||
|
37315e72c9 | ||
|
5c24fff8b5 |
16
.luacheckrc
Normal file
16
.luacheckrc
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
read_globals = {
|
||||||
|
"DIR_DELIM",
|
||||||
|
"core",
|
||||||
|
"dump",
|
||||||
|
"vector", "nodeupdate",
|
||||||
|
"VoxelManip", "VoxelArea",
|
||||||
|
"PseudoRandom", "ItemStack",
|
||||||
|
"AreaStore",
|
||||||
|
"default",
|
||||||
|
table = { fields = { "copy", "getn" } }
|
||||||
|
}
|
||||||
|
|
||||||
|
globals = {
|
||||||
|
"minetest"
|
||||||
|
}
|
||||||
|
|
11
README
11
README
@ -11,7 +11,9 @@
|
|||||||
priv: warp_admin - set/change/delete warps
|
priv: warp_admin - set/change/delete warps
|
||||||
priv: warp_user - list, and use warps
|
priv: warp_user - list, and use warps
|
||||||
|
|
||||||
warps are stored in the world folder file "warps.txt".
|
warps are stored in mod_storage. If you had an older version that
|
||||||
|
uses the `warps.txt` file, it will be converted on load, after
|
||||||
|
which the file can be removed.
|
||||||
|
|
||||||
A warpstone can be given or found in the creative inventory (item
|
A warpstone can be given or found in the creative inventory (item
|
||||||
id: warps:warpstone). This warpstone can be placed on the ground
|
id: warps:warpstone). This warpstone can be placed on the ground
|
||||||
@ -22,9 +24,10 @@ warpstone can be removed by shift-punching the warp stone.
|
|||||||
|
|
||||||
All warps are delayed by ~5 seconds. You have to stand still for
|
All warps are delayed by ~5 seconds. You have to stand still for
|
||||||
that duration, otherwise the warp will be cancelled. This may avoid
|
that duration, otherwise the warp will be cancelled. This may avoid
|
||||||
warp spamming and warping out of combat a bit. There's a bit
|
warp spamming and warping out of combat a bit. The mod tries
|
||||||
of variation in time due to the timer resolution in minetest
|
really hard to make sure that the player finds themselves in a
|
||||||
being rather large.
|
loaded area.
|
||||||
|
|
||||||
|
|
||||||
========
|
========
|
||||||
|
|
||||||
|
@ -1 +0,0 @@
|
|||||||
default
|
|
@ -1 +0,0 @@
|
|||||||
Warp locations and warp stones (portal stones)
|
|
166
init.lua
166
init.lua
@ -10,14 +10,54 @@ of the license, or (at your option) any later version.
|
|||||||
|
|
||||||
--]]
|
--]]
|
||||||
|
|
||||||
warps = {}
|
local warps = {}
|
||||||
warps_queue = {}
|
local warps_queue = {}
|
||||||
queue_state = 0
|
local queue_state = 0
|
||||||
local warps_freeze = 5
|
local warps_freeze = 5
|
||||||
-- t = time in usec
|
-- t = time in usec
|
||||||
-- p = player obj
|
-- p = player obj
|
||||||
-- w = warp name
|
-- w = warp name
|
||||||
|
|
||||||
|
local S = minetest.get_mod_storage()
|
||||||
|
assert(S, "mod_storage is required")
|
||||||
|
|
||||||
|
-- import warps or load
|
||||||
|
local function firstload()
|
||||||
|
local store = S:get("warps")
|
||||||
|
local worldpath = minetest.get_worldpath()
|
||||||
|
if store then
|
||||||
|
warps = minetest.deserialize(store)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local fh,err = io.open(worldpath .. "/warps.txt", "r")
|
||||||
|
if err then
|
||||||
|
-- If it doesn't exist, we've never used this mod before.
|
||||||
|
if not err:find("No such file or directory") then
|
||||||
|
minetest.log("error", "[warps] Error trying to load warps.txt: " .. err)
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
while true do
|
||||||
|
local line = fh:read()
|
||||||
|
if line == nil then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
local paramlist = string.split(line, " ")
|
||||||
|
local w = {
|
||||||
|
name = paramlist[1],
|
||||||
|
x = tonumber(paramlist[2]),
|
||||||
|
y = tonumber(paramlist[3]),
|
||||||
|
z = tonumber(paramlist[4]),
|
||||||
|
yaw = tonumber(paramlist[5]),
|
||||||
|
pitch = tonumber(paramlist[6])
|
||||||
|
}
|
||||||
|
table.insert(warps, w)
|
||||||
|
end
|
||||||
|
fh:close()
|
||||||
|
minetest.log("action", "[warps] converted warps to mod_storage. Please delete 'warps.txt'.")
|
||||||
|
S:set_string("warps", minetest.serialize(warps))
|
||||||
|
end
|
||||||
|
|
||||||
local function lookup_warp(name)
|
local function lookup_warp(name)
|
||||||
for i = 1,table.getn(warps) do
|
for i = 1,table.getn(warps) do
|
||||||
if warps[i].name == name then
|
if warps[i].name == name then
|
||||||
@ -47,7 +87,7 @@ local warp = function(player, dest)
|
|||||||
|
|
||||||
local pos = vector.new(warp)
|
local pos = vector.new(warp)
|
||||||
pos.y = pos.y + 0.5
|
pos.y = pos.y + 0.5
|
||||||
player:setpos(pos)
|
player:set_pos(pos)
|
||||||
player:set_look_horizontal(warp.yaw)
|
player:set_look_horizontal(warp.yaw)
|
||||||
player:set_look_vertical(warp.pitch)
|
player:set_look_vertical(warp.pitch)
|
||||||
minetest.chat_send_player(player:get_player_name(), "Warped to \"" .. dest .. "\"")
|
minetest.chat_send_player(player:get_player_name(), "Warped to \"" .. dest .. "\"")
|
||||||
@ -55,7 +95,7 @@ local warp = function(player, dest)
|
|||||||
minetest.sound_play("warps_plop", {pos = pos})
|
minetest.sound_play("warps_plop", {pos = pos})
|
||||||
end
|
end
|
||||||
|
|
||||||
do_warp_queue = function()
|
local function do_warp_queue()
|
||||||
if table.getn(warps_queue) == 0 then
|
if table.getn(warps_queue) == 0 then
|
||||||
queue_state = 0
|
queue_state = 0
|
||||||
return
|
return
|
||||||
@ -63,8 +103,8 @@ do_warp_queue = function()
|
|||||||
local t = minetest.get_us_time()
|
local t = minetest.get_us_time()
|
||||||
for i = table.getn(warps_queue),1,-1 do
|
for i = table.getn(warps_queue),1,-1 do
|
||||||
local e = warps_queue[i]
|
local e = warps_queue[i]
|
||||||
if e.p:getpos() then
|
if e.p:get_pos() then
|
||||||
if vector.equals(e.p:getpos(), e.pos) then
|
if vector.equals(e.p:get_pos(), e.pos) then
|
||||||
if t > e.t then
|
if t > e.t then
|
||||||
warp(e.p, e.w)
|
warp(e.p, e.w)
|
||||||
table.remove(warps_queue, i)
|
table.remove(warps_queue, i)
|
||||||
@ -87,10 +127,10 @@ end
|
|||||||
local warp_queue_add = function(player, dest)
|
local warp_queue_add = function(player, dest)
|
||||||
table.insert(warps_queue, {
|
table.insert(warps_queue, {
|
||||||
t = minetest.get_us_time() + (warps_freeze * 1000000),
|
t = minetest.get_us_time() + (warps_freeze * 1000000),
|
||||||
pos = player:getpos(),
|
pos = player:get_pos(),
|
||||||
p = player,
|
p = player,
|
||||||
w = dest,
|
w = dest,
|
||||||
sh = minetest.sound_play("warps_woosh", { pos = player:getpos() })
|
sh = minetest.sound_play("warps_woosh", { pos = player:get_pos() })
|
||||||
})
|
})
|
||||||
minetest.chat_send_player(player:get_player_name(), "Don't move for " .. warps_freeze .. " seconds!")
|
minetest.chat_send_player(player:get_player_name(), "Don't move for " .. warps_freeze .. " seconds!")
|
||||||
if queue_state == 0 then
|
if queue_state == 0 then
|
||||||
@ -103,48 +143,10 @@ local warp_queue_add = function(player, dest)
|
|||||||
if not minetest.get_node_or_nil(pos) then
|
if not minetest.get_node_or_nil(pos) then
|
||||||
minetest.emerge_area(vector.subtract(pos, 80), vector.add(pos, 80))
|
minetest.emerge_area(vector.subtract(pos, 80), vector.add(pos, 80))
|
||||||
end
|
end
|
||||||
end
|
-- force mapblock send to player, if supported
|
||||||
|
if player.send_mapblock then
|
||||||
local worldpath = minetest.get_worldpath()
|
player:send_mapblock(vector.divide(pos, 16))
|
||||||
|
|
||||||
local save = function ()
|
|
||||||
local fh,err = io.open(worldpath .. "/warps.txt", "w")
|
|
||||||
if err then
|
|
||||||
print("No existing warps to read.")
|
|
||||||
return
|
|
||||||
end
|
end
|
||||||
for i = 1,table.getn(warps) do
|
|
||||||
local s = warps[i].name .. " " .. warps[i].x .. " " .. warps[i].y .. " " ..
|
|
||||||
warps[i].z .. " " .. warps[i].yaw .. " " .. warps[i].pitch .. "\n"
|
|
||||||
fh:write(s)
|
|
||||||
end
|
|
||||||
fh:close()
|
|
||||||
end
|
|
||||||
|
|
||||||
local load = function ()
|
|
||||||
local fh,err = io.open(worldpath .. "/warps.txt", "r")
|
|
||||||
if err then
|
|
||||||
minetest.log("action", "[warps] loaded ")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
while true do
|
|
||||||
local line = fh:read()
|
|
||||||
if line == nil then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
local paramlist = string.split(line, " ")
|
|
||||||
local w = {
|
|
||||||
name = paramlist[1],
|
|
||||||
x = tonumber(paramlist[2]),
|
|
||||||
y = tonumber(paramlist[3]),
|
|
||||||
z = tonumber(paramlist[4]),
|
|
||||||
yaw = tonumber(paramlist[5]),
|
|
||||||
pitch = tonumber(paramlist[6])
|
|
||||||
}
|
|
||||||
table.insert(warps, w)
|
|
||||||
end
|
|
||||||
fh:close()
|
|
||||||
minetest.log("action", "[warps] loaded " .. table.getn(warps) .. " warp location(s)")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_privilege("warp_admin", {
|
minetest.register_privilege("warp_admin", {
|
||||||
@ -179,7 +181,7 @@ minetest.register_chatcommand("setwarp", {
|
|||||||
end
|
end
|
||||||
|
|
||||||
local player = minetest.get_player_by_name(name)
|
local player = minetest.get_player_by_name(name)
|
||||||
local pos = vector.round(player:getpos())
|
local pos = vector.round(player:get_pos())
|
||||||
table.insert(warps, {
|
table.insert(warps, {
|
||||||
name = param,
|
name = param,
|
||||||
x = pos.x,
|
x = pos.x,
|
||||||
@ -188,7 +190,7 @@ minetest.register_chatcommand("setwarp", {
|
|||||||
yaw = round_digits(player:get_look_horizontal(), 3),
|
yaw = round_digits(player:get_look_horizontal(), 3),
|
||||||
pitch = round_digits(player:get_look_vertical(), 3)
|
pitch = round_digits(player:get_look_vertical(), 3)
|
||||||
})
|
})
|
||||||
save()
|
S:set_string("warps", minetest.serialize(warps))
|
||||||
|
|
||||||
minetest.log("action", name .. " " .. h .. " warp \"" .. param .. "\": " ..
|
minetest.log("action", name .. " " .. h .. " warp \"" .. param .. "\": " ..
|
||||||
pos.x .. ", " .. pos.y .. ", " .. pos.z)
|
pos.x .. ", " .. pos.y .. ", " .. pos.z)
|
||||||
@ -239,6 +241,32 @@ minetest.register_chatcommand("warp", {
|
|||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
|
local function prepare_dropdown(x,y,w,h,curr_dest)
|
||||||
|
local dd = string.format("dropdown[%f,%f;%f,%f;ddwarp;", x, y, w, h)
|
||||||
|
local sel = 0
|
||||||
|
for idx, warp in ipairs(warps) do
|
||||||
|
local warpname = warp.name
|
||||||
|
dd = dd .. minetest.formspec_escape(warpname) .. ","
|
||||||
|
if curr_dest == warpname then
|
||||||
|
sel = idx
|
||||||
|
end
|
||||||
|
end
|
||||||
|
dd = dd .. ";"..tostring(sel).."]"
|
||||||
|
return dd
|
||||||
|
end
|
||||||
|
|
||||||
|
local function prepare_formspec(dest)
|
||||||
|
local custdest = ""
|
||||||
|
if not lookup_warp(dest) then
|
||||||
|
custdest = dest
|
||||||
|
end
|
||||||
|
return "size[4.5,3]label[0.7,0;Warp destination]"
|
||||||
|
.."field[1,2.2;3,0.2;destination;Future destination;"
|
||||||
|
..minetest.formspec_escape(custdest).."]"
|
||||||
|
.."button_exit[0.7,2.7;3,0.5;proceed;Proceed]"
|
||||||
|
..prepare_dropdown(0.7,0.4,3,1, dest)
|
||||||
|
end
|
||||||
|
|
||||||
minetest.register_node("warps:warpstone", {
|
minetest.register_node("warps:warpstone", {
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "warps_warpstone.obj",
|
mesh = "warps_warpstone.obj",
|
||||||
@ -250,14 +278,14 @@ minetest.register_node("warps:warpstone", {
|
|||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
groups = { choppy=3 },
|
groups = { choppy=3 },
|
||||||
light_source = 8,
|
light_source = 8,
|
||||||
|
diggable = false,
|
||||||
selection_box = {
|
selection_box = {
|
||||||
type = "fixed",
|
type = "fixed",
|
||||||
fixed = {-0.25, -0.5, -0.25, 0.25, 0.5, 0.25}
|
fixed = {-0.25, -0.5, -0.25, 0.25, 0.5, 0.25}
|
||||||
},
|
},
|
||||||
on_construct = function(pos)
|
on_construct = function(pos)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
meta:set_string("formspec",
|
meta:set_string("formspec", prepare_formspec(""))
|
||||||
"field[destination;Warp Destination;]")
|
|
||||||
meta:set_string("infotext", "Uninitialized Warp Stone")
|
meta:set_string("infotext", "Uninitialized Warp Stone")
|
||||||
end,
|
end,
|
||||||
on_receive_fields = function(pos, formname, fields, sender)
|
on_receive_fields = function(pos, formname, fields, sender)
|
||||||
@ -265,15 +293,24 @@ minetest.register_node("warps:warpstone", {
|
|||||||
minetest.chat_send_player(sender:get_player_name(), "You do not have permission to modify warp stones")
|
minetest.chat_send_player(sender:get_player_name(), "You do not have permission to modify warp stones")
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
if not fields.destination then
|
if not (fields.destination and fields.quit) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local dest
|
||||||
|
if fields.destination == "" and fields.ddwarp then
|
||||||
|
dest = fields.ddwarp
|
||||||
|
else
|
||||||
|
dest = fields.destination
|
||||||
|
end
|
||||||
|
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
meta:set_string("formspec",
|
|
||||||
"field[destination;Warp Destination;" .. fields.destination .. "]")
|
meta:set_string("formspec", prepare_formspec(dest))
|
||||||
meta:set_string("infotext", "Warp stone to " .. fields.destination)
|
meta:set_string("infotext", "Warp stone to " .. dest)
|
||||||
meta:set_string("warps_destination", fields.destination)
|
meta:set_string("warps_destination", dest)
|
||||||
minetest.log("action", sender:get_player_name() .. " changed warp stone to \"" .. fields.destination .. "\"")
|
minetest.log("action", sender:get_player_name() .. " changed warp stone at "
|
||||||
|
.. minetest.pos_to_string(pos) .. " to \"" .. dest .. "\"")
|
||||||
end,
|
end,
|
||||||
on_punch = function(pos, node, puncher, pointed_thingo)
|
on_punch = function(pos, node, puncher, pointed_thingo)
|
||||||
if puncher:get_player_control().sneak and
|
if puncher:get_player_control().sneak and
|
||||||
@ -285,15 +322,16 @@ minetest.register_node("warps:warpstone", {
|
|||||||
|
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
local destination = meta:get_string("warps_destination")
|
local destination = meta:get_string("warps_destination")
|
||||||
if destination == "" then
|
if destination == "" or lookup_warp(destination) == nil then
|
||||||
minetest.chat_send_player(puncher:get_player_name(),
|
minetest.chat_send_player(puncher:get_player_name(),
|
||||||
"Unknown warp location for this warp stone, cannot warp!")
|
"Unknown warp location for this warp stone, cannot warp!")
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
minetest.log("action", string.format("Going to warp player %s to waypoint %s",
|
||||||
|
puncher:get_player_name(), destination
|
||||||
|
))
|
||||||
warp_queue_add(puncher, destination)
|
warp_queue_add(puncher, destination)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
-- load existing warps
|
firstload()
|
||||||
load()
|
|
||||||
|
|
||||||
|
1
mod.conf
1
mod.conf
@ -1 +1,2 @@
|
|||||||
name = warps
|
name = warps
|
||||||
|
description = Warp locations and warp stones (portal stones)
|
||||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user