Make CSM standalone and add new features.
The CSM is now standalone on Minetest 5.0.0 and later, and new features from the server side mod have been backported.master
parent
0f4bdfe805
commit
405ebac2fb
19
README.md
19
README.md
|
@ -2,20 +2,20 @@
|
|||
|
||||
## Warning
|
||||
|
||||
This is mostly useless now, as this requires a `/mrkr` command to exist on the
|
||||
server. You probably want the (nicer)
|
||||
[non-CSM](https://git.minetest.land/luk3yx/advmarkers) mod. *This CSM does not
|
||||
co-operate with the server-side mod except for the fact that it provides a
|
||||
`/mrkr` command, if you play on a server with the server-side mod you don't
|
||||
need this.*
|
||||
This is mostly useless if you use Minetest 0.4, as without the CSM HUD API this
|
||||
CSM requires a `/mrkr` command to exist on the server. You probably want the
|
||||
(nicer) [non-CSM](https://git.minetest.land/luk3yx/advmarkers) mod instead.
|
||||
|
||||
*This CSM does not co-operate with the server-side mod except for the fact that
|
||||
it provides a `/mrkr` command, if you play on a server with the server-side mod
|
||||
you don't need this.*
|
||||
|
||||
## Original README
|
||||
|
||||
A marker/waypoint CSM for Minetest, designed for use with the (now-defunct) marker mod.
|
||||
|
||||
To display markers, the server currently needs the advmarkers server-side mod (or the marker mod) installed,
|
||||
otherwise "command not found" errors will be displayed, as CSMs cannot currently
|
||||
create HUDs on their own.
|
||||
This CSM works by itself on Minetest 5.0.0+, and with the server-side mod
|
||||
installed on Minetest 0.4.
|
||||
|
||||
## How to use
|
||||
|
||||
|
@ -28,6 +28,7 @@ create HUDs on their own.
|
|||
- `.mrkr_upload`: Uploads your markers to your current server's advmarkers
|
||||
[server-side mod].
|
||||
- `.mrkrthere`: Sets a marker at the last `.coords` position.
|
||||
- `.clrmrkr`: Hides the currently displayed waypoint.
|
||||
|
||||
If you die, a marker is automatically added at your death position, and will
|
||||
update the last `.coords` position.
|
||||
|
|
260
init.lua
260
init.lua
|
@ -30,50 +30,78 @@ local function string_to_pos(pos)
|
|||
end
|
||||
|
||||
-- Set the HUD position
|
||||
-- TODO: Make this entirely client-side or allow the command to be changed.
|
||||
function advmarkers.set_hud_pos(pos)
|
||||
local hud_id
|
||||
function advmarkers.set_hud_pos(pos, title)
|
||||
pos = string_to_pos(pos)
|
||||
if not pos then return end
|
||||
minetest.run_server_chatcommand('mrkr', tostring(pos.x) .. ' ' ..
|
||||
tostring(pos.y) .. ' ' .. tostring(pos.z))
|
||||
|
||||
-- Fall back to /mrkr if hud_add doesn't exist (Minetest 0.4).
|
||||
if not minetest.localplayer or not minetest.localplayer.hud_add or
|
||||
not minetest.localplayer.hud_change then
|
||||
minetest.run_server_chatcommand('mrkr', tostring(pos.x) .. ' ' ..
|
||||
tostring(pos.y) .. ' ' .. tostring(pos.z))
|
||||
end
|
||||
|
||||
if not title then
|
||||
title = pos.x .. ', ' .. pos.y .. ', ' .. pos.z
|
||||
end
|
||||
if hud_id then
|
||||
minetest.localplayer:hud_change(hud_id, 'name', title)
|
||||
minetest.localplayer:hud_change(hud_id, 'world_pos', pos)
|
||||
else
|
||||
hud_id = minetest.localplayer:hud_add({
|
||||
hud_elem_type = 'waypoint',
|
||||
name = title,
|
||||
text = 'm',
|
||||
number = 0x00ffff,
|
||||
world_pos = pos
|
||||
})
|
||||
end
|
||||
minetest.display_chat_message('Waypoint set to ' ..
|
||||
minetest.colorize('#00ffff', title))
|
||||
return true
|
||||
end
|
||||
|
||||
-- Add a marker
|
||||
function advmarkers.set_marker(pos, name)
|
||||
-- Add a waypoint
|
||||
function advmarkers.set_waypoint(pos, name)
|
||||
pos = pos_to_string(pos)
|
||||
if not pos then return end
|
||||
storage:set_string('marker-' .. tostring(name), pos)
|
||||
return true
|
||||
end
|
||||
advmarkers.set_marker = advmarkers.set_waypoint
|
||||
|
||||
-- Delete a marker
|
||||
function advmarkers.delete_marker(name)
|
||||
-- Delete a waypoint
|
||||
function advmarkers.delete_waypoint(name)
|
||||
storage:set_string('marker-' .. tostring(name), '')
|
||||
end
|
||||
advmarkers.delete_marker = advmarkers.delete_waypoint
|
||||
|
||||
-- Get a marker
|
||||
function advmarkers.get_marker(name)
|
||||
-- Get a waypoint
|
||||
function advmarkers.get_waypoint(name)
|
||||
return string_to_pos(storage:get_string('marker-' .. tostring(name)))
|
||||
end
|
||||
advmarkers.get_marker = advmarkers.get_waypoint
|
||||
|
||||
-- Rename a marker and re-interpret the position.
|
||||
function advmarkers.rename_marker(oldname, newname)
|
||||
-- Rename a waypoint and re-interpret the position.
|
||||
function advmarkers.rename_waypoint(oldname, newname)
|
||||
oldname, newname = tostring(oldname), tostring(newname)
|
||||
local pos = advmarkers.get_marker(oldname)
|
||||
if not pos or not advmarkers.set_marker(pos, newname) then return end
|
||||
local pos = advmarkers.get_waypoint(oldname)
|
||||
if not pos or not advmarkers.set_waypoint(pos, newname) then return end
|
||||
if oldname ~= newname then
|
||||
advmarkers.delete_marker(oldname)
|
||||
advmarkers.delete_waypoint(oldname)
|
||||
end
|
||||
return true
|
||||
end
|
||||
advmarkers.rename_marker = advmarkers.rename_waypoint
|
||||
|
||||
-- Display a marker
|
||||
function advmarkers.display_marker(name)
|
||||
return advmarkers.set_hud_pos(advmarkers.get_marker(name))
|
||||
-- Display a waypoint
|
||||
function advmarkers.display_waypoint(name)
|
||||
return advmarkers.set_hud_pos(advmarkers.get_waypoint(name), name)
|
||||
end
|
||||
advmarkers.display_marker = advmarkers.display_waypoint
|
||||
|
||||
-- Export markers
|
||||
-- Export waypoints
|
||||
function advmarkers.export(raw)
|
||||
local s = storage:to_table().fields
|
||||
if raw == 'M' then
|
||||
|
@ -86,7 +114,7 @@ function advmarkers.export(raw)
|
|||
return s
|
||||
end
|
||||
|
||||
-- Import markers
|
||||
-- Import waypoints
|
||||
function advmarkers.import(s)
|
||||
if type(s) ~= 'table' then
|
||||
local ver = s:sub(1, 1)
|
||||
|
@ -101,7 +129,7 @@ function advmarkers.import(s)
|
|||
end
|
||||
end
|
||||
|
||||
-- Iterate over markers to preserve existing ones and check for errors.
|
||||
-- Iterate over waypoints to preserve existing ones and check for errors.
|
||||
if type(s) == 'table' then
|
||||
for name, pos in pairs(s) do
|
||||
if type(name) == 'string' and type(pos) == 'string' and
|
||||
|
@ -124,92 +152,126 @@ function advmarkers.import(s)
|
|||
end
|
||||
end
|
||||
|
||||
-- Get the markers formspec
|
||||
-- Get the waypoints formspec
|
||||
local formspec_list = {}
|
||||
local selected_name = false
|
||||
function advmarkers.display_formspec()
|
||||
local formspec = 'size[5.25,8]' ..
|
||||
'label[0,0;Marker list]' ..
|
||||
'label[0,0;Waypoint list]' ..
|
||||
'button_exit[0,7.5;1.3125,0.5;display;Display]' ..
|
||||
'button[1.3125,7.5;1.3125,0.5;teleport;Teleport]' ..
|
||||
'button[2.625,7.5;1.3125,0.5;rename;Rename]' ..
|
||||
'button[3.9375,7.5;1.3125,0.5;delete;Delete]' ..
|
||||
'textlist[0,0.75;5,6;marker;'
|
||||
|
||||
-- Iterate over all the markers
|
||||
local id = 0
|
||||
-- Iterate over all the waypoints
|
||||
local selected = 1
|
||||
formspec_list = {}
|
||||
for name, pos in pairs(storage:to_table().fields) do
|
||||
|
||||
local waypoints = {}
|
||||
for name, _ in pairs(storage:to_table().fields) do
|
||||
if name:sub(1, 7) == 'marker-' then
|
||||
id = id + 1
|
||||
if id > 1 then
|
||||
formspec = formspec .. ','
|
||||
end
|
||||
name = name:sub(8)
|
||||
if not selected_name then
|
||||
selected_name = name
|
||||
end
|
||||
if name == selected_name then
|
||||
selected = id
|
||||
end
|
||||
formspec_list[#formspec_list + 1] = name
|
||||
formspec = formspec .. '##' .. minetest.formspec_escape(name)
|
||||
table.insert(waypoints, name:sub(8))
|
||||
end
|
||||
end
|
||||
table.sort(waypoints)
|
||||
|
||||
-- Close the text list and display the selected marker position
|
||||
for id, name in ipairs(waypoints) do
|
||||
if id > 1 then
|
||||
formspec = formspec .. ','
|
||||
end
|
||||
if not selected_name then
|
||||
selected_name = name
|
||||
end
|
||||
if name == selected_name then
|
||||
selected = id
|
||||
end
|
||||
formspec_list[#formspec_list + 1] = name
|
||||
formspec = formspec .. '##' .. minetest.formspec_escape(name)
|
||||
end
|
||||
|
||||
-- Close the text list and display the selected waypoint position
|
||||
formspec = formspec .. ';' .. tostring(selected) .. ']'
|
||||
if selected_name then
|
||||
local pos = advmarkers.get_marker(selected_name)
|
||||
local pos = advmarkers.get_waypoint(selected_name)
|
||||
if pos then
|
||||
pos = minetest.formspec_escape(tostring(pos.x) .. ', ' ..
|
||||
tostring(pos.y) .. ', ' .. tostring(pos.z))
|
||||
pos = 'Marker position: ' .. pos
|
||||
pos = 'Waypoint position: ' .. pos
|
||||
formspec = formspec .. 'label[0,6.75;' .. pos .. ']'
|
||||
end
|
||||
else
|
||||
-- Draw over the buttons
|
||||
formspec = formspec .. 'button_exit[0,7.5;5.25,0.5;quit;Close dialog]' ..
|
||||
'label[0,6.75;No markers. Add one with ".add_mrkr".]'
|
||||
'label[0,6.75;No waypoints. Add one with ".add_mrkr".]'
|
||||
end
|
||||
|
||||
-- Display the formspec
|
||||
return minetest.show_formspec('advmarkers-csm', formspec)
|
||||
end
|
||||
|
||||
-- Open the markers GUI
|
||||
function advmarkers.get_chatcommand_pos(pos)
|
||||
if pos == 'h' or pos == 'here' then
|
||||
pos = minetest.localplayer:get_pos()
|
||||
elseif pos == 't' or pos == 'there' then
|
||||
if not advmarkers.last_coords then
|
||||
return false, 'No-one has used ".coords" and you have not died!'
|
||||
end
|
||||
pos = advmarkers.last_coords
|
||||
else
|
||||
pos = string_to_pos(pos)
|
||||
if not pos then
|
||||
return false, 'Invalid position!'
|
||||
end
|
||||
end
|
||||
return pos
|
||||
end
|
||||
|
||||
local function register_chatcommand_alias(old, ...)
|
||||
local def = assert(minetest.registered_chatcommands[old])
|
||||
def.name = nil
|
||||
for i = 1, select('#', ...) do
|
||||
minetest.register_chatcommand(select(i, ...), table.copy(def))
|
||||
end
|
||||
end
|
||||
|
||||
-- Open the waypoints GUI
|
||||
minetest.register_chatcommand('mrkr', {
|
||||
params = '',
|
||||
description = 'Open the advmarkers GUI',
|
||||
func = advmarkers.display_formspec
|
||||
func = function(param)
|
||||
if param == '' then
|
||||
advmarkers.display_formspec()
|
||||
else
|
||||
local pos, err = advmarkers.get_chatcommand_pos(param)
|
||||
if not pos then
|
||||
return false, err
|
||||
end
|
||||
if not advmarkers.set_hud_pos(pos) then
|
||||
return false, 'Error setting the waypoint!'
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
-- Add a marker
|
||||
register_chatcommand_alias('mrkr', 'wp', 'wps', 'waypoint', 'waypoints')
|
||||
|
||||
-- Add a waypoint
|
||||
minetest.register_chatcommand('add_mrkr', {
|
||||
params = '<pos / "here" / "there"> <name>',
|
||||
description = 'Adds a marker.',
|
||||
description = 'Adds a waypoint.',
|
||||
func = function(param)
|
||||
local s, e = param:find(' ')
|
||||
if not s or not e then
|
||||
return false, 'Invalid syntax! See .help add_mrkr for more info.'
|
||||
end
|
||||
local pos = param:sub(1, s - 1)
|
||||
local pos = param:sub(1, s - 1)
|
||||
local name = param:sub(e + 1)
|
||||
|
||||
-- Validate the position
|
||||
if pos == 'here' then
|
||||
pos = minetest.localplayer:get_pos()
|
||||
elseif pos == 'there' then
|
||||
if not advmarkers.last_coords then
|
||||
return false, 'No-one has used ".coords" and you have not died!'
|
||||
end
|
||||
pos = advmarkers.last_coords
|
||||
else
|
||||
pos = string_to_pos(pos)
|
||||
if not pos then
|
||||
return false, 'Invalid position!'
|
||||
end
|
||||
local pos, err = advmarkers.get_chatcommand_pos(pos)
|
||||
if not pos then
|
||||
return false, err
|
||||
end
|
||||
|
||||
-- Validate the name
|
||||
|
@ -217,11 +279,13 @@ minetest.register_chatcommand('add_mrkr', {
|
|||
return false, 'Invalid name!'
|
||||
end
|
||||
|
||||
-- Set the marker
|
||||
return advmarkers.set_marker(pos, name), 'Done!'
|
||||
-- Set the waypoint
|
||||
return advmarkers.set_waypoint(pos, name), 'Done!'
|
||||
end
|
||||
})
|
||||
|
||||
register_chatcommand_alias('add_mrkr', 'add_wp', 'add_waypoint')
|
||||
|
||||
-- Set the HUD
|
||||
minetest.register_on_formspec_input(function(formname, fields)
|
||||
if formname == 'advmarkers-ignore' then
|
||||
|
@ -241,22 +305,22 @@ minetest.register_on_formspec_input(function(formname, fields)
|
|||
|
||||
if name then
|
||||
if fields.display then
|
||||
if not advmarkers.display_marker(name) then
|
||||
minetest.display_chat_message('Error displaying marker!')
|
||||
if not advmarkers.display_waypoint(name) then
|
||||
minetest.display_chat_message('Error displaying waypoint!')
|
||||
end
|
||||
elseif fields.rename then
|
||||
minetest.show_formspec('advmarkers-csm', 'size[6,3]' ..
|
||||
'label[0.35,0.2;Rename marker]' ..
|
||||
'label[0.35,0.2;Rename waypoint]' ..
|
||||
'field[0.3,1.3;6,1;new_name;New name;' ..
|
||||
minetest.formspec_escape(name) .. ']' ..
|
||||
'button[0,2;3,1;cancel;Cancel]' ..
|
||||
'button[3,2;3,1;rename_confirm;Rename]')
|
||||
elseif fields.rename_confirm then
|
||||
if fields.new_name and #fields.new_name > 0 then
|
||||
if advmarkers.rename_marker(name, fields.new_name) then
|
||||
if advmarkers.rename_waypoint(name, fields.new_name) then
|
||||
selected_name = fields.new_name
|
||||
else
|
||||
minetest.display_chat_message('Error renaming marker!')
|
||||
minetest.display_chat_message('Error renaming waypoint!')
|
||||
end
|
||||
advmarkers.display_formspec()
|
||||
else
|
||||
|
@ -267,7 +331,7 @@ minetest.register_on_formspec_input(function(formname, fields)
|
|||
elseif fields.teleport then
|
||||
minetest.show_formspec('advmarkers-csm', 'size[6,2.2]' ..
|
||||
'label[0.35,0.25;' .. minetest.formspec_escape(
|
||||
'Teleport to a marker\n - ' .. name
|
||||
'Teleport to a waypoint\n - ' .. name
|
||||
) .. ']' ..
|
||||
'button[0,1.25;2,1;cancel;Cancel]' ..
|
||||
'button_exit[2,1.25;1,1;teleport_tpj;/tpj]' ..
|
||||
|
@ -275,7 +339,7 @@ minetest.register_on_formspec_input(function(formname, fields)
|
|||
'button_exit[4,1.25;2,1;teleport_confirm;/teleport]')
|
||||
elseif fields.teleport_tpj then
|
||||
-- Teleport with /tpj
|
||||
local pos = advmarkers.get_marker(name)
|
||||
local pos = advmarkers.get_waypoint(name)
|
||||
if pos and minetest.localplayer then
|
||||
local cpos = minetest.localplayer:get_pos()
|
||||
for _, dir in ipairs({'x', 'y', 'z'}) do
|
||||
|
@ -284,11 +348,11 @@ minetest.register_on_formspec_input(function(formname, fields)
|
|||
tostring(distance))
|
||||
end
|
||||
else
|
||||
minetest.display_chat_message('Error teleporting to marker!')
|
||||
minetest.display_chat_message('Error teleporting to waypoint!')
|
||||
end
|
||||
elseif fields.teleport_confirm or fields.teleport_tpc then
|
||||
-- Teleport with /teleport
|
||||
local pos = advmarkers.get_marker(name)
|
||||
local pos = advmarkers.get_waypoint(name)
|
||||
local cmd
|
||||
if fields.teleport_confirm then
|
||||
cmd = 'teleport'
|
||||
|
@ -299,15 +363,15 @@ minetest.register_on_formspec_input(function(formname, fields)
|
|||
minetest.run_server_chatcommand(cmd,
|
||||
pos.x .. ',' .. pos.y .. ',' .. pos.z)
|
||||
else
|
||||
minetest.display_chat_message('Error teleporting to marker!')
|
||||
minetest.display_chat_message('Error teleporting to waypoint!')
|
||||
end
|
||||
elseif fields.delete then
|
||||
minetest.show_formspec('advmarkers-csm', 'size[6,2]' ..
|
||||
'label[0.35,0.25;Are you sure you want to delete this marker?]' ..
|
||||
'label[0.35,0.25;Are you sure you want to delete this waypoint?]' ..
|
||||
'button[0,1;3,1;cancel;Cancel]' ..
|
||||
'button[3,1;3,1;delete_confirm;Delete]')
|
||||
elseif fields.delete_confirm then
|
||||
advmarkers.delete_marker(name)
|
||||
advmarkers.delete_waypoint(name)
|
||||
selected_name = false
|
||||
advmarkers.display_formspec()
|
||||
elseif fields.cancel then
|
||||
|
@ -317,19 +381,19 @@ minetest.register_on_formspec_input(function(formname, fields)
|
|||
advmarkers.display_formspec()
|
||||
end
|
||||
elseif fields.display or fields.delete then
|
||||
minetest.display_chat_message('Please select a marker.')
|
||||
minetest.display_chat_message('Please select a waypoint.')
|
||||
end
|
||||
return true
|
||||
end)
|
||||
|
||||
-- Auto-add markers on death.
|
||||
-- Auto-add waypoints on death.
|
||||
minetest.register_on_death(function()
|
||||
if minetest.localplayer then
|
||||
local name = os.date('Death on %Y-%m-%d %H:%M:%S')
|
||||
local name = 'Death waypoint'
|
||||
local pos = minetest.localplayer:get_pos()
|
||||
advmarkers.last_coords = pos
|
||||
advmarkers.set_marker(pos, name)
|
||||
minetest.display_chat_message('Added marker "' .. name .. '".')
|
||||
advmarkers.set_waypoint(pos, name)
|
||||
minetest.display_chat_message('Added waypoint "' .. name .. '".')
|
||||
end
|
||||
end)
|
||||
|
||||
|
@ -345,11 +409,13 @@ minetest.register_chatcommand('mrkr_export', {
|
|||
export = advmarkers.export()
|
||||
end
|
||||
minetest.show_formspec('advmarkers-ignore',
|
||||
'field[_;Your marker export string;' ..
|
||||
'field[_;Your waypoint export string;' ..
|
||||
minetest.formspec_escape(export) .. ']')
|
||||
end
|
||||
})
|
||||
|
||||
register_chatcommand_alias('mrkr_export', 'wp_export', 'waypoint_export')
|
||||
|
||||
-- String importing
|
||||
minetest.register_chatcommand('mrkr_import', {
|
||||
params = '<advmarkers string>',
|
||||
|
@ -357,23 +423,27 @@ minetest.register_chatcommand('mrkr_import', {
|
|||
'existing markers that have the same name.',
|
||||
func = function(param)
|
||||
if advmarkers.import(param) then
|
||||
return true, 'Markers imported!'
|
||||
return true, 'Waypoints imported!'
|
||||
else
|
||||
return false, 'Invalid advmarkers string!'
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
-- Upload markers to the advmarkers server-side mod.
|
||||
register_chatcommand_alias('mrkr_export', 'wp_import', 'waypoint_import')
|
||||
|
||||
-- Upload waypoints to the advmarkers server-side mod.
|
||||
minetest.register_chatcommand('mrkr_upload', {
|
||||
params = '',
|
||||
description = 'Uploads all markers to this server\'s advmarkers storage.',
|
||||
description = 'Uploads all waypoints to this server\'s advmarkers storage.',
|
||||
func = function(param)
|
||||
local data = advmarkers.export()
|
||||
minetest.run_server_chatcommand('mrkr_import', data)
|
||||
end
|
||||
})
|
||||
|
||||
register_chatcommand_alias('mrkr_export', 'wp_upload', 'waypoint_upload')
|
||||
|
||||
-- Chat channels .coords integration.
|
||||
-- You do not need to have chat channels installed for this to work.
|
||||
if not minetest.registered_on_receiving_chat_message then
|
||||
|
@ -394,12 +464,32 @@ end)
|
|||
-- Add '.mrkrthere'
|
||||
minetest.register_chatcommand('mrkrthere', {
|
||||
params = '',
|
||||
description = 'Adds a (temporary) marker at the last ".coords" position.',
|
||||
description = 'Adds a (temporary) waypoint at the last ".coords" position.',
|
||||
func = function(param)
|
||||
if not advmarkers.last_coords then
|
||||
return false, 'No-one has used ".coords" and you have not died!'
|
||||
elseif not advmarkers.set_hud_pos(advmarkers.last_coords) then
|
||||
return false, 'Error setting the marker!'
|
||||
return false, 'Error setting the waypoint!'
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_chatcommand('clrmrkr', {
|
||||
params = '',
|
||||
description = 'Hides the displayed waypoint.',
|
||||
func = function(param)
|
||||
if hud_id then
|
||||
minetest.localplayer:hud_remove(hud_id)
|
||||
hud_id = nil
|
||||
return true, 'Hidden the currently displayed waypoint.'
|
||||
elseif not minetest.localplayer.hud_add then
|
||||
minetest.run_server_chatcommand('clrmrkr')
|
||||
return
|
||||
elseif not hud_id then
|
||||
return false, 'No waypoint is currently being displayed!'
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
register_chatcommand_alias('clrmrkr', 'clear_marker', 'clrwp',
|
||||
'clear_waypoint')
|
||||
|
|
Loading…
Reference in New Issue