refactor to make import/export of entries more generic, for future expansion of options

This commit is contained in:
FaceDeer 2020-02-04 21:00:38 -07:00
parent 195425e168
commit 77270dc445
4 changed files with 244 additions and 131 deletions

243
init.lua
View File

@ -11,6 +11,8 @@ local sfinv_modpath = minetest.get_modpath("sfinv")
local modstore = minetest.get_mod_storage() local modstore = minetest.get_mod_storage()
local ccompass_recalibration_allowed = minetest.settings:get_bool("ccompass_recalibrate", true) local ccompass_recalibration_allowed = minetest.settings:get_bool("ccompass_recalibrate", true)
local ccompass_restrict_target = minetest.settings:get_bool("ccompass_restrict_target", false)
local ccompass_description_prefix = "^Compass to "
local S = minetest.get_translator(modname) local S = minetest.get_translator(modname)
@ -24,6 +26,10 @@ local LOCATION_CATEGORY = 1
local EVENT_CATEGORY = 2 local EVENT_CATEGORY = 2
local GENERAL_CATEGORY = 3 local GENERAL_CATEGORY = 3
-- used for determining if an item is a ccompass
local ccompass_prefix = "ccompass:"
local ccompass_prefix_length = #ccompass_prefix
-------------------------------------------------------- --------------------------------------------------------
-- Data store -- Data store
@ -118,6 +124,10 @@ end
--------------------------------------- ---------------------------------------
-- Reading and writing stuff to items -- Reading and writing stuff to items
----------------------------------------------------------------
-- Export
-- Book parameters -- Book parameters
local lpp = 14 local lpp = 14
local max_text_size = 10000 local max_text_size = 10000
@ -166,6 +176,32 @@ local function write_cgpsmap(player_name)
return new_map return new_map
end end
local function write_ccompass(player_name, old_compass)
local state = get_state(player_name)
local category = state.category
if category ~= LOCATION_CATEGORY then
return
end
local entry_selected = state.entry_selected[category]
local topic = modstore:get_string(player_name .. "_category_" .. category .. "_entry_" .. entry_selected .. "_topic")
local pos = minetest.string_to_pos(topic)
if not pos then
return
end
local content = modstore:get_string(player_name .. "_category_" .. category .. "_entry_" .. entry_selected .. "_content")
content = truncate_string(first_line(content), max_title_size)
local new_ccompass = ItemStack("ccompass:0")
local param = {
target_pos_string = topic,
target_name = content,
playername = player_name
}
ccompass.set_target(new_ccompass, param)
return new_ccompass
end
local function write_item(player_name, itemstack) local function write_item(player_name, itemstack)
local item_name = itemstack:get_name() local item_name = itemstack:get_name()
if item_name == "default:book" then if item_name == "default:book" then
@ -174,8 +210,14 @@ local function write_item(player_name, itemstack)
if item_name == "compassgps:cgpsmap" then if item_name == "compassgps:cgpsmap" then
return write_cgpsmap(player_name) return write_cgpsmap(player_name)
end end
if item_name:sub(1,ccompass_prefix_length) == ccompass_prefix then
return write_ccompass(player_name, itemstack)
end
end end
----------------------------------------------------------------------------------------
-- Import
local function read_book(itemstack, player_name) local function read_book(itemstack, player_name)
local meta = itemstack:get_meta() local meta = itemstack:get_meta()
local topic = meta:get_string("title") local topic = meta:get_string("title")
@ -200,6 +242,21 @@ local function read_book(itemstack, player_name)
save_state(player_name, state) save_state(player_name, state)
end end
local function read_ccompass(itemstack, player_name)
local meta = itemstack:get_meta()
local topic = meta:get_string("target_pos")
local content = meta:get_string("description")
local prefix_start, prefix_end = content:find(ccompass_description_prefix)
if prefix_end then
content = content:sub(prefix_end+1)
end
local state = get_state(player_name)
local entry_index = state.entry_counts[LOCATION_CATEGORY] + 1
state.entry_counts[LOCATION_CATEGORY] = entry_index
save_entry(player_name, LOCATION_CATEGORY, entry_index, content, topic)
save_state(player_name, state)
end
local function read_cgpsmap(itemstack, player_name) local function read_cgpsmap(itemstack, player_name)
-- TODO: get_metadata is a deprecated function, but it is necessary because that's what cgpsmap uses. -- TODO: get_metadata is a deprecated function, but it is necessary because that's what cgpsmap uses.
local meta = minetest.deserialize(itemstack:get_metadata()) local meta = minetest.deserialize(itemstack:get_metadata())
@ -221,63 +278,63 @@ local function read_item(itemstack, player_name)
read_book(itemstack, player_name) read_book(itemstack, player_name)
elseif item_name == "compassgps:cgpsmap_marked" then elseif item_name == "compassgps:cgpsmap_marked" then
read_cgpsmap(itemstack, player_name) read_cgpsmap(itemstack, player_name)
elseif item_name:sub(1,ccompass_prefix_length) == ccompass_prefix then
read_ccompass(itemstack, player_name)
end end
end end
local function set_ccompass(player_name, old_compass) --------------------------------------------------------------------------
local old_pos = old_compass:get_meta():get_string("target_pos") -- Detached inventory
if not ccompass_recalibration_allowed and old_pos ~= "" then
minetest.chat_send_player(player_name, S("Compass is already calibrated."))
return
end
local state = get_state(player_name) -- Allow or disallow ccompasses based on whether they've got target info in their meta
local category = state.category local function ccompass_permitted_target(itemstack)
if category ~= LOCATION_CATEGORY then if ccompass_restrict_target then
return -- We have no idea whether there's an allowed node at this location, so don't allow
-- setting compasses when node type restriction is enabled.
return false
end end
local topic = modstore:get_string(player_name .. "_category_" .. category .. "_entry_" .. entry_selected .. "_topic") if not itemstack:get_name():sub(1,ccompass_prefix_length) == ccompass_prefix then
local pos = minetest.string_to_pos(topic) return false
if not pos then
return
end end
local meta = itemstack:get_meta()
local content = modstore:get_string(player_name .. "_category_" .. category .. "_entry_" .. entry_selected .. "_content") local has_pos = minetest.string_to_pos(meta:get_string("target_pos"))
content = truncate_string(first_line(content), max_title_size) if has_pos and not ccompass_recalibration_allowed then
local new_ccompass = ItemStack("ccompass:0") return false
local param = { end
target_pos_string = topic, return true
target_name = content, end
playername = player_name local function ccompass_permitted_source(itemstack)
} if not itemstack:get_name():sub(1,ccompass_prefix_length) == ccompass_prefix then
ccompass.set_target(new_ccompass, param) return false
return new_ccompass end
local meta = itemstack:get_meta()
local has_pos = minetest.string_to_pos(meta:get_string("target_pos"))
if not has_pos then
return false
end
return true
end end
local ccompass_prefix = "ccompass:"
local ccompass_prefix_length = #ccompass_prefix
local detached_callbacks = { local detached_callbacks = {
allow_put = function(inv, listname, index, stack, player) allow_put = function(inv, listname, index, stack, player)
local stack_name = stack:get_name() local stack_name = stack:get_name()
if listname == "write_book" then if listname == "export_item" then
if stack_name == "default:book" then if stack_name == "default:book" then
return 1 return 1
end end
local player_name = player:get_player_name() local player_name = player:get_player_name()
local state = get_state(player_name) local state = get_state(player_name)
local category = state.category local category = state.category
if category == LOCATION_CATEGORY and stack_name == "compassgps:cgpsmap" then if category == LOCATION_CATEGORY and
(stack_name == "compassgps:cgpsmap" or
ccompass_permitted_target(stack)) then
return 1 return 1
end end
return 0 return 0
elseif listname == "read_book" then elseif listname == "import_item" then
if stack_name == "default:book_written" or stack_name == "compassgps:cgpsmap_marked" then if stack_name == "default:book_written" or
return 1 stack_name == "compassgps:cgpsmap_marked" or
end ccompass_permitted_source(stack) then
return 0
elseif listname == "set_compass" then
-- TODO: support setting cgpscompass compasses directly
if stack_name:sub(1,ccompass_prefix_length) == ccompass_prefix then
return 1 return 1
end end
return 0 return 0
@ -285,17 +342,12 @@ local detached_callbacks = {
end, end,
on_put = function(inv, listname, index, stack, player) on_put = function(inv, listname, index, stack, player)
local player_name = player:get_player_name() local player_name = player:get_player_name()
if listname == "write_book" then if listname == "export_item" then
local new_item = write_item(player_name, stack)
inv:remove_item(listname, stack) inv:remove_item(listname, stack)
inv:add_item(listname, write_item(player_name, stack)) inv:add_item(listname, new_item)
elseif listname == "read_book" then elseif listname == "import_item" then
read_item(stack, player_name) read_item(stack, player_name)
elseif listname == "set_compass" then
local new_ccompass = set_ccompass(player_name, stack)
if new_ccompass then
inv:remove_item(listname, stack)
inv:add_item(listname, new_ccompass)
end
end end
end, end,
} }
@ -306,17 +358,12 @@ local function ensure_detached_inventory(player_name)
return return
end end
local inv = minetest.create_detached_inventory("personal_log_"..player_name, detached_callbacks) local inv = minetest.create_detached_inventory("personal_log_"..player_name, detached_callbacks)
if default_modpath then inv:set_size("export_item", 1)
inv:set_size("write_book", 1) inv:set_size("import_item", 1)
inv:set_size("read_book", 1)
end
if ccompass_modpath or compassgps_modpath then
inv:set_size("set_compass", 1)
end
item_invs[player_name] = true item_invs[player_name] = true
end end
-- if a player leaves stuff in their detached inventory, try giving it to them when they leave -- if a player leaves stuff in their detached inventory, try giving it to them when they exit
local function try_return(detached_inv, player_inv, listname) local function try_return(detached_inv, player_inv, listname)
local item = detached_inv:get_stack(listname, 1) local item = detached_inv:get_stack(listname, 1)
item = player_inv:add_item("main", item) item = player_inv:add_item("main", item)
@ -327,15 +374,63 @@ local function return_all_items(player)
if item_invs[player_name] then if item_invs[player_name] then
local player_inv = minetest.get_inventory({type="player", name=player_name}) local player_inv = minetest.get_inventory({type="player", name=player_name})
local detached_inv = minetest.get_inventory({type="detached", name="personal_log_"..player_name}) local detached_inv = minetest.get_inventory({type="detached", name="personal_log_"..player_name})
try_return(detached_inv, player_inv, "set_compass") -- do compass first, it's most expensive try_return(detached_inv, player_inv, "export_item")
try_return(detached_inv, player_inv, "write_book") try_return(detached_inv, player_inv, "import_item")
try_return(detached_inv, player_inv, "read_book")
end end
end end
local function item_formspec(player_name, label, listname) ------------------------------------------------------------------------
-- Import/export formspec
local import_mods = {}
local export_generic_mods = {}
local export_location_mods = {}
if default_modpath then
table.insert(import_mods, S("a book"))
table.insert(export_generic_mods, S("a book"))
table.insert(export_location_mods, S("a book"))
end
if ccompass_modpath then
table.insert(import_mods, S("a calibrated compass"))
if not ccompass_restrict_target then
table.insert(export_location_mods, S("a compass"))
end
end
if compassgps_modpath then
table.insert(import_mods, S("a GPS compass map"))
table.insert(export_location_mods, S("a GPS compass map"))
end
local function aggregate_localized_string(list)
if #list == 1 then
return S("@1", list[1])
end
if #list == 2 then
return S("@1 or @2", list[1], list[2])
end
if #list == 3 then
return S("@1, @2 or @3", list[1], list[2], list[3])
end
end
local import_label = aggregate_localized_string(import_mods)
local export_generic_label = aggregate_localized_string(export_generic_mods)
local export_location_label = aggregate_localized_string(export_location_mods)
local function item_formspec(player_name, category, listname, topic)
local label
if listname == "import_item" then
label = S("Import an entry from @1", import_label)
else
if category == LOCATION_CATEGORY then
label = S('Export "@1" to @2', topic, export_location_label)
else
label = S('Export "@1" to @2', topic, export_generic_label)
end
end
local formspec = "size[8,6]" local formspec = "size[8,6]"
.. "label[1,0.25;" .. label .. "]" .. "label[0,1;" .. label .. "]"
.. "list[detached:personal_log_"..player_name..";"..listname..";3.5,0;1,1;]" .. "list[detached:personal_log_"..player_name..";"..listname..";3.5,0;1,1;]"
.. "list[current_player;main;0,1.5;8,4;]" .. "list[current_player;main;0,1.5;8,4;]"
.. "listring[]" .. "listring[]"
@ -402,21 +497,16 @@ local function make_personal_log_formspec(player)
.."button[0,0;2,0.5;save;"..S("Save").."]" .."button[0,0;2,0.5;save;"..S("Save").."]"
.."button[2,0;2,0.5;create;"..S("New").."]" .."button[2,0;2,0.5;create;"..S("New").."]"
.."button[4.5,0;2,0.5;move_up;"..S("Move Up").."]" .."button[4.5,0;2,0.5;move_up;"..S("Move Up").."]"
.."button[4.5,0.5;2,0.5;move_down;"..S("Move Down").."]" .."button[4.5,0.75;2,0.5;move_down;"..S("Move Down").."]"
.."button[7,0;2,0.5;delete;"..S("Delete") .."]" .."button[7,0;2,0.5;delete;"..S("Delete") .."]"
if category_index == LOCATION_CATEGORY and minetest.check_player_privs(player_name, "teleport") then if category_index == LOCATION_CATEGORY and minetest.check_player_privs(player_name, "teleport") then
formspec[#formspec+1] = "button[7,0.5;2,0.5;teleport;"..S("Teleport") .."]" formspec[#formspec+1] = "button[7,0.5;2,0.5;teleport;"..S("Teleport") .."]"
end end
if default_modpath then if default_modpath or ccompass_modpath or compassgps_modpath then
formspec[#formspec+1] = "button[0,0.75;1.25,0.5;copy_to;"..S("To Book").."]" formspec[#formspec+1] = "button[0,0.75;2.0,0.5;copy_to;"..S("Export").."]"
.."button[1.375,0.75;1.25,0.5;copy_from;"..S("From Book").."]" .."button[2,0.75;2.0,0.5;copy_from;"..S("Import").."]"
end
-- TODO: support setting cgpscompass compasses directly
if ccompass_modpath and category_index == LOCATION_CATEGORY then
formspec[#formspec+1] = "button[2.75,0.75;1.25,0.5;set_compass;"..S("To Compass").."]"
end end
formspec[#formspec+1] = "container_end[]" formspec[#formspec+1] = "container_end[]"
@ -523,21 +613,20 @@ local function on_player_receive_fields(player, fields, update_callback)
if fields.copy_to then if fields.copy_to then
if valid_entry_selected then if valid_entry_selected then
local topic = modstore:get_string(player_name .. "_category_" .. category .. "_entry_" .. entry_selected .. "_topic")
if category ~= 3 then
-- If it's a location or an event, add a little context to the title
local content = modstore:get_string(player_name .. "_category_" .. category .. "_entry_" .. entry_selected .. "_content")
topic = S("@1: @2", topic, truncate_string(first_line(content), short_title_size))
end
minetest.show_formspec(player_name, "personal_log:item", minetest.show_formspec(player_name, "personal_log:item",
item_formspec(player_name, S("Copy log to blank book:"), "write_book")) item_formspec(player_name, category, "export_item", topic))
end end
return return
end end
if fields.copy_from then if fields.copy_from then
minetest.show_formspec(player_name, "personal_log:item", minetest.show_formspec(player_name, "personal_log:item",
item_formspec(player_name, S("Copy log from written book:"), "read_book")) item_formspec(player_name, category, "import_item"))
return
end
if fields.set_compass then
if valid_entry_selected then
minetest.show_formspec(player_name, "personal_log:item",
item_formspec(player_name, S("Set a compass to this location:"), "set_compass"))
end
return return
end end

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-02-04 13:23-0700\n" "POT-Creation-Date: 2020-02-04 20:56-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,96 +17,120 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n" "Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: personal_log\init.lua:18 #: personal_log\init.lua:20
msgid "Location" msgid "Location"
msgstr "" msgstr ""
#: personal_log\init.lua:19 #: personal_log\init.lua:21
msgid "Event" msgid "Event"
msgstr "" msgstr ""
#: personal_log\init.lua:20 #: personal_log\init.lua:22
msgid "General" msgid "General"
msgstr "" msgstr ""
#: personal_log\init.lua:142 #: personal_log\init.lua:152
msgid "\"@1\" by @2" msgid "\"@1\" by @2"
msgstr "" msgstr ""
#: personal_log\init.lua:230 #: personal_log\init.lua:389
msgid "Compass is already calibrated." #: personal_log\init.lua:390
#: personal_log\init.lua:391
msgid "a book"
msgstr "" msgstr ""
#: personal_log\init.lua:342 #: personal_log\init.lua:394
msgid "Back" msgid "a calibrated compass"
msgstr "" msgstr ""
#: personal_log\init.lua:363 #: personal_log\init.lua:396
msgid "Category:" msgid "a compass"
msgstr "" msgstr ""
#: personal_log\init.lua:364 #: personal_log\init.lua:400
msgid "Personal Log Entries" #: personal_log\init.lua:401
msgstr "" msgid "a GPS compass map"
#: personal_log\init.lua:402
msgid "Save"
msgstr ""
#: personal_log\init.lua:403
msgid "New"
msgstr ""
#: personal_log\init.lua:404
msgid "Move Up"
msgstr ""
#: personal_log\init.lua:405
msgid "Move Down"
msgstr "" msgstr ""
#: personal_log\init.lua:406 #: personal_log\init.lua:406
msgid "Delete" msgid "@1"
msgstr "" msgstr ""
#: personal_log\init.lua:409 #: personal_log\init.lua:409
msgid "@1 or @2"
msgstr ""
#: personal_log\init.lua:412
msgid "@1, @2 or @3"
msgstr ""
#: personal_log\init.lua:423
msgid "Import an entry from @1"
msgstr ""
#: personal_log\init.lua:426
#: personal_log\init.lua:428
msgid "Export \"@1\" to @2"
msgstr ""
#: personal_log\init.lua:437
msgid "Back"
msgstr ""
#: personal_log\init.lua:458
msgid "Category:"
msgstr ""
#: personal_log\init.lua:459
msgid "Personal Log Entries"
msgstr ""
#: personal_log\init.lua:497
msgid "Save"
msgstr ""
#: personal_log\init.lua:498
msgid "New"
msgstr ""
#: personal_log\init.lua:499
msgid "Move Up"
msgstr ""
#: personal_log\init.lua:500
msgid "Move Down"
msgstr ""
#: personal_log\init.lua:501
msgid "Delete"
msgstr ""
#: personal_log\init.lua:504
msgid "Teleport" msgid "Teleport"
msgstr "" msgstr ""
#: personal_log\init.lua:413 #: personal_log\init.lua:508
msgid "To Book" msgid "Export"
msgstr "" msgstr ""
#: personal_log\init.lua:414 #: personal_log\init.lua:509
msgid "From Book" msgid "Import"
msgstr "" msgstr ""
#: personal_log\init.lua:419 #: personal_log\init.lua:620
msgid "To Compass" msgid "@1: @2"
msgstr "" msgstr ""
#: personal_log\init.lua:527 #: personal_log\init.lua:668
msgid "Copy log to blank book:" #: personal_log\init.lua:680
msgstr ""
#: personal_log\init.lua:533
msgid "Copy log from written book:"
msgstr ""
#: personal_log\init.lua:539
msgid "Set a compass to this location:"
msgstr ""
#: personal_log\init.lua:579
#: personal_log\init.lua:591
msgid "Your personal log for keeping track of what happens where" msgid "Your personal log for keeping track of what happens where"
msgstr "" msgstr ""
#: personal_log\init.lua:592 #: personal_log\init.lua:681
#: personal_log\init.lua:600 #: personal_log\init.lua:689
msgid "Log" msgid "Log"
msgstr "" msgstr ""
#: personal_log\init.lua:604 #: personal_log\init.lua:693
msgid "Open personal log" msgid "Open personal log"
msgstr "" msgstr ""

View File

@ -12,7 +12,7 @@ Logs can be entered into three different categories:
- Events - Events
- General - General
Location logs will automatically have the player's coordinates saved with them when they're created. If the [ccompass](https://github.com/minetest-mods/ccompass) mod is installed there will be an interface that allows you to set a compass to track the location of one of these entries. Location logs will automatically have the player's coordinates saved with them when they're created. If the [ccompass](https://github.com/minetest-mods/ccompass) mod is installed there will be an interface that allows you to set a compass to track the location of one of these entries. You can also read and write maps belonging to the [compassgps](https://github.com/Kilarin/compassgps/) mod.
Event logs automatically have the current date saved with them when they're created. Event logs automatically have the current date saved with them when they're created.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 20 KiB