Fix errors under 5.x and allow selecting warps from a dropdown (#5)

- Loading would previously fail if there was both no data in mod_storage "warps" and no warps.txt
- A wrong variable used while adding the warp queue was causing crashes when attempting to warp
- Don't even attempt to teleport to a warp spot that doesn't exit
- Allow selecting warps from a dropdown for ease of use, but still allow text input as warps might be created later than the warp crystals are created (negotiable, invalid input could be dropped and only the combobox allowed if others object).
This commit is contained in:
Montandalar 2021-02-17 08:07:09 +11:00 committed by GitHub
parent 81c3bd5bd9
commit b2d71bf105
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 79 additions and 20 deletions

16
.luacheckrc Normal file
View 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"
}

View File

@ -10,9 +10,9 @@ 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
@ -22,14 +22,19 @@ local S = minetest.get_mod_storage()
assert(S, "mod_storage is required") assert(S, "mod_storage is required")
-- import warps or load -- import warps or load
local store = S:get("warps") local function firstload()
local worldpath = minetest.get_worldpath() local store = S:get("warps")
if store then local worldpath = minetest.get_worldpath()
warps = minetest.deserialize(store) if store then
else warps = minetest.deserialize(store)
return
end
local fh,err = io.open(worldpath .. "/warps.txt", "r") local fh,err = io.open(worldpath .. "/warps.txt", "r")
if err then if err then
minetest.log("action", "[warps] loaded ") -- 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 return
end end
while true do while true do
@ -90,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
@ -140,7 +145,7 @@ local warp_queue_add = function(player, dest)
end end
-- force mapblock send to player, if supported -- force mapblock send to player, if supported
if player.send_mapblock then if player.send_mapblock then
player:send_mapblock(vector.divide(dest, 16)) player:send_mapblock(vector.divide(pos, 16))
end end
end end
@ -236,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",
@ -254,8 +285,7 @@ minetest.register_node("warps:warpstone", {
}, },
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)
@ -263,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
@ -283,12 +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,
}) })
firstload()