From 42c3b25ec9166dd1a0b9ca7d3efaf1ab03e4caf0 Mon Sep 17 00:00:00 2001 From: luk3yx Date: Sun, 22 Nov 2020 18:49:19 +1300 Subject: [PATCH] Improve SSCSM communication and /mrkr there --- README.md | 13 ++++++++--- init.lua | 67 +++++++++++++++++++++++++------------------------------ sscsm.lua | 16 +++++-------- 3 files changed, 46 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 0862543..3d3bd71 100644 --- a/README.md +++ b/README.md @@ -8,14 +8,21 @@ Unlike the [CSM], this mod is standalone, and conflicts with the marker mod. `advmarkers` introduces the following chatcommands: - - `/mrkr`: Opens a formspec allowing you to display or delete markers. If you give this command a parameter (`h`/`here`, `t`/`there` or co-ordinates), it will set your HUD position to those co-ordinates. - - `/add_mrkr`: Adds markers. You can use `.add_mrkr x,y,z Marker name` to add markers. Adding a marker with (exactly) the same name as another will overwrite the original marker. If you replace `x,y,z` with `here`, the marker will be set to your current position, and replacing it with `there` will set the marker to the last `.coords` position. + - `/wp`, `/mrkr`: Opens a formspec allowing you to display or delete waypoints. If you give this command a parameter (`h`/`here`, `t`/`there` or co-ordinates), it will set your HUD position to those co-ordinates. + - `/add_wp`, `/add_mrkr`: Adds markers. You can use `.add_mrkr x,y,z Marker name` to add markers. Adding a marker with (exactly) the same name as another will overwrite the original marker. - `/mrkr_export`: Exports your markers to an advmarkers string. Remember to not modify the text before copying it. You can use `/mrkr_export old` if you want an export string compatible with older versions of the advmarkers CSM (it should start with `M` instead of `J`). This old format does **not** work with this mod, so only use it if you know what you are doing! - `/mrkr_import`: Imports your markers from an advmarkers string (`.mrkr_import `). Any markers with the same name will not be overwritten, and if they do not have the same co-ordinates, `_` will be appended to the imported one. - `/mrkrthere`: Alias for `/mrkr there`. If you die, a marker is automatically added at your death position, and will -update the last `.coords` position. +update the "there" position. + +### "Here" and "there" positions + +Both /wp and /add_wp accept "here"/"h" and "there"/"t" in place of +co-ordinates. Using "here" will set the waypoint to your current position, and +"there" will set it to the most recent co-ordinates that appear in chat (or +your last death position). ## Chat channels integration diff --git a/init.lua b/init.lua index 90fd51d..4b68540 100644 --- a/init.lua +++ b/init.lua @@ -14,6 +14,8 @@ local hud = {} local use_sscsm = false advmarkers.last_coords = {} +local abs, type = math.abs, type + -- Convert positions to/from strings local function pos_to_string(pos) if type(pos) == 'table' then @@ -28,7 +30,8 @@ local function string_to_pos(pos) if type(pos) == 'string' then pos = minetest.string_to_pos(pos) end - if type(pos) == 'table' then + if type(pos) == 'table' and abs(pos.x) < 31000 and abs(pos.y) < 31000 and + abs(pos.z) < 31000 then return vector.round(pos) end end @@ -288,7 +291,7 @@ function advmarkers.get_chatcommand_pos(player, pos) pos = player:get_pos() elseif pos == 't' or pos == 'there' then if not advmarkers.last_coords[pname] then - return false, 'No-one has used ".coords" and you have not died!' + return false, 'No "there" position found!' end pos = advmarkers.last_coords[pname] else @@ -498,25 +501,19 @@ minetest.register_chatcommand('mrkr_import', { register_chatcommand_alias('mrkr_import', 'wp_import', 'waypoint_import') --- Chat channels .coords integration. --- You do not need to have chat channels installed for this to work. -local function get_coords(msg, strict) - local str = 'Current Position: %-?[0-9]+, %-?[0-9]+, %-?[0-9]+%.' - if strict then - str = '^' .. str +-- Find co-ordinates sent in chat messages +local function get_coords(msg) + if msg:byte(1) == 1 or #msg > 1000 then return end + local pos = msg:match('%-?[0-9%.]+, *%-?[0-9%.]+, *%-?[0-9%.]+') + if pos then + return string_to_pos(pos) end - local s, e = msg:find(str) - local pos = false - if s and e then - pos = string_to_pos(msg:sub(s + 18, e - 1)) - end - return pos end -- Get global co-ords table.insert(minetest.registered_on_chat_messages, 1, function(_, msg) if msg:sub(1, 1) == '/' then return end - local pos = get_coords(msg, true) + local pos = get_coords(msg) if pos then advmarkers.last_coords = {} for _, player in ipairs(get_connected_players()) do @@ -529,7 +526,7 @@ end) local old_chat_send_player = minetest.chat_send_player function minetest.chat_send_player(name, msg, ...) if type(name) == 'string' and type(msg) == 'string' and - get_player_by_name(name) then + get_player_by_name(name) then local pos = get_coords(msg) if pos then advmarkers.last_coords[name] = pos @@ -590,33 +587,29 @@ sscsm.register({ }) -- SSCSM communication --- TODO: Make this use a table (or multiple channels). -sscsm.register_on_com_receive('advmarkers:cmd', function(name, param) - if type(param) ~= 'string' then - return +sscsm.register_on_com_receive('advmarkers:delete', function(name, param) + if type(param) == 'string' then + advmarkers.delete_waypoint(name, param) end +end) - local cmd = param:sub(1, 1) - if cmd == 'D' then - -- D: Delete - advmarkers.delete_waypoint(name, param:sub(2)) - elseif cmd == 'S' then - -- S: Set - local s, e = param:find(' ', nil, true) - if s and e then - local pos = string_to_pos(param:sub(2, s - 1)) - if pos then - advmarkers.set_waypoint(name, pos, param:sub(e + 1)) - end - end - elseif cmd == '0' then - -- 0: Display - if not advmarkers.display_waypoint(name, param:sub(2)) then - minetest.chat_send_player(name, 'Error displaying waypoint!') +sscsm.register_on_com_receive('advmarkers:set', function(name, param) + if type(param) == 'table' and type(param.name) == 'string' and + type(param.pos) == 'string' then + local pos = string_to_pos(param.pos) + if pos then + advmarkers.set_waypoint(name, pos, param.name) end end end) +sscsm.register_on_com_receive('advmarkers:display', function(name, param) + if type(param) ~= 'string' or + not advmarkers.display_waypoint(name, param) then + minetest.chat_send_player(name, 'Error displaying waypoint!') + end +end) + -- Send waypoint list once SSCSMs are loaded. sscsm.register_on_sscsms_loaded(function(name) local player = minetest.get_player_by_name(name) diff --git a/sscsm.lua b/sscsm.lua index 2648a6b..20a7ea6 100644 --- a/sscsm.lua +++ b/sscsm.lua @@ -21,16 +21,10 @@ local function string_to_pos(pos) end end --- Run remote command --- TODO: Use separate SSCSM com channels -local function run_remote_command(cmd, param) - sscsm.com_send('advmarkers:cmd', cmd .. (param or '')) -end - -- Display a waypoint function advmarkers.display_waypoint(name) if data[name] then - run_remote_command('0', name) + sscsm.com_send('advmarkers:display', name) return true end return false @@ -46,7 +40,7 @@ advmarkers.get_marker = advmarkers.get_waypoint function advmarkers.delete_waypoint(name) if data[name] ~= nil then data[name] = nil - run_remote_command('D', name) + sscsm.com_send('advmarkers:delete', name) end end advmarkers.delete_marker = advmarkers.delete_waypoint @@ -57,8 +51,10 @@ function advmarkers.set_waypoint(pos, name) if not pos then return end name = tostring(name) data[name] = pos - run_remote_command('S', minetest.pos_to_string(pos):gsub(' ', '') .. - ' ' .. name) + sscsm.com_send('advmarkers:set', { + name = name, + pos = minetest.pos_to_string(pos), + }) return true end advmarkers.set_marker = advmarkers.set_waypoint