simple_waypoints/init.lua

261 lines
7.3 KiB
Lua
Raw Normal View History

2019-12-31 10:12:04 -08:00
-------------- INIT VARIABLES ------------------
2019-03-18 12:32:39 +00:00
local modstorage = minetest.get_mod_storage()
local world_path = minetest.get_worldpath()
local world_name = world_path:match( "([^/]+)$" )
local waypoints = minetest.deserialize(modstorage:get_string(world_name)) or {}
2019-12-31 10:12:04 -08:00
--------------- HELPER FUNCTIONS ---------------
2019-03-18 12:32:39 +00:00
local function save() -- dumps table to modstorage
modstorage:set_string(world_name, minetest.serialize(waypoints))
end
local function getIndexByName(table, n)
for k,v in pairs(table) do
if v.name == n then
return k
else
end
end
end
local function getPosByName(table, n)
for k,v in pairs(table) do
if v.name == n then
return v.pos
else
end
end
end
local function waypointExists(table, n)
for k,v in pairs(table) do
if v.name == n then
return true, "Waypoint exists."
end
end
end
local function validCommandArgs(args)
if type(args) ~= "string" then
invalidInput = "We need a string." return false
elseif string.match (args, "[%W%s]") ~= nil then
invalidInput = "Invalid characters detected." return false
elseif string.len (args) == 0 then
invalidInput = "Please specify a name." return false
else return true
end
end
local function addWaypointHud(player, table)
local wayName = table[#table].name
local wayPos = minetest.string_to_pos(table[#table].pos)
table[#table].hudId = player:hud_add({
hud_elem_type = "waypoint",
name = wayName,
text = "m",
number = 0xFFFFFF,
world_pos = wayPos,
})
end
local function loadWaypointsHud(player, table)
for k,v in pairs(table) do
player:hud_add({
hud_elem_type = "waypoint",
name = v.name,
text = "m",
number = 0xFFFFFF,
world_pos = minetest.string_to_pos(v.pos),
})
end
end
2019-12-31 10:12:04 -08:00
--------------- ON JOIN ------------------
2019-03-18 12:32:39 +00:00
local join = minetest.register_on_joinplayer(function(player)
minetest.after(.5, function()
loadWaypointsHud(player, waypoints)
end)
end)
-------------- NODE DEFINITIONS -----------------
local palette = {"blue", "green", "orange", "pink", "purple", "red", "white", "yellow"}
2019-12-31 10:12:04 -08:00
-- BEACON DEFINITION
2019-03-18 12:32:39 +00:00
for _, color in ipairs(palette) do
minetest.register_node("simple_waypoints:"..color.."_beacon", {
visual_scale = 1.0,
drawtype = "plantlike",
tiles = {"beacon_"..color..".png"},
paramtype = "light",
walkable = false,
diggable = false,
light_source = 13,
groups = {not_in_creative_inventory=1}
})
end
2019-12-31 10:12:04 -08:00
-- BEACON FUNCTIONS
2019-03-18 12:32:39 +00:00
local function placeBeacon(pos)
local random = math.random(1,#palette)
for i=0,50 do
local target_node = minetest.get_node({x=pos.x, y=pos.y+i, z=pos.z})
if target_node.name == "air" then
minetest.add_node({x=pos.x, y=pos.y+i, z=pos.z},
{name="simple_waypoints:"..palette[random].."_beacon"})
end
end
end
local function removeBeacon(pos)
for _,v in ipairs(palette) do
for i=0,50 do
local target_node = minetest.get_node({x=pos.x, y=pos.y+i, z=pos.z})
if target_node.name == "simple_waypoints:"..v.."_beacon" then
minetest.add_node({x=pos.x, y=pos.y+i, z=pos.z}, {name="air"})
end
end
end
end
2019-12-31 10:12:04 -08:00
2019-03-18 12:32:39 +00:00
--------------- CHAT COMMANDS -------------------
-- CREATE WAYPOINT
minetest.register_chatcommand("wc", {
params = "<waypoint_name>",
description = "create a waypoint at current position using a unique name",
privs = {shout = true},
func = function (name, params)
local player = minetest.get_player_by_name(name)
local p_pos = player:get_pos()
local round_pos = vector.round(p_pos)
if waypointExists(waypoints, params) == true then
return true, tostring("Waypoint "..params.." already exists.")
elseif validCommandArgs(params) then
waypoints[#waypoints+1] = { name = params,
pos = minetest.pos_to_string(round_pos) }
addWaypointHud(player, waypoints)
placeBeacon(round_pos)
save()
return true, "Waypoint "..params.." created!"
else
return true, invalidInput
end
end
})
-- DELETE WAYPOINT
minetest.register_chatcommand("wd", {
params = "<waypoint_name>",
description = "Delete a waypoint using its name.",
privs = {shout = true},
func = function(name,params)
local player = minetest.get_player_by_name(name)
local targetIndex = getIndexByName(waypoints, params)
local beaconPos = getPosByName(waypoints, params)
if (validCommandArgs(params) == true and type(targetIndex) == "number") then
removeBeacon(minetest.string_to_pos(beaconPos))
player:hud_remove(waypoints[targetIndex].hudId)
table.remove (waypoints, targetIndex)
save()
return true, "Waypoint deleted."
elseif type(targetIndex) ~= "number" then
return false, "Waypoint "..params.." is invalid or inexistent."
end
end
})
-- LIST WAYPOINTS
minetest.register_chatcommand("wl", {
params = "",
description = "Lists your waypoints.",
privs = {shout = true},
func = function(name)
local player = minetest.get_player_by_name(name)
local p_name = player:get_player_name()
for k,v in pairs(waypoints) do
minetest.chat_send_player(p_name, tostring(k.." "..v.name.." "..v.pos))
end
end
})
-- TELEPORT TO WAYPOINT
minetest.register_chatcommand("wt", {
params = "<waypoint_name>",
description = "Teleports you to a specified waypoint.",
privs = {shout = true},
func = function(name, params)
local player = minetest.get_player_by_name(name)
local p_name = player:get_player_name()
local targetPos = getPosByName(waypoints, params)
if (validCommandArgs(params) == true and type(targetPos) == "string") then
player:set_pos(minetest.string_to_pos(targetPos))
return true, tostring("Teleported "..p_name.." to "..params..".")
elseif type(targetPos) ~= "string" then
return true, tostring("Waypoint "..params.." is invalid or inexistent.")
end
end
})
2019-12-31 10:12:04 -08:00
-- SHOW WAYPOINTS FORMSPEC
minetest.register_chatcommand("wf", {
func = function(name)
waypoints_form.show_to(name)
end,
})
--------------- FORMSPEC -----------------------
local selected
waypoints_form = {}
function waypoints_form.get_formspec(name)
local text = "Waypoints list"
formspec = {
"size[11,14]",
"real_coordinates[true]",
"label[0.375,0.5;", minetest.formspec_escape(text), "]",
"button_exit[8.7,0.75;2,1;teleport;Teleport]",
"button[8.7,1.75;2,1;add;Add]",
"button[8.7,2.75;2,1;remove;Remove]",
"button[8.7,3.75;2,1;rename;Rename]",
}
local f = ""
f = f..
"textlist[0.375,0.75;8,13;waylist"..";"
for i = 1, #waypoints do
f = f..i.." "..minetest.formspec_escape(waypoints[i].name..""..waypoints[i].pos)..","
end
formspec[#formspec+1] = f
return table.concat(formspec, " ")
end
function waypoints_form.show_to(name)
minetest.show_formspec(name, "simple_waypoints:waypoints_form", waypoints_form.get_formspec(name))
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "simple_waypoints:waypoints_form" then
return
elseif fields.waylist then
local event = minetest.explode_textlist_event(fields.waylist)
if(event.type == "CHG") then
selected_idx = event.index
end
elseif fields.teleport then
local pname = player:get_player_name()
if selected_idx == nil then return
else player:set_pos(minetest.string_to_pos(waypoints[selected_idx].pos))
minetest.chat_send_all(pname .. " Teleported to " .. waypoints[selected_idx].name)
selected_idx = nil -- "Teleport" button remembers the last location when you don't select a valid item. This is a reset.
end
end
end)