Improve SSCSM communication and /mrkr there

This commit is contained in:
luk3yx 2020-11-22 18:49:19 +13:00
parent 69b7857466
commit 42c3b25ec9
3 changed files with 46 additions and 50 deletions

View File

@ -8,14 +8,21 @@ Unlike the [CSM], this mod is standalone, and conflicts with the marker mod.
`advmarkers` introduces the following chatcommands: `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. - `/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_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. - `/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_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 <advmarkers string>`). 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. - `/mrkr_import`: Imports your markers from an advmarkers string (`.mrkr_import <advmarkers string>`). 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`. - `/mrkrthere`: Alias for `/mrkr there`.
If you die, a marker is automatically added at your death position, and will 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 ## Chat channels integration

View File

@ -14,6 +14,8 @@ local hud = {}
local use_sscsm = false local use_sscsm = false
advmarkers.last_coords = {} advmarkers.last_coords = {}
local abs, type = math.abs, type
-- Convert positions to/from strings -- Convert positions to/from strings
local function pos_to_string(pos) local function pos_to_string(pos)
if type(pos) == 'table' then if type(pos) == 'table' then
@ -28,7 +30,8 @@ local function string_to_pos(pos)
if type(pos) == 'string' then if type(pos) == 'string' then
pos = minetest.string_to_pos(pos) pos = minetest.string_to_pos(pos)
end 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) return vector.round(pos)
end end
end end
@ -288,7 +291,7 @@ function advmarkers.get_chatcommand_pos(player, pos)
pos = player:get_pos() pos = player:get_pos()
elseif pos == 't' or pos == 'there' then elseif pos == 't' or pos == 'there' then
if not advmarkers.last_coords[pname] 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 end
pos = advmarkers.last_coords[pname] pos = advmarkers.last_coords[pname]
else else
@ -498,25 +501,19 @@ minetest.register_chatcommand('mrkr_import', {
register_chatcommand_alias('mrkr_import', 'wp_import', 'waypoint_import') register_chatcommand_alias('mrkr_import', 'wp_import', 'waypoint_import')
-- Chat channels .coords integration. -- Find co-ordinates sent in chat messages
-- You do not need to have chat channels installed for this to work. local function get_coords(msg)
local function get_coords(msg, strict) if msg:byte(1) == 1 or #msg > 1000 then return end
local str = 'Current Position: %-?[0-9]+, %-?[0-9]+, %-?[0-9]+%.' local pos = msg:match('%-?[0-9%.]+, *%-?[0-9%.]+, *%-?[0-9%.]+')
if strict then if pos then
str = '^' .. str return string_to_pos(pos)
end 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 end
-- Get global co-ords -- Get global co-ords
table.insert(minetest.registered_on_chat_messages, 1, function(_, msg) table.insert(minetest.registered_on_chat_messages, 1, function(_, msg)
if msg:sub(1, 1) == '/' then return end if msg:sub(1, 1) == '/' then return end
local pos = get_coords(msg, true) local pos = get_coords(msg)
if pos then if pos then
advmarkers.last_coords = {} advmarkers.last_coords = {}
for _, player in ipairs(get_connected_players()) do for _, player in ipairs(get_connected_players()) do
@ -529,7 +526,7 @@ end)
local old_chat_send_player = minetest.chat_send_player local old_chat_send_player = minetest.chat_send_player
function minetest.chat_send_player(name, msg, ...) function minetest.chat_send_player(name, msg, ...)
if type(name) == 'string' and type(msg) == 'string' and 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) local pos = get_coords(msg)
if pos then if pos then
advmarkers.last_coords[name] = pos advmarkers.last_coords[name] = pos
@ -590,33 +587,29 @@ sscsm.register({
}) })
-- SSCSM communication -- SSCSM communication
-- TODO: Make this use a table (or multiple channels). sscsm.register_on_com_receive('advmarkers:delete', function(name, param)
sscsm.register_on_com_receive('advmarkers:cmd', function(name, param) if type(param) == 'string' then
if type(param) ~= 'string' then advmarkers.delete_waypoint(name, param)
return
end end
end)
local cmd = param:sub(1, 1) sscsm.register_on_com_receive('advmarkers:set', function(name, param)
if cmd == 'D' then if type(param) == 'table' and type(param.name) == 'string' and
-- D: Delete type(param.pos) == 'string' then
advmarkers.delete_waypoint(name, param:sub(2)) local pos = string_to_pos(param.pos)
elseif cmd == 'S' then if pos then
-- S: Set advmarkers.set_waypoint(name, pos, param.name)
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!')
end end
end 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. -- Send waypoint list once SSCSMs are loaded.
sscsm.register_on_sscsms_loaded(function(name) sscsm.register_on_sscsms_loaded(function(name)
local player = minetest.get_player_by_name(name) local player = minetest.get_player_by_name(name)

View File

@ -21,16 +21,10 @@ local function string_to_pos(pos)
end end
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 -- Display a waypoint
function advmarkers.display_waypoint(name) function advmarkers.display_waypoint(name)
if data[name] then if data[name] then
run_remote_command('0', name) sscsm.com_send('advmarkers:display', name)
return true return true
end end
return false return false
@ -46,7 +40,7 @@ advmarkers.get_marker = advmarkers.get_waypoint
function advmarkers.delete_waypoint(name) function advmarkers.delete_waypoint(name)
if data[name] ~= nil then if data[name] ~= nil then
data[name] = nil data[name] = nil
run_remote_command('D', name) sscsm.com_send('advmarkers:delete', name)
end end
end end
advmarkers.delete_marker = advmarkers.delete_waypoint advmarkers.delete_marker = advmarkers.delete_waypoint
@ -57,8 +51,10 @@ function advmarkers.set_waypoint(pos, name)
if not pos then return end if not pos then return end
name = tostring(name) name = tostring(name)
data[name] = pos data[name] = pos
run_remote_command('S', minetest.pos_to_string(pos):gsub(' ', '') .. sscsm.com_send('advmarkers:set', {
' ' .. name) name = name,
pos = minetest.pos_to_string(pos),
})
return true return true
end end
advmarkers.set_marker = advmarkers.set_waypoint advmarkers.set_marker = advmarkers.set_waypoint